cod fix
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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 ? (
|
||||
<Metric
|
||||
label="Rider charge"
|
||||
value={job.deliverycharges ? moneyExact(job.deliverycharges) : '—'}
|
||||
isSmall
|
||||
/>
|
||||
) : (
|
||||
<Metric
|
||||
label="Cash to collect"
|
||||
value={order?.collectionamt ? moneyExact(order.collectionamt) : '—'}
|
||||
isSmall
|
||||
/>
|
||||
)}
|
||||
) : 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. */}
|
||||
|
||||
@@ -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={<ShoppingCart size={15} />}
|
||||
/>
|
||||
<KpiCard
|
||||
label="Cash to collect"
|
||||
value={money(orderTotals.cod)}
|
||||
note="COD on these orders"
|
||||
tone={orderTotals.cod > 0 ? 'warning' : 'neutral'}
|
||||
icon={<Banknote size={15} />}
|
||||
/>
|
||||
{/* 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. */}
|
||||
<KpiCard
|
||||
label="Items"
|
||||
value={count(orderTotals.qty)}
|
||||
@@ -468,9 +484,6 @@ export function SalesPage() {
|
||||
<TotalsBar
|
||||
label={`${orderRows.length} order${orderRows.length === 1 ? '' : 's'}`}
|
||||
chips={[
|
||||
...(orderTotals.cod > 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({
|
||||
<Th>Pickup</Th>
|
||||
<Th>Drop</Th>
|
||||
<Th>Qty</Th>
|
||||
<Th>COD</Th>
|
||||
<Th>Amount</Th>
|
||||
<Th>Status</Th>
|
||||
<Th />
|
||||
@@ -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({
|
||||
<Td isMuted>
|
||||
<Mono>{orderQuantity(row) || '—'}</Mono>
|
||||
</Td>
|
||||
{/* Only rendered when there is cash to collect — a COD column
|
||||
of dashes is a column that costs width and says nothing. */}
|
||||
<Td isStrong={cod > 0} isMuted={cod === 0}>
|
||||
<Mono>{cod > 0 ? moneyExact(cod) : '—'}</Mono>
|
||||
</Td>
|
||||
<Td isStrong={amount > 0} isMuted={amount === 0}>
|
||||
<Mono>{amount > 0 ? moneyExact(amount) : '—'}</Mono>
|
||||
</Td>
|
||||
|
||||
Reference in New Issue
Block a user