# 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
