Test Failed
Pull Request — master (#21)
by Maximo
05:21
created

api/controllers/AppsPlansController.php (2 issues)

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 Gewaer\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
 * @property \Phalcon\Db\Adapter\Pdo\Mysql $db
28
 */
29
class AppsPlansController extends BaseController
30
{
31
    /*
32
     * fields we accept to create
33
     *
34
     * @var array
35
     */
36
    protected $createFields = [];
37
38
    /*
39
     * fields we accept to create
40
     *
41
     * @var array
42
     */
43
    protected $updateFields = [];
44
45
    /**
46
     * set objects
47
     *
48
     * @return void
49
     */
50 4
    public function onConstruct()
51
    {
52 4
        $this->model = new AppsPlans();
53 4
        $this->additionalSearchFields = [
54 4
            ['is_deleted', ':', 0],
55 4
            ['apps_id', ':', $this->app->getId()],
56
        ];
57 4
    }
58
59
    /**
60
     * Given the app plan stripe id , subscribe the current company to this aps
61
     *
62
     * @return Response
63
     */
64 1
    public function create(): Response
65
    {
66 1
        if (!$this->userData->hasRole('Default.Admins')) {
67
            throw new UnauthorizedHttpException(_('You dont have permission to subscribe this apps'));
68
        }
69
70
        //Ok let validate user password
71 1
        $validation = new Validation();
72 1
        $validation->add('stripe_id', new PresenceOf(['message' => _('The plan is required.')]));
73 1
        $validation->add('number', new PresenceOf(['message' => _('Credit Card Number is required.')]));
74 1
        $validation->add('exp_month', new PresenceOf(['message' => _('Credit Card Number is required.')]));
75 1
        $validation->add('exp_year', new PresenceOf(['message' => _('Credit Card Number is required.')]));
76 1
        $validation->add('cvc', new PresenceOf(['message' => _('CVC is required.')]));
77
78
        //validate this form for password
79 1
        $messages = $validation->validate($this->request->getPost());
80 1
        if (count($messages)) {
81
            foreach ($messages as $message) {
82
                throw new UnprocessableEntityHttpException($message);
83
            }
84
        }
85
86 1
        $stripeId = $this->request->getPost('stripe_id');
87 1
        $company = $this->userData->defaultCompany;
88 1
        $cardNumber = $this->request->getPost('number');
89 1
        $expMonth = $this->request->getPost('exp_month');
90 1
        $expYear = $this->request->getPost('exp_year');
91 1
        $cvc = $this->request->getPost('cvc');
92
93 1
        $appPlan = $this->model->findFirstByStripeId($stripeId);
94
95 1
        if (!is_object($appPlan)) {
96
            throw new NotFoundHttpException(_('This plan doesnt exist'));
97
        }
98
99 1
        $userSubscription = Subscription::findFirst([
100 1
            'conditions' => 'user_id = ?0 and company_id = ?1 and apps_id = ?2 and is_deleted  = 0',
101 1
            'bind' => [$this->userData->getId(), $this->userData->default_company, $this->app->getId()]
102
        ]);
103
104 1
        if (is_object($userSubscription)) {
105
            throw new NotFoundHttpException(_('You are already subscribed to this plan'));
106
        }
107
108 1
        $card = StripeToken::create([
109
            'card' => [
110 1
                'number' => $cardNumber,
111 1
                'exp_month' => $expMonth,
112 1
                'exp_year' => $expYear,
113 1
                'cvc' => $cvc,
114
            ],
115
        ], [
116 1
            'api_key' => $this->config->stripe->secret
117
        ])->id;
118
119
        $this->db->begin();
120
121
        //if fails it will throw exception
122
        if ($appPlan->free_trial_dates == 0) {
123
            $this->userData->newSubscription($appPlan->name, $appPlan->stripe_id, $company, $this->app)->create($card);
124
        } else {
125
            $this->userData->newSubscription($appPlan->name, $appPlan->stripe_id, $company, $this->app)->trialDays($appPlan->free_trial_dates)->create($card);
126
        }
127
128
        //update company app
129
        $companyApp = UserCompanyApps::getCurrentApp();
130
131
        //update the company app to the new plan
132
        if (is_object($companyApp)) {
133
            $subscription = $this->userData->subscription($appPlan->stripe_plan);
134
            $companyApp->strip_id = $stripeId;
0 ignored issues
show
Bug Best Practice introduced by
The property strip_id does not exist on Gewaer\Models\UserCompanyApps. Since you implemented __set, consider adding a @property annotation.
Loading history...
135
            $companyApp->subscriptions_id = $subscription->getId();
136
            if (!$companyApp->update()) {
137
                $this->db->rollback();
138
                throw new UnprocessableEntityHttpException((string) current($companyApp->getMessages()));
139
            }
140
141
            //update the subscription with the plan
142
            $subscription->apps_plans_id = $appPlan->getId();
143
            if (!$subscription->update()) {
144
                $this->db->rollback();
145
                throw new UnprocessableEntityHttpException((string) current($subscription->getMessages()));
146
            }
147
        }
148
149
        $this->db->commit();
150
151
        //sucess
152
        return $this->response($appPlan);
153
    }
154
155
    /**
156
     * Update a given subscription
157
     *
158
     * @param string $stripeId
159
     * @return Response
160
     */
161 2
    public function edit($stripeId) : Response
162
    {
163 2
        $appPlan = $this->model->findFirstByStripeId($stripeId);
164
165 2
        if (!is_object($appPlan)) {
166
            throw new NotFoundHttpException(_('This plan doesnt exist'));
167
        }
168
169 2
        $userSubscription = Subscription::findFirst([
170 2
            'conditions' => 'user_id = ?0 and company_id = ?1 and apps_id = ?2 and is_deleted  = 0',
171 2
            'bind' => [$this->userData->getId(), $this->userData->default_company, $this->app->getId()]
172
        ]);
173
174 2
        if (!is_object($userSubscription)) {
175 2
            throw new NotFoundHttpException(_('No current subscription found'));
176
        }
177
178
        $this->db->begin();
179
180
        $subscription = $this->userData->subscription($userSubscription->name);
181
182
        if ($subscription->onTrial()) {
183
            $subscription->name = $appPlan->name;
184
            $subscription->stripe_id = $appPlan->stripe_id;
185
            $subscription->stripe_plan = $appPlan->stripe_plan;
186
        } else {
187
            $subscription->swap($stripeId);
188
        }
189
190
        //update company app
191
        $companyApp = UserCompanyApps::getCurrentApp();
192
193
        //update the company app to the new plan
194
        if (is_object($companyApp)) {
195
            $subscription->name = $stripeId;
196
            $subscription->save();
197
198
            $companyApp->strip_id = $stripeId;
0 ignored issues
show
Bug Best Practice introduced by
The property strip_id does not exist on Gewaer\Models\UserCompanyApps. Since you implemented __set, consider adding a @property annotation.
Loading history...
199
            $companyApp->subscriptions_id = $subscription->getId();
200
            if (!$companyApp->update()) {
201
                $this->db->rollback();
202
                throw new UnprocessableEntityHttpException((string) current($companyApp->getMessages()));
203
            }
204
205
            //update the subscription with the plan
206
            $subscription->apps_plans_id = $appPlan->getId();
207
            if (!$subscription->update()) {
208
                $this->db->rollback();
209
210
                throw new UnprocessableEntityHttpException((string) current($subscription->getMessages()));
211
            }
212
        }
213
214
        $this->db->commit();
215
216
        //return the new subscription plan
217
        return $this->response($appPlan);
218
    }
219
220
    /**
221
     * Cancel a given subscription
222
     *
223
     * @param string $stripeId
224
     * @return Response
225
     */
226 1
    public function delete($stripeId): Response
227
    {
228 1
        $appPlan = $this->model->findFirstByStripeId($stripeId);
229
230 1
        if (!is_object($appPlan)) {
231
            throw new NotFoundHttpException(_('This plan doesnt exist'));
232
        }
233
234 1
        $userSubscription = Subscription::findFirst([
235 1
            'conditions' => 'user_id = ?0 and company_id = ?1 and apps_id = ?2 and is_deleted  = 0',
236 1
            'bind' => [$this->userData->getId(), $this->userData->default_company, $this->app->getId()]
237
        ]);
238
239 1
        if (!is_object($userSubscription)) {
240 1
            throw new NotFoundHttpException(_('No current subscription found'));
241
        }
242
243
        $subscription = $this->userData->subscription($userSubscription->name);
244
245
        //if on trial you can cancel without going to stripe
246
        if (!$subscription->onTrial()) {
247
            $subscription->cancel();
248
        }
249
250
        $subscription->is_deleted = 1;
251
        $subscription->update();
252
253
        return $this->response($appPlan);
254
    }
255
}
256