netgescon-day0/app/Http/Controllers/Admin/TabelleMillesimaliController.php

258 lines
8.7 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\GestioneCondominiale;
use App\Models\TabellaMillesimaleConti;
use App\Models\VoceSpesaMillesimale;
use App\Models\MillesimiUnita;
use App\Models\UnitaImmobiliare;
use App\Models\Stabile;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class TabelleMillesimaliController extends Controller
{
/**
* Display a listing of the resource
*/
public function index(Request $request)
{
$stabileId = $request->get('stabile_id');
$gestioneId = $request->get('gestione_id');
$stabili = Stabile::all();
$gestioni = collect();
$tabelle = collect();
if ($stabileId) {
$gestioni = GestioneCondominiale::where('stabile_id', $stabileId)
->orderBy('anno_inizio', 'desc')
->get();
if ($gestioneId) {
$tabelle = TabellaMillesimaleConti::where('gestione_id', $gestioneId)
->with('vociSpesa')
->orderBy('codice')
->get();
}
}
return view('admin.tabelle-millesimali.index', compact(
'stabili',
'gestioni',
'tabelle',
'stabileId',
'gestioneId'
));
}
/**
* Show the form for creating a new resource
*/
public function create(Request $request)
{
$gestioneId = $request->get('gestione_id');
$gestione = GestioneCondominiale::with('stabile')->findOrFail($gestioneId);
return view('admin.tabelle-millesimali.create', compact('gestione'));
}
/**
* Store a newly created resource in storage
*/
public function store(Request $request)
{
$validated = $request->validate([
'gestione_id' => 'required|exists:gestioni_condominiali,id',
'codice' => 'required|string|max:10',
'descrizione' => 'required|string|max:255',
'intestazione_colonne' => 'required|string|max:50',
'calcolo' => 'required|in:M,A,X,P',
'gestione_tipo' => 'required|in:O,R',
'decimali' => 'required|integer|min:0|max:4',
'unita_misura' => 'required|string|max:10',
'totale_millesimi' => 'required|numeric|min:0',
]);
// Verifica unicità codice per gestione
$exists = TabellaMillesimaleConti::where('gestione_id', $validated['gestione_id'])
->where('codice', $validated['codice'])
->exists();
if ($exists) {
return back()->withErrors(['codice' => 'Codice tabella già esistente per questa gestione.']);
}
$tabella = TabellaMillesimaleConti::create($validated);
return redirect()->route('admin.tabelle-millesimali.show', $tabella)
->with('success', 'Tabella millesimale creata con successo.');
}
/**
* Display the specified resource
*/
public function show(TabellaMillesimaleConti $tabelleMillesimali)
{
$tabella = $tabelleMillesimali->load([
'gestione.stabile',
'vociSpesa' => function ($q) {
$q->orderBy('codice_voce');
},
'millesimi.unitaImmobiliare' => function ($q) {
$q->orderBy('scala')->orderBy('piano')->orderBy('interno');
}
]);
// Statistiche della tabella
$stats = [
'totale_voci_spesa' => $tabella->vociSpesa->count(),
'totale_unita_coinvolte' => $tabella->millesimi->count(),
'somma_millesimi_assegnati' => $tabella->millesimi->sum('millesimi'),
'percentuale_copertura' => $tabella->totale_millesimi > 0 ?
round(($tabella->millesimi->sum('millesimi') / $tabella->totale_millesimi) * 100, 2) : 0,
'importo_preventivo_totale' => $tabella->vociSpesa->sum('importo_preventivo'),
'importo_consuntivo_totale' => $tabella->vociSpesa->sum('importo_consuntivo'),
];
return view('admin.tabelle-millesimali.show', compact('tabella', 'stats'));
}
/**
* Gestisci millesimi delle unità
*/
public function millesimi(TabellaMillesimaleConti $tabelleMillesimali)
{
$tabella = $tabelleMillesimali->load('gestione.stabile');
// Ottieni tutte le unità dello stabile
$unita = UnitaImmobiliare::whereHas('palazzina', function ($q) use ($tabella) {
$q->where('stabile_id', $tabella->gestione->stabile_id);
})
->with(['millesimi' => function ($q) use ($tabella) {
$q->where('tabella_millesimale_id', $tabella->id);
}])
->orderBy('scala')->orderBy('piano')->orderBy('interno')
->get();
return view('admin.tabelle-millesimali.millesimi', compact('tabella', 'unita'));
}
/**
* Salva millesimi delle unità
*/
public function salvaMillesimi(Request $request, TabellaMillesimaleConti $tabelleMillesimali)
{
$validated = $request->validate([
'millesimi' => 'required|array',
'millesimi.*' => 'nullable|numeric|min:0'
]);
DB::transaction(function () use ($validated, $tabelleMillesimali) {
foreach ($validated['millesimi'] as $unitaId => $valore) {
if ($valore !== null && $valore > 0) {
MillesimiUnita::updateOrCreate([
'unita_immobiliare_id' => $unitaId,
'tabella_millesimale_id' => $tabelleMillesimali->id,
], [
'millesimi' => $valore
]);
} else {
// Rimuovi se valore nullo o zero
MillesimiUnita::where('unita_immobiliare_id', $unitaId)
->where('tabella_millesimale_id', $tabelleMillesimali->id)
->delete();
}
}
});
return back()->with('success', 'Millesimi aggiornati con successo.');
}
/**
* Gestisci voci di spesa
*/
public function vociSpesa(TabellaMillesimaleConti $tabelleMillesimali)
{
$tabella = $tabelleMillesimali->load(['gestione.stabile', 'vociSpesa']);
return view('admin.tabelle-millesimali.voci-spesa', compact('tabella'));
}
/**
* Calcola ripartizioni per tutte le unità
*/
public function calcolaRipartizioni(TabellaMillesimaleConti $tabelleMillesimali, Request $request)
{
$tipoCalcolo = $request->get('tipo_calcolo', 'PREVENTIVO');
$anno = $request->get('anno', date('Y'));
$tabella = $tabelleMillesimali->load([
'vociSpesa',
'millesimi.unitaImmobiliare',
'gestione'
]);
$ripartizioni = [];
$totalePerUnita = [];
foreach ($tabella->vociSpesa as $voce) {
$importo = $tipoCalcolo === 'CONSUNTIVO' ?
($voce->importo_consuntivo ?? $voce->importo_preventivo) :
$voce->importo_preventivo;
if (!$importo) continue;
foreach ($tabella->millesimi as $millesimo) {
$unitaId = $millesimo->unita_immobiliare_id;
$quotaSpettante = $millesimo->calcolaQuotaSpettante($importo);
$ripartizioni[] = [
'unita_immobiliare_id' => $unitaId,
'voce_spesa_id' => $voce->id,
'gestione_id' => $tabella->gestione_id,
'importo_spettante' => $quotaSpettante,
'millesimi_applicati' => $millesimo->millesimi,
'tipo_calcolo' => $tipoCalcolo,
'anno_competenza' => $anno,
];
$totalePerUnita[$unitaId] = ($totalePerUnita[$unitaId] ?? 0) + $quotaSpettante;
}
}
return view('admin.tabelle-millesimali.ripartizioni', compact(
'tabella',
'ripartizioni',
'totalePerUnita',
'tipoCalcolo',
'anno'
));
}
/**
* Report riepilogativo tabelle millesimali
*/
public function report(Request $request)
{
$stabileId = $request->get('stabile_id');
$anno = $request->get('anno', date('Y'));
if (!$stabileId) {
return view('admin.tabelle-millesimali.report', ['stabili' => Stabile::all()]);
}
$stabile = Stabile::with([
'gestioniCondominiali' => function ($q) use ($anno) {
$q->byAnno($anno);
},
'gestioniCondominiali.tabelleMillesimali.vociSpesa',
'gestioniCondominiali.tabelleMillesimali.millesimi.unitaImmobiliare'
])->findOrFail($stabileId);
return view('admin.tabelle-millesimali.report', compact('stabile', 'stabileId', 'anno'));
}
}