@extends('layouts.dashboard') @section('content') @php /** * Vendor → Payouts / Royalty. What the restaurant is owed (or owes) and its statement history. * Reuses the shared KPI card + .qm-table idiom — no new CSS. In franchise mode the same page reads * as royalty invoices the restaurant owes the platform (labels swap via $producesInvoices); * marketplace shows payouts owed to the restaurant. * * A marketplace payout is read-only here — the admin transfers it, and this page is the * restaurant's window onto that so it is never settled blind. A franchise INVOICE is not: the * restaurant owes that money, so an open one carries the button that settles it, in the status * cell where the owner learns it is waiting for them (the same place the sponsored-placement list * puts its own pay button, for the same reason). * * @var float $pendingNet money owed but not yet on a statement (payout owed / royalty due) * @var int $pendingCount unsettled orders behind that figure * @var array $statements this restaurant's statements, newest first * @var array $pager pagination for $statements * @var float $settledTotal lifetime settled (paid out / royalty paid) * @var bool $hasPayee whether a payee is on file (always true in franchise — not shown) * @var bool $producesInvoices franchise: statements are royalty invoices, not payouts * @var bool $canPayInvoice franchise: an open invoice can be settled from here right now */ $statements = $statements ?? []; $producesInvoices = $producesInvoices ?? false; $canPayInvoice = $canPayInvoice ?? false; // One label set per money model — payouts owed to the restaurant, or royalty invoices it owes. $L = $producesInvoices ? ['title' => 'vendor.royalty.title', 'intro' => 'vendor.royalty.intro', 'pending' => 'vendor.royalty.kpi_pending', 'settled' => 'vendor.royalty.kpi_settled', 'statements' => 'vendor.royalty.kpi_statements', 'history' => 'vendor.royalty.history_title', 'amount' => 'common.royalty', 'net' => 'vendor.royalty.col_net', 'empty' => 'vendor.royalty.empty', 'this_month' => 'vendor.payouts.kpi_this_month', 'avg' => 'vendor.payouts.kpi_avg'] : ['title' => 'vendor.payouts.title', 'intro' => 'vendor.payouts.intro', 'pending' => 'vendor.payouts.kpi_pending', 'settled' => 'vendor.payouts.kpi_settled', 'statements' => 'vendor.payouts.kpi_statements', 'history' => 'vendor.payouts.history_title', 'amount' => 'common.commission', 'net' => 'vendor.payouts.col_net', 'empty' => 'vendor.payouts.empty', 'this_month' => 'vendor.payouts.kpi_this_month', 'avg' => 'vendor.payouts.kpi_avg']; $statusPill = static fn (string $s): string => match ($s) { 'paid' => 'qm-pill-green', 'issued' => 'qm-pill-blue', 'disputed' => 'qm-pill-red', default => 'qm-pill-amber', }; $cur = setting('currency_symbol', '$'); @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp
{{ t_raw($L['intro']) }}
| {{ t_raw('vendor.payouts.col_period') }} | {{ t_raw('admin.users.col_orders') }} | {{ t_raw('vendor.payouts.col_gross') }} | {{ t_raw($L['amount']) }} | {{ t_raw($L['net']) }} | {{ t_raw('common.status') }} | {{ t_raw('vendor.payouts.col_reference') }} |
|---|---|---|---|---|---|---|
| {!! fmt_day($s['period_start']) !!} – {!! fmt_day($s['period_end']) !!} | {{ number_format((int) $s['orders_count']) }} | {{ money($s['gross_sales']) }} | {{ money($s['commission_total']) }} | {{ money($s['net_payable']) }} | {{ status_label('payout', (string) $s['status']) }} @php /* An invoice the platform has raised but not been paid — draft or issued — is money this restaurant owes, so it gets the way to hand it over. ONE button, not one per gateway: which gateway is asked at checkout, next to the figure it applies to. A statement worth nothing has no charge to open and is skipped, exactly as the controller's own payable test does. */ @endphp @if ($canPayInvoice && in_array((string) $s['status'], ['draft', 'issued'], true) && (float) $s['net_payable'] > 0) @endif | {!! $s['payment_ref'] ? e((string) $s['payment_ref']) : dash() !!} |