# 🧭 Piano Operativo Import Unità Immobiliari (Gescon → NetGescon) **Versione**: 0.1 – 03 Agosto 2025 **Ambito**: Modulo `Admin → Gescon Import → Tab Unità` (Laravel) --- ## 🎯 Obiettivi 1. **Acquisire le unità da `singolo_anno.mdb` (tabella `condomin`)** preservando i riferimenti \(SCALA/INTERNO/SUB\) e le informazioni d'uso. 2. **Popolare almeno tre archivi NetGescon** con dati coerenti e deduplicati: - `unita_immobiliari` - `soggetti` / `rubrica_universale` - `proprieta` + `rubrica_ruoli` 3. **Classificare pertinenze e locali tecnici** per gestire cumuli, manutentori e futuri contratti/chiavi. 4. **Preparare l'aggancio a rate/pagamenti** garantendo codici stabili, millesimi e diritti aggiornati. --- ## 🗂️ Fonti Legacy & Metadati | Fonte | Percorso | Note operative | | --- | --- | --- | | `singolo_anno.mdb` → `condomin` | `/mnt/gescon-archives/gescon//singolo_anno.mdb` | Accesso via `mdb-tables`/`mdb-export`. Il servizio `LegacyArchiveService::unita()` estrae headers dinamici, preview righe e summary scale/occupanti. | | Staging SQL (`gescon_import.condomin`) | Connessione configurabile (`gescon_import`, fallback `gescon_import_`) | Replica della tabella per lavorare senza MDB. Le colonne vengono lette tramite `Schema::connection(...)->getColumnListing`. | | Dataset JSON (`migration_datasets` / `migration_records`) | chiave `unita` | Utilizzato come fallback per test oppure quando MDB/staging non è disponibile. | | Summary calcolati | `LegacyArchiveService` → `summary.scale`, `summary.people` | Liste di scale, interni presenti, proprietari e inquilini dedotti dalle colonne nominative. Utili per UI mapping e per generare ruoli. | **Headers principali di `condomin` da considerare** (case insensitive): `cod_stabile`, `cod_cond`, `scala`, `piano`, `interno`, `sub`, `cognome`, `nome`, `codice_fiscale`, `telefono`, `email`, `indirizzo_corrispondenza`, `millesimi_*`, `inquilino`, `proprietario`, `note`, `cognome_inquilino`, `nome_inquilino`, `cf_inquilino`. --- ## 🧱 Tabelle Target & Responsabilità | Tabella | Scopo | Campi chiave | Dipendenze | | --- | --- | --- | --- | | `unita_immobiliari` | Master unità (abitazioni, pertinenze, locali tecnici) | `stabile_id`, `codice_unita`, `scala`, `interno`, `piano`, `tipo_unita`, `millesimi_*`, `stato_occupazione`, `meta` | richiede `stabili.id` | | `soggetti` | Albero proprietari/occupanti “legacy-friendly” usato da contabilità | `codice_fiscale`, `email`, `codice_univoco`, `tipo` | Deducibile direttamente da `condomin` | | `rubrica_universale` | Anagrafica unica NetGescon (contatti, manutentori, banche) | `codice_univoco`, `categoria`, `tipo_contatto`, `pec`, `telefono` | Sincronizzata con `soggetti` (1:1 logico) | | `proprieta` | Relazione giuridica unità ↔ soggetto | `unita_immobiliare_id`, `soggetto_id`, `tipo_diritto`, `percentuale_possesso`, `data_inizio/fine` | richiede unità + soggetti | | `rubrica_ruoli` | Ruoli dinamici (proprietario, inquilino, manutentore, tecnico locale) con periodo e preferenze | `rubrica_id`, `ruolo_standard`, `unita_immobiliare_id`, `stabile_id`, `data_inizio/fine`, `meta` | richiede rubrica | | `unita_pertinenze` *(opzionale ma supportato)* | legame unità principale ↔ pertinenza (cantina, box, locale tecnico) | `unita_principale_id`, `unita_accessoria_id`, `tipo`, `cumulo` | richiede unità distinte | --- ## 🔁 Matrici di Mapping ### 1. Identità & Posizionamento | Target (`unita_immobiliari`) | Source `condomin` | Regole/Note | | --- | --- | --- | | `stabile_id` | input utente / lookup `stabili` (`codice_stabile`, `denominazione`) | obbligatorio dal tab principale; fallback `mapping.stabile_id`. | | `codice_unita` | `cod_stabile`, `scala`, `interno` | formato `STAB-SCALA-INT`. Zero padding opzionale. Per pertinenze usa il codice normalizzato (es. `LT03`). | | `palazzina`, `scala` | `scala` | normalizzare: uppercase, fallback `A`. UI deve mostrare lista scale da `summary.scale`. | | `piano` | `piano` | convertire `T/PT/R`→0, `S/PS/-1`→-1, numeri interi altrove. | | `interno` | `interno` | trim, uppercase, gestire multi valori (es. `1/A`). | | `subalterno` | `sub` oppure `interno` | se vuoto, mantenere `interno`. | | `denominazione` | `cognome + nome` | fallback `"Scala {scala} Interno {interno}"`. | | `posizione_dettagliata` | composizione `palazzina / scala / piano / interno` | utile per UI senza query aggiuntive. | ### 2. Dati catastali & superfici | Target | Source | Regole | | --- | --- | --- | | `foglio`, `particella`, `subalterno` | `foglio`, `particella`, `sub` | normalizzare numeri, rimuovere leading zeros superflui ma conservarli in `meta_legacy`. | | `categoria_catastale`, `classe`, `consistenza`, `rendita_catastale` | `categoria`, `classe`, `cons`, `rendita` (se presenti) | tipicamente presenti nei dataset `condomin`. | | `superficie_commerciale`, `superficie_calpestabile` | `sup_com`, `sup_calp` | unità m². Validare range 0-10.000. | | `millesimi_generali`, `millesimi_riscaldamento`, `millesimi_acqua`, `millesimi_ascensore`, `millesimi_scale` | `millesimi_generali`, `mill_risc`, `mill_acqua`, `mill_asc`, `mill_scale` | usare `decimal(8,3)`; se >1000 loggare warning. | ### 3. Caratteristiche, impianti, autorizzazioni | Target | Legacy | Note | | --- | --- | --- | | `tipo_unita` | derived | `abitazione` default. Pattern `CAN`, `BOX/GAR`, `PA`, `SOF`, `LT` ⇒ `cantina`, `box`, `posto_auto`, `soffitta`, `locale_tecnico`. | | `utilizzo_attuale` | `uso`, `destinazione` | mapping statico (es. `AB`→`residenziale`, `U`→`ufficio`). | | `stato_conservazione` | `stato`, `cons`, flag qualitativo | mappare `O/B/D/C` → `ottimo/buono/discreto/scarso`. | | `stato_occupazione` | flag `proprietario`, `inquilino`, `libero` | `proprietario=1` ⇒ `occupata_proprietario`; `inquilino=1` ⇒ `occupata_inquilino`; altrimenti `libera`. | | `riscaldamento`, `ha_climatizzazione`, `ha_impianto_gas` | `tipo_risc`, `clima`, `gas` | booleane/in enum. | | `ha_cambio_destinazione_uso`, `data_scadenza_autorizzazioni`, `note_autorizzazioni` | `cambio_uso`, `scad_aut`, `note` | Fieldset per future audit. | | `valore_commerciale_stimato`, `canone_locazione_mensile` | `valore`, `canone` | Numeric, usati per analisi rate. | ### 4. Metadati & Audit - `meta_legacy` (JSON) con: `cod_cond`, `id_record`, `path_archivio`, `raw_columns` per tracciabilità. - `created_by` / `updated_by`: impostare all'utente che effettua il mapping/import. - `attiva`, `unita_demo`: flag gestiti dall'import (+ eventuale override UI). --- ## 👥 Anagrafica Unica & Ruoli Occupanti ### Soggetti (`soggetti`) | Target campo | Source | Regole | | --- | --- | --- | | `nome`, `cognome`, `codice_fiscale`, `email`, `telefono`, `indirizzo` | `cognome`, `nome`, `codice_fiscale`, `email`, `telefono`, `indirizzo_corrispondenza` | Normalizzare CF (uppercase, 16 char). Vuoti ⇒ `null`. | | `tipo` | flag `proprietario` / `inquilino` | `proprietario=1` ⇒ `proprietario`, `inquilino=1` ⇒ `inquilino`, fallback `proprietario`. | | `codice_univoco` | generato | `generateStableCondKey('S', cod_stabile, nome_norm)` con retry. | ### Rubrica Universale (`rubrica_universale`) - Sincronizzare 1:1 con `soggetti` usando `codice_univoco` come ponte. - `categoria`: `condomino` per proprietari, `occupante` per inquilini, `locale_tecnico` per manutentori (vedi sezione dedicata). - `tipo_contatto`: `persona_fisica` se valorizzati `nome`/`cognome`, altrimenti `persona_giuridica`. - Dati aggiuntivi: `pec`, `cellulare`, `note` (da `note` o `note_inquilino`). ### Ruoli (`rubrica_ruoli`) | Campo | Valore | Fonte | | --- | --- | --- | | `ruolo_standard` | `proprietario`, `occupante`, `referente_locale_tecnico`, `manutentore_locale_tecnico` | Dalla casistica: proprietario/inquilino, più voci speciali per locali tecnici. | | `unita_immobiliare_id` | lookup da `codice_unita` | Necessario per ruoli legati alla singola unità. | | `stabile_id` | `stabile.id` usato nel mapping | Permette vista aggregata condominio. | | `data_inizio` / `data_fine` | se disponibili in `condomin` (`data_inizio_locazione`, `data_fine_locazione`) | Altrimenti `null` e gestito successivamente. | | `meta` | JSON con `legacy_cod_cond`, `scala`, `interno`, `fonte` | per audit e dedup futuro. | --- ## 🗝️ Pertinenze & Locali Tecnici 1. **Classificazione automatica** sul campo `interno` (case insensitive, spazi normalizzati): - `CAN\d+` → `cantina` - `BOX`, `GAR`, `GARAGE` → `box` - `PA`, `POSTO AUTO` → `posto_auto` - `SOF`, `SOFFITTA`, `SOLAIO` → `soffitta` - `LT`, `LOCALE TECNICO` → `locale_tecnico` 2. **Codice unità** mantiene il prefisso (`BOX01`, `LT03`) per distinguere dai civici. 3. **`unita_pertinenze`**: dopo l'inserimento, collegare la prima unità principale della stessa scala come `unita_principale_id`, marcando `cumulo=true`. In futuro l'UI dovrà consentire la scelta manuale. 4. **Manutentori**: per `locale_tecnico` valorizzare anche `rubrica_ruoli` con `ruolo_standard = manutentore_locale_tecnico` quando nel dataset sono presenti riferimenti (es. colonne `tecnico`, `manutentore`). Nell'immediato, salvare il nominativo raw in `meta_legacy` per completamenti successivi. --- ## ✅ Validazioni & Normalizzazioni 1. **SCALA / INTERNO obbligatori**: se mancanti, bloccare salvataggio UI e richiedere input manuale. 2. **Codici fiscali**: validare lunghezza (16/11/partita IVA). Se non validi, flaggare in `meta.warnings`. 3. **Millesimi**: totale per scala deve avvicinarsi a 1000 (±5). In caso contrario, riportare nel riepilogo import. 4. **Duplicati unità**: `codice_unita` deve essere unico; UI deve suggerire un merge se già presente. 5. **Dedup soggetti**: ordine preferenza `codice_fiscale` → `email` → `nome+cognome`. Le funzioni `findExistingSoggetto` e `dedupSoggettiBy` già disponibili vanno riutilizzate nel controller. 6. **Ruoli sovrapposti**: prima di inserire in `rubrica_ruoli` controllare se esiste un record attivo con stesso `rubrica_id` + `unita_immobiliare_id` + `ruolo_standard`. Aggiornare date invece di duplicare. 7. **Locali tecnici senza manutentore**: marcare `stato_occupazione = 'locale_tecnico'` e impostare `note` "Manutentore da assegnare" per facilitarne l'individuazione post-import. --- ## 🚀 Prossimi Passi Implementativi 1. **UI Mapping**: - Riutilizzare il pattern "schede stabili" per mostrare preview condomin con badge Scala/Interno, includendo summary persone. - Esporre selettori per ognuna delle categorie sopra (identità, catastale, superfici, ruoli) con default suggeriti. 2. **Controller/Service**: - Estendere `GesconImportController@mappingSave` con sezione `unità`, salvando in `gescon_import_mappings.meta['unita']` il pairing `target_field` → `legacy_key`. - Aggiungere action `executeUnitImport()` che orchestri `LegacyArchiveService`, `ImportGesconFullPipeline::stepUnita/stepSoggetti/stepDiritti` filtrati per stabile/scala. 3. **Test & Verifica**: - Dataset di prova: `condomin` per `cod_stabile = 000123`. Verificare totale righe importate = righe legate allo stabile. - Validare che ogni proprietario compaia in `rubrica_ruoli` con `ruolo_standard = proprietario` e che eventuali `inquilini` aggiungano ruoli e diritti di tipo `locazione`. 4. **Estensioni future**: - Collegare `locale_tecnico` a `chiavi_stabili` (tipologia `locali_tecnici`). - Integrare `dett_tab` per popolare `dettaglio_millesimi` con scala-specific translations. - Pre-calcolare `responsabile_pagamenti` per pipeline rate/bollette. --- Con questo blueprint il team può implementare la nuova esperienza di mapping/import delle unità immobiliari mantenendo coerenza con l'anagrafica unica e preparando i dati per occupanti, locali tecnici e rate/pagamenti.