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