📋 Commit iniziale con: - ✅ Documentazione unificata in docs/ - ✅ Codice Laravel in netgescon-laravel/ - ✅ Script automazione in scripts/ - ✅ Configurazione sync rsync - ✅ Struttura organizzata e pulita 🔄 Versione: 2025.07.19-1644 🎯 Sistema pronto per Git distribuito
15 KiB
15 KiB
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
// 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à):
- Telefono Principale (UNIVOCO nel sistema)
- Telefono Secondario
- Telefono Ufficio
- Telefono Emergenza
Email (ordinate per priorità):
- Email Principale
- Email Secondaria
- Email Lavoro
- 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:
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
// 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
// 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:
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
-- 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
// 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
// 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