193 lines
5.1 KiB
PHP
193 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
|
|
class TabellaMillesimale extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
protected $table = 'tabelle_millesimali';
|
|
|
|
protected $fillable = [
|
|
'stabile_id',
|
|
'nome_tabella_millesimale',
|
|
'descrizione',
|
|
'tipo',
|
|
'attiva',
|
|
'data_approvazione',
|
|
'ordinamento',
|
|
];
|
|
|
|
protected $casts = [
|
|
'attiva' => 'boolean',
|
|
'data_approvazione' => 'date',
|
|
'ordinamento' => 'integer',
|
|
'created_at' => 'datetime',
|
|
'updated_at' => 'datetime',
|
|
];
|
|
|
|
/**
|
|
* Relazione con Stabile
|
|
*/
|
|
public function stabile()
|
|
{
|
|
return $this->belongsTo(Stabile::class, 'stabile_id', 'id');
|
|
}
|
|
|
|
/**
|
|
* Relazione con Dettagli Millesimi
|
|
*/
|
|
public function dettagli()
|
|
{
|
|
return $this->hasMany(DettaglioTabellaMillesimale::class, 'tabella_millesimale_id');
|
|
}
|
|
|
|
/**
|
|
* Relazione con RipartizioneSpese
|
|
*/
|
|
public function ripartizioniSpese()
|
|
{
|
|
return $this->hasMany(RipartizioneSpese::class);
|
|
}
|
|
|
|
/**
|
|
* Scope per tabelle attive
|
|
*/
|
|
public function scopeAttive($query)
|
|
{
|
|
return $query->where('attiva', true);
|
|
}
|
|
|
|
/**
|
|
* Scope ordinato
|
|
*/
|
|
public function scopeOrdinato($query)
|
|
{
|
|
return $query->orderBy('ordinamento')->orderBy('nome_tabella_millesimale');
|
|
}
|
|
|
|
/**
|
|
* Calcola il totale millesimi
|
|
*/
|
|
public function getTotaleMillesimiAttribute()
|
|
{
|
|
return $this->dettagli()->sum('millesimi');
|
|
}
|
|
|
|
/**
|
|
* Verifica se la tabella è bilanciata (totale = 1000)
|
|
*/
|
|
public function getIsBilanciataAttribute()
|
|
{
|
|
$totale = $this->totale_millesimi;
|
|
return abs($totale - 1000) < 0.0001; // Tolleranza per errori di precisione
|
|
}
|
|
|
|
/**
|
|
* Ottieni lo sbilanciamento della tabella
|
|
*/
|
|
public function getSbilanciamentoAttribute()
|
|
{
|
|
return $this->totale_millesimi - 1000;
|
|
}
|
|
|
|
/**
|
|
* Conta le unità immobiliari con millesimi assegnati
|
|
*/
|
|
public function getUnitaAssegnateAttribute()
|
|
{
|
|
return $this->dettagli()->count();
|
|
}
|
|
|
|
/**
|
|
* Accessor per riassunto tabella
|
|
*/
|
|
public function getRiassuntoAttribute()
|
|
{
|
|
return [
|
|
'nome' => $this->nome_tabella_millesimale,
|
|
'stabile' => $this->stabile->denominazione ?? 'N/A',
|
|
'unita_assegnate' => $this->unita_assegnate,
|
|
'totale_millesimi' => $this->totale_millesimi,
|
|
'is_bilanciata' => $this->is_bilanciata,
|
|
'sbilanciamento' => $this->sbilanciamento
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Metodo per assegnare millesimi a un'unità immobiliare
|
|
*/
|
|
public function assegnaMillesimi($unitaImmobiliareId, $millesimi)
|
|
{
|
|
return DettaglioTabellaMillesimale::updateOrCreate(
|
|
[
|
|
'tabella_millesimale_id' => $this->id,
|
|
'unita_immobiliare_id' => $unitaImmobiliareId
|
|
],
|
|
[
|
|
'millesimi' => $millesimi
|
|
]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Metodo per bilanciare automaticamente la tabella
|
|
*/
|
|
public function bilancia()
|
|
{
|
|
$dettagli = $this->dettagli;
|
|
$totaleCorrente = $dettagli->sum('millesimi');
|
|
|
|
if ($totaleCorrente == 0) {
|
|
throw new \InvalidArgumentException('Impossibile bilanciare una tabella senza millesimi assegnati');
|
|
}
|
|
|
|
$fattoreCorrezione = 1000 / $totaleCorrente;
|
|
|
|
foreach ($dettagli as $dettaglio) {
|
|
$nuoviMillesimi = round($dettaglio->millesimi * $fattoreCorrezione, 4);
|
|
$dettaglio->update(['millesimi' => $nuoviMillesimi]);
|
|
}
|
|
|
|
return $this->fresh();
|
|
}
|
|
|
|
/**
|
|
* Ottieni tutte le tipologie standard di tabelle millesimali
|
|
*/
|
|
public static function getTipologieStandard()
|
|
{
|
|
return [
|
|
'proprieta_generale' => 'Proprietà Generale',
|
|
'scale' => 'Scale',
|
|
'ascensore' => 'Ascensore',
|
|
'riscaldamento' => 'Riscaldamento',
|
|
'acqua_calda' => 'Acqua Calda Sanitaria',
|
|
'condizionamento' => 'Condizionamento',
|
|
'garage' => 'Garage/Autorimesse',
|
|
'giardino' => 'Giardino',
|
|
'piscina' => 'Piscina',
|
|
'personalizzata' => 'Personalizzata'
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Metodo per creare ripartizione spese automatica
|
|
*/
|
|
public function creaRipartizioneSpese($voceSpesaId, $importoTotale, $dataRipartizione = null)
|
|
{
|
|
return RipartizioneSpese::create([
|
|
'voce_spesa_id' => $voceSpesaId,
|
|
'stabile_id' => $this->id,
|
|
'tabella_millesimale_id' => $this->tabelleMillesimali()->where('tipo', 'generale')->first()?->id,
|
|
'tipo_ripartizione' => 'millesimale',
|
|
'importo_totale' => $importoTotale,
|
|
'data_ripartizione' => $dataRipartizione ?? now(),
|
|
'stato' => 'bozza',
|
|
'creato_da' => auth()->id() ?? 1
|
|
]);
|
|
}
|
|
} |