283 lines
11 KiB
PHP
283 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\VoceSpesa;
|
|
use App\Models\Stabile;
|
|
use App\Models\TabellaMillesimale;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Str;
|
|
|
|
class VoceSpesaController extends Controller
|
|
{
|
|
/**
|
|
* Display a listing of the resource.
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
$query = VoceSpesa::with(['stabile', 'tabellaMillesimaleDefault'])
|
|
->whereHas('stabile', function($q) {
|
|
$q->where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null);
|
|
});
|
|
|
|
// Filtro per stabile
|
|
if ($request->filled('stabile_id')) {
|
|
$query->where('stabile_id', $request->stabile_id);
|
|
}
|
|
|
|
// Filtro per categoria
|
|
if ($request->filled('categoria')) {
|
|
$query->where('categoria', $request->categoria);
|
|
}
|
|
|
|
// Filtro per stato
|
|
if ($request->filled('stato')) {
|
|
$query->where('stato', $request->stato);
|
|
}
|
|
|
|
// Ricerca per denominazione
|
|
if ($request->filled('search')) {
|
|
$query->where('denominazione', 'like', '%' . $request->search . '%');
|
|
}
|
|
|
|
$vociSpesa = $query->orderBy('denominazione')->paginate(15);
|
|
|
|
// Dati per i filtri
|
|
$stabili = Stabile::where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null)
|
|
->orderBy('denominazione')
|
|
->get();
|
|
|
|
$categorie = VoceSpesa::distinct()->pluck('categoria')->filter()->sort();
|
|
|
|
return view('admin.voci-spesa.index', compact('vociSpesa', 'stabili', 'categorie'));
|
|
}
|
|
|
|
/**
|
|
* Show the form for creating a new resource.
|
|
*/
|
|
public function create()
|
|
{
|
|
$stabili = Stabile::where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null)
|
|
->orderBy('denominazione')
|
|
->get();
|
|
|
|
$tabelleMillesimali = TabellaMillesimale::whereHas('stabile', function($q) {
|
|
$q->where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null);
|
|
})
|
|
->orderBy('denominazione')
|
|
->get();
|
|
|
|
return view('admin.voci-spesa.create', compact('stabili', 'tabelleMillesimali'));
|
|
}
|
|
|
|
/**
|
|
* Store a newly created resource in storage.
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
$request->validate([
|
|
'stabile_id' => 'required|exists:stabili,id',
|
|
'denominazione' => 'required|string|max:255',
|
|
'categoria' => 'required|string|max:100',
|
|
'sottocategoria' => 'nullable|string|max:100',
|
|
'descrizione' => 'nullable|string',
|
|
'importo_previsto' => 'nullable|numeric|min:0',
|
|
'periodicita' => 'nullable|in:una_tantum,mensile,trimestrale,semestrale,annuale',
|
|
'tabella_millesimale_default_id' => 'required|exists:tabelle_millesimali,id',
|
|
'ripartizione_personalizzata' => 'nullable|boolean',
|
|
'stato' => 'required|in:attiva,inattiva,archiviata',
|
|
'note' => 'nullable|string',
|
|
'tags' => 'nullable|string|max:500',
|
|
]);
|
|
|
|
// Verifica che lo stabile appartenga all'amministratore
|
|
$stabile = Stabile::where('id', $request->stabile_id)
|
|
->where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null)
|
|
->firstOrFail();
|
|
|
|
// Verifica che la tabella millesimale appartenga allo stabile
|
|
$tabellaMillesimale = TabellaMillesimale::where('id', $request->tabella_millesimale_default_id)
|
|
->where('stabile_id', $request->stabile_id)
|
|
->firstOrFail();
|
|
|
|
$voceSpesa = VoceSpesa::create([
|
|
'codice_spesa' => $this->generateCodiceSpesa(),
|
|
'stabile_id' => $request->stabile_id,
|
|
'denominazione' => $request->denominazione,
|
|
'categoria' => $request->categoria,
|
|
'sottocategoria' => $request->sottocategoria,
|
|
'descrizione' => $request->descrizione,
|
|
'importo_previsto' => $request->importo_previsto,
|
|
'periodicita' => $request->periodicita,
|
|
'tabella_millesimale_default_id' => $request->tabella_millesimale_default_id,
|
|
'ripartizione_personalizzata' => $request->boolean('ripartizione_personalizzata'),
|
|
'stato' => $request->stato,
|
|
'note' => $request->note,
|
|
'tags' => $request->tags,
|
|
'created_by' => Auth::id(),
|
|
]);
|
|
|
|
return redirect()->route('admin.voci-spesa.index')
|
|
->with('success', 'Voce di spesa creata con successo.');
|
|
}
|
|
|
|
/**
|
|
* Display the specified resource.
|
|
*/
|
|
public function show(VoceSpesa $voceSpesa)
|
|
{
|
|
// Verifica autorizzazione
|
|
$this->authorize('view', $voceSpesa);
|
|
|
|
$voceSpesa->load(['stabile', 'tabellaMillesimaleDefault', 'ripartizioniSpese.dettagli.unitaImmobiliare']);
|
|
|
|
return view('admin.voci-spesa.show', compact('voceSpesa'));
|
|
}
|
|
|
|
/**
|
|
* Show the form for editing the specified resource.
|
|
*/
|
|
public function edit(VoceSpesa $voceSpesa)
|
|
{
|
|
// Verifica autorizzazione
|
|
$this->authorize('update', $voceSpesa);
|
|
|
|
$stabili = Stabile::where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null)
|
|
->orderBy('denominazione')
|
|
->get();
|
|
|
|
$tabelleMillesimali = TabellaMillesimale::where('stabile_id', $voceSpesa->stabile_id)
|
|
->orderBy('denominazione')
|
|
->get();
|
|
|
|
return view('admin.voci-spesa.edit', compact('voceSpesa', 'stabili', 'tabelleMillesimali'));
|
|
}
|
|
|
|
/**
|
|
* Update the specified resource in storage.
|
|
*/
|
|
public function update(Request $request, VoceSpesa $voceSpesa)
|
|
{
|
|
// Verifica autorizzazione
|
|
$this->authorize('update', $voceSpesa);
|
|
|
|
$request->validate([
|
|
'denominazione' => 'required|string|max:255',
|
|
'categoria' => 'required|string|max:100',
|
|
'sottocategoria' => 'nullable|string|max:100',
|
|
'descrizione' => 'nullable|string',
|
|
'importo_previsto' => 'nullable|numeric|min:0',
|
|
'periodicita' => 'nullable|in:una_tantum,mensile,trimestrale,semestrale,annuale',
|
|
'tabella_millesimale_default_id' => 'required|exists:tabelle_millesimali,id',
|
|
'ripartizione_personalizzata' => 'nullable|boolean',
|
|
'stato' => 'required|in:attiva,inattiva,archiviata',
|
|
'note' => 'nullable|string',
|
|
'tags' => 'nullable|string|max:500',
|
|
]);
|
|
|
|
// Verifica che la tabella millesimale appartenga allo stabile
|
|
$tabellaMillesimale = TabellaMillesimale::where('id', $request->tabella_millesimale_default_id)
|
|
->where('stabile_id', $voceSpesa->stabile_id)
|
|
->firstOrFail();
|
|
|
|
$voceSpesa->update([
|
|
'denominazione' => $request->denominazione,
|
|
'categoria' => $request->categoria,
|
|
'sottocategoria' => $request->sottocategoria,
|
|
'descrizione' => $request->descrizione,
|
|
'importo_previsto' => $request->importo_previsto,
|
|
'periodicita' => $request->periodicita,
|
|
'tabella_millesimale_default_id' => $request->tabella_millesimale_default_id,
|
|
'ripartizione_personalizzata' => $request->boolean('ripartizione_personalizzata'),
|
|
'stato' => $request->stato,
|
|
'note' => $request->note,
|
|
'tags' => $request->tags,
|
|
'updated_by' => Auth::id(),
|
|
]);
|
|
|
|
return redirect()->route('admin.voci-spesa.index')
|
|
->with('success', 'Voce di spesa aggiornata con successo.');
|
|
}
|
|
|
|
/**
|
|
* Remove the specified resource from storage.
|
|
*/
|
|
public function destroy(VoceSpesa $voceSpesa)
|
|
{
|
|
// Verifica autorizzazione
|
|
$this->authorize('delete', $voceSpesa);
|
|
|
|
// Verifica che non ci siano ripartizioni associate
|
|
if ($voceSpesa->ripartizioniSpese()->exists()) {
|
|
return redirect()->route('admin.voci-spesa.index')
|
|
->with('error', 'Impossibile eliminare la voce di spesa: esistono ripartizioni associate.');
|
|
}
|
|
|
|
$voceSpesa->delete();
|
|
|
|
return redirect()->route('admin.voci-spesa.index')
|
|
->with('success', 'Voce di spesa eliminata con successo.');
|
|
}
|
|
|
|
/**
|
|
* Duplica una voce di spesa esistente
|
|
*/
|
|
public function duplicate(VoceSpesa $voceSpesa)
|
|
{
|
|
// Verifica autorizzazione
|
|
$this->authorize('view', $voceSpesa);
|
|
|
|
$nuovaVoceSpesa = $voceSpesa->replicate();
|
|
$nuovaVoceSpesa->codice_spesa = $this->generateCodiceSpesa();
|
|
$nuovaVoceSpesa->denominazione = $voceSpesa->denominazione . ' (Copia)';
|
|
$nuovaVoceSpesa->stato = 'inattiva';
|
|
$nuovaVoceSpesa->created_by = Auth::id();
|
|
$nuovaVoceSpesa->save();
|
|
|
|
return redirect()->route('admin.voci-spesa.edit', $nuovaVoceSpesa)
|
|
->with('success', 'Voce di spesa duplicata con successo.');
|
|
}
|
|
|
|
/**
|
|
* Ottieni le tabelle millesimali per uno stabile (AJAX)
|
|
*/
|
|
public function getTabelleMillesimali(Request $request)
|
|
{
|
|
$stabileId = $request->get('stabile_id');
|
|
|
|
if (!$stabileId) {
|
|
return response()->json([]);
|
|
}
|
|
|
|
// Verifica che lo stabile appartenga all'amministratore
|
|
$stabile = Stabile::where('id', $stabileId)
|
|
->where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null)
|
|
->first();
|
|
|
|
if (!$stabile) {
|
|
return response()->json([]);
|
|
}
|
|
|
|
$tabelle = TabellaMillesimale::where('stabile_id', $stabileId)
|
|
->where('stato', 'attiva')
|
|
->orderBy('denominazione')
|
|
->get(['id', 'denominazione', 'tipo_tabella']);
|
|
|
|
return response()->json($tabelle);
|
|
}
|
|
|
|
/**
|
|
* Genera un codice spesa univoco
|
|
*/
|
|
private function generateCodiceSpesa(): string
|
|
{
|
|
do {
|
|
$codice = 'SP' . strtoupper(Str::random(6));
|
|
} while (VoceSpesa::where('codice_spesa', $codice)->exists());
|
|
|
|
return $codice;
|
|
}
|
|
}
|