|null $payload */ class GuestNotification extends Model { /** @use HasFactory<\Database\Factories\GuestNotificationFactory> */ use HasFactory; protected $fillable = [ 'tenant_id', 'event_id', 'type', 'title', 'body', 'payload', 'audience_scope', 'target_identifier', 'status', 'priority', 'expires_at', ]; protected function casts(): array { return [ 'payload' => 'array', 'expires_at' => 'datetime', 'type' => GuestNotificationType::class, 'audience_scope' => GuestNotificationAudience::class, 'status' => GuestNotificationState::class, ]; } public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } public function event(): BelongsTo { return $this->belongsTo(Event::class); } public function receipts(): HasMany { return $this->hasMany(GuestNotificationReceipt::class); } public function scopeForEvent(Builder $query, Event $event): void { $query->where('event_id', $event->getKey()); } public function scopeActive(Builder $query): void { $query->where('status', GuestNotificationState::ACTIVE->value); } public function scopeNotExpired(Builder $query): void { $query->where(function (Builder $builder) { $builder->whereNull('expires_at')->orWhere('expires_at', '>', Carbon::now()); }); } public function scopeVisibleToGuest(Builder $query, ?string $guestIdentifier): void { $query->where(function (Builder $builder) use ($guestIdentifier) { $builder->where('audience_scope', GuestNotificationAudience::ALL->value); if ($guestIdentifier) { $builder->orWhere(function (Builder $inner) use ($guestIdentifier) { $inner->where('audience_scope', GuestNotificationAudience::GUEST->value) ->where('target_identifier', $guestIdentifier); }); } }); } public function hasExpired(): bool { return $this->expires_at instanceof Carbon && $this->expires_at->isPast(); } }