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

Companies::getPaymentGatewayCustomerId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
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\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
     * System Module Id
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected '*', expecting T_FUNCTION or T_CONST on line 123 at column 5
Loading history...
124
     * @var integer
125
     */
126
    private $system_modules_id = 1;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $system_modules_id.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

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