# ๐Ÿ’ฐ IMPLEMENTAZIONE SISTEMA CONTABILE PARTITA DOPPIA CON GESTIONI MULTIPLE ## ๐Ÿ“‹ **OVERVIEW IMPLEMENTAZIONE** Sistema contabile condominiale in partita doppia con gestioni multiple (ORDINARIA, RISCALDAMENTO, STRAORDINARIA) integrate con chiusura e riapertura contabile classica. --- ## ๐ŸŽฏ **PRINCIPI FONDAMENTALI** ### ๐Ÿ“… **Gestioni Multiple per Condominio** ``` ๐Ÿข CONDOMINIO โ”œโ”€โ”€ ๐Ÿ“Š GESTIONE ORDINARIA (spese comuni) โ”œโ”€โ”€ ๐Ÿ”ฅ GESTIONE RISCALDAMENTO (spese termiche) โ””โ”€โ”€ โšก GESTIONE STRAORDINARIA (lavori straordinari) ``` ### ๐Ÿ’Ž **Partita Doppia con Gestioni** ```sql -- Ogni movimento contabile รจ collegato a: registrazione_contabile { gestione_id, -- FK alla tabella gestioni tipo_gestione, -- ENUM('ORDINARIA','RISCALDAMENTO','STRAORDINARIA') dare_totale, -- Totale DARE avere_totale -- Totale AVERE (deve essere = dare_totale) } ``` ### ๐Ÿ”„ **Chiusura e Riapertura Contabile** 1. **CHIUSURA GESTIONE**: Movimenti di chiusura a Stato Patrimoniale e Conto Economico 2. **RIAPERTURA GESTIONE**: Riporto saldi patrimoniali alla gestione successiva --- ## ๐Ÿ—ƒ๏ธ **SCHEMA DATABASE AGGIORNATO** ### 1๏ธโƒฃ **Tabella: `gestioni_contabili` (ESTESA)** ```sql -- AGGIORNAMENTO tabella esistente ALTER TABLE gestioni_contabili ADD COLUMN IF NOT EXISTS tipo_gestione ENUM('ORDINARIA','RISCALDAMENTO','STRAORDINARIA') NOT NULL DEFAULT 'ORDINARIA'; ALTER TABLE gestioni_contabili ADD COLUMN IF NOT EXISTS gestione_precedente_id BIGINT UNSIGNED NULL; ALTER TABLE gestioni_contabili ADD COLUMN IF NOT EXISTS saldi_apertura JSON NULL; ALTER TABLE gestioni_contabili ADD COLUMN IF NOT EXISTS saldi_chiusura JSON NULL; -- Indici aggiuntivi ALTER TABLE gestioni_contabili ADD INDEX idx_tipo_gestione (tipo_gestione); ALTER TABLE gestioni_contabili ADD INDEX idx_condominio_tipo (condominio_id, tipo_gestione); ``` ### 2๏ธโƒฃ **Tabella: `registrazioni_contabili` (AGGIORNATA)** ```sql -- AGGIORNAMENTO per gestioni multiple ALTER TABLE registrazioni_contabili ADD COLUMN IF NOT EXISTS tipo_gestione ENUM('ORDINARIA','RISCALDAMENTO','STRAORDINARIA') NOT NULL DEFAULT 'ORDINARIA'; ALTER TABLE registrazioni_contabili ADD COLUMN IF NOT EXISTS ritenuta_acconto DECIMAL(10,4) DEFAULT 0; ALTER TABLE registrazioni_contabili ADD COLUMN IF NOT EXISTS percentuale_ritenuta DECIMAL(5,2) DEFAULT 0; ALTER TABLE registrazioni_contabili ADD COLUMN IF NOT EXISTS codice_ritenuta VARCHAR(10); ALTER TABLE registrazioni_contabili ADD COLUMN IF NOT EXISTS imponibile_ritenuta DECIMAL(12,4) DEFAULT 0; -- Indici per performance ALTER TABLE registrazioni_contabili ADD INDEX idx_gestione_tipo (gestione_id, tipo_gestione); ALTER TABLE registrazioni_contabili ADD INDEX idx_ritenuta (ritenuta_acconto); ``` ### 3๏ธโƒฃ **Nuova Tabella: `ripartizioni_gestioni`** ```sql CREATE TABLE ripartizioni_gestioni ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, registrazione_id BIGINT UNSIGNED NOT NULL, movimento_id BIGINT UNSIGNED NOT NULL, -- ๐ŸŽฏ COLLEGAMENTO GESTIONI gestione_ordinaria_perc DECIMAL(5,2) DEFAULT 0, -- % su gestione ordinaria gestione_riscaldamento_perc DECIMAL(5,2) DEFAULT 0, -- % su gestione riscaldamento gestione_straordinaria_perc DECIMAL(5,2) DEFAULT 0, -- % su gestione straordinaria -- ๐Ÿ’ฐ IMPORTI RIPARTITI importo_ordinaria DECIMAL(12,4) DEFAULT 0, importo_riscaldamento DECIMAL(12,4) DEFAULT 0, importo_straordinaria DECIMAL(12,4) DEFAULT 0, -- ๐Ÿ“Š TABELLE MILLESIMALI tabella_ordinaria VARCHAR(50) DEFAULT 'GENERALE', tabella_riscaldamento VARCHAR(50) DEFAULT 'RISCALDAMENTO', tabella_straordinaria VARCHAR(50) DEFAULT 'GENERALE', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (registrazione_id) REFERENCES registrazioni_contabili(id) ON DELETE CASCADE, FOREIGN KEY (movimento_id) REFERENCES movimenti_contabili(id) ON DELETE CASCADE, INDEX idx_registrazione (registrazione_id), INDEX idx_movimento (movimento_id), -- CONSTRAINT: La somma delle percentuali deve essere 100% CONSTRAINT chk_percentuali_totale CHECK ( gestione_ordinaria_perc + gestione_riscaldamento_perc + gestione_straordinaria_perc = 100 ) ) ENGINE=InnoDB COMMENT='Ripartizione movimenti tra gestioni multiple'; ``` ### 4๏ธโƒฃ **Nuova Tabella: `chiusure_riaperture_contabili`** ```sql CREATE TABLE chiusure_riaperture_contabili ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, gestione_id BIGINT UNSIGNED NOT NULL, -- ๐ŸŽฏ TIPO OPERAZIONE tipo_operazione ENUM('CHIUSURA','RIAPERTURA') NOT NULL, data_operazione DATE NOT NULL, -- ๐Ÿ“Š DATI CHIUSURA/RIAPERTURA saldi_conti JSON NOT NULL, -- Saldi di tutti i conti totale_stato_patrimoniale DECIMAL(12,4), -- Totale SP totale_conto_economico DECIMAL(12,4), -- Totale CE risultato_gestione DECIMAL(12,4), -- Utile/Perdita -- ๐Ÿ”— COLLEGAMENTO RIAPERTURA chiusura_precedente_id BIGINT UNSIGNED NULL, -- Link alla chiusura precedente -- ๐Ÿ“‹ CONTROLLI confermata BOOLEAN DEFAULT FALSE, confermata_da BIGINT UNSIGNED, confermata_il TIMESTAMP NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, created_by BIGINT UNSIGNED NOT NULL, FOREIGN KEY (gestione_id) REFERENCES gestioni_contabili(id) ON DELETE RESTRICT, FOREIGN KEY (chiusura_precedente_id) REFERENCES chiusure_riaperture_contabili(id), FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT, INDEX idx_gestione_tipo (gestione_id, tipo_operazione), INDEX idx_data (data_operazione), INDEX idx_confermata (confermata) ) ENGINE=InnoDB COMMENT='Chiusure e riaperture contabili per gestione'; ``` --- ## ๐ŸŽจ **INTERFACCIA UTENTE - SPECIFICA SCHERMATA** ### ๐Ÿ“ **Maschera Registrazione Contabile Avanzata** ```php // STRUTTURA FORM REGISTRAZIONE [ // ๐Ÿ“… SEZIONE INTESTAZIONE 'data_operazione' => 'required|date', 'causale' => 'required|string|max:500', 'importo_totale' => 'required|numeric|min:0.01', // ๐ŸŽฏ GESTIONI (CHECKBOX MULTIPLE) 'gestioni' => [ 'ordinaria' => ['attiva' => true, 'percentuale' => 70], 'riscaldamento' => ['attiva' => true, 'percentuale' => 30], 'straordinaria' => ['attiva' => false, 'percentuale' => 0] ], // ๐Ÿ’ฐ SEZIONE RITENUTA D'ACCONTO 'ritenuta_section' => [ 'applica_ritenuta' => true, 'codice_ritenuta' => 'R001', // Select da tabella ritenute 'percentuale_ritenuta' => 20.00, 'imponibile_ritenuta' => 1000.00, 'importo_ritenuta' => 200.00 // Calcolato automaticamente ], // ๐Ÿ“Š SEZIONE RIGHE CONTABILI (DARE/AVERE) 'righe_contabili' => [ [ 'sottoconto_id' => 1, 'descrizione' => 'Pulizie scale marzo', 'importo_dare' => 1000.00, 'importo_avere' => 0, 'ripartizione_gestioni' => [ 'ordinaria' => 70, 'riscaldamento' => 30 ] ], [ 'sottoconto_id' => 2, 'descrizione' => 'Ritenuta d\'acconto 20%', 'importo_dare' => 200.00, 'importo_avere' => 0 ], [ 'sottoconto_id' => 3, 'descrizione' => 'Pagamento bonifico', 'importo_dare' => 0, 'importo_avere' => 1200.00 ] ] ] ``` ### ๐ŸŽจ **Layout Schermata HTML** ```html
๐Ÿ“… Dati Generali Registrazione
๐ŸŽฏ Ripartizione per Gestioni
๐Ÿ’ก Il totale delle percentuali deve essere 100%
๐Ÿ’ฐ Ritenuta d'Acconto
๐Ÿ“Š Righe Contabili (Partita Doppia)
Sottoconto Descrizione DARE โ‚ฌ AVERE โ‚ฌ Gestioni Azioni
TOTALI 0.00 0.00 โš ๏ธ Non bilanciato
``` --- ## โš™๏ธ **WORKFLOW IMPLEMENTAZIONE** ### 1๏ธโƒฃ **Models Laravel** ```php // GestioneContabile.php (AGGIORNATO) class GestioneContabile extends Model { protected $fillable = [ 'condominio_id', 'denominazione', 'tipo_gestione', 'data_inizio', 'data_fine_prevista', 'stato', 'gestione_precedente_id', 'saldi_apertura', 'saldi_chiusura' ]; protected $casts = [ 'saldi_apertura' => 'array', 'saldi_chiusura' => 'array', 'data_inizio' => 'date', 'data_fine_prevista' => 'date' ]; // Relazione con registrazioni public function registrazioni() { return $this->hasMany(RegistrazioneContabile::class, 'gestione_id'); } // Calcolo saldi automatico public function calcolaSaldi() { // Implementazione calcolo saldi DARE/AVERE } } // RegistrazioneContabile.php (AGGIORNATO) class RegistrazioneContabile extends Model { protected $fillable = [ 'gestione_id', 'tipo_gestione', 'data_operazione', 'causale', 'importo_totale', 'ritenuta_acconto', 'percentuale_ritenuta', 'codice_ritenuta' ]; // Relazione gestioni multiple public function ripartizioniGestioni() { return $this->hasMany(RipartizioneGestione::class, 'registrazione_id'); } // Verifica quadratura public function isQuadrata() { $dare = $this->movimenti()->sum('importo_dare'); $avere = $this->movimenti()->sum('importo_avere'); return abs($dare - $avere) < 0.01; } } ``` ### 2๏ธโƒฃ **Controller Avanzato** ```php // ContabilitaAvanzataController.php class ContabilitaAvanzataController extends Controller { public function creaRegistrazione(Request $request) { DB::beginTransaction(); try { // 1. Validazione input $validated = $this->validateRegistrazione($request); // 2. Creazione registrazione principale $registrazione = $this->creaRegistrazionePrincipale($validated); // 3. Creazione movimenti DARE/AVERE $this->creaMovimentiContabili($registrazione, $validated['righe']); // 4. Gestione ripartizioni multiple gestioni $this->creaRipartizioniGestioni($registrazione, $validated['gestioni']); // 5. Calcolo ripartizione condomini $this->calcolaRipartizioneCondomini($registrazione); // 6. Verifica quadratura finale if (!$registrazione->isQuadrata()) { throw new Exception('Partita doppia non bilanciata'); } DB::commit(); return response()->json(['success' => true, 'id' => $registrazione->id]); } catch (Exception $e) { DB::rollback(); return response()->json(['error' => $e->getMessage()], 400); } } public function chiusuraGestione($gestioneId) { // Implementazione chiusura contabile $gestione = GestioneContabile::findOrFail($gestioneId); // 1. Calcolo saldi finali tutti i sottoconti $saldiFinali = $this->calcolaSaldiFinali($gestione); // 2. Creazione registrazioni di chiusura $this->creaRegistrazioniChiusura($gestione, $saldiFinali); // 3. Aggiornamento stato gestione $gestione->update(['stato' => 'chiusa_definitiva']); } public function riaperturaGestione($nuovaGestioneId, $precedenteGestioneId) { // Implementazione riapertura con riporto saldi } } ``` ### 3๏ธโƒฃ **JavaScript Frontend** ```javascript // contabilita-avanzata.js class ContabilitaAvanzata { constructor() { this.inizializzaForm(); this.bindEvents(); } inizializzaForm() { // Inizializzazione form e validazioni this.calcolaTotali(); this.verificaQuadratura(); } aggiungiRiga() { // Aggiunge una nuova riga alla tabella movimenti const nuovaRiga = this.creaNuovaRigaTemplate(); $('#righe-contabili-table tbody').append(nuovaRiga); this.bindEventsRiga(); } calcolaTotali() { let totaleDare = 0; let totaleAvere = 0; $('.importo-dare').each(function() { totaleDare += parseFloat($(this).val()) || 0; }); $('.importo-avere').each(function() { totaleAvere += parseFloat($(this).val()) || 0; }); $('#totale-dare').text(totaleDare.toFixed(2)); $('#totale-avere').text(totaleAvere.toFixed(2)); this.verificaQuadratura(totaleDare, totaleAvere); } verificaQuadratura(dare, avere) { const differenza = Math.abs(dare - avere); const status = $('#quadratura-status'); if (differenza < 0.01) { status.removeClass('badge-warning badge-danger') .addClass('badge-success') .text('โœ… Bilanciato'); } else { status.removeClass('badge-success badge-danger') .addClass('badge-warning') .text(`โš ๏ธ Differenza: ${differenza.toFixed(2)}`); } } calcolaRipartizione() { // Calcola la ripartizione automatica tra gestioni const formData = new FormData($('#registrazione-contabile-form')[0]); $.post('/api/calcola-ripartizione', formData) .done(function(response) { // Aggiorna la UI con i risultati this.aggiornaRipartizione(response.ripartizioni); }.bind(this)); } salvaRegistrazione() { if (!this.validaForm()) return; const formData = new FormData($('#registrazione-contabile-form')[0]); $.post('/api/registrazioni-contabili', formData) .done(function(response) { Swal.fire('Successo!', 'Registrazione salvata correttamente', 'success'); window.location.href = '/admin/contabilita'; }) .fail(function(xhr) { Swal.fire('Errore!', xhr.responseJSON.error, 'error'); }); } } // Inizializzazione $(document).ready(function() { new ContabilitaAvanzata(); }); ``` --- ## ๐Ÿ“‹ **CHECKLIST IMPLEMENTAZIONE** ### โœ… **Database** - [ ] Eseguire migration gestioni multiple - [ ] Aggiornare tabelle esistenti - [ ] Creare nuove tabelle ripartizioni - [ ] Implementare trigger calcolo saldi ### โœ… **Backend Laravel** - [ ] Aggiornare Models esistenti - [ ] Creare ContabilitaAvanzataController - [ ] Implementare API per calcoli - [ ] Creare Service per chiusura/riapertura ### โœ… **Frontend** - [ ] Creare form registrazione avanzato - [ ] Implementare JavaScript calcoli - [ ] Integrare con sistema esistente - [ ] Test interfaccia utente ### โœ… **Integrazione** - [ ] Collegare con sistema esistente stabili - [ ] Implementare ripartizione millesimale - [ ] Test con dati reali - [ ] Validazione chiusura/riapertura --- ## ๐ŸŽฏ **PROSSIMI PASSI** 1. **๐Ÿ“ค TRASFERIMENTO DOCUMENTAZIONE**: Copia questo file sulla VM 2. **๐Ÿ’พ IMPLEMENTAZIONE DATABASE**: Eseguire le migration 3. **๐ŸŽจ SVILUPPO INTERFACCIA**: Creare le schermate 4. **๐Ÿ”„ INTEGRAZIONE**: Collegare con sistema esistente 5. **๐Ÿ“Š TEST**: Validare con dati reali Questa documentazione fornisce tutte le specifiche per implementare il sistema contabile avanzato con gestioni multiple e partita doppia classica! ๐Ÿš€๐Ÿ’ฐ