Test Failed
Pull Request — master (#55)
by Rafael
05:22
created

Companies::beforeCreate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 1
rs 10
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\Models\AppsSettings;
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
32
    const DEFAULT_COMPANY = 'DefaulCompany';
33
    const PAYMENT_GATEWAY_CUSTOMER_KEY = 'payment_gateway_customer_id';
34
35
    /**
36
     *
37
     * @var integer
38
     */
39
    public $id;
40
41
    /**
42
     *
43
     * @var string
44
     */
45
    public $name;
46
47
    /**
48
     *
49
     * @var string
50
     */
51
    public $profile_image;
52
53
    /**
54
     *
55
     * @var string
56
     */
57
    public $website;
58
59
    /**
60
     *
61
     * @var integer
62
     */
63
    public $users_id;
64
65
    /**
66
     *
67
     * @var integer
68
     */
69
    public $has_activities;
70
71
    /**
72
     *
73
     * @var string
74
     */
75
    public $created_at;
76
77
    /**
78
     *
79
     * @var string
80
     */
81
    public $updated_at;
82
83
    /**
84
     *
85
     * @var integer
86
     */
87
    public $is_deleted;
88
89
    /**
90
     * Provide the app plan id
91
     *
92
     * @var integer
93
     */
94
    public $appPlanId = null;
95
96
    /**
97
     *
98
     * @var integer
99
     */
100
    public $currency_id;
101
102
    /**
103
     *
104
     * @var string
105
     */
106
    public $language;
107
108
    /**
109
     *
110
     * @var string
111
     */
112
    public $timezone;
113
114
    /**
115
     *
116
     * @var string
117
     */
118
    public $currency;
119
120
    /**
121
     * Initialize method for model.
122
     */
123 8
    public function initialize()
124
    {
125 8
        $this->setSource('companies');
126
127 8
        $this->belongsTo('users_id', 'Baka\Auth\Models\Users', 'id', ['alias' => 'user']);
128 8
        $this->hasMany('id', 'Baka\Auth\Models\CompanySettings', 'id', ['alias' => 'settings']);
129
130 8
        $this->belongsTo(
131 8
            'users_id',
132 8
            'Gewaer\Models\Users',
133 8
            'id',
134 8
            ['alias' => 'user']
135
        );
136
137 8
        $this->hasMany(
138 8
            'id',
139 8
            'Gewaer\Models\CompaniesBranches',
140 8
            'companies_id',
141 8
            ['alias' => 'branches']
142
        );
143
144 8
        $this->hasMany(
145 8
            'id',
146 8
            'Gewaer\Models\CompaniesCustomFields',
147 8
            'companies_id',
148 8
            ['alias' => 'fields']
149
        );
150
151 8
        $this->hasMany(
152 8
            'id',
153 8
            'Gewaer\CustomFields\CustomFields',
154 8
            'companies_id',
155 8
            ['alias' => 'custom-fields']
156
        );
157
158 8
        $this->hasMany(
159 8
            'id',
160 8
            'Gewaer\Models\UsersAssociatedCompany',
161 8
            'companies_id',
162 8
            ['alias' => 'UsersAssociatedCompany']
163
        );
164
165 8
        $this->hasMany(
166 8
            'id',
167 8
            'Gewaer\Models\UsersAssociatedApps',
168 8
            'companies_id',
169 8
            ['alias' => 'UsersAssociatedApps']
170
        );
171
172
173 8
        $this->hasOne(
174 8
            'id',
175 8
            'Gewaer\Models\CompaniesBranches',
176 8
            'companies_id',
177
            [
178 8
                'alias' => 'branch',
179
            ]
180
        );
181
182 8
        $this->hasOne(
183 8
            'id',
184 8
            'Gewaer\Models\UserCompanyApps',
185 8
            'companies_id',
186
            [
187 8
                'alias' => 'app',
188
                'params' => [
189 8
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId()
190
                ]
191
            ]
192
        );
193
194 8
        $this->hasOne(
195 8
            'id',
196 8
            'Gewaer\Models\UserCompanyApps',
197 8
            'companies_id',
198
            [
199 8
                'alias' => 'apps',
200
                'params' => [
201 8
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId()
202
                ]
203
            ]
204
        );
205
206 8
        $this->hasOne(
207 8
            'id',
208 8
            'Gewaer\Models\Subscription',
209 8
            'companies_id',
210
            [
211 8
                'alias' => 'subscription',
212
                'params' => [
213 8
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId() . ' AND ends_at is null AND is_deleted = 0 ',
214 8
                    'order' => 'id DESC'
215
                ]
216
            ]
217
        );
218
219 8
        $this->hasMany(
220 8
            'id',
221 8
            'Gewaer\Models\Subscription',
222 8
            'companies_id',
223
            [
224 8
                'alias' => 'subscriptions',
225
                'params' => [
226 8
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId() . ' AND is_deleted = 0',
227 8
                    'order' => 'id DESC'
228
                ]
229
            ]
230
        );
231
232 8
        $this->hasMany(
233 8
            'id',
234 8
            'Gewaer\Models\UserWebhooks',
235 8
            'companies_id',
236 8
            ['alias' => 'user-webhooks']
237
        );
238
239 8
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
240 8
        $this->hasMany(
241 8
            'id',
242 8
            'Gewaer\Models\FileSystem',
243 8
            'entity_id',
244
            [
245 8
                'alias' => 'filesystem',
246 8
                'conditions' => 'system_modules_id = ?0',
247 8
                'bind' => [$systemModule->getId()]
248
            ]
249
        );
250 8
    }
251
252
    /**
253
     * Model validation
254
     *
255
     * @return void
256
     */
257
    public function validation()
258
    {
259
        $validator = new Validation();
260
261
        $validator->add(
262
            'name',
263
            new PresenceOf([
264
                'model' => $this,
265
                'required' => true,
266
            ])
267
        );
268
269
        return $this->validate($validator);
270
    }
271
272
    /**
273
    * Register a company given a user and name
274
    *
275
    * @param  Users  $user
276
    * @param  string $name
277
    * @return Companies
278
    */
279
    public static function register(Users $user, string $name): Companies
280
    {
281
        $company = new self();
282
        $company->name = $name;
283
        $company->users_id = $user->getId();
284
285
        if (!$company->save()) {
286
            throw new Exception(current($company->getMessages()));
287
        }
288
289
        return $company;
290
    }
291
292
    /**
293
     * Returns table name mapped in the model.
294
     *
295
     * @return string
296
     */
297 2
    public function getSource() : string
298
    {
299 2
        return 'companies';
300
    }
301
302
    /**
303
     * Confirm if a user belongs to this current company
304
     *
305
     * @param Users $user
306
     * @return boolean
307
     */
308
    public function userAssociatedToCompany(Users $user): bool
309
    {
310
        return is_object($this->getUsersAssociatedCompany('users_id =' . $user->getId())) ? true : false;
311
    }
312
313
    /**
314
     * Get the stripe customer id from the
315
     *
316
     * @return ?string
317
     */
318
    public function getPaymentGatewayCustomerId(): ?string
319
    {
320
        return $this->getSettings(self::PAYMENT_GATEWAY_CUSTOMER_KEY);
321
    }
322
323
    /**
324
     * Before crate company
325
     *
326
     * @return void
327
     */
328 1
    public function beforeCreate()
329
    {
330 1
        parent::beforeCreate();
331
332
333 1
        $this->language = $this->di->getApp()->getSettings('language');
334 1
        $this->timezone = $this->di->getApp()->getSettings('timezone');
335 1
        $this->currency_id = Currencies::findFirstByCode($this->di->getApp()->getSettings('currency'))->getId();
1 ignored issue
show
Bug introduced by
The method findFirstByCode() does not exist on Gewaer\Models\Currencies. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

335
        $this->currency_id = Currencies::/** @scrutinizer ignore-call */ findFirstByCode($this->di->getApp()->getSettings('currency'))->getId();
Loading history...
336
    }
337
338
    /**
339
     * After creating the company
340
     *
341
     * @return void
342
     */
343
    public function afterCreate()
344
    {
345
        parent::afterCreate();
346
347
        //setup the user notificatoin setting
348
        $this->setSettings('notifications', $this->user->email);
349
350
        //multi user asociation
351
        $usersAssociatedCompany = new UsersAssociatedCompany();
352
        $usersAssociatedCompany->users_id = $this->user->getId();
353
        $usersAssociatedCompany->companies_id = $this->getId();
354
        $usersAssociatedCompany->identify_id = $this->user->getId();
355
        $usersAssociatedCompany->user_active = 1;
356
        $usersAssociatedCompany->user_role = 'admin';
357
        if (!$usersAssociatedCompany->save()) {
358
            throw new Exception((string)current($usersAssociatedCompany->getMessages()));
359
        }
360
361
        //now thta we setup de company and associated with the user we need to setup this as its default company
362
        if (!UserConfig::findFirst(['conditions' => 'users_id = ?0 and name = ?1', 'bind' => [$this->user->getId(), self::DEFAULT_COMPANY]])) {
363
            $userConfig = new UserConfig();
364
            $userConfig->users_id = $this->user->getId();
365
            $userConfig->name = self::DEFAULT_COMPANY;
366
            $userConfig->value = $this->getId();
367
368
            if (!$userConfig->save()) {
369
                throw new Exception((string)current($userConfig->getMessages()));
370
            }
371
        }
372
373
        // New User Associated Apps
374
        $usersAssociatedApp = new UsersAssociatedApps;
375
        $usersAssociatedApp->users_id = $this->user->getId();
376
        $usersAssociatedApp->companies_id = $this->getId();
377
        $usersAssociatedApp->apps_id = $this->di->getApp()->getId();
378
        $usersAssociatedApp->identify_id = $this->user->getId();
379
        $usersAssociatedApp->user_active = 1;
380
        $usersAssociatedApp->user_role = 'admin';
381
        if (!$usersAssociatedApp->save()) {
382
            throw new Exception((string)current($usersAssociatedApp->getMessages()));
383
        }
384
385
        /**
386
         * @var CompaniesBranches
387
         */
388
        $branch = new CompaniesBranches();
389
        $branch->companies_id = $this->getId();
390
        $branch->users_id = $this->user->getId();
391
        $branch->name = 'Default';
392
        $branch->is_default = 1;
393
        $branch->description = '';
394
        if (!$branch->save()) {
395
            throw new ServerErrorHttpException((string)current($branch->getMessages()));
396
        }
397
398
        //look for the default plan for this app
399
        $companyApps = new UserCompanyApps();
400
        $companyApps->companies_id = $this->getId();
401
        $companyApps->apps_id = $this->di->getApp()->getId();
402
        //$companyApps->subscriptions_id = 0;
403
404
        //we need to assign this company to a plan
405
        if (empty($this->appPlanId)) {
406
            $plan = AppsPlans::getDefaultPlan();
407
            $companyApps->stripe_id = $plan->stripe_id;
408
        }
409
410
        //If the newly created company is not the default then we create a new subscription with the same user
411
        if ($this->di->getUserData()->default_company != $this->getId()) {
412
            $this->setSettings(self::PAYMENT_GATEWAY_CUSTOMER_KEY, $this->startFreeTrial());
413
        }
414
415
        $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...
416
        $companyApps->created_at = date('Y-m-d H:i:s');
417
        $companyApps->is_deleted = 0;
418
419
        if (!$companyApps->save()) {
420
            throw new ServerErrorHttpException((string)current($companyApps->getMessages()));
421
        }
422
    }
423
424
    /**
425
     * Get the default company the users has selected
426
     *
427
     * @param  Users  $user
428
     * @return Companies
429
     */
430
    public static function getDefaultByUser(Users $user): Companies
431
    {
432
        //verify the user has a default company
433
        $defaultCompany = UserConfig::findFirst([
434
            'conditions' => 'users_id = ?0 and name = ?1',
435
            'bind' => [$user->getId(), self::DEFAULT_COMPANY],
436
        ]);
437
438
        //found it
439
        if (is_object($defaultCompany)) {
440
            return self::findFirst($defaultCompany->value);
441
        }
442
443
        //second try
444
        $defaultCompany = UsersAssociatedCompany::findFirst([
445
            'conditions' => 'users_id = ?0 and user_active =?1',
446
            'bind' => [$user->getId(), 1],
447
        ]);
448
449
        if (is_object($defaultCompany)) {
450
            return self::findFirst($defaultCompany->companies_id);
451
        }
452
453
        throw new Exception(_("User doesn't have an active company"));
454
    }
455
456
    /**
457
     * After the model was update we need to update its custom fields
458
     *
459
     * @return void
460
     */
461
    public function afterUpdate()
462
    {
463
        //only clean and change custom fields if they are been sent
464
        if (!empty($this->customFields)) {
465
            //replace old custom with new
466
            $allCustomFields = $this->getAllCustomFields();
467
            if (is_array($allCustomFields)) {
468
                foreach ($this->customFields as $key => $value) {
469
                    $allCustomFields[$key] = $value;
470
                }
471
            }
472
473
            if (!empty($allCustomFields)) {
474
                //set
475
                $this->setCustomFields($allCustomFields);
476
                //clean old
477
                $this->cleanCustomFields($this->getId());
478
                //save new
479
                $this->saveCustomFields();
480
            }
481
        }
482
    }
483
484
    /**
485
     * Start a free trial for a new company
486
     *
487
     * @return string //the customer id
488
     */
489
    public function startFreeTrial() : ?string
490
    {
491
        $defaultPlan = AppsPlans::getDefaultPlan();
492
        $trialEndsAt = Carbon::now()->addDays($this->di->getApp()->plan->free_trial_dates);
493
494
        //Lets create a new default subscription without payment method
495
        $this->user->newSubscription($defaultPlan->name, $defaultPlan->stripe_id, $this, $this->di->getApp())
496
                ->trialDays($defaultPlan->free_trial_dates)
497
                ->create();
498
499
        //ook for the subscription and update the missing info
500
        $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...
501
        $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...
502
        $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...
503
        $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...
504
        $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...
505
506
        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

506
        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...
507
            throw new ServerErrorHttpException((string)'Subscription for new company couldnt be created ' . current($this->getMessages()));
508
        }
509
510
        return $this->user->stripe_id;
511
    }
512
}
513