netgescon-master/docs/moduli/02-MODULO-UNITA-IMMOBILIARI.md
Pikappa2 480e7eafbd 🎯 NETGESCON - Setup iniziale repository completo
📋 Commit iniziale con:
-  Documentazione unificata in docs/
-  Codice Laravel in netgescon-laravel/
-  Script automazione in scripts/
-  Configurazione sync rsync
-  Struttura organizzata e pulita

🔄 Versione: 2025.07.19-1644
🎯 Sistema pronto per Git distribuito
2025-07-19 16:44:47 +02:00

28 KiB

🏠 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

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

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

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

namespace App\Http\Controllers;

use App\Models\UnitaImmobiliare;
use App\Models\Stabile;
use App\Http\Requests\UnitaImmobiliareRequest;
use App\Services\UnitaImmobiliareService;
use Illuminate\Http\Request;

class UnitaImmobiliareController extends Controller
{
    protected $unitaService;
    
    public function __construct(UnitaImmobiliareService $unitaService)
    {
        $this->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)

@extends('layouts.app')

@section('content')
<div class="container-fluid">
    <!-- Breadcrumb -->
    <nav aria-label="breadcrumb">
        <ol class="breadcrumb">
            <li class="breadcrumb-item"><a href="{{ route('stabili.index') }}">Stabili</a></li>
            <li class="breadcrumb-item"><a href="{{ route('stabili.show', $stabile) }}">{{ $stabile->denominazione }}</a></li>
            <li class="breadcrumb-item active">Unità Immobiliari</li>
        </ol>
    </nav>
    
    <div class="row">
        <div class="col-12">
            <div class="card">
                <div class="card-header d-flex justify-content-between align-items-center">
                    <h3>🏠 Unità Immobiliari - {{ $stabile->denominazione }}</h3>
                    @can('update', $stabile)
                        <a href="{{ route('unita.create', $stabile) }}" class="btn btn-primary">
                            <i class="fas fa-plus"></i> Nuova Unità
                        </a>
                    @endcan
                </div>
                
                <div class="card-body">
                    <!-- Statistiche Rapide -->
                    <div class="row mb-4">
                        <div class="col-md-3">
                            <div class="card border-primary">
                                <div class="card-body text-center">
                                    <h4 class="text-primary">{{ $statistiche['totale_unita'] }}</h4>
                                    <p class="mb-0">Unità Totali</p>
                                </div>
                            </div>
                        </div>
                        <div class="col-md-3">
                            <div class="card border-success">
                                <div class="card-body text-center">
                                    <h4 class="text-success">{{ $statistiche['unita_attive'] }}</h4>
                                    <p class="mb-0">Unità Attive</p>
                                </div>
                            </div>
                        </div>
                        <div class="col-md-3">
                            <div class="card border-info">
                                <div class="card-body text-center">
                                    <h4 class="text-info">{{ number_format($statistiche['superficie_totale'], 0) }} mq</h4>
                                    <p class="mb-0">Superficie Totale</p>
                                </div>
                            </div>
                        </div>
                        <div class="col-md-3">
                            <div class="card border-warning">
                                <div class="card-body text-center">
                                    <h4 class="text-warning">{{ $statistiche['proprieta_attive'] }}</h4>
                                    <p class="mb-0">Proprietari</p>
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <!-- Filtri di Ricerca -->
                    <form method="GET" class="mb-4">
                        <div class="row">
                            <div class="col-md-2">
                                <input type="text" name="search" class="form-control" 
                                       placeholder="Cerca unità..." 
                                       value="{{ request('search') }}">
                            </div>
                            <div class="col-md-2">
                                <select name="tipologia" class="form-control">
                                    <option value="">Tutte le tipologie</option>
                                    <option value="appartamento" {{ request('tipologia') == 'appartamento' ? 'selected' : '' }}>Appartamento</option>
                                    <option value="box" {{ request('tipologia') == 'box' ? 'selected' : '' }}>Box</option>
                                    <option value="cantina" {{ request('tipologia') == 'cantina' ? 'selected' : '' }}>Cantina</option>
                                    <option value="posto_auto" {{ request('tipologia') == 'posto_auto' ? 'selected' : '' }}>Posto Auto</option>
                                </select>
                            </div>
                            <div class="col-md-2">
                                <select name="piano" class="form-control">
                                    <option value="">Tutti i piani</option>
                                    @foreach($statistiche['piani'] as $piano)
                                        <option value="{{ $piano }}" {{ request('piano') == $piano ? 'selected' : '' }}>
                                            Piano {{ $piano }}
                                        </option>
                                    @endforeach
                                </select>
                            </div>
                            <div class="col-md-2">
                                <select name="stato" class="form-control">
                                    <option value="">Tutti gli stati</option>
                                    <option value="attiva" {{ request('stato') == 'attiva' ? 'selected' : '' }}>Attiva</option>
                                    <option value="venduta" {{ request('stato') == 'venduta' ? 'selected' : '' }}>Venduta</option>
                                    <option value="sfittata" {{ request('stato') == 'sfittata' ? 'selected' : '' }}>Sfittata</option>
                                </select>
                            </div>
                            <div class="col-md-2">
                                <button type="submit" class="btn btn-outline-primary">
                                    <i class="fas fa-search"></i> Cerca
                                </button>
                            </div>
                        </div>
                    </form>
                    
                    <!-- Tabella Unità -->
                    <div class="table-responsive">
                        <table class="table table-striped table-hover">
                            <thead>
                                <tr>
                                    <th>Codice</th>
                                    <th>Tipologia</th>
                                    <th>Piano</th>
                                    <th>Superficie</th>
                                    <th>Proprietario</th>
                                    <th>Millesimi</th>
                                    <th>Stato</th>
                                    <th>Azioni</th>
                                </tr>
                            </thead>
                            <tbody>
                                @forelse($unita as $unita_item)
                                    <tr>
                                        <td>
                                            <strong>{{ $unita_item->codice_unita }}</strong>
                                            @if($unita_item->denominazione)
                                                <br><small class="text-muted">{{ $unita_item->denominazione }}</small>
                                            @endif
                                        </td>
                                        <td>
                                            <span class="badge badge-secondary">{{ ucfirst($unita_item->tipologia_unita) }}</span>
                                            @if($unita_item->categoria_catastale)
                                                <br><small class="text-muted">Cat. {{ $unita_item->categoria_catastale }}</small>
                                            @endif
                                        </td>
                                        <td>{{ $unita_item->piano ?? '-' }}</td>
                                        <td>
                                            @if($unita_item->superficie_commerciale)
                                                {{ number_format($unita_item->superficie_commerciale, 0) }} mq
                                                @if($unita_item->numero_vani)
                                                    <br><small class="text-muted">{{ $unita_item->numero_vani }} vani</small>
                                                @endif
                                            @else
                                                -
                                            @endif
                                        </td>
                                        <td>
                                            @if($unita_item->proprietari->count() > 0)
                                                @foreach($unita_item->proprietari as $proprietario)
                                                    <div>{{ $proprietario->nome_completo }}</div>
                                                    @if($proprietario->pivot->quota_proprieta < 1)
                                                        <small class="text-muted">{{ number_format($proprietario->pivot->quota_proprieta * 100, 1) }}%</small>
                                                    @endif
                                                @endforeach
                                            @else
                                                <em class="text-muted">Nessun proprietario</em>
                                            @endif
                                        </td>
                                        <td>
                                            @if($unita_item->millesimi_totali)
                                                {{ number_format($unita_item->millesimi_totali, 3) }}‰
                                            @else
                                                <em class="text-muted">Non definiti</em>
                                            @endif
                                        </td>
                                        <td>
                                            @switch($unita_item->stato)
                                                @case('attiva')
                                                    <span class="badge badge-success">Attiva</span>
                                                    @break
                                                @case('venduta')
                                                    <span class="badge badge-info">Venduta</span>
                                                    @break
                                                @case('sfittata')
                                                    <span class="badge badge-warning">Sfittata</span>
                                                    @break
                                                @case('in_ristrutturazione')
                                                    <span class="badge badge-secondary">In Ristrutturazione</span>
                                                    @break
                                                @default
                                                    <span class="badge badge-light">{{ ucfirst($unita_item->stato) }}</span>
                                            @endswitch
                                        </td>
                                        <td>
                                            <div class="btn-group" role="group">
                                                @can('view', $stabile)
                                                    <a href="{{ route('unita.show', [$stabile, $unita_item]) }}" 
                                                       class="btn btn-sm btn-info" title="Visualizza">
                                                        <i class="fas fa-eye"></i>
                                                    </a>
                                                @endcan
                                                @can('update', $stabile)
                                                    <a href="{{ route('unita.edit', [$stabile, $unita_item]) }}" 
                                                       class="btn btn-sm btn-warning" title="Modifica">
                                                        <i class="fas fa-edit"></i>
                                                    </a>
                                                @endcan
                                                @can('update', $stabile)
                                                    <a href="{{ route('unita.proprieta', [$stabile, $unita_item]) }}" 
                                                       class="btn btn-sm btn-success" title="Proprietari">
                                                        <i class="fas fa-users"></i>
                                                    </a>
                                                @endcan
                                            </div>
                                        </td>
                                    </tr>
                                @empty
                                    <tr>
                                        <td colspan="8" class="text-center">
                                            <em>Nessuna unità immobiliare trovata</em>
                                        </td>
                                    </tr>
                                @endforelse
                            </tbody>
                        </table>
                    </div>
                    
                    <!-- Paginazione -->
                    {{ $unita->links() }}
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

🔄 WORKFLOW OPERATIVO

📝 Processo Creazione Unità

  1. Accesso da Stabile: Admin accede dalla vista dettaglio stabile
  2. Form Guidato: Wizard step-by-step per dati completi
  3. Validazione Avanzata: Controllo unicità codice e coerenza dati
  4. Salvataggio Atomico: Insert unità + configurazioni iniziali
  5. Collegamento Automatico: Link con tabelle millesimali default

📊 Gestione Proprietari

  1. Aggiunta Proprietario: Selezione da anagrafica o creazione nuova
  2. Definizione Quote: Specificazione percentuali proprietà
  3. Validazione Totali: Controllo che la somma quote = 100%
  4. Storico Automatico: Tracking passaggi proprietà
  5. Documenti Collegati: Upload atti, contratti, planimetrie

🧮 Gestione Millesimi

  1. Collegamento Tabelle: Assegnazione millesimi per ogni tabella
  2. Validazione Matematica: Controllo coerenza totali = 1000‰
  3. Approvazione Formale: Workflow approvazione assemblea
  4. Storico Modifiche: Versioning millesimi nel tempo
  5. Calcoli Automatici: Ripartizioni spese in base a millesimi

🔒 BUSINESS RULES

Regole Validazione

  • Codice Unità Univoco: Per stabile (es: A01, B12, Box-05)
  • Quote Proprietà: Somma deve essere = 100% per unità
  • Millesimi Coerenti: Valori devono essere > 0 e matematicamente corretti
  • Superfici Logiche: Superficie calpestabile ≤ commerciale
  • Dati Catastali: Se presenti, devono essere completi e validi

🔄 Automazioni

  • Aggiornamento Contatori: Numero unità in tabella stabili
  • Calcolo Superficie: Totali automatici per piano/tipologia
  • Notificazioni: Alert per modifiche importanti
  • Backup Differenziale: Salvataggio automatico modifiche critiche

📈 METRICHE E REPORTISTICA

📊 KPI Principali

  • Numero unità per tipologia
  • Superficie totale per piano
  • Distribuzione millesimi
  • Percentuale unità con proprietari definiti
  • Tempo medio gestione pratica proprietà

📋 Report Automatici

  • Registro unità immobiliari
  • Tabella proprietari attuali
  • Distribuzione millesimi per tabella
  • Analisi superfici e rendite
  • Report modifiche periodiche

🚀 PROSSIMI SVILUPPI

🔄 Fase 2 - Miglioramenti

  • Import massivo unità da Excel/CAD
  • Gestione contratti locazione
  • Integrazione con visure catastali
  • Calcolo IMU/TASI automatico

🎯 Fase 3 - Avanzate

  • Planimetrie interattive
  • Timeline visuale modifiche
  • Analisi predittiva valori
  • App mobile proprietari

Documento tecnico Modulo Unità Immobiliari | Versione 1.0 | Luglio 2025