Passed
Pull Request — master (#75)
by Rafael
06:24
created

Companies::getDefaultByUser()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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