Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
1.20% covered (danger)
1.20%
1 / 83
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ReloadCommand
1.20% covered (danger)
1.20%
1 / 83
50.00% covered (danger)
50.00%
1 / 2
150.86
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 / 82
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2
3namespace App\Console\Commands;
4
5use App\Http\Models\Auth\User;
6use App\Http\Models\FlyCutUsage;
7use App\Http\Models\FlyMsgUserDailyUsage;
8use App\Http\Models\UserInfo;
9use App\Services\UserInfo\FlyMsgUserDailyUsageService;
10use App\Services\UserInfo\UserInfoService;
11use Illuminate\Console\Command;
12use Illuminate\Support\Facades\Log;
13use MongoDB\BSON\UTCDateTime;
14
15class ReloadCommand extends Command
16{
17    public function __construct(
18        public UserInfoService $userInfoService,
19        public FlyMsgUserDailyUsageService $flyMsgUserDailyUsageService
20    ) {
21        parent::__construct();
22    }
23
24    protected $signature = 'app:reload {perPage} {page} {email}';
25
26    protected $description = 'Update Usage To create daily usage for all users';
27
28    public function handle(): void
29    {
30        $this->info("ReloadCommand started");
31        $totalTimeStartAt = now();
32
33        ini_set('memory_limit', '-1');
34
35        $failed_users = [];
36        $failed_users_count = 0;
37        $added_users_count = 0;
38        $perPage = $this->argument('perPage');
39        $page = $this->argument('page');
40        $email = $this->argument('email');
41
42        $users = User::where('deleted_at', null);
43
44        if ($email !== 'all') {
45            $users = $users->where('email', $email);
46        }
47
48        $users = $users
49            ->skip(($page - 1) * $perPage)
50            ->take($perPage)
51            ->get();
52
53        $totalUsers = count($users);
54        $this->info("Processing " . $totalUsers . " users");
55
56        $userInfoDispatcher = UserInfo::getEventDispatcher();
57        UserInfo::unsetEventDispatcher();
58        $userDispatcher = User::getEventDispatcher();
59        User::unsetEventDispatcher();
60        $dailyDispatcher = FlyMsgUserDailyUsage::getEventDispatcher();
61        FlyMsgUserDailyUsage::unsetEventDispatcher();
62        $flyCutDispatcher = FlyCutUsage::getEventDispatcher();
63        FlyCutUsage::unsetEventDispatcher();
64
65        $averageProcessingTime = 0;
66
67        foreach ($users as $user) {
68            $processingStartAt = now();
69            try {
70                // if (!$user->user_info_id) {
71                $user_info = $this->userInfoService->processUser($user);
72                $user->user_info_id = $user_info->id;
73                $user->save();
74                // }
75                $this->userInfoService->recalculateFlyCutUsage($user->id);
76                $this->flyMsgUserDailyUsageService->processUserUsage($user, false);
77                $this->flyMsgUserDailyUsageService->processUserSummaryUsage($user);
78                $this->userInfoService->pushItToHubspot($user->id, false);
79                $user->last_update_usage_at = new UTCDateTime(now()->getTimestamp() * 1000);
80                $user->save();
81                $added_users_count++;
82            } catch (\Exception $e) {
83                $this->error("Failed to process user {$user->email}" . $e->getMessage());
84                $failed_users[] = [
85                    'user_id' => $user->id,
86                    'email' => $user->email,
87                    'error' => $e->getMessage(),
88                ];
89                $failed_users_count++;
90            }
91
92            $duration = now()->diffInMilliseconds($processingStartAt);
93            $averageDuration = $duration < 180 ? 180 : $duration;
94            if ($averageProcessingTime === 0) {
95                $averageProcessingTime = $averageDuration;
96            } else {
97                $averageProcessingTime = (int) round(($averageProcessingTime + $averageDuration) / 2);
98            }
99
100            if ($duration < 180) {
101                usleep((180 - $duration) * 1000);
102            }
103
104            $totalUsers--;
105            $estimatedTimeLeftSeconds = round(($totalUsers * $averageProcessingTime) / 1000, 2);
106            $estimatedTimeLeftMinutes = round($estimatedTimeLeftSeconds / 60, 2);
107            $this->output->write("\rAverage processing time $averageProcessingTime milliseconds | Percentage: " . round(($totalUsers / count($users)) * 100, 2) . "% | Remaining users: " . $totalUsers . " | Estimated time left: {$estimatedTimeLeftMinutes} minutes.        ", false);
108
109            // test $this->info("Processing user {$user->email} took " . $duration . " diffInMilliseconds");
110            // $this->info("Remaining users: " . $totalUsers . " | Percentage: " . round(($totalUsers / count($users)) * 100, 2) . "%");
111        }
112
113        if ($userInfoDispatcher) {
114            UserInfo::setEventDispatcher($userInfoDispatcher);
115        }
116        if ($userDispatcher) {
117            User::setEventDispatcher($userDispatcher);
118        }
119        if ($dailyDispatcher) {
120            FlyMsgUserDailyUsage::setEventDispatcher($dailyDispatcher);
121        }
122        if ($flyCutDispatcher) {
123            FlyCutUsage::setEventDispatcher($flyCutDispatcher);
124        }
125
126        $totalDurationInMinutes = now()->diffInMinutes($totalTimeStartAt);
127        $totalDurationInSeconds = now()->diffInSeconds($totalTimeStartAt);
128
129        Log::info("ReloadCommand completed", [
130            'completed_users_count' => $added_users_count,
131            'total_duration_in_minutes' => $totalDurationInMinutes,
132            'total_duration_in_seconds' => $totalDurationInSeconds,
133            'failed_users_count' => $failed_users_count,
134            'failed_users' => $failed_users,
135            'totalDurationInMinutes' => $totalDurationInMinutes,
136            'totalDurationInSeconds' => $totalDurationInSeconds,
137        ]);
138
139        $this->info("ReloadCommand completed");
140        $this->info("Total duration in minutes: {$totalDurationInMinutes}");
141        $this->info("Total duration in seconds: {$totalDurationInSeconds}");
142        $this->info("Completed users: {$added_users_count}");
143        $this->info("Failed users: {$failed_users_count}");
144    }
145}