feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Enhance logging
This commit is contained in:
@@ -129,6 +129,8 @@ const normalizeLog = (input) => {
|
||||
*/
|
||||
const logLevelColor = (level) => {
|
||||
switch ((level || "").toUpperCase()) {
|
||||
case "SILLY":
|
||||
return "purple";
|
||||
case "DEBUG":
|
||||
return "orange";
|
||||
case "INFO":
|
||||
|
||||
@@ -412,6 +412,7 @@ export function DmsContainer({ bodyshop, setBreadcrumbs, setSelectedHeader, inse
|
||||
setActiveLogLevel(value);
|
||||
}}
|
||||
>
|
||||
<Select.Option key="SILLY">SILLY</Select.Option>
|
||||
<Select.Option key="DEBUG">DEBUG</Select.Option>
|
||||
<Select.Option key="INFO">INFO</Select.Option>
|
||||
<Select.Option key="WARN">WARN</Select.Option>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const { RRClient } = require("./lib/index.cjs");
|
||||
const { getRRConfigFromBodyshop } = require("./rr-config");
|
||||
const RRLogger = require("./rr-logger");
|
||||
const CreateRRLogEvent = require("./rr-logger-event");
|
||||
const InstanceManager = require("../utils/instanceMgr").default;
|
||||
|
||||
/**
|
||||
@@ -206,30 +206,35 @@ const buildCustomerPayloadFromJob = (job, overrides = {}) => {
|
||||
* Maps data.dmsRecKey -> customerNo for compatibility with existing callers.
|
||||
*/
|
||||
const createRRCustomer = async ({ bodyshop, job, overrides = {}, socket }) => {
|
||||
const log = RRLogger(socket, { ns: "rr" });
|
||||
const { client, opts } = buildClientAndOpts(bodyshop);
|
||||
const payload = buildCustomerPayloadFromJob(job, overrides);
|
||||
|
||||
let res;
|
||||
let response;
|
||||
try {
|
||||
const safePayload = sanitizeRRCustomerPayload(payload);
|
||||
res = await client.insertCustomer(safePayload, opts);
|
||||
response = await client.insertCustomer(safePayload, opts);
|
||||
CreateRRLogEvent(socket, "SILLY", "RR createRRCustomer called", { response });
|
||||
} catch (e) {
|
||||
log("error", "RR insertCustomer transport error", { message: e?.message, stack: e?.stack, payload });
|
||||
CreateRRLogEvent(socket, "ERROR", "RR insertCustomer transport error", {
|
||||
message: e?.message,
|
||||
stack: e?.stack,
|
||||
payload
|
||||
});
|
||||
throw e;
|
||||
}
|
||||
|
||||
const data = res?.data ?? res;
|
||||
const trx = res?.statusBlocks?.transaction;
|
||||
const data = response?.data ?? response;
|
||||
const trx = response?.statusBlocks?.transaction;
|
||||
|
||||
let customerNo = data?.dmsRecKey;
|
||||
if (!customerNo) {
|
||||
log("error", "RR insertCustomer returned no dmsRecKey/custNo", {
|
||||
CreateRRLogEvent(socket, "ERROR", "RR insertCustomer returned no dmsRecKey/custNo", {
|
||||
status: trx?.status,
|
||||
statusCode: trx?.statusCode,
|
||||
message: trx?.message,
|
||||
data
|
||||
});
|
||||
|
||||
throw new Error(
|
||||
`RR insertCustomer returned no dmsRecKey (status=${trx?.status ?? "?"} code=${trx?.statusCode ?? "?"}${
|
||||
trx?.message ? ` msg=${trx.message}` : ""
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
const { buildRRRepairOrderPayload } = require("./rr-job-helpers");
|
||||
const { buildClientAndOpts } = require("./rr-lookup");
|
||||
const { ensureRRServiceVehicle } = require("./rr-service-vehicles");
|
||||
const RRLogger = require("./rr-logger");
|
||||
const CreateRRLogEvent = require("./rr-logger-event");
|
||||
|
||||
/**
|
||||
* Export a job to Reynolds & Reynolds as a Repair Order (create or update).
|
||||
* @param args
|
||||
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks, xml: *, parsed: any, customerNo: string, svId: null, roNo: *}>}
|
||||
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks,customerNo: string, svId: null, roNo: *}>}
|
||||
*/
|
||||
const exportJobToRR = async (args) => {
|
||||
const { bodyshop, job, advisorNo, selectedCustomer, existing, socket } = args || {};
|
||||
const log = RRLogger(socket, { ns: "rr-export" });
|
||||
|
||||
if (!bodyshop) throw new Error("exportJobToRR: bodyshop is required");
|
||||
if (!job) throw new Error("exportJobToRR: job is required");
|
||||
@@ -48,9 +47,9 @@ const exportJobToRR = async (args) => {
|
||||
socket
|
||||
});
|
||||
svId = svRes?.svId || null;
|
||||
log("info", "RR service vehicle ensured", { created: svRes?.created, svId });
|
||||
CreateRRLogEvent(socket, "INFO", "RR service vehicle ensured", { created: svRes?.created, svId });
|
||||
} catch (e) {
|
||||
log("warn", "RR ensure service vehicle failed; continuing", { error: e?.message });
|
||||
CreateRRLogEvent(socket, "WARN", "RR ensure service vehicle failed; continuing", { error: e?.message });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,23 +63,25 @@ const exportJobToRR = async (args) => {
|
||||
// Canonical update key is "roNo" (prefer DMS RO number); accept fallbacks from "existing"
|
||||
const roNoForUpdate = existing?.roNo || existing?.dmsRoNo || existing?.dmsRepairOrderId || null;
|
||||
|
||||
const rrRes = roNoForUpdate
|
||||
const response = roNoForUpdate
|
||||
? await client.updateRepairOrder({ ...payload, roNo: String(roNoForUpdate) }, finalOpts) // ✅ use roNo on update
|
||||
: await client.createRepairOrder(payload, finalOpts);
|
||||
|
||||
const data = rrRes?.data || null;
|
||||
CreateRRLogEvent(socket, "INFO", `RR raw Repair Order ${roNoForUpdate ? "updated" : "created"}`, {
|
||||
response
|
||||
});
|
||||
|
||||
const data = response?.data || null;
|
||||
const roStatus = data?.roStatus || null;
|
||||
|
||||
// Extract canonical roNo you'll need for finalize step
|
||||
const roNo = data?.dmsRoNo ?? data?.outsdRoNo ?? roStatus?.dmsRoNo ?? null;
|
||||
|
||||
return {
|
||||
success: rrRes?.success === true || roStatus?.status === "Success",
|
||||
success: response?.success === true || roStatus?.status === "Success",
|
||||
data,
|
||||
roStatus,
|
||||
statusBlocks: rrRes?.statusBlocks || [],
|
||||
xml: rrRes?.xml,
|
||||
parsed: rrRes?.parsed,
|
||||
statusBlocks: response?.statusBlocks || [],
|
||||
customerNo: String(selected),
|
||||
svId,
|
||||
roNo
|
||||
@@ -90,11 +91,10 @@ const exportJobToRR = async (args) => {
|
||||
/**
|
||||
* Finalize an RR Repair Order by sending finalUpdate: "Y".
|
||||
* @param args
|
||||
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks, xml: *, parsed: any}>}
|
||||
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks}>}
|
||||
*/
|
||||
const finalizeRRRepairOrder = async (args) => {
|
||||
const { bodyshop, job, advisorNo, customerNo, roNo, vin, socket } = args || {};
|
||||
const log = RRLogger(socket, { ns: "rr-finalize" });
|
||||
|
||||
if (!bodyshop) throw new Error("finalizeRRRepairOrder: bodyshop is required");
|
||||
if (!job) throw new Error("finalizeRRRepairOrder: job is required");
|
||||
@@ -142,7 +142,7 @@ const finalizeRRRepairOrder = async (args) => {
|
||||
estimate: { estimateType: "Final" }
|
||||
};
|
||||
|
||||
log("info", "RR finalize updateRepairOrder", {
|
||||
CreateRRLogEvent(socket, "INFO", "Finalizing RR Repair Order", {
|
||||
roNo: roNoToSend,
|
||||
outsdRoNo: String(externalRo),
|
||||
customerNo: String(customerNo),
|
||||
@@ -157,9 +157,7 @@ const finalizeRRRepairOrder = async (args) => {
|
||||
success: rrRes?.success === true || roStatus?.status === "Success",
|
||||
data,
|
||||
roStatus,
|
||||
statusBlocks: rrRes?.statusBlocks || [],
|
||||
xml: rrRes?.xml,
|
||||
parsed: rrRes?.parsed
|
||||
statusBlocks: rrRes?.statusBlocks || []
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
const baseLogger = require("../utils/logger");
|
||||
|
||||
const safeSerialize = (value) => {
|
||||
try {
|
||||
const seen = new WeakSet();
|
||||
return JSON.stringify(value, (key, val) => {
|
||||
if (typeof val === "bigint") return val.toString();
|
||||
if (val instanceof Error) return { name: val.name, message: val.message, stack: val.stack };
|
||||
if (typeof val === "function") return undefined;
|
||||
if (typeof val === "object" && val !== null) {
|
||||
if (seen.has(val)) return "[Circular]";
|
||||
seen.add(val);
|
||||
if (val instanceof Date) return val.toISOString();
|
||||
if (val instanceof Map) return Object.fromEntries(val);
|
||||
if (val instanceof Set) return Array.from(val);
|
||||
if (typeof Buffer !== "undefined" && Buffer.isBuffer?.(val)) return `<Buffer len=${val.length}>`;
|
||||
}
|
||||
return val;
|
||||
});
|
||||
} catch {
|
||||
try {
|
||||
return String(value);
|
||||
} catch {
|
||||
return "[Unserializable]";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const RRLogger = (_socket, defaults = {}) => {
|
||||
return function log(level = "info", message = "", ctx = {}) {
|
||||
const lvl = String(level || "info").toLowerCase();
|
||||
const iso = new Date().toISOString();
|
||||
|
||||
const msgStr = typeof message === "string" ? message : safeSerialize(message);
|
||||
const mergedCtx = ctx && typeof ctx === "object" ? { ...defaults, ...ctx } : { ...defaults };
|
||||
|
||||
const ctxStr = Object.keys(mergedCtx || {}).length ? ` ${safeSerialize(mergedCtx)}` : "";
|
||||
const line = `[RR] ${iso} [${lvl.toUpperCase()}] ${msgStr}${ctxStr}`;
|
||||
|
||||
const logger = baseLogger?.logger || baseLogger || console;
|
||||
const fn = (logger[lvl] || logger.log || logger.info || console[lvl] || console.log).bind(logger);
|
||||
|
||||
try {
|
||||
fn(line);
|
||||
} catch {
|
||||
try {
|
||||
console.log(line);
|
||||
} catch {
|
||||
// swallow
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = RRLogger;
|
||||
@@ -136,7 +136,7 @@ const rrCombinedSearch = async (bodyshop, args = {}) => {
|
||||
const { client, opts } = buildClientAndOpts(bodyshop);
|
||||
const payload = toCombinedSearchPayload(args);
|
||||
const res = await client.combinedSearch(payload, opts);
|
||||
return res?.data ?? res; // lib returns { success, data, ... }
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -156,8 +156,7 @@ const rrGetAdvisors = async (bodyshop, args = {}) => {
|
||||
advisorNumber: args.advisorNumber ? String(args.advisorNumber) : undefined
|
||||
};
|
||||
|
||||
const res = await client.getAdvisors(payload, opts);
|
||||
return res?.data ?? res;
|
||||
return client.getAdvisors(payload, opts);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -177,16 +177,20 @@ const rrMultiCustomerSearch = async ({ bodyshop, job, socket, redisHelpers }) =>
|
||||
for (const { q, fromVin } of queriesList) {
|
||||
try {
|
||||
CreateRRLogEvent(socket, "DEBUG", `{RR-SEARCH} Executing ${q.kind} query`, { q });
|
||||
const res = await rrCombinedSearch(bodyshop, q);
|
||||
|
||||
const multiResponse = await rrCombinedSearch(bodyshop, q);
|
||||
|
||||
CreateRRLogEvent(socket, "SILLY", "Multi Customer Search - raw combined search", { response: multiResponse });
|
||||
|
||||
if (fromVin) {
|
||||
const blocks = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
|
||||
ownersSet = ownersFromVinBlocks(blocks, job?.v_vin);
|
||||
const multiBlocks = Array.isArray(multiResponse?.data) ? multiResponse.data : [];
|
||||
ownersSet = ownersFromVinBlocks(multiBlocks, job?.v_vin);
|
||||
try {
|
||||
await redisHelpers.setSessionTransactionData(
|
||||
socket.id,
|
||||
getTransactionType(job.id),
|
||||
RRCacheEnums.VINCandidates,
|
||||
blocks,
|
||||
multiBlocks,
|
||||
defaultRRTTL
|
||||
);
|
||||
} catch {
|
||||
@@ -194,7 +198,7 @@ const rrMultiCustomerSearch = async ({ bodyshop, job, socket, redisHelpers }) =>
|
||||
}
|
||||
}
|
||||
|
||||
const norm = normalizeCustomerCandidates(res, { ownersSet });
|
||||
const norm = normalizeCustomerCandidates(multiResponse, { ownersSet });
|
||||
merged.push(...norm);
|
||||
} catch (e) {
|
||||
CreateRRLogEvent(socket, "WARN", "Multi-search subquery failed", { kind: q.kind, error: e.message });
|
||||
@@ -220,24 +224,29 @@ const registerRREvents = ({ socket, redisHelpers }) => {
|
||||
|
||||
CreateRRLogEvent(socket, "DEBUG", "rr-lookup-combined: begin", { jobid, params });
|
||||
|
||||
const res = await rrCombinedSearch(bodyshop, params || {});
|
||||
const response = await rrCombinedSearch(bodyshop, params || {});
|
||||
|
||||
CreateRRLogEvent(socket, "SILLY", "rr-lookup-combined: received response", {
|
||||
response
|
||||
});
|
||||
|
||||
let ownersSet = null;
|
||||
|
||||
if ((params?.kind || "").toLowerCase() === "vin") {
|
||||
const blocks = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
|
||||
const blocks = Array.isArray(response?.data) ? response.data : [];
|
||||
ownersSet = ownersFromVinBlocks(blocks);
|
||||
}
|
||||
|
||||
const normalized = sortVehicleOwnerFirst(normalizeCustomerCandidates(res, { ownersSet }));
|
||||
const normalized = sortVehicleOwnerFirst(normalizeCustomerCandidates(response, { ownersSet }));
|
||||
const rid = resolveJobId(jobid, { jobid }, null);
|
||||
const decorated = normalized.map((c) => (c.vinOwner != null ? c : { ...c, vinOwner: !!c.isVehicleOwner }));
|
||||
|
||||
cb?.({ jobid: rid, data: decorated });
|
||||
|
||||
socket.emit("rr-select-customer", decorated);
|
||||
|
||||
CreateRRLogEvent(socket, "DEBUG", "rr-lookup-combined: emitted rr-select-customer", {
|
||||
count: decorated.length,
|
||||
res
|
||||
count: decorated.length
|
||||
});
|
||||
} catch (e) {
|
||||
CreateRRLogEvent(socket, "ERROR", "RR combined lookup error", { error: e.message, jobid });
|
||||
@@ -291,10 +300,13 @@ const registerRREvents = ({ socket, redisHelpers }) => {
|
||||
|
||||
// 2) Fetch + cache when no cache or forced refresh
|
||||
if (!result) {
|
||||
const live = await rrGetAdvisors(bodyshop, { departmentType: requestedDept });
|
||||
result = Array.isArray(live) ? live : [];
|
||||
const getAdvisorsCall = await rrGetAdvisors(bodyshop, { departmentType: requestedDept });
|
||||
result = Array.isArray(getAdvisorsCall?.data) ? getAdvisorsCall.data : [];
|
||||
try {
|
||||
await redisHelpers.setProviderCache(ns, field, result, ADVISORS_CACHE_TTL);
|
||||
CreateRRLogEvent(socket, "SILLY", "rr-get-advisors: fetched live data", {
|
||||
getAdvisorsCall
|
||||
});
|
||||
CreateRRLogEvent(socket, "DEBUG", "rr-get-advisors: cache populated", {
|
||||
ns,
|
||||
field,
|
||||
@@ -440,22 +452,25 @@ const registerRREvents = ({ socket, redisHelpers }) => {
|
||||
try {
|
||||
const vehQ = makeVehicleSearchPayloadFromJob(job);
|
||||
if (vehQ && vehQ.kind === "vin" && job?.v_vin) {
|
||||
const resVin = await rrCombinedSearch(bodyshop, vehQ);
|
||||
const blocksVin = Array.isArray(resVin?.data) ? resVin.data : Array.isArray(resVin) ? resVin : [];
|
||||
const vinResponse = await rrCombinedSearch(bodyshop, vehQ);
|
||||
|
||||
CreateRRLogEvent(socket, "SILLY", `VIN owner pre-check response`, { response: vinResponse });
|
||||
|
||||
const vinBlocks = Array.isArray(vinResponse?.data) ? vinResponse.data : [];
|
||||
|
||||
try {
|
||||
await redisHelpers.setSessionTransactionData(
|
||||
socket.id,
|
||||
ns,
|
||||
RRCacheEnums.VINCandidates,
|
||||
blocksVin,
|
||||
vinBlocks,
|
||||
defaultRRTTL
|
||||
);
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
|
||||
const ownersSet = ownersFromVinBlocks(blocksVin, job.v_vin);
|
||||
const ownersSet = ownersFromVinBlocks(vinBlocks, job.v_vin);
|
||||
|
||||
if (ownersSet?.size) {
|
||||
const sel = String(selectedCustNo);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const RRLogger = require("./rr-logger");
|
||||
const { buildClientAndOpts, rrCombinedSearch } = require("./rr-lookup");
|
||||
const CreateRRLogEvent = require("./rr-logger-event");
|
||||
|
||||
/**
|
||||
* Pick and normalize VIN from inputs
|
||||
@@ -36,7 +36,7 @@ const pickCustNo = ({ selectedCustomerNo, custNo, customerNo }) => {
|
||||
* @returns {Set<any>}
|
||||
*/
|
||||
const ownersFromCombined = (res, wantedVin) => {
|
||||
const blocks = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
|
||||
const blocks = Array.isArray(res?.data) ? res.data : [];
|
||||
const owners = new Set();
|
||||
for (const blk of blocks) {
|
||||
const serv = Array.isArray(blk?.ServVehicle) ? blk.ServVehicle : [];
|
||||
@@ -72,7 +72,6 @@ const isAlreadyExistsError = (e) => {
|
||||
* - selectedCustomerNo / custNo / customerNo
|
||||
* - license (optional)
|
||||
* - socket (for logging)
|
||||
* - logNs (namespace for logs)
|
||||
*
|
||||
* Returns: { created:boolean, exists:boolean, vin, customerNo, svId?, status? }
|
||||
*/
|
||||
@@ -87,12 +86,9 @@ const ensureRRServiceVehicle = async (args = {}) => {
|
||||
custNo,
|
||||
customerNo,
|
||||
license,
|
||||
socket,
|
||||
logNs = "rr-service-vehicles"
|
||||
socket
|
||||
} = args;
|
||||
|
||||
const log = RRLogger(socket, { ns: logNs });
|
||||
|
||||
// Build/derive essentials
|
||||
let client = inClient;
|
||||
let routing = inRouting;
|
||||
@@ -116,17 +112,24 @@ const ensureRRServiceVehicle = async (args = {}) => {
|
||||
try {
|
||||
let owners = new Set();
|
||||
if (bodyshop) {
|
||||
const comb = await rrCombinedSearch(bodyshop, { kind: "vin", vin: vinStr, maxResults: 50 });
|
||||
owners = ownersFromCombined(comb, vinStr);
|
||||
const combinedSearchResponse = await rrCombinedSearch(bodyshop, { kind: "vin", vin: vinStr, maxResults: 50 });
|
||||
|
||||
CreateRRLogEvent(socket, "silly", "{SV} Preflight combined search by VIN: raw response", {
|
||||
response: combinedSearchResponse
|
||||
});
|
||||
|
||||
owners = ownersFromCombined(combinedSearchResponse, vinStr);
|
||||
}
|
||||
// Short-circuit: VIN exists anywhere -> don't try to insert
|
||||
if (owners.size > 0) {
|
||||
const ownedBySame = owners.has(custNoStr);
|
||||
log(ownedBySame ? "info" : "warn", "{SV} VIN already present in RR; skipping insert", {
|
||||
|
||||
CreateRRLogEvent(socket, ownedBySame ? "info" : "warn", "{SV} VIN already present in RR; skipping insert", {
|
||||
vin: vinStr,
|
||||
selectedCustomerNo: custNoStr,
|
||||
owners: Array.from(owners)
|
||||
});
|
||||
|
||||
return {
|
||||
created: false,
|
||||
exists: true,
|
||||
@@ -137,7 +140,10 @@ const ensureRRServiceVehicle = async (args = {}) => {
|
||||
}
|
||||
} catch (e) {
|
||||
// Preflight shouldn't be fatal; log and continue to insert (idempotency will still be handled)
|
||||
log("warn", "{SV} VIN preflight lookup failed; continuing to insert", { vin: vinStr, error: e?.message });
|
||||
CreateRRLogEvent(socket, "WARN", "{SV} VIN preflight lookup failed; continuing to insert", {
|
||||
vin: vinStr,
|
||||
error: e?.message
|
||||
});
|
||||
}
|
||||
|
||||
// --- Attempt insert (idempotent) ---
|
||||
@@ -163,30 +169,26 @@ const ensureRRServiceVehicle = async (args = {}) => {
|
||||
}
|
||||
};
|
||||
|
||||
log("debug", "{SV} Inserting service vehicle", {
|
||||
CreateRRLogEvent(socket, "info", "{SV} Inserting service vehicle", {
|
||||
vin: vinStr,
|
||||
selectedCustomerNo: custNoStr,
|
||||
payloadShape: Object.keys(insertPayload).filter((k) => insertPayload[k] != null)
|
||||
});
|
||||
|
||||
// Be tolerant to method name differences
|
||||
const fnName =
|
||||
typeof client.insertServiceVehicle === "function"
|
||||
? "insertServiceVehicle"
|
||||
: typeof client.serviceVehicleInsert === "function"
|
||||
? "serviceVehicleInsert"
|
||||
: null;
|
||||
|
||||
if (!fnName) {
|
||||
throw new Error("RR client does not expose insertServiceVehicle/serviceVehicleInsert");
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await client[fnName](insertPayload, insertOpts);
|
||||
const res = await client.insertServiceVehicle(insertPayload, insertOpts);
|
||||
|
||||
CreateRRLogEvent(socket, "silly", "{SV} insertServiceVehicle: raw response", { res });
|
||||
|
||||
const data = res?.data ?? {};
|
||||
const svId = data?.dmsRecKey || data?.svId || undefined;
|
||||
|
||||
log("info", "{SV} insertServiceVehicle: success", { vin: vinStr, customerNo: custNoStr, svId });
|
||||
CreateRRLogEvent(socket, "info", "{SV} insertServiceVehicle: success", {
|
||||
vin: vinStr,
|
||||
customerNo: custNoStr,
|
||||
svId
|
||||
});
|
||||
|
||||
return {
|
||||
created: true,
|
||||
exists: false,
|
||||
@@ -198,12 +200,13 @@ const ensureRRServiceVehicle = async (args = {}) => {
|
||||
} catch (e) {
|
||||
if (isAlreadyExistsError(e)) {
|
||||
// Treat as idempotent success
|
||||
log("warn", "{SV} insertServiceVehicle: already exists; treating as success", {
|
||||
CreateRRLogEvent(socket, "warn", "{SV} insertServiceVehicle: already exists; treating as success", {
|
||||
vin: vinStr,
|
||||
customerNo: custNoStr,
|
||||
code: e?.code,
|
||||
status: e?.meta?.status || e?.status
|
||||
});
|
||||
|
||||
return {
|
||||
created: false,
|
||||
exists: true,
|
||||
@@ -212,11 +215,13 @@ const ensureRRServiceVehicle = async (args = {}) => {
|
||||
status: e?.meta?.status || e?.status
|
||||
};
|
||||
}
|
||||
log("error", "{SV} insertServiceVehicle: failure", {
|
||||
|
||||
CreateRRLogEvent(socket, "error", "{SV} insertServiceVehicle: failure", {
|
||||
message: e?.message,
|
||||
code: e?.code,
|
||||
status: e?.meta?.status || e?.status
|
||||
});
|
||||
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ const makeVehicleSearchPayloadFromJob = (job) => {
|
||||
* @returns {any[]}
|
||||
*/
|
||||
const normalizeCustomerCandidates = (res, { ownersSet = null } = {}) => {
|
||||
const blocks = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
|
||||
const blocks = Array.isArray(res?.data) ? res.data : [];
|
||||
const out = [];
|
||||
|
||||
const pickAddr = (addrArr) => {
|
||||
|
||||
Reference in New Issue
Block a user