78 lines
3.6 KiB
PHP
78 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Enums\LicenseStatus;
|
|
use App\Models\DeploymentInstallation;
|
|
use App\Models\Device;
|
|
use App\Models\License;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
|
|
class LicenseEntitlementService
|
|
{
|
|
public function allowsUse(int $tenantId): bool
|
|
{
|
|
$license = $this->current($tenantId);
|
|
|
|
return $license !== null && ($license->grace_until ?? $license->expires_at)->isFuture();
|
|
}
|
|
|
|
public function provisionInitial(Tenant $tenant, DeploymentInstallation $installation, string $planCode, bool $activate = false, ?int $issuerId = null): License
|
|
{
|
|
$plan = config("billing.plans.{$planCode}");
|
|
abort_unless($plan && $plan['deployment'] === $installation->deployment_type->value, 422, 'Paket tidak sesuai deployment tenant.');
|
|
$isFree = $plan['price'] === 0;
|
|
$startsAt = now();
|
|
|
|
return License::withoutGlobalScope('tenant')->create([
|
|
'tenant_id' => $tenant->id, 'deployment_installation_id' => $installation->id,
|
|
'license_key_hash' => hash('sha256', random_bytes(32)), 'plan' => $planCode,
|
|
'status' => $activate || $isFree ? LicenseStatus::Active : LicenseStatus::Pending,
|
|
'max_devices' => $plan['max_devices'], 'max_users' => $plan['max_users'], 'features' => ['device_access_management'],
|
|
'starts_at' => $startsAt, 'expires_at' => $isFree ? $startsAt->copy()->addYears(10) : $startsAt->copy()->addMonth(),
|
|
'grace_until' => $isFree ? null : $startsAt->copy()->addMonth()->addDays(7),
|
|
'issued_by' => $issuerId,
|
|
]);
|
|
}
|
|
|
|
public function current(int $tenantId): ?License
|
|
{
|
|
$license = License::withoutGlobalScope('tenant')->where('tenant_id', $tenantId)
|
|
->whereIn('status', [LicenseStatus::Active->value, LicenseStatus::Grace->value])
|
|
->latest('created_at')->first();
|
|
if ($license) {
|
|
return $license;
|
|
}
|
|
if (License::withoutGlobalScope('tenant')->where('tenant_id', $tenantId)->exists()) {
|
|
return null;
|
|
}
|
|
$installation = DeploymentInstallation::withoutGlobalScope('tenant')->where('tenant_id', $tenantId)->first();
|
|
if (! $installation || $installation->deployment_type->value !== 'managed_cloud') {
|
|
return null;
|
|
}
|
|
$plan = config('billing.plans.cloud_free');
|
|
|
|
return License::withoutGlobalScope('tenant')->create([
|
|
'tenant_id' => $tenantId, 'deployment_installation_id' => $installation->id,
|
|
'license_key_hash' => hash('sha256', random_bytes(32)), 'plan' => 'cloud_free',
|
|
'status' => LicenseStatus::Active, 'max_devices' => $plan['max_devices'], 'max_users' => $plan['max_users'],
|
|
'features' => ['device_access_management'], 'starts_at' => now(), 'expires_at' => now()->addYears(10),
|
|
]);
|
|
}
|
|
|
|
public function assertCanAddDevice(int $tenantId): void
|
|
{
|
|
$license = $this->current($tenantId);
|
|
abort_unless($license, 402, 'Lisensi tenant belum aktif.');
|
|
abort_if($license->max_devices !== null && Device::withoutGlobalScope('tenant')->where('tenant_id', $tenantId)->count() >= $license->max_devices, 422, 'Batas perangkat paket tercapai. Upgrade paket melalui menu Lisensi & Tagihan.');
|
|
}
|
|
|
|
public function assertCanAddUser(int $tenantId): void
|
|
{
|
|
$license = $this->current($tenantId);
|
|
abort_unless($license, 402, 'Lisensi tenant belum aktif.');
|
|
abort_if($license->max_users !== null && User::withoutGlobalScope('tenant')->where('tenant_id', $tenantId)->count() >= $license->max_users, 422, 'Batas user aplikasi paket tercapai. Upgrade paket melalui menu Lisensi & Tagihan.');
|
|
}
|
|
}
|