authorizeRead('gruppi'); $viewMode = request('view', 'table'); $user = auth()->user(); $vista = \App\Models\VistaReport::where('user_id', $user->id) ->where('tipo', 'gruppi') ->where('is_default', true) ->first(); $allColumns = ['nome', 'descrizione', 'diocesi', 'livello', 'padre', 'membri', 'responsabili', 'indirizzo', 'citta', 'telefono', 'email']; $defaultVisible = ['nome', 'livello', 'padre', 'membri', 'responsabili']; if ($vista && !empty($vista->colonne_visibili)) { $visibleColumns = $vista->colonne_visibili; } else { $visibleColumns = $defaultVisible; } $allGruppi = Gruppo::with(['diocesi', 'parent', 'children', 'individui', 'avatar']) ->orderBy('nome') ->get() ->map(function ($gruppo) { $depth = 0; $parent = $gruppo->parent; while ($parent) { $depth++; $parent = $parent->parent; } $gruppo->depth = $depth; return $gruppo; }); if ($viewMode === 'table') { $gruppi = $this->sortGruppiHierarchically($allGruppi); } else { $gruppi = $allGruppi; } return view('gruppi.index', compact( 'gruppi', 'allColumns', 'visibleColumns', 'viewMode', 'vista' )); } protected function sortGruppiHierarchically($gruppi) { $rootGroups = $gruppi->filter(fn($g) => $g->parent_id === null)->sortBy('nome'); $sorted = collect(); foreach ($rootGroups as $root) { $sorted->push($root); $this->addChildrenRecursive($root, $gruppi, $sorted); } return $sorted; } protected function addChildrenRecursive($parent, $allGruppi, &$sorted) { $children = $allGruppi->filter(fn($g) => $g->parent_id === $parent->id)->sortBy('nome'); foreach ($children as $child) { $sorted->push($child); $this->addChildrenRecursive($child, $allGruppi, $sorted); } } public function create(Request $request) { $this->authorizeWrite('gruppi'); $diocesi = Diocesi::orderBy('nome')->get(); $allGruppi = Gruppo::orderBy('nome')->get(); $selectedParent = $request->query('parent_id') ? Gruppo::find($request->query('parent_id')) : null; $individui = Individuo::orderBy('cognome')->orderBy('nome')->get(); return view('gruppi.create', compact('diocesi', 'allGruppi', 'selectedParent', 'individui')); } public function store(Request $request) { $this->authorizeWrite('gruppi'); $data = $request->validate([ 'nome' => 'required|string|max:255', 'descrizione' => 'nullable|string', 'parent_id' => 'nullable|exists:gruppi,id', 'diocesi_id' => 'nullable|exists:diocesi,id', 'responsabile_ids' => 'nullable|array', 'responsabile_ids.*' => 'exists:individui,id', 'indirizzo_incontro' => 'nullable|string|max:500', 'cap_incontro' => 'nullable|string|max:10', 'città_incontro' => 'nullable|string|max:255', 'sigla_provincia_incontro' => 'nullable|string|max:2', 'mappa_posizione' => 'nullable|string', ]); if (!empty($data['responsabile_ids'])) { $data['responsabile_ids'] = json_encode(array_values($data['responsabile_ids'])); } $gruppo = Gruppo::create($data); if ($request->has('individui')) { foreach ($request->individui as $individuoData) { if (!empty($individuoData['individuo_id'])) { $gruppo->individui()->attach($individuoData['individuo_id'], [ 'ruolo_nel_gruppo' => $individuoData['ruolo_nel_gruppo'] ?? null, 'data_adesione' => $individuoData['data_adesione'] ?? null, ]); } } } return redirect('/gruppi/' . $gruppo->id)->with('success', 'Gruppo creato con successo.'); } public function show($id) { $this->authorizeRead('gruppi'); $gruppo = Gruppo::with(['parent', 'children', 'diocesi', 'individui.contatti', 'individui.documenti', 'individui' => function ($q) { $q->withPivot('ruolo_ids', 'ruolo_nel_gruppo', 'data_adesione'); }, 'avatar', 'eventi' => function ($q) { $q->where('is_incontro_gruppo', true); }, 'eventi.responsabili.contatti'])->findOrFail($id); return view('gruppi.show', compact('gruppo')); } public function edit($id) { $this->authorizeWrite('gruppi'); $gruppo = Gruppo::with(['individui.contatti', 'individui.documenti', 'avatar'])->findOrFail($id); $diocesi = Diocesi::orderBy('nome')->get(); $gruppi = Gruppo::where('id', '!=', $gruppo->id)->orderBy('nome')->get(); $membri = $gruppo->individui()->withPivot('ruolo_ids', 'ruolo_nel_gruppo', 'data_adesione')->orderBy('cognome')->orderBy('nome')->get(); return view('gruppi.edit', compact('gruppo', 'diocesi', 'gruppi', 'membri')); } public function update(Request $request, $id) { $this->authorizeWrite('gruppi'); $gruppo = Gruppo::findOrFail($id); $data = $request->validate([ 'nome' => 'required|string|max:255', 'descrizione' => 'nullable|string', 'parent_id' => 'nullable|exists:gruppi,id', 'diocesi_id' => 'nullable|exists:diocesi,id', 'responsabile_ids' => 'nullable|array', 'responsabile_ids.*' => 'exists:individui,id', 'indirizzo_incontro' => 'nullable|string|max:500', 'cap_incontro' => 'nullable|string|max:10', 'città_incontro' => 'nullable|string|max:255', 'sigla_provincia_incontro' => 'nullable|string|max:2', 'mappa_posizione' => 'nullable|string', ]); if (!empty($data['responsabile_ids'])) { $data['responsabile_ids'] = json_encode(array_values($data['responsabile_ids'])); } else { $data['responsabile_ids'] = null; } $gruppo->update($data); if ($request->has('individui')) { $gruppo->individui()->detach(); foreach ($request->individui as $individuoData) { if (!empty($individuoData['individuo_id'])) { $gruppo->individui()->attach($individuoData['individuo_id'], [ 'ruolo_ids' => !empty($individuoData['ruolo_ids']) ? json_encode(array_values($individuoData['ruolo_ids'])) : null, 'data_adesione' => $individuoData['data_adesione'] ?? null, ]); } } } return redirect('/gruppi/' . $gruppo->id)->with('success', 'Gruppo aggiornato.'); } public function destroy($id) { $this->authorizeDelete('gruppi'); $gruppo = Gruppo::with('children', 'individui')->findOrFail($id); $hasChildren = $gruppo->children()->count() > 0; $isSuperAdmin = auth()->user()->isSuperAdmin(); if ($hasChildren && !$isSuperAdmin) { return redirect('/gruppi')->with('error', 'Solo il superamministratore può eliminare un gruppo con sottogruppi.'); } if ($hasChildren && $isSuperAdmin) { foreach ($gruppo->children as $child) { $this->destroyGruppo($child); } } $this->destroyGruppo($gruppo); return redirect('/gruppi')->with('success', 'Gruppo eliminato.'); } protected function destroyGruppo(Gruppo $gruppo): void { $gruppo->individui()->detach(); $gruppo->eventi()->detach(); foreach ($gruppo->documenti as $documento) { if ($documento->file_path && file_exists(storage_path('app/public/' . $documento->file_path))) { unlink(storage_path('app/public/' . $documento->file_path)); } } $gruppo->documenti()->delete(); $gruppo->delete(); } public function allGruppi() { $this->authorizeRead('gruppi'); $gruppi = Gruppo::select('id', 'nome') ->orderBy('nome') ->get() ->map(function($g) { return [ 'id' => $g->id, 'nome' => $g->nome, 'full_path' => $g->getFullPathAttribute(), ]; }); return response()->json($gruppi); } public function individuiEmail(Gruppo $gruppo) { $this->authorizeRead('gruppi'); $individui = $gruppo->individui()->with('contatti')->get(); $result = $individui->map(function($ind) { $emails = $ind->contatti->where('tipo', 'email')->pluck('valore')->toArray(); return [ 'id' => $ind->id, 'codice_id' => $ind->codice_id, 'cognome' => $ind->cognome, 'nome' => $ind->nome, 'emails' => $emails, ]; }); return response()->json($result); } public function saveVista(Request $request) { $data = $request->validate([ 'nome' => 'required|string|max:255', 'colonne_visibili' => 'nullable|array', 'colonne_visibili.*' => 'string', 'is_default' => 'nullable|boolean', ]); if (!empty($data['is_default'])) { \App\Models\VistaReport::where('user_id', auth()->id()) ->where('tipo', 'gruppi') ->where('is_default', true) ->update(['is_default' => false]); } $vista = \App\Models\VistaReport::create([ 'user_id' => auth()->id(), 'nome' => $data['nome'], 'tipo' => 'gruppi', 'colonne_visibili' => $data['colonne_visibili'] ?? [], 'is_default' => !empty($data['is_default']), ]); return response()->json(['success' => true, 'vista_id' => $vista->id]); } public function deleteVista($id) { $vista = \App\Models\VistaReport::where('user_id', auth()->id()) ->where('id', $id) ->firstOrFail(); $vista->delete(); return redirect()->route('gruppi.index')->with('success', 'Vista eliminata.'); } }