289 lines
7.7 KiB
PHP
289 lines
7.7 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
|
|
class TabellaMillesimale extends Model
|
|
{
|
|
use HasFactory, SoftDeletes;
|
|
|
|
protected $table = 'tabelle_millesimali';
|
|
|
|
protected $fillable = [
|
|
'stabile_id',
|
|
'nome_tabella', // Campo effettivo nel database
|
|
'codice_tabella', // TAB.A, TAB.B, TAB.C, etc.
|
|
'nome_tabella_millesimale', // Mantengo per compatibilità
|
|
'denominazione', // Spese Generali, Spese Scale, etc.
|
|
'descrizione',
|
|
'tipo', // Mantengo per compatibilità
|
|
'tipo_tabella', // 'generali', 'scale', 'riscaldamento', 'ascensore', 'altro'
|
|
'tipo_calcolo', // 'millesimi', 'parti', 'fisso'
|
|
'totale_millesimi',
|
|
'attiva', // Mantengo per compatibilità
|
|
'stato_tabella', // 'attiva', 'sospesa', 'archiviata'
|
|
'data_approvazione',
|
|
'data_decorrenza',
|
|
'ordinamento',
|
|
'note',
|
|
'creato_da',
|
|
'modificato_da'
|
|
];
|
|
|
|
protected $casts = [
|
|
'attiva' => 'boolean',
|
|
'totale_millesimi' => 'decimal:4',
|
|
'data_approvazione' => 'date',
|
|
'data_decorrenza' => 'date',
|
|
'ordinamento' => 'integer',
|
|
'created_at' => 'datetime',
|
|
'updated_at' => 'datetime',
|
|
'deleted_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(DettaglioMillesimale::class, 'tabella_id');
|
|
}
|
|
|
|
/**
|
|
* Relazione con dettagli millesimali per unità (nuovo nome)
|
|
*/
|
|
public function dettagliMillesimali()
|
|
{
|
|
return $this->hasMany(DettaglioMillesimale::class, 'tabella_id');
|
|
}
|
|
|
|
/**
|
|
* Relazione con utente che ha creato
|
|
*/
|
|
public function createBy()
|
|
{
|
|
return $this->belongsTo(User::class, 'creato_da');
|
|
}
|
|
|
|
/**
|
|
* Relazione con utente che ha modificato
|
|
*/
|
|
public function updatedBy()
|
|
{
|
|
return $this->belongsTo(User::class, 'modificato_da');
|
|
}
|
|
|
|
/**
|
|
* Relazione con RipartizioneSpese
|
|
*/
|
|
public function ripartizioniSpese()
|
|
{
|
|
return $this->hasMany(RipartizioneSpese::class);
|
|
}
|
|
|
|
/**
|
|
* Scope per tabelle attive
|
|
*/
|
|
public function scopeAttive($query)
|
|
{
|
|
return $query->where('attiva', true)
|
|
->orWhere('stato_tabella', 'attiva');
|
|
}
|
|
|
|
/**
|
|
* Scope per tipo tabella
|
|
*/
|
|
public function scopeTipo($query, $tipo)
|
|
{
|
|
return $query->where('tipo_tabella', $tipo)
|
|
->orWhere('tipo', $tipo);
|
|
}
|
|
|
|
/**
|
|
* Scope per stabile
|
|
*/
|
|
public function scopePerStabile($query, $stabileId)
|
|
{
|
|
return $query->where('stabile_id', $stabileId);
|
|
}
|
|
|
|
/**
|
|
* 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');
|
|
}
|
|
|
|
/**
|
|
* Calcola totale millesimi dalla somma dei dettagli
|
|
*/
|
|
public function calcolaTotaleMillesimi()
|
|
{
|
|
return $this->dettagliMillesimali()->sum('millesimi');
|
|
}
|
|
|
|
/**
|
|
* Accessor per descrizione completa
|
|
*/
|
|
public function getDescrizioneCompletaAttribute()
|
|
{
|
|
$codice = $this->codice_tabella ?: $this->nome_tabella_millesimale;
|
|
$nome = $this->denominazione ?: $this->nome_tabella_millesimale;
|
|
return "{$codice} - {$nome}";
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
}
|
|
|
|
/**
|
|
* Verifica se la tabella è bilanciata
|
|
*/
|
|
public function isBilanciata()
|
|
{
|
|
$calcolato = $this->calcolaTotaleMillesimi();
|
|
return abs($calcolato - 1000) < 0.01; // Tolleranza di 0.01
|
|
}
|
|
|
|
/**
|
|
* Ottieni tutte le unità con i loro millesimi per questa tabella
|
|
*/
|
|
public function getUnitaConMillesimi()
|
|
{
|
|
return $this->dettagliMillesimali()
|
|
->with('unitaImmobiliare')
|
|
->orderBy('millesimi', 'desc')
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
]);
|
|
}
|
|
}
|