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

452
        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...
453
            throw new ServerErrorHttpException((string)'Subscription for new company couldnt be created ' . current($this->getMessages()));
454
        }
455
456 3
        return $this->user->stripe_id;
457
    }
458
}
459