'date', 'data_inizio' => 'date', 'data_fine' => 'date', 'canone_mensile' => 'decimal:2', 'deposito_cauzionale' => 'decimal:2', 'configurazione_spese' => 'array' ]; /** * Relazione con l'unità immobiliare */ public function unitaImmobiliare() { return $this->belongsTo(UnitaImmobiliare::class); } /** * Relazione con l'anagrafica condominiale (conduttore/inquilino) */ public function conduttore() { return $this->belongsTo(AnagraficaCondominiale::class, 'conduttore_id'); } /** * Relazione con l'anagrafica condominiale (locatore) */ public function locatore() { return $this->belongsTo(AnagraficaCondominiale::class, 'locatore_id'); } /** * Alias per l'inquilino */ public function inquilino() { return $this->conduttore(); } /** * Alias legacy */ public function anagraficaCondominiale() { return $this->conduttore(); } /** * Scope per contratti attivi */ public function scopeAttivi($query) { return $query->where('stato', 'attivo'); } /** * Scope per contratti in corso */ public function scopeInCorso($query) { return $query->where('stato', 'attivo') ->whereDate('data_inizio', '<=', now()) ->where(function ($q) { $q->whereNull('data_fine') ->orWhereDate('data_fine', '>=', now()); }); } /** * Scope per contratti scaduti */ public function scopeScaduti($query) { return $query->where('stato', 'attivo') ->whereNotNull('data_fine') ->whereDate('data_fine', '<', now()); } /** * Scope per contratti in scadenza */ public function scopeInScadenza($query, $giorni = 30) { return $query->where('stato', 'attivo') ->whereNotNull('data_fine') ->whereDate('data_fine', '>=', now()) ->whereDate('data_fine', '<=', now()->addDays($giorni)); } /** * Scope per tipo di contratto */ public function scopeByTipoContratto($query, $tipo) { return $query->where('tipo_contratto', $tipo); } /** * Scope per unità immobiliare */ public function scopeByUnitaImmobiliare($query, $unitaId) { return $query->where('unita_immobiliare_id', $unitaId); } /** * Scope per inquilino */ public function scopeByInquilino($query, $anagraficaId) { return $query->where('anagrafica_condominiale_id', $anagraficaId); } /** * Accessor per il tipo di contratto formattato */ public function getTipoContrattoFormattatoAttribute() { return match ($this->tipo_contratto) { 'libero_mercato' => 'Libero Mercato', 'concordato' => 'Concordato', 'transitorio' => 'Transitorio', 'studenti' => 'Studenti Universitari', 'commerciale' => 'Commerciale', 'uso_foresteria' => 'Uso Foresteria', default => ucfirst(str_replace('_', ' ', $this->tipo_contratto)) }; } /** * Accessor per lo stato formattato */ public function getStatoFormattatoAttribute() { return match ($this->stato) { 'attivo' => 'Attivo', 'scaduto' => 'Scaduto', 'risolto' => 'Risolto', 'disdetto' => 'Disdetto', 'sospeso' => 'Sospeso', default => ucfirst($this->stato) }; } /** * Accessor per la modalità di pagamento formattata */ public function getModalitaPagamentoFormattataAttribute() { return match ($this->modalita_pagamento) { 'bonifico' => 'Bonifico Bancario', 'contanti' => 'Contanti', 'assegno' => 'Assegno', 'rid' => 'RID Bancario', 'carta_credito' => 'Carta di Credito', default => ucfirst(str_replace('_', ' ', $this->modalita_pagamento)) ]; } /** * Accessor per il canone annuale */ public function getCanoneAnnualeAttribute() { return $this->canone_mensile * 12; } /** * Accessor per i dati della registrazione */ public function getDatiRegistrazioneAttribute() { return [ 'data' => $this->data_registrazione, 'numero' => $this->numero_registrazione, 'ufficio' => $this->ufficio_registrazione ]; } /** * Metodo per verificare se il contratto è in corso */ public function isInCorso() { if ($this->stato !== 'attivo') { return false; } $oggi = now()->toDateString(); if ($this->data_inizio > $oggi) { return false; // Non ancora iniziato } if ($this->data_fine && $this->data_fine < $oggi) { return false; // Già scaduto } return true; // In corso } /** * Metodo per verificare se il contratto è scaduto */ public function isScaduto() { return $this->data_fine && $this->data_fine < now()->toDateString(); } /** * Metodo per verificare se il contratto è in scadenza */ public function isInScadenza($giorni = 30) { if (!$this->data_fine) { return false; } $oggi = now(); return $this->data_fine >= $oggi->toDateString() && $this->data_fine <= $oggi->addDays($giorni)->toDateString(); } /** * Metodo per calcolare la durata del contratto */ public function getDurata() { if (!$this->data_fine) { return null; // Durata indeterminata } return $this->data_inizio->diffInDays($this->data_fine); } /** * Metodo per calcolare il canone con rivalutazione ISTAT */ public function getCanoneRivalutato($indice_attuale = null) { if (!$indice_attuale || !$this->indice_istat_base) { return $this->canone_mensile; } $coefficiente_rivalutazione = $indice_attuale / $this->indice_istat_base; return $this->canone_mensile * $coefficiente_rivalutazione; } /** * Metodo per ottenere i giorni rimanenti */ public function getGiorniRimanenti() { if (!$this->data_fine) { return null; } $oggi = now(); if ($this->data_fine < $oggi->toDateString()) { return 0; // Scaduto } return $oggi->diffInDays($this->data_fine); } /** * Metodo per calcolare l'imposta di registro annuale */ public function getImpostaRegistro() { if ($this->cedolare_secca) { return 0; // Con cedolare secca non si paga l'imposta di registro } // Calcolo standard: 2% del canone annuale return $this->canone_annuale * 0.02; } /** * Metodo per calcolare la cedolare secca annuale */ public function getCedolareSecca() { if (!$this->cedolare_secca) { return 0; } $aliquota = $this->aliquota_cedolare ?: 21; // Default 21% return $this->canone_annuale * ($aliquota / 100); } }