@php // KPIs lead the page; the section banner introduces the detail below them.
@endphp
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'blue', 'icon' => 'fa-receipt', 'label' => t_raw('admin.payouts.col_gross'),
'value' => money($payout['gross_sales']),
'meta' => '' . t('admin.payouts.kpi_gross_cap', [':orders' => number_format((int) $payout['orders_count'])]) . ''])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'violet', 'icon' => 'fa-percentage', 'label' => t_raw('common.commission'),
'value' => money($payout['commission_total']),
'meta' => '' . t('admin.payouts.kpi_commission_cap') . ''])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'amber', 'icon' => 'fa-sliders-h', 'label' => t_raw('admin.payouts.kpi_adjustments'),
'value' => money($adjustments),
'meta' => '' . ($payout['adjustment_note'] !== null && $payout['adjustment_note'] !== '' ? e((string) $payout['adjustment_note']) : t('admin.payouts.kpi_adjustments_cap')) . ''])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'green', 'icon' => 'fa-money-check-alt', 'label' => t_raw('admin.payouts.col_net_payable'),
'value' => money($payout['net_payable']),
'meta' => '' . ($isPaid
? t($producesInvoices ? 'admin.payouts.kpi_net_paid_cap_invoice' : 'admin.payouts.kpi_net_paid_cap', [':date' => fmt_day($payout['paid_at'], true)])
: t($producesInvoices ? 'admin.payouts.kpi_net_cap_invoice' : 'admin.payouts.kpi_net_cap')) . ''])
@partial('kpi-card', ['variant' => 'panel', 'accent' => 'teal', 'icon' => 'fa-receipt', 'label' => t_raw('admin.payouts.kpi_avg_order'), 'value' => money((int) $payout['orders_count'] > 0 ? (float) $payout['gross_sales'] / (int) $payout['orders_count'] : 0), 'meta' => '' . t('admin.payouts.kpi_avg_order_cap', [':orders' => number_format((int) $payout['orders_count'])]) . ''])
{{ t_raw('admin.payouts.detail_heading') }}
{!! t_raw('admin.payouts.detail_sub', [':restaurant' => (string) $payout['restaurant_name'], ':from' => fmt_day($payout['period_start'], true), ':to' => fmt_day($payout['period_end'], true)]) !!}
{{ t_raw('admin.payouts.statement_title') }}
{{ t_raw($producesInvoices ? 'admin.payouts.statement_sub_invoice' : 'admin.payouts.statement_sub') }}
- {{ t_raw('common.restaurant') }}
- {{ (string) $payout['restaurant_name'] }}
- {{ t_raw($producesInvoices ? 'admin.payouts.field_recipient_invoice' : 'admin.payouts.field_recipient') }}
- {!! or_dash($payout['owner_name'] ?? null) !!}
@if (!empty($payout['owner_email'])){{ (string) $payout['owner_email'] }}@endif
- {{ t_raw('common.period') }}
- {!! fmt_day($payout['period_start']) !!} – {!! fmt_day($payout['period_end']) !!}
- {{ t_raw('admin.payouts.field_prepared') }}
- {!! fmt_datetime($payout['created_at']) !!}
@if (!empty($payout['created_by_name'])){{ (string) $payout['created_by_name'] }}@endif
- {{ t_raw('admin.shared.payment_reference') }}
- {!! or_dash($payout['payment_ref'] ?? null) !!}
- {{ t_raw($producesInvoices ? 'admin.payouts.field_transferred_invoice' : 'admin.payouts.field_transferred') }}
- {!! !empty($payout['paid_at']) ? fmt_datetime($payout['paid_at']) : dash() !!}
@php /* SENT BY US, AND WAITING ON THE PROVIDER. A statement the product disbursed itself carries
the gateway's own reference and sits at 'issued' until reconcile_payouts confirms the
batch. Asking the operator to "mark as paid" in that window would have them hand-confirm a
payment the product made — asserting an outcome only the provider knows yet. So the
manual form is withheld while the machine's answer is pending; Dispute stays, because a
batch that fails needs flagging, and settling out-of-band stays available on any statement
the product did NOT send. */
@endphp
@php $awaitingGateway = $status === 'issued' && !empty($payout['payment_ref']);
@endphp
@if (!$isPaid)
{{ t_raw($producesInvoices ? 'admin.payouts.settle_title_invoice' : 'admin.payouts.settle_title') }}
{{ t_raw($producesInvoices ? 'admin.payouts.settle_sub_invoice' : 'admin.payouts.settle_sub', [':amount' => money($payout['net_payable'])]) }}
@if ($status !== 'disputed')
@endif
@php /* Stated before the form, not after the attempt: the transfer is blocked, this is how
much is owed back, and the two ways it clears. The form stays usable — the adjustment
that clears the debt is submitted through it, and settle() re-reads the balance with
that adjustment applied. */
@endphp
@if ($outstanding > 0)
{{ t_raw('admin.payouts.negative_title', [':amount' => money($outstanding)]) }}
{{ t_raw('admin.payouts.negative_text') }}
@endif
@php /* SEND IT, rather than only record that somebody else did.
Every restaurant on this install stores a payee, and the platform is holding the
money — so the operator can disburse from here instead of paying out-of-band and
typing a reference back in. $sendable is the model's own dispatchable() answer, the
SAME rule the scheduled sweep applies, so this appears only when pressing it would
genuinely pay: an unpaid payout-kind statement, a positive balance, and a payee the
rail can reach. The amount is the one on this page and is sent without re-gathering,
so what is approved here is what leaves.
Marking as paid stays below it, because settling outside the product is still valid —
a bank transfer has no rail here and always will not. */
@endphp
@if (!empty($sendable))
@endif
@if ($awaitingGateway)
@php /* The PROVIDER'S own answer, not a paraphrase of it. PayPal Payouts is asynchronous: the
batch is accepted at once and each item settles after, so there is a window where the
product holds a reference and not an outcome. "Unclaimed" is called out separately
because it is not a transfer in flight — PayPal has the money and cannot deliver it, and
it returns to the platform after 30 days unless the payee is corrected. */
@endphp
@php $ps = $providerStatus ?? null;
@endphp
@if ($ps === 'unclaimed')
{{ t_raw('admin.payouts.provider_unclaimed', [':ref' => e((string) $payout['payment_ref'])]) }}
@elseif ($ps === 'pending')
{{ t_raw('admin.payouts.provider_pending', [':ref' => e((string) $payout['payment_ref'])]) }}
@else
{{ t_raw('admin.payouts.awaiting_gateway', [':ref' => e((string) $payout['payment_ref'])]) }}
@endif
@else
@endif
@endif
{{ t_raw('admin.payouts.lines_title') }}
{{ t_raw('admin.payouts.lines_sub') }}
{{ t_raw('admin.payouts.lines_title') }}
| {{ t_raw('vendor.shifts.col_order') }} |
{{ t_raw('common.date') }} |
{{ t_raw('admin.payouts.col_method') }} |
{{ t_raw('admin.payouts.col_order_total') }} |
{{ t_raw('admin.payouts.col_rate') }} |
{{ t_raw('common.commission') }} |
@php /* The line's `net` is takings−commission on a payout (what the platform owes back)
and the commission itself on an invoice (the royalty the restaurant owes), so
the head names the party the column runs to. */
@endphp
{{ t_raw($producesInvoices ? 'admin.payouts.col_net_invoice' : 'admin.payouts.col_net') }} |
@if ($linesPage)
@foreach ($linesPage as $line)
| {!! or_dash($line['order_number'] ?? null) !!} |
{!! !empty($line['placed_at']) ? fmt_day($line['placed_at']) : dash() !!} |
@php $m = (string) ($line['payment_method'] ?? ''); $ico = $m !== '' ? payment_method_icon($m) : ''; echo $ico !== '' ? $ico : ($m !== '' ? status_label('payment_method', $m) : dash());
@endphp |
{{ money($line['order_total']) }} |
{!! $line['commission_rate'] !== null ? e((string) (float) $line['commission_rate']) . '%' : dash() !!} |
{{ money($line['commission_amount']) }} |
{{ money($line['net']) }} |
@endforeach
@else
@partial('table-empty', ['colspan' => 7, 'icon' => 'fa-receipt', 'msg' => t('admin.payouts.lines_empty')])
@endif
@if ($lines)
| {{ t_raw('admin.payouts.lines_total', [':count' => number_format(count($lines))]) }} |
{{ money($linesGross) }} |
{!! dash() !!} |
{{ money($linesCommission) }} |
{{ money($linesNet) }} |
@endif
@partial('table-toolbar', ['pager' => $linesPager, 'base' => '/admin/payouts/' . (int) $payout['id']])
@php /* /.qm-d2 */
@endphp
@endsection