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; $planKey = $plans->planKey($organization); $branchCount = $plans->activeBranchCount($organization); $enterprisePrice = $plans->enterprisePriceMinor($organization); return view('qms.pro.index', [ 'organization' => $organization, 'planKey' => $planKey, 'isPro' => $planKey === 'pro', 'isEnterprise' => $planKey === 'enterprise', 'hasPaidPlan' => $plans->hasPaidPlan($organization), 'canManage' => $canManage, 'proPriceMinor' => $plans->proPriceMinor(), 'enterprisePricePerBranchMinor' => $plans->enterprisePricePerBranchMinor(), 'enterprisePriceMinor' => $enterprisePrice, 'branchCount' => $branchCount, 'canSubscribeEnterprise' => $plans->canSubscribeEnterprise($organization), 'enterpriseMinBranches' => (int) config('qms.enterprise.min_branches', 2), 'currency' => (string) config('billing.currency', 'GHS'), 'planExpiresAt' => $expiresAt, 'enterpriseBilledBranches' => (int) ($settings['enterprise_billed_branches'] ?? $branchCount), 'salesUrl' => ladill_platform_url('contact-sales'), ]); } public function subscribe(Request $request, PlanService $plans, BillingClient $billing): RedirectResponse { $this->authorizeAbility($request, 'settings.manage'); $organization = $this->organization($request); if ($plans->hasPaidPlan($organization)) { return redirect()->route('qms.pro.index') ->with('success', 'Your organization already has an active paid plan.'); } return $this->chargePlan( $organization, $billing, $plans->proPriceMinor(), 'pro', 'queue_pro', 'queue-pro-'.$organization->id.'-'.now()->format('Y-m-d-His'), 'Ladill Queue Pro — monthly subscription', 'Welcome to Queue Pro — active for one month.', ); } public function subscribeEnterprise(Request $request, PlanService $plans, BillingClient $billing): RedirectResponse { $this->authorizeAbility($request, 'settings.manage'); $organization = $this->organization($request); if ($plans->hasPaidPlan($organization)) { return redirect()->route('qms.pro.index') ->with('success', 'Your organization already has an active paid plan.'); } if (! $plans->canSubscribeEnterprise($organization)) { $min = (int) config('qms.enterprise.min_branches', 2); return redirect()->route('qms.pro.index') ->with('error', "Enterprise billing requires at least {$min} active branches. Add another branch or choose Pro for a single site."); } $priceMinor = $plans->enterprisePriceMinor($organization); return $this->chargePlan( $organization, $billing, $priceMinor, 'enterprise', 'queue_enterprise', 'queue-enterprise-'.$organization->id.'-'.now()->format('Y-m-d-His'), 'Ladill Queue Enterprise — monthly subscription', 'Welcome to Queue Enterprise — active for one month.', $plans->activeBranchCount($organization), ); } private function chargePlan( $organization, BillingClient $billing, int $priceMinor, string $plan, string $billingSource, string $reference, string $description, string $successMessage, ?int $enterpriseBranches = null, ): RedirectResponse { 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.'); } $charged = $billing->debit( $organization->owner_ref, $priceMinor, $billingSource, $reference, $description, ); } 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.'); } $settings = $organization->settings ?? []; $settings['plan'] = $plan; $settings['auto_renew'] = true; $settings['plan_expires_at'] = now() ->addDays((int) config('qms.pro.period_days', 30)) ->toIso8601String(); if ($enterpriseBranches !== null) { $settings['enterprise_billed_branches'] = $enterpriseBranches; } unset($settings['plan_renewal_error']); $organization->update(['settings' => $settings]); return redirect()->route('qms.pro.index')->with('success', $successMessage); } }