feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration -Dedupe
This commit is contained in:
@@ -160,36 +160,8 @@ async function rrGetAdvisors(bodyshop, args = {}) {
|
||||
return res?.data ?? res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parts lookup (graceful if the underlying lib exposes a different name)
|
||||
* @param bodyshop
|
||||
* @param args - common fields like { partNumber, description, make, model, year }
|
||||
*/
|
||||
async function rrGetParts(bodyshop, args = {}) {
|
||||
const { client, opts } = buildClientAndOpts(bodyshop);
|
||||
const payload = {
|
||||
partNumber: args.partNumber ?? args.partNo ?? args.number ?? undefined,
|
||||
description: args.description ?? undefined,
|
||||
make: args.make ?? undefined,
|
||||
model: args.model ?? undefined,
|
||||
year: args.year ?? undefined
|
||||
};
|
||||
|
||||
// Try common method names. If none exist, return an empty list to avoid crashes.
|
||||
if (typeof client.getParts === "function") {
|
||||
const res = await client.getParts(payload, opts);
|
||||
return res?.data ?? res;
|
||||
}
|
||||
if (typeof client.getPartNumbers === "function") {
|
||||
const res = await client.getPartNumbers(payload, opts);
|
||||
return res?.data ?? res;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
rrCombinedSearch,
|
||||
rrGetAdvisors,
|
||||
rrGetParts,
|
||||
buildClientAndOpts
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// RR events aligned to Fortellis flow with Fortellis-style logging via CreateRRLogEvent
|
||||
|
||||
const CreateRRLogEvent = require("../rr/rr-logger-event");
|
||||
const { rrCombinedSearch, rrGetAdvisors, rrGetParts, buildClientAndOpts } = require("../rr/rr-lookup");
|
||||
const { rrCombinedSearch, rrGetAdvisors, buildClientAndOpts } = require("../rr/rr-lookup");
|
||||
const { QueryJobData } = require("../rr/rr-job-helpers");
|
||||
const { exportJobToRR } = require("../rr/rr-job-export");
|
||||
const CdkCalculateAllocations = require("../cdk/cdk-calculate-allocations").default;
|
||||
@@ -46,6 +46,33 @@ function sortVehicleOwnerFirst(list) {
|
||||
.map(({ v }) => v);
|
||||
}
|
||||
|
||||
/**
|
||||
* NEW: merge candidates coming from multiple queries (name + vin) by custNo.
|
||||
* - keeps first non-empty name
|
||||
* - preserves/ORs vinOwner/isVehicleOwner
|
||||
* - keeps first non-empty address
|
||||
*/
|
||||
function mergeByCustNo(items = []) {
|
||||
const byId = new Map();
|
||||
for (const c of items) {
|
||||
const id = (c?.custNo || "").trim();
|
||||
if (!id) continue;
|
||||
const prev = byId.get(id);
|
||||
if (!prev) {
|
||||
byId.set(id, { ...c, isVehicleOwner: !!(c.vinOwner || c.isVehicleOwner) });
|
||||
} else {
|
||||
byId.set(id, {
|
||||
...prev,
|
||||
name: prev.name || c.name,
|
||||
isVehicleOwner: !!(prev.isVehicleOwner || prev.vinOwner || c.isVehicleOwner || c.vinOwner),
|
||||
vinOwner: !!(prev.vinOwner || c.vinOwner || prev.isVehicleOwner || c.isVehicleOwner),
|
||||
address: prev.address || c.address
|
||||
});
|
||||
}
|
||||
}
|
||||
return Array.from(byId.values());
|
||||
}
|
||||
|
||||
async function getSessionOrSocket(redisHelpers, socket) {
|
||||
let sess = null;
|
||||
try {
|
||||
@@ -142,7 +169,10 @@ async function rrMultiCustomerSearch({ bodyshop, job, socket, redisHelpers }) {
|
||||
}
|
||||
}
|
||||
|
||||
return sortVehicleOwnerFirst(merged);
|
||||
// NEW: dedupe across queries (name + vin)
|
||||
const deduped = mergeByCustNo(merged);
|
||||
|
||||
return sortVehicleOwnerFirst(deduped);
|
||||
}
|
||||
|
||||
// ---------------- register handlers ----------------
|
||||
@@ -253,24 +283,6 @@ function registerRREvents({ socket, redisHelpers }) {
|
||||
}
|
||||
});
|
||||
|
||||
// ---------- Parts ----------
|
||||
socket.on("rr-get-parts", async (args = {}, ack) => {
|
||||
try {
|
||||
const { bodyshopId } = await getSessionOrSocket(redisHelpers, socket);
|
||||
const bodyshop = await getBodyshopForSocket({ bodyshopId, socket });
|
||||
CreateRRLogEvent(socket, "DEBUG", "rr-get-parts: begin", { args });
|
||||
const res = await rrGetParts(bodyshop, args);
|
||||
ack?.({ ok: true, result: res });
|
||||
socket.emit("rr-get-parts:result", res);
|
||||
CreateRRLogEvent(socket, "DEBUG", "rr-get-parts: success", {
|
||||
count: Array.isArray(res) ? res.length : undefined
|
||||
});
|
||||
} catch (err) {
|
||||
CreateRRLogEvent(socket, "ERROR", "rr-get-parts: failed", { error: err?.message });
|
||||
ack?.({ ok: false, error: err?.message || "get parts failed" });
|
||||
}
|
||||
});
|
||||
|
||||
// ================= Fortellis-style two-step export =================
|
||||
// 1) Stage export -> search (Full Name + VIN) -> emit rr-select-customer
|
||||
socket.on("rr-export-job", async ({ jobid, jobId, txEnvelope } = {}) => {
|
||||
|
||||
Reference in New Issue
Block a user