Files
ladill-queue/app/Http/Controllers/Qms/ProController.php
T
isaaccladandCursor 0770faaa9f
Deploy Ladill Queue / deploy (push) Successful in 42s
Add Queue Pro billing, renewal, and scheduler.
Organizations can upgrade from wallet with plan expiry enforcement and nightly qms:pro-renew charges.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 01:07:24 +00:00

93 lines
3.4 KiB
PHP

<?php
namespace App\Http\Controllers\Qms;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Qms\Concerns\ScopesToAccount;
use App\Services\Billing\BillingClient;
use App\Services\Qms\PlanService;
use App\Services\Qms\QmsPermissions;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\View\View;
class ProController extends Controller
{
use ScopesToAccount;
public function index(Request $request, PlanService $plans): View
{
$organization = $this->organization($request);
$canManage = app(QmsPermissions::class)->can($this->member($request), 'settings.manage');
$settings = $organization->settings ?? [];
$expiresAt = ! empty($settings['plan_expires_at'])
? Carbon::parse($settings['plan_expires_at'])
: null;
return view('qms.pro.index', [
'organization' => $organization,
'isPro' => $plans->isPro($organization),
'canManage' => $canManage,
'priceMinor' => $plans->proPriceMinor(),
'currency' => (string) config('billing.currency', 'GHS'),
'planExpiresAt' => $expiresAt,
'proFeatures' => [
'Unlimited branches & queues',
'Advanced routing rules',
'Digital displays & kiosk devices',
'Appointment reminders',
'Analytics & report exports',
],
]);
}
public function subscribe(Request $request, PlanService $plans, BillingClient $billing): RedirectResponse
{
$this->authorizeAbility($request, 'settings.manage');
$organization = $this->organization($request);
if ($plans->isPro($organization)) {
return redirect()->route('qms.pro.index')
->with('success', 'Your organization is already on Queue Pro.');
}
$priceMinor = $plans->proPriceMinor();
try {
if (! $billing->canAfford($organization->owner_ref, $priceMinor)) {
return redirect()->route('qms.pro.index')
->with('error', 'Insufficient wallet balance. Top up your Ladill wallet to upgrade to Pro.');
}
$charged = $billing->debit(
$organization->owner_ref,
$priceMinor,
'queue_pro',
'queue-pro-'.$organization->id.'-'.now()->format('Y-m-d-His'),
'Ladill Queue Pro — monthly subscription',
);
} catch (\Throwable) {
return redirect()->route('qms.pro.index')
->with('error', 'Could not process upgrade. Please try again.');
}
if (! $charged) {
return redirect()->route('qms.pro.index')
->with('error', 'Insufficient wallet balance. Top up your Ladill wallet to upgrade to Pro.');
}
$settings = $organization->settings ?? [];
$settings['plan'] = 'pro';
$settings['auto_renew'] = true;
$settings['plan_expires_at'] = now()
->addDays((int) config('qms.pro.period_days', 30))
->toIso8601String();
unset($settings['plan_renewal_error']);
$organization->update(['settings' => $settings]);
return redirect()->route('qms.pro.index')
->with('success', 'Welcome to Queue Pro — active for one month.');
}
}