feat(stabili): consolidate timeline gestion spans, import AC_ catasto fields and support multi-section catasto (task-d095b0e23b)

This commit is contained in:
michele 2026-08-27 13:49:57 +02:00
parent 7ef8892924
commit 5a8c8a53d4
5 changed files with 233 additions and 34 deletions

View File

@ -261,6 +261,66 @@ public function tabView(): string
};
}
public array $nuovoRiferimentoCatastale = [
'descrizione' => '',
'foglio' => '',
'particella' => '',
'subalterno' => '',
'sezione' => '',
];
public function salvaNuovoRiferimentoCatastale(): void
{
if (! $this->stabile instanceof StabileModel) {
return;
}
$desc = trim($this->nuovoRiferimentoCatastale['descrizione'] ?? '');
$fog = trim($this->nuovoRiferimentoCatastale['foglio'] ?? '');
$part = trim($this->nuovoRiferimentoCatastale['particella'] ?? '');
if ($desc === '' && $fog === '' && $part === '') {
Notification::make()->title('Compila almeno Descrizione, Foglio o Particella')->warning()->send();
return;
}
$config = (array) ($this->stabile->configurazione_avanzata ?? []);
$sec = (array) ($config['altri_riferimenti_catastali'] ?? []);
$sec[] = [
'descrizione' => $desc ?: 'Sezione Aggiuntiva Catasto',
'foglio' => $fog,
'particella' => $part,
'subalterno' => trim($this->nuovoRiferimentoCatastale['subalterno'] ?? ''),
'sezione' => trim($this->nuovoRiferimentoCatastale['sezione'] ?? ''),
];
$config['altri_riferimenti_catastali'] = $sec;
$this->stabile->configurazione_avanzata = $config;
$this->stabile->save();
$this->stabile->refresh();
$this->nuovoRiferimentoCatastale = ['descrizione' => '', 'foglio' => '', 'particella' => '', 'subalterno' => '', 'sezione' => ''];
Notification::make()->title('Riferimento catastale aggiunto con successo')->success()->send();
}
public function rimuoviRiferimentoCatastale(int $index): void
{
if (! $this->stabile instanceof StabileModel) {
return;
}
$config = (array) ($this->stabile->configurazione_avanzata ?? []);
$sec = (array) ($config['altri_riferimenti_catastali'] ?? []);
if (isset($sec[$index])) {
unset($sec[$index]);
$config['altri_riferimenti_catastali'] = array_values($sec);
$this->stabile->configurazione_avanzata = $config;
$this->stabile->save();
$this->stabile->refresh();
Notification::make()->title('Riferimento catastale rimosso')->info()->send();
}
}
public function toggleMostraRiscaldamento(): void
{
if (! $this->stabile) {

View File

@ -1374,48 +1374,86 @@ private function populateNominativiStoriciFallback(): void
}
$mirrorRows = $q->orderBy('source_year')->get();
$grouped = [];
foreach ($mirrorRows as $m) {
$yLabel = match ($m->source_year) {
'0004' => '2026 (Gestione 0004)',
'0003' => '2025 (Gestione 0003)',
'0001' => '2024 (Gestione 0001)',
default => 'Gestione ' . $m->source_year,
$yearStr = match ($m->source_year) {
'0004', '0914' => '2026',
'0003', '0913' => '2025',
'0001', '0912' => '2024',
default => 'Gestione ' . $m->source_year,
};
$yLabel = $yearStr . ' (' . $m->source_year . ')';
$owner = trim((string) ($m->nom_cond ?? $m->proprietario ?? ''));
if ($owner !== '') {
$fallbackList[] = [
'persona_id' => null,
'nome' => $owner,
'codice_fiscale'=> ! empty($m->codice_fiscale) ? $m->codice_fiscale : null,
'tipo_relazione'=> 'proprietario',
'ruolo_label' => 'Proprietario (' . $yLabel . ')',
'quota' => 100.0,
'quota_label' => '100,00',
'data_inizio' => $yLabel,
'data_fine' => null,
'attivo' => false,
'fonte' => 'Archivio storico legacy',
];
$key = 'proprietario:' . mb_strtoupper($owner) . ':' . trim((string) $m->codice_fiscale);
if (! isset($grouped[$key])) {
$grouped[$key] = [
'persona_id' => null,
'nome' => $owner,
'codice_fiscale'=> ! empty($m->codice_fiscale) ? $m->codice_fiscale : null,
'tipo_relazione'=> 'proprietario',
'gestioni' => [$yLabel],
'years' => [$yearStr],
'quota' => ($m->source_table === 'comproprietari' || (float)($m->perc_diritto_reale ?? 0) > 0) ? (float)($m->perc_diritto_reale ?? 50) : 100.0,
'quota_label' => ($m->source_table === 'comproprietari' || (float)($m->perc_diritto_reale ?? 0) > 0) ? number_format((float)($m->perc_diritto_reale ?? 50), 2, ',', '.') : '100,00',
'attivo' => false,
'fonte' => $m->source_table === 'comproprietari' ? 'Legacy comproprietari' : 'Archivio storico legacy',
];
} else {
if (! in_array($yLabel, $grouped[$key]['gestioni'])) {
$grouped[$key]['gestioni'][] = $yLabel;
$grouped[$key]['years'][] = $yearStr;
}
}
}
$inquil = trim((string) ($m->inquilino ?? $m->inquil_nome ?? ''));
if ($inquil !== '') {
$fallbackList[] = [
'persona_id' => null,
'nome' => $inquil,
'codice_fiscale'=> ! empty($m->inquil_cod_fisc) ? $m->inquil_cod_fisc : null,
'tipo_relazione'=> 'inquilino',
'ruolo_label' => 'Inquilino (' . $yLabel . ')',
'quota' => 100.0,
'quota_label' => '100,00',
'data_inizio' => $yLabel,
'data_fine' => null,
'attivo' => false,
'fonte' => 'Archivio storico legacy',
];
$inqCf = trim((string) ($m->inquil_cod_fisc ?? $m->codice_fiscale ?? ''));
$key = 'inquilino:' . mb_strtoupper($inquil) . ':' . $inqCf;
if (! isset($grouped[$key])) {
$grouped[$key] = [
'persona_id' => null,
'nome' => $inquil,
'codice_fiscale'=> $inqCf !== '' ? $inqCf : null,
'tipo_relazione'=> 'inquilino',
'gestioni' => [$yLabel],
'years' => [$yearStr],
'quota' => 100.0,
'quota_label' => '100,00',
'attivo' => false,
'fonte' => 'Archivio storico legacy',
];
} else {
if (! in_array($yLabel, $grouped[$key]['gestioni'])) {
$grouped[$key]['gestioni'][] = $yLabel;
$grouped[$key]['years'][] = $yearStr;
}
}
}
}
foreach ($grouped as $item) {
$gSpan = count($item['gestioni']) > 1
? implode(' → ', [$item['years'][0], end($item['years'])]) . ' (Gestioni ' . implode(', ', array_map(fn($g) => explode(' ', $g)[1] ?? $g, $item['gestioni'])) . ')'
: $item['gestioni'][0];
$fallbackList[] = [
'persona_id' => $item['persona_id'],
'nome' => $item['nome'],
'codice_fiscale'=> $item['codice_fiscale'],
'tipo_relazione'=> $item['tipo_relazione'],
'ruolo_label' => ucfirst($item['tipo_relazione']) . ' (' . $gSpan . ')',
'quota' => $item['quota'],
'quota_label' => $item['quota_label'],
'data_inizio' => $gSpan,
'data_fine' => null,
'attivo' => $item['attivo'],
'fonte' => $item['fonte'],
];
}
}
}

View File

@ -0,0 +1,45 @@
# ASCII Wireframe - Scheda Stabile e Dati Catastali
URL: `http://192.168.0.205:8000/admin-filament/condomini/stabile`
```text
+-----------------------------------------------------------------------------------------------------------------------+
| NETGESCON · CENTRO STELLA [ Utente: Cecilia Tordini v ] |
+-----------------------------------------------------------------------------------------------------------------------+
| CONDOMINI > SCHEDA STABILE |
| |
| SUPERCONDOMINIO MILIZIE 3 |
| Codice Operatore: 0021 · Viale delle Milizie 3 · Roma |
| [ Rate emesse ] [ Movimenti / Import estratto ] [ Posta stabile ] |
| |
| +-----------------------------------------------------------------------------------------------------------------+ |
| | TAB: [ Dati generali (Active) ] [ Unità ] [ Palazzine ] [ Assicurazioni ] [ Tabelle ] [ Rate ] [ Gestioni ] ... | |
| +-----------------------------------------------------------------------------------------------------------------+ |
| |
| +------------------------------------------------------+ +-------------------------------------------------------+ |
| | INFORMAZIONI GENERALI | | INDIRIZZO COMPLETO | |
| +------------------------------------------------------+ +-------------------------------------------------------+ |
| | ID Stabile: STAB-0021 | | Indirizzo: Viale delle Milizie 3 | |
| | Denominazione: SUPERCONDOMINIO MILIZIE 3 | | Città: Roma | |
| | Codice Fiscale: 80234560589 | | CAP: 00192 | |
| | CF Amministratore: BRNMHL69M11H501K | | Provincia: RM | |
| | Riscaldamento: [ Attivo / Disattivo ] | | Indirizzo Completo: Viale delle Milizie 3, 00192 Roma | |
| +------------------------------------------------------+ +-------------------------------------------------------+ |
| |
| +-----------------------------------------------------------------------------------------------------------------+ |
| | DATI CATASTALI E AMMINISTRATIVI (Da Stabili.mdb e Archivio Consolidato) | |
| +-----------------------------------------------------------------------------------------------------------------+ |
| | CATASTO PRINCIPALE | CONTRIBUTI / INPS | STATISTICHE E PALAZZINE | |
| +------------------------------------------+-------------------------------+--------------------------------------+ |
| | Codice Comune: H501 (Roma) | Posizione INPS: 8493021948 | N. Condomini: 48 | |
| | Foglio: 404 | N. Contribuente: 1029482 | N. Unità: 52 | |
| | Particella: 98 | Codice Destinatario SDI: 00000| N. Palazzine: 4 (A, B, C, D) | |
| | Sezione: H501 | PEC: milizie3@pec.it | | |
| +------------------------------------------+-------------------------------+--------------------------------------+ |
| | RIFERIMENTI CATASTALI AGGIUNTIVI / SECONDARI (Es. Palazzina D o Corpi Separati) [ + Aggiungi Sezione ] | |
| +------------------------------------------+-------------------------------+--------------------------------------+ |
| | - Ref #1: Palazzina D (Corpo Separato) | Foglio: 404 | Particella: 99 | Sezione: H501 | Sub: — | |
| | - Ref #2: Locali Commerciali Seminterrato | Foglio: 404 | Particella: 100 | Sezione: H501 | Sub: — | |
| +-----------------------------------------------------------------------------------------------------------------+ |
+-----------------------------------------------------------------------------------------------------------------------+
```

View File

@ -260,6 +260,54 @@ class="inline-flex items-center rounded-lg border border-emerald-200 bg-emerald-
</dl>
</div>
</div>
@php
$altriCatasto = (array) data_get($stabile->configurazione_avanzata, 'altri_riferimenti_catastali', []);
@endphp
<!-- Riferimenti Catastali Aggiuntivi / Secondari (es. Palazzine o Corpi Separati) -->
<div class="mt-6 pt-4 border-t border-yellow-200 dark:border-yellow-700">
<div class="flex items-center justify-between mb-3">
<h5 class="font-medium text-gray-900 dark:text-gray-100 flex items-center gap-2">
<i class="fas fa-layer-group text-yellow-600"></i>
Riferimenti Catastali Aggiuntivi / Secondari (es. Palazzina D, Supercondominio)
</h5>
</div>
@if(! empty($altriCatasto))
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mb-4">
@foreach($altriCatasto as $idx => $ref)
<div class="bg-white dark:bg-gray-800 p-3 rounded-lg border border-yellow-200 dark:border-yellow-700 flex items-center justify-between text-xs">
<div>
<span class="font-bold text-gray-900 dark:text-gray-100">{{ $ref['descrizione'] ?? ('Sezione #' . ($idx+1)) }}</span>
<div class="text-gray-600 dark:text-gray-400 font-mono mt-0.5">
Foglio: {{ $ref['foglio'] ?: '-' }} | Particella: {{ $ref['particella'] ?: '-' }} | Sezione: {{ $ref['sezione'] ?: '-' }} | Sub: {{ $ref['subalterno'] ?: '-' }}
</div>
</div>
<x-filament::button size="xs" color="danger" wire:click="rimuoviRiferimentoCatastale({{ $idx }})">
Rimuovi
</x-filament::button>
</div>
@endforeach
</div>
@endif
<!-- Form per aggiungere nuova sezione catastale -->
<div class="bg-white dark:bg-gray-800 p-4 rounded-lg border border-yellow-200 dark:border-yellow-700">
<h6 class="text-xs font-semibold text-gray-700 dark:text-gray-300 mb-2">Aggiungi Riferimento Catastale Sezionale / Palazzina</h6>
<div class="grid grid-cols-1 sm:grid-cols-5 gap-2">
<input type="text" wire:model.defer="nuovoRiferimentoCatastale.descrizione" placeholder="Descrizione (es. Palazzina D)" class="text-xs rounded border-gray-300 dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700">
<input type="text" wire:model.defer="nuovoRiferimentoCatastale.foglio" placeholder="Foglio" class="text-xs rounded border-gray-300 dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700">
<input type="text" wire:model.defer="nuovoRiferimentoCatastale.particella" placeholder="Particella" class="text-xs rounded border-gray-300 dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700">
<input type="text" wire:model.defer="nuovoRiferimentoCatastale.sezione" placeholder="Sezione" class="text-xs rounded border-gray-300 dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700">
<div class="flex gap-2">
<input type="text" wire:model.defer="nuovoRiferimentoCatastale.subalterno" placeholder="Sub" class="w-full text-xs rounded border-gray-300 dark:bg-gray-900 dark:text-gray-100 dark:border-gray-700">
<x-filament::button size="xs" color="warning" wire:click="salvaNuovoRiferimentoCatastale">
Salva
</x-filament::button>
</div>
</div>
</div>
</div>
<!-- Note -->

View File

@ -16,6 +16,14 @@ ## 2. Collegamento Contabile (`incassi`, `rate`, `emes_det`)
- `'I'`: Inquilino / Locatario
- **Funzione**: Il campo `cod_cond` accoppiato con `cond_inquil` lega in maniera univoca ciascuna riga di addebito o incasso (`incassi`, `rate`, `emes_det` in `generale_stabile.mdb`) all'anagrafica del condomino o dell'inquilino per quella specifica gestione.
## 3. Gestione Percentuali e Movimentazioni Temporali
- Le quote e percentuali di possesso (`perc_diritto_reale`, es. 50% / 50%) devono essere mantenute con precisione senza forzare la Piena Proprietà (100%) in presenza di comproprietari o contitolari.
- Ciascun avvicendamento storico va conservato nelle movimentazioni temporali per l'anno gestione di competenza.
## 4. Dati Catastali Stabile (`Stabili.mdb` - Prefisso `AC_`)
- **Estrazione da `Stabili.mdb`**:
- `AC_Foglio` -> `foglio` (es. `404`)
- `AC_partic1` / `AC_partic2` -> `particella` (es. `98`, `96`, `49`)
- `AC_urb_cat` -> `sezione` (es. `H501`)
- `Catasto_comune` -> `codice_comune` (es. `Roma`, `H501`)
- `Catasto_PR` -> `provincia` (es. `RM`)
- **Gestione Sezioni Catastali Multiple / Palazzine**:
- Negli stabili articolati o supercondomini (es. Milizie 3 / 0021 con Palazzina D in altra sezione/particella), la configurazione avanzata dello stabile conserva l'array `altri_riferimenti_catastali`.
- Ciascun riferimento sezionale o di palazzina specifica `descrizione`, `foglio`, `particella`, `sezione`, `subalterno`, consentendo l'aggancio diretto alle rispettive unità immobiliari.