} */ private function billingSnapshot(?string $publicId): array { if (! $publicId) { return [0, []]; } $balanceMinor = $this->billing->balanceMinor($publicId); $ledger = $this->billing->serviceLedger($publicId, config('billing.service', 'transfer')); return [$balanceMinor, $ledger]; } public function wallet(): View { $user = ladill_account(); [$balanceMinor, $ledger] = $this->billingSnapshot($user?->public_id); return view('qr.account.wallet', [ 'balanceMinor' => $balanceMinor, 'spentMinor' => (int) ($ledger['spent_minor'] ?? 0), 'creditedMinor' => (int) ($ledger['credited_minor'] ?? 0), 'topupUrl' => $this->topupUrl(), ]); } public function billing(): View { $user = ladill_account(); [$balanceMinor, $ledger] = $this->billingSnapshot($user?->public_id); $activeTransfers = Transfer::query() ->where('user_id', $user->id) ->where('status', Transfer::STATUS_ACTIVE) ->where(function ($query) { $query->whereNull('expires_at')->orWhere('expires_at', '>', now()); }) ->orderByDesc('storage_bytes') ->get(); $storageBytes = (int) $activeTransfers->sum('storage_bytes'); $storageGb = round($storageBytes / (1024 * 1024 * 1024), 2); $pricePerGb = (float) config('transfer.price_per_gb_month', 1.0); $monthlyTotalGhs = round($activeTransfers->sum(fn (Transfer $transfer) => $transfer->monthlyCostGhs()), 2); return view('qr.account.billing', [ 'balanceMinor' => $balanceMinor, 'spentMinor' => (int) ($ledger['spent_minor'] ?? 0), 'creditedMinor' => (int) ($ledger['credited_minor'] ?? 0), 'activeTransfers' => $activeTransfers, 'storageBytes' => $storageBytes, 'storageGb' => $storageGb, 'pricePerGb' => $pricePerGb, 'monthlyTotalGhs' => $monthlyTotalGhs, 'walletUrl' => route('account.wallet'), 'topupUrl' => $this->topupUrl(), ]); } public function settings(): View { $account = ladill_account(); $settings = $account->getOrCreateQrSetting(); return view('transfer.settings', [ 'account' => $account, 'settings' => $settings, ]); } public function updateSettings(Request $request): RedirectResponse { $account = ladill_account(); $data = $request->validate([ 'notify_email' => ['nullable', 'email', 'max:255'], 'product_updates' => ['nullable', 'boolean'], ]); QrSetting::updateOrCreate( ['user_id' => $account->id], [ 'notify_email' => $data['notify_email'] ?? null, 'product_updates' => $request->boolean('product_updates'), ], ); return redirect()->route('account.settings')->with('success', 'Settings saved.'); } }