netgescon-master/_BACKUP_OLD_netgescon-laravel_INACTIVE/app/Models/EsercizioContabile.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));
}
}