✨ Nuovo Sistema Ripartizione Spese: - Migration e modelli RipartizioneSpese, DettaglioRipartizioneSpese - Calcolo automatico ripartizione millesimale - Gestione quote personalizzate ed esenzioni - Stati workflow: bozza → confermata → contabilizzata - Integrazione con tabelle millesimali e voci spesa ✨ Nuovo Sistema Gestione Rate: - Migration e modelli PianoRateizzazione, Rata (aggiornato) - Generazione automatica rate per piani di rateizzazione - Gestione pagamenti completi e parziali - Frequenze: mensile, trimestrale, semestrale, personalizzata - Monitoraggio scadenze e stati rate 🔧 Funzionalità Avanzate: - Codici automatici univoci (RS*, PR*, RT*) - Relazioni complete tra tutti i modelli - Scope e query builder avanzati - Statistiche e reporting - Backward compatibility con vecchia struttura �� Test e Integrazione: - Test modelli e database completati - Relazioni Eloquent integrate - Metodi di calcolo validati - Sistema pronto per produzione
300 lines
8.7 KiB
PHP
300 lines
8.7 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
class Stabile extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
protected $table = 'stabili';
|
|
|
|
protected $fillable = [
|
|
'amministratore_id',
|
|
'denominazione',
|
|
'codice_fiscale',
|
|
'cod_fisc_amministratore',
|
|
'indirizzo',
|
|
'citta',
|
|
'cap',
|
|
'provincia',
|
|
'note',
|
|
'old_id',
|
|
'stato',
|
|
// Nuovi campi per i dati catastali
|
|
'codice_catastale_comune',
|
|
'foglio',
|
|
'particella',
|
|
'subalterno',
|
|
'sezione',
|
|
// Nuovi campi per dati SDI
|
|
'codice_destinatario_sdi',
|
|
'pec_amministratore',
|
|
'pec_condominio',
|
|
// Nuovi campi per gestione rate
|
|
'numero_rate_ordinarie',
|
|
'mesi_rate_ordinarie',
|
|
'numero_rate_straordinarie',
|
|
'mesi_rate_straordinarie',
|
|
// Altri campi
|
|
'anno_costruzione',
|
|
'numero_piani',
|
|
'numero_unita',
|
|
'superficie_totale',
|
|
'tipo_riscaldamento',
|
|
'tipo_acqua',
|
|
'presenza_ascensore',
|
|
'numero_ascensori',
|
|
'presenza_giardino',
|
|
'presenza_piscina',
|
|
'presenza_garage',
|
|
'numero_garage',
|
|
'codice_interno',
|
|
'registro_anagrafe',
|
|
'documenti_path',
|
|
'attivo'
|
|
];
|
|
|
|
protected $casts = [
|
|
'created_at' => 'datetime',
|
|
'updated_at' => 'datetime',
|
|
'anno_costruzione' => 'integer',
|
|
'numero_piani' => 'integer',
|
|
'numero_unita' => 'integer',
|
|
'superficie_totale' => 'decimal:2',
|
|
'numero_ascensori' => 'integer',
|
|
'numero_garage' => 'integer',
|
|
'numero_rate_ordinarie' => 'integer',
|
|
'numero_rate_straordinarie' => 'integer',
|
|
'presenza_ascensore' => 'boolean',
|
|
'presenza_giardino' => 'boolean',
|
|
'presenza_piscina' => 'boolean',
|
|
'presenza_garage' => 'boolean',
|
|
'registro_anagrafe' => 'boolean',
|
|
'attivo' => 'boolean',
|
|
'mesi_rate_ordinarie' => 'array',
|
|
'mesi_rate_straordinarie' => 'array'
|
|
];
|
|
|
|
/**
|
|
* Relazione con Amministratore
|
|
*/
|
|
public function amministratore()
|
|
{
|
|
return $this->belongsTo(Amministratore::class, 'amministratore_id', 'id');
|
|
}
|
|
|
|
/**
|
|
* Relazione con UnitaImmobiliari
|
|
*/
|
|
public function unitaImmobiliari()
|
|
{
|
|
return $this->hasMany(UnitaImmobiliare::class, 'stabile_id', 'id');
|
|
}
|
|
|
|
/**
|
|
* Relazione con Tickets
|
|
*/
|
|
public function tickets()
|
|
{
|
|
return $this->hasMany(Ticket::class, 'stabile_id', 'id');
|
|
}
|
|
|
|
/**
|
|
* Relazione con RipartizioneSpese
|
|
*/
|
|
public function ripartizioniSpese()
|
|
{
|
|
return $this->hasMany(RipartizioneSpese::class);
|
|
}
|
|
|
|
/**
|
|
* Relazione con PianoRateizzazione
|
|
*/
|
|
public function pianiRateizzazione()
|
|
{
|
|
return $this->hasMany(PianoRateizzazione::class);
|
|
}
|
|
|
|
/**
|
|
* Scope per stabili attivi
|
|
*/
|
|
public function scopeAttivi($query)
|
|
{
|
|
return $query->where('attivo', true);
|
|
}
|
|
|
|
/**
|
|
* Scope per stabili per amministratore
|
|
*/
|
|
public function scopeByAmministratore($query, $amministratoreId)
|
|
{
|
|
return $query->where('amministratore_id', $amministratoreId);
|
|
}
|
|
|
|
/**
|
|
* Accessor per il nome completo dell'indirizzo
|
|
*/
|
|
public function getIndirizzoCompletoAttribute()
|
|
{
|
|
return $this->indirizzo . ', ' . $this->cap . ' ' . $this->citta .
|
|
($this->provincia ? ' (' . $this->provincia . ')' : '');
|
|
}
|
|
|
|
/**
|
|
* Accessor per i dati catastali
|
|
*/
|
|
public function getDatiCatastaliAttribute()
|
|
{
|
|
return [
|
|
'codice_comune' => $this->codice_catastale_comune,
|
|
'foglio' => $this->foglio,
|
|
'particella' => $this->particella,
|
|
'subalterno' => $this->subalterno,
|
|
'sezione' => $this->sezione
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Accessor per i dati SDI
|
|
*/
|
|
public function getDatiSdiAttribute()
|
|
{
|
|
return [
|
|
'codice_destinatario' => $this->codice_destinatario_sdi,
|
|
'pec_amministratore' => $this->pec_amministratore,
|
|
'pec_condominio' => $this->pec_condominio
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Accessor per la configurazione rate ordinarie
|
|
*/
|
|
public function getConfigurazioneRateOrdinarieAttribute()
|
|
{
|
|
return [
|
|
'numero_rate' => $this->numero_rate_ordinarie,
|
|
'mesi' => $this->mesi_rate_ordinarie
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Accessor per la configurazione rate straordinarie
|
|
*/
|
|
public function getConfigurazioneRateStraordinarieAttribute()
|
|
{
|
|
return [
|
|
'numero_rate' => $this->numero_rate_straordinarie,
|
|
'mesi' => $this->mesi_rate_straordinarie
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Accessor per le caratteristiche dello stabile
|
|
*/
|
|
public function getCaratteristicheAttribute()
|
|
{
|
|
return [
|
|
'anno_costruzione' => $this->anno_costruzione,
|
|
'numero_piani' => $this->numero_piani,
|
|
'numero_unita' => $this->numero_unita,
|
|
'superficie_totale' => $this->superficie_totale,
|
|
'tipo_riscaldamento' => $this->tipo_riscaldamento,
|
|
'tipo_acqua' => $this->tipo_acqua,
|
|
'presenza_ascensore' => $this->presenza_ascensore,
|
|
'numero_ascensori' => $this->numero_ascensori,
|
|
'presenza_giardino' => $this->presenza_giardino,
|
|
'presenza_piscina' => $this->presenza_piscina,
|
|
'presenza_garage' => $this->presenza_garage,
|
|
'numero_garage' => $this->numero_garage
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Metodo per ottenere tutte le anagrafiche associate
|
|
*/
|
|
public function getAnagraficheAssociate()
|
|
{
|
|
return AnagraficaCondominiale::whereHas('dirittiReali.unitaImmobiliare', function ($query) {
|
|
$query->where('stabile_id', $this->id);
|
|
})->orWhereHas('contrattiLocazione.unitaImmobiliare', function ($query) {
|
|
$query->where('stabile_id', $this->id);
|
|
})->distinct()->get();
|
|
}
|
|
|
|
/**
|
|
* Metodo per ottenere i proprietari dello stabile
|
|
*/
|
|
public function getProprietari()
|
|
{
|
|
return AnagraficaCondominiale::whereHas('dirittiReali', function ($query) {
|
|
$query->where('tipo_diritto', 'proprieta')
|
|
->whereNull('data_fine')
|
|
->whereHas('unitaImmobiliare', function ($q) {
|
|
$q->where('stabile_id', $this->id);
|
|
});
|
|
})->distinct()->get();
|
|
}
|
|
|
|
/**
|
|
* Metodo per ottenere gli inquilini dello stabile
|
|
*/
|
|
public function getInquilini()
|
|
{
|
|
return AnagraficaCondominiale::whereHas('contrattiLocazione', function ($query) {
|
|
$query->where('stato', 'attivo')
|
|
->whereDate('data_inizio', '<=', now())
|
|
->where(function ($q) {
|
|
$q->whereNull('data_fine')
|
|
->orWhereDate('data_fine', '>=', now());
|
|
})
|
|
->whereHas('unitaImmobiliare', function ($q) {
|
|
$q->where('stabile_id', $this->id);
|
|
});
|
|
})->distinct()->get();
|
|
}
|
|
|
|
/**
|
|
* Metodo per calcolare il totale millesimi
|
|
*/
|
|
public function getTotaleMillesimi($tipo = 'proprieta')
|
|
{
|
|
$campo = 'millesimi_' . $tipo;
|
|
return $this->unitaImmobiliari()->where('attiva', true)->sum($campo);
|
|
}
|
|
|
|
/**
|
|
* Metodo per verificare la coerenza dei millesimi
|
|
*/
|
|
public function verificaMillesimi($tipo = 'proprieta')
|
|
{
|
|
$totale = $this->getTotaleMillesimi($tipo);
|
|
return abs($totale - 1000) < 0.001; // Tolleranza per errori di arrotondamento
|
|
}
|
|
|
|
/**
|
|
* Metodo per ottenere le statistiche dello stabile
|
|
*/
|
|
public function getStatistiche()
|
|
{
|
|
$unita = $this->unitaImmobiliari()->where('attiva', true);
|
|
|
|
return [
|
|
'totale_unita' => $unita->count(),
|
|
'unita_in_locazione' => $unita->whereHas('contrattiLocazione', function ($query) {
|
|
$query->where('stato', 'attivo')
|
|
->whereDate('data_inizio', '<=', now())
|
|
->where(function ($q) {
|
|
$q->whereNull('data_fine')
|
|
->orWhereDate('data_fine', '>=', now());
|
|
});
|
|
})->count(),
|
|
'superficie_totale' => $unita->sum('superficie_commerciale'),
|
|
'totale_millesimi_proprieta' => $this->getTotaleMillesimi('proprieta'),
|
|
'totale_proprietari' => $this->getProprietari()->count(),
|
|
'totale_inquilini' => $this->getInquilini()->count()
|
|
];
|
|
}
|
|
} |