/ app / Http / Services / UserService.php
UserService.php
  1  <?php
  2  
  3  namespace App\Http\Services;
  4  
  5  use App\Enums\RoleEnum;
  6  use App\Enums\UserTypeEnum;
  7  use App\Models\Dossier;
  8  use App\Models\Role;
  9  use App\Models\User;
 10  use Crypt_GPG;
 11  use Exception;
 12  use Illuminate\Support\Arr;
 13  use Illuminate\Support\Str;
 14  use Illuminate\Support\Facades\Auth;
 15  use Illuminate\Support\Facades\DB;
 16  use Illuminate\Support\Facades\Hash;
 17  use Illuminate\Support\Facades\Log;
 18  use Illuminate\Support\Facades\Session;
 19  
 20  class UserService
 21  {
 22      /**
 23       * Display a listing of the resource.
 24       *
 25       * @return User
 26       */
 27      public static function find(int $userId)
 28      {
 29          return User::where('id', $userId)->first();
 30      }
 31  
 32      /**
 33       * Search resources
 34       *
 35       * @return \Illuminate\Http\Response
 36       */
 37      public static function searchUsers(bool $isInternal, string $searchString, string $sortField, string $sortDirection, array|null $filters)
 38      {
 39          $usersQuery = User::with(['roles', 'entities', 'entities.type']);
 40  
 41          if ($filters && $filters['withTrashed']) {
 42              $usersQuery->withTrashed();
 43          }
 44  
 45          $usersQuery->where('user_type_id', $isInternal ? UserTypeEnum::INTERNAL->value : UserTypeEnum::EXTERNAL->value);
 46  
 47          if ($filters && Arr::exists($filters, 'entity_id')) {
 48              $usersQuery->whereHas('entities', function ($query) use ($filters) {
 49                  $query->where('entities.id', $filters['entity_id']);
 50              });
 51          }
 52  
 53          $usersQuery
 54              ->where(function ($query) use ($searchString) {
 55                  $query
 56                      ->where('name', 'like', '%' . $searchString . '%')
 57                      ->orWhere('internal_identification_number', 'like', '%' . $searchString . '%')
 58                      ->orWhere('personal_identification_number', 'like', '%' . $searchString . '%')
 59                      ->orWhere('phone', 'like', '%' . $searchString . '%')
 60                      ->orWhere('email', 'like', '%' . $searchString . '%');
 61              });
 62  
 63          if ($filters && $filters['created_at_since']) {
 64              $usersQuery->where('created_at', '>=', $filters['created_at_since']);
 65          }
 66  
 67          if ($filters && $filters['created_at_to']) {
 68              $usersQuery->where('created_at', '<=', $filters['created_at_to']);
 69          }
 70  
 71          if ($filters && $filters['role_ids']) {
 72              $usersQuery->whereHas('roles', function ($query) use ($filters) {
 73                  $query->whereIn('roles.id', $filters['role_ids']);
 74              });
 75          }
 76  
 77          if ($sortField && $sortDirection) {
 78              $usersQuery->orderBy($sortField, $sortDirection);
 79          }
 80  
 81          return $usersQuery;
 82      }
 83  
 84      public static function searchUsersByDossierId(int $dossierId, string $searchString, string $sortField, string $sortDirection, array|null $filters)
 85      {
 86          return User::query()
 87              ->where(function ($query) use ($dossierId) {
 88                  $query
 89                      ->whereRelation('dossiers', 'dossiers.id', $dossierId)
 90                      ->orWhereRelation('dossiersAsPrincipalCertifier', 'dossiers.id', $dossierId);
 91              })
 92              ->where(function ($query) use ($searchString) {
 93                  $query
 94                      ->where('name', 'like', '%' . $searchString . '%')
 95                      ->orWhere('internal_identification_number', 'like', '%' . $searchString . '%')
 96                      ->orWhere('personal_identification_number', 'like', '%' . $searchString . '%')
 97                      ->orWhere('phone', 'like', '%' . $searchString . '%')
 98                      ->orWhere('email', 'like', '%' . $searchString . '%');
 99              })
100              ->when($filters && $filters['withTrashed'], function ($query) {
101                  return $query->withTrashed();
102              })
103              ->when($filters && $filters['type'], function ($query) use ($filters) {
104                  return $query->where('user_type_id', $filters['type']);
105              })
106              ->when($filters && $filters['created_at_since'], function ($query) use ($filters) {
107                  return $query->where('created_at', '>=', $filters['created_at_since']);
108              })
109              ->when($filters && $filters['created_at_to'], function ($query) use ($filters) {
110                  return $query->where('created_at', '<=', $filters['created_at_to']);
111              })
112              ->when($sortField && $sortDirection, function ($query) use ($sortField, $sortDirection) {
113                  return $query->orderBy($sortField, $sortDirection);
114              })
115              ->get();
116      }
117  
118      /**
119       * Create a resource
120       *
121       * @return \Illuminate\Http\Response
122       */
123      public static function create(array $userData, array $relation): bool|Exception
124      {
125          try {
126              DB::beginTransaction();
127  
128  
129              $user = User::create($userData);
130  
131              if ($userData['user_type_id'] == UserTypeEnum::EXTERNAL->value) {
132                  $user->entities()->detach($relation['entity_id']);
133  
134                  foreach ($relation['role_ids'] as $roleId) {
135                      $user->entities()->attach($relation['entity_id'], [
136                          'role_id' => $roleId,
137                          'is_poc' => $relation['is_poc'],
138                      ]);
139                  }
140              }
141  
142              self::updateRol($relation['role_ids'], $user);
143  
144              DB::commit();
145  
146              return true;
147          } catch (Exception $e) {
148              DB::rollBack();
149              throw new Exception($e->getMessage());
150          }
151      }
152  
153      /**
154       * Update a resource
155       *
156       * @return \Illuminate\Http\Response
157       */
158      public static function update(array $data, int $userId)
159      {
160          try {
161              DB::beginTransaction();
162  
163              $user = User::findOrFail($userId);
164              $user->user_type_id = $data['user']['user_type_id'];
165              $user->alias = $data['user']['alias'];
166              $user->name = $data['user']['name'];
167              $user->lastname = $data['user']['lastname'];
168              $user->username = $data['user']['username'];
169              $user->email = $data['user']['email'];
170              $user->phone = $data['user']['phone'];
171              $user->address = $data['user']['address'];
172              $user->internal_identification_number = $data['user']['internal_identification_number'];
173              $user->personal_identification_number = $data['user']['personal_identification_number'];
174              $user->can_access_inbox = $data['user']['can_access_inbox'];
175              $user->can_access_sgoc = $data['user']['can_access_sgoc'];
176  
177              if (isset($data['user']['password'])) {
178                  $user->password = Hash::make($data['user']['password']);
179              }
180  
181              $user->save();
182  
183              if ($data['user']['user_type_id'] == UserTypeEnum::EXTERNAL->value) {
184                  // Duda: Voy a dejar la creacion de mas de una entidad por cada rol ya que no se si esto se usa en algun sitio y no quiero romper nada de la funcionalidad
185                  $user->entities()->detach($data['relation']['entity_id']);
186  
187                  foreach ($data['relation']['role_ids'] as $roleId) {
188                      $user->entities()->attach($data['relation']['entity_id'], [
189                          'role_id' => $roleId,
190                          'is_poc' => $data['relation']['is_poc'],
191                      ]);
192                  }
193                  self::updateRol($data['relation']['role_ids'], $user);
194              } else {
195                  $user->entities()->detach();
196                  self::updateRol($data['relation']['role_ids'], $user);
197              }
198  
199              DB::commit();
200  
201              return true;
202          } catch (Exception $e) {
203              DB::rollBack();
204              logger($e);
205              throw new Exception(__('users.notifications.update.error.message'));
206          }
207      }
208  
209      private static function updateRol(array $roleIds, User $user)
210      {
211          $user->syncRoles($roleIds);
212  
213          $rolesNames = Role::whereIn('id', $roleIds)->pluck('name');
214          foreach ($rolesNames as $roleName) {
215              activity()
216                  ->performedOn($user)
217                  ->causedBy(Auth::user())
218                  ->withProperties([
219                      'new' => Str::headline($roleName),
220                  ])
221                  ->log('updated rol');
222          }
223      }
224  
225  
226      protected static function importGpgKey(string $public_gpg_key): string|null
227      {
228          if (config('app.env') == "production") {
229              unset($_ENV['argv']);
230          }
231          $gpg = new Crypt_GPG();
232          $importKey = $gpg->importKey($public_gpg_key);
233          Log::info($importKey);
234          if (isset($importKey['fingerprint'])) {
235              return $importKey['fingerprint'];
236          }
237      }
238  
239      /**
240       * Destroy a resource
241       *
242       */
243      public static function remove(int $userId): void
244      {
245          try {
246              DB::beginTransaction();
247  
248              $user = User::findOrFail($userId);
249              $user->update([
250                  'is_active' => false,
251              ]);
252              $user->delete();
253  
254              DB::commit();
255          } catch (Exception $e) {
256              DB::rollBack();
257              log_exception($e);
258              throw new Exception(__('users.notifications.remove.error.message'));
259          }
260      }
261  
262      public static function destroy(int $userId): void
263      {
264          try {
265              DB::beginTransaction();
266              User::withTrashed()->find($userId)->forceDelete();
267              DB::commit();
268          } catch (Exception $e) {
269              DB::rollBack();
270              log_exception($e);
271              throw new Exception(__('users.notifications.remove.error.message'));
272          }
273      }
274  
275      /**
276       * Restore a resource
277       *
278       */
279      public static function restore(int $userId): void
280      {
281          try {
282              DB::beginTransaction();
283  
284              $user = User::withTrashed()->find($userId);
285              $user->restore();
286              $user->update([
287                  'is_active' => true,
288              ]);
289  
290              DB::commit();
291          } catch (Exception $e) {
292              DB::rollBack();
293              throw new Exception(__('users.notifications.remove.error.message'));
294          }
295      }
296  
297      public static function getInternalUsers()
298      {
299          return User::query()
300              ->selectRaw('id, CONCAT(name, " ", IFNULL(lastname, "")) as name, alias, user_type_id')
301              ->where('user_type_id', UserTypeEnum::INTERNAL->value)
302              ->orderBy('name')
303              ->get();
304      }
305  
306      public static function getExternalUsers()
307      {
308          return User::query()
309              ->selectRaw('id, CONCAT(name, " ", IFNULL(lastname, "")) as name, alias, user_type_id')
310              ->where('user_type_id', UserTypeEnum::EXTERNAL->value)
311              ->orderBy('name')
312              ->get();
313      }
314  
315      public static function getExternalCertifiersUsers()
316      {
317          return User::query()
318              ->selectRaw('id, CONCAT(name, " ", IFNULL(lastname, "")) as name, alias, user_type_id')
319              ->whereHas('roles', function ($query) {
320                  $query->where('roles.id', RoleEnum::externalCertifier()->value);
321              })
322              ->orderBy('name')
323              ->get();
324      }
325  
326      public static function getAllUsers()
327      {
328          return User::query()
329              ->selectRaw('id, CONCAT(name, " ", IFNULL(lastname, "")) as name, alias, user_type_id')
330              ->orderBy('name')
331              ->get();
332      }
333  
334      public static function changePassword(int $id, array $data): bool
335      {
336          $user = User::findOrFail($id);
337  
338          if (Hash::check($data['new_password'], $user->password)) {
339              throw new Exception(__('users.notifications.change_password.error.equal.message'));
340              return false;
341          }
342  
343          return $user->update([
344              'password' => Hash::make($data['new_password'])
345          ]);
346      }
347  
348      public static function invalidateUserSession($userId)
349      {
350          $sessions = DB::table('sessions')
351              ->whereUserId($userId)
352              ->delete();
353      }
354  }