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

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