libellé affiché dans le back-office. */ public const STATUSES = [ 'running' => 'En cours', 'scheduled' => 'Programmée', 'inactive' => 'Inactive', 'ended' => 'Terminée', ]; protected $guarded = ['id']; protected function casts(): array { return [ 'starts_at' => 'datetime', 'ends_at' => 'datetime', 'active' => 'boolean', 'priority' => 'integer', 'width' => 'integer', ]; } public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } public function groups(): BelongsToMany { return $this->belongsToMany(DirectoryGroup::class, 'campaign_group'); } public function scopeRunning(Builder $q): Builder { return $q->where('active', true)->where('starts_at', '<=', now())->where('ends_at', '>=', now()); } /** running | scheduled | inactive | ended — doit rester cohérent avec scopeRunning(). */ public function status(): string { $now = now()->startOfSecond(); // même précision que la comparaison SQL de scopeRunning() return match (true) { $this->ends_at->lt($now) => 'ended', ! $this->active => 'inactive', $this->starts_at->gt($now) => 'scheduled', default => 'running', }; } public function displayWidth(): int { return $this->width ?: self::DEFAULT_WIDTH; } }