From 69b4c50e14da454245213edcd916419f562e31f8 Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Thu, 23 Jul 2026 17:39:10 +0000 Subject: [PATCH] Net sales: use forecast (otb + pickup) instead of otb-only for future dates The forecasting API's total.otb is booked-to-date only; total.forecast adds expected pickup and equals otb for past dates anyway. Using otb-only for future days understated expected net sales in the current-week/month forecast sections. Relabelled "(OTB)" cards to "(Forecast)" to match. Co-Authored-By: Claude Sonnet 4.6 --- backend/src/routes/net-sales.js | 11 ++++++----- frontend/src/pages/Monthly.tsx | 4 ++-- frontend/src/pages/Weekly.tsx | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/backend/src/routes/net-sales.js b/backend/src/routes/net-sales.js index e28569c..1fb7d74 100644 --- a/backend/src/routes/net-sales.js +++ b/backend/src/routes/net-sales.js @@ -40,13 +40,14 @@ export async function netSalesRoutes(fastify) { const startStr = batchStart.toISOString().slice(0, 10) const data = await fcFetch(`/forecast/revenue?start_date=${startStr}&days=${batchDays}&type=all&dow_align=true`) for (const d of (data?.data ?? [])) { + // forecast = otb + expected pickup for future dates; equals otb for past dates allDays.push({ date: d.date, - net_sales: parseFloat(d.total?.otb ?? 0), - py_sales: parseFloat(d.total?.prior_final ?? 0), - accom: parseFloat(d.accom?.otb ?? 0), - dry: parseFloat(d.dry?.otb ?? 0), - wet: parseFloat(d.wet?.otb ?? 0), + net_sales: parseFloat(d.total?.forecast ?? d.total?.otb ?? 0), + py_sales: parseFloat(d.total?.prior_final ?? 0), + accom: parseFloat(d.accom?.forecast ?? d.accom?.otb ?? 0), + dry: parseFloat(d.dry?.forecast ?? d.dry?.otb ?? 0), + wet: parseFloat(d.wet?.forecast ?? d.wet?.otb ?? 0), is_past: d.is_past ?? true, }) } diff --git a/frontend/src/pages/Monthly.tsx b/frontend/src/pages/Monthly.tsx index 37c6cd0..6afe5fb 100644 --- a/frontend/src/pages/Monthly.tsx +++ b/frontend/src/pages/Monthly.tsx @@ -303,14 +303,14 @@ export default function Monthly() { )}
-
% Net Sales (OTB)
+
% Net Sales (Forecast)
{pctSalesFull != null ? `${pctSalesFull.toFixed(1)}%` : '—'}
{pyWagesFull != null && pySalesFull > 0 && (
PY {((pyWagesFull / pySalesFull) * 100).toFixed(1)}%
)}
-
Net Sales (OTB)
+
Net Sales (Forecast)
{fmtMoney(netSalesFull)}
{pySalesFull > 0 &&
PY {fmtMoney(pySalesFull)}{pyPct(netSalesFull, pySalesFull)}
}
diff --git a/frontend/src/pages/Weekly.tsx b/frontend/src/pages/Weekly.tsx index 437fb74..1fc68fb 100644 --- a/frontend/src/pages/Weekly.tsx +++ b/frontend/src/pages/Weekly.tsx @@ -272,11 +272,11 @@ export default function Weekly() {
-
% Net Sales (OTB)
+
% Net Sales (Forecast)
{pctSalesFull != null ? `${pctSalesFull.toFixed(1)}%` : '—'}
-
Net Sales (OTB)
+
Net Sales (Forecast)
{fmtMoney(netSalesFull)}
{pySalesFull > 0 &&
PY {fmtMoney(pySalesFull)}{pyPct(netSalesFull, pySalesFull)}
}