with(['institution', 'user', 'userPosition']) ->orderByDesc('start_year'); $this->applyTrashed($query, $request->input('trashed')); if ($request->filled('institution_id')) { $query->where('institution_id', $request->integer('institution_id')); } if ($request->filled('user_id')) { $query->where('user_id', $request->integer('user_id')); } if ($request->filled('user_position_id')) { $query->where('user_position_id', $request->integer('user_position_id')); } if ($request->filled('open')) { $request->boolean('open') ? $query->whereNotNull('is_open') : $query->whereNull('is_open'); } $affiliations = $query->paginate($request->integer('per_page') ?: 20); return $this->paginatedCollectionResponse($affiliations); } /** * Crea un'affiliazione. */ public function store(StoreUserAffiliationRequest $request): JsonResponse { $affiliation = UserAffiliation::create($request->validated()); return $this->createdResponse($affiliation->load(['institution', 'user', 'userPosition'])); } /** * Dettaglio (con ente, utente e posizione). */ public function show(UserAffiliation $userAffiliation): JsonResponse { return $this->okResponse($userAffiliation->load(['institution', 'user', 'userPosition'])); } /** * Aggiorna un'affiliazione. */ public function update(UpdateUserAffiliationRequest $request, UserAffiliation $userAffiliation): JsonResponse { $userAffiliation->update($request->validated()); return $this->updatedResponse($userAffiliation->load(['institution', 'user', 'userPosition'])); } /** * Cestina (soft delete). */ public function destroy(UserAffiliation $userAffiliation): JsonResponse { $userAffiliation->delete(); return $this->deletedResponse(); } /** * Ripristina un'affiliazione cestinata. Bloccato (409) se nel frattempo รจ * stata aperta un'altra affiliazione per lo stesso ente+utente: va prima * chiusa/eliminata quella attuale, oppure si elimina definitivamente questa. */ public function restore(UserAffiliation $userAffiliation): JsonResponse { if ($userAffiliation->hasConflictingOpenAffiliation()) { return $this->conflictResponse( 'Cannot restore: another open affiliation already exists for this user at this institution.' ); } $userAffiliation->restore(); return $this->restoredResponse($userAffiliation->load(['institution', 'user', 'userPosition'])); } /** * Elimina definitivamente un'affiliazione. */ public function forceDestroy(UserAffiliation $userAffiliation): JsonResponse { $userAffiliation->forceDelete(); return $this->deletedResponse(); } /** * Include i soft-deleted: `with` (tutti) o `only` (solo cestinati). * * @param Builder $query */ private function applyTrashed(Builder $query, ?string $trashed): void { match ($trashed) { 'with' => $query->withTrashed(), 'only' => $query->onlyTrashed(), default => null, }; } }