feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - rr-Utils hardening
This commit is contained in:
@@ -45,8 +45,7 @@ const makeVehicleSearchPayloadFromJob = (job) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize customer candidates from VIN blocks
|
||||
* Adds `vinOwner` (and keeps `isVehicleOwner` for backward compat).
|
||||
* Normalize customer candidates from VIN/name blocks, including address + owner flag
|
||||
* @param res
|
||||
* @param ownersSet
|
||||
* @returns {any[]}
|
||||
@@ -54,6 +53,51 @@ const makeVehicleSearchPayloadFromJob = (job) => {
|
||||
const normalizeCustomerCandidates = (res, { ownersSet = null } = {}) => {
|
||||
const blocks = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
|
||||
const out = [];
|
||||
|
||||
const pickAddr = (addrArr) => {
|
||||
const arr = Array.isArray(addrArr) ? addrArr : addrArr ? [addrArr] : [];
|
||||
if (!arr.length) return null;
|
||||
|
||||
const chosen = arr.find((a) => (a?.Type || a?.type || "").toString().toUpperCase() === "P") || arr[0];
|
||||
|
||||
// NEW: include County
|
||||
const line1 = chosen?.Addr1 ?? chosen?.AddressLine1 ?? chosen?.Line1 ?? chosen?.Street1 ?? undefined;
|
||||
const line2 = chosen?.Addr2 ?? chosen?.AddressLine2 ?? chosen?.Line2 ?? chosen?.Street2 ?? undefined;
|
||||
const city = chosen?.City ?? chosen?.city ?? undefined;
|
||||
const state = chosen?.State ?? chosen?.StateOrProvince ?? chosen?.state ?? undefined;
|
||||
const postalCode = chosen?.Zip ?? chosen?.PostalCode ?? chosen?.zip ?? undefined;
|
||||
const country = chosen?.Country ?? chosen?.CountryCode ?? chosen?.country ?? undefined;
|
||||
const county = chosen?.County ?? chosen?.county ?? undefined; // << added
|
||||
|
||||
// instrumentation (kept minimal; County is now expected)
|
||||
if ((process.env.RR_DEBUG_ADDR ?? "1") !== "0") {
|
||||
const allowed = new Set([
|
||||
"Type",
|
||||
"Addr1",
|
||||
"AddressLine1",
|
||||
"Line1",
|
||||
"Street1",
|
||||
"Addr2",
|
||||
"AddressLine2",
|
||||
"Line2",
|
||||
"Street2",
|
||||
"City",
|
||||
"State",
|
||||
"StateOrProvince",
|
||||
"Zip",
|
||||
"PostalCode",
|
||||
"Country",
|
||||
"CountryCode",
|
||||
"County" // << allow County
|
||||
]);
|
||||
const unknown = Object.keys(chosen || {}).filter((k) => !allowed.has(k));
|
||||
if (unknown.length) console.log("[RR:normCandidates] Unexpected address keys seen:", unknown);
|
||||
}
|
||||
|
||||
if (!line1 && !city && !state && !postalCode && !country && !county) return null;
|
||||
return { line1, line2, city, state, postalCode, country, county };
|
||||
};
|
||||
|
||||
for (const blk of blocks) {
|
||||
const serv = Array.isArray(blk?.ServVehicle) ? blk.ServVehicle : [];
|
||||
const custNos = serv.map((sv) => sv?.VehicleServInfo?.CustomerNo).filter(Boolean);
|
||||
@@ -61,35 +105,49 @@ const normalizeCustomerCandidates = (res, { ownersSet = null } = {}) => {
|
||||
const nci = blk?.NameContactId;
|
||||
const ind = nci?.NameId?.IndName;
|
||||
const bus = nci?.NameId?.BusName;
|
||||
const personal = [ind?.FirstName || ind?.FName, ind?.LastName || ind?.LName].filter(Boolean).join(" ").trim();
|
||||
const company = bus?.CompanyName || bus?.BName;
|
||||
|
||||
const personal = [ind?.FirstName ?? ind?.FName, ind?.LastName ?? ind?.LName].filter(Boolean).join(" ").trim();
|
||||
const company = bus?.CompanyName ?? bus?.BName;
|
||||
const name = (personal || company || "").trim();
|
||||
|
||||
const address = pickAddr(nci?.Address);
|
||||
|
||||
for (const custNo of custNos) {
|
||||
const cno = String(custNo).trim();
|
||||
const isOwner = !!(ownersSet && ownersSet.has(cno));
|
||||
if (!cno) continue;
|
||||
|
||||
const item = {
|
||||
custNo: cno,
|
||||
name: name || `Customer ${cno}`,
|
||||
vinOwner: isOwner,
|
||||
isVehicleOwner: isOwner // legacy key kept for any older FE code
|
||||
address: address || undefined
|
||||
};
|
||||
|
||||
if (ownersSet && ownersSet.has(cno)) {
|
||||
item.isVehicleOwner = true;
|
||||
item.vinOwner = true;
|
||||
}
|
||||
|
||||
out.push(item);
|
||||
}
|
||||
}
|
||||
// Dedup by custNo, keep vinOwner/isVehicleOwner if any
|
||||
const seen = new Map();
|
||||
|
||||
const byId = new Map();
|
||||
for (const c of out) {
|
||||
const key = (c.custNo || "").trim();
|
||||
if (!key) continue;
|
||||
const prev = seen.get(key);
|
||||
if (!prev) {
|
||||
seen.set(key, c);
|
||||
} else if ((c.vinOwner || c.isVehicleOwner) && !(prev.vinOwner || prev.isVehicleOwner)) {
|
||||
seen.set(key, { ...prev, vinOwner: true, isVehicleOwner: true });
|
||||
const prev = byId.get(key);
|
||||
if (!prev) byId.set(key, c);
|
||||
else {
|
||||
byId.set(key, {
|
||||
...prev,
|
||||
isVehicleOwner: prev.isVehicleOwner || c.isVehicleOwner,
|
||||
vinOwner: prev.vinOwner || c.vinOwner,
|
||||
address: prev.address || c.address
|
||||
});
|
||||
}
|
||||
}
|
||||
return Array.from(seen.values());
|
||||
|
||||
return Array.from(byId.values());
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -99,12 +157,13 @@ const normalizeCustomerCandidates = (res, { ownersSet = null } = {}) => {
|
||||
* @returns {string|null}
|
||||
*/
|
||||
const readAdvisorNo = (payload, cached) => {
|
||||
const v =
|
||||
(payload?.txEnvelope?.advisorNo != null && String(payload.txEnvelope.advisorNo)) ||
|
||||
(payload?.advisorNo != null && String(payload.advisorNo)) ||
|
||||
(cached != null && String(cached)) ||
|
||||
null;
|
||||
return v && v.trim() !== "" ? v : null;
|
||||
const tx = payload?.txEnvelope || payload?.envelope || {};
|
||||
|
||||
const get = (v) => (v != null && String(v).trim() !== "" ? String(v).trim() : null);
|
||||
|
||||
let value = get(tx?.advisorNo) || get(payload?.advisorNo) || get(cached) || null;
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user