Fix endcustomer package allocation and event create gating
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-02-06 13:21:11 +01:00
parent 0291d537fb
commit df00deb0df
11 changed files with 409 additions and 14 deletions

View File

@@ -110,7 +110,14 @@ class EventController extends Controller
$tenantPackage = $tenant->tenantPackages()
->with('package')
->where('active', true)
->where(function ($query) {
$query->whereNull('expires_at')->orWhere('expires_at', '>', now());
})
->whereHas('package', fn ($query) => $query->withTrashed()->where('type', 'endcustomer'))
->withCount('eventPackages')
->orderBy('event_packages_count')
->orderByDesc('purchased_at')
->orderByDesc('id')
->first();
$package = null;

View File

@@ -111,21 +111,26 @@ class CheckoutAssignmentService
]);
}
} else {
$tenantPackage = TenantPackage::updateOrCreate(
[
if ($purchase->wasRecentlyCreated) {
$tenantPackage = TenantPackage::create([
'tenant_id' => $tenant->id,
'package_id' => $package->id,
],
[
'price' => round($price, 2),
'active' => true,
'purchased_at' => now(),
'expires_at' => $this->resolveExpiry($package, $tenant),
]
);
]);
} else {
$tenantPackage = TenantPackage::query()
->where('tenant_id', $tenant->id)
->where('package_id', $package->id)
->orderByDesc('purchased_at')
->orderByDesc('id')
->first();
}
}
if ($package->type !== 'reseller') {
if ($package->type !== 'reseller' && $tenantPackage) {
$tenant->forceFill([
'subscription_status' => 'active',
'subscription_expires_at' => $tenantPackage->expires_at,

View File

@@ -13,13 +13,38 @@ class PackageLimitEvaluator
public function assessEventCreation(Tenant $tenant, ?string $includedPackageSlug = null): ?array
{
$hasEndcustomerPackage = $tenant->tenantPackages()
$activeEndcustomerPackages = $tenant->tenantPackages()
->where('active', true)
->where(function ($query) {
$query->whereNull('expires_at')->orWhere('expires_at', '>', now());
})
->whereHas('package', fn ($query) => $query->withTrashed()->where('type', 'endcustomer'))
->exists();
->withCount(['eventPackages' => function ($query) use ($tenant) {
$query->whereHas('event', fn ($eventQuery) => $eventQuery->where('tenant_id', $tenant->id));
}])
->get();
if ($hasEndcustomerPackage) {
return null;
if ($activeEndcustomerPackages->isNotEmpty()) {
$hasAvailableEndcustomerPackage = $activeEndcustomerPackages
->contains(fn ($tenantPackage) => (int) ($tenantPackage->event_packages_count ?? 0) < 1);
if ($hasAvailableEndcustomerPackage) {
return null;
}
return [
'code' => 'event_limit_exceeded',
'title' => __('api.packages.event_limit_exceeded.title'),
'message' => __('api.packages.event_limit_exceeded.message'),
'status' => 402,
'meta' => [
'scope' => 'events',
'used' => (int) $activeEndcustomerPackages->count(),
'limit' => (int) $activeEndcustomerPackages->count(),
'remaining' => 0,
'source' => 'endcustomer_packages',
],
];
}
if ($tenant->hasEventAllowanceFor($includedPackageSlug)) {