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 }