Test Failed
Pull Request — master (#98)
by Maximo
06:13
created

Companies::validation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 13
ccs 0
cts 11
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Canvas\Models;
5
6
use Phalcon\Validation;
7
use Phalcon\Validation\Validator\PresenceOf;
0 ignored issues
show
Bug introduced by
The type Phalcon\Validation\Validator\PresenceOf was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

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