# 🏠 MODULO UNITÀ IMMOBILIARI - Specifiche Complete ## 📋 OVERVIEW Il **Modulo Unità Immobiliari** gestisce l'anagrafica completa delle singole unità immobiliari all'interno di ogni stabile, i collegamenti con proprietari/inquilini, la gestione delle quote millesimali e lo storico delle proprietà. --- ## 🎯 OBIETTIVI DEL MODULO ### ✅ Funzionalità Core - **Anagrafica Unità Complete**: Tutti i dati tecnici e amministrativi - **Gestione Proprietari**: Collegamento con persone fisiche/giuridiche - **Quote Millesimali**: Gestione millesimi per ogni tabella - **Storico Proprietà**: Tracking completo passaggi di proprietà - **Classificazioni Multiple**: Tipologie uso, categorie catastali, ecc. ### 🔗 Integrazione Sistema - **Collegamento Stabile**: Ogni unità appartiene a uno stabile - **Base Contabile**: Fondamento per ripartizioni spese - **Gestione Documenti**: Archivio contratti, atti, planimetrie - **API Complete**: Endpoint per app mobile e integrazioni --- ## 💾 STRUTTURA DATABASE ### 📊 Tabella: `unita_immobiliari` ```sql CREATE TABLE unita_immobiliari ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, stabile_id BIGINT UNSIGNED NOT NULL, -- Identificazione Unità codice_unita VARCHAR(20) NOT NULL COMMENT 'Es: A01, B12, Box-05', denominazione VARCHAR(255) COMMENT 'Nome descrittivo unità', piano VARCHAR(10) COMMENT 'Piano (T, 1, 2, S1, ecc.)', interno VARCHAR(10) COMMENT 'Numero interno', -- Tipologia e Uso tipologia_unita ENUM('appartamento', 'box', 'cantina', 'locale_commerciale', 'ufficio', 'posto_auto', 'altro') NOT NULL, destinazione_uso ENUM('residenziale', 'commerciale', 'ufficio', 'deposito', 'garage', 'altro') NOT NULL, categoria_catastale VARCHAR(5) COMMENT 'A/1, A/2, C/1, ecc.', classe_catastale VARCHAR(5), -- Dati Tecnici superficie_commerciale DECIMAL(8,2) COMMENT 'mq', superficie_calpestabile DECIMAL(8,2) COMMENT 'mq', superficie_balconi DECIMAL(8,2) COMMENT 'mq', superficie_terrazzi DECIMAL(8,2) COMMENT 'mq', numero_vani DECIMAL(3,1), numero_bagni TINYINT, numero_balconi TINYINT, altezza_media DECIMAL(3,2) COMMENT 'metri', -- Dati Catastali foglio VARCHAR(10), particella VARCHAR(10), subalterno VARCHAR(10), rendita_catastale DECIMAL(10,2), valore_catastale DECIMAL(12,2), -- Caratteristiche Tecniche riscaldamento ENUM('autonomo', 'centralizzato', 'condominiale', 'assente') DEFAULT 'centralizzato', condizionamento BOOLEAN DEFAULT FALSE, ascensore BOOLEAN DEFAULT FALSE, balcone BOOLEAN DEFAULT FALSE, terrazzo BOOLEAN DEFAULT FALSE, giardino BOOLEAN DEFAULT FALSE, posto_auto BOOLEAN DEFAULT FALSE, classe_energetica ENUM('A4', 'A3', 'A2', 'A1', 'B', 'C', 'D', 'E', 'F', 'G'), -- Stato Unità stato ENUM('attiva', 'venduta', 'sfittata', 'in_ristrutturazione', 'disabitata') DEFAULT 'attiva', data_costruzione DATE, data_ultima_ristrutturazione DATE, -- Note e Descrizioni descrizione TEXT, note_amministrative TEXT, caratteristiche_speciali TEXT, -- Timestamps e Audit created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_by BIGINT UNSIGNED, updated_by BIGINT UNSIGNED, -- Indici INDEX idx_stabile_codice (stabile_id, codice_unita), INDEX idx_tipologia (tipologia_unita), INDEX idx_stato (stato), INDEX idx_catastale (foglio, particella, subalterno), -- Foreign Keys FOREIGN KEY (stabile_id) REFERENCES stabili(id) ON DELETE CASCADE, FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL, FOREIGN KEY (updated_by) REFERENCES users(id) ON DELETE SET NULL, -- Constraints UNIQUE KEY uk_stabile_codice_unita (stabile_id, codice_unita) ) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` ### 📊 Tabella: `unita_proprieta` ```sql CREATE TABLE unita_proprieta ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, unita_id BIGINT UNSIGNED NOT NULL, persona_id BIGINT UNSIGNED NOT NULL, -- Tipo Proprietà tipo_proprieta ENUM('proprieta', 'usufrutto', 'nuda_proprieta', 'diritto_superficie', 'altro') DEFAULT 'proprieta', quota_proprieta DECIMAL(8,6) NOT NULL DEFAULT 1.000000 COMMENT 'Quota di proprietà (es: 0.5 = 50%)', -- Periodo Validità data_inizio DATE NOT NULL, data_fine DATE NULL, -- Dati Acquisizione titolo_acquisizione ENUM('acquisto', 'successione', 'donazione', 'permuta', 'altro'), atto_notarile VARCHAR(255), data_atto DATE, notaio VARCHAR(255), prezzo_acquisto DECIMAL(12,2), -- Stato Attuale attivo BOOLEAN DEFAULT TRUE, note TEXT, -- Timestamps created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_by BIGINT UNSIGNED, -- Indici INDEX idx_unita_attivo (unita_id, attivo), INDEX idx_persona_periodo (persona_id, data_inizio, data_fine), INDEX idx_data_atto (data_atto), -- Foreign Keys FOREIGN KEY (unita_id) REFERENCES unita_immobiliari(id) ON DELETE CASCADE, FOREIGN KEY (persona_id) REFERENCES persone(id) ON DELETE CASCADE, FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL ) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` ### 📊 Tabella: `unita_millesimi` ```sql CREATE TABLE unita_millesimi ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, unita_id BIGINT UNSIGNED NOT NULL, tabella_millesimale_id BIGINT UNSIGNED NOT NULL, -- Valori Millesimali millesimi DECIMAL(10,6) NOT NULL COMMENT 'Valore millesimale (es: 25.500000)', percentuale DECIMAL(8,6) GENERATED ALWAYS AS (millesimi / 1000) STORED COMMENT 'Percentuale automatica', -- Validità Temporale data_inizio DATE NOT NULL, data_fine DATE NULL, -- Approvazione approvato BOOLEAN DEFAULT FALSE, data_approvazione DATE NULL, verbale_approvazione VARCHAR(255), -- Note note TEXT, -- Timestamps created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_by BIGINT UNSIGNED, -- Indici INDEX idx_unita_tabella (unita_id, tabella_millesimale_id), INDEX idx_tabella_periodo (tabella_millesimale_id, data_inizio, data_fine), INDEX idx_approvato (approvato), -- Foreign Keys FOREIGN KEY (unita_id) REFERENCES unita_immobiliari(id) ON DELETE CASCADE, FOREIGN KEY (tabella_millesimale_id) REFERENCES tabelle_millesimali(id) ON DELETE CASCADE, FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL, -- Constraint unico per periodo UNIQUE KEY uk_unita_tabella_periodo (unita_id, tabella_millesimale_id, data_inizio) ) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ``` --- ## 🔧 CONTROLLER LARAVEL ### 📝 UnitaImmobiliareController ```php unitaService = $unitaService; $this->middleware('auth'); $this->middleware('permission:unita.view')->only(['index', 'show']); $this->middleware('permission:unita.create')->only(['create', 'store']); $this->middleware('permission:unita.edit')->only(['edit', 'update']); $this->middleware('permission:unita.delete')->only(['destroy']); } /** * Lista unità per stabile */ public function index(Request $request, Stabile $stabile) { $this->authorize('view', $stabile); $unita = $this->unitaService->getUnitaByStabile($stabile, $request->all()); $statistiche = $this->unitaService->getStatisticheStabile($stabile); return view('unita.index', compact('stabile', 'unita', 'statistiche')); } /** * Form creazione nuova unità */ public function create(Stabile $stabile) { $this->authorize('update', $stabile); return view('unita.create', compact('stabile')); } /** * Salvataggio nuova unità */ public function store(UnitaImmobiliareRequest $request, Stabile $stabile) { $this->authorize('update', $stabile); try { $unita = $this->unitaService->createUnita($stabile, $request->validated()); return redirect()->route('unita.show', [$stabile, $unita]) ->with('success', 'Unità immobiliare creata con successo!'); } catch (\Exception $e) { return back()->withInput() ->with('error', 'Errore durante la creazione: ' . $e->getMessage()); } } /** * Visualizzazione dettaglio unità */ public function show(Stabile $stabile, UnitaImmobiliare $unita) { $this->authorize('view', $stabile); $unita->load(['proprieta.persona', 'millesimi.tabella', 'documenti']); $dashboard = $this->unitaService->getDashboardUnita($unita); return view('unita.show', compact('stabile', 'unita', 'dashboard')); } /** * Form modifica unità */ public function edit(Stabile $stabile, UnitaImmobiliare $unita) { $this->authorize('update', $stabile); return view('unita.edit', compact('stabile', 'unita')); } /** * Aggiornamento unità */ public function update(UnitaImmobiliareRequest $request, Stabile $stabile, UnitaImmobiliare $unita) { $this->authorize('update', $stabile); try { $this->unitaService->updateUnita($unita, $request->validated()); return redirect()->route('unita.show', [$stabile, $unita]) ->with('success', 'Unità immobiliare aggiornata con successo!'); } catch (\Exception $e) { return back()->withInput() ->with('error', 'Errore durante l\'aggiornamento: ' . $e->getMessage()); } } /** * Gestione proprietari unità */ public function proprieta(Stabile $stabile, UnitaImmobiliare $unita) { $this->authorize('view', $stabile); $proprieta = $unita->proprieta()->with('persona')->get(); $persone = $this->unitaService->getPersoneDisponibili($stabile); return view('unita.proprieta', compact('stabile', 'unita', 'proprieta', 'persone')); } /** * Gestione millesimi unità */ public function millesimi(Stabile $stabile, UnitaImmobiliare $unita) { $this->authorize('view', $stabile); $millesimi = $unita->millesimi()->with('tabella')->get(); $tabelle = $stabile->tabelleMillesimali()->get(); return view('unita.millesimi', compact('stabile', 'unita', 'millesimi', 'tabelle')); } } ``` --- ## 🎨 INTERFACCE UTENTE ### 📋 Lista Unità (`unita/index.blade.php`) ```html @extends('layouts.app') @section('content')
Unità Totali
Unità Attive
Superficie Totale
Proprietari
| Codice | Tipologia | Piano | Superficie | Proprietario | Millesimi | Stato | Azioni |
|---|---|---|---|---|---|---|---|
|
{{ $unita_item->codice_unita }}
@if($unita_item->denominazione)
{{ $unita_item->denominazione }} @endif |
{{ ucfirst($unita_item->tipologia_unita) }}
@if($unita_item->categoria_catastale)
Cat. {{ $unita_item->categoria_catastale }} @endif |
{{ $unita_item->piano ?? '-' }} |
@if($unita_item->superficie_commerciale)
{{ number_format($unita_item->superficie_commerciale, 0) }} mq
@if($unita_item->numero_vani)
{{ $unita_item->numero_vani }} vani @endif @else - @endif |
@if($unita_item->proprietari->count() > 0)
@foreach($unita_item->proprietari as $proprietario)
{{ $proprietario->nome_completo }}
@if($proprietario->pivot->quota_proprieta < 1)
{{ number_format($proprietario->pivot->quota_proprieta * 100, 1) }}%
@endif
@endforeach
@else
Nessun proprietario
@endif
|
@if($unita_item->millesimi_totali) {{ number_format($unita_item->millesimi_totali, 3) }}‰ @else Non definiti @endif | @switch($unita_item->stato) @case('attiva') Attiva @break @case('venduta') Venduta @break @case('sfittata') Sfittata @break @case('in_ristrutturazione') In Ristrutturazione @break @default {{ ucfirst($unita_item->stato) }} @endswitch | |
| Nessuna unità immobiliare trovata | |||||||