import { buildBulkBookingPayload, buildBulkBookingPayloads } from '@/lib/bulkOrderPayload'; /** * Coordinates on the bulk booking payload. * * This is the regression guard for the billing defect. The builder used * `Number(value) || 0` on all four coordinates, so a row with no usable pin * was submitted as (0, 0) — and the backend cannot tell that apart from a * deliberate pin in the Gulf of Guinea. * * Both failure modes came from that one substitution: * * • With a charge quoted, the console had measured the distance from those * same 0,0 coordinates. OSRM refuses to route to open ocean, so the * Haversine fallback returned roughly 11,000 km, and adminController * honours a supplied `finalprice` verbatim. Massive overcharge. * • With no charge quoted, the backend measured for itself — and skipped the * calculation entirely, because its guard is * `if booking.Deliverylatitude != 0 && ...`. Base rate, no distance * component. Undercharge. * * A coordinate we do not have is now null, which the server can refuse. */ const PICKUP = { address: 'Doormile Base, Peelamedu', pincode: '641004', city: 'Coimbatore', latitude: 11.0168, longitude: 76.9558, }; const ROW = { firstname: 'Priya', contactno: '9876543210', address: '45 Cross Cut Rd, Gandhipuram', postcode: '641012', city: 'Coimbatore', latitude: 11.0272, longitude: 76.9722, totalcharge: 180, }; const build = (row = {}, pickup = PICKUP) => buildBulkBookingPayload({ row: { ...ROW, ...row }, sharedPickup: pickup, tenantId: 3, tenantLocationId: 7, deliverytime: '2026-09-18 10:00:00', notes: '', anchors: [], }); describe('buildBulkBookingPayload — coordinates', () => { it('passes real coordinates through untouched', () => { const p = build(); expect(p.pickuplatitude).toBe(11.0168); expect(p.pickuplongitude).toBe(76.9558); expect(p.deliverylatitude).toBe(11.0272); expect(p.deliverylongitude).toBe(76.9722); }); it('sends null, NOT 0, for a delivery pin that is missing', () => { const p = build({ latitude: null, longitude: null }); expect(p.deliverylatitude).toBeNull(); expect(p.deliverylongitude).toBeNull(); // The specific regression: 0 would have been priced as an 11,000 km run. expect(p.deliverylatitude).not.toBe(0); }); it('sends null for an empty sheet cell', () => { // An untouched Excel cell arrives as '' rather than null, and // `Number('') || 0` is 0. const p = build({ latitude: '', longitude: '' }); expect(p.deliverylatitude).toBeNull(); expect(p.deliverylongitude).toBeNull(); }); it('sends null for an unparseable sheet cell', () => { const p = build({ latitude: 'N/A', longitude: '--' }); expect(p.deliverylatitude).toBeNull(); expect(p.deliverylongitude).toBeNull(); }); it('refuses to forward a literal zero it was handed', () => { // A row that already carried 0 — which is what the geocoding shim used to // return for a suggestion with no coordinates — must not be laundered // into a valid-looking payload. const p = build({ latitude: 0, longitude: 0 }); expect(p.deliverylatitude).toBeNull(); expect(p.deliverylongitude).toBeNull(); }); it('sends null for a coordinate outside its axis range', () => { const p = build({ latitude: 94.912, longitude: 200 }); expect(p.deliverylatitude).toBeNull(); expect(p.deliverylongitude).toBeNull(); }); it('nulls the pickup end too, rather than relying on the backend rescue', () => { // adminController falls back to the hub or tenant location when pickup is // 0,0. That rescue exists, but sending data that needs rescuing is not the // same as sending correct data. const p = build({}, { ...PICKUP, latitude: null, longitude: undefined }); expect(p.pickuplatitude).toBeNull(); expect(p.pickuplongitude).toBeNull(); }); it('treats the two ends independently', () => { const p = build({ latitude: null, longitude: null }); expect(p.pickuplatitude).toBe(11.0168); expect(p.deliverylatitude).toBeNull(); }); }); describe('buildBulkBookingPayloads — batch', () => { it('nulls only the rows that are missing a pin', () => { const payloads = buildBulkBookingPayloads({ rows: [ROW, { ...ROW, latitude: 0, longitude: 0 }, { ...ROW, latitude: '' }], sharedPickup: PICKUP, tenantId: 3, tenantLocationId: 7, deliverytime: '2026-09-18 10:00:00', notes: '', anchors: [], }); expect(payloads).toHaveLength(3); expect(payloads[0].deliverylatitude).toBe(11.0272); expect(payloads[1].deliverylatitude).toBeNull(); expect(payloads[2].deliverylatitude).toBeNull(); // The good row keeps its longitude even though a sibling lost its latitude. expect(payloads[2].deliverylongitude).toBe(76.9722); }); });