Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
38.89% covered (danger)
38.89%
21 / 54
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ImportSeniorUSerService
38.89% covered (danger)
38.89%
21 / 54
20.00% covered (danger)
20.00%
1 / 5
32.82
0.00% covered (danger)
0.00%
0 / 1
 import
58.33% covered (warning)
58.33%
7 / 12
0.00% covered (danger)
0.00%
0 / 1
5.16
 store
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
12
 update
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 query
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
1.00
 checkExistsUser
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace Domain\User\Services;
4
5use App\Events\ServiceProcessed;
6use App\Helper\AppHelper;
7use App\Models\User;
8use Domain\Shared\Enums\SectorEnum;
9use Domain\Shared\Integrations\Senior\Exceptions\IntegrationSoapSeniorException;
10use Domain\Shared\Integrations\Senior\SeniorQueryExecute;
11use Domain\User\Enums\AccessLevel;
12use Illuminate\Database\Eloquent\Builder;
13use Illuminate\Database\Eloquent\Model;
14use Illuminate\Support\Facades\Hash;
15use Illuminate\Database\UniqueConstraintViolationException;
16
17readonly class ImportSeniorUSerService
18{
19    /**
20     * @throws IntegrationSoapSeniorException
21     */
22    public function import(string|int $identifier, string $searchBy = 'code', User $user = null): void
23    {
24        $result = (new SeniorQueryExecute())->execute($this->query($identifier, $searchBy));
25
26        if (!isset($result[0]['R999USU_CODUSU'])) {
27            throw new IntegrationSoapSeniorException(__('No user found in Senior with :searchBy :identifier',
28                ['searchBy' => $searchBy, 'identifier' => $identifier]
29            ));
30        }
31
32        $seniorUser = $result[0];
33        //Realiza verificação com base no nome do usuário
34        if (is_null($user)) {
35            $user = $this->checkExistsUser($seniorUser);
36        }
37
38        if($user) {
39            $this->update($seniorUser, $user);
40        } else {
41            $this->store($seniorUser);
42        }
43
44        ServiceProcessed::dispatch(self::class, AppHelper::systemUser());
45    }
46
47    /**
48     * @param $seniorUser
49     * @return void
50     */
51    private function store($seniorUser)
52    {
53        $user = new User();
54        $user->password = Hash::make('12345678');
55        $user->name = $seniorUser['R910USU_NOMCOM'];
56        $user->email = $seniorUser['R900CPL_EMAIL'] ?? 'usuario'.$seniorUser['R999USU_CODUSU'].'@rex.com.br';
57        $user->access_level = (object) [
58            SectorEnum::WAREHOUSE->value => [
59                AccessLevel::REQUESTER->value
60            ]
61        ];
62
63        $user->integrations = [
64            'senior' => [
65                'user_code' => $seniorUser['R999USU_CODUSU'],
66                'user' => $seniorUser['R999USU_NOMUSU'],
67                'password' => null
68            ]
69        ];
70
71        try {
72            $user->save();
73        } catch (UniqueConstraintViolationException $e) {
74            // Tratamento de concorrência: se o usuário foi criado por outro processo nesse meio tempo,
75            // capturamos o erro, buscamos o usuário existente e atualizamos.
76            $existingUser = User::where('email', $user->email)->first();
77            if ($existingUser) {
78                $this->update($seniorUser, $existingUser);
79                return;
80            }
81            throw $e;
82        }
83    }
84
85    private function update($seniorUser, $user)
86    {
87        $integrations = $user->integrations ?? [];
88        $existingSeniorData = $integrations['senior'] ?? [];
89
90        $integrations['senior'] = [
91            'user_code' => $seniorUser['R999USU_CODUSU'],
92            'user' => $existingSeniorData['user'] ?? $seniorUser['R999USU_NOMUSU'],
93            'password' => $existingSeniorData['password'] ?? null,
94        ];
95
96        $user->integrations = $integrations;
97        $user->save();
98    }
99
100    /**
101     * @param string|int $identifier
102     * @param string $searchBy
103     * @return string
104     */
105    private function query(string|int $identifier, string $searchBy)
106    {
107        $whereClause = match ($searchBy) {
108            'username' => "R999usu.nomusu = '$identifier'",
109            default => "R999usu.codusu = '$identifier'",
110        };
111
112        return "SELECT
113                    R999usu.codusu AS R999usu_Codusu,
114                    R999usu.nomusu AS R999usu_Nomusu,
115                    R910usu.nomcom AS R910usu_Nomcom,
116                    R910usu.desusu AS R910usu_Desusu,
117                    R910usu.altsen AS R910usu_Altsen,
118                    R910usu.conhab AS R910usu_Conhab,
119                    R910usu.conblo AS R910usu_Conblo,
120                    R900cpl.email  AS R900cpl_Email
121                FROM R999usu
122                INNER JOIN r910usu
123                    ON r910usu.codent = r999usu.codusu
124                INNER JOIN R900cpl
125                    ON R900cpl.perid = r999usu.codusu
126                WHERE $whereClause ";
127    }
128
129    /**
130     * @param $seniorUser
131     * @return Builder|Model|object|null
132     */
133    private function checkExistsUser($seniorUser)
134    {
135        return User::query()
136            ->where('integrations->senior->user', $seniorUser['R999USU_NOMUSU'])
137            ->where('email', $seniorUser['R900CPL_EMAIL'] ?? 'usuario'.$seniorUser['R999USU_CODUSU'].'@rex.com.br')
138            ->first();
139    }
140}