'datetime', 'numero_duplicati' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime' ]; /** * Tipologie chiavi disponibili */ public const TIPOLOGIE = [ 'portone_principale' => 'Portone Principale', 'porte_secondarie' => 'Porte Secondarie', 'locali_tecnici' => 'Locali Tecnici', 'spazi_comuni' => 'Spazi Comuni', 'servizi' => 'Servizi', 'emergenza' => 'Emergenza' ]; /** * Stati chiave disponibili */ public const STATI = [ 'attiva' => 'Attiva', 'smarrita' => 'Smarrita', 'sostituita' => 'Sostituita', 'fuori_uso' => 'Fuori Uso' ]; /** * Relazione con Stabile */ public function stabile() { return $this->belongsTo(Stabile::class, 'stabile_id'); } /** * Relazione con MovimentiChiavi */ public function movimenti() { return $this->hasMany(MovimentoChiave::class, 'chiave_id'); } /** * Accessor per QR Code Image */ public function getQrCodeImageAttribute() { return QrCode::size(200)->generate($this->qr_code_data); } /** * Accessor per tipologia descrizione */ public function getTipologiaDescrizioneAttribute() { return self::TIPOLOGIE[$this->tipologia] ?? $this->tipologia; } /** * Accessor per stato descrizione */ public function getStatoDescrizioneAttribute() { return self::STATI[$this->stato] ?? $this->stato; } /** * Accessor per stato badge class */ public function getStatoBadgeClassAttribute() { return match($this->stato) { 'attiva' => 'bg-success', 'smarrita' => 'bg-danger', 'sostituita' => 'bg-warning', 'fuori_uso' => 'bg-secondary', default => 'bg-secondary' }; } /** * Scope per chiavi attive */ public function scopeAttive($query) { return $query->where('stato', 'attiva'); } /** * Scope per tipologia */ public function scopePerTipologia($query, $tipologia) { return $query->where('tipologia', $tipologia); } /** * Genera un nuovo codice chiave univoco */ public static function generaCodiceChiave(Stabile $stabile) { $prefisso = 'CH-' . $stabile->id . '-'; $numero = 1; do { $codice = $prefisso . str_pad($numero, 4, '0', STR_PAD_LEFT); $exists = self::where('codice_chiave', $codice)->exists(); $numero++; } while ($exists); return $codice; } /** * Genera dati QR Code per la chiave */ public function generaQrCodeData() { $data = [ 'stabile_id' => $this->stabile_id, 'chiave_id' => $this->id, 'codice' => $this->codice_chiave, 'tipologia' => $this->tipologia, 'timestamp' => now()->timestamp, 'hash' => md5($this->codice_chiave . $this->stabile_id . config('app.key')) ]; return json_encode($data); } /** * Registra un movimento della chiave */ public function registraMovimento($tipo, $assegnataA = null, $assegnataDa = null, $motivo = null, $note = null) { return $this->movimenti()->create([ 'tipo_movimento' => $tipo, 'assegnata_a' => $assegnataA, 'assegnata_da' => $assegnataDa, 'motivo' => $motivo, 'note' => $note, 'data_movimento' => now() ]); } /** * Boot method per eventi model */ protected static function boot() { parent::boot(); static::creating(function ($chiave) { if (empty($chiave->codice_chiave)) { $chiave->codice_chiave = self::generaCodiceChiave($chiave->stabile); } if (empty($chiave->qr_code_data)) { $chiave->qr_code_data = $chiave->generaQrCodeData(); } }); static::created(function ($chiave) { // Registra movimento di creazione $chiave->registraMovimento('assegnazione', null, auth()->user()->name ?? 'Sistema', 'Creazione chiave'); }); } }