'decimal:2', 'confirmed_at' => 'datetime', ]; public const STATI = [ 'bozza' => 'Bozza', 'inviato' => 'Inviato', 'in_lavorazione' => 'In lavorazione', 'chiuso' => 'Chiuso', ]; protected static function booted(): void { static::deleting(function (Preventivo $preventivo): void { // Elimina immagini degli item (disk 'public') e PDF (disk 'local') prima della cancellazione. foreach ($preventivo->items()->get() as $item) { if ($item->immagine_path && Storage::disk('public')->exists($item->immagine_path)) { Storage::disk('public')->delete($item->immagine_path); } $item->delete(); } if ($preventivo->pdf_path && Storage::disk('local')->exists($preventivo->pdf_path)) { Storage::disk('local')->delete($preventivo->pdf_path); } }); } public function cliente(): BelongsTo { return $this->belongsTo(Cliente::class); } public function items(): HasMany { return $this->hasMany(PreventivoItem::class); } /** Ricalcola e salva il totale dagli item. */ public function ricalcolaTotale(): void { $this->totale = $this->items()->sum('prezzo_totale'); $this->save(); } /** Numero progressivo assegnato alla conferma (max+1). */ public static function prossimoNumero(): int { return (int) static::max('numero') + 1; } }