Files
doormilxpress_astryx/src/lib/bookingDrops.js

55 lines
2.5 KiB
JavaScript

// ============================================================================
// One pickup, many drops.
//
// A customer-app booking is ONE pickup carrying N destinations — never N
// bookings. `GET /admin/bookings` reports how many each row has
// (`destinationcount`, `totalpackagecount`) without shipping the destination
// array, which is fetched only when a row is opened.
//
// Every helper here has to survive three shapes of row, because all three
// reach the Orders table at once:
//
// 1. The console running AHEAD of the backend that adds these fields, where
// `destinationcount` is undefined. Nothing may change for that row.
// 2. An ordinary single-drop booking, which is most of them.
// 3. A console-created booking, which has no bookingdestinations rows at all
// and reports 0 — distinct from 1, and rendered the same as case 1.
// ============================================================================
export const plural = (count, word) => `${count} ${word}${count === 1 ? '' : 's'}`;
/**
* How many drops one pickup carries, or 0 when the row cannot say.
*
* `Number(undefined) || 0` collapses the absent-field case to 0, which is what
* keeps a console deployed before the backend rendering exactly as it does
* today.
*/
export const dropCountOf = (row) => Number(row?.destinationcount) || 0;
/**
* Whether this pickup created more than one shipment.
*
* The single gate for every multi-drop behaviour on the Orders page: the
* summary line, and — more importantly — the refusal to render the booking's
* own `consignmentstatus` as the row's status. Deliberately `> 1`, never
* `>= 1`: "1 destination · 1 package" on every B2C row is noise on the common
* case, and a single-drop booking's consignment status IS the booking's.
*/
export const isMultiDrop = (row) => dropCountOf(row) > 1;
/**
* The collapsed row's summary — "3 destinations · 4 packages".
*
* Only meaningful when `isMultiDrop(row)`; callers gate on that.
*/
export const dropSummary = (row) => {
const drops = dropCountOf(row);
/* Packages fall back to the destination count rather than to zero. Every
destination carries at least one package, so "3 destinations · 0 packages"
describes a booking the data cannot actually produce — and would be the
reading if the count arrived without the sum. */
const packages = Number(row?.totalpackagecount) || drops;
return `${plural(drops, 'destination')} · ${plural(packages, 'package')}`;
};