User.php
1 <?php 2 3 namespace App\Models; 4 5 use App\Enums\UserTypeEnum; 6 use App\Models\Dossier; 7 use Illuminate\Database\Eloquent\Relations\BelongsToMany; 8 use Spatie\Activitylog\LogOptions; 9 use Illuminate\Support\Facades\Auth; 10 use Spatie\Permission\Traits\HasRoles; 11 use Tymon\JWTAuth\Contracts\JWTSubject; 12 use Illuminate\Notifications\Notifiable; 13 use Spatie\Activitylog\Traits\LogsActivity; 14 use Illuminate\Database\Eloquent\SoftDeletes; 15 use Laravel\Fortify\TwoFactorAuthenticatable; 16 use Illuminate\Database\Eloquent\Casts\Attribute; 17 use Illuminate\Database\Eloquent\Relations\MorphOne; 18 use Illuminate\Database\Eloquent\Relations\MorphMany; 19 use Illuminate\Database\Eloquent\Factories\HasFactory; 20 use Illuminate\Database\Eloquent\Relations\MorphToMany; 21 use Illuminate\Foundation\Auth\User as Authenticatable; 22 23 class User extends Authenticatable implements JWTSubject 24 { 25 use HasFactory, Notifiable, SoftDeletes, LogsActivity, HasRoles, TwoFactorAuthenticatable; 26 27 /** 28 * The attributes that should be hidden for arrays. 29 * 30 * @var array 31 */ 32 protected $hidden = [ 33 'password', 34 'totp', 35 'gpg', 36 'gpg_pass', 37 ]; 38 39 /** 40 * The attributes that are mass assignable. 41 * 42 * @var array 43 */ 44 protected $guarded = []; 45 46 public function getJWTIdentifier() 47 { 48 return $this->getKey(); 49 } 50 51 /** 52 * Return a key value array, containing any custom claims to be added to the JWT. 53 * 54 * @return array 55 */ 56 public function getJWTCustomClaims() 57 { 58 return []; 59 } 60 61 public function isInternal() 62 { 63 return $this->user_type_id === UserTypeEnum::INTERNAL->value; 64 } 65 66 public function isExternal() 67 { 68 return $this->user_type_id === UserTypeEnum::EXTERNAL->value; 69 } 70 71 public function getActivitylogOptions(): LogOptions 72 { 73 return LogOptions::defaults() 74 ->logOnly([ 75 'id', 76 'username', 77 'totp', 78 'user_type_id', 79 'user_type.name', 80 'personal_identification_number', 81 'email', 82 'name', 83 'address', 84 'internal_identification_number', 85 ])->logOnlyDirty() 86 ->dontSubmitEmptyLogs() 87 ->useLogName($this->id); 88 } 89 90 /** 91 * Get the user's first name. 92 */ 93 protected function fullname(): Attribute 94 { 95 return Attribute::make( 96 get: fn() => $this->name . ($this->lastname ? ' ' . $this->lastname : ''), 97 ); 98 } 99 100 /** 101 * PHPWord 102 * @return Attribute 103 */ 104 protected function printingName(): Attribute 105 { 106 return Attribute::make( 107 //Vamos a usar el fullName aquí, 108 // si se da el caso de que se tenga que cambiar, ya se verá 109 get: function ($value) { 110 return $this->fullName; 111 }, 112 ); 113 } 114 115 // Gets user object by username 116 public static function getUserByUsername(string $username) 117 { 118 return User::where('username', $username)->firstOrFail(); 119 } 120 121 public function activeKey(): MorphOne 122 { 123 return $this->morphOne(GpgKey::class, 'entity'); 124 } 125 126 public function user_type() 127 { 128 return $this->belongsTo(UserType::class); 129 } 130 131 public function entity(): Entity|null 132 { 133 return $this->entities() ? $this->entities()->first() : null; 134 } 135 136 public function isPoc(Entity $entity): bool 137 { 138 return $this->entities()->whereEntityId($entity->id)->first()->pivot->is_poc; 139 } 140 141 // MORPH 142 143 public function entities(): MorphToMany 144 { 145 return $this->morphedByMany(Entity::class, 'entity', 'entity_user') 146 ->withPivot(['role_id', 'is_poc'])->using(EntityUser::class); 147 } 148 149 public function laboratory() 150 { 151 return $this->entities()->where('entity_type_id', 1)->first(); 152 } 153 154 public function dossiers(): MorphToMany 155 { 156 return $this->morphedByMany(Dossier::class, 'entity', 'entity_user') 157 ->withPivot('role_id')->using(EntityUser::class); 158 } 159 160 // MORPH 161 162 public function roles(): \Illuminate\Database\Eloquent\Relations\BelongsToMany 163 { 164 return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id'); 165 } 166 167 public function mainRole(): Role|null 168 { 169 return $this->roles()->orderBy('id', 'asc')->first(); 170 } 171 172 public function hasPerm(string $permission) 173 { 174 return in_array(1, $this->roles->pluck($permission)->toArray()); 175 } 176 177 public function isAuth() 178 { 179 return $this->id == Auth::user()->id; 180 } 181 182 // DOSSIERS 183 184 public function dossiersAsInformedPersonal() 185 { 186 return $this->belongsToMany(Dossier::class, 'informed_user_dossier', 'user_id', 'dossier_id'); 187 } 188 189 public function dossiersAsSecondaryCertifier() 190 { 191 return $this->belongsToMany(Dossier::class, 'user_dossier', 'user_id', 'dossier_id') 192 ->wherePivotIn('external', [false, 0]); 193 } 194 195 public function dossiersAsExternalCertifier() 196 { 197 return $this->belongsToMany(Dossier::class, 'user_dossier', 'user_id', 'dossier_id') 198 ->wherePivotIn('external', [true, 1]); 199 } 200 201 public function dossiersAsPrincipalCertifier() 202 { 203 return $this->hasMany(Dossier::class, 'principal_certifier_id'); 204 } 205 206 public function getDossiersByUser() 207 { 208 $dossierIds = EntityUser::where('entity_type', 'App\Models\Dossier') 209 ->where('user_id', $this->id)->pluck('entity_id'); 210 return Dossier::whereIn('id', $dossierIds)->get(); 211 } 212 213 public function allDossiers() 214 { 215 $princDossiers = $this->dossiersAsPrincipalCertifier ?? collect(); 216 $dossiers = $this->getDossiersByUser() ?? collect(); 217 218 $allDossiers = collect([$princDossiers, $dossiers])->flatten(); 219 220 return $allDossiers; 221 } 222 223 public function allStages() 224 { 225 $dossiers = $this->allDossiers(); 226 $stages = collect(); 227 228 foreach ($dossiers as $dossier) { 229 $stages->merge($dossier->stages); 230 } 231 232 return $stages; 233 } 234 235 public function isInDossier(Dossier $dossier) 236 { 237 return $dossier->principalCertifier?->id == $this->id or 238 User::technicalManager()->id == $this->id or 239 $this->dossiers()->where('dossiers.id', $dossier->id)->exists(); 240 } 241 242 public function hasToeInAnyDossier() 243 { 244 return $this->dossiers() 245 ->whereHas('principalCertifier', fn($query) => $query->where('users.id', $this->id)) 246 ->whereHas('toe') 247 ->exists(); 248 } 249 250 public function isCertifierInDossier(Dossier $dossier) 251 { 252 if ($this->id == $dossier->principal_certifier_id) { 253 return true; 254 } 255 256 $isSecondary = $dossier->secondaryCertifiers()->pluck('id')->contains($this->id); 257 $isExternal = $dossier->externalCertifiers()->pluck('id')->contains($this->id); 258 259 return $isSecondary || $isExternal; 260 } 261 262 public function dossierLogs() 263 { 264 return $this->hasMany(DossierLog::class); 265 } 266 267 // TASKS 268 public function tasks() 269 { 270 return $this->hasMany(Task::class); 271 } 272 273 //CAN VALIDATE 274 public static function canValidate() 275 { 276 $allUsers = self::all(); 277 $usersCanValidate = []; 278 279 foreach ($allUsers as $user) { 280 $roles = $user->roles->toArray(); 281 282 if (in_array(1, array_column($roles, 'can_validate_and_approve'))) { 283 array_push($usersCanValidate, $user); 284 } 285 } 286 287 return collect($usersCanValidate); 288 } 289 290 //MEET 291 public function audits() 292 { 293 return $this->belongsToMany(Audit::class, 'audits_users', 'user_id', 'audit_id'); 294 } 295 296 public function meets(): BelongsToMany 297 { 298 return $this->belongsToMany(Meet::class, 'meet_user', 'user_id', 'meet_id')->withPivot('id'); 299 } 300 301 // GPG 302 // Assign GPG fingerprint 303 public function addFingerprintFromGpgKey(string $fingerprint) 304 { 305 $this->gpg_fingerprint = $fingerprint; 306 $this->save(); 307 } 308 309 public function getFullName() 310 { 311 return $this->name . ' ' . $this->lastname; 312 } 313 314 public function gpg_keys(): MorphMany 315 { 316 return $this->morphMany(GpgKey::class, 'entity'); 317 } 318 319 // Recommendations 320 321 public function recommendations() 322 { 323 return $this->hasMany(Recommendation::class); 324 } 325 326 public function getRoleInDossier($dossierId) 327 { 328 $dossier = Dossier::find($dossierId); 329 if (!$dossier) { 330 return __('roles.' . $this->roles->first()->name); 331 } 332 333 if ($this->id == $dossier->principal_certifier_id) { 334 return __('roles.principal_certifier'); 335 } 336 337 $role = EntityUser::where('entity_type', Dossier::class) 338 ->where('entity_id', $dossierId) 339 ->where('user_id', $this->id) 340 ->first() 341 ->role 342 ->name ?? null; 343 344 $traduccion = $role ? __("roles.$role") : __('roles.unassigned'); 345 return $traduccion; 346 } 347 348 public function getRolesInDossier($dossierId) 349 { 350 $dossier = Dossier::find($dossierId); 351 if (!$dossier) { 352 return $this->roles->pluck('name'); 353 } 354 355 $roles = collect(); 356 if ($this->id == $dossier->principal_certifier_id) { 357 $roles->push(__('roles.principal_certifier')); 358 } 359 360 $entityRoles = EntityUser::where('entity_type', Dossier::class) 361 ->where('entity_id', $dossierId) 362 ->where('user_id', $this->id) 363 ->get(); 364 365 foreach ($entityRoles as $entityRole) { 366 $roleName = $entityRole->role->name; 367 $roles->push(__('roles.' . $roleName)); 368 } 369 370 return $roles; 371 } 372 373 public function getDossierRole($dossierId) 374 { 375 if ($this->id == Dossier::find($dossierId)->principal_certifier_id) { 376 return Role::whereName('principal_certifier')->first(); 377 } 378 379 $role = EntityUser::where('entity_type', Dossier::class) 380 ->where('entity_id', $dossierId) 381 ->where('user_id', $this->id) 382 ->first() 383 ->role ?? null; 384 385 return $role; 386 } 387 388 389 public function outputs(): MorphToMany 390 { 391 return $this->morphToMany(OutPut::class, 'outputable'); 392 } 393 394 public static function technicalManager() 395 { 396 $technicalManager = Role::whereName('technical_manager')->first()->users()->first(); 397 if ($technicalManager) { 398 return $technicalManager; 399 } 400 401 $root = Role::whereName('root')->first()->users()->first(); 402 if ($root) { 403 return $root; 404 } 405 406 return null; 407 } 408 409 public function dossiersAsPOC() 410 { 411 return $this->belongsToMany(Dossier::class, 'dossier_poc'); 412 } 413 414 public function getExternalRoleNames() 415 { 416 return Role::query() 417 ->whereIn('id', $this->entities()->pluck('role_id')) 418 ->pluck('name'); 419 } 420 }