Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
1.03% covered (danger)
1.03%
1 / 97
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReloadInviteCommand
1.03% covered (danger)
1.03%
1 / 97
50.00% covered (danger)
50.00%
1 / 2
264.16
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
 handle
0.00% covered (danger)
0.00%
0 / 96
0.00% covered (danger)
0.00%
0 / 1
240
1<?php
2
3namespace App\Console\Commands;
4
5use App\Http\Models\Admin\AdminUserInvitation;
6use App\Http\Models\Admin\Company;
7use App\Http\Models\Admin\CompanyGroup;
8use App\Http\Models\Auth\User;
9use App\Http\Models\FlyCutUsage;
10use App\Http\Models\FlyMsgUserDailyUsage;
11use App\Http\Models\UserInfo;
12use App\Services\UserInfo\FlyMsgUserDailyUsageService;
13use App\Services\UserInfo\UserInfoService;
14use Carbon\Carbon;
15use Illuminate\Console\Command;
16use Illuminate\Support\Facades\Log;
17use MongoDB\BSON\UTCDateTime;
18
19class ReloadInviteCommand extends Command
20{
21    public function __construct(
22        public UserInfoService $userInfoService,
23        public FlyMsgUserDailyUsageService $flyMsgUserDailyUsageService
24    ) {
25        parent::__construct();
26    }
27
28    protected $signature = 'app:invite';
29
30    protected $description = 'Update Usage To create daily usage for all users';
31
32    public function handle(): void
33    {
34        $this->info("ReloadInviteCommand started");
35        $totalTimeStartAt = now();
36
37        ini_set('memory_limit', '-1');
38
39        $failed_users = [];
40        $failed_users_count = 0;
41        $added_users_count = 0;
42
43        $users = AdminUserInvitation::where('deleted_at', null)->get();
44
45        $totalUsers = count($users);
46        $this->info("Processing " . $totalUsers . " users");
47
48        $userInfoDispatcher = UserInfo::getEventDispatcher();
49        UserInfo::unsetEventDispatcher();
50
51        $averageProcessingTime = 0;
52
53        foreach ($users as $user) {
54            $processingStartAt = now();
55            try {
56                $hasUser = User::where('email', $user->email)->first();
57
58                if ($hasUser) {
59                    $this->info("User with email {$user->email} already exists, skipping.");
60                    continue;
61                }
62
63                $result = [
64                    'first_name' => '',
65                    'last_name' => '',
66                    'full_name' => '',
67                    'email' => $user->email,
68                    'signup_source' => 'email',
69                    'company_id' => $user->company_id,
70                    'status' => 'Invited',
71                    'user_id' => $user->id,
72                    'company_group_id' => $user->company_group_id,
73                ];
74
75                if (!empty($user['created_at'])) {
76                    $carbonCreationDate = Carbon::parse($user['created_at']);
77                    $result['account_creation_date'] = new UTCDateTime($carbonCreationDate->getTimestamp() * 1000);
78                    $result['user_created_at'] = new UTCDateTime($carbonCreationDate->getTimestamp() * 1000);
79                }
80
81                if (!empty($user['updated_at'])) {
82                    $carbonUpdateDate = Carbon::parse($user['updated_at']);
83                    $result['user_updated_at'] = new UTCDateTime($carbonUpdateDate->getTimestamp() * 1000);
84                }
85
86                if (!empty($user['email'])) {
87                    $result['email_domain'] = strrchr($user->email, "@");
88                    $result['email_domain_count'] = UserInfo::where('email_domain', $result['email_domain'])->count();
89
90                    $userInfoDispatcher = UserInfo::getEventDispatcher();
91                    UserInfo::unsetEventDispatcher();
92
93                    UserInfo::where('email_domain', $result['email_domain'])->update(['email_domain_count' => $result['email_domain_count']]);
94
95                    if ($userInfoDispatcher) {
96                        UserInfo::setEventDispatcher($userInfoDispatcher);
97                    }
98                }
99
100                if (!empty($user['status'])) {
101                    $result['status_date'] = now();
102                }
103
104                $companyName = Company::find($user['company_id'])->name;
105                $result['company'] = $companyName;
106                $result['company_name'] = $companyName;
107
108                if (!empty($user['company_group_id'])) {
109                    $group = CompanyGroup::find($user['company_group_id']);
110                    $parentGroup = CompanyGroup::where('id', $group->parent_id)->first();
111
112                    if ($parentGroup) {
113                        $result['group_id'] = $parentGroup->id;
114                        $result['group_name'] = $parentGroup->name;
115                        $result['subgroup_id'] = $group->id;
116                        $result['subgroup_name'] = $group->name;
117                    } else {
118                        $result['group_id'] = $group->id;
119                        $result['group_name'] = $group->name;
120                    }
121                } else {
122                    $result['group_name'] = null;
123                }
124
125                $result['is_invitation'] = true;
126                $result['is_invite'] = true;
127
128                $userInfo = UserInfo::firstOrNew(['email' => $result['email']]);
129
130                $userInfo->fill($result);
131
132                $user->user_info_id = $userInfo->id;
133                $userInfo->save();
134                $user->save();
135                $added_users_count++;
136            } catch (\Exception $e) {
137                $this->error("Failed to process user {$user->email}" . $e->getMessage());
138                $failed_users[] = [
139                    'user_id' => $user->id,
140                    'email' => $user->email,
141                    'error' => $e->getMessage(),
142                ];
143                $failed_users_count++;
144            }
145
146            $duration = now()->diffInMilliseconds($processingStartAt);
147            $averageDuration = $duration < 180 ? 180 : $duration;
148            if ($averageProcessingTime === 0) {
149                $averageProcessingTime = $averageDuration;
150            } else {
151                $averageProcessingTime = (int) round(($averageProcessingTime + $averageDuration) / 2);
152            }
153
154            if ($duration < 180) {
155                usleep((180 - $duration) * 1000);
156            }
157
158            $totalUsers--;
159            $estimatedTimeLeftSeconds = round(($totalUsers * $averageProcessingTime) / 1000, 2);
160            $estimatedTimeLeftMinutes = round($estimatedTimeLeftSeconds / 60, 2);
161            $this->output->write("\rAverage processing time $averageProcessingTime milliseconds | Percentage: " . round(($totalUsers / count($users)) * 100, 2) . "% | Remaining users: " . $totalUsers . " | Estimated time left: {$estimatedTimeLeftMinutes} minutes.        ", false);
162
163            // test $this->info("Processing user {$user->email} took " . $duration . " diffInMilliseconds");
164            // $this->info("Remaining users: " . $totalUsers . " | Percentage: " . round(($totalUsers / count($users)) * 100, 2) . "%");
165        }
166
167        if ($userInfoDispatcher) {
168            UserInfo::setEventDispatcher($userInfoDispatcher);
169        }
170
171        $totalDurationInMinutes = now()->diffInMinutes($totalTimeStartAt);
172        $totalDurationInSeconds = now()->diffInSeconds($totalTimeStartAt);
173
174        $this->info("ReloadInviteCommand completed");
175        $this->info("Total duration in minutes: {$totalDurationInMinutes}");
176        $this->info("Total duration in seconds: {$totalDurationInSeconds}");
177        $this->info("Completed users: {$added_users_count}");
178        $this->info("Failed users: {$failed_users_count}");
179    }
180}