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

491 lines
18 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Stabile;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class StabileController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$user = Auth::user();
// Collaboratore: mostra solo stabili assegnati via pivot
if ($user->hasRole('collaboratore')) {
$stabili = $user->stabiliAssegnati()->paginate(10);
} else {
// Amministratore: mostra solo i propri stabili
$amministratore = $user->amministratore ?? null;
$amministratore_id = $amministratore ? $amministratore->id : null;
if (!$amministratore_id) {
$stabili = Stabile::whereRaw('1=0')->paginate(10);
} else {
$stabili = Stabile::where('amministratore_id', $amministratore_id)->paginate(10);
}
}
return view('admin.stabili.index', compact('stabili'));
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
if (Auth::user()->hasRole('collaboratore')) {
abort(403, 'I collaboratori non possono creare nuovi stabili');
}
return view('admin.stabili.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
if (Auth::user()->hasRole('collaboratore')) {
abort(403, 'I collaboratori non possono creare nuovi stabili');
}
$request->validate([
'denominazione' => 'required|string|max:255',
'codice_fiscale' => 'nullable|string|max:20|unique:stabili,codice_fiscale',
'cod_fisc_amministratore' => 'nullable|string|max:20',
'indirizzo' => 'required|string|max:255',
'citta' => 'required|string|max:255',
'cap' => 'required|string|max:10',
'provincia' => 'nullable|string|max:2',
'stato' => 'required|in:attivo,inattivo',
'note' => 'nullable|string',
'old_id' => 'nullable|integer|unique:stabili,old_id',
]);
$stabile = Stabile::create([
'amministratore_id' => (Auth::user()->amministratore->id ?? null),
'denominazione' => $request->denominazione,
'codice_fiscale' => $request->codice_fiscale,
'cod_fisc_amministratore' => $request->cod_fisc_amministratore,
'indirizzo' => $request->indirizzo,
'citta' => $request->citta,
'cap' => $request->cap,
'provincia' => $request->provincia,
'stato' => $request->stato,
'note' => $request->note,
'old_id' => $request->old_id,
]);
return redirect()->route('admin.stabili.index')
->with('success', 'Stabile creato con successo.');
}
/**
* Display the specified resource.
*/
public function show(Stabile $stabile)
{
$user = Auth::user();
// Autorizzazione: amministratore proprietario o collaboratore assegnato
$allowed = false;
if ($user->hasRole('collaboratore')) {
$allowed = $user->stabiliAssegnati()->where('stabili.id', $stabile->id)->exists();
} else {
$amministratore = $user->amministratore ?? null;
$allowed = $amministratore && $stabile->amministratore_id === $amministratore->id;
}
if (!$allowed) {
abort(403, 'Non hai i permessi per visualizzare questo stabile');
}
// Caricamento minimale le altre relazioni sono lazy via endpoints tab
$stabile->load(['amministratore']);
return view('admin.stabili.show', compact('stabile'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Stabile $stabile)
{
// I collaboratori non possono modificare
if (Auth::user()->hasRole('collaboratore')) {
abort(403, 'I collaboratori non possono modificare gli stabili');
}
// Verifica che l'utente possa modificare questo stabile
$amministratore = Auth::user()->amministratore ?? null;
$amministratore_id = $amministratore ? $amministratore->id : null;
if ($stabile->amministratore_id !== $amministratore_id) {
abort(403, 'Non hai i permessi per modificare questo stabile');
}
return view('admin.stabili.edit', compact('stabile'));
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Stabile $stabile)
{
// I collaboratori non possono modificare
if (Auth::user()->hasRole('collaboratore')) {
abort(403, 'I collaboratori non possono modificare gli stabili');
}
// Verifica che l'utente possa modificare questo stabile
$amministratore = Auth::user()->amministratore ?? null;
$amministratore_id = $amministratore ? $amministratore->id : null;
if ($stabile->amministratore_id !== $amministratore_id) {
abort(403, 'Non hai i permessi per modificare questo stabile');
}
$request->validate([
'denominazione' => 'required|string|max:255',
'codice_fiscale' => 'nullable|string|max:20|unique:stabili,codice_fiscale,' . $stabile->id,
'cod_fisc_amministratore' => 'nullable|string|max:20',
'indirizzo' => 'required|string|max:255',
'citta' => 'required|string|max:255',
'cap' => 'required|string|max:10',
'provincia' => 'nullable|string|max:2',
'stato' => 'required|in:attivo,inattivo',
'note' => 'nullable|string',
'old_id' => 'nullable|integer|unique:stabili,old_id,' . $stabile->id,
]);
$stabile->update($request->all());
return redirect()->route('admin.stabili.index')
->with('success', 'Stabile aggiornato con successo.');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Stabile $stabile)
{
// I collaboratori non possono eliminare
if (Auth::user()->hasRole('collaboratore')) {
abort(403, 'I collaboratori non possono eliminare gli stabili');
}
// Verifica che l'utente possa eliminare questo stabile
$amministratore = Auth::user()->amministratore ?? null;
$amministratore_id = $amministratore ? $amministratore->id : null;
if ($stabile->amministratore_id !== $amministratore_id) {
abort(403);
}
$stabile->delete();
return redirect()->route('admin.stabili.index')
->with('success', 'Stabile eliminato con successo.');
}
/**
* Get tabella millesimali details for Excel-like view (API)
*/
public function getTabellaMillesimaliDettagli(Stabile $stabile, $tabellaId)
{
if (!$this->canAccessStabile($stabile)) {
return response()->json(['error' => 'Unauthorized'], 403);
}
$tabella = $stabile->tabelleMillesimali()->with('dettagli.unitaImmobiliare')->findOrFail($tabellaId);
$dettagli = $tabella->dettagli->map(function ($dettaglio) {
return [
'id' => $dettaglio->id,
'scala' => $dettaglio->unitaImmobiliare->scala ?? 'N/A',
'interno' => $dettaglio->unitaImmobiliare->interno ?? 'N/A',
'descrizione' => $dettaglio->unitaImmobiliare->descrizione ?? $dettaglio->descrizione_unita,
'millesimi' => (float)$dettaglio->millesimi,
'proprietario' => $dettaglio->unitaImmobiliare->getNomeProprietarioAttribute() ?? 'N/A'
];
});
$totaleMillesimi = $dettagli->sum('millesimi');
$bilanciato = abs($totaleMillesimi - 1000) < 0.01;
return response()->json([
'success' => true,
'tabella' => [
'id' => $tabella->id,
'codice' => $tabella->codice_tabella,
'denominazione' => $tabella->denominazione ?: $tabella->nome_tabella,
'tipo' => $tabella->tipo_tabella ?: $tabella->tipo,
'totale_millesimi' => $totaleMillesimi,
'bilanciata' => $bilanciato,
'differenza' => $totaleMillesimi - 1000
],
'dettagli' => $dettagli,
'statistiche' => [
'unita_count' => $dettagli->count(),
'millesimo_medio' => $dettagli->count() > 0 ? $dettagli->avg('millesimi') : 0,
'millesimo_max' => $dettagli->max('millesimi') ?? 0,
'millesimo_min' => $dettagli->min('millesimi') ?? 0
]
]);
}
/**
* Update a single millesimo value (API)
*/
public function aggiornaMillesimo(Request $request, Stabile $stabile, $tabellaId)
{
// Solo amministratore proprietario può modificare millesimi
if (!$this->isOwnerAmministratore($stabile)) {
return response()->json(['error' => 'Unauthorized'], 403);
}
$request->validate([
'dettaglio_id' => 'required|integer',
'nuovo_valore' => 'required|numeric|min:0'
]);
$tabella = $stabile->tabelleMillesimali()->findOrFail($tabellaId);
$dettaglio = $tabella->dettagli()->findOrFail($request->dettaglio_id);
$vecchioValore = $dettaglio->millesimi;
$dettaglio->update([
'millesimi' => $request->nuovo_valore,
'modificato_da' => Auth::id()
]);
// Ricalcola il totale della tabella
$nuovoTotale = $tabella->dettagli()->sum('millesimi');
$tabella->update([
'totale_millesimi' => $nuovoTotale,
'modificato_da' => Auth::id()
]);
return response()->json([
'success' => true,
'message' => 'Millesimo aggiornato con successo',
'vecchio_valore' => $vecchioValore,
'nuovo_valore' => $request->nuovo_valore,
'nuovo_totale' => $nuovoTotale,
'bilanciata' => abs($nuovoTotale - 1000) < 0.01
]);
}
/**
* Verify tabella millesimali balance (API)
*/
public function verificaBilanciamento(Stabile $stabile, $tabellaId)
{
if (!$this->canAccessStabile($stabile)) {
return response()->json(['error' => 'Unauthorized'], 403);
}
$tabella = $stabile->tabelleMillesimali()->findOrFail($tabellaId);
$totaleMillesimi = $tabella->dettagli()->sum('millesimi');
$differenza = $totaleMillesimi - 1000;
$bilanciata = abs($differenza) < 0.01;
// Aggiorna il totale nella tabella
$tabella->update([
'totale_millesimi' => $totaleMillesimi,
'modificato_da' => Auth::id()
]);
return response()->json([
'success' => true,
'bilanciata' => $bilanciata,
'totale_millesimi' => $totaleMillesimi,
'differenza' => $differenza,
'messaggio' => $bilanciata
? 'La tabella è correttamente bilanciata!'
: "La tabella non è bilanciata. Differenza: " . ($differenza > 0 ? '+' : '') . number_format($differenza, 4)
]);
}
/**
* Get Unità Immobiliari for AJAX tab loading
*/
public function getUnitaImmobiliari(Stabile $stabile)
{
// Verifica autorizzazione
if (!$this->canAccessStabile($stabile)) {
return response()->json(['error' => 'Unauthorized'], 403);
}
// Carica le unità immobiliari dello stabile
$unitaImmobiliari = $stabile->unitaImmobiliari()
->orderBy('codice_interno')
->orderBy('piano')
->orderBy('appartamento')
->get();
// Genera l'HTML della tabella
$html = view('admin.stabili.partials.unita-immobiliari-tab', compact('unitaImmobiliari', 'stabile'))->render();
return response()->json([
'success' => true,
'html' => $html
]);
}
/**
* Tab: Dati Generali (lightweight basic relations only)
*/
public function tabDatiGenerali(Stabile $stabile)
{
if (!$this->canAccessStabile($stabile)) {
return \response()->json(['error' => 'Unauthorized'], 403);
}
if (!$stabile->relationLoaded('amministratore')) {
$stabile->load('amministratore');
}
$html = \view('admin.stabili.tabs.dati-generali', compact('stabile'))->render();
return \response()->json(['success' => true, 'html' => $html]);
}
/**
* Tab: Palazzine
*/
public function tabPalazzine(Stabile $stabile)
{
if (!$this->canAccessStabile($stabile)) {
return \response()->json(['error' => 'Unauthorized'], 403);
}
if (!$stabile->relationLoaded('palazzine')) {
$stabile->load('palazzine');
}
$html = \view('admin.stabili.tabs.palazzine', compact('stabile'))->render();
return \response()->json(['success' => true, 'html' => $html]);
}
/**
* Tab: Dati Bancari
*/
public function tabDatiBancari(Stabile $stabile)
{
if (!$this->canAccessStabile($stabile)) {
return \response()->json(['error' => 'Unauthorized'], 403);
}
if (!$stabile->relationLoaded('datiBancari')) {
$stabile->load(['datiBancari.contatto']);
}
$html = \view('admin.stabili.tabs.dati-bancari', compact('stabile'))->render();
return \response()->json(['success' => true, 'html' => $html]);
}
/**
* Tab: Tabelle Millesimali
*/
public function tabTabelleMillesimali(Stabile $stabile)
{
if (!$this->canAccessStabile($stabile)) {
return \response()->json(['error' => 'Unauthorized'], 403);
}
if (!$stabile->relationLoaded('tabelleMillesimali')) {
$stabile->load(['tabelleMillesimali' => function ($q) {
$q->orderBy('ordinamento')->orderBy('nome_tabella');
}]);
}
if (!$stabile->relationLoaded('vociSpesa')) {
$stabile->load(['vociSpesa' => function ($q) {
$q->orderBy('ordinamento')->orderBy('descrizione');
}]);
}
$html = \view('admin.stabili.tabs.tabelle-millesimali', compact('stabile'))->render();
return \response()->json(['success' => true, 'html' => $html]);
}
/**
* Tab: Gestioni
*/
public function tabGestioni(Stabile $stabile)
{
if (!$this->canAccessStabile($stabile)) {
return \response()->json(['error' => 'Unauthorized'], 403);
}
if (!$stabile->relationLoaded('gestioniContabili')) {
$stabile->load('gestioniContabili');
}
$html = \view('admin.stabili.tabs.gestioni', compact('stabile'))->render();
return \response()->json(['success' => true, 'html' => $html]);
}
/**
* Tab: Unita Immobiliari (wrapper riusa endpoint esistente per lista)
*/
public function tabUnitaImmobiliari(Stabile $stabile)
{
if (!$this->canAccessStabile($stabile)) {
return \response()->json(['error' => 'Unauthorized'], 403);
}
// Carica count base; dettagli verranno fetchati da JS esistente (getUnitaImmobiliari)
$count = $stabile->unitaImmobiliari()->count();
$html = \view('admin.stabili.tabs.unita-immobiliari', compact('stabile', 'count'))->render();
return \response()->json(['success' => true, 'html' => $html]);
}
/**
* Tab: Gestione Documentale
*/
public function tabGestioneDocumentale(Stabile $stabile)
{
if (!$this->canAccessStabile($stabile)) {
return \response()->json(['error' => 'Unauthorized'], 403);
}
if (!$stabile->relationLoaded('documentiCollegati')) {
$stabile->load('documentiCollegati');
}
$html = \view('admin.stabili.tabs.gestione-documentale', compact('stabile'))->render();
return \response()->json(['success' => true, 'html' => $html]);
}
/**
* Carica appartamenti filtrati per il tab palazzine
*/
public function getAppartamenti(Request $request, $id)
{
$stabile = Stabile::findOrFail($id);
if (!$this->canAccessStabile($stabile)) {
abort(403);
}
$query = $stabile->unitaImmobiliari()->with(['soggetti' => function ($q) {
$q->withPivot('tipo_diritto');
}]);
// Filtro per scala
if ($request->scala) {
$query->where('scala', $request->scala);
}
// Filtro per presenza soggetti
if ($request->filtro == 'con-soggetti') {
$query->whereHas('soggetti');
} elseif ($request->filtro == 'senza-soggetti') {
$query->whereDoesntHave('soggetti');
}
$unita = $query->orderBy('piano')->orderBy('interno')->get();
return view('admin.stabili.tabs.partials.lista-appartamenti', compact('unita'))->render();
}
/**
* Helpers autorizzazione
*/
private function canAccessStabile(Stabile $stabile): bool
{
$user = Auth::user();
if ($user->hasRole('collaboratore')) {
return $user->stabiliAssegnati()->where('stabili.id', $stabile->id)->exists();
}
$amministratore = $user->amministratore ?? null;
return $amministratore && $stabile->amministratore_id === $amministratore->id;
}
private function isOwnerAmministratore(Stabile $stabile): bool
{
$user = Auth::user();
$amministratore = $user->amministratore ?? null;
return !$user->hasRole('collaboratore') && $amministratore && $stabile->amministratore_id === $amministratore->id;
}
}