qrCodes() ->where('type', QrCode::TYPE_EVENT) ->pluck('id'); $revenueMinor = (int) QrEventRegistration::query() ->whereIn('qr_code_id', $eventIds) ->where('status', QrEventRegistration::STATUS_CONFIRMED) ->where('amount_minor', '>', 0) ->get() ->sum(fn (QrEventRegistration $r) => $r->netAmountMinor()); $transactions = QrEventRegistration::query() ->whereIn('qr_code_id', $eventIds) ->where('status', QrEventRegistration::STATUS_CONFIRMED) ->where('amount_minor', '>', 0) ->with('qrCode:id,label,payload') ->orderByDesc('paid_at') ->orderByDesc('id') ->limit(50) ->get(); $balanceMinor = 0; $payoutAccount = null; $withdrawals = []; try { $balanceMinor = $this->billing->balanceMinor($account->public_id); } catch (Throwable $e) { Log::warning('Events payouts could not load wallet balance', [ 'user' => $account->public_id, 'error' => $e->getMessage(), ]); } try { $payoutAccount = $this->identity->payoutAccount($account->public_id); $withdrawals = $this->identity->withdrawals($account->public_id); } catch (Throwable $e) { Log::warning('Events payouts could not load payout account or withdrawals', [ 'user' => $account->public_id, 'error' => $e->getMessage(), ]); } return view('events.payouts', [ 'revenueMinor' => $revenueMinor, 'balanceMinor' => $balanceMinor, 'balanceGhs' => round($balanceMinor / 100, 2), 'transactions' => $transactions, 'payoutAccount' => $payoutAccount, 'withdrawals' => $withdrawals, ]); } public function banks(Request $request): JsonResponse { $type = $request->query('type') === 'bank_account' ? 'bank' : 'mobile_money'; try { return response()->json(['data' => $this->identity->banks($type)]); } catch (Throwable $e) { Log::warning('Events payouts could not load banks', ['error' => $e->getMessage()]); return response()->json(['data' => []]); } } public function updatePayoutAccount(Request $request): RedirectResponse { $data = $request->validate([ 'account_type' => ['required', 'in:mobile_money,bank_account'], 'account_name' => ['required', 'string', 'max:200'], 'account_number' => ['required', 'string', 'max:30'], 'bank_code' => ['required', 'string', 'max:30'], 'bank_name' => ['required', 'string', 'max:200'], 'currency' => ['sometimes', 'string', 'size:3'], ]); $data['currency'] = $data['currency'] ?? 'GHS'; $this->identity->updatePayoutAccount(ladill_account()->public_id, $data); return redirect() ->route('events.payouts') ->with('success', 'Payout account saved.'); } public function withdraw(Request $request): RedirectResponse { $data = $request->validate([ 'amount' => ['required', 'numeric', 'min:1', 'max:50000'], ]); $this->identity->withdraw(ladill_account()->public_id, (float) $data['amount']); return redirect() ->route('events.payouts') ->with('success', 'Withdrawal request submitted. Funds are sent to your payout account once processed.'); } }