'decimal:2', 'purchased_at' => 'datetime', 'gallery_expires_at' => 'datetime', 'gallery_warning_sent_at' => 'datetime', 'gallery_expired_notified_at' => 'datetime', 'used_photos' => 'integer', 'used_guests' => 'integer', ]; public function event(): BelongsTo { return $this->belongsTo(Event::class); } public function package(): BelongsTo { return $this->belongsTo(Package::class); } public function isActive(): bool { return $this->gallery_expires_at && $this->gallery_expires_at->isFuture(); } public function canUploadPhoto(): bool { if (! $this->isActive()) { return false; } $maxPhotos = $this->package->max_photos ?? 0; return $this->used_photos < $maxPhotos; } public function canAddGuest(): bool { if (! $this->isActive()) { return false; } $maxGuests = $this->package->max_guests ?? 0; return $this->used_guests < $maxGuests; } public function getRemainingPhotosAttribute(): int { $max = $this->package->max_photos ?? 0; return max(0, $max - $this->used_photos); } public function getRemainingGuestsAttribute(): int { $max = $this->package->max_guests ?? 0; return max(0, $max - $this->used_guests); } protected static function boot() { parent::boot(); static::creating(function ($eventPackage) { if (! $eventPackage->purchased_at) { $eventPackage->purchased_at = now(); } if (! $eventPackage->gallery_expires_at && $eventPackage->package) { $days = $eventPackage->package->gallery_days ?? 30; $eventPackage->gallery_expires_at = now()->addDays($days); } }); } }