57 lines
3.3 KiB
PHP
57 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\SystemRole;
|
|
use App\Models\BillingOrder;
|
|
use App\Models\DeploymentInstallation;
|
|
use App\Services\LicenseEntitlementService;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\Rule;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class BillingController extends Controller
|
|
{
|
|
public function index(Request $request, LicenseEntitlementService $entitlements): Response
|
|
{
|
|
abort_unless($request->user()->hasRole(SystemRole::TenantAdmin->value), 403);
|
|
$installation = DeploymentInstallation::query()->firstOrFail();
|
|
$license = $entitlements->current($request->user()->tenant_id);
|
|
|
|
return Inertia::render('billing/index', [
|
|
'installation' => ['deployment_type' => $installation->deployment_type->value, 'status' => $installation->status],
|
|
'license' => $license ? ['plan' => $license->plan, 'status' => $license->status->value, 'max_devices' => $license->max_devices, 'max_users' => $license->max_users, 'expires_at' => $license->expires_at?->toIso8601String(), 'grace_until' => $license->grace_until?->toIso8601String()] : null,
|
|
'plans' => collect(config('billing.plans'))->filter(fn ($plan) => $plan['deployment'] === $installation->deployment_type->value)->map(fn ($plan, $code) => ['code' => $code, ...$plan])->values(),
|
|
'orders' => BillingOrder::query()->latest()->limit(20)->get(['uuid', 'plan_code', 'gateway', 'status', 'total', 'currency', 'checkout_url', 'created_at', 'expires_at']),
|
|
'pendingOrder' => BillingOrder::query()->where('status', 'pending')->where('expires_at', '>', now())->latest()->first(['uuid', 'plan_code', 'total', 'currency', 'expires_at']),
|
|
'gateways' => [config('billing.default_gateway')],
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request): RedirectResponse
|
|
{
|
|
abort_unless($request->user()->hasRole(SystemRole::TenantAdmin->value), 403);
|
|
$data = $request->validate([
|
|
'plan_code' => ['required', Rule::in(array_keys(config('billing.plans')))],
|
|
'gateway' => ['required', Rule::in(array_keys(config('billing.gateways')))],
|
|
]);
|
|
$plan = config("billing.plans.{$data['plan_code']}");
|
|
$installation = DeploymentInstallation::query()->firstOrFail();
|
|
abort_unless($plan['deployment'] === $installation->deployment_type->value, 422, 'Paket tidak sesuai dengan deployment tenant.');
|
|
abort_if($plan['price'] === 0, 422, 'Paket gratis tidak membutuhkan checkout.');
|
|
BillingOrder::query()->where('status', 'pending')->where('expires_at', '<=', now())->update(['status' => 'expired']);
|
|
$pending = BillingOrder::query()->where('status', 'pending')->where('expires_at', '>', now())->latest()->first();
|
|
if ($pending) {
|
|
return to_route('checkout.show', $pending->uuid)->with('info', 'Selesaikan pembayaran yang masih pending sebelum membuat perpanjangan baru.');
|
|
}
|
|
$order = BillingOrder::create([
|
|
'tenant_id' => $request->user()->tenant_id, 'plan_code' => $data['plan_code'], 'gateway' => $data['gateway'],
|
|
'status' => 'pending', 'subtotal' => $plan['price'], 'tax' => 0, 'total' => $plan['price'], 'currency' => 'IDR', 'expires_at' => now()->addDay(),
|
|
]);
|
|
|
|
return to_route('checkout.show', $order->uuid);
|
|
}
|
|
}
|