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 = [];
|
||||
|
||||
foreach ($mirrorRows as $m) {
|
||||
$yearStr = match ($m->source_year) {
|
||||
'0004', '0914' => '2026',
|
||||
'0003', '0913' => '2025',
|
||||
'0001', '0912' => '2024',
|
||||
default => 'Gestione ' . $m->source_year,
|
||||
};
|
||||
$yLabel = $yearStr . ' (' . $m->source_year . ')';
|
||||
$gCode = (string) $m->source_year;
|
||||
$yLabel = 'Gestione ' . $gCode;
|
||||
|
||||
$owner = trim((string) ($m->nom_cond ?? $m->proprietario ?? ''));
|
||||
if ($owner !== '') {
|
||||
|
|
@ -1394,17 +1389,15 @@ private function populateNominativiStoriciFallback(): void
|
|||
'nome' => $owner,
|
||||
'codice_fiscale'=> ! empty($m->codice_fiscale) ? $m->codice_fiscale : null,
|
||||
'tipo_relazione'=> 'proprietario',
|
||||
'gestioni' => [$yLabel],
|
||||
'years' => [$yearStr],
|
||||
'gestioni' => [$gCode],
|
||||
'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;
|
||||
if (! in_array($gCode, $grouped[$key]['gestioni'])) {
|
||||
$grouped[$key]['gestioni'][] = $gCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1419,26 +1412,25 @@ private function populateNominativiStoriciFallback(): void
|
|||
'nome' => $inquil,
|
||||
'codice_fiscale'=> $inqCf !== '' ? $inqCf : null,
|
||||
'tipo_relazione'=> 'inquilino',
|
||||
'gestioni' => [$yLabel],
|
||||
'years' => [$yearStr],
|
||||
'gestioni' => [$gCode],
|
||||
'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;
|
||||
if (! in_array($gCode, $grouped[$key]['gestioni'])) {
|
||||
$grouped[$key]['gestioni'][] = $gCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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];
|
||||
$gList = $item['gestioni'];
|
||||
$gSpan = count($gList) > 1
|
||||
? 'Gestioni ' . implode(', ', $gList) . ' (Titolare storico)'
|
||||
: 'Gestione ' . $gList[0];
|
||||
|
||||
$fallbackList[] = [
|
||||
'persona_id' => $item['persona_id'],
|
||||
|
|
@ -2814,6 +2806,128 @@ protected function hydrateMillesimi(): void
|
|||
})
|
||||
->values()
|
||||
->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
|
||||
|
|
@ -3326,7 +3440,7 @@ protected function hydrateRelazioni(): void
|
|||
'ruolo_label' => 'Proprietario 100%',
|
||||
'quota' => 100.0,
|
||||
'quota_label' => '100,00',
|
||||
'data_inizio' => '01/01/' . $activeAnno,
|
||||
'data_inizio' => 'Gestione ' . $activeAnno,
|
||||
'data_fine' => null,
|
||||
'attivo' => true,
|
||||
'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
|
||||
+-----------------------------------------------------------------------------------------------------------------------+
|
||||
| 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 |
|
||||
| [<- Prec.] Unità: [ Scala A - Int. 11 (Piano 4 - Abitazione) [A-11] — BENEDETTO DANIELA v ] [Succ. ->] |
|
||||
| |
|
||||
| [ Riepilogo ] [ Tabelle Millesimali ] [ Catasto ] [ Economico ] [ Estratto Conto ] [ Acqua ] |
|
||||
| Stabile: [ 0016 - GERMANICO 96 v ] Anno Gestione: [ 0914 (Anno 2026 - Attiva) v ] |
|
||||
| Barra selezione unità: [<- Prec.] Unità: [ Scala B - Int. 4 (ID 321) v ] [Succ. ->] |
|
||||
| |
|
||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||
| | DETTAGLI UNITA IMMOBILIARE & ANAGRAFICA ATTIVA | |
|
||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||
| | Codice: 0021-A-11 | Scala: A | Piano: 4 | Interno: 11 | Tipo: Abitazione | |
|
||||
| | Proprietario Attivo: BENEDETTO DANIELA (Quota 100,00%) - Dal 09/06/2026 | |
|
||||
| | TAB: [ Riepilogo (Active) ] [ Tabelle Millesimali ] [ Estratto Conto ] [ Ripartizione Spese ] [ Dati Catasto ] | |
|
||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||
| |
|
||||
| +-----------------------------------------------------------------------------------------------------------------+ |
|
||||
| | 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 | |
|
||||
| | Dettaglio: CF BNDDNL86M58H224O | |
|
||||
| | - BARONE MICHELE | Proprietario | Quota: 50,00% | CF: BRNMHL69M11H501K | [Apri Anagrafica] | |
|
||||
| | - 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 | |
|
||||
| | Dettaglio: CF 01234567890 · Gestione 2026 (0004) | |
|
||||
| | [•] Proprietario: BARONE MICHELE (Quota: 50,00%) | |
|
||||
| | Intervallo: Gestioni 0004, 0005, 0909, 0912, 0913, 0914 (Titolare storico consolidato) | |
|
||||
| | | |
|
||||
| | [ Gestione 0003 ] ATER C/O UFFICIO CONDOMINI PASSIVI (Proprietario 100%) · Anno 2025 | |
|
||||
| | [ Gestione 0001 ] ATER C/O UFFICIO CONDOMINI PASSIVI (Proprietario 100%) · Anno 2024 | |
|
||||
| | [•] Comproprietario: FRANCIONI CLAUDIA (Quota: 50,00%) | |
|
||||
| | 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`.
|
||||
- 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