From 73b82877b8ae12ca2851eb877095bda3ff415c66 Mon Sep 17 00:00:00 2001 From: dharaneesh-r Date: Mon, 1 Jun 2026 10:31:36 +0530 Subject: [PATCH] issue --- src/pages/nearle/dispatch/Preview.js | 57 +++++++++++++++++++++------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/pages/nearle/dispatch/Preview.js b/src/pages/nearle/dispatch/Preview.js index 4cad274..aef756b 100644 --- a/src/pages/nearle/dispatch/Preview.js +++ b/src/pages/nearle/dispatch/Preview.js @@ -52,6 +52,12 @@ const tuningTypes = [ const extractRiders = (previewData) => { if (!previewData) return []; const map = new Map(); + // De-dupe by orderid across the whole tree. A rider can legitimately appear + // in multiple zones (one per delivery suburb), so the same rider_id is + // visited more than once. Without this guard, any stale copy left behind + // by applyReconcileResponse gets concatenated into the rider's orders and + // the same orderid is sent twice to /deliveries/createdeliveries. + const seenOrderIds = new Set(); const push = (riderId, riderName, orders) => { if (riderId == null) return; const key = String(riderId); @@ -59,7 +65,14 @@ const extractRiders = (previewData) => { map.set(key, { rider_id: riderId, rider_name: riderName, orders: [] }); } const entry = map.get(key); - entry.orders.push(...(orders || [])); + (orders || []).forEach((o) => { + const oid = o?.orderid != null ? String(o.orderid) : null; + if (oid) { + if (seenOrderIds.has(oid)) return; + seenOrderIds.add(oid); + } + entry.orders.push(o); + }); if (!entry.rider_name && riderName) entry.rider_name = riderName; }; @@ -188,30 +201,46 @@ const applyReconcileResponse = (preview, response) => { ); if (Array.isArray(next.zones) && next.zones.length) { + // Pass 1: wipe every existing copy of a responding rider's orders across + // ALL zones. The server's reconciled list is the single source of truth, + // and a rider can be present in multiple zones (one per delivery suburb). + // The previous "update first match, delete from map" loop left stale + // copies in the other zones, which extractRiders then concatenated into + // duplicate orderids — surfacing as duplicate deliveries on Assign. next.zones.forEach((zone) => { if (!Array.isArray(zone.riders)) return; zone.riders.forEach((r) => { const key = String(r.rider_id ?? r.userid); - if (newOrdersByRider.has(key)) { - r.orders = newOrdersByRider.get(key); - newOrdersByRider.delete(key); - } else { - // Rider wasn't in the response — keep their existing orders untouched. - } + if (newOrdersByRider.has(key)) r.orders = []; }); }); - // Any response riders we didn't place attach to the first zone. - if (newOrdersByRider.size) { - const target = next.zones[0]; - target.riders = target.riders || []; - newOrdersByRider.forEach((orders, riderKey) => { + + // Pass 2: drop the reconciled orders onto the first zone that already + // lists the rider. If the rider isn't anywhere in the tree, append a + // fresh rider entry to zone[0]. + newOrdersByRider.forEach((orders, riderKey) => { + let placed = false; + for (const zone of next.zones) { + if (!Array.isArray(zone.riders)) continue; + const target = zone.riders.find( + (r) => String(r.rider_id ?? r.userid) === riderKey + ); + if (target) { + target.orders = orders; + placed = true; + break; + } + } + if (!placed) { + const target = next.zones[0]; + target.riders = target.riders || []; target.riders.push({ rider_id: Number(riderKey) || riderKey, rider_name: orders[0]?.rider_name || `Rider ${riderKey}`, orders }); - }); - } + } + }); } else { next.zones = [ {