Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.23% covered (danger)
0.23%
1 / 434
4.76% covered (danger)
4.76%
1 / 21
CRAP
0.00% covered (danger)
0.00%
0 / 1
AdminUsersService
0.23% covered (danger)
0.23%
1 / 434
4.76% covered (danger)
4.76%
1 / 21
18504.44
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUsersPaginated
0.00% covered (danger)
0.00%
0 / 116
0.00% covered (danger)
0.00%
0 / 1
702
 deleteUsers
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
42
 unassignUsers
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
42
 deleteInvitation
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
30
 delete
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
2
 unassign
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
42
 deleteUser
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 unassignUser
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 deactivateUsers
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 deactivateUser
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
42
 deactivateUserBulk
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
56
 deactivateInvitedUser
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 deleteInvitedUser
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 moveUsersToGroup
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
20
 moveUserToGroup
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
20
 moveInvitationUserToGroup
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 acceptMoveToInvitation
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
90
 acceptUserInvitation
0.00% covered (danger)
0.00%
0 / 69
0.00% covered (danger)
0.00%
0 / 1
702
 rejectUserInvitation
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 1
240
 createUserForInvitationLogin
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace App\Http\Services\Admin\Users;
4
5use App\Actions\AccountCenter\Reporting\AccountCenterReporting;
6use App\Actions\Users\CancelUserPlanAction;
7use App\Actions\Users\UpdateUserPlanAction;
8use App\Events\User\Registered;
9use App\Exceptions\ExpectedException;
10use App\Http\Models\Admin\AdminUserInvitation;
11use App\Http\Models\Admin\Company;
12use App\Http\Models\Admin\CompanyGroup;
13use App\Http\Models\Admin\CompanyLicenses;
14use App\Http\Models\Auth\LinkedSocialAccount;
15use App\Http\Models\Auth\LoginHistory;
16use App\Http\Models\Auth\LogoutHistory;
17use App\Http\Models\Auth\Role;
18use App\Http\Models\Auth\User;
19use App\Http\Models\Plans;
20use App\Http\Models\UserInfo;
21use App\Http\Repositories\InstancyRepository;
22use App\Http\Repositories\InstancyUserDTO;
23use Carbon\Carbon;
24use Illuminate\Support\Facades\Queue;
25use App\Http\Models\UserPasswordReset;
26use App\Http\Services\InstancyServiceV2;
27use Illuminate\Support\Facades\Log;
28use MongoDB\BSON\UTCDateTime;
29use App\Jobs\Emails\DeactivateUserNotification;
30use App\Events\InstancyUserUpdate;
31use App\Services\Email\EmailService;
32
33class AdminUsersService extends AccountCenterReporting
34{
35    private string $cantDeactivateOwnAccount = "You cannot deactivate your own account.";
36    private string $cantDeleteOwnAccount = "You cannot delete your own account.";
37    private string $cantUnassignOwnAccount = "You cannot unassign your own account.";
38
39    public function __construct(
40        private CancelUserPlanAction $cancelUserPlanAction,
41        private InstancyRepository $instancyRepository,
42        private readonly UpdateUserPlanAction $updateUserPlanAction,
43        private readonly EmailService $emailService
44    ) {}
45
46    public function getUsersPaginated($filter, $deactivated, $perPage, $page, $categories, $sortBy, $sortOrder, $license_types, $account_status, $extensions)
47    {
48        $account_status = array_filter($account_status);
49        $license_types = array_filter($license_types);
50        $categories = array_filter($categories);
51
52        $usersQuery = UserInfo::select(
53            'user_id',
54            'first_name',
55            'last_name',
56            'full_name',
57            'status',
58            'is_invite',
59            'email',
60            'avatar',
61            'user_created_at',
62            'user_updated_at',
63            'status_date',
64            'company_id',
65            'company_name',
66            'group_id',
67            'group_name',
68            'subgroup_id',
69            'subgroup_name',
70            // 'sales_pro_team_manager',
71            'is_any_extension_installed',
72            'role_names',
73            'plan_name',
74            'created_at'
75        )->where('deleted_at', null);
76
77        if (filled($filter)) {
78            // $escapedFilter = preg_quote($filter, '/');
79            $usersQuery = $usersQuery->where(function ($query) use ($filter) {
80                $query->where('email', 'like', "%$filter%")
81                    ->orWhere('full_name', 'like', "%$filter$")
82                    ->orWhere('user_id', 'like', "%$filter$");
83            });
84        }
85
86        if (count($extensions) > 0) {
87            $string = str_replace('""', 'empty', $extensions[0]);
88            $extensions = array_map('intval', $extensions);
89            if (count($extensions) > 0) {
90                $extensions = array_map('boolval', $extensions);
91                $usersQuery = $usersQuery->whereIn('is_any_extension_installed', $extensions);
92            }
93        }
94
95        $deactivatedCompanies = Company::whereNotNull('deactivated_at')
96            ->pluck('id')
97            ->toArray();
98
99        if (count($account_status) > 0) {
100            $usersQuery = $usersQuery->whereIn('status', $account_status);
101        } elseif ($deactivated) {
102            $usersQuery = $usersQuery->where(function ($query) use ($deactivatedCompanies) {
103                $query->where('status', 'Deactivated')
104                    ->orWhereIn('company_id', $deactivatedCompanies);
105            });
106        } else {
107            $usersQuery = $usersQuery->where(function ($query) use ($deactivatedCompanies) {
108                $query->whereNull('deactivated_at')
109                    ->WhereNotIn('company_id', $deactivatedCompanies);
110            });
111
112            $usersQuery = $usersQuery->whereNotIn('status', ['Deactivated', 'Deleted']);
113        }
114
115        $emails = array_filter($categories, function ($category) {
116            return str_starts_with($category, '@') && $category !== 'all_individuals';
117        });
118
119        $companyIds = array_filter($categories, function ($category) {
120            return !str_starts_with($category, '@') && $category !== 'all_individuals';
121        });
122        $categoriesQuery = [];
123
124        if (in_array('all_individuals', $categories)) {
125            $categoriesQuery[] = function ($query) {
126                $query->whereNull('company_id')->where('email_domain_count', '>', 1);
127            };
128        } elseif (filled($emails) && count($emails) > 0) {
129            foreach ($emails as $email) {
130                $categoriesQuery[] = function ($query) use ($email) {
131                    $query->where('email_domain', $email)
132                        ->whereNull('company_id');
133                };
134            }
135        }
136
137        if (filled($companyIds) && count($companyIds) > 0) {
138            foreach ($companyIds as $companyId) {
139                $categoriesQuery[] = function ($query) use ($companyId) {
140                    $query->where('company_id', $companyId);
141                };
142            }
143        }
144
145        if (!empty($categoriesQuery)) {
146            $usersQuery = $usersQuery->where(function ($query) use ($categoriesQuery) {
147                foreach ($categoriesQuery as $filterQuery) {
148                    $query->orWhere($filterQuery);
149                }
150            });
151        }
152
153        if (count($license_types) > 0) {
154            $usersQuery = $usersQuery->whereIn('plan_id', $license_types);
155
156            $freemiumId = Plans::where('identifier', 'freemium')->first()?->_id;
157            if (in_array($freemiumId, $license_types)) {
158                $usersQuery = $usersQuery->orWhereNull('plan_id');
159            }
160        }
161
162        $skip = ($page - 1) * $perPage;
163        $take = $perPage;
164        $totalUsers = $usersQuery->count();
165        $currentPage = $skip / $take + 1;
166        $totalPages = ceil($totalUsers / $take);
167
168        if (!$sortBy) {
169            $sortBy = 'created_at';
170        }
171
172        if (!$sortOrder) {
173            $sortOrder = 'desc';
174        }
175
176        $sortOrder = $sortOrder == 'desc' ? -1 : 1;
177
178        $sortPipeline = match (true) {
179            $sortBy == 'name' => [
180                ['column' => 'first_name', 'direction' => $sortOrder == 1 ? 'asc' : 'desc'],
181                ['column' => 'last_name', 'direction' => $sortOrder == 1 ? 'asc' : 'desc'],
182                ['column' => 'created_at', 'direction' => 'desc'],
183            ],
184            default => [
185                ['column' => 'created_at', 'direction' => $sortOrder == 1 ? 'asc' : 'desc']
186            ],
187        };
188
189        foreach ($sortPipeline as $sort) {
190            $usersQuery->orderBy($sort['column'], $sort['direction']);
191        }
192
193        $users = $usersQuery->skip($skip)
194            ->take($perPage)
195            ->get();
196
197        return [
198            'users' => $users,
199            'total' => $totalUsers,
200            'total_pages' => $totalPages,
201            'current_page' => $currentPage,
202        ];
203    }
204
205    public function deleteUsers(array $userIds, $adminUser, ?string $company_id)
206    {
207        if (isset($userIds) && in_array($adminUser->id, $userIds)) {
208            throw new ExpectedException($this->cantDeleteOwnAccount);
209        }
210
211        $users = User::whereIn('_id', $userIds)->get();
212
213        foreach ($users as $user) {
214            $this->deleteUser($user, $adminUser, $company_id);
215        }
216
217        $invitations = AdminUserInvitation::whereIn('_id', $userIds)->get();
218
219        if (!empty($invitations)) {
220            foreach ($invitations as $invite) {
221                $this->deleteInvitation($invite);
222            }
223        }
224    }
225
226    public function unassignUsers(array $userIds, $adminUser, ?string $company_id)
227    {
228        if (isset($userIds) && in_array($adminUser->id, $userIds)) {
229            throw new ExpectedException($this->cantUnassignOwnAccount);
230        }
231
232        $users = User::whereIn('_id', $userIds)->get();
233
234        foreach ($users as $user) {
235            $this->unassignUser($user, $adminUser, $company_id);
236        }
237
238        $invitations = AdminUserInvitation::whereIn('_id', $userIds)->get();
239
240        if (!empty($invitations)) {
241            foreach ($invitations as $invite) {
242                $this->deleteInvitation($invite);
243            }
244        }
245    }
246
247    public function deleteInvitation(AdminUserInvitation $invitation)
248    {
249        $invitationSubPlan = $invitation->subscription("invitation");
250
251        $plan = (isset($invitationSubPlan->plan)) ? $invitationSubPlan->plan : '';
252
253        if ($invitation->company_id && $plan && $plan->identifier != Plans::FREEMIUM_IDENTIFIER) {
254            $invitationSubPlan->markAsCancelledOnlyInDB();
255        }
256
257        $invitation->delete();
258    }
259
260    public function delete($user)
261    {
262        $user->deleted_at = Carbon::now()->toDateTimeString();
263        $user->status = "Deleted";
264        $user->save();
265
266        $this->cancelUserPlanAction->execute($user);
267
268        $searchByIdEmail = ['email' => $user->email];
269
270        //force delete for below tables data for the user
271        AdminUserInvitation::where($searchByIdEmail)->forceDelete();
272        LinkedSocialAccount::where($searchByIdEmail)->forceDelete();
273        LoginHistory::where($searchByIdEmail)->forceDelete();
274        LogoutHistory::where($searchByIdEmail)->forceDelete();
275        UserPasswordReset::where($searchByIdEmail)->forceDelete();
276
277        $user->delete();
278
279        // soft delete the users table
280        $user->fill([
281            'first_name' => '',
282            'last_name' => '',
283            'avatar' => '',
284            'email' => "delete_from_flymsg_$user->email",
285            'password' => '',
286            'remember_token' => '',
287            'card_last_four' => '',
288            'card_brand' => '',
289            'team_id' => '',
290            'pm_last_four' => '',
291            'pm_type' => '',
292        ]);
293        $user->save();
294    }
295
296    public function unassign($user)
297    {
298        $userSub = $user->subscription("main");
299        if ($userSub) {
300            $plan = $userSub->plan;
301
302            if (isset($plan->identifier) && $plan->identifier != Plans::FREEMIUM_IDENTIFIER && $userSub->valid()) {
303                if ($user->company_id) {
304                    $userSub->markAsCancelledOnlyInDB();
305                } else {
306                    $userSub->markAsCanceled();
307                }
308            }
309        }
310        $instancyService = new InstancyServiceV2();
311        $instancyService->updateMembership($user->email, now()->toDateString());
312        $user->company_id = '';
313        $user->company_group_id = '';
314        $user->invited_to_company = null;
315        $user->invited_to_company_by_admin = null;
316        $user->status = "Active";
317        $user->save();
318    }
319
320    public function deleteUser(User $user, $adminUser)
321    {
322        if ($user->id == $adminUser->id) {
323            throw new ExpectedException($this->cantDeleteOwnAccount);
324        }
325
326        Log::info('Deleting user: ', [
327            'user' => $user->email,
328            'admin' => $adminUser->email,
329            'date' => Carbon::now()->toDateTimeString(),
330        ]);
331        $this->delete($user);
332    }
333
334    public function unassignUser(User $user, $adminUser)
335    {
336        if ($user->id == $adminUser->id) {
337            throw new ExpectedException($this->cantUnassignOwnAccount);
338        }
339
340        Log::info('Unassign user: ', [
341            'user' => $user->email,
342            'admin' => $adminUser->email,
343            'date' => Carbon::now()->toDateTimeString(),
344        ]);
345        $this->unassign($user);
346    }
347
348    public function deactivateUsers(array $userIds, string $adminUserId, ?string $company_id)
349    {
350        if (isset($userIds) && in_array($adminUserId, $userIds)) {
351            throw new ExpectedException($this->cantDeactivateOwnAccount);
352        }
353
354        $users = User::whereIn('_id', $userIds)->get();
355
356        foreach ($users as $user) {
357            $this->deactivateUser($user, $adminUserId, $company_id);
358        }
359    }
360
361    public function deactivateUser(User $user, string $adminUserId, ?string $company_id, $cancellation_date = null)
362    {
363        if ($user->id == $adminUserId) {
364            throw new ExpectedException($this->cantDeactivateOwnAccount);
365        }
366
367        $user->status = "Deactivated";
368        $user->deactivated_at = Carbon::now()->toDateTimeString();
369        if (!empty($cancellation_date)) {
370            $user->deactivated_at = $cancellation_date->toDateTimeString();
371        }
372
373        $user->company_group_id = null;
374        $user->save();
375
376        $admin = auth()->user();
377        $companyName = $admin->company->name;
378        $companyEmail = $admin->email;
379
380        if ($company_id) {
381            $company = Company::find($user->company_id);
382            $companyLicense = CompanyLicenses::where('company_id', $company->id)->first();
383            $community = $companyLicense->business_pro_enterprise_plus ?? [];
384            $isPro = in_array('yes_dedicated', $community) || in_array('yes_community', $community);
385
386            if ($isPro) {
387                DeactivateUserNotification::dispatch($user->email, $companyEmail, $companyName, $this->emailService)->delay(now()->addSeconds(2));
388            }
389        }
390
391        $this->cancelUserPlanAction->execute($user, true, $cancellation_date);
392    }
393
394    public function deactivateUserBulk(array $userIds, string $adminUserId, string $company_id)
395    {
396        if (isset($userIds) && in_array($adminUserId, $userIds)) {
397            throw new ExpectedException("You cannot deactivate your own account.");
398        }
399
400        $users = User::whereIn('_id', $userIds)->get();
401
402        // create the users ids array those available in users table
403        $existingUsers = User::whereIn('_id', $userIds)->pluck('_id')->toArray();
404
405        // users those not found in users table
406        $invitedUsers = array_diff($userIds, $existingUsers);
407
408        foreach ($users as $user) {
409            $this->deactivateUser($user, $adminUserId, empty($company_id) ? $user->company_id : $company_id);
410        }
411
412        // for the invited users those not yet registered
413        if (!empty($invitedUsers)) {
414            $invitedUsers = AdminUserInvitation::whereIn('_id', $invitedUsers)->get();
415            foreach ($invitedUsers as $invitedUser) {
416                $this->deleteInvitedUser($invitedUser);
417            }
418        }
419    }
420
421    public function deactivateInvitedUser(AdminUserInvitation $user, string $adminUserId)
422    {
423        if ($user->id == $adminUserId) {
424            throw new ExpectedException($this->cantDeactivateOwnAccount);
425        }
426
427        $user->status = "Deactivated";
428        $user->deactivated_at = Carbon::now()->toDateTimeString();
429        $user->company_group_id = null;
430        $user->save();
431    }
432
433    public function deleteInvitedUser(AdminUserInvitation $user)
434    {
435        $user->forceDelete();
436    }
437
438    public function moveUsersToGroup(array $usersId, ?CompanyGroup $group)
439    {
440        $users = User::whereIn('_id', $usersId)->get();
441
442        // create the users ids array those available in users table
443        $existingUsers = User::whereIn('_id', $usersId)->pluck('_id')->toArray();
444
445        // users those not found in users table
446        $invitedUsers = array_diff($usersId, $existingUsers);
447
448        // for main users those are active
449        foreach ($users as $user) {
450            $user = $this->moveUserToGroup($user, $group);
451        }
452
453        // for the invited users those not yet registered
454        if (!empty($invitedUsers)) {
455            $invitedUsers = AdminUserInvitation::whereIn('_id', $invitedUsers)->get();
456            foreach ($invitedUsers as $invitedUser) {
457                $invitedUser = $this->moveInvitationUserToGroup($invitedUser, $group);
458            }
459        }
460
461        return $users;
462    }
463
464    public function moveUserToGroup(User $user, ?CompanyGroup $group)
465    {
466        $user->company_group_id = $group ? $group->id : null;
467        $user->save();
468
469        if ($user->instancy_id) {
470            if ($group) {
471                $newGroup = $group->instancy_id;
472            } else {
473                $newGroup = $user->company->instancy_id;
474            }
475
476            $instancyUser = new InstancyUserDTO(
477                $user->instancy_id,
478                $newGroup,
479                $user->first_name,
480                $user->last_name,
481                $user->email,
482                $user->company->name,
483            );
484
485            //old code
486            //$this->instancyRepository->updateUser($instancyUser);
487            InstancyUserUpdate::dispatch($instancyUser);
488        }
489
490        return $user;
491    }
492
493    public function moveInvitationUserToGroup(AdminUserInvitation $user, ?CompanyGroup $group)
494    {
495        $user->company_group_id = $group ? $group->id : null;
496        $user->save();
497
498        return $user;
499    }
500
501    private function acceptMoveToInvitation(User $user, AdminUserInvitation $invitation)
502    {
503        $user->removeAllRoles();
504        $group_ids = [];
505
506        $planId = $invitation->plan_id;
507        $companyId = $invitation->company_id;
508        $roleName = $invitation->role_name;
509        $groupId = $invitation->company_group_id;
510        $subgroupId = $invitation->company_subgroup_id;
511        $hasCorporatePlan = $invitation->has_corporate_plan;
512        $plan = Plans::find($planId);
513        $companyLicense = CompanyLicenses::where('company_id', $companyId)
514            ->active()
515            ->first();
516
517        if (($roleName == Role::GROUP_ADMIN || $roleName = Role::REPORTING_ADMIN) && ($groupId || $subgroupId)) {
518            $group_ids = [$groupId] ?? [$subgroupId] ?? [];
519        }
520        $user->assignRole($roleName, $group_ids);
521
522        $user->company_id = $companyId;
523        $user->activation_date = Carbon::now()->toDateTimeString();
524        if (filled($groupId)) {
525            $user->company_group_id = $groupId;
526        }
527
528        if (filled($subgroupId)) {
529            $user->company_group_id = $subgroupId;
530        }
531        $user->status = "Active";
532        $user->unset('invited_to_company');
533        $user->unset('invited_to_company_by_admin');
534
535        $this->updateUserPlanAction->execute($user, $plan, $companyLicense->contract_end_date, $hasCorporatePlan);
536
537        if ($invitation) {
538            if ($invitation->reminder_job_id) {
539                Queue::forget($invitation->reminder_job_id);
540                $invitation->reminder_job_id = null;
541                $invitation->save();
542            }
543
544            $invitation->delete();
545        }
546
547        $user->save();
548
549        $user->refresh();
550        return $user;
551    }
552
553    public function acceptUserInvitation(User $user, ?string $company_id)
554    {
555        $invitation = AdminUserInvitation::where('email', $user->email)->withTrashed();
556
557        if ($company_id) {
558            $invitation = $invitation->where('company_id', $company_id);
559        }
560
561        $invitation = $invitation->first();
562
563        if ($invitation->move_assign) {
564            return $this->acceptMoveToInvitation($user, $invitation);
565        }
566
567        if ($invitation && $invitation->deleted_at && $company_id == $invitation->company_id) {
568            $user->unset('invited_to_company');
569            $user->unset('invited_to_company_by_admin');
570            $user->save();
571            return $user;
572        }
573
574        // if (!$invitation) {
575        //     throw new ExpectedException("Invitation not found");
576        // }
577
578        if ($invitation) {
579            $plan = Plans::find($invitation->plan_id);
580            if ($company_id && !$plan) {
581                throw new ExpectedException("The user was invited without a Plan. This shouldn't have happened.");
582            }
583
584            // Change the users plan to the invited one
585            $useSub = $user->subscription('main');
586
587            $changeSubscription = !filled($useSub) || ($useSub->stripe_plan != $plan->stripe_id);
588
589            if ($changeSubscription) {
590                if ($user->subscribed('main')) {
591                    $companyLicense = CompanyLicenses::where('company_id', $user->company_id)
592                        ->active()
593                        ->first();
594                    if (filled($useSub->ends_at) && ($useSub->ends_at == $companyLicense?->contract_end_date)) {
595                        $useSub->update([
596                            'stripe_status' => 'canceled',
597                            'ends_at' => Carbon::now()->toDateTimeString(),
598                        ]);
599                    } else {
600                        $useSub->cancel();
601                    }
602                } else {
603                    $subscription = $user->subscriptions()->latest()->first();
604                    if ($subscription) {
605                        $subscription->update([
606                            'ends_at' => Carbon::now()->toDateTimeString(),
607                            'stripe_status' => 'canceled',
608                        ]);
609                    }
610                }
611            }
612
613            $license = CompanyLicenses::where('company_id', $user->company_id)
614                ->active()
615                ->first();
616
617            if ($company_id && !$license) {
618                throw new ExpectedException("Failed to assign $plan. The company doesn't have any active licenses.");
619            }
620
621            if ($company_id && $changeSubscription) {
622                $user->subscriptions()->create([
623                    'name' => 'main',
624                    'stripe_status' => 'active',
625                    'stripe_plan' => $plan->stripe_id,
626                    'quantity' => "1",
627                    'ends_at' => $license->contract_end_date,
628                    'starts_at' => Carbon::now()->startOfDay()->toDateTimeString(),
629                ]);
630                $license->reduceCompanyLicenseCountForNewUsers($plan);
631            }
632        }
633
634        // Change the users status to Active
635        $user->status = "Active";
636        $user->activation_date = Carbon::now()->toDateTimeString();
637
638        if ($invitation) {
639            if ($invitation->company_group_id) {
640                $user->company_group_id = $invitation->company_group_id;
641            }
642            if ($invitation->company_subgroup_id) {
643                $user->company_group_id = $invitation->company_subgroup_id;
644            }
645        }
646
647        $user->unset('invited_to_company');
648        $user->unset('invited_to_company_by_admin');
649        $user->save();
650
651        if ($invitation) {
652            if ($invitation->reminder_job_id) {
653                Queue::forget($invitation->reminder_job_id);
654                $invitation->reminder_job_id = null;
655                $invitation->save();
656            }
657
658            $invitation->delete();
659        }
660
661        if (isset($plan) && !empty($plan)) {
662            $user->plan = $plan;
663        }
664
665        $user->refresh();
666
667        return $user;
668    }
669
670    public function rejectUserInvitation(User $user, ?string $company_id)
671    {
672        $invitation = AdminUserInvitation::where('email', $user->email)->withTrashed();
673
674        if ($company_id) {
675            $invitation = $invitation->where('company_id', $company_id);
676        }
677
678        $invitation = $invitation->first();
679
680        if ($invitation) {
681            $plan = Plans::find($invitation->plan_id);
682
683            if ($plan) {
684                // Change the users plan to the invited one
685                $useSub = $user->subscription('main');
686
687                $changeSubscription = filled($useSub) && ($useSub->stripe_plan == $plan->stripe_id);
688
689                if ($changeSubscription) {
690                    $companyLicense = CompanyLicenses::where('company_id', $user->company_id)
691                        ->active()
692                        ->first();
693
694                    if ($user->subscribed('main')) {
695                        if (filled($useSub->ends_at) && ($useSub->ends_at == $companyLicense?->contract_end_date)) {
696                            $useSub->update([
697                                'stripe_status' => 'canceled',
698                                'ends_at' => Carbon::now()->toDateTimeString(),
699                            ]);
700                        } else {
701                            $useSub->cancel();
702                        }
703                    } else {
704                        $subscription = $user->subscriptions()->latest()->first();
705                        if ($subscription) {
706                            $subscription->update([
707                                'ends_at' => Carbon::now()->toDateTimeString(),
708                                'stripe_status' => 'canceled',
709                            ]);
710                        }
711                    }
712
713                    if ($changeSubscription && $companyLicense) {
714                        $companyLicense->restoreLicenseCountForDeletedUsers($plan);
715                    }
716                }
717            }
718        }
719
720        // Change the users status to Active
721        $user->status = "Active";
722        $user->unset('activation_date');
723        $user->unset('company_id');
724        $user->unset('company_group_id');
725        $user->unset('invited_to_company');
726        $user->unset('invited_to_company_by_admin');
727        $user->save();
728        // remove roles
729        $user->removeAllRoles();
730
731        if ($invitation) {
732            if ($invitation->reminder_job_id) {
733                Queue::forget($invitation->reminder_job_id);
734                $invitation->reminder_job_id = null;
735                $invitation->save();
736            }
737
738            if (!$invitation->deleted_at) {
739                $invitation->delete();
740            }
741        }
742
743        return $user;
744    }
745
746    public function createUserForInvitationLogin(AdminUserInvitation $invitation)
747    {
748        $user = new User();
749        $user->status = "Invited";
750        $user->email = $invitation->email;
751        $user->first_name = "";
752        $user->last_name = "";
753        $user->password = $invitation->password ?? $invitation->temp_password;
754        $user->temp_password = $invitation->password ?? $invitation->temp_password;
755        $user->company_id = $invitation->company_id;
756        $user->email_verified_at = new UTCDateTime(now()->getTimestamp() * 1000);
757        $user->onboardingv2_presented = true;
758
759        $user->save();
760
761        $data = [
762            "email" => $user->email,
763            "first_name" => $user->first_name,
764            "last_name" => $user->last_name,
765            "do_not_send_welcome_notification" => true
766        ];
767
768        Registered::dispatch($user, $data);
769
770        $user = $this->acceptUserInvitation($user, $invitation->company_id);
771
772        return $user;
773    }
774}