This commit is contained in:
2026-06-01 10:31:36 +05:30
parent b8097efbcf
commit 73b82877b8

View File

@@ -52,6 +52,12 @@ const tuningTypes = [
const extractRiders = (previewData) => { const extractRiders = (previewData) => {
if (!previewData) return []; if (!previewData) return [];
const map = new Map(); 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) => { const push = (riderId, riderName, orders) => {
if (riderId == null) return; if (riderId == null) return;
const key = String(riderId); const key = String(riderId);
@@ -59,7 +65,14 @@ const extractRiders = (previewData) => {
map.set(key, { rider_id: riderId, rider_name: riderName, orders: [] }); map.set(key, { rider_id: riderId, rider_name: riderName, orders: [] });
} }
const entry = map.get(key); 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; 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) { 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) => { next.zones.forEach((zone) => {
if (!Array.isArray(zone.riders)) return; if (!Array.isArray(zone.riders)) return;
zone.riders.forEach((r) => { zone.riders.forEach((r) => {
const key = String(r.rider_id ?? r.userid); const key = String(r.rider_id ?? r.userid);
if (newOrdersByRider.has(key)) { if (newOrdersByRider.has(key)) r.orders = [];
r.orders = newOrdersByRider.get(key); });
newOrdersByRider.delete(key); });
} else {
// Rider wasn't in the response — keep their existing orders untouched. // 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) {
// Any response riders we didn't place attach to the first zone.
if (newOrdersByRider.size) {
const target = next.zones[0]; const target = next.zones[0];
target.riders = target.riders || []; target.riders = target.riders || [];
newOrdersByRider.forEach((orders, riderKey) => {
target.riders.push({ target.riders.push({
rider_id: Number(riderKey) || riderKey, rider_id: Number(riderKey) || riderKey,
rider_name: orders[0]?.rider_name || `Rider ${riderKey}`, rider_name: orders[0]?.rider_name || `Rider ${riderKey}`,
orders orders
}); });
});
} }
});
} else { } else {
next.zones = [ next.zones = [
{ {