From b75000471495b30e3208bff974c596cae02f354d Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Tue, 11 Aug 2026 17:31:20 +0000 Subject: [PATCH] Show Newbook fetch timestamp with staleness warning on Daily Cash Up Staff were seeing false 'out of balance' readings when the Newbook totals shown were fetched at page load (or last manual click) and had gone stale during the count, then balanced once re-checked later against fresh Newbook data. Surfacing when the data was last fetched, with a warning past 3 minutes, lets staff catch this before submitting instead of assuming a real shortfall. Co-Authored-By: Claude Sonnet 5 --- frontend/src/pages/DailyCashUp.tsx | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/DailyCashUp.tsx b/frontend/src/pages/DailyCashUp.tsx index 9ff6de2..90bb27c 100644 --- a/frontend/src/pages/DailyCashUp.tsx +++ b/frontend/src/pages/DailyCashUp.tsx @@ -49,6 +49,7 @@ export function DailyCashUp({ user }: Props) { const [notes, setNotes] = useState('') const [attachments, setAttachments] = useState([]) const [newbookTotals, setNewbookTotals] = useState(null) + const [newbookFetchedAt, setNewbookFetchedAt] = useState(null) const [tillPayments, setTillPayments] = useState([]) const [transactionBreakdown, setTransactionBreakdown] = useState(null) const [checkedItems, setCheckedItems] = useState>(new Set()) @@ -174,6 +175,7 @@ export function DailyCashUp({ user }: Props) { setNotes('') setAttachments([]) setNewbookTotals(null) + setNewbookFetchedAt(null) setTillPayments([]) setTransactionBreakdown(null) setCheckedItems(new Set()) @@ -193,6 +195,7 @@ export function DailyCashUp({ user }: Props) { '/newbook/payments', { date } ).then(data => { setNewbookTotals(data.totals) + setNewbookFetchedAt(new Date()) setTillPayments(data.till_payments || []) setTransactionBreakdown(data.transaction_breakdown || null) }).catch(() => { /* silently ignore — button still available */ }) @@ -230,6 +233,7 @@ export function DailyCashUp({ user }: Props) { count: number; totals: PaymentTotals; till_payments: TillPayment[]; transaction_breakdown: TransactionBreakdown }>('/newbook/payments', { date }) setNewbookTotals(data.totals) + setNewbookFetchedAt(new Date()) setTillPayments(data.till_payments || []) setTransactionBreakdown(data.transaction_breakdown || null) flash(`Fetched ${data.count} payment(s) from Newbook.`) @@ -492,9 +496,21 @@ export function DailyCashUp({ user }: Props) {

Newbook Reconciliation

- - {fetching ? <> Fetching… : <> Fetch Payments} - +
+ {newbookFetchedAt && (() => { + const ageMin = (Date.now() - newbookFetchedAt.getTime()) / 60000 + const stale = ageMin >= 3 + return ( + + Fetched {newbookFetchedAt.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' })} + {stale ? ' — re-fetch before submitting' : ''} + + ) + })()} + + {fetching ? <> Fetching… : <> Fetch Payments} + +
{newbookTotals && (