e2e changes
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user