fix(unita): enforce deterministic timeline gestion spans, import tabelle/dett_tab millesimal tables from legacy MDB and document Commercialista rule (task-d095b0e23b)
This commit is contained in:
parent
81734c7eea
commit
f345abc3ba
|
|
@ -1377,13 +1377,8 @@ private function populateNominativiStoriciFallback(): void
|
||||||
$grouped = [];
|
$grouped = [];
|
||||||
|
|
||||||
foreach ($mirrorRows as $m) {
|
foreach ($mirrorRows as $m) {
|
||||||
$yearStr = match ($m->source_year) {
|
$gCode = (string) $m->source_year;
|
||||||
'0004', '0914' => '2026',
|
$yLabel = 'Gestione ' . $gCode;
|
||||||
'0003', '0913' => '2025',
|
|
||||||
'0001', '0912' => '2024',
|
|
||||||
default => 'Gestione ' . $m->source_year,
|
|
||||||
};
|
|
||||||
$yLabel = $yearStr . ' (' . $m->source_year . ')';
|
|
||||||
|
|
||||||
$owner = trim((string) ($m->nom_cond ?? $m->proprietario ?? ''));
|
$owner = trim((string) ($m->nom_cond ?? $m->proprietario ?? ''));
|
||||||
if ($owner !== '') {
|
if ($owner !== '') {
|
||||||
|
|
@ -1394,17 +1389,15 @@ private function populateNominativiStoriciFallback(): void
|
||||||
'nome' => $owner,
|
'nome' => $owner,
|
||||||
'codice_fiscale'=> ! empty($m->codice_fiscale) ? $m->codice_fiscale : null,
|
'codice_fiscale'=> ! empty($m->codice_fiscale) ? $m->codice_fiscale : null,
|
||||||
'tipo_relazione'=> 'proprietario',
|
'tipo_relazione'=> 'proprietario',
|
||||||
'gestioni' => [$yLabel],
|
'gestioni' => [$gCode],
|
||||||
'years' => [$yearStr],
|
|
||||||
'quota' => ($m->source_table === 'comproprietari' || (float)($m->perc_diritto_reale ?? 0) > 0) ? (float)($m->perc_diritto_reale ?? 50) : 100.0,
|
'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',
|
'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,
|
'attivo' => false,
|
||||||
'fonte' => $m->source_table === 'comproprietari' ? 'Legacy comproprietari' : 'Archivio storico legacy',
|
'fonte' => $m->source_table === 'comproprietari' ? 'Legacy comproprietari' : 'Archivio storico legacy',
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
if (! in_array($yLabel, $grouped[$key]['gestioni'])) {
|
if (! in_array($gCode, $grouped[$key]['gestioni'])) {
|
||||||
$grouped[$key]['gestioni'][] = $yLabel;
|
$grouped[$key]['gestioni'][] = $gCode;
|
||||||
$grouped[$key]['years'][] = $yearStr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1419,26 +1412,25 @@ private function populateNominativiStoriciFallback(): void
|
||||||
'nome' => $inquil,
|
'nome' => $inquil,
|
||||||
'codice_fiscale'=> $inqCf !== '' ? $inqCf : null,
|
'codice_fiscale'=> $inqCf !== '' ? $inqCf : null,
|
||||||
'tipo_relazione'=> 'inquilino',
|
'tipo_relazione'=> 'inquilino',
|
||||||
'gestioni' => [$yLabel],
|
'gestioni' => [$gCode],
|
||||||
'years' => [$yearStr],
|
|
||||||
'quota' => 100.0,
|
'quota' => 100.0,
|
||||||
'quota_label' => '100,00',
|
'quota_label' => '100,00',
|
||||||
'attivo' => false,
|
'attivo' => false,
|
||||||
'fonte' => 'Archivio storico legacy',
|
'fonte' => 'Archivio storico legacy',
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
if (! in_array($yLabel, $grouped[$key]['gestioni'])) {
|
if (! in_array($gCode, $grouped[$key]['gestioni'])) {
|
||||||
$grouped[$key]['gestioni'][] = $yLabel;
|
$grouped[$key]['gestioni'][] = $gCode;
|
||||||
$grouped[$key]['years'][] = $yearStr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($grouped as $item) {
|
foreach ($grouped as $item) {
|
||||||
$gSpan = count($item['gestioni']) > 1
|
$gList = $item['gestioni'];
|
||||||
? implode(' → ', [$item['years'][0], end($item['years'])]) . ' (Gestioni ' . implode(', ', array_map(fn($g) => explode(' ', $g)[1] ?? $g, $item['gestioni'])) . ')'
|
$gSpan = count($gList) > 1
|
||||||
: $item['gestioni'][0];
|
? 'Gestioni ' . implode(', ', $gList) . ' (Titolare storico)'
|
||||||
|
: 'Gestione ' . $gList[0];
|
||||||
|
|
||||||
$fallbackList[] = [
|
$fallbackList[] = [
|
||||||
'persona_id' => $item['persona_id'],
|
'persona_id' => $item['persona_id'],
|
||||||
|
|
@ -2814,6 +2806,128 @@ protected function hydrateMillesimi(): void
|
||||||
})
|
})
|
||||||
->values()
|
->values()
|
||||||
->all();
|
->all();
|
||||||
|
|
||||||
|
if (empty($this->millesimiPerTabella)) {
|
||||||
|
$this->millesimiPerTabella = $this->loadMillesimiFromLegacyMdb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function loadMillesimiFromLegacyMdb(): array
|
||||||
|
{
|
||||||
|
if (! $this->unita || ! $this->unita->stabile) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$codStabile = trim((string) $this->unita->stabile->codice_stabile);
|
||||||
|
$scala = trim((string) $this->unita->scala);
|
||||||
|
$interno = trim((string) $this->unita->interno);
|
||||||
|
|
||||||
|
if ($codStabile === '' || $interno === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$idCond = null;
|
||||||
|
if ($this->hasImportConnection() && DbSchema::connection('gescon_import')->hasTable('condomin_mirror')) {
|
||||||
|
$q = DB::connection('gescon_import')->table('condomin_mirror')
|
||||||
|
->where('cod_stabile', $codStabile)
|
||||||
|
->where('interno', $interno);
|
||||||
|
if ($scala !== '') {
|
||||||
|
$q->where('scala', $scala);
|
||||||
|
}
|
||||||
|
$mRow = $q->first();
|
||||||
|
if ($mRow) {
|
||||||
|
$idCond = $mRow->id_cond ?: $mRow->cod_cond;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $idCond) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$candidatePaths = [
|
||||||
|
"/mnt/gescon-archives/gescon/{$codStabile}/0914/singolo_anno.mdb",
|
||||||
|
"/mnt/gescon-archives/gescon/{$codStabile}/0004/singolo_anno.mdb",
|
||||||
|
];
|
||||||
|
|
||||||
|
$mdbPath = null;
|
||||||
|
foreach ($candidatePaths as $p) {
|
||||||
|
if (file_exists($p) && is_readable($p)) {
|
||||||
|
$mdbPath = $p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $mdbPath) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$tabRows = $this->extractMdbTableRows($mdbPath, 'tabelle');
|
||||||
|
$dettRows = $this->extractMdbTableRows($mdbPath, 'dett_tab');
|
||||||
|
|
||||||
|
$tabMap = [];
|
||||||
|
foreach ($tabRows as $tr) {
|
||||||
|
$c = isset($tr['cod_tab']) ? (string) $tr['cod_tab'] : null;
|
||||||
|
if ($c) {
|
||||||
|
$tabMap[$c] = isset($tr['des_tab']) && trim((string) $tr['des_tab']) !== '' ? (string) $tr['des_tab'] : $c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$res = [];
|
||||||
|
foreach ($dettRows as $dr) {
|
||||||
|
$drIdCond = isset($dr['id_cond']) ? (string) $dr['id_cond'] : null;
|
||||||
|
$drInq = isset($dr['cond_inquil']) ? (string) $dr['cond_inquil'] : 'C';
|
||||||
|
$mm = isset($dr['mm']) && is_numeric($dr['mm']) ? (float) $dr['mm'] : 0.0;
|
||||||
|
|
||||||
|
if ($drIdCond === (string) $idCond && strtoupper($drInq) === 'C' && $mm > 0) {
|
||||||
|
$cTab = isset($dr['cod_tab']) ? (string) $dr['cod_tab'] : 'TAB';
|
||||||
|
$nomeTab = $tabMap[$cTab] ?? $cTab;
|
||||||
|
$res[] = [
|
||||||
|
'tipo' => str_contains(strtolower($cTab), 'risc') ? 'riscaldamento' : (str_contains(strtolower($cTab), 'stra') ? 'straordinaria' : 'ordinaria'),
|
||||||
|
'gruppo' => $this->mapTipoToGruppo($cTab),
|
||||||
|
'id' => null,
|
||||||
|
'codice' => $cTab,
|
||||||
|
'nome' => $nomeTab,
|
||||||
|
'millesimi' => $mm,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $res;
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function extractMdbTableRows(string $mdbPath, string $tableName): array
|
||||||
|
{
|
||||||
|
$proc = new \Symfony\Component\Process\Process(['mdb-export', $mdbPath, $tableName]);
|
||||||
|
$proc->run();
|
||||||
|
|
||||||
|
if (! $proc->isSuccessful()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$csvContent = $proc->getOutput();
|
||||||
|
$stream = fopen('php://memory', 'r+');
|
||||||
|
fwrite($stream, $csvContent);
|
||||||
|
rewind($stream);
|
||||||
|
|
||||||
|
$header = fgetcsv($stream);
|
||||||
|
if (! $header) {
|
||||||
|
fclose($stream);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$rows = [];
|
||||||
|
while (($data = fgetcsv($stream)) !== false) {
|
||||||
|
if (count($data) === count($header)) {
|
||||||
|
$rows[] = array_combine($header, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose($stream);
|
||||||
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setMillesimiGruppo(string $gruppo): void
|
public function setMillesimiGruppo(string $gruppo): void
|
||||||
|
|
@ -3326,7 +3440,7 @@ protected function hydrateRelazioni(): void
|
||||||
'ruolo_label' => 'Proprietario 100%',
|
'ruolo_label' => 'Proprietario 100%',
|
||||||
'quota' => 100.0,
|
'quota' => 100.0,
|
||||||
'quota_label' => '100,00',
|
'quota_label' => '100,00',
|
||||||
'data_inizio' => '01/01/' . $activeAnno,
|
'data_inizio' => 'Gestione ' . $activeAnno,
|
||||||
'data_fine' => null,
|
'data_fine' => null,
|
||||||
'attivo' => true,
|
'attivo' => true,
|
||||||
'fonte' => 'legacy_condomin_mirror',
|
'fonte' => 'legacy_condomin_mirror',
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,55 @@
|
||||||
# ASCII Wireframe - Scheda Unità Immobiliare
|
# ASCII Wireframe - Scheda Unità Immobiliare (Timeline e Tabelle Millesimali)
|
||||||
|
|
||||||
URL: `http://192.168.0.205:8000/admin-filament/unita-immobiliare`
|
URL: `http://192.168.0.205:8000/admin-filament/unita-immobiliare?unita_id=321`
|
||||||
|
|
||||||
```text
|
```text
|
||||||
+-----------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------------------------------------------------------------------------------------+
|
||||||
| NETGESCON · CENTRO STELLA [ Utente: Cecilia Tordini v ] |
|
| NETGESCON · CENTRO STELLA [ Utente: Cecilia Tordini v ] |
|
||||||
+-----------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------------------------------------------------------------------------------------+
|
||||||
| UNITA IMMOBILIARE |
|
| UNITA IMMOBILIARI > SCHEDA UNITA IMMOBILIARE (Scala B - Int. 4 - Piano 2) |
|
||||||
| |
|
| |
|
||||||
| BARRA DI SELEZIONE E TIMELINE |
|
| Stabile: [ 0016 - GERMANICO 96 v ] Anno Gestione: [ 0914 (Anno 2026 - Attiva) v ] |
|
||||||
| [<- Prec.] Unità: [ Scala A - Int. 11 (Piano 4 - Abitazione) [A-11] — BENEDETTO DANIELA v ] [Succ. ->] |
|
| Barra selezione unità: [<- Prec.] Unità: [ Scala B - Int. 4 (ID 321) v ] [Succ. ->] |
|
||||||
| |
|
|
||||||
| [ Riepilogo ] [ Tabelle Millesimali ] [ Catasto ] [ Economico ] [ Estratto Conto ] [ Acqua ] |
|
|
||||||
| |
|
| |
|
||||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
| | DETTAGLI UNITA IMMOBILIARE & ANAGRAFICA ATTIVA | |
|
| | TAB: [ Riepilogo (Active) ] [ Tabelle Millesimali ] [ Estratto Conto ] [ Ripartizione Spese ] [ Dati Catasto ] | |
|
||||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
|
||||||
| | Codice: 0021-A-11 | Scala: A | Piano: 4 | Interno: 11 | Tipo: Abitazione | |
|
|
||||||
| | Proprietario Attivo: BENEDETTO DANIELA (Quota 100,00%) - Dal 09/06/2026 | |
|
|
||||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
| |
|
| |
|
||||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
| | TIMELINE SUBENTRI E GESTIONI ANTERIORE (Cronistoria Titolari) | |
|
| | TITOLARI E COMPROPRIETARI IN CARICA (Gestione 0914 - Anno 2026) | |
|
||||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
| | [ Da 09/06/2026 ] BENEDETTO DANIELA (Proprietario 100%) · Fonte: Anagrafica consolidata | |
|
| | - BARONE MICHELE | Proprietario | Quota: 50,00% | CF: BRNMHL69M11H501K | [Apri Anagrafica] | |
|
||||||
| | Dettaglio: CF BNDDNL86M58H224O | |
|
| | - FRANCIONI CLAUDIA / | Comproprietario | Quota: 50,00% | CF: FRNCLD49P51H501B | [Apri Anagrafica] | |
|
||||||
|
| | [Email: cecilia.tordini@gmail.com] | |
|
||||||
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
|
| |
|
||||||
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
|
| | TIMELINE SUBENTRI E GESTIONI ANTERIORI (Determinismo Certificato Legacy) | |
|
||||||
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
|
| | Cronistoria titolari ed avvicendamenti per questa unità immobiliare tra le diverse gestioni | |
|
||||||
| | | |
|
| | | |
|
||||||
| | [ Fino a 08/06/2026 ] ATER C/O UFFICIO CONDOMINI PASSIVI (Proprietario 100%) · Fonte: Legacy condomin | |
|
| | [•] Proprietario: BARONE MICHELE (Quota: 50,00%) | |
|
||||||
| | Dettaglio: CF 01234567890 · Gestione 2026 (0004) | |
|
| | Intervallo: Gestioni 0004, 0005, 0909, 0912, 0913, 0914 (Titolare storico consolidato) | |
|
||||||
| | | |
|
| | | |
|
||||||
| | [ Gestione 0003 ] ATER C/O UFFICIO CONDOMINI PASSIVI (Proprietario 100%) · Anno 2025 | |
|
| | [•] Comproprietario: FRANCIONI CLAUDIA (Quota: 50,00%) | |
|
||||||
| | [ Gestione 0001 ] ATER C/O UFFICIO CONDOMINI PASSIVI (Proprietario 100%) · Anno 2024 | |
|
| | Intervallo: Gestioni 0004, 0005, 0909, 0912, 0913, 0914 (Legacy comproprietari) | |
|
||||||
|
| | CF: FRNCLD49P51H501B · Email: cecilia.tordini@gmail.com | |
|
||||||
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
|
| |
|
||||||
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
|
| | TABELLE MILLESIMALI E ATTRIBUZIONE QUOTE (Da singolo_anno.mdb: tabelle & dett_tab) | |
|
||||||
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
|
| | CODICE TABELLA | NOME TABELLA / CATEGORIA | VALORE MILLESIMI (mm) | SOGGETTO ATTRIBUTO | |
|
||||||
|
| +-----------------+------------------------------------+-----------------------+------------------------------------+ |
|
||||||
|
| | TAB.A | Tabella Millesimale A (Proprietà) | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | TAB.BB | Tabella Millesimale Scala B | 21,6060 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | TABA.P | Tabella Millesimale Proprietà P. | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | DET_18 | Detrazione Fiscali 18% | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | REND | Rendita Fabbricati | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | RI.ASS | Ripartizione Assicurazione | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | ANTICI | Anticipi Condominiali | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | L02.ST | Lavori Straordinari L02 | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
|
| | L03.ST | Lavori Straordinari L03 | 15,2780 mm | Condomino (BARONE MICHELE/FRANCIONI| |
|
||||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||||
+-----------------------------------------------------------------------------------------------------------------------+
|
+-----------------------------------------------------------------------------------------------------------------------+
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,16 @@ ## 4. Dati Catastali Stabile (`Stabili.mdb` - Prefisso `AC_`)
|
||||||
- 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`.
|
- 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.
|
- Ciascun riferimento sezionale o di palazzina specifica `descrizione`, `foglio`, `particella`, `sezione`, `subalterno`, consentendo l'aggancio diretto alle rispettive unità immobiliari.
|
||||||
|
|
||||||
|
## 5. Tabelle Millesimali da Legacy (`tabelle` e `dett_tab` in `singolo_anno.mdb`)
|
||||||
|
- **Tabella definizioni**: `tabelle` con campi `cod_tab`, `des_tab`, `totale`.
|
||||||
|
- **Tabella dettagli ed attribuzione**: `dett_tab` con campi `cod_tab`, `id_cond`, `cond_inquil`, `mm`.
|
||||||
|
- **Regola di collegamento**:
|
||||||
|
- `tabelle.cod_tab` si lega a `dett_tab.cod_tab`.
|
||||||
|
- `dett_tab.id_cond` si lega tassativamente a `condomin.id_cond` dell'unità immobiliare per quella specifica gestione.
|
||||||
|
- `dett_tab.cond_inquil` (`'C'` Condomino, `'I'` Inquilino) attribuisce i millesimi (`mm`) al soggetto titolare.
|
||||||
|
|
||||||
|
## 6. Principio di Deterministicità Assoluta (Regola Commercialista)
|
||||||
|
- **Divieto di Fallback o Date Fittizie**: È tassativamente vietato inventare date fittizie (es. `01/01/2000` o `01/01/2026` ripetute) o stimare ruoli non presenti negli archivi MDB.
|
||||||
|
- **Trattamento dati mancanti**: Se una relazione o una data di decorrenza non è presente negli archivi consolidati, il sistema deve riportare unicamente le gestioni storiche certe (es. `Gestioni 0004, 0005, 0909, 0912, 0913, 0914`) oppure restituire `BLOCCO_DATI`. I dati devono essere certificabili e certi al 100%.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user