feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Checkpoint

This commit is contained in:
Dave
2025-11-05 11:14:54 -05:00
parent bedca60744
commit f2faa5b686
10 changed files with 381 additions and 466 deletions

View File

@@ -41,76 +41,90 @@ function buildClientAndOpts(bodyshop) {
*/
function toCombinedSearchPayload(args = {}) {
const q = { ...args };
let kind = (q.kind || "").toString().trim().toLowerCase();
// Decide kind if not provided
let kind = (q.kind || "").toString().trim();
if (!kind) {
if (q.phone) kind = "phone";
else if (q.license) kind = "license";
else if (q.vin) kind = "vin";
else if (q.nameRecId || q.custId) kind = "namerecid";
else if (q.name && (q.name.fname || q.name.lname || q.name.mname || q.name.name)) kind = "name";
else if (q.stkNo || q.stock) kind = "stkno";
else if (q.nameRecId || q.custId) kind = "nameRecId";
else if (typeof q.name === "string" || (q.name && (q.name.fname || q.name.lname || q.name.mname || q.name.name))) {
kind = "name";
} else if (q.stkNo || q.stock) kind = "stkNo";
}
// Map loose aliases into the RR builders expected fields
const payload = { maxResults: q.maxResults || q.maxRecs || 50, kind };
const payload = {
maxResults: q.maxResults || q.maxRecs || 50,
kind
};
switch (kind) {
switch ((kind || "").toLowerCase()) {
case "phone":
payload.kind = "phone";
payload.phone = q.phone;
payload.phone = String(q.phone ?? "").trim();
break;
case "license":
payload.kind = "license";
payload.license = q.license;
payload.license = String(q.license ?? "").trim();
break;
case "vin":
payload.kind = "vin";
payload.vin = q.vin;
payload.vin = String(q.vin ?? "").trim();
break;
case "namerecid":
payload.kind = "nameRecId";
payload.nameRecId = q.nameRecId || q.custId;
payload.nameRecId = String(q.nameRecId ?? q.custId ?? "").trim();
break;
case "stkno":
case "stkNo":
payload.kind = "stkNo";
payload.stkNo = String(q.stkNo ?? q.stock ?? "").trim();
break;
case "name": {
payload.kind = "name";
const name = q.name;
if (name.name) {
payload.name = { name: name.name }; // For LName
} else if (name.fname && name.lname) {
payload.name = {
fname: name.fname,
lname: name.lname,
...(name.mname ? { mname: name.mname } : {})
}; // For FullName
} else if (name.lname) {
payload.name = { name: name.lname }; // Fallback to LName if only lname
} else {
// Invalid; but to handle gracefully, perhaps throw or skip
const n = q.name;
// STRING => last-name-only intent
if (typeof n === "string") {
const last = n.trim();
if (last) payload.name = { name: last }; // <LName Name="..."/>
break;
}
// OBJECT => always treat as FullName (even if only one of the parts is present)
const fname = n?.fname && String(n.fname).trim();
const lname = n?.lname && String(n.lname).trim();
const mname = n?.mname && String(n.mname).trim();
const lastOnly = n?.name && String(n.name).trim();
if (fname || lname || mname) {
const full = {};
if (fname) full.fname = fname;
if (mname) full.mname = mname;
if (lname) full.lname = lname;
payload.name = full; // will render <FullName .../>
} else if (lastOnly) {
payload.name = { name: lastOnly }; // explicit last-only
}
break;
}
case "stkno":
payload.kind = "stkNo";
payload.stkNo = q.stkNo || q.stock;
break;
default:
// Let the RR builder throw the canonical “Unsupported CombinedSearch kind”
payload.kind = q.kind; // may be undefined; RR lib will validate
payload.kind = kind;
}
// Add compatible secondary fields for combinations
if (q.vin && kind !== "vin") payload.vin = q.vin;
if (q.phone && kind !== "phone") payload.phone = q.phone;
if (q.license && kind !== "license") payload.license = q.license;
// Optional vehicle narrowing; the RR builder defaults to ANY/ANY/ANY if omitted
if (q.make || q.model || q.year) {
payload.make = q.make || "ANY";
payload.model = q.model || "ANY";
payload.year = q.year || "ANY";
}
if (q.vin && payload.kind !== "vin") payload.vin = String(q.vin).trim();
if (q.phone && payload.kind !== "phone") payload.phone = String(q.phone).trim();
if (q.license && payload.kind !== "license") payload.license = String(q.license).trim();
return payload;
}
/**