📋 AGGIUNTE PRINCIPALI: - Sistema contabile partita doppia con gestioni multiple - Documentazione implementazione completa - Models Laravel: GestioneContabile, MovimentoPartitaDoppia - Controller ContabilitaAvanzataController - Migration sistema contabile completo - Scripts automazione e trasferimento - Manuali utente e checklist implementazione 📊 FILES PRINCIPALI: - docs/10-IMPLEMENTAZIONE-CONTABILITA-PARTITA-DOPPIA-GESTIONI.md - SPECIFICHE-SISTEMA-CONTABILE-COMPLETO.md - netgescon-laravel/database/migrations/2025_07_20_100000_create_complete_accounting_system.php - netgescon-laravel/app/Models/GestioneContabile.php ✅ CHECKPOINT SICURO PER ROLLBACK
20 KiB
20 KiB
💰 SISTEMA CONTABILE CONDOMINIALE NETGESCON - PARTITA DOPPIA
📋 OVERVIEW
Sistema contabile in partita doppia specifico per amministrazione condominiale, con gestioni (esercizi) amministrative che non seguono l'anno solare ma le decisioni assembleari.
🎯 PRINCIPI CONTABILI CONDOMINIALI
📅 Gestioni vs Anni Solari
- GESTIONE = Esercizio contabile condominiale
- Inizio: Delibera assemblea (es: 01/01/2024)
- Fine: Approvazione bilancio assemblea successiva (es: 30/04/2025)
- Movimenti post-31/12 possono appartenere alla gestione precedente
- Chiusura solo con approvazione formale bilancio
💎 Partita Doppia Condominiale
📊 DARE = AVERE (sempre bilanciato per gestione)
ESEMPIO Pagamento Fattura:
DARE: Conto Spesa (es: Pulizie Scale) €1.000
AVERE: Conto Banca €1.000
ESEMPIO Incasso Rata:
DARE: Conto Banca €5.000
AVERE: Conto Ricavi (Rate Condominiali) €5.000
🏢 Struttura Contabile Gerarchica
🏛️ MASTRO (Categoria principale)
├── 📂 CONTO (Sottocategoria)
│ ├── 📄 SOTTOCONTO (Voce specifica)
│ ├── 📄 SOTTOCONTO
│ └── 📄 SOTTOCONTO
└── 📂 CONTO
🗃️ SCHEMA DATABASE COMPLETO
1️⃣ Tabella: gestioni_contabili
CREATE TABLE gestioni_contabili (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
condominio_id BIGINT UNSIGNED NOT NULL,
-- 📅 PERIODO GESTIONE
denominazione VARCHAR(255) NOT NULL, -- "Gestione 2024", "Esercizio 2023-2024"
data_inizio DATE NOT NULL, -- Inizio gestione (delibera assemblea)
data_fine_prevista DATE NOT NULL, -- Fine prevista (solitamente 31/12)
data_chiusura_effettiva DATE NULL, -- Chiusura reale (approvazione bilancio)
-- 📊 STATO GESTIONE
stato ENUM('aperta','chiusa_provvisoria','chiusa_definitiva') DEFAULT 'aperta',
-- 🏛️ ASSEMBLEA APPROVAZIONE
data_assemblea_approvazione DATE NULL,
verbale_approvazione VARCHAR(255),
-- 💰 TOTALI GESTIONE (calcolati automaticamente)
totale_entrate DECIMAL(12,4) DEFAULT 0,
totale_uscite DECIMAL(12,4) DEFAULT 0,
saldo_gestione DECIMAL(12,4) DEFAULT 0,
-- 📋 NOTE E AUDIT
note_gestione TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by BIGINT UNSIGNED,
FOREIGN KEY (condominio_id) REFERENCES stabili(id) ON DELETE CASCADE,
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL,
INDEX idx_condominio_periodo (condominio_id, data_inizio, data_fine_prevista),
INDEX idx_stato (stato),
INDEX idx_data_chiusura (data_chiusura_effettiva)
) ENGINE=InnoDB COMMENT='Gestioni contabili condominiali (esercizi amministrativi)';
2️⃣ Tabella: piano_conti_mastri
CREATE TABLE piano_conti_mastri (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-- 📊 IDENTIFICAZIONE MASTRO
codice_mastro VARCHAR(10) NOT NULL, -- "100", "200", "300"
denominazione VARCHAR(255) NOT NULL, -- "ENTRATE", "SPESE AMMINISTRATIVE"
tipo_mastro ENUM('ATTIVO','PASSIVO','COSTI','RICAVI') NOT NULL,
-- 🎨 VISUALIZZAZIONE
colore_hex VARCHAR(7) DEFAULT '#6c757d', -- Per dashboard e report
icona VARCHAR(50) DEFAULT 'fas fa-folder', -- FontAwesome icon
ordine_visualizzazione SMALLINT DEFAULT 0,
-- 📋 CONFIGURAZIONE
descrizione TEXT,
attivo BOOLEAN DEFAULT TRUE,
-- 📅 AUDIT
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_codice_mastro (codice_mastro),
INDEX idx_tipo_ordine (tipo_mastro, ordine_visualizzazione),
INDEX idx_attivo (attivo)
) ENGINE=InnoDB COMMENT='Mastri del piano dei conti condominiale';
3️⃣ Tabella: piano_conti_conti
CREATE TABLE piano_conti_conti (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
mastro_id BIGINT UNSIGNED NOT NULL,
-- 📂 IDENTIFICAZIONE CONTO
codice_conto VARCHAR(15) NOT NULL, -- "101", "201.1", "301.A"
denominazione VARCHAR(255) NOT NULL, -- "Rate Condominiali", "Pulizie Scale"
-- 🎯 CONFIGURAZIONE CONTABILE
tipo_saldo ENUM('DARE','AVERE') NOT NULL, -- Natura del saldo
ripartizione_automatica BOOLEAN DEFAULT TRUE, -- Se ripartire automaticamente
tabella_millesimale_default VARCHAR(50), -- "GENERALE", "ASCENSORE", etc
-- 🎨 VISUALIZZAZIONE
colore_hex VARCHAR(7), -- Eredita da mastro se NULL
icona VARCHAR(50), -- FontAwesome icon specifica
ordine_visualizzazione SMALLINT DEFAULT 0,
-- 📋 CONFIGURAZIONE
descrizione TEXT,
attivo BOOLEAN DEFAULT TRUE,
-- 📅 AUDIT
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (mastro_id) REFERENCES piano_conti_mastri(id) ON DELETE CASCADE,
UNIQUE KEY uk_codice_conto (codice_conto),
INDEX idx_mastro_ordine (mastro_id, ordine_visualizzazione),
INDEX idx_ripartizione (ripartizione_automatica),
INDEX idx_attivo (attivo)
) ENGINE=InnoDB COMMENT='Conti del piano dei conti condominiale';
4️⃣ Tabella: piano_conti_sottoconti
CREATE TABLE piano_conti_sottoconti (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
conto_id BIGINT UNSIGNED NOT NULL,
-- 📄 IDENTIFICAZIONE SOTTOCONTO
codice_sottoconto VARCHAR(20) NOT NULL, -- "101.01", "201.1.A", "301.ASC.A"
denominazione VARCHAR(255) NOT NULL, -- "Rate Ordinarie", "Pulizia Scale A"
-- 🎯 CONFIGURAZIONE SPECIFICA
ripartizione_specifica VARCHAR(100), -- "SOLO_SCALA_A", "PIANO_1_3", etc
percentuale_ripartizione DECIMAL(5,2), -- Se ripartizione fissa %
importo_fisso DECIMAL(10,2), -- Se importo fisso per unità
-- 📊 NATURA CONTABILE
tipo_saldo ENUM('DARE','AVERE'), -- Eredita da conto se NULL
deducibile_fiscale BOOLEAN DEFAULT FALSE, -- Se deducibile per dichiarazioni
-- 🎨 VISUALIZZAZIONE
ordine_visualizzazione SMALLINT DEFAULT 0,
-- 📋 CONFIGURAZIONE
descrizione TEXT,
attivo BOOLEAN DEFAULT TRUE,
-- 📅 AUDIT
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (conto_id) REFERENCES piano_conti_conti(id) ON DELETE CASCADE,
UNIQUE KEY uk_codice_sottoconto (codice_sottoconto),
INDEX idx_conto_ordine (conto_id, ordine_visualizzazione),
INDEX idx_ripartizione (ripartizione_specifica),
INDEX idx_attivo (attivo)
) ENGINE=InnoDB COMMENT='Sottoconti specifici del piano dei conti';
5️⃣ Tabella: registrazioni_contabili ⭐ CUORE DEL SISTEMA
CREATE TABLE registrazioni_contabili (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-- 🎯 COLLEGAMENTO GESTIONE (FONDAMENTALE!)
gestione_id BIGINT UNSIGNED NOT NULL,
condominio_id BIGINT UNSIGNED NOT NULL,
-- 📅 DATE MOVIMENTO
data_operazione DATE NOT NULL, -- Data effettiva operazione
data_registrazione DATE NOT NULL, -- Data inserimento contabile
data_competenza DATE NOT NULL, -- Data competenza contabile
data_valuta DATE, -- Data valuta bancaria
-- 📋 IDENTIFICAZIONE MOVIMENTO
numero_registrazione VARCHAR(20) NOT NULL, -- Numerazione progressiva per gestione
causale VARCHAR(500) NOT NULL, -- Descrizione movimento
riferimento_documento VARCHAR(255), -- Numero fattura, ricevuta, etc
-- 💰 IMPORTO TOTALE
importo_totale DECIMAL(12,4) NOT NULL, -- Importo complessivo movimento
-- 🎯 CLASSIFICAZIONE
tipo_movimento ENUM('ENTRATA','USCITA','GIROCONTO') NOT NULL,
categoria_movimento VARCHAR(100), -- "FORNITURA", "RATA", "MANUTENZIONE"
sottocategoria VARCHAR(100), -- Classificazione aggiuntiva
-- 🏦 DATI BANCARI
conto_corrente VARCHAR(50), -- Conto utilizzato
numero_assegno VARCHAR(20), -- Se pagamento con assegno
cro_bonifico VARCHAR(50), -- CRO/TRN bonifico
-- 👥 SOGGETTI COINVOLTI
fornitore_id BIGINT UNSIGNED, -- Collegamento anagrafica fornitori
cliente_id BIGINT UNSIGNED, -- Collegamento anagrafica (per entrate)
-- ⚙️ STATO E CONTROLLI
stato ENUM('bozza','confermata','ripartita','chiusa') DEFAULT 'bozza',
ripartita BOOLEAN DEFAULT FALSE, -- Se già ripartita ai condomini
riconciliata BOOLEAN DEFAULT FALSE, -- Se riconciliata con estratto conto
-- 🔄 RIPARTIZIONE AUTOMATICA
ripartizione_automatica BOOLEAN DEFAULT TRUE,
tabella_millesimale_usata VARCHAR(50), -- Quale tabella millesimale usata
-- 📎 ALLEGATI E NOTE
numero_allegati SMALLINT DEFAULT 0,
note_interne TEXT, -- Note riservate amministratore
note_pubbliche TEXT, -- Note visibili ai condomini
-- 📅 AUDIT COMPLETO
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by BIGINT UNSIGNED NOT NULL,
updated_by BIGINT UNSIGNED,
-- 🔗 FOREIGN KEYS
FOREIGN KEY (gestione_id) REFERENCES gestioni_contabili(id) ON DELETE RESTRICT,
FOREIGN KEY (condominio_id) REFERENCES stabili(id) ON DELETE CASCADE,
FOREIGN KEY (fornitore_id) REFERENCES persone(id) ON DELETE SET NULL,
FOREIGN KEY (cliente_id) REFERENCES persone(id) ON DELETE SET NULL,
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT,
-- 📊 INDICI OTTIMIZZAZIONE
INDEX idx_gestione_data (gestione_id, data_operazione),
INDEX idx_condominio_gestione (condominio_id, gestione_id),
INDEX idx_numero_gestione (gestione_id, numero_registrazione),
INDEX idx_tipo_categoria (tipo_movimento, categoria_movimento),
INDEX idx_stato_ripartita (stato, ripartita),
INDEX idx_data_competenza (data_competenza),
INDEX idx_fornitore (fornitore_id),
INDEX idx_importo (importo_totale),
-- ✅ CONSTRAINTS
UNIQUE KEY uk_numero_per_gestione (gestione_id, numero_registrazione),
CONSTRAINT chk_importo_positivo CHECK (importo_totale > 0)
) ENGINE=InnoDB COMMENT='Registrazioni contabili in partita doppia per gestione';
6️⃣ Tabella: movimenti_contabili (DARE/AVERE)
CREATE TABLE movimenti_contabili (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
registrazione_id BIGINT UNSIGNED NOT NULL,
-- 📊 PARTITA DOPPIA
sottoconto_id BIGINT UNSIGNED NOT NULL, -- A quale sottoconto imputare
-- 💰 IMPORTI DARE/AVERE
importo_dare DECIMAL(12,4) DEFAULT 0, -- Importo in DARE
importo_avere DECIMAL(12,4) DEFAULT 0, -- Importo in AVERE
-- 📋 DETTAGLI MOVIMENTO
descrizione VARCHAR(500), -- Descrizione specifica riga
quantita DECIMAL(10,3), -- Quantità se applicabile
prezzo_unitario DECIMAL(10,4), -- Prezzo unitario se applicabile
-- 🎯 RIPARTIZIONE
da_ripartire BOOLEAN DEFAULT TRUE, -- Se questa riga va ripartita
tabella_millesimale VARCHAR(50), -- Tabella per questa riga specifica
-- 📅 AUDIT
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 🔗 FOREIGN KEYS
FOREIGN KEY (registrazione_id) REFERENCES registrazioni_contabili(id) ON DELETE CASCADE,
FOREIGN KEY (sottoconto_id) REFERENCES piano_conti_sottoconti(id) ON DELETE RESTRICT,
-- 📊 INDICI
INDEX idx_registrazione (registrazione_id),
INDEX idx_sottoconto (sottoconto_id),
INDEX idx_ripartizione (da_ripartire),
-- ✅ CONSTRAINTS PARTITA DOPPIA
CONSTRAINT chk_dare_or_avere CHECK (
(importo_dare > 0 AND importo_avere = 0) OR
(importo_dare = 0 AND importo_avere > 0)
)
) ENGINE=InnoDB COMMENT='Movimenti dare/avere della partita doppia';
7️⃣ Tabella: ripartizioni_condomini (RISULTATO FINALE)
CREATE TABLE ripartizioni_condomini (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
registrazione_id BIGINT UNSIGNED NOT NULL,
movimento_id BIGINT UNSIGNED NOT NULL,
unita_immobiliare_id BIGINT UNSIGNED NOT NULL,
-- 💰 IMPORTO RIPARTITO
importo_ripartito DECIMAL(12,4) NOT NULL, -- Quanto spetta a questa unità
-- 📊 CALCOLO RIPARTIZIONE
millesimi_utilizzati DECIMAL(8,4) NOT NULL, -- Millesimi usati per calcolo
tabella_millesimale VARCHAR(50) NOT NULL, -- Quale tabella usata
-- 👥 IMPUTAZIONE
persona_id BIGINT UNSIGNED, -- A chi imputare (proprietario)
tipo_imputazione ENUM('proprietario','inquilino','delegato') DEFAULT 'proprietario',
-- 📅 PERIODO
data_competenza_inizio DATE,
data_competenza_fine DATE,
-- ⚙️ STATO
stato ENUM('calcolata','confermata','fatturata','pagata') DEFAULT 'calcolata',
-- 📅 AUDIT
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 🔗 FOREIGN KEYS
FOREIGN KEY (registrazione_id) REFERENCES registrazioni_contabili(id) ON DELETE CASCADE,
FOREIGN KEY (movimento_id) REFERENCES movimenti_contabili(id) ON DELETE CASCADE,
FOREIGN KEY (unita_immobiliare_id) REFERENCES unita_immobiliari(id) ON DELETE CASCADE,
FOREIGN KEY (persona_id) REFERENCES persone(id) ON DELETE SET NULL,
-- 📊 INDICI
INDEX idx_registrazione (registrazione_id),
INDEX idx_unita (unita_immobiliare_id),
INDEX idx_persona_stato (persona_id, stato),
INDEX idx_data_competenza (data_competenza_inizio, data_competenza_fine),
-- ✅ CONSTRAINTS
CONSTRAINT chk_importo_ripartito_positivo CHECK (importo_ripartito > 0),
CONSTRAINT chk_millesimi_valid CHECK (millesimi_utilizzati > 0 AND millesimi_utilizzati <= 1000)
) ENGINE=InnoDB COMMENT='Ripartizione finale per singola unità immobiliare';
🎯 PIANO CONTI STANDARD CONDOMINIALE
📊 Schema MASTRO → CONTO → SOTTOCONTO
🏛️ 100 - ENTRATE
├── 📂 101 - Rate Condominiali
│ ├── 📄 101.01 - Rate Ordinarie
│ ├── 📄 101.02 - Rate Straordinarie
│ ├── 📄 101.03 - Interessi di Mora
│ └── 📄 101.04 - Rate Anni Precedenti
├── 📂 102 - Altri Ricavi
│ ├── 📄 102.01 - Affitti Spazi Comuni
│ ├── 📄 102.02 - Rimborsi Assicurazioni
│ └── 📄 102.03 - Interessi Attivi Bancari
└── 📂 103 - Fondi e Accantonamenti
├── 📄 103.01 - Fondo di Riserva
└── 📄 103.02 - Fondi Specifici
🏛️ 200 - SPESE AMMINISTRATIVE
├── 📂 201 - Pulizie
│ ├── 📄 201.01 - Pulizie Scale Scala A
│ ├── 📄 201.02 - Pulizie Scale Scala B
│ └── 📄 201.03 - Materiali Pulizia
├── 📂 202 - Energia Elettrica
│ ├── 📄 202.01 - Illuminazione Scale
│ └── 📄 202.02 - Forza Motrice Ascensori
└── 📂 203 - Amministrazione
├── 📄 203.01 - Compenso Amministratore
└── 📄 203.02 - Spese Postali e Bancarie
🏛️ 300 - MANUTENZIONI
├── 📂 301 - Ascensori
│ ├── 📄 301.01 - Manutenzione Ordinaria Asc. A
│ ├── 📄 301.02 - Manutenzione Ordinaria Asc. B
│ └── 📄 301.03 - Riparazioni Straordinarie
└── 📂 302 - Impianti
├── 📄 302.01 - Manutenzione Autoclave
└── 📄 302.02 - Manutenzione Citofoni
🏛️ 400 - FONDI E RISERVE
├── 📂 401 - Liquidità
│ ├── 📄 401.01 - C/C Banco BPM
│ └── 📄 401.02 - Cassa Contante
└── 📂 402 - Crediti/Debiti
├── 📄 402.01 - Crediti vs Condomini
└── 📄 402.02 - Debiti vs Fornitori
⚙️ WORKFLOW REGISTRAZIONE CONTABILE
1️⃣ Inserimento Registrazione
// Esempio: Pagamento fattura pulizie €1.000 + IVA €220
$registrazione = new RegistrazioneContabile([
'gestione_id' => $gestioneAttiva->id,
'data_operazione' => '2024-03-15',
'causale' => 'Pagamento fattura pulizie marzo 2024',
'importo_totale' => 1220.00,
'tipo_movimento' => 'USCITA'
]);
// Movimenti in partita doppia
$movimenti = [
// DARE: Spesa pulizie
[
'sottoconto_id' => $sottocontoPulizieScalaA->id,
'importo_dare' => 1000.00,
'descrizione' => 'Pulizie scala A marzo 2024'
],
// DARE: IVA
[
'sottoconto_id' => $sottocontoIVA->id,
'importo_dare' => 220.00,
'descrizione' => 'IVA 22% su pulizie'
],
// AVERE: Uscita banca
[
'sottoconto_id' => $sottocontoBanca->id,
'importo_avere' => 1220.00,
'descrizione' => 'Pagamento bonifico'
]
];
2️⃣ Ripartizione Automatica
// Sistema calcola ripartizione per ogni unità
foreach ($condominio->unitaImmobiliari as $unita) {
$importoRipartito = ($movimento->importo_dare * $unita->millesimi_generali) / 1000;
RipartizioneCondomino::create([
'registrazione_id' => $registrazione->id,
'unita_immobiliare_id' => $unita->id,
'importo_ripartito' => $importoRipartito,
'millesimi_utilizzati' => $unita->millesimi_generali,
'tabella_millesimale' => 'GENERALE'
]);
}
3️⃣ Controlli Partita Doppia
// Verifica quadratura DARE = AVERE
$totaleDare = $registrazione->movimenti()->sum('importo_dare');
$totaleAvere = $registrazione->movimenti()->sum('importo_avere');
if ($totaleDare != $totaleAvere) {
throw new Exception("Partita doppia non bilanciata: DARE €{$totaleDare} ≠ AVERE €{$totaleAvere}");
}
📋 ISTRUZIONI PER COPILOT
💰 IMPLEMENTAZIONE SISTEMA CONTABILE CONDOMINIALE
MANUALI DA CONSULTARE:
1. /home/michele/netgescon/docs/02-architettura-laravel/09-sistema-contabile/SISTEMA-CONTABILE-PARTITA-DOPPIA.md
2. /home/michele/netgescon/docs/04-DATABASE-STRUTTURE.md
3. /home/michele/netgescon/docs/02-architettura-laravel/03-anagrafica-condomini/ANALISI-ANAGRAFICA.md
PRINCIPI FONDAMENTALI:
1. 📅 GESTIONE = ESERCIZIO CONTABILE (non anno solare)
2. 💰 PARTITA DOPPIA: ogni movimento ha DARE = AVERE
3. 🏗️ STRUTTURA: MASTRO → CONTO → SOTTOCONTO
4. 🔍 CAMPO GESTIONE: ogni registrazione legata a gestione_id
5. 📊 RIPARTIZIONE: automatica per millesimi alle unità
SCHEMA DATABASE:
- gestioni_contabili (esercizi amministrativi)
- piano_conti_mastri (categorie principali)
- piano_conti_conti (sottocategorie)
- piano_conti_sottoconti (voci specifiche)
- registrazioni_contabili (movimenti con gestione_id)
- movimenti_contabili (dare/avere)
- ripartizioni_condomini (risultato finale per unità)
WORKFLOW:
1. Crea gestione contabile
2. Inserisci registrazione con gestione_id
3. Crea movimenti dare/avere bilanciati
4. Sistema calcola ripartizione automatica
5. Genera prospetti per condomini
OBIETTIVO: Zero perdite economiche, controllo totale centesimi, gestioni amministrative reali.
Questo sistema garantirà il controllo totale di ogni centesimo nelle gestioni condominiali! 💎✨