45 خطوط
1.5 KiB
PHP
45 خطوط
1.5 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\Subscriptions\Application;
|
|
|
|
use App\Models\User;
|
|
use App\Modules\Identity\Domain\Enums\AccountStatus;
|
|
use App\Modules\Identity\Domain\UserInvitation;
|
|
use App\Modules\Subscriptions\Domain\Subscription;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
final class SeatQuota
|
|
{
|
|
public function assertAvailable(string $organizationId, string $errorField = 'email'): void
|
|
{
|
|
$subscription = Subscription::query()
|
|
->where('organization_id', $organizationId)
|
|
->where('status', 'active')
|
|
->where('starts_at', '<=', now())
|
|
->where(fn ($query) => $query->whereNull('expires_at')->orWhere('expires_at', '>', now()))
|
|
->latest('starts_at')
|
|
->first();
|
|
|
|
if (! $subscription || $subscription->seat_limit === null) {
|
|
return;
|
|
}
|
|
|
|
$users = User::query()
|
|
->where('organization_id', $organizationId)
|
|
->whereIn('status', [AccountStatus::Active, AccountStatus::Invited])
|
|
->count();
|
|
$pendingInvitations = UserInvitation::query()
|
|
->where('organization_id', $organizationId)
|
|
->whereNull('accepted_at')
|
|
->whereNull('revoked_at')
|
|
->where('expires_at', '>', now())
|
|
->count();
|
|
|
|
if ($users + $pendingInvitations >= $subscription->seat_limit) {
|
|
throw ValidationException::withMessages([
|
|
$errorField => ['The organization has reached its seat limit.'],
|
|
]);
|
|
}
|
|
}
|
|
}
|