295 lines
6.8 KiB
PHP
295 lines
6.8 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
|
|
class EsercizioContabile extends Model
|
|
{
|
|
use HasFactory, SoftDeletes;
|
|
|
|
protected $table = 'esercizi_contabili';
|
|
|
|
protected $fillable = [
|
|
'stabile_id',
|
|
'descrizione',
|
|
'anno',
|
|
'data_inizio',
|
|
'data_fine',
|
|
'tipologia',
|
|
'descrizione_straordinaria',
|
|
'ordine_sequenza',
|
|
'stato',
|
|
'chiusa_contabilita',
|
|
'data_limite_bilancio',
|
|
'approvato_assemblea',
|
|
'data_approvazione',
|
|
'assemblea_id',
|
|
'esercizio_precedente_id',
|
|
];
|
|
|
|
protected $casts = [
|
|
'data_inizio' => 'date',
|
|
'data_fine' => 'date',
|
|
'data_limite_bilancio' => 'date',
|
|
'data_approvazione' => 'date',
|
|
'chiusa_contabilita' => 'boolean',
|
|
'approvato_assemblea' => 'boolean',
|
|
'anno' => 'integer',
|
|
'ordine_sequenza' => 'integer',
|
|
];
|
|
|
|
protected $dates = [
|
|
'data_inizio',
|
|
'data_fine',
|
|
'data_limite_bilancio',
|
|
'data_approvazione',
|
|
'deleted_at',
|
|
];
|
|
|
|
// === RELATIONSHIPS ===
|
|
|
|
/**
|
|
* Stabile di appartenenza
|
|
*/
|
|
public function stabile(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Stabile::class);
|
|
}
|
|
|
|
/**
|
|
* Esercizio precedente
|
|
*/
|
|
public function esercizio_precedente(): BelongsTo
|
|
{
|
|
return $this->belongsTo(EsercizioContabile::class, 'esercizio_precedente_id');
|
|
}
|
|
|
|
/**
|
|
* Esercizio successivo
|
|
*/
|
|
public function esercizio_successivo()
|
|
{
|
|
return $this->hasOne(EsercizioContabile::class, 'esercizio_precedente_id');
|
|
}
|
|
|
|
/**
|
|
* Assemblea di approvazione
|
|
*/
|
|
public function assemblea(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Assemblea::class);
|
|
}
|
|
|
|
/**
|
|
* Movimenti contabili dell'esercizio
|
|
*/
|
|
public function movimenti(): HasMany
|
|
{
|
|
return $this->hasMany(MovimentoContabile::class, 'esercizio_id');
|
|
}
|
|
|
|
/**
|
|
* Bilanci dell'esercizio
|
|
*/
|
|
public function bilanci(): HasMany
|
|
{
|
|
return $this->hasMany(Bilancio::class, 'esercizio_id');
|
|
}
|
|
|
|
// === ACCESSORS ===
|
|
|
|
/**
|
|
* Nome completo dell'esercizio
|
|
*/
|
|
public function getNomeCompletoAttribute(): string
|
|
{
|
|
$tipologia = ucfirst($this->tipologia);
|
|
$nome = "{$tipologia} {$this->anno}";
|
|
|
|
if ($this->tipologia === 'straordinaria' && $this->descrizione_straordinaria) {
|
|
$nome .= " - " . $this->descrizione_straordinaria;
|
|
}
|
|
|
|
return $nome;
|
|
}
|
|
|
|
/**
|
|
* Verifica se l'esercizio è aperto
|
|
*/
|
|
public function getIsApertoAttribute(): bool
|
|
{
|
|
return $this->stato === 'aperto';
|
|
}
|
|
|
|
/**
|
|
* Verifica se l'esercizio è chiuso
|
|
*/
|
|
public function getIsChiusoAttribute(): bool
|
|
{
|
|
return $this->stato === 'chiuso';
|
|
}
|
|
|
|
/**
|
|
* Verifica se l'esercizio è consolidato
|
|
*/
|
|
public function getIsConsolidatoAttribute(): bool
|
|
{
|
|
return $this->stato === 'consolidato';
|
|
}
|
|
|
|
/**
|
|
* Colore badge per la tipologia
|
|
*/
|
|
public function getColoreBadgeAttribute(): string
|
|
{
|
|
return match($this->tipologia) {
|
|
'ordinaria' => 'primary',
|
|
'riscaldamento' => 'warning',
|
|
'straordinaria' => 'danger',
|
|
default => 'secondary'
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Icona per la tipologia
|
|
*/
|
|
public function getIconaAttribute(): string
|
|
{
|
|
return match($this->tipologia) {
|
|
'ordinaria' => 'fas fa-calendar-alt',
|
|
'riscaldamento' => 'fas fa-fire',
|
|
'straordinaria' => 'fas fa-exclamation-triangle',
|
|
default => 'fas fa-book'
|
|
};
|
|
}
|
|
|
|
// === SCOPES ===
|
|
|
|
/**
|
|
* Scope per filtrare per tipologia
|
|
*/
|
|
public function scopeByTipologia($query, string $tipologia)
|
|
{
|
|
return $query->where('tipologia', $tipologia);
|
|
}
|
|
|
|
/**
|
|
* Scope per esercizi aperti
|
|
*/
|
|
public function scopeAperti($query)
|
|
{
|
|
return $query->where('stato', 'aperto');
|
|
}
|
|
|
|
/**
|
|
* Scope per esercizi chiusi
|
|
*/
|
|
public function scopeChiusi($query)
|
|
{
|
|
return $query->where('stato', 'chiuso');
|
|
}
|
|
|
|
/**
|
|
* Scope per esercizi di uno stabile
|
|
*/
|
|
public function scopeByStabile($query, int $stabileId)
|
|
{
|
|
return $query->where('stabile_id', $stabileId);
|
|
}
|
|
|
|
/**
|
|
* Scope per esercizi per anno
|
|
*/
|
|
public function scopeByAnno($query, int $anno)
|
|
{
|
|
return $query->where('anno', $anno);
|
|
}
|
|
|
|
/**
|
|
* Scope per ordinamento sequenziale
|
|
*/
|
|
public function scopeOrdinatiSequenzialmente($query)
|
|
{
|
|
return $query->orderBy('tipologia', 'asc')
|
|
->orderBy('ordine_sequenza', 'asc')
|
|
->orderBy('anno', 'asc');
|
|
}
|
|
|
|
// === METHODS ===
|
|
|
|
/**
|
|
* Verifica se l'esercizio può essere modificato
|
|
*/
|
|
public function puoEssereModificato(): bool
|
|
{
|
|
return $this->stato === 'aperto' && !$this->chiusa_contabilita;
|
|
}
|
|
|
|
/**
|
|
* Verifica se l'esercizio può essere chiuso
|
|
*/
|
|
public function puoEssereChiuso(): bool
|
|
{
|
|
return $this->stato === 'aperto' && !$this->chiusa_contabilita;
|
|
}
|
|
|
|
/**
|
|
* Chiude l'esercizio
|
|
*/
|
|
public function chiudi(): bool
|
|
{
|
|
if (!$this->puoEssereChiuso()) {
|
|
return false;
|
|
}
|
|
|
|
$this->stato = 'chiuso';
|
|
$this->chiusa_contabilita = true;
|
|
|
|
return $this->save();
|
|
}
|
|
|
|
/**
|
|
* Consolida l'esercizio
|
|
*/
|
|
public function consolida(): bool
|
|
{
|
|
if ($this->stato !== 'chiuso') {
|
|
return false;
|
|
}
|
|
|
|
$this->stato = 'consolidato';
|
|
return $this->save();
|
|
}
|
|
|
|
/**
|
|
* Ottieni il prossimo numero di sequenza per una tipologia
|
|
*/
|
|
public static function getNextSequenza(int $stabileId, string $tipologia): int
|
|
{
|
|
return static::where('stabile_id', $stabileId)
|
|
->where('tipologia', $tipologia)
|
|
->max('ordine_sequenza') + 1;
|
|
}
|
|
|
|
/**
|
|
* Crea esercizio successivo
|
|
*/
|
|
public function creaEsercizioSuccessivo(array $attributes = []): ?EsercizioContabile
|
|
{
|
|
$defaults = [
|
|
'stabile_id' => $this->stabile_id,
|
|
'tipologia' => $this->tipologia,
|
|
'anno' => $this->anno + 1,
|
|
'ordine_sequenza' => $this->ordine_sequenza + 1,
|
|
'esercizio_precedente_id' => $this->id,
|
|
];
|
|
|
|
return static::create(array_merge($defaults, $attributes));
|
|
}
|
|
}
|