'date', 'data_chiusura' => 'date', 'budget_previsto' => 'decimal:2', 'fondo_cassa_iniziale' => 'decimal:2', 'regole_ripartizione' => 'json', ]; protected static function boot() { parent::boot(); static::creating(function ($model) { if (!$model->codice_gestione) { $model->codice_gestione = static::generateCodiceGestione(); } }); } /** * Genera un codice univoco per la gestione */ public static function generateCodiceGestione(): string { do { $codice = 'GES' . sprintf('%05d', rand(10000, 99999)); } while (static::where('codice_gestione', $codice)->exists()); return $codice; } /** * Relazioni */ public function stabile(): BelongsTo { return $this->belongsTo(Stabile::class); } public function esercizioContabile(): BelongsTo { return $this->belongsTo(EsercizioContabile::class, 'esercizio_contabile_id'); } public function tabellaMillesimale(): BelongsTo { return $this->belongsTo(TabellaMillesimale::class, 'tabella_millesimale_id'); } public function movimenti(): HasMany { return $this->hasMany(MovimentoPartitaDoppia::class, 'gestione_contabile_id'); } public function rate(): HasMany { return $this->hasMany(RataCondominiale::class, 'gestione_contabile_id'); } /** * Scopes */ public function scopeAttive($query) { return $query->where('stato', 'attiva'); } public function scopeByTipologia($query, $tipologia) { return $query->where('tipologia', $tipologia); } /** * Metodi di business logic */ public function calcolaTotaleMovimenti($tipo = null): float { $query = $this->movimenti()->where('stato_movimento', '!=', 'bozza'); if ($tipo) { // Implementare logica per tipo entrata/uscita basata su dare/avere } return $query->sum('importo_netto'); } public function calcolaSaldoContabile(): float { // Implementare calcolo saldo basato su partita doppia $entrate = $this->movimenti() ->whereHas('righeContabili', function($q) { $q->where('dare_avere', 'avere'); }) ->sum('importo_netto'); $uscite = $this->movimenti() ->whereHas('righeContabili', function($q) { $q->where('dare_avere', 'dare'); }) ->sum('importo_netto'); return $entrate - $uscite; } public function getTotaleRateAttribute(): float { return $this->rate()->sum('importo_dovuto'); } public function getTotaleIncassatoAttribute(): float { return $this->rate()->sum('importo_pagato'); } public function getPercentualeIncassoAttribute(): float { $totale = $this->getTotaleRateAttribute(); if ($totale == 0) return 0; return ($this->getTotaleIncassatoAttribute() / $totale) * 100; } /** * Verifica se la gestione รจ chiudibile */ public function isChiudibile(): bool { // Verifica che tutti i movimenti siano confermati $movimentiNonConfermati = $this->movimenti() ->whereIn('stato_movimento', ['bozza', 'da_verificare']) ->count(); return $movimentiNonConfermati === 0; } /** * Chiude la gestione */ public function chiudiGestione(): bool { if (!$this->isChiudibile()) { return false; } $this->update([ 'stato' => 'chiusa', 'data_chiusura' => now(), ]); return true; } }