e2e changes

This commit is contained in:
2026-09-16 17:12:30 +05:30
parent 5cb9872037
commit f25b3fcf65
15 changed files with 1057 additions and 583 deletions

View File

@@ -39,10 +39,25 @@ import { assignability, assignedFrom } from '../assignDelivery';
import { useSelection } from '@/components/useSelection';
import { TablePager } from '@/components/TablePager';
import { usePaged } from '@/components/usePaged';
import { isCounterSale } from '../branchStats';
import './deliveries.css';
type Tab = 'orders' | 'deliveries' | 'counter';
/**
* The bill number a counter sale was imported under.
*
* The importer records it twice — `remarks` as `OFFLINE:<billno>`, and
* `ordernotes` as prose — but `getorders` returns only `ordernotes`, so that
* is what this reads. The shop knows the sale by the number printed on the
* slip, and matching it back to their own sheet is the whole point of showing
* it; the platform's `orderid` means nothing to them and is only the fallback.
*/
function offlineBillNumber(order: OrderRow): string {
const found = /\(bill\s+(.+?)\)\s*$/i.exec(String(order.ordernotes ?? ''));
return found?.[1]?.trim() || String(order.orderid ?? '');
}
/**
* Sales — app orders, delivery jobs and counter bills.
*
@@ -94,7 +109,18 @@ export function SalesPage() {
const billPages = usePosBillsByBranch(branchIds, { ...dates.range, pagesize: 200 });
const posSummary = usePosSalesByBranch(branchIds, dates.range);
const allOrders = orders.data ?? [];
/**
* App orders and imported counter bills, told apart.
*
* `uploadofflinesales` writes a till's day into `orders` like any other row,
* tagged `deliverytype = 'OFFLINE'`. Everything on this page treated the
* whole response as online, so an imported bill was counted under "Online
* Orders", added to Order value and Average order, and was missing from the
* Counter sales tab that exists to show it.
*/
const everyOrder = orders.data ?? [];
const allOrders = useMemo(() => everyOrder.filter((row) => !isCounterSale(row)), [everyOrder]);
const importedBills = useMemo(() => everyOrder.filter(isCounterSale), [everyOrder]);
const allDeliveries = deliveries.data ?? [];
const orderRows = useMemo(
@@ -115,6 +141,31 @@ export function SalesPage() {
out.push({ bill, branch: branch?.locationname ?? `Branch ${branchId}` });
}
});
/* Imported bills belong in this table too — they are counter sales that
reached us on a spreadsheet instead of over MQTT.
`terminalid` and `cashiername` are left undefined rather than filled
with a placeholder: a sheet does not say which till rang the sale or who
was on it, and inventing either would put a name against a transaction
that has none. The table already renders a dash for what is missing. */
for (const order of importedBills) {
const branch = branches.find((entry) => entry.locationid === Number(order.locationid));
out.push({
bill: {
locationid: Number(order.locationid ?? 0),
invoicenumber: offlineBillNumber(order),
billedat: order.orderdate,
businessdate: order.orderdate,
total: orderValue(order),
taxamount: Number(order.taxamount ?? 0),
itemcount: Number(order.itemcount ?? 0),
customername: order.deliverycustomer ?? '',
customermobile: order.deliverycontactno ?? '',
},
branch: branch?.locationname ?? order.locationname ?? `Branch ${order.locationid}`,
});
}
const term = keyword.trim().toLowerCase();
return out
.filter(({ bill }) =>
@@ -129,7 +180,7 @@ export function SalesPage() {
adrift of the rest, so newest-first was newest-first only within a
terminal. */
.sort((a, b) => (billedAtMs(b.bill) ?? 0) - (billedAtMs(a.bill) ?? 0));
}, [billPages, branchIds, branches, keyword]);
}, [billPages, branchIds, branches, keyword, importedBills]);
/**
* The tab strip for whichever sub-tab is open.
@@ -152,18 +203,28 @@ export function SalesPage() {
) as Record<StatusKey, number>;
}, [tab, allOrders, allDeliveries]);
const counterTotals = useMemo(
() =>
posSummary.reduce(
(acc, page) => ({
bills: acc.bills + (page.data?.billcount ?? 0),
gross: acc.gross + (page.data?.grosssales ?? 0),
tax: acc.tax + (page.data?.taxcollected ?? 0),
}),
{ bills: 0, gross: 0, tax: 0 },
),
[posSummary],
);
const counterTotals = useMemo(() => {
const fromTills = posSummary.reduce(
(acc, page) => ({
bills: acc.bills + (page.data?.billcount ?? 0),
gross: acc.gross + (page.data?.grosssales ?? 0),
tax: acc.tax + (page.data?.taxcollected ?? 0),
}),
{ bills: 0, gross: 0, tax: 0 },
);
// Plus the days that arrived on a spreadsheet. The POS summary cannot see
// these — they were never in `pos_orders` — so a shop that imports rather
// than syncs had "Counter revenue ₹0" over a table of its own bills.
return importedBills.reduce(
(acc, order) => ({
bills: acc.bills + 1,
gross: acc.gross + orderValue(order),
tax: acc.tax + Number(order.taxamount ?? 0),
}),
fromTills,
);
}, [posSummary, importedBills]);
const orderTotals = useMemo(() => {
const value = orderRows.reduce((sum, row) => sum + orderValue(row), 0);