netgescon-master/app/Models/StrutturaFisicaDettaglio.php
2025-07-20 14:57:25 +00:00

190 lines
4.2 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class StrutturaFisicaDettaglio extends Model
{
use HasFactory;
protected $table = 'struttura_fisica_dettaglio';
protected $primaryKey = 'id';
protected $fillable = [
'stabile_id',
'tipo',
'codice',
'nome',
'descrizione',
'parent_id',
'dati_aggiuntivi',
'stato',
];
protected $casts = [
'dati_aggiuntivi' => 'array',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
// ================================
// RELAZIONI
// ================================
/**
* Stabile di appartenenza
*/
public function stabile()
{
return $this->belongsTo(Stabile::class, 'stabile_id');
}
/**
* Elemento padre (palazzina per scale, scala per piani)
*/
public function parent()
{
return $this->belongsTo(self::class, 'parent_id');
}
/**
* Elementi figli (scale per palazzina, piani per scala)
*/
public function children()
{
return $this->hasMany(self::class, 'parent_id');
}
// ================================
// SCOPE
// ================================
/**
* Filtra per tipo di struttura
*/
public function scopeTipo($query, string $tipo)
{
return $query->where('tipo', $tipo);
}
/**
* Solo elementi di primo livello (palazzine)
*/
public function scopeRoot($query)
{
return $query->whereNull('parent_id');
}
/**
* Solo elementi attivi
*/
public function scopeAttivi($query)
{
return $query->where('stato', 'attivo');
}
// ================================
// ACCESSORS & MUTATORS
// ================================
/**
* Badge tipo struttura
*/
public function getTipoBadgeAttribute(): string
{
return match($this->tipo) {
'palazzina' => 'bg-primary',
'scala' => 'bg-info',
'piano' => 'bg-success',
'locale' => 'bg-warning',
default => 'bg-secondary'
};
}
/**
* Icona tipo struttura
*/
public function getTipoIconaAttribute(): string
{
return match($this->tipo) {
'palazzina' => 'fas fa-building',
'scala' => 'fas fa-stairs',
'piano' => 'fas fa-layer-group',
'locale' => 'fas fa-door-open',
default => 'fas fa-cube'
};
}
/**
* Path completo gerarchico
*/
public function getPathCompletoAttribute(): string
{
$path = [$this->nome];
$parent = $this->parent;
while ($parent) {
array_unshift($path, $parent->nome);
$parent = $parent->parent;
}
return implode(' > ', $path);
}
// ================================
// METODI STATICI
// ================================
/**
* Costruisci albero gerarchico per stabile
*/
public static function alberoStabile(int $stabileId): array
{
$strutture = self::where('stabile_id', $stabileId)
->orderBy('tipo')
->orderBy('codice')
->get();
return self::buildTree($strutture);
}
/**
* Costruisce struttura ad albero
*/
private static function buildTree($elements, $parentId = null): array
{
$branch = [];
foreach ($elements as $element) {
if ($element->parent_id == $parentId) {
$children = self::buildTree($elements, $element->id);
if ($children) {
$element->children = $children;
}
$branch[] = $element;
}
}
return $branch;
}
// ================================
// COSTANTI
// ================================
const TIPI_STRUTTURA = [
'palazzina' => 'Palazzina',
'scala' => 'Scala',
'piano' => 'Piano',
'locale' => 'Locale Tecnico',
];
const STATI = [
'attivo' => 'Attivo',
'inattivo' => 'Inattivo',
'manutenzione' => 'In Manutenzione',
];
}