📋 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
642 lines
28 KiB
Markdown
642 lines
28 KiB
Markdown
# 🏠 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
|
|
<?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`)
|
|
```html
|
|
@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*
|