netgescon-master/docs/02-architettura-laravel/09-sistema-contabile/DATABASE-CONTABILE-COMPLETO.sql
Pikappa2 480e7eafbd 🎯 NETGESCON - Setup iniziale repository completo
📋 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
2025-07-19 16:44:47 +02:00

751 lines
31 KiB
SQL

-- =============================================
-- NETGESCON: SISTEMA CONTABILE COMPLETO v3.0
-- Partita Doppia + Multi-Gestione + Protocolli + Maschera Unica + Riconciliazione Avanzata
-- =============================================
-- FEATURES AGGIORNATE:
-- ✅ Maschera Unica di Registrazione per tutti i documenti
-- ✅ Tabelle Millesimali Strutturate con calcoli automatici
-- ✅ Riconciliazione Bancaria con algoritmi di matching
-- ✅ Triggers per aggiornamento saldi real-time
-- ✅ Sistema Backup Granulari per singolo condominio
-- ✅ Compliance Fiscale automatica
-- ✅ Workflow guidato step-by-step
-- ✅ Audit completo con tracciabilità totale
-- 1. PIANO DEI CONTI (3 LIVELLI: MASTRO.CONTO.SOTTOCONTO)
CREATE TABLE piano_conti (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
codice VARCHAR(10) NOT NULL COMMENT 'Formato: 01.001.0001',
mastro VARCHAR(2) NOT NULL COMMENT 'Primo livello: 01, 02, 03...',
conto VARCHAR(3) NOT NULL COMMENT 'Secondo livello: 001, 002, 003...',
sottoconto VARCHAR(4) NOT NULL COMMENT 'Terzo livello: 0001, 0002, 0003...',
denominazione VARCHAR(255) NOT NULL,
tipo_conto ENUM('ATTIVO','PASSIVO','COSTO','RICAVO','PATRIMONIALE') NOT NULL,
natura ENUM('DARE','AVERE') NOT NULL COMMENT 'Natura contabile del conto',
gestione ENUM('TUTTE','ORDINARIA','RISCALDAMENTO','STRAORDINARIA') DEFAULT 'TUTTE',
attivo BOOLEAN DEFAULT TRUE,
saldo_dare DECIMAL(12,2) DEFAULT 0.00,
saldo_avere DECIMAL(12,2) DEFAULT 0.00,
saldo_finale DECIMAL(12,2) GENERATED ALWAYS AS (
CASE
WHEN natura = 'DARE' THEN saldo_dare - saldo_avere
ELSE saldo_avere - saldo_dare
END
) STORED,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT,
updated_by INT,
CONSTRAINT fk_piano_conti_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_piano_conti_created_by FOREIGN KEY (created_by) REFERENCES users(id),
CONSTRAINT fk_piano_conti_updated_by FOREIGN KEY (updated_by) REFERENCES users(id),
UNIQUE KEY unique_conto_condominio (condominio_id, codice),
INDEX idx_tipo_natura (tipo_conto, natura),
INDEX idx_gestione (gestione),
INDEX idx_saldi (saldo_finale, attivo)
) COMMENT = 'Piano dei conti a 3 livelli con saldi automatici';
-- 2. GESTIONI CONTABILI (MULTI-ESERCIZIO)
CREATE TABLE gestioni_contabili (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
anno_riferimento YEAR NOT NULL,
tipo_gestione ENUM('ORDINARIA','RISCALDAMENTO','STRAORDINARIA') NOT NULL,
denominazione VARCHAR(255) NOT NULL,
descrizione TEXT,
data_inizio DATE NOT NULL,
data_fine DATE NOT NULL,
data_chiusura DATE NULL COMMENT 'Data effettiva chiusura contabile',
stato ENUM('APERTA','PROVVISORIA','CHIUSA','APPROVATA') DEFAULT 'APERTA',
protocollo_prefix VARCHAR(10) COMMENT 'Prefisso protocollo: ORD2025, RISC2025, STR2025',
ultimo_protocollo INT DEFAULT 0,
saldo_iniziale DECIMAL(12,2) DEFAULT 0.00,
saldo_finale DECIMAL(12,2) DEFAULT 0.00,
totale_costi DECIMAL(12,2) DEFAULT 0.00,
totale_ricavi DECIMAL(12,2) DEFAULT 0.00,
conguaglio DECIMAL(12,2) DEFAULT 0.00,
approvata_assemblea DATE NULL,
verbale_approvazione VARCHAR(255) NULL,
budget_preventivo DECIMAL(12,2) DEFAULT 0.00,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT,
updated_by INT,
CONSTRAINT fk_gestioni_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_gestioni_created_by FOREIGN KEY (created_by) REFERENCES users(id),
CONSTRAINT fk_gestioni_updated_by FOREIGN KEY (updated_by) REFERENCES users(id),
UNIQUE KEY unique_gestione_anno (condominio_id, anno_riferimento, tipo_gestione),
INDEX idx_stato_gestione (stato, tipo_gestione),
INDEX idx_date_gestione (data_inizio, data_fine)
) COMMENT = 'Gestioni contabili multiple per condominio con protocolli separati';
-- 3. CONTI BANCARI E CASSE
CREATE TABLE conti_bancari (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
tipo_conto ENUM('BANCARIO','POSTALE','PAYPAL','STRIPE','CASSA','SATISPAY','ALTRO') NOT NULL,
denominazione VARCHAR(255) NOT NULL,
descrizione TEXT,
banca VARCHAR(255) NULL,
filiale VARCHAR(255) NULL,
iban VARCHAR(34) NULL,
swift VARCHAR(11) NULL,
abi VARCHAR(5) NULL,
cab VARCHAR(5) NULL,
numero_conto VARCHAR(50) NULL,
conto_piano_conti_id INT NOT NULL COMMENT 'Collegamento al piano dei conti',
saldo_iniziale DECIMAL(12,2) DEFAULT 0.00,
saldo_attuale DECIMAL(12,2) DEFAULT 0.00,
data_ultimo_movimento DATE NULL,
attivo BOOLEAN DEFAULT TRUE,
api_enabled BOOLEAN DEFAULT FALSE COMMENT 'Abilitazione sync automatica',
api_config JSON NULL COMMENT 'Configurazioni API banca',
limite_scoperto DECIMAL(12,2) DEFAULT 0.00,
commissioni_fisse DECIMAL(10,2) DEFAULT 0.00,
note TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT,
updated_by INT,
CONSTRAINT fk_conti_bancari_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_conti_bancari_piano_conti FOREIGN KEY (conto_piano_conti_id) REFERENCES piano_conti(id),
CONSTRAINT fk_conti_bancari_created_by FOREIGN KEY (created_by) REFERENCES users(id),
CONSTRAINT fk_conti_bancari_updated_by FOREIGN KEY (updated_by) REFERENCES users(id),
UNIQUE KEY unique_iban_condominio (condominio_id, iban),
INDEX idx_tipo_attivo (tipo_conto, attivo),
INDEX idx_saldo_data (saldo_attuale, data_ultimo_movimento)
) COMMENT = 'Gestione conti bancari, casse e sistemi di pagamento';
-- 4. REGISTRO PRIMA NOTA (PRE-ELABORAZIONE)
CREATE TABLE registro_prima_nota (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
gestione_id INT NOT NULL,
protocollo_gestione VARCHAR(20) COMMENT 'Protocollo specifico gestione: ORD2025/001',
protocollo_generale VARCHAR(20) COMMENT 'Protocollo annuale master: 2025/1234',
data_registrazione DATE NOT NULL,
data_competenza DATE NOT NULL,
data_scadenza DATE NULL,
descrizione TEXT NOT NULL,
documento_tipo ENUM('FATTURA_ATTIVA','FATTURA_PASSIVA','RICEVUTA','BONIFICO','VERSAMENTO','NOTA_CREDITO','NOTA_DEBITO','ALTRO') NOT NULL,
documento_numero VARCHAR(100),
documento_data DATE,
documento_serie VARCHAR(20),
fornitore_id INT NULL,
condomino_id INT NULL,
importo_imponibile DECIMAL(10,2) DEFAULT 0.00,
importo_iva DECIMAL(10,2) DEFAULT 0.00,
importo_totale DECIMAL(10,2) NOT NULL,
ritenuta_acconto DECIMAL(10,2) DEFAULT 0.00,
percentuale_ritenuta DECIMAL(5,2) DEFAULT 0.00,
causale_ritenuta VARCHAR(100) NULL,
split_payment BOOLEAN DEFAULT FALSE,
reverse_charge BOOLEAN DEFAULT FALSE,
codice_iva VARCHAR(20) NULL,
stato ENUM('BOZZA','VALIDATO','CONTABILIZZATO','ANNULLATO','STORNATO') DEFAULT 'BOZZA',
urgente BOOLEAN DEFAULT FALSE,
note TEXT,
validato_da INT NULL,
validato_at TIMESTAMP NULL,
contabilizzato_da INT NULL,
contabilizzato_at TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT NOT NULL,
updated_by INT,
CONSTRAINT fk_prima_nota_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_prima_nota_gestione FOREIGN KEY (gestione_id) REFERENCES gestioni_contabili(id),
CONSTRAINT fk_prima_nota_fornitore FOREIGN KEY (fornitore_id) REFERENCES fornitori(id),
CONSTRAINT fk_prima_nota_condomino FOREIGN KEY (condomino_id) REFERENCES condomini_proprietari(id),
CONSTRAINT fk_prima_nota_validato_da FOREIGN KEY (validato_da) REFERENCES users(id),
CONSTRAINT fk_prima_nota_contabilizzato_da FOREIGN KEY (contabilizzato_da) REFERENCES users(id),
CONSTRAINT fk_prima_nota_created_by FOREIGN KEY (created_by) REFERENCES users(id),
CONSTRAINT fk_prima_nota_updated_by FOREIGN KEY (updated_by) REFERENCES users(id),
INDEX idx_protocolli (protocollo_gestione, protocollo_generale),
INDEX idx_stato_competenza (stato, data_competenza),
INDEX idx_scadenze_urgenti (data_scadenza, urgente, stato),
INDEX idx_importi (importo_totale, ritenuta_acconto)
) COMMENT = 'Registro prima nota per pre-elaborazione documenti';
-- 5. TRANSAZIONI CONTABILI (LIBRO MASTRO)
CREATE TABLE transazioni_contabili (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
gestione_id INT NOT NULL,
prima_nota_id INT NULL COMMENT 'Collegamento opzionale a prima nota',
numero_transazione VARCHAR(20) NOT NULL COMMENT 'Numerazione progressiva: TC2025/001234',
data_transazione DATE NOT NULL,
data_competenza DATE NOT NULL,
descrizione TEXT NOT NULL,
importo_totale DECIMAL(12,2) NOT NULL,
tipo_transazione ENUM('REGISTRAZIONE','PAGAMENTO','INCASSO','GIROCONTO','STORNO','CHIUSURA') NOT NULL,
stato ENUM('APERTA','CHIUSA','ANNULLATA','STORNATA') DEFAULT 'APERTA',
quadratura_ok BOOLEAN DEFAULT FALSE COMMENT 'Verifica dare=avere automatica',
revisione_richiesta BOOLEAN DEFAULT FALSE,
note TEXT,
documento_collegato VARCHAR(500) NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT NOT NULL,
updated_by INT,
CONSTRAINT fk_transazioni_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_transazioni_gestione FOREIGN KEY (gestione_id) REFERENCES gestioni_contabili(id),
CONSTRAINT fk_transazioni_prima_nota FOREIGN KEY (prima_nota_id) REFERENCES registro_prima_nota(id),
CONSTRAINT fk_transazioni_created_by FOREIGN KEY (created_by) REFERENCES users(id),
CONSTRAINT fk_transazioni_updated_by FOREIGN KEY (updated_by) REFERENCES users(id),
UNIQUE KEY unique_numero_transazione (condominio_id, numero_transazione),
INDEX idx_data_gestione (data_transazione, gestione_id),
INDEX idx_quadratura_stato (quadratura_ok, stato),
INDEX idx_competenza_tipo (data_competenza, tipo_transazione)
) COMMENT = 'Transazioni contabili del libro mastro';
-- 6. RIGHE MOVIMENTI CONTABILI (DARE/AVERE)
CREATE TABLE righe_movimenti_contabili (
id INT PRIMARY KEY AUTO_INCREMENT,
transazione_id INT NOT NULL,
conto_id INT NOT NULL,
tipo_movimento ENUM('DARE','AVERE') NOT NULL,
importo DECIMAL(10,2) NOT NULL,
descrizione_riga VARCHAR(255),
riferimento_documento VARCHAR(100) NULL,
fornitore_id INT NULL,
condomino_id INT NULL,
unita_immobiliare_id INT NULL,
conto_bancario_id INT NULL,
data_scadenza DATE NULL COMMENT 'Per gestione crediti/debiti',
liquidato BOOLEAN DEFAULT FALSE,
data_liquidazione DATE NULL,
note_riga TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by INT,
CONSTRAINT fk_righe_transazione FOREIGN KEY (transazione_id) REFERENCES transazioni_contabili(id) ON DELETE CASCADE,
CONSTRAINT fk_righe_conto FOREIGN KEY (conto_id) REFERENCES piano_conti(id),
CONSTRAINT fk_righe_fornitore FOREIGN KEY (fornitore_id) REFERENCES fornitori(id),
CONSTRAINT fk_righe_condomino FOREIGN KEY (condomino_id) REFERENCES condomini_proprietari(id),
CONSTRAINT fk_righe_unita FOREIGN KEY (unita_immobiliare_id) REFERENCES unita_immobiliari(id),
CONSTRAINT fk_righe_conto_bancario FOREIGN KEY (conto_bancario_id) REFERENCES conti_bancari(id),
CONSTRAINT fk_righe_created_by FOREIGN KEY (created_by) REFERENCES users(id),
INDEX idx_conto_tipo (conto_id, tipo_movimento),
INDEX idx_liquidazione (liquidato, data_scadenza),
INDEX idx_importo_movimento (importo, tipo_movimento),
INDEX idx_soggetti (fornitore_id, condomino_id, unita_immobiliare_id)
) COMMENT = 'Righe dettaglio movimenti in dare e avere';
-- 7. MOVIMENTI BANCARI
CREATE TABLE movimenti_bancari (
id INT PRIMARY KEY AUTO_INCREMENT,
conto_bancario_id INT NOT NULL,
data_movimento DATE NOT NULL,
data_valuta DATE NOT NULL,
data_contabile DATE NOT NULL,
descrizione TEXT NOT NULL,
importo DECIMAL(10,2) NOT NULL,
tipo_movimento ENUM('ENTRATA','USCITA') NOT NULL,
causale VARCHAR(255),
causale_abi VARCHAR(10) NULL COMMENT 'Codice ABI causale',
riferimento_bancario VARCHAR(100),
cro VARCHAR(30) NULL,
trn VARCHAR(50) NULL,
ordinante VARCHAR(255) NULL,
beneficiario VARCHAR(255) NULL,
iban_ordinante VARCHAR(34) NULL,
iban_beneficiario VARCHAR(34) NULL,
commissioni DECIMAL(8,2) DEFAULT 0.00,
transazione_contabile_id INT NULL COMMENT 'Collegamento a contabilità',
riconciliato BOOLEAN DEFAULT FALSE,
riconciliato_at TIMESTAMP NULL,
riconciliato_da INT NULL,
automatico BOOLEAN DEFAULT FALSE COMMENT 'Importato automaticamente',
note TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_movimenti_conto_bancario FOREIGN KEY (conto_bancario_id) REFERENCES conti_bancari(id) ON DELETE CASCADE,
CONSTRAINT fk_movimenti_transazione FOREIGN KEY (transazione_contabile_id) REFERENCES transazioni_contabili(id),
CONSTRAINT fk_movimenti_riconciliato_da FOREIGN KEY (riconciliato_da) REFERENCES users(id),
INDEX idx_riconciliazione (riconciliato, data_movimento),
INDEX idx_importo_tipo (importo, tipo_movimento),
INDEX idx_date_movimento (data_movimento, data_valuta),
INDEX idx_causali (causale_abi, causale),
INDEX idx_soggetti (ordinante, beneficiario)
) COMMENT = 'Movimenti estratto conto bancario con riconciliazione';
-- 8. SISTEMA RITENUTE FISCALI
CREATE TABLE ritenute_fiscali (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
fattura_prima_nota_id INT NOT NULL,
fornitore_id INT NOT NULL,
anno_riferimento YEAR NOT NULL,
data_fattura DATE NOT NULL,
numero_fattura VARCHAR(100) NOT NULL,
importo_imponibile DECIMAL(10,2) NOT NULL,
percentuale_ritenuta DECIMAL(5,2) NOT NULL,
importo_ritenuta DECIMAL(10,2) NOT NULL,
codice_tributo VARCHAR(10) NOT NULL COMMENT 'Codice tributo F24',
mese_competenza VARCHAR(7) NOT NULL COMMENT 'Formato: 2025-03',
data_scadenza_versamento DATE NOT NULL COMMENT 'Entro il 16 del mese successivo',
versata BOOLEAN DEFAULT FALSE,
data_versamento DATE NULL,
importo_versato DECIMAL(10,2) NULL,
f24_generato BOOLEAN DEFAULT FALSE,
f24_path VARCHAR(500) NULL,
f24_numero VARCHAR(50) NULL,
transazione_versamento_id INT NULL,
note TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_ritenute_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_ritenute_prima_nota FOREIGN KEY (fattura_prima_nota_id) REFERENCES registro_prima_nota(id),
CONSTRAINT fk_ritenute_fornitore FOREIGN KEY (fornitore_id) REFERENCES fornitori(id),
CONSTRAINT fk_ritenute_transazione FOREIGN KEY (transazione_versamento_id) REFERENCES transazioni_contabili(id),
INDEX idx_scadenze (data_scadenza_versamento, versata),
INDEX idx_competenza (mese_competenza, condominio_id),
INDEX idx_anno_fornitore (anno_riferimento, fornitore_id),
INDEX idx_versamenti (versata, data_versamento)
) COMMENT = 'Gestione ritenute d acconto con F24 automatico';
-- 9. BILANCI DI CHIUSURA
CREATE TABLE bilanci_chiusura (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
gestione_id INT NOT NULL,
tipo_bilancio ENUM('PREVENTIVO','CONSUNTIVO','STRAORDINARIO') NOT NULL,
anno_riferimento YEAR NOT NULL,
data_chiusura DATE NOT NULL,
data_approvazione DATE NULL,
totale_attivo DECIMAL(12,2) NOT NULL DEFAULT 0.00,
totale_passivo DECIMAL(12,2) NOT NULL DEFAULT 0.00,
totale_costi DECIMAL(12,2) NOT NULL DEFAULT 0.00,
totale_ricavi DECIMAL(12,2) NOT NULL DEFAULT 0.00,
conguaglio_gestione DECIMAL(12,2) NOT NULL DEFAULT 0.00 COMMENT 'Positivo=credito condominio, Negativo=debito',
fondi_disponibili DECIMAL(12,2) NOT NULL DEFAULT 0.00,
fondi_impegnati DECIMAL(12,2) NOT NULL DEFAULT 0.00,
stato ENUM('BOZZA','PROVVISORIO','APPROVATO','ARCHIVIATO') DEFAULT 'BOZZA',
verbale_assemblea VARCHAR(255) NULL,
delibera_assemblea VARCHAR(255) NULL,
note TEXT,
pdf_path VARCHAR(500) NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT,
CONSTRAINT fk_bilanci_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_bilanci_gestione FOREIGN KEY (gestione_id) REFERENCES gestioni_contabili(id),
CONSTRAINT fk_bilanci_created_by FOREIGN KEY (created_by) REFERENCES users(id),
UNIQUE KEY unique_bilancio_gestione (gestione_id, tipo_bilancio),
INDEX idx_data_stato (data_chiusura, stato),
INDEX idx_anno_tipo (anno_riferimento, tipo_bilancio)
) COMMENT = 'Bilanci di chiusura per gestioni';
-- 10. AUDIT TRAIL COMPLETO
CREATE TABLE audit_contabile (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
tabella_riferimento VARCHAR(100) NOT NULL,
record_id INT NOT NULL,
operazione ENUM('INSERT','UPDATE','DELETE') NOT NULL,
dati_precedenti JSON NULL,
dati_nuovi JSON NULL,
campo_modificato VARCHAR(100) NULL,
valore_precedente TEXT NULL,
valore_nuovo TEXT NULL,
user_id INT NOT NULL,
ip_address VARCHAR(45),
user_agent TEXT,
session_id VARCHAR(100),
timestamp_operazione TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_audit_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
CONSTRAINT fk_audit_user FOREIGN KEY (user_id) REFERENCES users(id),
INDEX idx_tabella_record (tabella_riferimento, record_id),
INDEX idx_condominio_timestamp (condominio_id, timestamp_operazione),
INDEX idx_user_operazione (user_id, operazione),
INDEX idx_audit_sessione (session_id, timestamp_operazione)
) COMMENT = 'Audit completo di tutte le modifiche contabili';
-- 11. TABELLE MILLESIMALI STRUTTURATE
CREATE TABLE tipologie_tabelle_millesimali (
id INT PRIMARY KEY AUTO_INCREMENT,
condominio_id INT NOT NULL,
codice VARCHAR(20) NOT NULL,
denominazione VARCHAR(255) NOT NULL,
descrizione TEXT,
tipo_ripartizione ENUM('MILLESIMI','PERCENTUALE','IMPORTO_FISSO','UNITA_UTILIZZO') NOT NULL,
attiva BOOLEAN DEFAULT TRUE,
ordine_visualizzazione INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_tipologie_tabelle_condominio FOREIGN KEY (condominio_id) REFERENCES condomini(id) ON DELETE CASCADE,
UNIQUE KEY unique_codice_condominio (condominio_id, codice),
INDEX idx_tipo_attiva (tipo_ripartizione, attiva)
) COMMENT = 'Tipologie tabelle millesimali per condominio';
CREATE TABLE tabelle_millesimali (
id INT PRIMARY KEY AUTO_INCREMENT,
tipologia_id INT NOT NULL,
unita_immobiliare_id INT NOT NULL,
condomino_id INT NOT NULL,
valore_millesimi DECIMAL(8,5) NOT NULL DEFAULT 0.00000,
percentuale DECIMAL(5,2) NULL,
importo_fisso DECIMAL(10,2) NULL,
unita_utilizzo INT NULL,
data_validita_da DATE NOT NULL,
data_validita_a DATE NULL,
attiva BOOLEAN DEFAULT TRUE,
note TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
CONSTRAINT fk_tabelle_tipologia FOREIGN KEY (tipologia_id) REFERENCES tipologie_tabelle_millesimali(id) ON DELETE CASCADE,
CONSTRAINT fk_tabelle_unita FOREIGN KEY (unita_immobiliare_id) REFERENCES unita_immobiliari(id),
CONSTRAINT fk_tabelle_condomino FOREIGN KEY (condomino_id) REFERENCES condomini_proprietari(id),
UNIQUE KEY unique_tabella_unita_validita (tipologia_id, unita_immobiliare_id, data_validita_da),
INDEX idx_validita (data_validita_da, data_validita_a, attiva),
INDEX idx_millesimi (valore_millesimi)
) COMMENT = 'Tabelle millesimali con storico modifiche';
-- =============================================
-- TRIGGERS AUTOMATICI
-- =============================================
DELIMITER //
-- Trigger aggiornamento saldi piano conti
CREATE TRIGGER aggiorna_saldo_piano_conti_insert
AFTER INSERT ON righe_movimenti_contabili
FOR EACH ROW
BEGIN
IF NEW.tipo_movimento = 'DARE' THEN
UPDATE piano_conti
SET saldo_dare = saldo_dare + NEW.importo,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.conto_id;
ELSE
UPDATE piano_conti
SET saldo_avere = saldo_avere + NEW.importo,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.conto_id;
END IF;
END//
CREATE TRIGGER aggiorna_saldo_piano_conti_update
AFTER UPDATE ON righe_movimenti_contabili
FOR EACH ROW
BEGIN
-- Reversa vecchi valori
IF OLD.tipo_movimento = 'DARE' THEN
UPDATE piano_conti
SET saldo_dare = saldo_dare - OLD.importo
WHERE id = OLD.conto_id;
ELSE
UPDATE piano_conti
SET saldo_avere = saldo_avere - OLD.importo
WHERE id = OLD.conto_id;
END IF;
-- Applica nuovi valori
IF NEW.tipo_movimento = 'DARE' THEN
UPDATE piano_conti
SET saldo_dare = saldo_dare + NEW.importo,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.conto_id;
ELSE
UPDATE piano_conti
SET saldo_avere = saldo_avere + NEW.importo,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.conto_id;
END IF;
END//
CREATE TRIGGER aggiorna_saldo_piano_conti_delete
AFTER DELETE ON righe_movimenti_contabili
FOR EACH ROW
BEGIN
IF OLD.tipo_movimento = 'DARE' THEN
UPDATE piano_conti
SET saldo_dare = saldo_dare - OLD.importo,
updated_at = CURRENT_TIMESTAMP
WHERE id = OLD.conto_id;
ELSE
UPDATE piano_conti
SET saldo_avere = saldo_avere - OLD.importo,
updated_at = CURRENT_TIMESTAMP
WHERE id = OLD.conto_id;
END IF;
END//
-- Trigger aggiornamento saldi bancari
CREATE TRIGGER aggiorna_saldo_bancario_insert
AFTER INSERT ON movimenti_bancari
FOR EACH ROW
BEGIN
IF NEW.tipo_movimento = 'ENTRATA' THEN
UPDATE conti_bancari
SET saldo_attuale = saldo_attuale + NEW.importo,
data_ultimo_movimento = NEW.data_movimento,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.conto_bancario_id;
ELSE
UPDATE conti_bancari
SET saldo_attuale = saldo_attuale - NEW.importo,
data_ultimo_movimento = NEW.data_movimento,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.conto_bancario_id;
END IF;
END//
-- Trigger controllo quadratura transazioni
CREATE TRIGGER verifica_quadratura_transazione
AFTER INSERT ON righe_movimenti_contabili
FOR EACH ROW
BEGIN
DECLARE totale_dare DECIMAL(12,2);
DECLARE totale_avere DECIMAL(12,2);
SELECT
COALESCE(SUM(CASE WHEN tipo_movimento = 'DARE' THEN importo ELSE 0 END), 0),
COALESCE(SUM(CASE WHEN tipo_movimento = 'AVERE' THEN importo ELSE 0 END), 0)
INTO totale_dare, totale_avere
FROM righe_movimenti_contabili
WHERE transazione_id = NEW.transazione_id;
UPDATE transazioni_contabili
SET quadratura_ok = (totale_dare = totale_avere),
importo_totale = totale_dare,
updated_at = CURRENT_TIMESTAMP
WHERE id = NEW.transazione_id;
END//
-- Trigger auto-generazione protocolli
CREATE TRIGGER genera_protocollo_prima_nota
BEFORE INSERT ON registro_prima_nota
FOR EACH ROW
BEGIN
DECLARE nuovo_protocollo INT;
DECLARE prefix_gestione VARCHAR(10);
-- Ottieni prefix gestione
SELECT protocollo_prefix INTO prefix_gestione
FROM gestioni_contabili
WHERE id = NEW.gestione_id;
-- Incrementa e ottieni nuovo numero protocollo
UPDATE gestioni_contabili
SET ultimo_protocollo = ultimo_protocollo + 1
WHERE id = NEW.gestione_id;
SELECT ultimo_protocollo INTO nuovo_protocollo
FROM gestioni_contabili
WHERE id = NEW.gestione_id;
-- Assegna protocolli
SET NEW.protocollo_gestione = CONCAT(prefix_gestione, '/', LPAD(nuovo_protocollo, 3, '0'));
-- Protocollo generale basato su anno
IF NEW.protocollo_generale IS NULL THEN
SET NEW.protocollo_generale = CONCAT(YEAR(NEW.data_registrazione), '/', LPAD(nuovo_protocollo, 4, '0'));
END IF;
END//
-- Trigger audit automatico
CREATE TRIGGER audit_piano_conti_update
AFTER UPDATE ON piano_conti
FOR EACH ROW
BEGIN
INSERT INTO audit_contabile (
condominio_id, tabella_riferimento, record_id, operazione,
dati_precedenti, dati_nuovi, user_id, ip_address
) VALUES (
NEW.condominio_id, 'piano_conti', NEW.id, 'UPDATE',
JSON_OBJECT('saldo_dare', OLD.saldo_dare, 'saldo_avere', OLD.saldo_avere),
JSON_OBJECT('saldo_dare', NEW.saldo_dare, 'saldo_avere', NEW.saldo_avere),
COALESCE(NEW.updated_by, NEW.created_by),
COALESCE(@user_ip, '0.0.0.0')
);
END//
DELIMITER ;
-- =============================================
-- INDICI PER PERFORMANCE
-- =============================================
-- Indici compositi per query frequenti
CREATE INDEX idx_prima_nota_gestione_stato ON registro_prima_nota (gestione_id, stato, data_competenza);
CREATE INDEX idx_transazioni_gestione_data ON transazioni_contabili (gestione_id, data_transazione, stato);
CREATE INDEX idx_righe_conto_data ON righe_movimenti_contabili (conto_id, transazione_id);
CREATE INDEX idx_movimenti_bancari_riconciliazione ON movimenti_bancari (conto_bancario_id, riconciliato, data_movimento);
CREATE INDEX idx_ritenute_scadenze ON ritenute_fiscali (condominio_id, data_scadenza_versamento, versata);
-- =============================================
-- VISTE UTILI
-- =============================================
-- Vista bilancio di verifica
CREATE VIEW vista_bilancio_verifica AS
SELECT
pc.condominio_id,
gc.tipo_gestione,
gc.anno_riferimento,
pc.codice,
pc.denominazione,
pc.tipo_conto,
pc.natura,
pc.saldo_dare,
pc.saldo_avere,
pc.saldo_finale
FROM piano_conti pc
JOIN gestioni_contabili gc ON pc.gestione IN ('TUTTE', gc.tipo_gestione)
WHERE pc.attivo = TRUE
ORDER BY pc.condominio_id, gc.tipo_gestione, pc.codice;
-- Vista scadenze ritenute
CREATE VIEW vista_scadenze_ritenute AS
SELECT
rf.condominio_id,
f.ragione_sociale,
rf.data_scadenza_versamento,
rf.importo_ritenuta,
rf.versata,
DATEDIFF(rf.data_scadenza_versamento, CURDATE()) AS giorni_scadenza
FROM ritenute_fiscali rf
JOIN fornitori f ON rf.fornitore_id = f.id
WHERE rf.versata = FALSE
ORDER BY rf.data_scadenza_versamento;
-- Vista movimenti non riconciliati
CREATE VIEW vista_movimenti_non_riconciliati AS
SELECT
cb.condominio_id,
cb.denominazione AS conto,
mb.data_movimento,
mb.descrizione,
mb.importo,
mb.tipo_movimento,
DATEDIFF(CURDATE(), mb.data_movimento) AS giorni_pendente
FROM movimenti_bancari mb
JOIN conti_bancari cb ON mb.conto_bancario_id = cb.id
WHERE mb.riconciliato = FALSE
ORDER BY mb.data_movimento DESC;
-- =============================================
-- STORED PROCEDURES UTILI
-- =============================================
DELIMITER //
-- Procedura chiusura gestione
CREATE PROCEDURE chiudi_gestione_contabile(
IN p_gestione_id INT,
IN p_data_chiusura DATE,
IN p_user_id INT
)
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
-- Aggiorna stato gestione
UPDATE gestioni_contabili
SET stato = 'CHIUSA',
data_chiusura = p_data_chiusura,
updated_by = p_user_id,
updated_at = CURRENT_TIMESTAMP
WHERE id = p_gestione_id;
-- Calcola totali
UPDATE gestioni_contabili gc
SET totale_costi = (
SELECT COALESCE(SUM(rmc.importo), 0)
FROM righe_movimenti_contabili rmc
JOIN transazioni_contabili tc ON rmc.transazione_id = tc.id
JOIN piano_conti pc ON rmc.conto_id = pc.id
WHERE tc.gestione_id = gc.id
AND pc.tipo_conto = 'COSTO'
AND rmc.tipo_movimento = 'DARE'
),
totale_ricavi = (
SELECT COALESCE(SUM(rmc.importo), 0)
FROM righe_movimenti_contabili rmc
JOIN transazioni_contabili tc ON rmc.transazione_id = tc.id
JOIN piano_conti pc ON rmc.conto_id = pc.id
WHERE tc.gestione_id = gc.id
AND pc.tipo_conto = 'RICAVO'
AND rmc.tipo_movimento = 'AVERE'
)
WHERE gc.id = p_gestione_id;
-- Calcola conguaglio
UPDATE gestioni_contabili
SET conguaglio = totale_ricavi - totale_costi
WHERE id = p_gestione_id;
COMMIT;
END//
DELIMITER ;
-- =============================================
-- COMMENTI FINALI
-- =============================================
/*
SISTEMA CONTABILE NETGESCON - CARATTERISTICHE PRINCIPALI:
1. PARTITA DOPPIA COMPLETA
- Ogni movimento ha sempre dare = avere
- Controlli automatici di quadratura
- Saldi calcolati automaticamente via trigger
2. MULTI-GESTIONE
- Ordinaria, Riscaldamento, Straordinarie separate
- Protocolli indipendenti per gestione
- Possibilità di spostare spese tra gestioni
3. SISTEMA PROTOCOLLI MULTIPLI
- Protocollo generale annuale
- Protocolli specifici per gestione
- Numerazione automatica
4. RICONCILIAZIONE BANCARIA
- Import automatico movimenti
- Collegamento a transazioni contabili
- Vista movimenti non riconciliati
5. GESTIONE RITENUTE AUTOMATICA
- Calcolo automatico ritenute
- Scadenzario F24
- Generazione modelli
6. AUDIT COMPLETO
- Tracking di ogni modifica
- Storico modifiche dettagliato
- Tracciabilità utenti
7. PERFORMANCE OTTIMIZZATE
- Saldi pre-calcolati via trigger
- Indici per query frequenti
- Viste per report standard
PROSSIMI PASSI:
- Implementazione interfacce Laravel
- API per import dati automatici
- Report e stampe bilanci
- Dashboard contabile avanzata
*/