has('stabile_id') && $request->stabile_id) { $query->where('stabile_id', $request->stabile_id); } if ($request->has('tipo_tabella') && $request->tipo_tabella) { $query->where('tipo_tabella', $request->tipo_tabella); } if ($request->has('solo_attive') && $request->solo_attive) { $query->where('attiva', true); } // Applica ordinamento personalizzato (ordinamento, codice, nome) $tabelle = $query->ordinato()->get(); $stabili = Stabile::orderBy('denominazione')->get(); return view('admin.tabelle-millesimali.index', compact('tabelle', 'stabili')); } /** * Show the form for creating a new resource. */ public function create() { return view('admin.tabelle-millesimali.create', [ 'title' => 'Nuova Tabella Millesimale', 'breadcrumb' => [ 'Dashboard' => route('admin.dashboard'), 'Tabelle Millesimali' => route('admin.tabelle-millesimali.index'), 'Nuova Tabella' => '' ] ]); } /** * Store a newly created resource in storage. */ public function store(Request $request) { $validated = $request->validate([ 'stabile_id' => 'required|exists:stabili,id', 'nome_tabella' => 'required|string|max:255', 'codice_tabella' => 'nullable|string|max:255', 'tipo_tabella' => 'required|in:proprieta,riscaldamento,ascensore,scale,pulizie,antenna_tv,portineria,cortile,custom,temporanea', 'descrizione' => 'nullable|string', 'data_decorrenza' => 'nullable|date', 'totale_millesimi' => 'required|numeric|min:0', 'attiva' => 'boolean' ]); $validated['attiva'] = $request->has('attiva'); $validated['stato_tabella'] = $validated['attiva'] ? 'attiva' : 'sospesa'; $validated['created_by'] = auth()->id(); $tabella = TabellaMillesimale::create($validated); return response()->json([ 'success' => true, 'message' => 'Tabella millesimale creata con successo', 'tabella_id' => $tabella->id ]); } /** * Display the specified resource. */ public function show(TabellaMillesimale $tabellaMillesimale) { $tabellaMillesimale->load(['stabile', 'dettagliTabelle.unitaImmobiliare']); // Calcola statistiche $statistiche = [ 'unita_configurate' => $tabellaMillesimale->dettagliTabelle->count(), 'unita_totali' => $tabellaMillesimale->stabile->unitaImmobiliari->count(), 'millesimi_assegnati' => $tabellaMillesimale->dettagliTabelle->sum('millesimi'), 'millesimi_residui' => $tabellaMillesimale->totale_millesimi - $tabellaMillesimale->dettagliTabelle->sum('millesimi') ]; return view('admin.tabelle-millesimali.show', compact('tabellaMillesimale', 'statistiche')); } /** * Sospendi tabella */ public function sospendi(TabellaMillesimale $tabellaMillesimale) { $tabellaMillesimale->update([ 'attiva' => false, 'stato_tabella' => 'sospesa' ]); return response()->json([ 'success' => true, 'message' => 'Tabella sospesa con successo' ]); } /** * Riattiva tabella */ public function riattiva(TabellaMillesimale $tabellaMillesimale) { $tabellaMillesimale->update([ 'attiva' => true, 'stato_tabella' => 'attiva' ]); return response()->json([ 'success' => true, 'message' => 'Tabella riattivata con successo' ]); } /** * Configura millesimi per unità immobiliari */ public function configuraMillesimi(TabellaMillesimale $tabellaMillesimale) { $tabellaMillesimale->load(['stabile.unitaImmobiliari', 'dettagliTabelle']); // Calcola statistiche $statistiche = [ 'unita_configurate' => $tabellaMillesimale->dettagliTabelle->count(), 'unita_totali' => $tabellaMillesimale->stabile->unitaImmobiliari->count(), 'millesimi_assegnati' => $tabellaMillesimale->dettagliTabelle->sum('millesimi'), 'millesimi_residui' => $tabellaMillesimale->totale_millesimi - $tabellaMillesimale->dettagliTabelle->sum('millesimi') ]; return view('admin.tabelle-millesimali.configura-millesimi', compact('tabellaMillesimale', 'statistiche')); } /** * Show the form for editing the specified resource. */ public function edit(string $id) { return view('admin.tabelle-millesimali.edit', [ 'title' => 'Modifica Tabella Millesimale', 'breadcrumb' => [ 'Dashboard' => route('admin.dashboard'), 'Tabelle Millesimali' => route('admin.tabelle-millesimali.index'), 'Modifica' => '' ] ]); } /** * Update the specified resource in storage. */ public function update(Request $request, string $id) { // TODO: Implement update logic return redirect()->route('admin.tabelle-millesimali.index') ->with('success', 'Tabella millesimale aggiornata con successo.'); } /** * Remove the specified resource from storage. */ public function destroy(TabellaMillesimale $tabellaMillesimale) { try { // Verifica se la tabella ha dettagli associati if ($tabellaMillesimale->dettagliTabelle()->count() > 0) { return response()->json([ 'success' => false, 'message' => 'Impossibile eliminare la tabella: sono presenti millesimi configurati.' ], 422); } // Verifica se è utilizzata in ripartizioni spese if ($tabellaMillesimale->ripartizioniSpese()->count() > 0) { return response()->json([ 'success' => false, 'message' => 'Impossibile eliminare la tabella: è utilizzata in ripartizioni spese.' ], 422); } $nome = $tabellaMillesimale->nome_tabella; $tabellaMillesimale->delete(); return response()->json([ 'success' => true, 'message' => "Tabella millesimale '{$nome}' eliminata con successo." ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'message' => 'Errore durante l\'eliminazione della tabella: ' . $e->getMessage() ], 500); } } /** * Bilancia automaticamente la tabella millesimale */ public function bilancia(TabellaMillesimale $tabellaMillesimale) { try { $dettagli = $tabellaMillesimale->dettagliTabelle; if ($dettagli->count() == 0) { return response()->json([ 'success' => false, 'message' => 'Impossibile bilanciare una tabella senza millesimi assegnati.' ], 422); } $totaleCorrente = $dettagli->sum('millesimi'); if ($totaleCorrente == 0) { return response()->json([ 'success' => false, 'message' => 'Impossibile bilanciare una tabella con totale millesimi pari a zero.' ], 422); } $fattoreCorrezione = 1000 / $totaleCorrente; foreach ($dettagli as $dettaglio) { $nuoviMillesimi = round($dettaglio->millesimi * $fattoreCorrezione, 4); $dettaglio->update(['millesimi' => $nuoviMillesimi]); } // Aggiorna il totale nella tabella $nuovoTotale = $tabellaMillesimale->dettagliTabelle()->sum('millesimi'); $tabellaMillesimale->update(['totale_millesimi' => $nuovoTotale]); return response()->json([ 'success' => true, 'message' => 'Tabella bilanciata con successo.', 'nuovo_totale' => number_format($nuovoTotale, 4, '.', '') ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'message' => 'Errore durante il bilanciamento: ' . $e->getMessage() ], 500); } } /** * Ottieni le voci di spesa associate a una tabella millesimale */ public function getVociSpesa(TabellaMillesimale $tabellaMillesimale) { $voci = $tabellaMillesimale->vociSpesa() ->orderBy('ordinamento', 'asc') ->orderBy('codice', 'asc') ->get(); return response()->json([ 'tabella' => [ 'id' => $tabellaMillesimale->id, 'nome_tabella' => $tabellaMillesimale->nome_tabella, 'codice_tabella' => $tabellaMillesimale->codice_tabella, ], 'voci' => $voci->map(function ($voce) { return [ 'id' => $voce->id, 'codice' => $voce->codice, 'descrizione' => $voce->descrizione, 'importo' => $voce->importo ?? 0, 'categoria' => $voce->categoria, 'attiva' => $voce->attiva ]; }) ]); } /** * Salva la configurazione dei millesimi */ public function storeMillesimi(Request $request, TabellaMillesimale $tabellaMillesimale) { $request->validate([ 'millesimi' => 'required|array', 'millesimi.*' => 'numeric|min:0|max:1000' ]); try { DB::beginTransaction(); // Prima elimina tutti i dettagli esistenti $tabellaMillesimale->dettagliTabelle()->delete(); $millesimiTotali = 0; $dettagliCreati = 0; // Crea i nuovi dettagli foreach ($request->millesimi as $unitaId => $millesimi) { if (is_numeric($millesimi) && $millesimi > 0) { DettaglioTabellaMillesimale::create([ 'tabella_millesimale_id' => $tabellaMillesimale->id, 'unita_immobiliare_id' => $unitaId, 'millesimi' => $millesimi ]); $millesimiTotali += $millesimi; $dettagliCreati++; } } // Aggiorna il totale nella tabella millesimale $tabellaMillesimale->update([ 'totale_millesimi' => $millesimiTotali ]); DB::commit(); return response()->json([ 'success' => true, 'message' => "Configurazione salvata con successo! {$dettagliCreati} unità configurate con totale {$millesimiTotali} millesimi." ]); } catch (\Exception $e) { DB::rollBack(); Log::error('Errore salvataggio millesimi: ' . $e->getMessage()); return response()->json([ 'success' => false, 'message' => 'Errore durante il salvataggio della configurazione.' ], 500); } } /** * Salva i millesimi via JSON (per interfaccia avanzata) */ public function salvaMillesimi(Request $request, TabellaMillesimale $tabellaMillesimale) { $request->validate([ 'millesimi' => 'required|array', 'millesimi.*.unita_immobiliare_id' => 'required|exists:unita_immobiliari,id', 'millesimi.*.millesimi' => 'required|numeric|min:0|max:1000' ]); try { DB::beginTransaction(); // Elimina tutti i dettagli esistenti $tabellaMillesimale->dettagliTabelle()->delete(); $millesimiTotali = 0; $dettagliCreati = 0; // Crea i nuovi dettagli foreach ($request->millesimi as $dettaglio) { DettaglioTabellaMillesimale::create([ 'tabella_millesimale_id' => $tabellaMillesimale->id, 'unita_immobiliare_id' => $dettaglio['unita_immobiliare_id'], 'millesimi' => $dettaglio['millesimi'] ]); $millesimiTotali += $dettaglio['millesimi']; $dettagliCreati++; } // Aggiorna il totale nella tabella millesimale $tabellaMillesimale->update([ 'totale_millesimi' => $millesimiTotali ]); DB::commit(); return response()->json([ 'success' => true, 'message' => "Millesimi salvati con successo! {$dettagliCreati} unità configurate per un totale di " . number_format($millesimiTotali, 4, ',', '.') . " millesimi." ]); } catch (\Exception $e) { DB::rollBack(); Log::error('Errore salvataggio millesimi JSON: ' . $e->getMessage()); return response()->json([ 'success' => false, 'message' => 'Errore durante il salvataggio dei millesimi.' ], 500); } } }