888 lines
32 KiB
PHP
888 lines
32 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Stabile;
|
|
use App\Models\ChiaveStabile;
|
|
use App\Models\MovimentoChiave;
|
|
use App\Models\FondoCondominiale;
|
|
use App\Models\StrutturaFisicaDettaglio;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class StabileController extends Controller
|
|
{
|
|
/**
|
|
* Display a listing of the resource.
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
$stabili = Stabile::where('amministratore_id', Auth::user()->amministratore->id_amministratore ?? null)
|
|
->paginate(10);
|
|
|
|
// Se è una richiesta AJAX, restituisce solo la vista parziale
|
|
if ($request->ajax()) {
|
|
return view('admin.stabili.index-ajax', compact('stabili'));
|
|
}
|
|
|
|
return view('admin.stabili.index', compact('stabili'));
|
|
}
|
|
|
|
/**
|
|
* Show the form for creating a new resource.
|
|
*/
|
|
public function create()
|
|
{
|
|
// Passa le variabili necessarie per la sidebar
|
|
$userRole = 'admin';
|
|
$userPermissions = [
|
|
'dashboard' => true,
|
|
'stabili' => true,
|
|
'condomini' => true,
|
|
'tickets' => true,
|
|
'super_admin' => false
|
|
];
|
|
|
|
return view('admin.stabili.create', compact('userRole', 'userPermissions'));
|
|
}
|
|
|
|
/**
|
|
* Restituisce solo il form di creazione per richieste AJAX
|
|
*/
|
|
public function createForm()
|
|
{
|
|
if (request()->ajax()) {
|
|
return view('admin.stabili._form-bootstrap', ['stabile' => null]);
|
|
}
|
|
|
|
// Se non è AJAX, passa le variabili per la sidebar
|
|
$userRole = 'admin';
|
|
$userPermissions = [
|
|
'dashboard' => true,
|
|
'stabili' => true,
|
|
'condomini' => true,
|
|
'tickets' => true,
|
|
'super_admin' => false
|
|
];
|
|
|
|
return redirect()->route('admin.stabili.create')->with(compact('userRole', 'userPermissions'));
|
|
}
|
|
|
|
/**
|
|
* Store a newly created resource in storage.
|
|
*/
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([
|
|
'denominazione' => 'required|string|max:255',
|
|
'codice_stabile' => 'nullable|string|max:50',
|
|
'codice_fiscale' => 'nullable|string|max:20',
|
|
'partita_iva' => 'nullable|string|max:20',
|
|
'indirizzo' => 'required|string|max:255',
|
|
'citta' => 'required|string|max:255',
|
|
'cap' => 'required|string|max:10',
|
|
'provincia' => 'nullable|string|max:2',
|
|
'note' => 'nullable|string',
|
|
|
|
// Campi bancari
|
|
'iban_principale' => 'nullable|string|max:34',
|
|
'banca_principale' => 'nullable|string|max:255',
|
|
'filiale' => 'nullable|string|max:255',
|
|
'iban_secondario' => 'nullable|string|max:34',
|
|
'banca_secondaria' => 'nullable|string|max:255',
|
|
'filiale_secondaria' => 'nullable|string|max:255',
|
|
|
|
// Amministratore
|
|
'amministratore_nome' => 'nullable|string|max:255',
|
|
'amministratore_email' => 'nullable|email|max:255',
|
|
'data_nomina' => 'nullable|date',
|
|
'scadenza_mandato' => 'nullable|date',
|
|
|
|
// Dati catastali
|
|
'foglio' => 'nullable|string|max:20',
|
|
'mappale' => 'nullable|string|max:20',
|
|
'subalterno' => 'nullable|string|max:20',
|
|
'categoria' => 'nullable|string|max:20',
|
|
'rendita_catastale' => 'nullable|numeric',
|
|
'superficie_catastale' => 'nullable|numeric',
|
|
|
|
// Palazzine e Locali
|
|
'palazzine' => 'nullable|array',
|
|
'palazzine.*.numero' => 'nullable|string|max:10',
|
|
'palazzine.*.indirizzo' => 'nullable|string|max:255',
|
|
'palazzine.*.scala' => 'nullable|string|max:10',
|
|
'palazzine.*.interni' => 'nullable|integer|min:0',
|
|
'palazzine.*.piani' => 'nullable|integer|min:0',
|
|
|
|
'locali' => 'nullable|array',
|
|
'locali.*.tipo' => 'nullable|string|max:50',
|
|
'locali.*.descrizione' => 'nullable|string|max:255',
|
|
'locali.*.ubicazione' => 'nullable|string|max:100',
|
|
]);
|
|
|
|
// Auto-genera codice stabile se non fornito
|
|
if (empty($validated['codice_stabile'])) {
|
|
$validated['codice_stabile'] = $this->generateCodiceStabile();
|
|
}
|
|
|
|
// Prepara dati JSON per palazzine
|
|
if (isset($validated['palazzine'])) {
|
|
$validated['palazzine_data'] = json_encode($validated['palazzine']);
|
|
unset($validated['palazzine']);
|
|
}
|
|
|
|
// Prepara dati JSON per locali di servizio
|
|
if (isset($validated['locali'])) {
|
|
$validated['locali_servizio'] = json_encode($validated['locali']);
|
|
unset($validated['locali']);
|
|
}
|
|
|
|
$stabile = Stabile::create($validated);
|
|
|
|
if ($request->wantsJson()) {
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Stabile creato con successo!',
|
|
'stabile' => $stabile,
|
|
'redirect' => route('admin.stabili.show', $stabile)
|
|
]);
|
|
}
|
|
|
|
return redirect()->route('admin.stabili.show', $stabile)
|
|
->with('success', 'Stabile creato con successo!');
|
|
}
|
|
|
|
/**
|
|
* Generate a unique codice stabile
|
|
*/
|
|
private function generateCodiceStabile()
|
|
{
|
|
$prefix = 'STB';
|
|
$lastStabile = Stabile::where('codice_stabile', 'LIKE', $prefix . '%')
|
|
->orderBy('codice_stabile', 'desc')
|
|
->first();
|
|
|
|
if ($lastStabile) {
|
|
$lastNumber = (int) substr($lastStabile->codice_stabile, 3);
|
|
$newNumber = $lastNumber + 1;
|
|
} else {
|
|
$newNumber = 1;
|
|
}
|
|
|
|
return $prefix . str_pad($newNumber, 3, '0', STR_PAD_LEFT);
|
|
}
|
|
|
|
/**
|
|
* Display the specified resource.
|
|
*/
|
|
public function show(Stabile $stabile)
|
|
{
|
|
// Verifica che l'utente possa accedere a questo stabile
|
|
if ($stabile->amministratore_id !== Auth::user()->amministratore->id_amministratore ?? null) {
|
|
abort(403);
|
|
}
|
|
|
|
// Carica relazioni per dashboard
|
|
$stabile->load([
|
|
'chiavi' => function($query) {
|
|
$query->with('movimenti')->latest();
|
|
},
|
|
'fondiCondominiali' => function($query) {
|
|
$query->orderBy('tipo');
|
|
},
|
|
'tabelleMillesimali' => function($query) {
|
|
$query->with('dettagliMillesimi');
|
|
},
|
|
'contatori' => function($query) {
|
|
$query->with('lettureContatore');
|
|
},
|
|
'unitaImmobiliari'
|
|
]);
|
|
|
|
// Calcoli KPI dashboard
|
|
$kpi = [
|
|
'totale_unita' => $stabile->unitaImmobiliari->count(),
|
|
'totale_chiavi' => $stabile->chiavi->count(),
|
|
'chiavi_disponibili' => $stabile->chiavi->where('stato', 'disponibile')->count(),
|
|
'chiavi_in_uso' => $stabile->chiavi->where('stato', 'in_uso')->count(),
|
|
'totale_fondi' => $stabile->fondiCondominiali->count(),
|
|
'saldo_totale' => $stabile->fondiCondominiali->sum('saldo_attuale'),
|
|
'totale_contatori' => $stabile->contatori->count(),
|
|
'totale_tabelle_millesimali' => $stabile->tabelleMillesimali->count(),
|
|
];
|
|
|
|
return view('admin.stabili.show', compact('stabile', 'kpi'));
|
|
}
|
|
|
|
/**
|
|
* Show the form for editing the specified resource.
|
|
*/
|
|
public function edit(Stabile $stabile)
|
|
{
|
|
// Verifica che l'utente possa modificare questo stabile
|
|
if ($stabile->amministratore_id !== Auth::user()->amministratore->id_amministratore ?? null) {
|
|
abort(403);
|
|
}
|
|
|
|
return view('admin.stabili.edit', compact('stabile'));
|
|
}
|
|
|
|
/**
|
|
* Update the specified resource in storage.
|
|
*/
|
|
public function update(Request $request, Stabile $stabile)
|
|
{
|
|
// Verifica che l'utente possa modificare questo stabile
|
|
if ($stabile->amministratore_id !== Auth::user()->amministratore->id_amministratore ?? null) {
|
|
abort(403);
|
|
}
|
|
|
|
$request->validate([
|
|
'denominazione' => 'required|string|max:255',
|
|
'codice_fiscale' => 'nullable|string|max:20|unique:stabili,codice_fiscale,' . $stabile->id . ',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 . ',id',
|
|
// Campi avanzati struttura fisica
|
|
'numero_palazzine' => 'nullable|integer|min:1|max:20',
|
|
'numero_scale_per_palazzina' => 'nullable|integer|min:1|max:10',
|
|
'numero_piani' => 'nullable|integer|min:1|max:50',
|
|
'piano_seminterrato' => 'boolean',
|
|
'piano_sottotetto' => 'boolean',
|
|
'presenza_ascensore' => 'boolean',
|
|
'cortile_giardino' => 'boolean',
|
|
'superficie_cortile' => 'nullable|numeric|min:0',
|
|
// Servizi
|
|
'riscaldamento_centralizzato' => 'boolean',
|
|
'acqua_centralizzata' => 'boolean',
|
|
'gas_centralizzato' => 'boolean',
|
|
'servizio_portineria' => 'boolean',
|
|
'orari_portineria' => 'nullable|string|max:255',
|
|
'videocitofono' => 'boolean',
|
|
'antenna_tv_centralizzata' => 'boolean',
|
|
'internet_condominiale' => 'boolean',
|
|
// Dati economici
|
|
'fondo_riserva_minimo' => 'nullable|numeric|min:0',
|
|
'importo_rata_standard' => 'nullable|numeric|min:0',
|
|
'frequenza_rate' => 'nullable|in:mensile,bimestrale,trimestrale,quadrimestrale,semestrale,annuale',
|
|
'giorno_scadenza_rate' => 'nullable|integer|min:1|max:31',
|
|
'iban_condominio' => 'nullable|string|max:34',
|
|
// Configurazioni millesimi
|
|
'millesimi_generali_calcolati' => 'boolean',
|
|
'millesimi_riscaldamento_separati' => 'boolean',
|
|
'millesimi_acqua_separati' => 'boolean',
|
|
'millesimi_ascensore_separati' => 'boolean',
|
|
]);
|
|
|
|
$dati = $request->all();
|
|
|
|
// Gestione configurazione avanzata
|
|
$configurazioneAvanzata = [
|
|
'auto_generazione_unita' => $request->has('auto_generazione_unita'),
|
|
'calcolo_automatico_millesimi' => $request->has('calcolo_automatico_millesimi'),
|
|
'notifiche_scadenze' => $request->has('notifiche_scadenze'),
|
|
'backup_automatico' => $request->has('backup_automatico'),
|
|
];
|
|
$dati['configurazione_avanzata'] = $configurazioneAvanzata;
|
|
|
|
$stabile->update($dati);
|
|
|
|
return redirect()->route('admin.stabili.show', $stabile)
|
|
->with('success', 'Stabile aggiornato con successo.');
|
|
}
|
|
|
|
/**
|
|
* Remove the specified resource from storage.
|
|
*/
|
|
public function destroy(Stabile $stabile)
|
|
{
|
|
// Verifica che l'utente possa eliminare questo stabile
|
|
if ($stabile->amministratore_id !== Auth::user()->amministratore->id_amministratore ?? null) {
|
|
abort(403);
|
|
}
|
|
|
|
$stabile->delete();
|
|
|
|
return redirect()->route('admin.stabili.index')
|
|
->with('success', 'Stabile eliminato con successo.');
|
|
}
|
|
|
|
// ================================
|
|
// MODULO STABILI AVANZATO
|
|
// ================================
|
|
|
|
/**
|
|
* Dashboard gestione chiavi
|
|
*/
|
|
public function chiavi(Stabile $stabile)
|
|
{
|
|
$this->authorizeAccess($stabile);
|
|
|
|
$chiavi = $stabile->chiavi()
|
|
->with(['movimenti' => function($query) {
|
|
$query->latest()->limit(3);
|
|
}])
|
|
->paginate(15);
|
|
|
|
return view('admin.stabili.chiavi.index', compact('stabile', 'chiavi'));
|
|
}
|
|
|
|
/**
|
|
* Movimento chiave (consegna/restituzione)
|
|
*/
|
|
public function movimentoChiave(Request $request, Stabile $stabile, ChiaveStabile $chiave)
|
|
{
|
|
$this->authorizeAccess($stabile);
|
|
|
|
$request->validate([
|
|
'tipo_movimento' => 'required|in:consegna,restituzione,smarrimento,duplicazione',
|
|
'soggetto_riferimento' => 'required|string|max:255',
|
|
'note' => 'nullable|string|max:500',
|
|
]);
|
|
|
|
DB::transaction(function() use ($request, $chiave) {
|
|
// Crea movimento
|
|
$movimento = $chiave->movimenti()->create([
|
|
'tipo_movimento' => $request->tipo_movimento,
|
|
'soggetto_riferimento' => $request->soggetto_riferimento,
|
|
'data_movimento' => now(),
|
|
'note' => $request->note,
|
|
'utente_id' => Auth::id(),
|
|
]);
|
|
|
|
// Aggiorna stato chiave
|
|
$nuovoStato = match($request->tipo_movimento) {
|
|
'consegna' => 'in_uso',
|
|
'restituzione' => 'disponibile',
|
|
'smarrimento' => 'smarrita',
|
|
'duplicazione' => 'disponibile',
|
|
default => $chiave->stato
|
|
};
|
|
|
|
$chiave->update(['stato' => $nuovoStato]);
|
|
});
|
|
|
|
return back()->with('success', 'Movimento registrato con successo');
|
|
}
|
|
|
|
/**
|
|
* Gestione fondi condominiali
|
|
*/
|
|
public function fondi(Stabile $stabile)
|
|
{
|
|
$this->authorizeAccess($stabile);
|
|
|
|
$fondi = $stabile->fondiCondominiali()
|
|
->orderBy('tipo')
|
|
->paginate(10);
|
|
|
|
return view('admin.stabili.fondi.index', compact('stabile', 'fondi'));
|
|
}
|
|
|
|
/**
|
|
* Struttura fisica dettaglio
|
|
*/
|
|
public function strutturaFisica(Stabile $stabile)
|
|
{
|
|
$this->authorizeAccess($stabile);
|
|
|
|
$strutture = $stabile->strutturaFisica()
|
|
->orderBy('tipo')
|
|
->orderBy('codice')
|
|
->get()
|
|
->groupBy('tipo');
|
|
|
|
return view('admin.stabili.struttura.index', compact('stabile', 'strutture'));
|
|
}
|
|
|
|
/**
|
|
* Auto-generazione struttura fisica
|
|
*/
|
|
public function autoGeneraStruttura(Request $request, Stabile $stabile)
|
|
{
|
|
$this->authorizeAccess($stabile);
|
|
|
|
$request->validate([
|
|
'num_palazzine' => 'required|integer|min:1|max:20',
|
|
'num_scale_per_palazzina' => 'required|integer|min:1|max:10',
|
|
'num_piani_per_scala' => 'required|integer|min:1|max:50',
|
|
'num_unita_per_piano' => 'required|integer|min:1|max:20',
|
|
]);
|
|
|
|
DB::transaction(function() use ($request, $stabile) {
|
|
// Elimina struttura esistente se richiesto
|
|
if ($request->pulisci_esistente) {
|
|
$stabile->strutturaFisica()->delete();
|
|
}
|
|
|
|
$strutture = [];
|
|
|
|
// Genera palazzine
|
|
for ($p = 1; $p <= $request->num_palazzine; $p++) {
|
|
$strutture[] = [
|
|
'stabile_id' => $stabile->id,
|
|
'tipo' => 'palazzina',
|
|
'codice' => sprintf('PAL-%02d', $p),
|
|
'nome' => "Palazzina {$p}",
|
|
'parent_id' => null,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
];
|
|
}
|
|
|
|
StrutturaFisicaDettaglio::insert($strutture);
|
|
|
|
// Recupera palazzine create per le scale
|
|
$palazzine = $stabile->strutturaFisica()->where('tipo', 'palazzina')->get();
|
|
|
|
foreach ($palazzine as $palazzina) {
|
|
$strutture_scale = [];
|
|
|
|
// Genera scale per questa palazzina
|
|
for ($s = 1; $s <= $request->num_scale_per_palazzina; $s++) {
|
|
$strutture_scale[] = [
|
|
'stabile_id' => $stabile->id,
|
|
'tipo' => 'scala',
|
|
'codice' => sprintf('%s-SC%02d', $palazzina->codice, $s),
|
|
'nome' => "Scala {$s}",
|
|
'parent_id' => $palazzina->id,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
];
|
|
}
|
|
|
|
StrutturaFisicaDettaglio::insert($strutture_scale);
|
|
|
|
// Genera piani per ogni scala
|
|
$scale = $stabile->strutturaFisica()->where('parent_id', $palazzina->id)->get();
|
|
|
|
foreach ($scale as $scala) {
|
|
$strutture_piani = [];
|
|
|
|
for ($piano = 0; $piano <= $request->num_piani_per_scala; $piano++) {
|
|
$nome_piano = $piano == 0 ? 'Piano Terra' : "Piano {$piano}";
|
|
|
|
$strutture_piani[] = [
|
|
'stabile_id' => $stabile->id,
|
|
'tipo' => 'piano',
|
|
'codice' => sprintf('%s-P%02d', $scala->codice, $piano),
|
|
'nome' => $nome_piano,
|
|
'parent_id' => $scala->id,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
];
|
|
}
|
|
|
|
StrutturaFisicaDettaglio::insert($strutture_piani);
|
|
}
|
|
}
|
|
});
|
|
|
|
return back()->with('success', 'Struttura fisica generata automaticamente');
|
|
}
|
|
|
|
/**
|
|
* Auto-generazione unità immobiliari da struttura
|
|
*/
|
|
public function autoGeneraUnita(Request $request, Stabile $stabile)
|
|
{
|
|
$this->authorizeAccess($stabile);
|
|
|
|
$request->validate([
|
|
'template_nome' => 'required|string',
|
|
'millesimi_default' => 'required|numeric|min:0|max:1000',
|
|
]);
|
|
|
|
$unita_create = 0;
|
|
|
|
DB::transaction(function() use ($request, $stabile, &$unita_create) {
|
|
$piani = $stabile->strutturaFisica()->where('tipo', 'piano')->get();
|
|
|
|
foreach ($piani as $piano) {
|
|
for ($u = 1; $u <= $request->num_unita_per_piano; $u++) {
|
|
// Genera codice unità
|
|
$codice_unita = sprintf('%s-U%02d', $piano->codice, $u);
|
|
|
|
// Template nome (es: "Appartamento {piano} - {numero}")
|
|
$nome_unita = str_replace(
|
|
['{piano}', '{numero}', '{codice}'],
|
|
[$piano->nome, $u, $codice_unita],
|
|
$request->template_nome
|
|
);
|
|
|
|
// Crea unità immobiliare (assumendo esistenza model UnitaImmobiliare)
|
|
// Sarà implementato nel prossimo modulo
|
|
|
|
$unita_create++;
|
|
}
|
|
}
|
|
});
|
|
|
|
return back()->with('success', "Programmate {$unita_create} unità immobiliari per generazione");
|
|
}
|
|
|
|
/**
|
|
* API per gestione tabelle millesimali
|
|
*/
|
|
public function storeTabellaMillesimale(Request $request, Stabile $stabile)
|
|
{
|
|
$request->validate([
|
|
'nome' => 'required|string|max:255',
|
|
'descrizione' => 'nullable|string|max:1000',
|
|
]);
|
|
|
|
try {
|
|
$tabella = $stabile->tabelleMillesimali()->create([
|
|
'nome' => $request->nome,
|
|
'descrizione' => $request->descrizione,
|
|
'stato' => 'attiva',
|
|
'created_by' => Auth::id(),
|
|
]);
|
|
|
|
return response()->json(['success' => true, 'tabella' => $tabella]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function updateTabellaMillesimale(Request $request, Stabile $stabile, $tabellaId)
|
|
{
|
|
$request->validate([
|
|
'nome' => 'required|string|max:255',
|
|
'descrizione' => 'nullable|string|max:1000',
|
|
]);
|
|
|
|
try {
|
|
$tabella = $stabile->tabelleMillesimali()->findOrFail($tabellaId);
|
|
$tabella->update([
|
|
'nome' => $request->nome,
|
|
'descrizione' => $request->descrizione,
|
|
'updated_by' => Auth::id(),
|
|
]);
|
|
|
|
return response()->json(['success' => true, 'tabella' => $tabella]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function destroyTabellaMillesimale(Stabile $stabile, $tabellaId)
|
|
{
|
|
try {
|
|
$tabella = $stabile->tabelleMillesimali()->findOrFail($tabellaId);
|
|
$tabella->delete();
|
|
|
|
return response()->json(['success' => true]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API per gestione contatori
|
|
*/
|
|
public function storeContatore(Request $request, Stabile $stabile)
|
|
{
|
|
$request->validate([
|
|
'nome' => 'required|string|max:255',
|
|
'tipo' => 'required|in:gas,elettricita,acqua,riscaldamento,altro',
|
|
'ubicazione' => 'required|string|max:255',
|
|
'unita_misura' => 'required|string|max:50',
|
|
'numero_serie' => 'nullable|string|max:100',
|
|
]);
|
|
|
|
try {
|
|
$contatore = $stabile->contatori()->create([
|
|
'nome' => $request->nome,
|
|
'tipo' => $request->tipo,
|
|
'ubicazione' => $request->ubicazione,
|
|
'unita_misura' => $request->unita_misura,
|
|
'numero_serie' => $request->numero_serie,
|
|
'stato' => 'attivo',
|
|
'created_by' => Auth::id(),
|
|
]);
|
|
|
|
return response()->json(['success' => true, 'contatore' => $contatore]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function storeLetturaContatore(Request $request, Stabile $stabile, $contatoreId)
|
|
{
|
|
$request->validate([
|
|
'valore' => 'required|numeric|min:0',
|
|
'data_lettura' => 'required|date',
|
|
]);
|
|
|
|
try {
|
|
$contatore = $stabile->contatori()->findOrFail($contatoreId);
|
|
$lettura = $contatore->lettureContatore()->create([
|
|
'valore' => $request->valore,
|
|
'data_lettura' => $request->data_lettura,
|
|
'rilevata_da' => Auth::id(),
|
|
]);
|
|
|
|
return response()->json(['success' => true, 'lettura' => $lettura]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API per gestione chiavi
|
|
*/
|
|
public function storeChiave(Request $request, Stabile $stabile)
|
|
{
|
|
$request->validate([
|
|
'codice' => 'required|string|max:50',
|
|
'descrizione' => 'required|string|max:255',
|
|
'tipo' => 'required|in:portone,ascensore,cantina,terrazza,garage,altro',
|
|
'zona' => 'nullable|string|max:100',
|
|
'numero_copie' => 'required|integer|min:1',
|
|
'note' => 'nullable|string|max:1000',
|
|
]);
|
|
|
|
try {
|
|
$chiave = $stabile->chiavi()->create([
|
|
'codice' => $request->codice,
|
|
'descrizione' => $request->descrizione,
|
|
'tipo' => $request->tipo,
|
|
'zona' => $request->zona,
|
|
'numero_copie' => $request->numero_copie,
|
|
'stato' => 'disponibile',
|
|
'note' => $request->note,
|
|
'created_by' => Auth::id(),
|
|
]);
|
|
|
|
return response()->json(['success' => true, 'chiave' => $chiave]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function assegnaChiave(Request $request, Stabile $stabile, $chiaveId)
|
|
{
|
|
$request->validate([
|
|
'assegnatario' => 'required|string|max:255',
|
|
]);
|
|
|
|
try {
|
|
$chiave = $stabile->chiavi()->findOrFail($chiaveId);
|
|
|
|
if ($chiave->stato !== 'disponibile') {
|
|
return response()->json(['success' => false, 'message' => 'Chiave non disponibile']);
|
|
}
|
|
|
|
DB::transaction(function () use ($chiave, $request) {
|
|
// Crea movimento
|
|
MovimentoChiave::create([
|
|
'chiave_id' => $chiave->id,
|
|
'tipo_movimento' => 'assegnazione',
|
|
'assegnatario' => $request->assegnatario,
|
|
'data_movimento' => now(),
|
|
'created_by' => Auth::id(),
|
|
]);
|
|
|
|
// Aggiorna stato chiave
|
|
$chiave->update([
|
|
'stato' => 'in_uso',
|
|
'assegnatario_attuale' => $request->assegnatario,
|
|
]);
|
|
});
|
|
|
|
return response()->json(['success' => true, 'chiave' => $chiave]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function restituisciChiave(Request $request, Stabile $stabile, $chiaveId)
|
|
{
|
|
try {
|
|
$chiave = $stabile->chiavi()->findOrFail($chiaveId);
|
|
|
|
if ($chiave->stato !== 'in_uso') {
|
|
return response()->json(['success' => false, 'message' => 'Chiave non in uso']);
|
|
}
|
|
|
|
DB::transaction(function () use ($chiave) {
|
|
// Crea movimento
|
|
MovimentoChiave::create([
|
|
'chiave_id' => $chiave->id,
|
|
'tipo_movimento' => 'restituzione',
|
|
'assegnatario' => $chiave->assegnatario_attuale,
|
|
'data_movimento' => now(),
|
|
'created_by' => Auth::id(),
|
|
]);
|
|
|
|
// Aggiorna stato chiave
|
|
$chiave->update([
|
|
'stato' => 'disponibile',
|
|
'assegnatario_attuale' => null,
|
|
]);
|
|
});
|
|
|
|
return response()->json(['success' => true, 'chiave' => $chiave]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API per gestione fondi
|
|
*/
|
|
public function storeFondo(Request $request, Stabile $stabile)
|
|
{
|
|
$request->validate([
|
|
'nome' => 'required|string|max:255',
|
|
'tipo' => 'required|in:ordinario,straordinario,riserva,lavori,manutenzione,altro',
|
|
'saldo_iniziale' => 'required|numeric',
|
|
'obiettivo_saldo' => 'nullable|numeric',
|
|
'descrizione' => 'nullable|string|max:1000',
|
|
'attivo' => 'boolean',
|
|
]);
|
|
|
|
try {
|
|
$fondo = $stabile->fondiCondominiali()->create([
|
|
'nome' => $request->nome,
|
|
'tipo' => $request->tipo,
|
|
'saldo_iniziale' => $request->saldo_iniziale,
|
|
'saldo_attuale' => $request->saldo_iniziale,
|
|
'obiettivo_saldo' => $request->obiettivo_saldo,
|
|
'descrizione' => $request->descrizione,
|
|
'stato' => $request->attivo ? 'attivo' : 'inattivo',
|
|
'created_by' => Auth::id(),
|
|
]);
|
|
|
|
return response()->json(['success' => true, 'fondo' => $fondo]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* API per import GESCON
|
|
*/
|
|
public function importStabile(Request $request, Stabile $stabile)
|
|
{
|
|
try {
|
|
// Simulazione import da GESCON
|
|
// TODO: Implementare connessione reale al database GESCON
|
|
|
|
// Per ora simuliamo un import di successo
|
|
sleep(2); // Simula processamento
|
|
|
|
// Aggiorna alcuni campi con dati "importati"
|
|
$stabile->update([
|
|
'anno_costruzione' => 1985,
|
|
'superficie_totale' => 1200,
|
|
'numero_ascensori' => 1,
|
|
'numero_garage' => 15,
|
|
'note' => 'Dati importati da GESCON il ' . now()->format('d/m/Y H:i'),
|
|
'updated_by' => Auth::id(),
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Importazione completata con successo',
|
|
'stabile' => $stabile
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function importMillesimi(Request $request, Stabile $stabile)
|
|
{
|
|
try {
|
|
// Simulazione import tabelle millesimali da GESCON
|
|
sleep(1);
|
|
|
|
// Crea tabelle di esempio
|
|
$tabelle = [
|
|
['nome' => 'Proprietà Generale', 'descrizione' => 'Tabella millesimale principale'],
|
|
['nome' => 'Scale', 'descrizione' => 'Spese scale e ascensore'],
|
|
['nome' => 'Riscaldamento', 'descrizione' => 'Ripartizione spese riscaldamento'],
|
|
];
|
|
|
|
foreach ($tabelle as $tabella) {
|
|
$stabile->tabelleMillesimali()->firstOrCreate(
|
|
['nome' => $tabella['nome']],
|
|
[
|
|
'descrizione' => $tabella['descrizione'],
|
|
'stato' => 'attiva',
|
|
'created_by' => Auth::id(),
|
|
]
|
|
);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Tabelle millesimali importate con successo'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function importUnita(Request $request, Stabile $stabile)
|
|
{
|
|
try {
|
|
// Simulazione import unità immobiliari
|
|
sleep(2);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Import unità immobiliari completato (funzionalità da implementare)'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
public function importFinanziari(Request $request, Stabile $stabile)
|
|
{
|
|
try {
|
|
// Simulazione import dati finanziari
|
|
sleep(3);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Import dati finanziari completato (funzionalità da implementare)'
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return response()->json(['success' => false, 'message' => $e->getMessage()]);
|
|
}
|
|
}
|
|
|
|
// ================================
|
|
// UTILITY METHODS
|
|
// ================================
|
|
|
|
/**
|
|
* Autorizzazione accesso stabile
|
|
*/
|
|
private function authorizeAccess(Stabile $stabile)
|
|
{
|
|
if ($stabile->amministratore_id !== Auth::user()->amministratore->id_amministratore ?? null) {
|
|
abort(403, 'Accesso non autorizzato a questo stabile');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Genera QR Code per chiave
|
|
*/
|
|
private function generateQrCode(Stabile $stabile, string $nomeChiave): string
|
|
{
|
|
return "NETGESCON-KEY-{$stabile->id}-" . strtoupper(Str::slug($nomeChiave)) . "-" . time();
|
|
}
|
|
} |