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\Mail\GlobalAdminInvitationMail;
6use Carbon\Carbon;
7use Illuminate\Support\Facades\DB;
8use Illuminate\Support\Str;
9use App\Helpers\FlyMSGLogger;
10use App\Http\Models\Admin\AdminUserInvitation;
11use App\Http\Models\Admin\Company;
12use App\Http\Models\Admin\CompanyPOC;
13use App\Http\Models\Auth\Role;
14use App\Http\Models\Auth\User;
15use App\Http\Resources\ClientManagementCompanyPocsResource;
16use App\Mail\GlobalAdminInvitationExistentUserMail;
17use App\Services\Email\EmailService;
18use App\Traits\CompanyTrait;
19use Exception;
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            return $companyPoc;
66        } catch (\Exception $e) {
67            $session->abortTransaction();
68            FlyMSGLogger::logError(__METHOD__, $e);
69            throw $e;
70        }
71    }
72
73    private function processPocs(string $companyId, array $poc): CompanyPOC
74    {
75
76        $existingUser = User::firstWhere('email', $poc["email"]);
77        $password = Str::password(16);
78        $user = $existingUser ?? $this->createNewUser($poc, $companyId, $password);
79
80        if ($existingUser) {
81            $this->updateExistingUser($existingUser, $companyId);
82        }
83
84        $companyPOC = $this->createPoc($companyId, $poc, $user->id);
85        $this->createAdminUserInvitation($poc['email'], $companyId);
86        $this->sendInvitationMail($user, filled($existingUser), $password);
87
88        return $companyPOC;
89    }
90
91    private function createNewUser(array $poc, string $companyId, string $password): User
92    {
93        $hashed_password = bcrypt($password);
94
95        return User::create([
96            'email' => $poc["email"],
97            'first_name' => $poc["first_name"],
98            'last_name' => $poc["last_name"],
99            'password' => $hashed_password,
100            'company_id' => $companyId,
101            'temp_password_expiry' => Carbon::now()->addDays(7)->toDateTimeString(),
102            'temp_password' => $hashed_password,
103            'status' => 'Invited',
104            'onboardingv2_presented' => true
105        ]);
106    }
107
108    private function updateExistingUser(User $existingUser, string $companyId): void
109    {
110        $existingUser->update([
111            'company_id' => $companyId,
112            'company_group_id' => null,
113            'status' => 'Invited'
114        ]);
115        $existingUser->assignRole(Role::GLOBAL_ADMIN, []);
116    }
117
118    private function createPoc(string $companyId, array $poc, string $userId): CompanyPOC
119    {
120        return CompanyPOC::create([
121            "company_id" => $companyId,
122            "first_name" => $poc["first_name"],
123            "last_name" => $poc["last_name"],
124            "email" => $poc["email"],
125            "user_id" => $userId
126        ]);
127    }
128
129    private function sendInvitationMail(User $user, bool $isExistingUser, string $password): void
130    {
131        $inviter = auth()->user()->email;
132        $tempPasswordExpiry = Carbon::now()->addDays(7);
133
134        if ($isExistingUser) {
135            $this->emailService->send(
136                $user->email,
137                new GlobalAdminInvitationExistentUserMail(
138                    $user->email,
139                    $user->first_name,
140                    $user->last_name,
141                    $inviter,
142                    $password,
143                    $tempPasswordExpiry->format("m/d/Y") . " at " . $tempPasswordExpiry->format("h:i A"),
144                    $user->avatar
145                ),
146                'cac_invite_existing_user'
147            );
148        } else {
149            $this->emailService->send(
150                $user->email,
151                new GlobalAdminInvitationMail(
152                    $user->email,
153                    $user->first_name,
154                    $user->last_name,
155                    $inviter,
156                    $password,
157                    $tempPasswordExpiry->format("m/d/Y") . " at " . $tempPasswordExpiry->format("h:i A")
158                ),
159                'cac_invite_user'
160            );
161        }
162    }
163
164    private function createAdminUserInvitation(string $email, string $companyId): void
165    {
166        $data = [
167            'email' => $email,
168            'admin_email' => auth()->user()->email,
169            'company_id' => $companyId,
170            'role_name' => Role::GLOBAL_ADMIN,
171        ];
172
173        AdminUserInvitation::create($data);
174    }
175
176    public function removePoc(string $slug, string $userId): void
177    {
178        $session = DB::getMongoClient()->startSession();
179        $session->startTransaction();
180        try {
181            // Usa a instância injetada em vez da classe estática
182            $company = $this->companyModel->where('slug', $slug)->first();
183
184            if (!$company) {
185                throw new NotFoundHttpException('Company not found.');
186            }
187
188            if (empty($company)) {
189                throw new NotFoundHttpException('Company not found');
190            }
191
192            $pocsCount = $this->companyPOCModel->where('company_id', $company->id)->count();
193
194            if ($pocsCount <= 1) {
195                throw new Exception('It is not possible to remove the last POC user.');
196            }
197
198            $poc = $this->companyPOCModel
199                ->where('company_id', $company->id)
200                ->where('user_id', $userId)
201                ->first();
202
203            if (empty($poc)) {
204                throw new NotFoundHttpException('Company POC not found');
205            }
206
207            $poc->delete();
208
209            $session->commitTransaction();
210        } catch (NotFoundHttpException $e) {
211            $session->abortTransaction();
212            throw $e;
213        } catch (\Exception $e) {
214            $session->abortTransaction();
215            FlyMSGLogger::logError(__METHOD__, $e);
216            throw $e;
217        }
218    }
219}