491 lines
18 KiB
PHP
Executable File
491 lines
18 KiB
PHP
Executable File
<?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;
|
||
}
|
||
}
|