Implement package limit notification system
This commit is contained in:
151
app/Services/Packages/PackageLimitEvaluator.php
Normal file
151
app/Services/Packages/PackageLimitEvaluator.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Packages;
|
||||
|
||||
use App\Models\Event;
|
||||
use App\Models\EventPackage;
|
||||
use App\Models\Tenant;
|
||||
|
||||
class PackageLimitEvaluator
|
||||
{
|
||||
public function assessEventCreation(Tenant $tenant): ?array
|
||||
{
|
||||
if ($tenant->hasEventAllowance()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$package = $tenant->getActiveResellerPackage();
|
||||
|
||||
if ($package) {
|
||||
$limit = $package->package->max_events_per_year ?? 0;
|
||||
|
||||
return [
|
||||
'code' => 'event_limit_exceeded',
|
||||
'title' => 'Event quota reached',
|
||||
'message' => 'Your current package has no remaining event slots. Please upgrade or renew your subscription.',
|
||||
'status' => 402,
|
||||
'meta' => [
|
||||
'scope' => 'events',
|
||||
'used' => (int) $package->used_events,
|
||||
'limit' => $limit,
|
||||
'remaining' => max(0, $limit - $package->used_events),
|
||||
'tenant_package_id' => $package->id,
|
||||
'package_id' => $package->package_id,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'code' => 'event_credits_exhausted',
|
||||
'title' => 'No event credits remaining',
|
||||
'message' => 'You have no event credits remaining. Purchase additional credits or a package to create new events.',
|
||||
'status' => 402,
|
||||
'meta' => [
|
||||
'scope' => 'credits',
|
||||
'balance' => (int) ($tenant->event_credits_balance ?? 0),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function assessPhotoUpload(Tenant $tenant, int $eventId, ?Event $preloadedEvent = null): ?array
|
||||
{
|
||||
[$event, $eventPackage] = $this->resolveEventAndPackage($tenant, $eventId, $preloadedEvent);
|
||||
|
||||
if (! $event) {
|
||||
return [
|
||||
'code' => 'event_not_found',
|
||||
'title' => 'Event not accessible',
|
||||
'message' => 'The selected event could not be found or belongs to another tenant.',
|
||||
'status' => 404,
|
||||
'meta' => [
|
||||
'scope' => 'photos',
|
||||
'event_id' => $eventId,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
if (! $eventPackage || ! $eventPackage->package) {
|
||||
return [
|
||||
'code' => 'event_package_missing',
|
||||
'title' => 'Event package missing',
|
||||
'message' => 'No package is attached to this event. Assign a package to enable uploads.',
|
||||
'status' => 409,
|
||||
'meta' => [
|
||||
'scope' => 'photos',
|
||||
'event_id' => $event->id,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$maxPhotos = $eventPackage->package->max_photos;
|
||||
|
||||
if ($maxPhotos === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($eventPackage->used_photos >= $maxPhotos) {
|
||||
return [
|
||||
'code' => 'photo_limit_exceeded',
|
||||
'title' => 'Photo upload limit reached',
|
||||
'message' => 'This event has reached its photo allowance. Upgrade the event package to accept more uploads.',
|
||||
'status' => 402,
|
||||
'meta' => [
|
||||
'scope' => 'photos',
|
||||
'used' => (int) $eventPackage->used_photos,
|
||||
'limit' => (int) $maxPhotos,
|
||||
'remaining' => 0,
|
||||
'event_id' => $event->id,
|
||||
'package_id' => $eventPackage->package_id,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function resolveEventPackageForPhotoUpload(
|
||||
Tenant $tenant,
|
||||
int $eventId,
|
||||
?Event $preloadedEvent = null
|
||||
): ?EventPackage {
|
||||
[, $eventPackage] = $this->resolveEventAndPackage($tenant, $eventId, $preloadedEvent);
|
||||
|
||||
return $eventPackage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{0: ?Event, 1: ?\App\Models\EventPackage}
|
||||
*/
|
||||
private function resolveEventAndPackage(
|
||||
Tenant $tenant,
|
||||
int $eventId,
|
||||
?Event $preloadedEvent = null
|
||||
): array {
|
||||
$event = $preloadedEvent;
|
||||
|
||||
if (! $event) {
|
||||
$event = Event::with(['eventPackage.package', 'eventPackages.package'])
|
||||
->find($eventId);
|
||||
}
|
||||
|
||||
if (! $event || $event->tenant_id !== $tenant->id) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
$eventPackage = $event->eventPackage;
|
||||
|
||||
if (! $eventPackage && method_exists($event, 'eventPackages')) {
|
||||
$eventPackage = $event->eventPackages()
|
||||
->with('package')
|
||||
->orderByDesc('purchased_at')
|
||||
->orderByDesc('created_at')
|
||||
->first();
|
||||
}
|
||||
|
||||
if ($eventPackage && ! $eventPackage->relationLoaded('package')) {
|
||||
$eventPackage->load('package');
|
||||
}
|
||||
|
||||
return [$event, $eventPackage];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user