Passed
Pull Request — master (#55)
by Rafael
08:50
created

Companies::afterUpdate()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 5
nop 0
dl 0
loc 19
ccs 10
cts 10
cp 1
crap 5
rs 9.6111
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Gewaer\Models;
5
6
use Phalcon\Validation;
7
use Phalcon\Validation\Validator\PresenceOf;
8
use Gewaer\Exception\ServerErrorHttpException;
9
use Exception;
10
use Carbon\Carbon;
11
use Gewaer\Traits\ModelSettingsTrait;
12
use Gewaer\Traits\AppsSettingsTrait;
13
14
/**
15
 * Class Companies
16
 *
17
 * @package Gewaer\Models
18
 *
19
 * @property Users $user
20
 * @property Users $userData
21
 * @property DefaultCompany $default_company
22
 * @property CompaniesBranches $branch
23
 * @property CompaniesBranches $branches
24
 * @property Config $config
25
 * @property UserCompanyApps $app
26
 * @property \Phalcon\Di $di
27
 */
28
class Companies extends \Gewaer\CustomFields\AbstractCustomFieldsModel
29
{
30
    use ModelSettingsTrait;
31
    use AppsSettingsTrait;
32
33
    const DEFAULT_COMPANY = 'DefaulCompany';
34
    const PAYMENT_GATEWAY_CUSTOMER_KEY = 'payment_gateway_customer_id';
35
36
    /**
37
     *
38
     * @var integer
39
     */
40
    public $id;
41
42
    /**
43
     *
44
     * @var string
45
     */
46
    public $name;
47
48
    /**
49
     *
50
     * @var string
51
     */
52
    public $profile_image;
53
54
    /**
55
     *
56
     * @var string
57
     */
58
    public $website;
59
60
    /**
61
     *
62
     * @var integer
63
     */
64
    public $users_id;
65
66
    /**
67
     *
68
     * @var integer
69
     */
70
    public $has_activities;
71
72
    /**
73
     *
74
     * @var string
75
     */
76
    public $created_at;
77
78
    /**
79
     *
80
     * @var string
81
     */
82
    public $updated_at;
83
84
    /**
85
     *
86
     * @var integer
87
     */
88
    public $is_deleted;
89
90
    /**
91
     * Provide the app plan id
92
     *
93
     * @var integer
94
     */
95
    public $appPlanId = null;
96
97
    /**
98
     *
99
     * @var integer
100
     */
101
    public $currency_id;
102
103
    /**
104
     *
105
     * @var string
106
     */
107
    public $language;
108
109
    /**
110
     *
111
     * @var string
112
     */
113
    public $timezone;
114
115
    /**
116
     *
117
     * @var string
118
     */
119
    public $currency;
120
121
    /**
122
     * Initialize method for model.
123
     */
124 23
    public function initialize()
125
    {
126 23
        $this->setSource('companies');
127
128 23
        $this->belongsTo('users_id', 'Baka\Auth\Models\Users', 'id', ['alias' => 'user']);
129 23
        $this->hasMany('id', 'Baka\Auth\Models\CompanySettings', 'id', ['alias' => 'settings']);
130
131 23
        $this->belongsTo(
132 23
            'users_id',
133 23
            'Gewaer\Models\Users',
134 23
            'id',
135 23
            ['alias' => 'user']
136
        );
137
138 23
        $this->hasMany(
139 23
            'id',
140 23
            'Gewaer\Models\CompaniesBranches',
141 23
            'companies_id',
142 23
            ['alias' => 'branches']
143
        );
144
145 23
        $this->hasMany(
146 23
            'id',
147 23
            'Gewaer\Models\CompaniesCustomFields',
148 23
            'companies_id',
149 23
            ['alias' => 'fields']
150
        );
151
152 23
        $this->hasMany(
153 23
            'id',
154 23
            'Gewaer\CustomFields\CustomFields',
155 23
            'companies_id',
156 23
            ['alias' => 'custom-fields']
157
        );
158
159 23
        $this->hasMany(
160 23
            'id',
161 23
            'Gewaer\Models\UsersAssociatedCompany',
162 23
            'companies_id',
163 23
            ['alias' => 'UsersAssociatedCompany']
164
        );
165
166 23
        $this->hasMany(
167 23
            'id',
168 23
            'Gewaer\Models\UsersAssociatedApps',
169 23
            'companies_id',
170 23
            ['alias' => 'UsersAssociatedApps']
171
        );
172
173
174 23
        $this->hasOne(
175 23
            'id',
176 23
            'Gewaer\Models\CompaniesBranches',
177 23
            'companies_id',
178
            [
179 23
                'alias' => 'branch',
180
            ]
181
        );
182
183 23
        $this->hasOne(
184 23
            'id',
185 23
            'Gewaer\Models\UserCompanyApps',
186 23
            'companies_id',
187
            [
188 23
                'alias' => 'app',
189
                'params' => [
190 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId()
191
                ]
192
            ]
193
        );
194
195 23
        $this->hasOne(
196 23
            'id',
197 23
            'Gewaer\Models\UserCompanyApps',
198 23
            'companies_id',
199
            [
200 23
                'alias' => 'apps',
201
                'params' => [
202 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId()
203
                ]
204
            ]
205
        );
206
207 23
        $this->hasOne(
208 23
            'id',
209 23
            'Gewaer\Models\Subscription',
210 23
            'companies_id',
211
            [
212 23
                'alias' => 'subscription',
213
                'params' => [
214 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId() . ' AND ends_at is null AND is_deleted = 0 ',
215 23
                    'order' => 'id DESC'
216
                ]
217
            ]
218
        );
219
220 23
        $this->hasMany(
221 23
            'id',
222 23
            'Gewaer\Models\Subscription',
223 23
            'companies_id',
224
            [
225 23
                'alias' => 'subscriptions',
226
                'params' => [
227 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId() . ' AND is_deleted = 0',
228 23
                    'order' => 'id DESC'
229
                ]
230
            ]
231
        );
232
233 23
        $this->hasMany(
234 23
            'id',
235 23
            'Gewaer\Models\UserWebhooks',
236 23
            'companies_id',
237 23
            ['alias' => 'user-webhooks']
238
        );
239
240 23
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
241 23
        $this->hasMany(
242 23
            'id',
243 23
            'Gewaer\Models\FileSystem',
244 23
            'entity_id',
245
            [
246 23
                'alias' => 'filesystem',
247 23
                'conditions' => 'system_modules_id = ?0',
248 23
                'bind' => [$systemModule->getId()]
249
            ]
250
        );
251 23
    }
252
253
    /**
254
     * Model validation
255
     *
256
     * @return void
257
     */
258 5
    public function validation()
259
    {
260 5
        $validator = new Validation();
261
262 5
        $validator->add(
263 5
            'name',
264 5
            new PresenceOf([
265 5
                'model' => $this,
266
                'required' => true,
267
            ])
268
        );
269
270 5
        return $this->validate($validator);
271
    }
272
273
    /**
274
    * Register a company given a user and name
275
    *
276
    * @param  Users  $user
277
    * @param  string $name
278
    * @return Companies
279
    */
280
    public static function register(Users $user, string $name): Companies
281
    {
282
        $company = new self();
283
        $company->name = $name;
284
        $company->users_id = $user->getId();
285
286
        if (!$company->save()) {
287
            throw new Exception(current($company->getMessages()));
288
        }
289
290
        return $company;
291
    }
292
293
    /**
294
     * Returns table name mapped in the model.
295
     *
296
     * @return string
297
     */
298 15
    public function getSource() : string
299
    {
300 15
        return 'companies';
301
    }
302
303
    /**
304
     * Confirm if a user belongs to this current company
305
     *
306
     * @param Users $user
307
     * @return boolean
308
     */
309 2
    public function userAssociatedToCompany(Users $user): bool
310
    {
311 2
        return is_object($this->getUsersAssociatedCompany('users_id =' . $user->getId())) ? true : false;
312
    }
313
314
    /**
315
     * Get the stripe customer id from the
316
     *
317
     * @return ?string
318
     */
319 1
    public function getPaymentGatewayCustomerId(): ?string
320
    {
321 1
        return $this->getSettings(self::PAYMENT_GATEWAY_CUSTOMER_KEY);
322
    }
323
324
    /**
325
     * Before crate company
326
     *
327
     * @return void
328
     */
329 3
    public function beforeCreate()
330
    {
331 3
        parent::beforeCreate();
332
333
       
334 3
        $this->language = $this->getDefaultAppsSettingsByName('language');
335 3
        $this->timezone = $this->getDefaultAppsSettingsByName('timezone');
336 3
        $this->currency_id = Currencies::findFirstByCode($this->getDefaultAppsSettingsByName('currency'))->getId();
337 3
    }
338
339
    /**
340
     * After creating the company
341
     *
342
     * @return void
343
     */
344 3
    public function afterCreate()
345
    {
346 3
        parent::afterCreate();
347
348
        //setup the user notificatoin setting
349 3
        $this->setSettings('notifications', $this->user->email);
350
351
        //multi user asociation
352 3
        $usersAssociatedCompany = new UsersAssociatedCompany();
353 3
        $usersAssociatedCompany->users_id = $this->user->getId();
354 3
        $usersAssociatedCompany->companies_id = $this->getId();
355 3
        $usersAssociatedCompany->identify_id = $this->user->getId();
356 3
        $usersAssociatedCompany->user_active = 1;
357 3
        $usersAssociatedCompany->user_role = 'admin';
358 3
        if (!$usersAssociatedCompany->save()) {
359
            throw new Exception((string)current($usersAssociatedCompany->getMessages()));
360
        }
361
362
        //now thta we setup de company and associated with the user we need to setup this as its default company
363 3
        if (!UserConfig::findFirst(['conditions' => 'users_id = ?0 and name = ?1', 'bind' => [$this->user->getId(), self::DEFAULT_COMPANY]])) {
364 1
            $userConfig = new UserConfig();
365 1
            $userConfig->users_id = $this->user->getId();
366 1
            $userConfig->name = self::DEFAULT_COMPANY;
367 1
            $userConfig->value = $this->getId();
368
369 1
            if (!$userConfig->save()) {
370
                throw new Exception((string)current($userConfig->getMessages()));
371
            }
372
        }
373
374
        // New User Associated Apps
375 3
        $usersAssociatedApp = new UsersAssociatedApps;
376 3
        $usersAssociatedApp->users_id = $this->user->getId();
377 3
        $usersAssociatedApp->companies_id = $this->getId();
378 3
        $usersAssociatedApp->apps_id = $this->di->getApp()->getId();
379 3
        $usersAssociatedApp->identify_id = $this->user->getId();
380 3
        $usersAssociatedApp->user_active = 1;
381 3
        $usersAssociatedApp->user_role = 'admin';
382 3
        if (!$usersAssociatedApp->save()) {
383
            throw new Exception((string)current($usersAssociatedApp->getMessages()));
384
        }
385
386
        /**
387
         * @var CompaniesBranches
388
         */
389 3
        $branch = new CompaniesBranches();
390 3
        $branch->companies_id = $this->getId();
391 3
        $branch->users_id = $this->user->getId();
392 3
        $branch->name = 'Default';
393 3
        $branch->is_default = 1;
394 3
        $branch->description = '';
395 3
        if (!$branch->save()) {
396
            throw new ServerErrorHttpException((string)current($branch->getMessages()));
397
        }
398
399
        //look for the default plan for this app
400 3
        $companyApps = new UserCompanyApps();
401 3
        $companyApps->companies_id = $this->getId();
402 3
        $companyApps->apps_id = $this->di->getApp()->getId();
403
        //$companyApps->subscriptions_id = 0;
404
405
        //we need to assign this company to a plan
406 3
        if (empty($this->appPlanId)) {
407 3
            $plan = AppsPlans::getDefaultPlan();
408 3
            $companyApps->stripe_id = $plan->stripe_id;
409
        }
410
411
        //If the newly created company is not the default then we create a new subscription with the same user
412 3
        if ($this->di->getUserData()->default_company != $this->getId()) {
413 3
            $this->setSettings(self::PAYMENT_GATEWAY_CUSTOMER_KEY, $this->startFreeTrial());
414
        }
415
416 3
        $companyApps->subscriptions_id = $this->subscription->getId();
0 ignored issues
show
Bug Best Practice introduced by
The property subscription does not exist on Gewaer\Models\Companies. Since you implemented __get, consider adding a @property annotation.
Loading history...
417 3
        $companyApps->created_at = date('Y-m-d H:i:s');
418 3
        $companyApps->is_deleted = 0;
419
420 3
        if (!$companyApps->save()) {
421
            throw new ServerErrorHttpException((string)current($companyApps->getMessages()));
422
        }
423 3
    }
424
425
    /**
426
     * Get the default company the users has selected
427
     *
428
     * @param  Users  $user
429
     * @return Companies
430
     */
431
    public static function getDefaultByUser(Users $user): Companies
432
    {
433
        //verify the user has a default company
434
        $defaultCompany = UserConfig::findFirst([
435
            'conditions' => 'users_id = ?0 and name = ?1',
436
            'bind' => [$user->getId(), self::DEFAULT_COMPANY],
437
        ]);
438
439
        //found it
440
        if (is_object($defaultCompany)) {
441
            return self::findFirst($defaultCompany->value);
442
        }
443
444
        //second try
445
        $defaultCompany = UsersAssociatedCompany::findFirst([
446
            'conditions' => 'users_id = ?0 and user_active =?1',
447
            'bind' => [$user->getId(), 1],
448
        ]);
449
450
        if (is_object($defaultCompany)) {
451
            return self::findFirst($defaultCompany->companies_id);
452
        }
453
454
        throw new Exception(_("User doesn't have an active company"));
455
    }
456
457
    /**
458
     * After the model was update we need to update its custom fields
459
     *
460
     * @return void
461
     */
462 3
    public function afterUpdate()
463
    {
464
        //only clean and change custom fields if they are been sent
465 3
        if (!empty($this->customFields)) {
466
            //replace old custom with new
467 1
            $allCustomFields = $this->getAllCustomFields();
468 1
            if (is_array($allCustomFields)) {
469 1
                foreach ($this->customFields as $key => $value) {
470 1
                    $allCustomFields[$key] = $value;
471
                }
472
            }
473
474 1
            if (!empty($allCustomFields)) {
475
                //set
476 1
                $this->setCustomFields($allCustomFields);
477
                //clean old
478 1
                $this->cleanCustomFields($this->getId());
479
                //save new
480 1
                $this->saveCustomFields();
481
            }
482
        }
483 3
    }
484
485
    /**
486
     * Start a free trial for a new company
487
     *
488
     * @return string //the customer id
489
     */
490 3
    public function startFreeTrial() : ?string
491
    {
492 3
        $defaultPlan = AppsPlans::getDefaultPlan();
493 3
        $trialEndsAt = Carbon::now()->addDays($this->di->getApp()->plan->free_trial_dates);
494
495
        //Lets create a new default subscription without payment method
496 3
        $this->user->newSubscription($defaultPlan->name, $defaultPlan->stripe_id, $this, $this->di->getApp())
497 3
                ->trialDays($defaultPlan->free_trial_dates)
498 3
                ->create();
499
500
        //ook for the subscription and update the missing info
501 3
        $subscription = $this->subscription;
0 ignored issues
show
Bug Best Practice introduced by
The property subscription does not exist on Gewaer\Models\Companies. Since you implemented __get, consider adding a @property annotation.
Loading history...
502 3
        $subscription->apps_plans_id = $this->di->getApp()->default_apps_plan_id;
0 ignored issues
show
Bug introduced by
The property apps_plans_id does not seem to exist on Phalcon\Mvc\Model\Resultset.
Loading history...
503 3
        $subscription->trial_ends_days = $trialEndsAt->diffInDays(Carbon::now());
0 ignored issues
show
Bug introduced by
The property trial_ends_days does not seem to exist on Phalcon\Mvc\Model\Resultset.
Loading history...
504 3
        $subscription->is_freetrial = 1;
0 ignored issues
show
Bug introduced by
The property is_freetrial does not seem to exist on Phalcon\Mvc\Model\Resultset.
Loading history...
505 3
        $subscription->is_active = 1;
0 ignored issues
show
Bug introduced by
The property is_active does not seem to exist on Phalcon\Mvc\Model\Resultset.
Loading history...
506
507 3
        if (!$subscription->save()) {
0 ignored issues
show
Bug introduced by
The method save() does not exist on Phalcon\Mvc\Model\Resultset. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

507
        if (!$subscription->/** @scrutinizer ignore-call */ save()) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
508
            throw new ServerErrorHttpException((string)'Subscription for new company couldnt be created ' . current($this->getMessages()));
509
        }
510
511 3
        return $this->user->stripe_id;
512
    }
513
}
514