diff --git a/src/api/types.ts b/src/api/types.ts index b196527..6934486 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -560,8 +560,17 @@ export interface OrderRow { */ ordervalue?: number; orderamount?: number; - /** Cash to collect on delivery. Shown only when > 0. */ - collectionamt?: number; + /* + * `collectionamt` was declared here and read by three screens. It does not + * exist in Fiesta — `grep -rn "collectionamt" --include=*.go` returns nothing + * — so every one of them showed a dash or zero from the day it was written. + * Removed 2026-09-28 along with those screens. + * + * A type can describe a field the server has never sent, and nothing catches + * it: the optional marker makes `undefined` legal, and `?? 0` turns it into a + * plausible figure. That is the trap, and it is worth remembering before the + * next optional money field is added on the strength of a field name. + */ deliverycharge?: number; deliveryamt?: number; paymenttype?: number; diff --git a/src/features/store-admin/OrderDetailDrawer.tsx b/src/features/store-admin/OrderDetailDrawer.tsx index b9097ca..b058b9c 100644 --- a/src/features/store-admin/OrderDetailDrawer.tsx +++ b/src/features/store-admin/OrderDetailDrawer.tsx @@ -185,19 +185,18 @@ function Sheet({ label="Value" value={value > 0 ? moneyExact(value) : detailAmount > 0 ? moneyExact(detailAmount) : '—'} /> + {/* A delivery shows what the rider is paid. An order has no second + money figure worth the space: "Cash to collect" stood here and read + `collectionamt`, which Fiesta does not have, so it was a dash on + every order ever opened. See `pages/SalesPage.tsx` for why it cannot + be derived from `paymenttype` either. */} {job ? ( - ) : ( - - )} + ) : null} {/* Counted from the lines when the row carries no count. `itemcount` and `quantity` are both routinely absent on the list read, which is what made this a dash on an order that plainly had something in it. */} diff --git a/src/features/store-admin/pages/SalesPage.tsx b/src/features/store-admin/pages/SalesPage.tsx index 01be0db..2d3a0f1 100644 --- a/src/features/store-admin/pages/SalesPage.tsx +++ b/src/features/store-admin/pages/SalesPage.tsx @@ -5,7 +5,7 @@ import { Card } from '@astryxdesign/core/Card'; import { HStack } from '@astryxdesign/core/HStack'; import { Text } from '@astryxdesign/core/Text'; import { VStack } from '@astryxdesign/core/VStack'; -import { Banknote, Bike, Calculator, IndianRupee, MapPin, Package, Percent, Receipt, ReceiptText, ShoppingCart, Truck, UserX } from 'lucide-react'; +import { Bike, Calculator, IndianRupee, MapPin, Package, Percent, Receipt, ReceiptText, ShoppingCart, Truck, UserX } from 'lucide-react'; import type { DeliveryRow, OrderRow, PosSale, TenantLocation } from '@/api/types'; import { KpiCard } from '@/components/KpiCard'; import { PageHeader } from '@/components/PageHeader'; @@ -89,8 +89,28 @@ function offlineBillNumber(order: OrderRow): string { * - **Deliveries are their own read.** Not a filter over orders. The delivery * row has a rider name, a planned distance AND an actual one, a rider charge * AND a job value, and its own status ladder. - * - **COD only appears when there is cash to collect.** `collectionamt` on - * every row would be a column of dashes. + * + * ── There is no cash-on-delivery figure, and there never was ──────────────── + * + * A COD column, a COD total and a "cash to collect" metric were removed on + * 2026-09-28 because nothing could ever fill them. They read `collectionamt`, + * a field that does not exist anywhere in Fiesta — `grep --include=*.go` + * returns nothing — so all three had shown a dash or zero on every order since + * the day they were written. + * + * It cannot be derived either, which was measured rather than assumed: across + * 800 live orders spanning three tenants and two regions, including 247 + * delivered ones, `orders.paymenttype` is 42 on every single row, and + * `paymentstatus` is not returned by `getorders` at all. There is no signal in + * the data that separates a cash order from a prepaid one. + * + * (The same measurement shows `getdeliveryinsight`'s `payondelivery` and + * `paylater` aggregates are permanently zero — they key on paymenttype 43 and + * 64, which do not occur.) + * + * Bringing COD back means the customer app recording the payment method and + * Fiesta serving it. Until then a blank column promises a number the system + * has never been able to produce, which reads as broken rather than unbuilt. */ export function SalesPage() { const { scoped, selected, branches, tenantid } = useBranchScope(); @@ -279,9 +299,8 @@ export function SalesPage() { const orderTotals = useMemo(() => { const value = orderRows.reduce((sum, row) => sum + orderValue(row), 0); - const cod = orderRows.reduce((sum, row) => sum + (row.collectionamt ?? 0), 0); const qty = orderRows.reduce((sum, row) => sum + orderQuantity(row), 0); - return { value, cod, qty }; + return { value, qty }; }, [orderRows]); const deliveryTotals = useMemo(() => { @@ -407,13 +426,10 @@ export function SalesPage() { tone="accent" icon={} /> - 0 ? 'warning' : 'neutral'} - icon={} - /> + {/* A "Cash to collect" card stood here. It read `collectionamt`, + which Fiesta does not have, so it showed ₹0 on every order ever + listed. See the note at the top of this file for why it cannot + be derived either. */} 0 - ? [{ label: 'COD', value: money(orderTotals.cod), tone: 'warning' as const }] - : []), { label: 'Value', value: money(orderTotals.value), tone: 'accent' as const }, ]} /> @@ -758,7 +771,6 @@ function OrdersTable({ Pickup Drop Qty - COD Amount Status @@ -768,7 +780,6 @@ function OrdersTable({ {/* Keyed on orderheaderid, never orderid — `orderid` is not unique in this tenant's data, a defect the old console hit first. */} {paged.rows.map((row, index) => { - const cod = row.collectionamt ?? 0; const amount = orderValue(row); const verdict = assignability(row, branchOf(row), assigned, released); const stage = orderStage(row, stages); @@ -841,11 +852,6 @@ function OrdersTable({ {orderQuantity(row) || '—'} - {/* Only rendered when there is cash to collect — a COD column - of dashes is a column that costs width and says nothing. */} - 0} isMuted={cod === 0}> - {cod > 0 ? moneyExact(cod) : '—'} - 0} isMuted={amount === 0}> {amount > 0 ? moneyExact(amount) : '—'}