Failed Conditions
Pull Request — master (#55)
by Rafael
06:30
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
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
     * Initialize method for model.
103
     */
104 23
    public function initialize()
105
    {
106 23
        $this->setSource('companies');
107
108 23
        $this->belongsTo('users_id', 'Baka\Auth\Models\Users', 'id', ['alias' => 'user']);
109 23
        $this->hasMany('id', 'Baka\Auth\Models\CompanySettings', 'id', ['alias' => 'settings']);
110
111 23
        $this->belongsTo(
112 23
            'users_id',
113 23
            'Gewaer\Models\Users',
114 23
            'id',
115 23
            ['alias' => 'user']
116
        );
117
118 23
        $this->hasMany(
119 23
            'id',
120 23
            'Gewaer\Models\CompaniesBranches',
121 23
            'companies_id',
122 23
            ['alias' => 'branches']
123
        );
124
125 23
        $this->hasMany(
126 23
            'id',
127 23
            'Gewaer\Models\CompaniesCustomFields',
128 23
            'companies_id',
129 23
            ['alias' => 'fields']
130
        );
131
132 23
        $this->hasMany(
133 23
            'id',
134 23
            'Gewaer\CustomFields\CustomFields',
135 23
            'companies_id',
136 23
            ['alias' => 'custom-fields']
137
        );
138
139 23
        $this->hasMany(
140 23
            'id',
141 23
            'Gewaer\Models\UsersAssociatedCompany',
142 23
            'companies_id',
143 23
            ['alias' => 'UsersAssociatedCompany']
144
        );
145
146 23
        $this->hasOne(
147 23
            'id',
148 23
            'Gewaer\Models\CompaniesBranches',
149 23
            'companies_id',
150
            [
151 23
                'alias' => 'branch',
152
            ]
153
        );
154
155 23
        $this->hasOne(
156 23
            'id',
157 23
            'Gewaer\Models\UserCompanyApps',
158 23
            'companies_id',
159
            [
160 23
                'alias' => 'app',
161
                'params' => [
162 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId()
163
                ]
164
            ]
165
        );
166
167 23
        $this->hasOne(
168 23
            'id',
169 23
            'Gewaer\Models\UserCompanyApps',
170 23
            'companies_id',
171
            [
172 23
                'alias' => 'apps',
173
                'params' => [
174 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId()
175
                ]
176
            ]
177
        );
178
179 23
        $this->hasOne(
180 23
            'id',
181 23
            'Gewaer\Models\Subscription',
182 23
            'companies_id',
183
            [
184 23
                'alias' => 'subscription',
185
                'params' => [
186 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId() . ' AND ends_at is null AND is_deleted = 0 ',
187 23
                    'order' => 'id DESC'
188
                ]
189
            ]
190
        );
191
192 23
        $this->hasMany(
193 23
            'id',
194 23
            'Gewaer\Models\Subscription',
195 23
            'companies_id',
196
            [
197 23
                'alias' => 'subscriptions',
198
                'params' => [
199 23
                    'conditions' => 'apps_id = ' . $this->di->getApp()->getId() . ' AND is_deleted = 0',
200 23
                    'order' => 'id DESC'
201
                ]
202
            ]
203
        );
204
205 23
        $this->hasMany(
206 23
            'id',
207 23
            'Gewaer\Models\UserWebhooks',
208 23
            'companies_id',
209 23
            ['alias' => 'user-webhooks']
210
        );
211
212 23
        $systemModule = SystemModules::getSystemModuleByModelName(self::class);
213 23
        $this->hasMany(
214 23
            'id',
215 23
            'Gewaer\Models\FileSystem',
216 23
            'entity_id',
217
            [
218 23
                'alias' => 'filesystem',
219 23
                'conditions' => 'system_modules_id = ?0',
220 23
                'bind' => [$systemModule->getId()]
221
            ]
222
        );
223 23
    }
224
225
    /**
226
     * Model validation
227
     *
228
     * @return void
229
     */
230 5
    public function validation()
231
    {
232 5
        $validator = new Validation();
233
234 5
        $validator->add(
235 5
            'name',
236 5
            new PresenceOf([
237 5
                'model' => $this,
238
                'required' => true,
239
            ])
240
        );
241
242 5
        return $this->validate($validator);
243
    }
244
245
    /**
246
    * Register a company given a user and name
247
    *
248
    * @param  Users  $user
249
    * @param  string $name
250
    * @return Companies
251
    */
252
    public static function register(Users $user, string $name): Companies
253
    {
254
        $company = new self();
255
        $company->name = $name;
256
        $company->users_id = $user->getId();
257
258
        if (!$company->save()) {
259
            throw new Exception(current($company->getMessages()));
260
        }
261
262
        return $company;
263
    }
264
265
    /**
266
     * Returns table name mapped in the model.
267
     *
268
     * @return string
269
     */
270 15
    public function getSource() : string
271
    {
272 15
        return 'companies';
273
    }
274
275
    /**
276
     * Confirm if a user belongs to this current company
277
     *
278
     * @param Users $user
279
     * @return boolean
280
     */
281 2
    public function userAssociatedToCompany(Users $user): bool
282
    {
283 2
        return is_object($this->getUsersAssociatedCompany('users_id =' . $user->getId())) ? true : false;
284
    }
285
286
    /**
287
     * Get the stripe customer id from the
288
     *
289
     * @return ?string
290
     */
291 1
    public function getPaymentGatewayCustomerId(): ?string
292
    {
293 1
        return $this->getSettings(self::PAYMENT_GATEWAY_CUSTOMER_KEY);
294
    }
295
296
    /**
297
     * Before crate company
298
     *
299
     * @return void
300
     */
301 3
    public function beforeCreate()
302
    {
303 3
        parent::beforeCreate();
304
305
       
306 3
        $this->language = AppsSettings::getDefaultAppsSettingsByName('language');
0 ignored issues
show
Bug Best Practice introduced by
The property language does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
307 3
        $this->timezone = AppsSettings::getDefaultAppsSettingsByName('timezone');
0 ignored issues
show
Bug Best Practice introduced by
The property timezone does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
308 3
        $this->currency = Currencies::findFirstByCode(AppsSettings::getDefaultAppsSettingsByName('currency'))->getId();
1 ignored issue
show
Bug Best Practice introduced by
The property currency does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
The method findFirstByCode() does not exist on Gewaer\Models\Currencies. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

308
        $this->currency = Currencies::/** @scrutinizer ignore-call */ findFirstByCode(AppsSettings::getDefaultAppsSettingsByName('currency'))->getId();
Loading history...
309 3
    }
310
311
    /**
312
     * After creating the company
313
     *
314
     * @return void
315
     */
316 3
    public function afterCreate()
317
    {
318 3
        parent::afterCreate();
319
320
        //setup the user notificatoin setting
321 3
        $this->setSettings('notifications', $this->user->email);
322
323
        //multi user asociation
324 3
        $usersAssociatedCompany = new UsersAssociatedCompany();
325 3
        $usersAssociatedCompany->users_id = $this->user->getId();
326 3
        $usersAssociatedCompany->companies_id = $this->getId();
327 3
        $usersAssociatedCompany->identify_id = $this->user->getId();
328 3
        $usersAssociatedCompany->user_active = 1;
329 3
        $usersAssociatedCompany->user_role = 'admin';
330 3
        if (!$usersAssociatedCompany->save()) {
331
            throw new Exception((string)current($usersAssociatedCompany->getMessages()));
332
        }
333
334
        //now thta we setup de company and associated with the user we need to setup this as its default company
335 3
        if (!UserConfig::findFirst(['conditions' => 'users_id = ?0 and name = ?1', 'bind' => [$this->user->getId(), self::DEFAULT_COMPANY]])) {
336 1
            $userConfig = new UserConfig();
337 1
            $userConfig->users_id = $this->user->getId();
338 1
            $userConfig->name = self::DEFAULT_COMPANY;
339 1
            $userConfig->value = $this->getId();
340
341 1
            if (!$userConfig->save()) {
342
                throw new Exception((string)current($userConfig->getMessages()));
343
            }
344
        }
345
346
        /**
347
         * @var CompaniesBranches
348
         */
349 3
        $branch = new CompaniesBranches();
350 3
        $branch->companies_id = $this->getId();
351 3
        $branch->users_id = $this->user->getId();
352 3
        $branch->name = 'Default';
353 3
        $branch->is_default = 1;
354 3
        $branch->description = '';
355 3
        if (!$branch->save()) {
356
            throw new ServerErrorHttpException((string)current($branch->getMessages()));
357
        }
358
359
        //look for the default plan for this app
360 3
        $companyApps = new UserCompanyApps();
361 3
        $companyApps->companies_id = $this->getId();
362 3
        $companyApps->apps_id = $this->di->getApp()->getId();
363
        //$companyApps->subscriptions_id = 0;
364
365
        //we need to assign this company to a plan
366 3
        if (empty($this->appPlanId)) {
367 3
            $plan = AppsPlans::getDefaultPlan();
368 3
            $companyApps->stripe_id = $plan->stripe_id;
369
        }
370
371
        //If the newly created company is not the default then we create a new subscription with the same user
372 3
        if ($this->di->getUserData()->default_company != $this->getId()) {
373 3
            $this->setSettings(self::PAYMENT_GATEWAY_CUSTOMER_KEY, $this->startFreeTrial());
374
        }
375
376 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...
377 3
        $companyApps->created_at = date('Y-m-d H:i:s');
378 3
        $companyApps->is_deleted = 0;
379
380 3
        if (!$companyApps->save()) {
381
            throw new ServerErrorHttpException((string)current($companyApps->getMessages()));
382
        }
383 3
    }
384
385
    /**
386
     * Get the default company the users has selected
387
     *
388
     * @param  Users  $user
389
     * @return Companies
390
     */
391
    public static function getDefaultByUser(Users $user): Companies
392
    {
393
        //verify the user has a default company
394
        $defaultCompany = UserConfig::findFirst([
395
            'conditions' => 'users_id = ?0 and name = ?1',
396
            'bind' => [$user->getId(), self::DEFAULT_COMPANY],
397
        ]);
398
399
        //found it
400
        if (is_object($defaultCompany)) {
401
            return self::findFirst($defaultCompany->value);
402
        }
403
404
        //second try
405
        $defaultCompany = UsersAssociatedCompany::findFirst([
406
            'conditions' => 'users_id = ?0 and user_active =?1',
407
            'bind' => [$user->getId(), 1],
408
        ]);
409
410
        if (is_object($defaultCompany)) {
411
            return self::findFirst($defaultCompany->companies_id);
412
        }
413
414
        throw new Exception(_("User doesn't have an active company"));
415
    }
416
417
    /**
418
     * After the model was update we need to update its custom fields
419
     *
420
     * @return void
421
     */
422 3
    public function afterUpdate()
423
    {
424
        //only clean and change custom fields if they are been sent
425 3
        if (!empty($this->customFields)) {
426
            //replace old custom with new
427 1
            $allCustomFields = $this->getAllCustomFields();
428 1
            if (is_array($allCustomFields)) {
429 1
                foreach ($this->customFields as $key => $value) {
430 1
                    $allCustomFields[$key] = $value;
431
                }
432
            }
433
434 1
            if (!empty($allCustomFields)) {
435
                //set
436 1
                $this->setCustomFields($allCustomFields);
437
                //clean old
438 1
                $this->cleanCustomFields($this->getId());
439
                //save new
440 1
                $this->saveCustomFields();
441
            }
442
        }
443 3
    }
444
445
    /**
446
     * Start a free trial for a new company
447
     *
448
     * @return string //the customer id
449
     */
450 3
    public function startFreeTrial() : ?string
451
    {
452 3
        $defaultPlan = AppsPlans::getDefaultPlan();
453 3
        $trialEndsAt = Carbon::now()->addDays($this->di->getApp()->plan->free_trial_dates);
454
455
        //Lets create a new default subscription without payment method
456 3
        $this->user->newSubscription($defaultPlan->name, $defaultPlan->stripe_id, $this, $this->di->getApp())
457 3
                ->trialDays($defaultPlan->free_trial_dates)
458 3
                ->create();
459
460
        //ook for the subscription and update the missing info
461 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...
462 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...
463 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...
464 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...
465 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...
466
467 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

467
        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...
468
            throw new ServerErrorHttpException((string)'Subscription for new company couldnt be created ' . current($this->getMessages()));
469
        }
470
471 3
        return $this->user->stripe_id;
472
    }
473
}
474