Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.23% |
1 / 434 |
|
4.76% |
1 / 21 |
CRAP | |
0.00% |
0 / 1 |
AdminUsersService | |
0.23% |
1 / 434 |
|
4.76% |
1 / 21 |
18504.44 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getUsersPaginated | |
0.00% |
0 / 116 |
|
0.00% |
0 / 1 |
702 | |||
deleteUsers | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
42 | |||
unassignUsers | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
42 | |||
deleteInvitation | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
30 | |||
delete | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
2 | |||
unassign | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
42 | |||
deleteUser | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
unassignUser | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
deactivateUsers | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
20 | |||
deactivateUser | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
42 | |||
deactivateUserBulk | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
56 | |||
deactivateInvitedUser | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
deleteInvitedUser | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
moveUsersToGroup | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
20 | |||
moveUserToGroup | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
20 | |||
moveInvitationUserToGroup | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
acceptMoveToInvitation | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
90 | |||
acceptUserInvitation | |
0.00% |
0 / 69 |
|
0.00% |
0 / 1 |
702 | |||
rejectUserInvitation | |
0.00% |
0 / 44 |
|
0.00% |
0 / 1 |
240 | |||
createUserForInvitationLogin | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace App\Http\Services\Admin\Users; |
4 | |
5 | use App\Actions\AccountCenter\Reporting\AccountCenterReporting; |
6 | use App\Actions\Users\CancelUserPlanAction; |
7 | use App\Actions\Users\UpdateUserPlanAction; |
8 | use App\Events\User\Registered; |
9 | use App\Exceptions\ExpectedException; |
10 | use App\Http\Models\Admin\AdminUserInvitation; |
11 | use App\Http\Models\Admin\Company; |
12 | use App\Http\Models\Admin\CompanyGroup; |
13 | use App\Http\Models\Admin\CompanyLicenses; |
14 | use App\Http\Models\Auth\LinkedSocialAccount; |
15 | use App\Http\Models\Auth\LoginHistory; |
16 | use App\Http\Models\Auth\LogoutHistory; |
17 | use App\Http\Models\Auth\Role; |
18 | use App\Http\Models\Auth\User; |
19 | use App\Http\Models\Plans; |
20 | use App\Http\Models\UserInfo; |
21 | use App\Http\Repositories\InstancyRepository; |
22 | use App\Http\Repositories\InstancyUserDTO; |
23 | use Carbon\Carbon; |
24 | use Illuminate\Support\Facades\Queue; |
25 | use App\Http\Models\UserPasswordReset; |
26 | use App\Http\Services\InstancyServiceV2; |
27 | use Illuminate\Support\Facades\Log; |
28 | use MongoDB\BSON\UTCDateTime; |
29 | use App\Jobs\Emails\DeactivateUserNotification; |
30 | use App\Events\InstancyUserUpdate; |
31 | use App\Services\Email\EmailService; |
32 | |
33 | class 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 | } |