// VMAX Store Manager — the daily close (trust ceremony), variance reports, and the day banner. (function () { const DS = window.VMAX365DesignSystem_0f78b2; const { Button, SegmentedControl, Badge } = DS; const { Icon, Overline } = window.VMAXUI; const { NumberInput, Select } = window.VMAXW; const { K, reasonCodes, mobileChannels } = window.VMAXP; const { useVMAX } = window.VMAXStore; const { Panel } = window.VMAXMGRUI; // ---- The day banner (open / closing / closed; next-morning overlap) ---- function TheDay({ mobile }) { const [s] = useVMAX(); const d = s.day; const closed = d.status === 'closed'; return (
{closed ? 'Day closed' : 'Day open · trading'}
{closed ? `Signed off by ${d.closedBy} at ${d.closedAt} · balances carried to tomorrow` : `${s.day.date} · opened by ${d.openedBy || '—'} · close at end of shift or tomorrow morning`}
{!closed && Continuous}
); } // ---- Daily close ---- function DailyClose({ mobile, who }) { const [s, a] = useVMAX(); const t = s.tally; const c = s.close.counted || {}; const reasons = s.close.reasons || {}; const exp = { cash: t.cash, cold: t.coldCups, hot: t.hotCups, choc: 250 }; const setC = (patch) => a.setCounted(patch); const setR = (k, v) => a.setReason(k, v); const rows = [ { id: 'cash', exp: exp.cash, act: c.cash, tol: 5, unit: 'K' }, { id: 'cold', exp: exp.cold, act: c.cold, tol: 0 }, { id: 'hot', exp: exp.hot, act: c.hot, tol: 0 }, { id: 'choc', exp: exp.choc, act: c.choc, tol: 10 }, ]; const entered = rows.filter((r) => r.act != null && r.act !== ''); const variances = entered.map((r) => ({ ...r, diff: Number(r.act) - r.exp })).filter((r) => Math.abs(r.diff) > r.tol); const openV = variances.filter((r) => !reasons[r.id]); const allEntered = rows.every((r) => r.act != null && r.act !== ''); if (s.close.signed || s.day.status === 'closed') return (
Day closed

Signed off by {s.day.closedBy}. Every variance was recorded with a reason — balances become tomorrow's opening truth.

); return (
setC({ cash: v })} prefix="K" width={84} /> setR('cash', r)} /> {mobileChannels.map((ch) => setC({ mobile: { ...(c.mobile || t.mobile), [ch]: v } })} prefix="K" width={70} />)}
✓ Matched
setC({ cold: v })} width={56} /> setR('cold', r)} /> setC({ hot: v })} width={56} /> setR('hot', r)} /> setC({ choc: v })} width={56} /> setR('choc', r)} note="over tolerance" />
{!allEntered ? 'Count still in progress' : variances.length === 0 ? 'Everything balanced' : `${variances.length} variance${variances.length > 1 ? 's' : ''} to confirm`}
{!allEntered ? 'Enter each counted figure above to finish.' : openV.length ? `${openV.length} still need a reason — a variance without one stays open.` : 'Every variance has a reason. Ready to sign off.'}
); } function CloseSection({ n, title, subtitle, children, mobile }) { return (
{n}

{title}

{subtitle &&

{subtitle}

}
{children}
); } function CountRow({ label, expected, children }) { return (
{label}
System expects {expected}
{children}
); } function DiffLine({ act, exp, tol, unit = '', reasons, onReason, reason, note }) { if (act == null || act === '') return null; const diff = Number(act) - exp; const within = Math.abs(diff) <= tol; const shown = unit === 'K' ? `${diff < 0 ? '−' : '+'}K${Math.abs(diff)}` : `${diff > 0 ? '+' : ''}${diff}`; if (diff === 0) return
✓ Matches
; if (within) return
{shown} · within tolerance
; return (
{shown} {note || 'difference'}