Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
21.37% covered (danger)
21.37%
25 / 117
10.00% covered (danger)
10.00%
1 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
AdminCompaniesPocsService
21.37% covered (danger)
21.37%
25 / 117
10.00% covered (danger)
10.00%
1 / 10
257.32
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
 getPocs
0.00% covered (danger)
0.00%
0 / 10
0.00% covered (danger)
0.00%
0 / 1
12
 addPoc
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 processPocs
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 createNewUser
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 updateExistingUser
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 createPoc
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 sendInvitationMail
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
6
 createAdminUserInvitation
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 removePoc
96.00% covered (success)
96.00%
24 / 25
0.00% covered (danger)
0.00%
0 / 1
7
1<?php
2
3namespace App\Http\Services\Admin\Companies\Pocs;
4
5use App\Helpers\FlyMSGLogger;
6use App\Http\Models\Admin\AdminUserInvitation;
7use App\Http\Models\Admin\Company;
8use App\Http\Models\Admin\CompanyPOC;
9use App\Http\Models\Auth\Role;
10use App\Http\Models\Auth\User;
11use App\Http\Resources\ClientManagementCompanyPocsResource;
12use App\Mail\GlobalAdminInvitationExistentUserMail;
13use App\Mail\GlobalAdminInvitationMail;
14use App\Services\Email\EmailService;
15use App\Traits\CompanyTrait;
16use Carbon\Carbon;
17use Exception;
18use Illuminate\Support\Facades\DB;
19use Illuminate\Support\Str;
20use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
21
22class AdminCompaniesPocsService
23{
24    use CompanyTrait;
25
26    // Injeta os models no construtor
27    public function __construct(
28        protected Company $companyModel,
29        protected CompanyPOC $companyPOCModel,
30        protected EmailService $emailService
31    ) {}
32
33    public function getPocs(string $slug): array
34    {
35        $company = $this->getCompanyBySlug($slug);
36
37        if (empty($company)) {
38            throw new NotFoundHttpException('Company not found');
39        }
40
41        $pocs = CompanyPOC::where('company_id', $company->id)
42            ->with(['user'])->get();
43
44        return [
45            'pocs' => filled($pocs) ? ClientManagementCompanyPocsResource::collection($pocs) : [],
46            'company_slug' => $company->slug,
47            'company_name' => $company->name,
48        ];
49    }
50
51    public function addPoc($slug, $poc): CompanyPOC
52    {
53        $session = DB::getMongoClient()->startSession();
54        $session->startTransaction();
55        try {
56            $company = $this->getCompanyBySlug($slug);
57
58            if (empty($company)) {
59                throw new NotFoundHttpException('Company not found');
60            }
61
62            $companyPoc = $this->processPocs($company->id, $poc);
63
64            $session->commitTransaction();
65
66            return $companyPoc;
67        } catch (\Exception $e) {
68            $session->abortTransaction();
69            FlyMSGLogger::logError(__METHOD__, $e);
70            throw $e;
71        }
72    }
73
74    private function processPocs(string $companyId, array $poc): CompanyPOC
75    {
76
77        $existingUser = User::firstWhere('email', $poc['email']);
78        $password = Str::password(16);
79        $user = $existingUser ?? $this->createNewUser($poc, $companyId, $password);
80
81        if ($existingUser) {
82            $this->updateExistingUser($existingUser, $companyId);
83        }
84
85        $companyPOC = $this->createPoc($companyId, $poc, $user->id);
86        $this->createAdminUserInvitation($poc['email'], $companyId);
87        $this->sendInvitationMail($user, filled($existingUser), $password);
88
89        return $companyPOC;
90    }
91
92    private function createNewUser(array $poc, string $companyId, string $password): User
93    {
94        $hashed_password = bcrypt($password);
95
96        return User::create([
97            'email' => $poc['email'],
98            'first_name' => $poc['first_name'],
99            'last_name' => $poc['last_name'],
100            'password' => $hashed_password,
101            'company_id' => $companyId,
102            'temp_password_expiry' => Carbon::now()->addDays(7)->toDateTimeString(),
103            'temp_password' => $hashed_password,
104            'status' => 'Invited',
105            'onboardingv2_presented' => true,
106        ]);
107    }
108
109    private function updateExistingUser(User $existingUser, string $companyId): void
110    {
111        $existingUser->update([
112            'company_id' => $companyId,
113            'company_group_id' => null,
114            'status' => 'Invited',
115        ]);
116        $existingUser->assignRole(Role::GLOBAL_ADMIN, []);
117    }
118
119    private function createPoc(string $companyId, array $poc, string $userId): CompanyPOC
120    {
121        return CompanyPOC::create([
122            'company_id' => $companyId,
123            'first_name' => $poc['first_name'],
124            'last_name' => $poc['last_name'],
125            'email' => $poc['email'],
126            'user_id' => $userId,
127        ]);
128    }
129
130    private function sendInvitationMail(User $user, bool $isExistingUser, string $password): void
131    {
132        $inviter = auth()->user()->email;
133        $tempPasswordExpiry = Carbon::now()->addDays(7);
134
135        if ($isExistingUser) {
136            $this->emailService->send(
137                $user->email,
138                new GlobalAdminInvitationExistentUserMail(
139                    $user->email,
140                    $user->first_name,
141                    $user->last_name,
142                    $inviter,
143                    $password,
144                    $tempPasswordExpiry->format('m/d/Y').' at '.$tempPasswordExpiry->format('h:i A'),
145                    $user->avatar
146                ),
147                'cac_invite_existing_user'
148            );
149        } else {
150            $this->emailService->send(
151                $user->email,
152                new GlobalAdminInvitationMail(
153                    $user->email,
154                    $user->first_name,
155                    $user->last_name,
156                    $inviter,
157                    $password,
158                    $tempPasswordExpiry->format('m/d/Y').' at '.$tempPasswordExpiry->format('h:i A')
159                ),
160                'cac_invite_user'
161            );
162        }
163    }
164
165    private function createAdminUserInvitation(string $email, string $companyId): void
166    {
167        $data = [
168            'email' => $email,
169            'admin_email' => auth()->user()->email,
170            'company_id' => $companyId,
171            'role_name' => Role::GLOBAL_ADMIN,
172        ];
173
174        AdminUserInvitation::create($data);
175    }
176
177    public function removePoc(string $slug, string $userId): void
178    {
179        $session = DB::getMongoClient()->startSession();
180        $session->startTransaction();
181        try {
182            // Usa a instância injetada em vez da classe estática
183            $company = $this->companyModel->where('slug', $slug)->first();
184
185            if (! $company) {
186                throw new NotFoundHttpException('Company not found.');
187            }
188
189            if (empty($company)) {
190                throw new NotFoundHttpException('Company not found');
191            }
192
193            $pocsCount = $this->companyPOCModel->where('company_id', $company->id)->count();
194
195            if ($pocsCount <= 1) {
196                throw new Exception('It is not possible to remove the last POC user.');
197            }
198
199            $poc = $this->companyPOCModel
200                ->where('company_id', $company->id)
201                ->where('user_id', $userId)
202                ->first();
203
204            if (empty($poc)) {
205                throw new NotFoundHttpException('Company POC not found');
206            }
207
208            $poc->delete();
209
210            $session->commitTransaction();
211        } catch (NotFoundHttpException $e) {
212            $session->abortTransaction();
213            throw $e;
214        } catch (\Exception $e) {
215            $session->abortTransaction();
216            FlyMSGLogger::logError(__METHOD__, $e);
217            throw $e;
218        }
219    }
220}