Failed Conditions
Push — master ( eb5d54...ba9646 )
by Maximo
02:36
created

Users::currentCompanyBranchId()   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 Gewaer\Traits\PermissionsTrait;
7
use Gewaer\Traits\SubscriptionPlanLimitTrait;
8
use Phalcon\Cashier\Billable;
9
use Gewaer\Exception\ServerErrorHttpException;
10
use Exception;
11
use Carbon\Carbon;
12
use Phalcon\Validation;
13
use Phalcon\Validation\Validator\Email;
14
use Phalcon\Validation\Validator\PresenceOf;
15
use Phalcon\Validation\Validator\Regex;
16
use Phalcon\Validation\Validator\Uniqueness;
17
18
/**
19
 * Class Users
20
 *
21
 * @package Gewaer\Models
22
 *
23
 * @property Users $user
24
 * @property Config $config
25
 * @property Apps $app
26
 * @property Companies $defaultCompany
27
 * @property \Phalcon\Di $di
28
 */
29
class Users extends \Baka\Auth\Models\Users
30
{
31
    use PermissionsTrait;
32
    use Billable;
33
    use SubscriptionPlanLimitTrait;
34
35
    public $default_company_branch;
36
    public $roles_id;
37
    public $stripe_id;
38
    public $card_last_four;
39
    public $card_brand;
40
    public $trial_ends_at;
41
42
    /**
43
     * Provide the app plan id
44
     * if the user is signing up a new company
45
     *
46
     * @var integer
47
     */
48
    public $appPlanId = null;
49
50
    /**
51
     * Initialize method for model.
52
     */
53 45
    public function initialize()
54
    {
55 45
        $this->setSource('users');
56
57
        //overwrite parent relationships
58 45
        $this->hasOne('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'session']);
59 45
        $this->hasMany('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'sessions']);
60 45
        $this->hasMany('id', 'Baka\Auth\Models\SessionKeys', 'users_id', ['alias' => 'sessionKeys']);
61 45
        $this->hasMany('id', 'Baka\Auth\Models\Banlist', 'users_id', ['alias' => 'bans']);
62 45
        $this->hasMany('id', 'Baka\Auth\Models\Sessions', 'users_id', ['alias' => 'sessions']);
63 45
        $this->hasMany('id', 'Gewaer\Models\UserConfig', 'users_id', ['alias' => 'config']);
64 45
        $this->hasMany('id', 'Gewaer\Models\UserLinkedSources', 'users_id', ['alias' => 'sources']);
65 45
        $this->hasMany('id', 'Baka\Auth\Models\UsersAssociatedCompany', 'users_id', ['alias' => 'companies']);
66 45
        $this->hasOne('default_company', 'Gewaer\Models\Companies', 'id', ['alias' => 'defaultCompany']);
67 45
        $this->hasOne('default_company', 'Gewaer\Models\Companies', 'id', ['alias' => 'currentCompany']);
68
69 45
        $this->hasOne(
70 45
            'id',
71 45
            'Gewaer\Models\UserRoles',
72 45
            'users_id',
73 45
            ['alias' => 'permission']
74
        );
75
76 45
        $this->hasMany(
77 45
            'id',
78 45
            'Gewaer\Models\UserRoles',
79 45
            'users_id',
80 45
            ['alias' => 'permissions']
81
        );
82
83 45
        $this->hasManyToMany(
84 45
            'id',
85 45
            'Gewaer\Models\UserRoles',
86 45
            'users_id',
87 45
            'roles_id',
88 45
            'Gewaer\Models\Roles',
89 45
            'id',
90
            [
91 45
                'alias' => 'roles',
92
                'params' => [
93 45
                    'limit' => 1,
94 45
                    'conditions' => 'Gewaer\Models\UserRoles.apps_id = ' . $this->di->getConfig()->app->id,
95
                ]
96
            ]
97
        );
98
99 45
        $this->hasMany(
100 45
            'id',
101 45
            'Gewaer\Models\Subscription',
102 45
            'user_id',
103
            [
104 45
                'alias' => 'allSubscriptions',
105
                'params' => [
106 45
                    'conditions' => 'apps_id = ?0',
107 45
                    'bind' => [$this->di->getApp()->getId()],
108 45
                    'order' => 'id DESC'
109
                ]
110
            ]
111
        );
112
113 45
        $this->hasMany(
114 45
            'id',
115 45
            'Gewaer\Models\UsersAssociatedCompany',
116 45
            'users_id',
117
            [
118 45
                'alias' => 'companies',
119
            ]
120
        );
121 45
    }
122
123
    /**
124
     * Validations and business logic
125
     */
126 3
    public function validation()
127
    {
128 3
        $validator = new Validation();
129 3
        $validator->add(
130 3
            'email',
131 3
            new Email([
132 3
                'field' => 'email',
133
                'required' => true,
134
            ])
135
        );
136
137 3
        $validator->add(
138 3
            'displayname',
139 3
            new PresenceOf([
140 3
                'field' => 'displayname',
141
                'required' => true,
142
            ])
143
        );
144
145 3
        $validator->add(
146 3
            'displayname',
147 3
            new Regex([
148 3
                'field' => 'displayname',
149 3
                'message' => _('Please use alphanumerics only.'),
150 3
                'pattern' => '/^[A-Za-z0-9_-]{1,32}$/',
151
            ])
152
        );
153
154
        // Unique values
155 3
        $validator->add(
156 3
            'email',
157 3
            new Uniqueness([
158 3
                'field' => 'email',
159 3
                'message' => _('This email already has an account.'),
160
            ])
161
        );
162
163 3
        return $this->validate($validator);
164
    }
165
166
    /**
167
     * Returns table name mapped in the model.
168
     *
169
     * @return string
170
     */
171 36
    public function getSource() : string
172
    {
173 36
        return 'users';
174
    }
175
176
    /**
177
     * Get the User key for redis
178
     *
179
     * @return string
180
     */
181
    public function getKey() : string
182
    {
183
        return $this->id;
184
    }
185
186
    /**
187
     * A company owner is the first person that register this company
188
     * This only ocurres when signing up the first time, after that all users invites
189
     * come with a default_company id attached
190
     *
191
     * @return boolean
192
     */
193 3
    public function isFirstSignup(): bool
194
    {
195 3
        return empty($this->default_company) ? true : false;
196
    }
197
198
    /**
199
     * Does the user have a role assign to him?
200
     *
201
     * @return boolean
202
     */
203 7
    public function hasRole(): bool
204
    {
205 7
        return !empty($this->roles_id) ? true : false;
206
    }
207
208
    /**
209
     * Get all of the subscriptions for the user.
210
     */
211 3
    public function subscriptions()
212
    {
213 3
        $this->hasMany(
214 3
            'id',
215 3
            'Gewaer\Models\Subscription',
216 3
            'user_id',
217
            [
218 3
                'alias' => 'subscriptions',
219
                'params' => [
220 3
                    'conditions' => 'apps_id = ?0 and companies_id = ?1',
221 3
                    'bind' => [$this->di->getApp()->getId(), $this->default_company],
222 3
                    'order' => 'id DESC'
223
                ]
224
            ]
225
        );
226
227 3
        return $this->getRelated('subscriptions');
228
    }
229
230
    /**
231
     * Strat a free trial
232
     *
233
     * @param Users $user
234
     * @return Subscription
235
     */
236 1
    public function startFreeTrial() : Subscription
237
    {
238 1
        $defaultPlan = AppsPlans::getDefaultPlan();
239
240 1
        $subscription = new Subscription();
241 1
        $subscription->user_id = $this->getId();
242 1
        $subscription->companies_id = $this->default_company;
243 1
        $subscription->apps_id = $this->di->getApp()->getId();
244 1
        $subscription->apps_plans_id = $this->di->getApp()->default_apps_plan_id;
245 1
        $subscription->name = $defaultPlan->name;
246 1
        $subscription->stripe_id = $defaultPlan->stripe_id;
247 1
        $subscription->stripe_plan = $defaultPlan->stripe_plan;
248 1
        $subscription->quantity = 1;
249 1
        $subscription->trial_ends_at = Carbon::now()->addDays($this->di->getApp()->plan->free_trial_dates)->toDateTimeString();
250
251 1
        if (!$subscription->save()) {
252
            throw new ServerErrorHttpException((string)current($this->getMessages()));
253
        }
254
255 1
        $this->trial_ends_at = $subscription->trial_ends_at;
256 1
        $this->update();
257
258 1
        return $subscription;
259
    }
260
261
    /**
262
     * Before create
263
     *
264
     * @return void
265
     */
266 3
    public function beforeCreate()
267
    {
268 3
        parent::beforeCreate();
269
270
        //this is only empty when creating a new user
271 3
        if (!$this->isFirstSignup()) {
272
            //confirm if the app reach its limit
273 2
            $this->isAtLimit();
274
        }
275
276
        //Assign admin role to the system if we dont get a specify role
277 3
        if (!$this->hasRole()) {
278 1
            $role = Roles::findFirstByName('Admins');
279 1
            $this->roles_id = $role->getId();
280
        }
281 3
    }
282
283
    /**
284
     * Get an array of the associates companies Ids
285
     *
286
     * @return array
287
     */
288 6
    public function getAssociatedCompanies(): array
289
    {
290
        return array_map(function ($company) {
291 6
            return $company['companies_id'];
292 6
        }, $this->getCompanies(['columns' => 'companies_id'])->toArray());
1 ignored issue
show
Bug introduced by
The method getCompanies() does not exist on Gewaer\Models\Users. Since you implemented __call, 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

292
        }, $this->/** @scrutinizer ignore-call */ getCompanies(['columns' => 'companies_id'])->toArray());
Loading history...
293
    }
294
295
    /**
296
     * What the current company the users is logged in with
297
     * in this current session?
298
     *
299
     * @return integer
300
     */
301 24
    public function currentCompanyId(): int
302
    {
303 24
        return (int) $this->default_company;
304
    }
305
306
    /**
307
     * What the current company brach the users is logged in with
308
     * in this current session?
309
     *
310
     * @return integer
311
     */
312 1
    public function currentCompanyBranchId(): int
313
    {
314 1
        return (int) $this->default_company_branch;
315
    }
316
317
    /**
318
     * What to do after the creation of a new users
319
     *  - Assign default role
320
     *
321
     * @return void
322
     */
323 3
    public function afterCreate()
324
    {
325
        //need to run it here, since we overwirte the default_company id and null this function objective
326 3
        $isFirstSignup = $this->isFirstSignup();
327
328
        /**
329
         * User signing up for a new app / plan
330
         * How do we know? well he doesnt have a default_company
331
         */
332 3
        if ($isFirstSignup) {
333 1
            $company = new Companies();
334 1
            $company->name = $this->defaultCompanyName;
335 1
            $company->users_id = $this->getId();
336
337 1
            if (!$company->save()) {
338
                throw new Exception(current($company->getMessages()));
339
            }
340
341 1
            $this->default_company = $company->getId();
342
343 1
            if (!$this->update()) {
344
                throw new ServerErrorHttpException((string) current($this->getMessages()));
345
            }
346
347 1
            $this->default_company_branch = $this->defaultCompany->branch->getId();
348 1
            $this->update();
349
350
            //update default subscription free trial
351 1
            $company->app->subscriptions_id = $this->startFreeTrial()->getId();
352 1
            $company->update();
353
        } else {
354
            //we have the company id
355 2
            if (empty($this->default_company_branch)) {
356
                $this->default_company_branch = $this->defaultCompany->branch->getId();
357
            }
358
        }
359
360
        //Create new company associated company
361 3
        $newUserAssocCompany = new UsersAssociatedCompany();
362 3
        $newUserAssocCompany->users_id = $this->id;
363 3
        $newUserAssocCompany->companies_id = $this->default_company;
364 3
        $newUserAssocCompany->identify_id = 1;
365 3
        $newUserAssocCompany->user_active = 1;
366 3
        $newUserAssocCompany->user_role = $this->roles_id == 1 ? 'admins' : 'users';
367
368 3
        if (!$newUserAssocCompany->save()) {
369
            throw new ServerErrorHttpException((string)current($newUserAssocCompany->getMessages()));
370
        }
371
372
        //Insert record into user_roles
373 3
        $userRole = new UserRoles();
374 3
        $userRole->users_id = $this->id;
375 3
        $userRole->roles_id = $this->roles_id;
376 3
        $userRole->apps_id = $this->di->getApp()->getId();
377 3
        $userRole->companies_id = $this->default_company;
378
379 3
        if (!$userRole->save()) {
380
            throw new ServerErrorHttpException((string)current($userRole->getMessages()));
381
        }
382
383
        //update user activity when its not a empty user
384 3
        if (!$isFirstSignup) {
385 2
            $this->updateAppActivityLimit();
386
        }
387 3
    }
388
}
389