console update
This commit is contained in:
@@ -106,6 +106,30 @@ export function num(v: unknown): number {
|
||||
|
||||
export const str = (v: unknown): string => (v == null ? '' : String(v));
|
||||
|
||||
/**
|
||||
* Display name for a customer row. `gettenantcustomers` returns `firstname` /
|
||||
* `lastname` and has NO `customername` or `name` column, so code that read those
|
||||
* fell through to "Unknown Customer" for every customer on the platform. Delivery
|
||||
* rows spell the same person `deliverycustomer`, hence the extra fallbacks.
|
||||
*/
|
||||
export function customerName(r: Row): string {
|
||||
const full = `${str(r.firstname).trim()} ${str(r.lastname).trim()}`.trim();
|
||||
return (
|
||||
full ||
|
||||
str(r.deliverycustomer).trim() ||
|
||||
str(r.customername).trim() ||
|
||||
str(r.name).trim()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The store a customer belongs to. `gettenantcustomers` aliases the
|
||||
* `tenantcustomers.locationid` link as `tenantlocationid` — plain `locationid`
|
||||
* is NOT in the response, so filtering on it matched nothing. `deliverylocationid`
|
||||
* is the saved-address id, a different thing entirely, and must not be used here.
|
||||
*/
|
||||
export const customerStoreId = (r: Row): number => num(r.tenantlocationid) || num(r.locationid);
|
||||
|
||||
/** Fiesta date params want a bare `YYYY-MM-DD`. */
|
||||
export const ymd = (d: Date) =>
|
||||
`${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
@@ -352,27 +376,48 @@ export async function getDeliveries(opts: {
|
||||
pageno?: number;
|
||||
pagesize?: number;
|
||||
}): Promise<Row[]> {
|
||||
const rows = toRows(
|
||||
await fiestaGet('deliveries/getdeliveries', {
|
||||
tenantid: opts.tenantid,
|
||||
// NOTE: do NOT send `locationid` to getdeliveries — the backend's locationid
|
||||
// filter on THIS endpoint is broken: passing a real outlet id returns []
|
||||
// (it doesn't match against the row's own `locationid`), even though
|
||||
// deliverysummary honours the same id and the rows clearly carry it. So we
|
||||
// fetch tenant-wide here and scope by locationid client-side below; the KPI
|
||||
// strip (deliverysummary) keeps using the working server-side filter.
|
||||
applocationid: opts.applocationid,
|
||||
// The backend treats `status` as a LITERAL orderstatus filter — passing
|
||||
// 'all' matches nothing (returns []). Send empty to fetch every status and
|
||||
// let the board filter client-side by its status tabs.
|
||||
status: !opts.status || opts.status === 'all' ? '' : opts.status,
|
||||
fromdate: opts.fromdate,
|
||||
todate: opts.todate,
|
||||
keyword: opts.keyword,
|
||||
pageno: opts.pageno ?? 1,
|
||||
pagesize: opts.pagesize ?? 200,
|
||||
}),
|
||||
);
|
||||
const pagesize = opts.pagesize ?? 200;
|
||||
const fetchPage = async (pageno: number) =>
|
||||
toRows(
|
||||
await fiestaGet('deliveries/getdeliveries', {
|
||||
tenantid: opts.tenantid,
|
||||
// NOTE: do NOT send `locationid` to getdeliveries — the backend's locationid
|
||||
// filter on THIS endpoint is broken: passing a real outlet id returns []
|
||||
// (it doesn't match against the row's own `locationid`), even though
|
||||
// deliverysummary honours the same id and the rows clearly carry it. So we
|
||||
// fetch tenant-wide here and scope by locationid client-side below; the KPI
|
||||
// strip (deliverysummary) keeps using the working server-side filter.
|
||||
applocationid: opts.applocationid,
|
||||
// The backend treats `status` as a LITERAL orderstatus filter — passing
|
||||
// 'all' matches nothing (returns []). Send empty to fetch every status and
|
||||
// let the board filter client-side by its status tabs.
|
||||
status: !opts.status || opts.status === 'all' ? '' : opts.status,
|
||||
fromdate: opts.fromdate,
|
||||
todate: opts.todate,
|
||||
keyword: opts.keyword,
|
||||
pageno,
|
||||
pagesize,
|
||||
}),
|
||||
);
|
||||
|
||||
let rows: Row[];
|
||||
if (opts.pageno) {
|
||||
// An explicit page was asked for — honour it and don't walk the rest.
|
||||
rows = await fetchPage(opts.pageno);
|
||||
} else {
|
||||
// Walk every page. The endpoint has no total-count field, so a short page is
|
||||
// the only end-of-data signal. Previously this fetched page 1 only, which
|
||||
// silently dropped delivery 201+ for a busy tenant-wide day — the dispatch
|
||||
// board looked complete while missing stops. MAX_PAGES caps a runaway loop
|
||||
// if the backend ever ignores `pageno` and keeps returning full pages.
|
||||
const MAX_PAGES = 25;
|
||||
rows = [];
|
||||
for (let page = 1; page <= MAX_PAGES; page++) {
|
||||
const batch = await fetchPage(page);
|
||||
rows.push(...batch);
|
||||
if (batch.length < pagesize) break;
|
||||
}
|
||||
}
|
||||
return opts.locationid ? rows.filter((r) => num(r.locationid) === opts.locationid) : rows;
|
||||
}
|
||||
|
||||
@@ -758,7 +803,14 @@ export async function getTenantCustomers(opts: {
|
||||
locationid: opts.locationid,
|
||||
keyword: opts.keyword ?? '',
|
||||
pageno: opts.pageno ?? 1,
|
||||
pagesize: opts.pagesize ?? 20,
|
||||
// When a store is named the backend joins `customerlocations`, so it
|
||||
// returns one row per SAVED ADDRESS and applies LIMIT to those rows — not
|
||||
// to customers. Live: locationid=1185 → 12 rows → 2 customers (11 of them
|
||||
// one person's addresses). The old default of 20 therefore showed a store
|
||||
// roughly three customers. Ask for enough rows that dedupe still has every
|
||||
// customer to work with; the backend's DISTINCT ON fix makes this generous
|
||||
// rather than load-bearing.
|
||||
pagesize: opts.pagesize ?? 500,
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -423,7 +423,11 @@ export function useFiestaRiderPeriodicLogs(opts: {
|
||||
return useQuery({
|
||||
queryKey: fiestaKeys.riderPeriodicLogs(opts),
|
||||
queryFn: () => getRiderPeriodicLogs(opts),
|
||||
enabled: Boolean(opts.fromdate && opts.todate),
|
||||
// A rider is required. Without this guard the query fired on every page load
|
||||
// with no rider selected — and `riders/getriderperiodiclogs` 404s in both the
|
||||
// riders/ and partners/ namespaces (no such backend route exists), so every
|
||||
// load spent a request on a guaranteed failure.
|
||||
enabled: Boolean((opts.userid || opts.riderid) && opts.fromdate && opts.todate),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user