From 95af1666c76e41b919f3afead6a20f1d5db19233 Mon Sep 17 00:00:00 2001 From: michele Date: Mon, 31 Aug 2026 15:11:41 +0200 Subject: [PATCH] fix(catasto-hub): elimina mock e fallback hardcoded Milizie 3, sincronizza dati catastali reali da DB --- app/Filament/Pages/Condomini/CatastoHub.php | 756 +++--------------- .../pages/condomini/catasto-hub.blade.php | 14 +- .../run_205_followup_via_agy.sh | 2 +- tests/Feature/CatastoHubDbDrivenTest.php | 89 +++ 4 files changed, 229 insertions(+), 632 deletions(-) create mode 100644 tests/Feature/CatastoHubDbDrivenTest.php diff --git a/app/Filament/Pages/Condomini/CatastoHub.php b/app/Filament/Pages/Condomini/CatastoHub.php index 34b3037..7e643e3 100644 --- a/app/Filament/Pages/Condomini/CatastoHub.php +++ b/app/Filament/Pages/Condomini/CatastoHub.php @@ -214,6 +214,8 @@ public function mount(): void $dirPath = $service->getStoragePath($this->stabileAttivo->id); if (Storage::disk('public')->exists("{$dirPath}/geometria_stabile.json")) { $this->stabileSubalterni = json_decode(Storage::disk('public')->get("{$dirPath}/geometria_stabile.json"), true) ?: []; + } else { + $this->sincronizzaGeometriaDaDb(); } $associazioniPath = "{$dirPath}/anno_2026/associazioni_soppressi.json"; @@ -476,17 +478,6 @@ public function loadUnitaList(): void $jsonFilename = "risultato_immobile_" . (string)$uFoglio . "_" . (string)$uParticella . "{$subLabel}.json"; $jsonRelativePath = "{$dirPath}/{$jsonFilename}"; - if (! Storage::disk('public')->exists($jsonRelativePath) && ! empty($uSubalterno)) { - $subPattern = "_sub{$uSubalterno}.json"; - $allFiles = Storage::disk('public')->files($dirPath); - foreach ($allFiles as $f) { - if (str_contains($f, $subPattern)) { - $jsonRelativePath = $f; - break; - } - } - } - if (Storage::disk('public')->exists($jsonRelativePath)) { try { $sisterContent = json_decode(Storage::disk('public')->get($jsonRelativePath), true); @@ -657,17 +648,6 @@ public function selectUnita(int $unitaId): void } } - // Volture automatiche deterministiche per supercondominio Milizie 3 - if (trim((string)$u->interno) === '3' && trim((string)$uSubalterno) === '3') { - $uSubalterno = '503'; - } - if (trim((string)$u->interno) === '27' && trim((string)$uSubalterno) === '27') { - $uSubalterno = '56'; - } - if (trim((string)$u->interno) === '20' && trim((string)$u->scala) === 'A') { - $uSubalterno = '524'; - } - $this->stagingRawData = []; if ($u->legacy_cond_id && Schema::connection('gescon_import')->hasTable('condomin')) { $raw = DB::connection('gescon_import')->table('condomin') @@ -712,17 +692,6 @@ public function selectUnita(int $unitaId): void $jsonFilename = "risultato_immobile_" . (string)$uFoglio . "_" . (string)$uParticella . "{$subLabel}.json"; $jsonRelativePath = "{$dirPath}/{$jsonFilename}"; - if (! Storage::disk('public')->exists($jsonRelativePath) && ! empty($uSubalterno)) { - $subPattern = "_sub{$uSubalterno}.json"; - $allFiles = Storage::disk('public')->files($dirPath); - foreach ($allFiles as $f) { - if (str_contains($f, $subPattern)) { - $jsonRelativePath = $f; - break; - } - } - } - if (Storage::disk('public')->exists($jsonRelativePath)) { try { $sisterContent = json_decode(Storage::disk('public')->get($jsonRelativePath), true); @@ -893,6 +862,60 @@ protected function loadProprietari(): void }); } + public function sincronizzaGeometriaDaDb(): void + { + if (!$this->stabileAttivo) { + return; + } + + $service = new SisterCatastoService(); + $dirPath = $service->getStoragePath($this->stabileAttivo->id); + + $unitaStabile = UnitaImmobiliare::where('stabile_id', $this->stabileAttivo->id) + ->orderBy('scala') + ->orderBy('piano') + ->orderBy('interno') + ->get(); + + $subalterniList = []; + $indirizzoBase = $this->stabileAttivo->indirizzo ?? ''; + + foreach ($unitaStabile as $u) { + $subVal = trim((string)($u->subalterno ?: '')); + if ($subVal === '') { + continue; + } + + $rendVal = is_numeric($u->rendita_catastale) ? (float)$u->rendita_catastale : 0.0; + $renditaStr = $rendVal > 0.01 ? '€ ' . number_format($rendVal, 2, ',', '.') : '—'; + $cat = $u->categoria_catastale ? self::formattaCategoriaCatastale($u->categoria_catastale) : 'A/2 - Abitazioni di tipo civile'; + + $indDett = $indirizzoBase; + if ($u->scala) { + $indDett .= " Scala {$u->scala}"; + } + if ($u->interno) { + $indDett .= " Int. {$u->interno}"; + } + if ($u->piano) { + $indDett .= " Piano {$u->piano}"; + } + + $subalterniList[] = [ + 'sub' => $subVal, + 'rendita' => $renditaStr, + 'partita' => 'ATTIVA', + 'destinazione' => $cat, + 'indirizzo_completo' => $indDett, + ]; + } + + $this->stabileSubalterni = $subalterniList; + $this->ordinaSubalterniPerInterno(); + + Storage::disk('public')->put("{$dirPath}/geometria_stabile.json", json_encode($this->stabileSubalterni, JSON_PRETTY_PRINT)); + } + public function interrogaGeometriaStabile(): void { if (!$this->stabileAttivo) { @@ -900,249 +923,17 @@ public function interrogaGeometriaStabile(): void } try { - $service = new SisterCatastoService(); - $dirPath = $service->getStoragePath($this->stabileAttivo->id); - - // Caricamento dei dati catastali 1a1 reali forniti dall'utente e dallo staging condomin - $subalterni256 = []; - $subalterni253 = []; - - // 1. Mappa dei valori estratti dal documento reale di Sister (per Particella 256) - $realSisterMap256 = [ - '1' => ['rendita' => '€ 2.227,22', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 1'], - '2' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 2'], - '3' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '4' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 4'], - '5' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 5'], - '6' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 6'], - '7' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '8' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 8'], - '9' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 9'], - '10' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 10'], - '11' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '12' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '13' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 13'], - '14' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 14'], - '15' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 15'], - '16' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 16'], - '17' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 17'], - '18' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '19' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 19'], - '20' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '21' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '22' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 22'], - '23' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 23'], - '24' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 24'], - '25' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '26' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 26'], - '27' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. 27'], - '28' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '29' => ['rendita' => '€ 1.336,33', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Int. B'], - '30' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 1'], - '31' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 2'], - '32' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 3'], - '33' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 4'], - '34' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 5'], - '35' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 6'], - '36' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '37' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '38' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '39' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 10'], - '40' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 11'], - '41' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 12'], - '42' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 13'], - '43' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '44' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 15 Scala B Int. 15'], - '45' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 16'], - '46' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 17'], - '47' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 18'], - '48' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 19'], - '49' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '50' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 21'], - '51' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 22'], - '52' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 23'], - '53' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 24'], - '54' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '55' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Piano 6-S1'], - '56' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '57' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Int. 28'], - '58' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 1'], - '59' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '60' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 3'], - '61' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '62' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 5'], - '63' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '64' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 7'], - '65' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '66' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 9'], - '67' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 10'], - '68' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 11'], - '69' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 12'], - '70' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 13'], - '71' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '72' => ['rendita' => '€ 2.227,22', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 15'], - '73' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 16'], - '74' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 17'], - '75' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '76' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '77' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '78' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '79' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 22'], - '80' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 23'], - '81' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '82' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 25'], - '83' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 26'], - '84' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 27'], - '85' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Int. 28'], - '86' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 24 Piano 5'], - '87' => ['rendita' => '€ 105,77', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 24 Piano S1'], - - // Subalterni speciali >500 - '501' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 14'], - '502' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 18'], - '503' => ['rendita' => '€ 2.375,70', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Interno 3'], - '504' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 4'], - '505' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 19'], - '506' => ['rendita' => '€ 461,71', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala A Piano S1'], - '507' => ['rendita' => '—', 'partita' => 'Soppressa', 'dest' => 'Soppresso', 'ind' => 'Viale delle Milizie 3'], - '508' => ['rendita' => '€ 277,03', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala A Interno A Piano 7'], - '509' => ['rendita' => '€ 1.930,26', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Interno 14 Piano 3'], - '510' => ['rendita' => '€ 200,08', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Interno 14 Piano S1'], - '512' => ['rendita' => '€ 923,43', 'partita' => 'ATTIVA', 'dest' => 'C/2 - Magazzini e locali di deposito', 'ind' => 'Viale delle Milizie 3 Scala A Piano S1'], - '513' => ['rendita' => 'R.Euro:', 'partita' => 'Bene comune non censibile', 'dest' => 'Bene comune non censibile', 'ind' => 'Viale delle Milizie 3 Scala A Piano S1'], - '514' => ['rendita' => '€ 1.930,26', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Interno 8 Piano 1'], - '515' => ['rendita' => '€ 227,24', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala B Interno 8 Piano S1'], - '516' => ['rendita' => '€ 1.930,26', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 21 Piano 5'], - '517' => ['rendita' => '€ 169,29', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 16 Piano S1'], - '518' => ['rendita' => '€ 1.633,29', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala C Interno 2 Piano T'], - '519' => ['rendita' => '€ 123,12', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala C Piano S1'], - '520' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Interno 27 Piano 6'], - '521' => ['rendita' => '€ 123,12', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala B Interno 27 Piano S1'], - '522' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala B Interno 25 Piano 6'], - '523' => ['rendita' => '€ 124,98', 'partita' => 'ATTIVA', 'dest' => 'Cantina / Box (C/2)', 'ind' => 'Viale delle Milizie 3 Scala B Interno 25 Piano S1'], - '524' => ['rendita' => '€ 2.078,74', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Interno 20 Piano 5'], - '525' => ['rendita' => '€ 1.781,78', 'partita' => 'ATTIVA', 'dest' => 'Abitazione (A/2)', 'ind' => 'Viale delle Milizie 3 Scala A Interno 16 Piano S1'], - ]; - - foreach ($realSisterMap256 as $subStr => $item) { - $destVal = $item['dest']; - if (preg_match('/\(([A-F]\/?\d+)\)/i', $destVal, $m)) { - $destVal = self::formattaCategoriaCatastale($m[1]); - } elseif ($subStr === '512') { - $destVal = self::formattaCategoriaCatastale('C02'); - } else { - if (str_contains(strtolower($destVal), 'abitazione')) { - $destVal = self::formattaCategoriaCatastale('A02'); - } elseif (str_contains(strtolower($destVal), 'cantina') || str_contains(strtolower($destVal), 'magazzino')) { - $destVal = self::formattaCategoriaCatastale('C02'); - } - } - - $subalterni256[] = [ - 'sub' => $subStr, - 'rendita' => $item['rendita'], - 'partita' => $item['partita'], - 'destinazione' => $destVal, - 'indirizzo_completo' => $item['ind'] - ]; - } - - // Aggiungiamo eventuali fallbacks da staging solo se non sono Scala D e appartengono a 256 - if (Schema::connection('gescon_import')->hasTable('condomin')) { - $rawStaging256 = DB::connection('gescon_import')->table('condomin') - ->where('cod_stabile', $this->stabileAttivo->codice_stabile) - ->where(function($q) { - $q->whereNull('scala')->orWhere('scala', '<>', 'D'); - }) - ->whereNotNull('catasto_sub') - ->where('catasto_sub', '<>', '') - ->get(); - - foreach ($rawStaging256 as $r) { - $sVal = trim((string)$r->catasto_sub); - if ($sVal !== '' && !isset($realSisterMap256[$sVal])) { - $rendVal = is_numeric($r->catasto_rendita) ? (float)$r->catasto_rendita : 0.0; - $renditaStr = $rendVal > 0.01 ? '€ ' . number_format($rendVal, 2, ',', '.') : '—'; - $cat = strtoupper(trim((string)$r->catasto_categoria)); - $dest = ($cat === 'C02' || $cat === 'C06' || $cat === 'C07') ? 'Cantina / Box (C/2)' : 'Abitazione (' . ($cat ?: 'A/2') . ')'; - - $subalterni256[] = [ - 'sub' => $sVal, - 'rendita' => $renditaStr, - 'partita' => 'ATTIVA', - 'destinazione' => $dest, - 'indirizzo_completo' => 'Viale delle Milizie 3' . ($r->scala ? ', Scala ' . $r->scala : '') . ($r->interno ? ', Interno ' . $r->interno : '') - ]; - $realSisterMap256[$sVal] = true; - } - } - } - - // Scrittura cache isolata Compartimento 1 - Storage::disk('public')->put("{$dirPath}/geometria_stabile_405_256.json", json_encode($subalterni256, JSON_PRETTY_PRINT)); - - // --- COMPARTIMENTO 2: Particella 253 (Scala D) --- - $real253Specs = [ - '1' => ['cat' => 'A02', 'int' => '1', 'piano' => 'T-S1', 'rendita' => 'R.Euro:2227,22', 'cons' => '7,5 vani'], - '3' => ['cat' => 'A02', 'int' => '3', 'piano' => '1-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '4' => ['cat' => 'A02', 'int' => '4', 'piano' => 'S1-1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '5' => ['cat' => 'A02', 'int' => '5', 'piano' => '2-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '6' => ['cat' => 'A02', 'int' => '6', 'piano' => '2-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '7' => ['cat' => 'A02', 'int' => '7', 'piano' => '3-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '8' => ['cat' => '', 'int' => '', 'piano' => '', 'rendita' => 'Soppressa', 'cons' => ''], - '9' => ['cat' => '', 'int' => '', 'piano' => '', 'rendita' => 'Soppressa', 'cons' => ''], - '10' => ['cat' => 'A02', 'int' => '10', 'piano' => '4-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '11' => ['cat' => 'A02', 'int' => '11', 'piano' => '5-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '12' => ['cat' => 'A02', 'int' => '12', 'piano' => '5-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '13' => ['cat' => 'A02', 'int' => '', 'piano' => '6-S1', 'rendita' => 'R.Euro:1781,78', 'cons' => '6 vani'], - '14' => ['cat' => 'A02', 'int' => '14', 'piano' => '6-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '501' => ['cat' => 'A02', 'int' => '2', 'piano' => 'T-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '502' => ['cat' => 'C02', 'int' => 'Magazzino 9 mq', 'piano' => 'S1', 'rendita' => 'R.Euro:118,50', 'cons' => '9 mq'], - '503' => ['cat' => 'A02', 'int' => '9', 'piano' => '4', 'rendita' => 'R.Euro:2375,70', 'cons' => '8 vani'], - '504' => ['cat' => 'C02', 'int' => 'Magazzino 8 mq', 'piano' => 'S1', 'rendita' => 'R.Euro:105,77', 'cons' => '8 mq'], - '505' => ['cat' => 'A02', 'int' => '8', 'piano' => '3', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '506' => ['cat' => 'C02', 'int' => 'Magazzino 8 mq', 'piano' => 'S1', 'rendita' => 'R.Euro:105,77', 'cons' => '8 mq'] - ]; - - foreach ($real253Specs as $subD => $meta) { - $isSoppressa = $meta['rendita'] === 'Soppressa'; - $rendVal = 0.0; - if (preg_match('/R\.Euro:\s*([\d\.,]+)/i', $meta['rendita'], $mr)) { - $rendVal = (float)str_replace(',', '.', $mr[1]); - } - $renditaStr = $isSoppressa ? 'Soppressa' : ($rendVal > 0.01 ? '€ ' . number_format($rendVal, 2, ',', '.') : '—'); - - $dest = $isSoppressa ? 'Soppresso' : (($meta['cat'] === 'C02') ? 'Cantina / Box (C/2)' : 'Abitazione (A/2)'); - $ind = "VIALE DELLE MILIZIE n. 3 Scala D" . (!empty($meta['int']) ? " Interno " . $meta['int'] : "") . (!empty($meta['piano']) ? " Piano " . $meta['piano'] : ""); - - $subalterni253[] = [ - 'sub' => $subD, - 'rendita' => $renditaStr, - 'partita' => $isSoppressa ? 'Soppressa' : 'ATTIVA', - 'destinazione' => $dest, - 'indirizzo_completo' => $ind - ]; - } - - // Scrittura cache isolata Compartimento 2 - Storage::disk('public')->put("{$dirPath}/geometria_stabile_405_253.json", json_encode($subalterni253, JSON_PRETTY_PRINT)); - - // Unione delle due liste per la vista orizzontale a specchio TAB A - $this->stabileSubalterni = array_merge($subalterni256, $subalterni253); - $this->ordinaSubalterniPerInterno(); - - // Scrittura del file principale per retrocompatibilità - Storage::disk('public')->put("{$dirPath}/geometria_stabile.json", json_encode($this->stabileSubalterni, JSON_PRETTY_PRINT)); + $this->sincronizzaGeometriaDaDb(); Notification::make() - ->title('Geometria Stabile reale acquisita') - ->body('Allineamento multi-particella completato (256 per A-B-C, 253 per D).') + ->title('Geometria Stabile Sincronizzata dal Database') + ->body('Mappa subalterni e indirizzi aggiornata con successo dai dati consolidati dello stabile.') ->success() ->send(); } catch (Exception $e) { Notification::make() - ->title('Errore Sister Stabile') + ->title('Errore Geometria Stabile') ->body($e->getMessage()) ->danger() ->send(); @@ -1160,7 +951,6 @@ public function interrogaSister(bool $force = false): void $subLabel = ($this->editSubalterno !== null && $this->editSubalterno !== '') ? "_sub{$this->editSubalterno}" : ""; $jsonFilename = "risultato_immobile_" . (string)$this->editFoglio . "_" . (string)$this->editParticella . "{$subLabel}.json"; $jsonPath = "{$dirPath}/{$jsonFilename}"; - $subStr = (string)$this->editSubalterno; // 1. Lettura immediata da Cache locale se presente e non forzato @@ -1175,306 +965,12 @@ public function interrogaSister(bool $force = false): void return; } - // 2. Controllo anagrafica reale pre-caricata (mappa reale) - $subRealParams = [ - '1' => ['int' => '1', 'scala' => 'A', 'cat' => 'A02', 'cons' => '7,5 vani', 'rendita' => 'R.Euro:2227,22', 'id' => 'NjU0Mzg1IzY1NDM4NSNGIzQwNSMyNTYjSDUwMSMjMSMgI1JPTUE='], - '2' => ['int' => '2', 'scala' => 'A', 'cat' => 'A02', 'cons' => '5,5 vani', 'rendita' => 'R.Euro:1633,29', 'id' => 'NjU0Mzg2IzY1NDM4NiNGIzQwNSMyNTYjSDUwMSMwMjMwMzQxIzIjICNST01B'], - '3' => ['int' => '3', 'scala' => 'A', 'cat' => '', 'cons' => '', 'rendita' => 'Soppressa', 'id' => 'NjU0Mzg3IzY1NDM4NyNGIzQwNSMyNTYjSDUwMSNTb3BwcmVzc2EjMyMgI1JPTUE='], - '4' => ['int' => '4', 'scala' => 'A', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NjU0Mzg4IzY1NDM4OCNGIzQwNSMyNTYjSDUwMSMjNCMgI1JPTUE='], - '5' => ['int' => '5', 'scala' => 'A', 'cat' => 'A02', 'cons' => '5,5 vani', 'rendita' => 'R.Euro:1633,29', 'id' => 'NjU0Mzg5IzY1NDM4OSNGIzQwNSMyNTYjSDUwMSMwMjMwMzQxIzUjICNST01B'], - '6' => ['int' => '6', 'scala' => 'A', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NjU0MzkxIzY1NDM5MSNGIzQwNSMyNTYjSDUwMSNTb3BwcmVzc2EjNyMgI1JPTUE='], - '7' => ['int' => '7', 'scala' => 'A', 'cat' => '', 'cons' => '', 'rendita' => 'Soppressa', 'id' => 'NjU0MzkxIzY1NDM5MSNGIzQwNSMyNTYjSDUwMSNTb3BwcmVzc2EjNyMgI1JPTUE='], - '8' => ['int' => '8', 'scala' => 'A', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NjU0MzkyIzY1NDM5MiNGIzQwNSMyNTYjSDUwMSMjOCMgI1JPTUE='], - '9' => ['int' => '9', 'scala' => 'A', 'cat' => 'A02', 'cons' => '6 vani', 'rendita' => 'R.Euro:1781,78', 'id' => 'NjU0MzkzIzY1NDM5MyNGIzQwNSMyNTYjSDUwMSMjOSMgI1JPTUE='], - '10' => ['int' => '10', 'scala' => 'A', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NjU4Mzk0IzY1ODM5NCNGIzQwNSMyNTYjSDUwMSMjMTAjICNST01B'], - '18' => ['int' => '18', 'scala' => 'C', 'cat' => '', 'cons' => '', 'rendita' => 'Soppressa', 'id' => 'NjU1Mzg4IzY1NTM4OCNGIzQwNSMyNTYjSDUwMSN1Yl8xODMgI1JPTUE='], - '21' => ['int' => '19', 'scala' => 'C', 'cat' => '', 'cons' => '', 'rendita' => 'Soppressa', 'id' => 'NjU1Mzg5IzY1NTM5OSNGIzQwNSMyNTYjSDUwMSN1Yl8yMTMgI1JPTUE='], - '37' => ['int' => '21', 'scala' => 'C', 'cat' => '', 'cons' => '', 'rendita' => 'Soppressa', 'id' => 'NjU1MzkwIzY1NTM5MCNGIzQwNSMyNTYjSDUwMSN1Yl8zNzMgI1JPTUE='], - '86' => ['int' => '24', 'scala' => 'C', 'cat' => 'A02', 'cons' => '6 vani', 'rendita' => 'R.Euro:1781,78', 'id' => 'NjcwNTY0NyM2NzA1NjQ3I0YjNDA1IzI1NiNINTAxIyM4NiMgI1JPTUE='], - '87' => ['int' => '24', 'scala' => 'C', 'cat' => 'C02', 'cons' => '8 m2', 'rendita' => 'R.Euro:105,77', 'id' => 'NjcwNTY0OCM2NzA1NjQ4I0YjNDA1IzI1NiNINTAxIyM4NyMgI1JPTUE='], - - // Sub > 500 - '501' => ['int' => '14', 'scala' => 'C', 'cat' => 'A02', 'cons' => '5,5 vani', 'rendita' => 'R.Euro:1633,29', 'id' => 'NDQ5NTU3MiM0NDk1NTcyI0YjNDA1IzI1NiNINTAxIyM1MDEjICNST01B'], - '502' => ['int' => '18', 'scala' => 'C', 'cat' => 'A02', 'cons' => '5,5 vani', 'rendita' => 'R.Euro:1633,29', 'id' => 'NDQ5NTU3MyM0NDk1NTczI0YjNDA1IzI1NiNINTAxIyM1MDIjICNST01B'], - '503' => ['int' => '3', 'scala' => 'A', 'cat' => 'A02', 'cons' => '8 vani', 'rendita' => 'R.Euro:2375,70', 'id' => 'NDUxMjQ0NSM0NTEyNDQ1I0YjNDA1IzI1NiNINTAxIyM1MDMjICNST01B'], - '504' => ['int' => '4', 'scala' => 'C', 'cat' => 'A02', 'cons' => '5,5 vani', 'rendita' => 'R.Euro:1633,29', 'id' => 'NDU1MDk1MCM0NTUwOTUwI0YjNDA1IzI1NiNINTAxIyM1MDQjICNST01B'], - '505' => ['int' => '19', 'scala' => 'C', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NDU1MDk1MSM0NTUwOTUxI0YjNDA1IzI1NiNINTAxIyM1MDUjICNST01B'], - '506' => ['int' => 'Piano S1', 'scala' => 'A', 'cat' => 'C02', 'cons' => '30 m2', 'rendita' => 'R.Euro:461,71', 'id' => 'NDgxMTQxOSM0ODExNDE5I0YjNDA1IzI1NiNINTAxIyM1MDYjICNST01B'], - '507' => ['int' => '', 'scala' => 'A', 'cat' => '', 'cons' => '', 'rendita' => 'Soppressa', 'id' => 'NDgxMTQyNyM0ODExNDI3I0YjNDA1IzI1NiNINTAxI1NvcHByZXNzYSM1MDcjICNST01B'], - '508' => ['int' => 'A Piano 7', 'scala' => 'A', 'cat' => 'C02', 'cons' => '18 m2', 'rendita' => 'R.Euro:277,03', 'id' => 'NTA4MTU4NCM1MDgxNTg0I0YjNDA1IzI1NiNINTAxIyM1MDgjICNST01B'], - '509' => ['int' => '14 Piano 3', 'scala' => '', 'cat' => 'A02', 'cons' => '6,5 vani', 'rendita' => 'R.Euro:1930,26', 'id' => 'NTgwNTU2NCM1ODA1NTY0I0YjNDA1IzI1NiNINTAxIyM1MDkjICNST01B'], - '510' => ['int' => '14 Piano S1', 'scala' => '', 'cat' => 'C02', 'cons' => '13 m2', 'rendita' => 'R.Euro:200,08', 'id' => 'NTgwNTU2NSM1ODA1NTY1I0YjNDA1IzI1NiNINTAxIyM1MTAjICNST01B'], - '512' => ['int' => 'Piano S1', 'scala' => 'A', 'cat' => 'C02', 'cons' => '60 m2', 'rendita' => 'R.Euro:923,43', 'id' => 'NTkwMzc2MiM1OTAzNzYyI0YjNDA1IzI1NiNINTAxIyM1MTIjICNST01B'], - '513' => ['int' => 'Piano S1', 'scala' => 'A', 'cat' => 'B.C.N.C.', 'cons' => '', 'rendita' => 'R.Euro:0,00', 'id' => 'NTkwMzc2MyM1OTAzNzYzI0YjNDA1IzI1NiNINTAxI0JlbmUgY29tdW5lIG5vbiBjZW5zaWJpbGUjNTEzIyAjUk9NQQ=='], - '514' => ['int' => '8 Piano 1', 'scala' => 'B', 'cat' => 'A02', 'cons' => '6,5 vani', 'rendita' => 'R.Euro:1930,26', 'id' => 'NjU2MDc2NCM2NTYwNzY0I0YjNDA1IzI1NiNINTAxIyM1MTQjICNST01B'], - '515' => ['int' => '8 Piano S1', 'scala' => 'B', 'cat' => 'C02', 'cons' => '20 m2', 'rendita' => 'R.Euro:227,24', 'id' => 'NjU2MDc2NSM2NTYwNzY1I0YjNDA1IzI1NiNINTAxIyM1MTUjICNST01B'], - '516' => ['int' => '21 Piano 5', 'scala' => 'C', 'cat' => 'A02', 'cons' => '6,5 vani', 'rendita' => 'R.Euro:1930,26', 'id' => 'NjU6MjYxMSM2NTYyNjExI0YjNDA1IzI1NiNINTAxIyM1MTYjICNST01B'], - '517' => ['int' => '16 Piano S1', 'scala' => 'C', 'cat' => 'C02', 'cons' => '11 m2', 'rendita' => 'R.Euro:169,29', 'id' => 'NjU2MjYxMiM2NTYyNjEyI0YjNDA1IzI1NiNINTAxIyM1MTcjICNST01B'], - '518' => ['int' => '2 Piano T', 'scala' => 'C', 'cat' => 'A02', 'cons' => '5,5 vani', 'rendita' => 'R.Euro:1633,29', 'id' => 'NjU4NzA4NCM2NTg3MDg0I0YjNDA1IzI1NiNINTAxIyM1MTgjICNST01B'], - '519' => ['int' => 'Piano S1', 'scala' => 'C', 'cat' => 'C02', 'cons' => '8 m2', 'rendita' => 'R.Euro:123,12', 'id' => 'NjU4NzA4NSM2NTg3MDg1I0YjNDA1IzI1NiNINTAxIyM1MTkjICNST01B'], - '520' => ['int' => '27 Piano 6', 'scala' => 'B', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NjY4Mzc4NSM2NjgzNzg1I0YjNDA1IzI1NiNINTAxIyM1MjAjICNST01B'], - '521' => ['int' => '27 Piano S1', 'scala' => 'B', 'cat' => 'C02', 'cons' => '8 m2', 'rendita' => 'R.Euro:123,12', 'id' => 'NjY4Mzc4NiM2NjgzNzg2I0YjNDA1IzI1NiNINTAxIyM1MjEjICNST01B'], - '522' => ['int' => '25 Piano 6', 'scala' => 'B', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NjY5NDcyMCM2Njk0NzIwI0YjNDA1IzI1NiNINTAxIyM1MjIjICNST01B'], - '523' => ['int' => '25 Piano S1', 'scala' => 'B', 'cat' => 'C02', 'cons' => '11 m2', 'rendita' => 'R.Euro:124,98', 'id' => 'NjY5NDcyMSM2Njk0NzIxI0YjNDA1IzI1NiNINTAxIyM1MjMjICNST01B'], - '524' => ['int' => '20 Piano 5', 'scala' => 'A', 'cat' => 'A02', 'cons' => '7 vani', 'rendita' => 'R.Euro:2078,74', 'id' => 'NjcxMzk0NCM2NzEzOTQ0I0YjNDA1IzI1NiNINTAxIyM1MjQjICNST01B'], - '525' => ['int' => '16 Piano S1', 'scala' => 'A', 'cat' => 'A02', 'cons' => '6 vani', 'rendita' => 'R.Euro:1781,78', 'id' => 'NjcxMzk0NSM2NzEzOTQ1I0YjNDA1IzI1NiNINTAxIyM1MjVjICNST01B'], - ]; - - if (isset($subRealParams[$subStr])) { - $meta = $subRealParams[$subStr]; - $isSoppressa = $meta['rendita'] === 'Soppressa'; - - $pianoVal = $isSoppressa ? '' : ($meta['int'] && str_contains($meta['int'], 'Piano') ? $meta['int'] : 'Piano 5'); - $intestati = $isSoppressa ? [] : [ - [ - 'denominazione' => 'ATER COMUNE DI ROMA con sede in ROMA (RM)', - 'cf' => '00410700587', - 'proprieta' => 'Proprieta\'', - 'quota' => '1000/1000' - ] - ]; - - if ($subStr === '524') { - $pianoVal = 'Piano 5'; - $intestati = [ - [ - 'denominazione' => 'BENEDETTO DANIELA', - 'cf' => 'BNDDNL86M58H224O', - 'proprieta' => 'Proprieta\'', - 'quota' => '1/2' - ], - [ - 'denominazione' => 'FERRANTE BIAGIO', - 'cf' => 'FRRBGI87E25I438V', - 'proprieta' => 'Proprieta\'', - 'quota' => '1/2' - ] - ]; - } elseif ($subStr === '2') { - $pianoVal = 'Piano S1 - T'; - $intestati = [ - [ - 'denominazione' => 'SCILLIA MICHELE', - 'cf' => 'SCLMHL48C23H501F', - 'proprieta' => 'Proprieta\'', - 'quota' => '1/1' - ] - ]; - } elseif ($subStr === '503') { - $pianoVal = 'Piano T - S1'; - $intestati = [ - [ - 'denominazione' => 'IMPROTA RAFFAELLA', - 'cf' => 'MPRRFL70A01H501A', - 'proprieta' => 'Proprieta\'', - 'quota' => '1/2' - ], - [ - 'denominazione' => 'CONCILIO CHIARA', - 'cf' => 'CNCCHR75A01H501B', - 'proprieta' => 'Proprieta\'', - 'quota' => '1/2' - ] - ]; - } elseif ($subStr === '4') { - $pianoVal = 'Piano 1-S1'; - $intestati = [ - [ - 'denominazione' => 'MARSILI GIADA', - 'cf' => 'MRSGDI07M65H501D', - 'proprieta' => 'Proprieta\'', - 'quota' => '1/1' - ], - [ - 'denominazione' => 'MARSILI ROBERTO', - 'cf' => 'MRSRRT70B21H501A', - 'proprieta' => 'Abitazione', - 'quota' => '1/1' - ] - ]; - } - - $mockResult = [ - 'immobili' => [ - [ - 'sezioneUrb' => '', - 'foglio' => '405', - 'particella' => '256', - 'subalterno' => $subStr, - 'indirizzo' => 'VIALE DELLE MILIZIE n. 3 ' . ($meta['scala'] ? 'Scala ' . $meta['scala'] . ' ' : '') . ($meta['int'] ? 'Interno ' . $meta['int'] : '') . ($pianoVal ? ' Piano ' . str_ireplace('Piano', '', $pianoVal) : ''), - 'zonacensuaria' => '002', - 'categoria' => self::formattaCategoriaCatastale($meta['cat']), - 'classamento' => self::formattaCategoriaCatastale($meta['cat']), - 'classe' => $isSoppressa ? '' : '03', - 'consistenza' => $meta['cons'], - 'rendita' => $isSoppressa ? '' : $meta['rendita'], - 'partita' => $isSoppressa ? 'Soppressa' : '02303' . $subStr, - 'piano' => $pianoVal, - 'idImmobile' => $meta['id'], - 'intestati' => $intestati - ] - ] - ]; - Storage::disk('public')->put($jsonPath, json_encode($mockResult, JSON_PRETTY_PRINT)); - Notification::make()->title('Dati Catastali caricati per Sub ' . $subStr)->success()->send(); - $this->loadUnitaList(); - $this->selectUnita($this->selectedUnitaId); - return; - } - - if ($this->editParticella === '253') { - $real253Specs = [ - '1' => ['cat' => 'A02', 'int' => '1', 'piano' => 'T-S1', 'rendita' => 'R.Euro:2227,22', 'cons' => '7,5 vani'], - '3' => ['cat' => 'A02', 'int' => '3', 'piano' => '1-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '4' => ['cat' => 'A02', 'int' => '4', 'piano' => 'S1-1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '5' => ['cat' => 'A02', 'int' => '5', 'piano' => '2-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '6' => ['cat' => 'A02', 'int' => '6', 'piano' => '2-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '7' => ['cat' => 'A02', 'int' => '7', 'piano' => '3-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '8' => ['cat' => '', 'int' => '', 'piano' => '', 'rendita' => 'Soppressa', 'cons' => ''], - '9' => ['cat' => '', 'int' => '', 'piano' => '', 'rendita' => 'Soppressa', 'cons' => ''], - '10' => ['cat' => 'A02', 'int' => '10', 'piano' => '4-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '11' => ['cat' => 'A02', 'int' => '11', 'piano' => '5-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '12' => ['cat' => 'A02', 'int' => '12', 'piano' => '5-S1', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '13' => ['cat' => 'A02', 'int' => '', 'piano' => '6-S1', 'rendita' => 'R.Euro:1781,78', 'cons' => '6 vani'], - '14' => ['cat' => 'A02', 'int' => '14', 'piano' => '6-S1', 'rendita' => 'R.Euro:1484,81', 'cons' => '5 vani'], - '501' => ['cat' => 'A02', 'int' => '2', 'piano' => 'T-S1', 'rendita' => 'R.Euro:1633,29', 'cons' => '5,5 vani'], - '502' => ['cat' => 'C02', 'int' => 'Magazzino 9 mq', 'piano' => 'S1', 'rendita' => 'R.Euro:118,50', 'cons' => '9 mq'], - '503' => ['cat' => 'A02', 'int' => '9', 'piano' => '4', 'rendita' => 'R.Euro:2375,70', 'cons' => '8 vani'], - '504' => ['cat' => 'C02', 'int' => 'Magazzino 8 mq', 'piano' => 'S1', 'rendita' => 'R.Euro:105,77', 'cons' => '8 mq'], - '505' => ['cat' => 'A02', 'int' => '8', 'piano' => '3', 'rendita' => 'R.Euro:2078,74', 'cons' => '7 vani'], - '506' => ['cat' => 'C02', 'int' => 'Magazzino 8 mq', 'piano' => 'S1', 'rendita' => 'R.Euro:105,77', 'cons' => '8 mq'] - ]; - - if (isset($real253Specs[$subStr])) { - $meta = $real253Specs[$subStr]; - $isSoppressa = $meta['rendita'] === 'Soppressa'; - $pianoVal = $isSoppressa ? '' : 'Piano ' . $meta['piano']; - - $intestati = []; - $uReal = \App\Models\UnitaImmobiliare::where('stabile_id', $this->stabileAttivo->id) - ->where('scala', 'D') - ->where('subalterno', $subStr) - ->first(); - if ($uReal) { - $proprietariAttivi = DB::table('persone_unita_relazioni as pur') - ->join('persone as p', 'p.id', '=', 'pur.persona_id') - ->where('pur.unita_id', $uReal->id) - ->where('pur.tipo_relazione', 'proprietario') - ->where('pur.attivo', 1) - ->get(); - foreach ($proprietariAttivi as $pa) { - $intestati[] = [ - 'denominazione' => trim($pa->cognome . ' ' . $pa->nome), - 'cf' => $pa->codice_fiscale, - 'proprieta' => 'Proprieta\'', - 'quota' => '1/1' - ]; - } - } - - if ($subStr === '14') { - $intestati = [ - [ - 'denominazione' => "D'ANNA LUISA", - 'cf' => 'DNNLSU64L71H501D', - 'proprieta' => 'Proprieta\'', - 'quota' => '1/1' - ] - ]; - } - - if (empty($intestati) && !$isSoppressa) { - Notification::make() - ->title('Errore Catastale Bloccante') - ->body('Nessun intestatario reale o comproprietario attivo configurato per il Subalterno ' . $subStr . '.') - ->danger() - ->persistent() - ->send(); - return; - } - - $mockResult = [ - 'immobili' => [ - [ - 'sezioneUrb' => '', - 'foglio' => '405', - 'particella' => '253', - 'subalterno' => $subStr, - 'indirizzo' => 'VIALE DELLE MILIZIE n. 3 Scala D' . (!empty($meta['int']) ? ' Interno ' . $meta['int'] : '') . ($pianoVal ? ' ' . $pianoVal : ''), - 'zonacensuaria' => '002', - 'categoria' => self::formattaCategoriaCatastale($meta['cat']), - 'classamento' => self::formattaCategoriaCatastale($meta['cat']), - 'classe' => $isSoppressa ? '' : '03', - 'consistenza' => $meta['cons'], - 'rendita' => $isSoppressa ? '' : $meta['rendita'], - 'partita' => $isSoppressa ? 'Soppressa' : '02303' . $subStr, - 'piano' => $pianoVal, - 'idImmobile' => 'NjU1Mzg4IzY1NTM4OCNGIzQwNSMyNTMjSDUwMSM' . $subStr . 'M', - 'intestati' => $intestati - ] - ] - ]; - Storage::disk('public')->put($jsonPath, json_encode($mockResult, JSON_PRETTY_PRINT)); - Notification::make()->title('Dati Catastali caricati per Sub ' . $subStr)->success()->send(); - $this->loadUnitaList(); - $this->selectUnita($this->selectedUnitaId); - return; - } - } - - // 3. Fallback su staging condomin - if (Schema::connection('gescon_import')->hasTable('condomin')) { - $rStaging = DB::connection('gescon_import')->table('condomin') - ->where('cod_stabile', $this->stabileAttivo->codice_stabile) - ->where('catasto_sub', $subStr) - ->first(); - - if ($rStaging) { - $rendVal = is_numeric($rStaging->catasto_rendita) ? (float)$rStaging->catasto_rendita : 0.0; - $renditaStr = $rendVal > 0.01 ? 'R.Euro:' . number_format($rendVal, 2, '.', '') : ''; - $cat = strtoupper(trim((string)$rStaging->catasto_categoria)) ?: 'A02'; - - $mockResult = [ - 'immobili' => [ - [ - 'sezioneUrb' => '', - 'foglio' => '405', - 'particella' => '256', - 'subalterno' => $subStr, - 'indirizzo' => 'VIALE DELLE MILIZIE n. 3 Scala ' . ($rStaging->scala ?: 'B') . ' Interno ' . ($rStaging->interno ?: '1'), - 'zonacensuaria' => '002', - 'categoria' => $cat, - 'classamento' => $cat, - 'classe' => '03', - 'consistenza' => $rStaging->catasto_consistenza ?: '6 vani', - 'rendita' => $renditaStr, - 'partita' => '02303' . $subStr, - 'piano' => $rStaging->piano ?: 'Piano T', - 'idImmobile' => 'NDUxMjQ0NSM0NTEyNDQ1I0YjNDA1IzI1NiNINTAxIyM' . $subStr . 'IyM#ROMA', - 'intestati' => [ - [ - 'denominazione' => $rStaging->proprietario_denominazione ?: 'ATER COMUNE DI ROMA', - 'cf' => $rStaging->cond_cod_fisc ?: '00410700587', - 'proprieta' => 'Proprieta\'', - 'quota' => '1000/1000' - ] - ] - ] - ] - ]; - Storage::disk('public')->put($jsonPath, json_encode($mockResult, JSON_PRETTY_PRINT)); - Notification::make()->title('Dati Catastali caricati per Sub ' . $subStr)->success()->send(); - $this->loadUnitaList(); - $this->selectUnita($this->selectedUnitaId); - return; - } - } - - // 4. Chiamata reale a Sister API + // 2. Chiamata reale a Sister API try { $tipoCatasto = 'F'; $uffProvinciale = 'ROMA Territorio-RM'; - $denomComune = $service->getComuneCat($this->stabileAttivo->id, $uffProvinciale, $this->stabileAttivo->citta ?? 'ROMA'); + $cittaName = $this->stabileAttivo->citta ?? 'ROMA'; + $denomComune = $service->getComuneCat($this->stabileAttivo->id, $uffProvinciale, $cittaName); $result = $service->ricercaIntestatiImmobile( $this->stabileAttivo->id, @@ -1485,23 +981,38 @@ public function interrogaSister(bool $force = false): void (string)$this->editParticella, $this->editSubalterno, null, - null + $this->editSezioneUrbana ?: null ); - if (!empty($result)) { + if (!empty($result) && !isset($result['err'])) { Storage::disk('public')->put($jsonPath, json_encode($result, JSON_PRETTY_PRINT)); Notification::make()->title('Dati Catastali caricati da Sister API')->success()->send(); $this->loadUnitaList(); $this->selectUnita($this->selectedUnitaId); return; } - } catch (Exception $e) {} - // Se arriviamo qui, nessun dato è reperibile (Garbage In - Garbage Out) + if (isset($result['err'])) { + Notification::make() + ->title('Risposta Sister API') + ->body('Sister ha risposto: ' . $result['err']) + ->warning() + ->send(); + return; + } + } catch (Exception $e) { + Notification::make() + ->title('Errore Connessione Sister API') + ->body('Impossibile contattare Sister API: ' . $e->getMessage()) + ->danger() + ->send(); + return; + } + Notification::make() - ->title('Dati Catastali Non Disponibili (Garbage In - Garbage Out)') - ->body("Impossibile reperire i dati catastali ufficiali per il Subalterno {$subStr}. Nessun fallback matematico o stima probabilistica applicata.") - ->danger() + ->title('Dati Catastali Non Disponibili') + ->body("Nessun dato catastale ufficiale reperito per Foglio {$this->editFoglio}, Particella {$this->editParticella}, Subalterno {$subStr}. Nessun fallback probabilistico applicato.") + ->warning() ->send(); } @@ -2160,9 +1671,10 @@ public function caricaVisuraProprietariRt(): void $service = new SisterCatastoService(); $dirPath = $service->getStoragePath($this->stabileAttivo->id); - $files = Storage::disk('public')->files($dirPath); $soggetti = []; + // 1. Lettura dai file JSON Sister presenti per lo stabile attivo + $files = Storage::disk('public')->files($dirPath); foreach ($files as $file) { if (str_contains($file, 'risultato_immobile_') && str_ends_with($file, '.json')) { try { @@ -2220,58 +1732,54 @@ public function caricaVisuraProprietariRt(): void } } - // cointestatari storici per sub 503 (Interno 3) - $cfImprota = 'MPRRFL75C12H501Z'; - if (!isset($soggetti[$cfImprota])) { - $soggetti[$cfImprota] = [ - 'cf' => $cfImprota, - 'nominativo' => 'IMPROTA RAFFAELLA', - 'unita' => [] - ]; - } - $soggetti[$cfImprota]['unita'][] = [ - 'descrizione' => 'Scala A · Int. 3', - 'dettagli' => 'Foglio 405 Part. 256 Sub. 503', - 'titolo' => 'Comproprietà', - 'quota' => '1/2' - ]; + // 2. Integrazione da anagrafiche e titolarità consolidate a DB per lo stabile attivo + if (Schema::hasTable('unita_anagrafica_periodo') && Schema::hasTable('anagrafiche')) { + $unitaIds = collect($this->unitaList)->pluck('id')->all(); + $dbOwners = DB::table('unita_anagrafica_periodo as uap') + ->join('anagrafiche as a', 'a.id', '=', 'uap.anagrafica_id') + ->join('unita_immobiliari as u', 'u.id', '=', 'uap.unita_immobiliare_id') + ->whereIn('uap.unita_immobiliare_id', $unitaIds) + ->whereIn('uap.ruolo_occupazione', ['condomino', 'comproprietario', 'proprietario', 'nudo_proprietario', 'usufruttuario']) + ->select( + 'a.codice_fiscale', + 'a.cognome', + 'a.nome', + 'u.id as unita_id', + 'u.scala', + 'u.interno', + 'u.subalterno', + 'uap.ruolo_occupazione', + 'uap.percentuale_spesa' + ) + ->get(); - $cfConcilio = 'CNCCHR80A01H501Y'; - if (!isset($soggetti[$cfConcilio])) { - $soggetti[$cfConcilio] = [ - 'cf' => $cfConcilio, - 'nominativo' => 'CONCILIO CHIARA', - 'unita' => [] - ]; - } - $soggetti[$cfConcilio]['unita'][] = [ - 'descrizione' => 'Scala A · Int. 3', - 'dettagli' => 'Foglio 405 Part. 256 Sub. 503', - 'titolo' => 'Comproprietà', - 'quota' => '1/2' - ]; + $foglioDef = $this->stabileAttivo->foglio ?? $this->stabileAttivo->foglio_catasto ?? '—'; + $partDef = $this->stabileAttivo->particella_catasto ?? $this->stabileAttivo->mappale ?? '—'; - // Margaret Keehl per sub 7 / 707 - $cfKeehl = 'KHLMGR78C12H501K'; - if (!isset($soggetti[$cfKeehl])) { - $soggetti[$cfKeehl] = [ - 'cf' => $cfKeehl, - 'nominativo' => 'KEEHL MARGARET', - 'unita' => [] - ]; + foreach ($dbOwners as $row) { + $cf = strtoupper(trim($row->codice_fiscale ?? '')); + if (empty($cf)) { + continue; + } + $nome = trim("{$row->cognome} {$row->nome}"); + if (!isset($soggetti[$cf])) { + $soggetti[$cf] = [ + 'cf' => $cf, + 'nominativo' => $nome, + 'unita' => [] + ]; + } + + $unitaDesc = "Scala {$row->scala} · Int. {$row->interno}"; + $subLabel = $row->subalterno ?: 'ND'; + $soggetti[$cf]['unita'][] = [ + 'descrizione' => $unitaDesc, + 'dettagli' => "Foglio {$foglioDef} Part. {$partDef} Sub. {$subLabel}", + 'titolo' => ucfirst($row->ruolo_occupazione), + 'quota' => ((float)$row->percentuale_spesa > 0 ? number_format((float)$row->percentuale_spesa, 2, ',', '.') . '%' : '1000/1000') + ]; + } } - $soggetti[$cfKeehl]['unita'][] = [ - 'descrizione' => 'Scala A · Int. 7', - 'dettagli' => 'Foglio 405 Part. 256 Sub. 7', - 'titolo' => 'Proprietà', - 'quota' => '1000/1000' - ]; - $soggetti[$cfKeehl]['unita'][] = [ - 'descrizione' => 'Scala A · Piano S1 (Cantina)', - 'dettagli' => 'Foglio 405 Part. 256 Sub. 707', - 'titolo' => 'Proprietà', - 'quota' => '1000/1000' - ]; ksort($soggetti); $this->visuraProprietariRt = array_values($soggetti); diff --git a/resources/views/filament/pages/condomini/catasto-hub.blade.php b/resources/views/filament/pages/condomini/catasto-hub.blade.php index 204e8ec..c50fa60 100644 --- a/resources/views/filament/pages/condomini/catasto-hub.blade.php +++ b/resources/views/filament/pages/condomini/catasto-hub.blade.php @@ -34,8 +34,8 @@ Indirizzo: {{ $stabileAttivo->indirizzo }} {{ $stabileAttivo->civico }} | Codice Comune: {{ $stabileAttivo->codice_comune ?? $stabileAttivo->cod_comune ?? 'H501' }} | Sezione: {{ $stabileAttivo->sezione ?? 'ND' }} | - Foglio: {{ $stabileAttivo->foglio_catasto ?: $stabileAttivo->foglio ?: '405' }} | - Particella: {{ $stabileAttivo->particella_catasto ?: $stabileAttivo->mappale ?: '256/253' }} + Foglio: {{ $stabileAttivo->foglio ?: $stabileAttivo->foglio_catasto ?: '—' }} | + Particella: {{ $stabileAttivo->particella_catasto ?: $stabileAttivo->mappale ?: '—' }}

@else

Nessuno Stabile Attivo

@@ -49,7 +49,7 @@ wire:click="interrogaGeometriaStabile" class="inline-flex items-center gap-1.5 rounded-lg bg-primary-600 hover:bg-primary-700 px-3 py-2 text-xs font-bold text-white shadow-xs transition-colors" > - 🗺️ Ingestione Massiva Sister (Milizie 3) + 🗺️ Sincronizza Geometria da DB