# NETGESCON - ANALISI ANAGRAFICA CONDOMINI ## 📋 OVERVIEW L'anagrafica è il cuore del sistema: una **rubrica generale centralizzata** che evita duplicazioni. Una persona fisica può essere proprietaria di multiple unità immobiliari in diversi stabili, ma i suoi dati anagrafici sono memorizzati una sola volta. ## 👤 PRINCIPI FONDAMENTALI ### Unicità della Persona - **Una persona = Un record anagrafico** - **Identificatori univoci**: Codice Fiscale, Telefono principale - **Relazioni multiple**: Una persona può avere N proprietà/contratti - **Dati condivisi**: Contatti, anagrafica base - **Dati specifici**: Ruolo diverso per ogni unità/stabile ### Controlli Anti-Duplicazione ```php // Controlli all'inserimento nuova persona 1. Codice Fiscale già esistente? -> ERRORE o FORZATURA con log 2. Telefono principale già esistente? -> ERRORE o FORZATURA con log 3. Email principale già esistente? -> WARNING (possibile ma non ideale) 4. Nome+Cognome+Data Nascita uguali? -> WARNING (possibile omonimia) ``` ## 👥 STRUTTURA ANAGRAFICA PERSONE ### Dati Identificativi - **ID Persona** (Primary Key, Auto-increment) - **Codice Interno** (Generated: es. "ANA000001") - **Tipologia Persona** - Persona Fisica - Persona Giuridica (Società, Enti) - Ditta Individuale ### Dati Anagrafici Base - **Cognome** (obbligatorio) - **Nome** (obbligatorio) - **Codice Fiscale** (UNIVOCO, validato con algoritmo) - **Partita IVA** (se presente, validata) - **Data di Nascita** - **Luogo di Nascita** (Comune + Provincia, linkato a DB comuni) - **Sesso** (M/F/Altro) - **Cittadinanza** - **Stato Civile** ### Dati di Residenza - **Indirizzo Residenza** - Via/Piazza - Numero civico - CAP - Comune (linkato a DB comuni) - Provincia - Regione - Nazione (default: Italia) - **Indirizzo Domicilio** (se diverso da residenza) - **Indirizzo Corrispondenza** (se diverso da residenza) ### Contatti (Hierarchy System) **Telefoni** (ordinati per priorità): 1. **Telefono Principale** (UNIVOCO nel sistema) 2. Telefono Secondario 3. Telefono Ufficio 4. Telefono Emergenza **Email** (ordinate per priorità): 1. **Email Principale** 2. Email Secondaria 3. Email Lavoro 4. Email PEC (Posta Elettronica Certificata) **Altri Contatti**: - Fax - Skype/Teams - WhatsApp (numero) - Telegram - Social (Facebook, LinkedIn, etc) ### Preferenze Comunicazione - **Modalità Preferita**: Email, SMS, WhatsApp, Telefono, Posta - **Lingua Preferita**: Italiano, Inglese, Francese, etc - **Orari Contatto**: Mattino, Pomeriggio, Sera, Weekend OK/NO - **Privacy Consensi**: - Consenso Trattamento Dati Base - Consenso Marketing - Consenso Comunicazioni Automatiche - Consenso Condivisione Emergenze ## 🏢 PERSONE GIURIDICHE ### Dati Aggiuntivi per Società - **Ragione Sociale** - **Forma Giuridica** (SRL, SPA, SAS, SNC, etc) - **Codice REA** - **Capitale Sociale** - **Sede Legale** (può essere diversa da operativa) - **Sede Operativa** ### Rappresentanti Legali - **Amministratore Delegato** (linkato a persona fisica) - **Rappresentante Legale** (linkato a persona fisica) - **Procuratori** (possono essere multipli) - **Referente Amministrativo** (per pratiche condominiali) ## 🔗 RELAZIONI CON UNITÀ IMMOBILIARI ### Tabella Ponte: Persone ↔ Unità Ogni persona può avere **ruoli diversi** in **unità diverse**: ```sql CREATE TABLE persone_unita_ruoli ( id BIGINT PRIMARY KEY AUTO_INCREMENT, persona_id BIGINT NOT NULL, unita_id BIGINT NOT NULL, tipo_relazione ENUM('proprietario','inquilino','usufruttuario','delegato','referente','altro'), quota_proprieta DECIMAL(5,2), -- Solo se proprietario data_inizio DATE NOT NULL, data_fine DATE, -- NULL = relazione attiva attivo BOOLEAN DEFAULT TRUE, note TEXT ); ``` ### Esempi di Relazioni Multiple **Mario Rossi**: - Proprietario 100% di Stabile A, Unità 12 - Comproprietario 50% di Stabile B, Unità 5 - Delegato assemblea per Stabile C, Unità 8 (di sua madre) - Referente per Stabile A, Unità 15 (inquilino sordo) ## 📞 GESTIONE CONTATTI AVANZATA ### Validazione Automatica ```php // Validazione Codice Fiscale function validaCodiceFiscale($cf, $nome, $cognome, $dataNascita, $comuneNascita) { // Algoritmo calcolo CF + verifica con dati anagrafici $cfCalcolato = calcolaCodiceFiscale($nome, $cognome, $dataNascita, $comuneNascita); return $cf === $cfCalcolato; } // Validazione numero telefono function validaTelefono($telefono) { // Verifica formato internazionale/nazionale // Verifica esistenza numero (API?) return preg_match('/^(\+39|0039|39)?[0-9]{9,10}$/', $telefono); } ``` ### Sistema di Conferma Identità - **SMS con codice OTP** per conferma numero - **Email di verifica** per conferma email - **WhatsApp Business API** per conferma WA - **Chiamata automatica** con codice vocale ### Gestione Duplicati ```php // Quando viene inserita una persona con CF/Tel già esistente function gestioneDuplicati($nuoviDati) { $esistente = trovaPersonaEsistente($nuoviDati); if ($esistente) { // Proponi merge dei dati return [ 'azione' => 'merge_proposto', 'persona_esistente' => $esistente, 'differenze' => confrontaDati($esistente, $nuoviDati), 'suggerimento' => 'aggiorna_persona_esistente' ]; } } ``` ## 📋 AUDIT E TRACCIABILITÀ ### Log Modifiche Anagrafiche Ogni modifica ai dati anagrafici deve essere tracciata: ```sql CREATE TABLE audit_anagrafica ( id BIGINT PRIMARY KEY AUTO_INCREMENT, persona_id BIGINT NOT NULL, campo_modificato VARCHAR(100), valore_precedente TEXT, valore_nuovo TEXT, data_modifica TIMESTAMP DEFAULT CURRENT_TIMESTAMP, utente_id INT NOT NULL, -- Chi ha fatto la modifica ip_address VARCHAR(45), motivo_modifica TEXT, tipo_modifica ENUM('inserimento','aggiornamento','cancellazione','merge') ); ``` ### Campi Sensibili da Auditare - **Codice Fiscale** (modifica molto critica) - **Telefono Principale** (critico per identificazione) - **Email Principale** (importante per comunicazioni) - **Indirizzo Residenza** (importante per corrispondenza) - **Dati Bancari** (se presenti, molto sensibili) ## 🏗️ SCHEMA DATABASE COMPLETO ```sql -- Tabella principale persone CREATE TABLE persone ( id BIGINT PRIMARY KEY AUTO_INCREMENT, codice_interno VARCHAR(20) UNIQUE NOT NULL, tipologia ENUM('fisica','giuridica','ditta_individuale') NOT NULL, -- Dati anagrafici base cognome VARCHAR(100) NOT NULL, nome VARCHAR(100) NOT NULL, codice_fiscale VARCHAR(16) UNIQUE, -- Unique but nullable for foreign persons partita_iva VARCHAR(11), data_nascita DATE, luogo_nascita_comune_id INT, -- FK a comuni sesso ENUM('M','F','Altro'), cittadinanza VARCHAR(100) DEFAULT 'Italiana', stato_civile ENUM('celibe/nubile','coniugato/a','vedovo/a','divorziato/a','separato/a'), -- Residenza residenza_via VARCHAR(255), residenza_civico VARCHAR(10), residenza_cap VARCHAR(5), residenza_comune_id INT, -- FK a comuni -- Domicilio (se diverso) domicilio_via VARCHAR(255), domicilio_civico VARCHAR(10), domicilio_cap VARCHAR(5), domicilio_comune_id INT, -- Corrispondenza (se diverso) corrispondenza_via VARCHAR(255), corrispondenza_civico VARCHAR(10), corrispondenza_cap VARCHAR(5), corrispondenza_comune_id INT, -- Contatti principali telefono_principale VARCHAR(20) UNIQUE, -- UNIVOCO telefono_secondario VARCHAR(20), telefono_ufficio VARCHAR(20), telefono_emergenza VARCHAR(20), email_principale VARCHAR(255), email_secondaria VARCHAR(255), email_lavoro VARCHAR(255), email_pec VARCHAR(255), -- Altri contatti fax VARCHAR(20), whatsapp VARCHAR(20), telegram VARCHAR(100), skype VARCHAR(100), -- Preferenze modalita_comunicazione_preferita ENUM('email','sms','whatsapp','telefono','posta'), lingua_preferita VARCHAR(10) DEFAULT 'it', orari_contatto VARCHAR(255), -- Privacy e consensi consenso_privacy BOOLEAN DEFAULT FALSE, consenso_marketing BOOLEAN DEFAULT FALSE, consenso_comunicazioni_auto BOOLEAN DEFAULT FALSE, data_consenso_privacy TIMESTAMP, -- Dati società (se tipologia = giuridica) ragione_sociale VARCHAR(255), forma_giuridica VARCHAR(50), codice_rea VARCHAR(20), capitale_sociale DECIMAL(12,2), -- Audit created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, created_by INT, updated_by INT, -- Indici INDEX idx_cognome_nome (cognome, nome), INDEX idx_codice_fiscale (codice_fiscale), INDEX idx_telefono (telefono_principale), INDEX idx_email (email_principale), INDEX idx_comune_residenza (residenza_comune_id), -- Vincoli CONSTRAINT chk_cf_length CHECK (codice_fiscale IS NULL OR LENGTH(codice_fiscale) = 16), CONSTRAINT chk_piva_length CHECK (partita_iva IS NULL OR LENGTH(partita_iva) = 11) ); -- Rappresentanti legali per persone giuridiche CREATE TABLE rappresentanti_legali ( id BIGINT PRIMARY KEY AUTO_INCREMENT, persona_giuridica_id BIGINT NOT NULL, persona_fisica_id BIGINT NOT NULL, tipo_rappresentanza ENUM('amministratore_delegato','rappresentante_legale','procuratore','referente_amministrativo'), data_inizio DATE NOT NULL, data_fine DATE, poteri VARCHAR(500), -- Descrizione poteri/limitazioni attivo BOOLEAN DEFAULT TRUE, FOREIGN KEY (persona_giuridica_id) REFERENCES persone(id), FOREIGN KEY (persona_fisica_id) REFERENCES persone(id), INDEX idx_giuridica (persona_giuridica_id), INDEX idx_fisica (persona_fisica_id) ); -- Relazioni persone-unità con ruoli CREATE TABLE persone_unita_relazioni ( id BIGINT PRIMARY KEY AUTO_INCREMENT, persona_id BIGINT NOT NULL, unita_id BIGINT NOT NULL, tipo_relazione ENUM('proprietario','comproprietario','inquilino','usufruttuario','nudo_proprietario','delegato_assemblea','referente','amministratore_sostegno','altro'), quota_relazione DECIMAL(5,2), -- % proprietà o altra quota data_inizio DATE NOT NULL, data_fine DATE, -- NULL = relazione attiva attivo BOOLEAN DEFAULT TRUE, note TEXT, -- Preferenze per questa relazione specifica riceve_comunicazioni BOOLEAN DEFAULT TRUE, riceve_convocazioni BOOLEAN DEFAULT TRUE, vota_assemblea BOOLEAN DEFAULT TRUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (persona_id) REFERENCES persone(id) ON DELETE CASCADE, FOREIGN KEY (unita_id) REFERENCES unita_immobiliari(id) ON DELETE CASCADE, INDEX idx_persona (persona_id), INDEX idx_unita (unita_id), INDEX idx_attivo (attivo), INDEX idx_tipo (tipo_relazione), -- Constraint: non duplicare relazioni attive stesso tipo per stessa unità UNIQUE KEY unique_relazione_attiva (persona_id, unita_id, tipo_relazione, attivo) ); -- Conferme identità (SMS, Email, etc) CREATE TABLE conferme_identita ( id BIGINT PRIMARY KEY AUTO_INCREMENT, persona_id BIGINT NOT NULL, tipo_conferma ENUM('sms','email','whatsapp','chiamata'), contatto_confermare VARCHAR(255), -- numero o email da confermare codice_otp VARCHAR(10), data_invio TIMESTAMP DEFAULT CURRENT_TIMESTAMP, data_conferma TIMESTAMP NULL, stato ENUM('inviato','confermato','scaduto','fallito'), tentativi_falliti TINYINT DEFAULT 0, FOREIGN KEY (persona_id) REFERENCES persone(id) ON DELETE CASCADE, INDEX idx_persona (persona_id), INDEX idx_stato (stato), INDEX idx_data_invio (data_invio) ); ``` ## 🔍 FUNZIONALITÀ AVANZATE ### Ricerca Intelligente Persone ```php // Ricerca multi-campo con AI/fuzzy matching function ricercaPersone($query) { return Persona::where(function($q) use ($query) { $q->where('cognome', 'LIKE', "%$query%") ->orWhere('nome', 'LIKE', "%$query%") ->orWhere('codice_fiscale', '=', $query) ->orWhere('telefono_principale', 'LIKE', "%$query%") ->orWhere('email_principale', 'LIKE', "%$query%"); }) ->with(['unitaImmobiliari', 'stabili']) ->paginate(20); } ``` ### Import Automatico da Fonti Esterne - **Import da file Excel/CSV**: Batch upload con verifica duplicati - **API Agenzia Entrate**: Verifica dati catastali e anagrafici - **API Comune**: Verifica residenze e stato civile - **API Camera Commercio**: Dati società e rappresentanti legali ### Comunicazioni di Massa ```php // Invio comunicazione a gruppo target function inviaComuncazione($stabileId, $tipoDestinatari, $messaggio) { $destinatari = Persona::whereHas('unitaImmobiliari', function($q) use ($stabileId) { $q->where('stabile_id', $stabileId); }) ->where('consenso_comunicazioni_auto', true) ->get(); foreach ($destinatari as $persona) { match($persona->modalita_comunicazione_preferita) { 'email' => inviaEmail($persona->email_principale, $messaggio), 'sms' => inviaSMS($persona->telefono_principale, $messaggio), 'whatsapp' => inviaWhatsApp($persona->whatsapp, $messaggio), default => inviaEmail($persona->email_principale, $messaggio) }; } } ``` ### Dashboard Anagrafica - **Statistiche generali**: Totale persone, tipologie, distribuzione geografica - **Contatti mancanti**: Persone senza email/telefono - **Consensi privacy**: % consensi dati, scadenze - **Verifiche identità**: Numeri/email non confermati - **Duplicati sospetti**: Algoritmo detection automatico ## 🚀 ROADMAP ANAGRAFICA ### Fase 1 - Base (Sprint 1-2) - [ ] Struttura database completa - [ ] CRUD persone con validazioni - [ ] Sistema anti-duplicazione - [ ] Import da Excel/CSV ### Fase 2 - Validazioni (Sprint 3-4) - [ ] Algoritmo calcolo/verifica Codice Fiscale - [ ] Validazione numeri telefono - [ ] Sistema conferma SMS/Email - [ ] Audit completo modifiche ### Fase 3 - Integrazioni (Sprint 5-6) - [ ] API verifica dati anagrafici - [ ] Sistema comunicazioni multi-canale - [ ] Dashboard analytics anagrafica - [ ] Import automatico da fonti esterne ### Fase 4 - AI e Automazioni (Sprint 7-8) - [ ] Ricerca intelligente fuzzy - [ ] Detection automatico duplicati - [ ] Suggerimenti merge persone - [ ] Analisi preferenze comunicazione --- **Data Analisi:** 14/07/2025 **Stato:** BOZZA - In Definizione **Prossimo Step:** Integrazione con Codice Fiscale + API Comuni