Test Failed
Pull Request — master (#70)
by Rafael
07:26 queued 02:00
created

Companies   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 486
Duplicated Lines 0 %

Test Coverage

Coverage 87.5%

Importance

Changes 0
Metric Value
wmc 25
eloc 195
dl 0
loc 486
ccs 161
cts 184
cp 0.875
rs 10
c 0
b 0
f 0

11 Methods

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