'decimal:2', 'purchased_at' => 'datetime', 'expires_at' => 'datetime', 'used_events' => 'integer', 'active' => 'boolean', 'event_warning_sent_at' => 'datetime', 'event_warning_threshold' => 'float', 'event_limit_notified_at' => 'datetime', 'expiry_warning_sent_at' => 'datetime', 'expired_notified_at' => 'datetime', ]; public function tenant(): BelongsTo { return $this->belongsTo(Tenant::class); } public function package(): BelongsTo { return $this->belongsTo(Package::class)->withTrashed(); } public function isActive(): bool { if ($this->package && $this->package->isEndcustomer()) { return (bool) $this->active; } return $this->active && (! $this->expires_at || $this->expires_at->isFuture()); } public function canCreateEvent(): bool { if (! $this->isActive()) { return false; } if (! $this->package->isReseller()) { return false; } $maxEvents = $this->package->max_events_per_year; if ($maxEvents === null) { return true; } $maxEvents = max(0, (int) $maxEvents); return $this->used_events < $maxEvents; } public function getRemainingEventsAttribute(): ?int { if (! $this->package->isReseller()) { return 0; } $max = $this->package->max_events_per_year; if ($max === null) { return null; } $max = max(0, (int) $max); return max(0, $max - $this->used_events); } protected static function boot() { parent::boot(); static::creating(function (self $tenantPackage) { if (! $tenantPackage->purchased_at) { $tenantPackage->purchased_at = now(); } if ($tenantPackage->price === null) { $package = $tenantPackage->package ?? Package::query()->find($tenantPackage->package_id); $tenantPackage->price = $package?->price ?? 0; } $package = $tenantPackage->package; if ($package && $package->isReseller()) { // Reseller packages represent prepaid Event-Kontingente and should not expire by default. } elseif (! $tenantPackage->expires_at) { $tenantPackage->expires_at = now()->addYear(); } if ($tenantPackage->active === null) { $tenantPackage->active = true; } }); static::updating(function (self $tenantPackage) { $package = $tenantPackage->package; if ($package && $package->isReseller()) { if ( $tenantPackage->isDirty('expires_at') && $tenantPackage->expires_at instanceof CarbonInterface && $tenantPackage->expires_at->isPast() ) { $tenantPackage->active = false; } return; } }); } }