@extends('layouts.dashboard') @section('content') @php /** * Vendor → Cash drawer → session report: the Z-report once closed, and the X-report (a * mid-shift reading) while the session is still open. * * The X-report obeys the same blind rule as the cash-up screen. An operator who could * print expected cash from here would never have to face the blind count, so while the * session is open and uncounted the cash summary, the cash tender line and the movement * amounts are withheld. Everything the report exists to give that is NOT cash in that * drawer — card and wallet takings, tips, who served, service mode, menu section — is * shown in full throughout. * * @var array $shift @var array|null $totals @var float|null $expected @var bool $reveal * @var array $tenders @var array $counts @var array $movements * @var array $byServer @var array $byMode @var array $byCategory */ $closed = ($shift['status'] ?? '') === 'closed'; $reveal = $reveal ?? $closed; $typeLabels = ['sale' => t_raw('vendor.shifts.type_sale'), 'refund' => t_raw('vendor.shifts.type_refund'), 'payin' => t_raw('vendor.shifts.type_payin'), 'payout' => t_raw('vendor.shifts.type_payout'), 'drop' => t_raw('vendor.shifts.type_drop')]; $typePills = ['sale' => 'qm-pill-green', 'refund' => 'qm-pill-red', 'payin' => 'qm-pill-blue', 'payout' => 'qm-pill-amber', 'drop' => 'qm-pill-grey']; // Covers both key spaces: ledger tenders (cash/card/...) and, for sessions // predating the ledger, orders.payment_method (cod/offline/...). $cashLbl = t_raw('status.payment_method.cash'); $cardLbl = t_raw('status.payment_method.card'); $methodLabels = ['cash' => $cashLbl, 'cod' => $cashLbl, 'card' => $cardLbl, 'offline' => $cardLbl, 'stripe' => 'Stripe', 'paypal' => 'PayPal', 'other' => t_raw('status.payment_method.other')]; // Which tender keys ARE the cash in the drawer, and therefore have to wait for the count. $cashKeys = ['cash', 'cod']; $modeLabels = ['delivery' => t_raw('common.delivery'), 'pickup' => t_raw('common.pickup'), 'dine_in' => t_raw('common.dine_in')]; $counts += ['total_c' => 0, 'cancelled_c' => 0, 'discounted_c' => 0, 'discount_s' => 0, 'refunded_c' => 0, 'tip_s' => 0, 'tipped_c' => 0]; $variance = $closed && $shift['variance'] !== null ? (float) $shift['variance'] : null; $byServer = $byServer ?? []; $byMode = $byMode ?? []; $byCategory = $byCategory ?? []; @endphp
{!! $closed ? t('vendor.shifts.report_sub_closed') : t('vendor.shifts.report_sub_open') !!}
{!! t_raw('vendor.shifts.opened_template', [':date' => fmt_datetime($shift['opened_at'])]) !!}{!! !empty($shift['opened_by']) ? ' ' . t('vendor.shifts.by_name_suffix', [':name' => (string) $shift['opened_by']]) : '' !!} @if ($closed && $shift['closed_at']) · {!! t_raw('vendor.shifts.closed_template', [':date' => fmt_datetime($shift['closed_at'])]) !!}{!! !empty($shift['closed_by']) ? ' ' . t('vendor.shifts.by_name_suffix', [':name' => (string) $shift['closed_by']]) : '' !!}@endif
{{ t_raw('vendor.shifts.xreport_blind_notice') }}
@else| {{ t_raw('vendor.shifts.col_tender') }} | {{ t_raw('vendor.shifts.col_paid_orders') }} | {{ t_raw('vendor.shifts.col_takings') }} |
|---|---|---|
| @php $m = (string) $t['payment_method']; $ico = payment_method_icon($m); echo $ico !== '' ? $ico : e($methodLabels[$m] ?? ucfirst($m)); @endphp | {{ (int) $t['c'] }} | @php /* Card and wallet takings are already banked and can never be counted in the till, so they are shown throughout. The cash line is the till, so it waits for the count like everything else. */ @endphp@if ($isCash && !$reveal){{ t_raw('vendor.shifts.hidden_until_counted') }}@else{{ money($t['s']) }}@endif |
| {{ t_raw('vendor.staff.col_member') }} | {{ t_raw('common.orders') }} | {{ t_raw('vendor.shifts.col_settled') }} | {{ t_raw('vendor.shifts.stat_tips') }} |
|---|---|---|---|
|
{!! brandmark_html($s['avatar'] ?? null, (string) $s['name'], 'md', 'qm-brandmark--round') !!}
{{ (string) $s['name'] }}
|
{{ number_format((int) $s['orders_c']) }} | {{ money($s['settled']) }} | {{ money($s['tips']) }} |
| {{ t_raw('vendor.shifts.col_service_mode') }} | {{ t_raw('common.orders') }} | {{ t_raw('vendor.analytics.kpi_covers') }} | {{ t_raw('vendor.shifts.col_takings') }} |
|---|---|---|---|
| {{ $modeLabels[(string) $m['service_mode']] ?? (string) $m['service_mode'] }} | {{ number_format((int) $m['orders_c']) }} | {!! (int) $m['covers'] > 0 ? number_format((int) $m['covers']) : dash() !!} | {{ money($m['revenue']) }} |
| {{ t_raw('vendor.menu.category_label') }} | {{ t_raw('vendor.shifts.col_units') }} | {{ t_raw('vendor.shifts.col_takings') }} |
|---|---|---|
| {!! (string) $c['category'] !== '' ? e((string) $c['category']) : t('vendor.menu.uncategorised_option') !!} | {{ number_format((int) $c['units']) }} | {{ money($c['revenue']) }} |
{{ t_raw('vendor.shifts.xreport_movements_blind') }}
@else| {{ t_raw('common.when') }} | {{ t_raw('common.type') }} | {{ t_raw('common.amount') }} | {{ t_raw('vendor.shifts.col_order') }} | {{ t_raw('vendor.shifts.col_by') }} | {{ t_raw('common.note') }} |
|---|---|---|---|---|---|
| {!! fmt_clock($m['created_at']) !!} | {{ $typeLabels[$m['type']] ?? ucfirst((string) $m['type']) }} | {{ in_array($m['type'], ['refund', 'payout', 'drop'], true) ? '−' : '+' }}{{ money($m['amount']) }} | {!! or_dash($m['order_number'] ?? null) !!} | {!! or_dash($m['user_name'] ?? null) !!} | {!! or_dash($m['note'] ?? null) !!} |