Passed
Push — master ( 682802...46670a )
by Maximo
05:00 queued 10s
created

AppsPlansController::edit()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 34
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 17
nc 4
nop 1
dl 0
loc 34
ccs 0
cts 24
cp 0
crap 20
rs 9.7
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gewaer\Api\Controllers;
6
7
use Gewaer\Models\AppsPlans;
8
use Gewaer\Exception\UnauthorizedHttpException;
9
use Gewaer\Exception\NotFoundHttpException;
10
use Stripe\Token as StripeToken;
11
use Phalcon\Http\Response;
12
use Phalcon\Validation;
13
use Phalcon\Validation\Validator\PresenceOf;
14
use Gewaer\Exception\UnprocessableEntityHttpException;
15
use Phalcon\Cashier\Subscription;
16
use Baka\Auth\Models\UserCompanyApps;
17
18
/**
19
 * Class LanguagesController
20
 *
21
 * @package Gewaer\Api\Controllers
22
 *
23
 * @property Users $userData
24
 * @property Request $request
25
 * @property Config $config
26
 * @property Apps $app
27
 */
28
class AppsPlansController extends BaseController
29
{
30
    /*
31
     * fields we accept to create
32
     *
33
     * @var array
34
     */
35
    protected $createFields = [];
36
37
    /*
38
     * fields we accept to create
39
     *
40
     * @var array
41
     */
42
    protected $updateFields = [];
43
44
    /**
45
     * set objects
46
     *
47
     * @return void
48
     */
49
    public function onConstruct()
50
    {
51
        $this->model = new AppsPlans();
52
        $this->additionalSearchFields = [
53
            ['is_deleted', ':', 0],
54
            ['apps_id', ':', $this->app->getId()],
55
        ];
56
    }
57
58
    /**
59
     * Given the app plan stripe id , subscribe the current company to this aps
60
     *
61
     * @return Response
62
     */
63
    public function create(): Response
64
    {
65
        if (!$this->userData->hasRole('Default.Admins')) {
66
            throw new UnauthorizedHttpException(_('You dont have permission to subscribe this apps'));
67
        }
68
69
        //Ok let validate user password
70
        $validation = new Validation();
71
        $validation->add('stripe_id', new PresenceOf(['message' => _('The plan is required.')]));
72
        $validation->add('number', new PresenceOf(['message' => _('Credit Card Number is required.')]));
73
        $validation->add('exp_month', new PresenceOf(['message' => _('Credit Card Number is required.')]));
74
        $validation->add('exp_year', new PresenceOf(['message' => _('Credit Card Number is required.')]));
75
        $validation->add('cvc', new PresenceOf(['message' => _('CVC is required.')]));
76
77
        //validate this form for password
78
        $messages = $validation->validate($this->request->getPost());
79
        if (count($messages)) {
80
            foreach ($messages as $message) {
81
                throw new UnprocessableEntityHttpException($message);
82
            }
83
        }
84
85
        $stripeId = $this->request->getPost('stripe_id');
86
        $company = $this->userData->defaultCompany;
87
        $cardNumber = $this->request->getPost('number');
88
        $expMonth = $this->request->getPost('exp_month');
89
        $expYear = $this->request->getPost('exp_year');
90
        $cvc = $this->request->getPost('cvc');
91
92
        $appPlan = $this->model->findFirstByStripeId($stripeId);
93
94
        if (!is_object($appPlan)) {
95
            throw new NotFoundHttpException(_('This plan doesnt exist'));
96
        }
97
98
        $userSubscription = Subscription::findFirst([
99
            'conditions' => 'user_id = ?0 and company_id = ?1 and apps_id = ?2 and is_deleted  = 0',
100
            'bind' => [$this->userData->getId(), $this->userData->default_company, $this->app->getId()]
101
        ]);
102
103
        if (is_object($userSubscription)) {
104
            throw new NotFoundHttpException(_('You are already subscribed to this plan'));
105
        }
106
107
        $card = StripeToken::create([
108
            'card' => [
109
                'number' => $cardNumber,
110
                'exp_month' => $expMonth,
111
                'exp_year' => $expYear,
112
                'cvc' => $cvc,
113
            ],
114
        ], [
115
            'api_key' => $this->config->stripe->secret
116
        ])->id;
117
118
        //if fails it will throw exception
119
        if ($appPlan->free_trial_dates == 0) {
120
            $this->userData->newSubscription($appPlan->name, $appPlan->stripe_id, $company, $this->app)->create($card);
121
        } else {
122
            $this->userData->newSubscription($appPlan->name, $appPlan->stripe_id, $company, $this->app)->trialDays($appPlan->free_trial_dates)->create($card);
123
        }
124
125
        //update company app
126
        $companyApp = UserCompanyApps::findFirst([
127
            'conditions' => 'company_id = ?0 and apps_id = ?1',
128
            'bind' => [$this->userData->defaultCompany->getId(), $this->app->getId()]
129
        ]);
130
131
        //udpate the company app to the new plan
132
        if (is_object($companyApp)) {
133
            $companyApp->strip_id = $stripeId;
134
            $companyApp->subscriptions_id = $this->userData->subscription($appPlan->stripe_plan)->getId();
135
            $companyApp->update();
136
        }
137
138
        //sucess
139
        return $this->response($appPlan);
140
    }
141
142
    /**
143
     * Update a given subscription
144
     *
145
     * @param string $stripeId
146
     * @return Response
147
     */
148
    public function edit($stripeId) : Response
149
    {
150
        $appPlan = $this->model->findFirstByStripeId($stripeId);
151
152
        if (!is_object($appPlan)) {
153
            throw new NotFoundHttpException(_('This plan doesnt exist'));
154
        }
155
156
        $userSubscription = Subscription::findFirst([
157
            'conditions' => 'user_id = ?0 and company_id = ?1 and apps_id = ?2 and is_deleted  = 0',
158
            'bind' => [$this->userData->getId(), $this->userData->default_company, $this->app->getId()]
159
        ]);
160
161
        if (!is_object($userSubscription)) {
162
            throw new NotFoundHttpException(_('No current subscription found'));
163
        }
164
165
        $this->userData->subscription($userSubscription->name)->swap($stripeId);
166
167
        //update company app
168
        $companyApp = UserCompanyApps::findFirst([
169
            'conditions' => 'company_id = ?0 and apps_id = ?1',
170
            'bind' => [$this->userData->defaultCompany->getId(), $this->app->getId()]
171
        ]);
172
173
        //udpate the company app to the new plan
174
        if (is_object($companyApp)) {
175
            $companyApp->strip_id = $stripeId;
176
            $companyApp->subscriptions_id = $this->userData->subscription($stripeId)->getId();
177
            $companyApp->update();
178
        }
179
180
        //return the new subscription plan
181
        return $this->response($appPlan);
182
    }
183
184
    /**
185
     * Cancel a given subscription
186
     *
187
     * @param string $stripeId
188
     * @return Response
189
     */
190
    public function delete($stripeId): Response
191
    {
192
        $appPlan = $this->model->findFirstByStripeId($stripeId);
193
194
        if (!is_object($appPlan)) {
195
            throw new NotFoundHttpException(_('This plan doesnt exist'));
196
        }
197
198
        $userSubscription = Subscription::findFirst([
199
            'conditions' => 'user_id = ?0 and company_id = ?1 and apps_id = ?2 and is_deleted  = 0',
200
            'bind' => [$this->userData->getId(), $this->userData->default_company, $this->app->getId()]
201
        ]);
202
203
        if (!is_object($userSubscription)) {
204
            throw new NotFoundHttpException(_('No current subscription found'));
205
        }
206
207
        $subscription = $this->userData->subscription($userSubscription->name)->cancel();
208
        $subscription->is_deleted = 1;
209
        $subscription->update();
210
211
        return $this->response($appPlan);
212
    }
213
}
214