@extends('layouts.dashboard') @section('content') @php /** * Vendor → Inventory: countable stock with a movement ledger. * @var array $items stock rows (+ linked_count) * @var array $dishes restaurant dishes (id, name, stock_item_id) for the link picker * @var array|null $historyItem stock row whose ledger is open (?item=) * @var array $movements ledger rows for $historyItem (newest first) */ $fmtQty = static fn ($v): string => (rtrim(rtrim(number_format((float) $v, 2, '.', ''), '0'), '.') ?: '0'); $reasonLabels = ['sale' => t('vendor.inventory.reason_sale'), 'restock' => t('vendor.inventory.reason_restock'), 'waste' => t('vendor.inventory.reason_waste'), 'adjust' => t('vendor.inventory.reason_adjust'), 'void' => t('vendor.inventory.reason_void')]; $reasonPills = ['sale' => 'qm-pill-blue', 'restock' => 'qm-pill-green', 'waste' => 'qm-pill-red', 'adjust' => 'qm-pill-grey', 'void' => 'qm-pill-amber']; $kpis = $kpis ?? ['items' => 0, 'out' => 0, 'low' => 0, 'value' => 0.0, 'valued' => 0, 'waste_qty' => 0.0, 'waste_events' => 0]; $waste = $waste ?? []; $countSheet = $countSheet ?? []; // The stock list takes no filters beyond the restaurant scope, so the export needs no query string. $qs = ''; @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp
{{ t_raw('vendor.inventory.intro_sub') }}
| {{ t_raw('vendor.inventory.col_item') }} | {{ t_raw('vendor.inventory.col_on_hand') }} | {{ t_raw('vendor.inventory.col_reserved') }} | {{ t_raw('vendor.inventory.col_available') }} | {{ t_raw('vendor.inventory.col_burn') }} | {{ t_raw('vendor.inventory.col_low_at') }} | {{ t_raw('vendor.inventory.col_tracked') }} | {{ t_raw('vendor.inventory.col_dishes') }} | {{ t_raw('common.actions') }} |
|---|---|---|---|---|---|---|---|---|
| {{ $it['name'] }} {{ $it['unit'] }} |
{!! $fmtQty($physical) !!} {{ $it['unit'] }} | {!! $reserved > 0 ? '' . e($fmtQty($reserved)) . ' ' . e($it['unit']) . '' : dash() !!} | {!! $label !!} {!! $fmtQty($it['on_hand']) !!} {{ $it['unit'] }} | @php /* What this item actually consumes on a trading day, and therefore how long the shelf lasts. Cover is the number that decides whether an order goes in today; on-hand alone never could. */ @endphp @php $perDay = (float) ($it['burn_per_day'] ?? 0); $cover = $it['days_cover'] ?? null; @endphp
@if ($perDay <= 0)
{!! dash() !!}
{{ t_raw('vendor.inventory.burn_no_movement') }}
@else
@php
$cTone = $cover === null ? 'grey' : ($cover < 2 ? 'red' : ($cover < 5 ? 'amber' : 'green'));
@endphp
{{ t_raw('vendor.inventory.cover_days', [':n' => $fmtQty($cover)]) }}
{{ t_raw('vendor.inventory.burn_per_day', [':qty' => $fmtQty($perDay) . ' ' . (string) $it['unit']]) }}
@if ((float) ($it['burn_wasted'] ?? 0) > 0){{ t_raw('vendor.inventory.burn_wasted', [':qty' => $fmtQty($it['burn_wasted']) . ' ' . (string) $it['unit']]) }} @endif
@endif
|
{!! $low > 0 ? e($fmtQty($low)) . ' ' . e($it['unit']) : dash() !!} | {{ (int) $it['linked_count'] }} {{ t_raw('vendor.inventory.linked_count_suffix') }} | @partial('row-actions', ['actions' => [ [ 'label' => t_raw('vendor.inventory.aria_record_movement') . ' ' . $it['name'], 'icon' => 'fa-exchange-alt', 'primary' => true, 'attrs' => [ 'data-bs-toggle' => 'modal', 'data-bs-target' => '#invMoveModal', 'data-inv-move' => '', 'data-id' => (int) $it['id'], 'data-name' => $it['name'], 'data-unit' => $it['unit'], 'data-onhand' => $fmtQty($it['on_hand']), ], ], [ 'label' => t_raw('vendor.inventory.aria_movement_history') . ' ' . $it['name'], 'icon' => 'fa-history', 'primary' => true, 'href' => '/vendor/inventory?item=' . (int) $it['id'] . '#inv-history', ], [ 'label' => t_raw('common.edit'), 'icon' => 'fa-pen', 'attrs' => [ 'data-bs-toggle' => 'modal', 'data-bs-target' => '#invModal', 'data-inv-edit' => '', 'data-id' => (int) $it['id'], 'data-name' => $it['name'], 'data-unit' => $it['unit'], 'data-low' => $fmtQty($low), 'data-cost' => $it['unit_cost'] !== null ? $fmtQty($it['unit_cost']) : '', 'data-track' => (int) $it['track'], ], ], [ 'label' => t_raw('common.delete'), 'icon' => 'fa-trash-alt', 'danger' => true, 'form' => [ 'action' => '/vendor/inventory/delete', 'fields' => ['id' => (int) $it['id']], 'confirm' => t_raw('vendor.inventory.confirm_delete_item'), ], ], ]]) |
{{ t_raw('vendor.inventory.waste_sub', [':events' => number_format((int) $kpis['waste_events'])]) }}
| {{ t_raw('vendor.inventory.col_item') }} | {{ t_raw('vendor.inventory.col_written_off') }} | {{ t_raw('common.when') }} | {{ t_raw('vendor.inventory.col_by') }} | {{ t_raw('common.note') }} |
|---|---|---|---|---|
| {{ $w['item_name'] }} | {!! $fmtQty($qty) !!} {{ $w['unit'] }} | {!! fmt_datetime($w['created_at']) !!} | {!! or_dash($w['user_name'] ?? null) !!} | {!! or_dash($w['note'] ?? null) !!} |
{{ t_raw('vendor.inventory.history_sub') }} {!! $fmtQty($historyItem['on_hand']) !!} {{ $historyItem['unit'] }}
| {{ t_raw('common.when') }} | {{ t_raw('common.type') }} | {{ t_raw('vendor.inventory.col_change') }} | {{ t_raw('common.order') }} | {{ t_raw('vendor.inventory.col_by') }} | {{ t_raw('common.note') }} |
|---|---|---|---|---|---|
| {!! fmt_datetime($m['created_at']) !!} | {!! $reasonLabels[$m['reason']] ?? e(ucfirst((string) $m['reason'])) !!} | {{ $delta > 0 ? '+' : '' }}{!! $fmtQty($delta) !!} {{ $historyItem['unit'] }} | {!! or_dash($m['order_number'] ?? null) !!} | {!! or_dash($m['user_name'] ?? null) !!} | {!! or_dash($m['note'] ?? null) !!} |