feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Enhance logging
This commit is contained in:
@@ -1,16 +1,19 @@
|
|||||||
const { buildRRRepairOrderPayload } = require("./rr-job-helpers");
|
const { buildRRRepairOrderPayload } = require("./rr-job-helpers");
|
||||||
const { buildClientAndOpts } = require("./rr-lookup");
|
const { buildClientAndOpts } = require("./rr-lookup");
|
||||||
const { ensureRRServiceVehicle } = require("./rr-service-vehicles");
|
|
||||||
const CreateRRLogEvent = require("./rr-logger-event");
|
const CreateRRLogEvent = require("./rr-logger-event");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export a job to Reynolds & Reynolds as a Repair Order (create or update).
|
* Step 1: Export a job to Reynolds & Reynolds as a *new* Repair Order.
|
||||||
|
*
|
||||||
|
* This is the "create" phase only:
|
||||||
|
* - We always call createRepairOrder
|
||||||
|
* - Any follow-up / finalUpdate is handled by finalizeRRRepairOrder
|
||||||
|
*
|
||||||
* @param args
|
* @param args
|
||||||
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks,customerNo: string, svId: null, roNo: *}>}
|
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks, customerNo: string, svId: string|null, roNo: *}>}
|
||||||
*/
|
*/
|
||||||
const exportJobToRR = async (args) => {
|
const exportJobToRR = async (args) => {
|
||||||
const { bodyshop, job, advisorNo, selectedCustomer, txEnvelope, socket } = args || {};
|
const { bodyshop, job, advisorNo, selectedCustomer, txEnvelope, socket, svId } = args || {};
|
||||||
const existing = txEnvelope?.existing || {};
|
|
||||||
|
|
||||||
if (!bodyshop) throw new Error("exportJobToRR: bodyshop is required");
|
if (!bodyshop) throw new Error("exportJobToRR: bodyshop is required");
|
||||||
if (!job) throw new Error("exportJobToRR: job is required");
|
if (!job) throw new Error("exportJobToRR: job is required");
|
||||||
@@ -24,6 +27,7 @@ const exportJobToRR = async (args) => {
|
|||||||
|
|
||||||
const { client, opts } = buildClientAndOpts(bodyshop);
|
const { client, opts } = buildClientAndOpts(bodyshop);
|
||||||
|
|
||||||
|
// For step 1 we always "Insert" (create). Finalize handles the update.
|
||||||
const finalOpts = {
|
const finalOpts = {
|
||||||
...opts,
|
...opts,
|
||||||
envelope: {
|
envelope: {
|
||||||
@@ -31,35 +35,15 @@ const exportJobToRR = async (args) => {
|
|||||||
sender: {
|
sender: {
|
||||||
...(opts?.envelope?.sender || {}),
|
...(opts?.envelope?.sender || {}),
|
||||||
task: "BSMRO",
|
task: "BSMRO",
|
||||||
// If we have an existing RO number we'll be updating, otherwise inserting
|
referenceId: "Insert"
|
||||||
referenceId: existing?.roNo || existing?.dmsRoNo || existing?.dmsRepairOrderId ? "Update" : "Insert"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure service vehicle for create flows (best-effort)
|
|
||||||
let svId = null;
|
|
||||||
|
|
||||||
if (!(existing?.roNo || existing?.dmsRoNo || existing?.dmsRepairOrderId)) {
|
|
||||||
try {
|
|
||||||
const svRes = await ensureRRServiceVehicle({
|
|
||||||
bodyshop,
|
|
||||||
job,
|
|
||||||
overrides: {},
|
|
||||||
customerNo: String(selected),
|
|
||||||
socket
|
|
||||||
});
|
|
||||||
svId = svRes?.svId || null;
|
|
||||||
CreateRRLogEvent(socket, "INFO", "RR service vehicle ensured", { created: svRes?.created, svId });
|
|
||||||
} catch (e) {
|
|
||||||
CreateRRLogEvent(socket, "WARN", "RR ensure service vehicle failed; continuing", { error: e?.message });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const story = txEnvelope?.story ? String(txEnvelope.story).trim() : null;
|
const story = txEnvelope?.story ? String(txEnvelope.story).trim() : null;
|
||||||
const makeOverride = txEnvelope?.makeOverride ? String(txEnvelope.makeOverride).trim() : null;
|
const makeOverride = txEnvelope?.makeOverride ? String(txEnvelope.makeOverride).trim() : null;
|
||||||
|
|
||||||
// Build RO payload for create/update
|
// Build RO payload for create
|
||||||
const payload = buildRRRepairOrderPayload({
|
const payload = buildRRRepairOrderPayload({
|
||||||
job,
|
job,
|
||||||
selectedCustomer: { customerNo: String(selected), custNo: String(selected) },
|
selectedCustomer: { customerNo: String(selected), custNo: String(selected) },
|
||||||
@@ -68,14 +52,9 @@ const exportJobToRR = async (args) => {
|
|||||||
makeOverride
|
makeOverride
|
||||||
});
|
});
|
||||||
|
|
||||||
// Canonical update key is "roNo" (prefer DMS RO number); accept fallbacks from "existing"
|
const response = await client.createRepairOrder(payload, finalOpts);
|
||||||
const roNoForUpdate = existing?.roNo || existing?.dmsRoNo || existing?.dmsRepairOrderId || null;
|
|
||||||
|
|
||||||
const response = roNoForUpdate
|
CreateRRLogEvent(socket, "INFO", "RR raw Repair Order created", {
|
||||||
? await client.updateRepairOrder({ ...payload, roNo: String(roNoForUpdate) }, finalOpts) // ✅ use roNo on update
|
|
||||||
: await client.createRepairOrder(payload, finalOpts);
|
|
||||||
|
|
||||||
CreateRRLogEvent(socket, "INFO", `RR raw Repair Order ${roNoForUpdate ? "updated" : "created"}`, {
|
|
||||||
payload,
|
payload,
|
||||||
response
|
response
|
||||||
});
|
});
|
||||||
@@ -92,13 +71,16 @@ const exportJobToRR = async (args) => {
|
|||||||
roStatus,
|
roStatus,
|
||||||
statusBlocks: response?.statusBlocks || [],
|
statusBlocks: response?.statusBlocks || [],
|
||||||
customerNo: String(selected),
|
customerNo: String(selected),
|
||||||
|
// svId comes from the earlier ensureRRServiceVehicle call (if the caller passes it)
|
||||||
svId,
|
svId,
|
||||||
roNo
|
roNo
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalize an RR Repair Order by sending finalUpdate: "Y".
|
* Step 2: Finalize an RR Repair Order by sending finalUpdate: "Y".
|
||||||
|
* This is the *update* phase.
|
||||||
|
*
|
||||||
* @param args
|
* @param args
|
||||||
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks}>}
|
* @returns {Promise<{success, data: *, roStatus: *, statusBlocks}>}
|
||||||
*/
|
*/
|
||||||
@@ -146,7 +128,6 @@ const finalizeRRRepairOrder = async (args) => {
|
|||||||
customerNo: String(customerNo),
|
customerNo: String(customerNo),
|
||||||
advisorNo: String(advisorNo),
|
advisorNo: String(advisorNo),
|
||||||
vin: cleanVin,
|
vin: cleanVin,
|
||||||
mileageIn: job?.kmin,
|
|
||||||
mileageOut: job?.kmout,
|
mileageOut: job?.kmout,
|
||||||
estimate: { estimateType: "Final" }
|
estimate: { estimateType: "Final" }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ const buildRRRepairOrderPayload = ({ job, selectedCustomer, advisorNo, story })
|
|||||||
if (!customerNo) throw new Error("No RR customer selected (customerNo/CustNo missing)");
|
if (!customerNo) throw new Error("No RR customer selected (customerNo/CustNo missing)");
|
||||||
|
|
||||||
const adv = advisorNo != null && String(advisorNo).trim() !== "" ? String(advisorNo).trim() : null;
|
const adv = advisorNo != null && String(advisorNo).trim() !== "" ? String(advisorNo).trim() : null;
|
||||||
if (!adv) throw new Error("advisorNo is required for RR export");
|
|
||||||
|
if (!adv) throw new Error("advisorNo is required for RR export");
|
||||||
|
|
||||||
const vinRaw = job?.v_vin;
|
const vinRaw = job?.v_vin;
|
||||||
const vin =
|
const vin =
|
||||||
@@ -95,24 +96,16 @@ const buildRRRepairOrderPayload = ({ job, selectedCustomer, advisorNo, story })
|
|||||||
const ro = job?.ro_number != null ? job.ro_number : job?.id != null ? job.id : null;
|
const ro = job?.ro_number != null ? job.ro_number : job?.id != null ? job.id : null;
|
||||||
if (ro == null) throw new Error("Missing repair order identifier (ro_number/id)");
|
if (ro == null) throw new Error("Missing repair order identifier (ro_number/id)");
|
||||||
|
|
||||||
const mileageIn = job.kmin;
|
|
||||||
|
|
||||||
const roStr = String(ro);
|
const roStr = String(ro);
|
||||||
|
|
||||||
const output = {
|
const output = {
|
||||||
// ---- RO Number (all variants; library currently requires `outsdRoNo`) ----
|
|
||||||
outsdRoNo: roStr,
|
outsdRoNo: roStr,
|
||||||
repairOrderNumber: roStr,
|
repairOrderNumber: roStr,
|
||||||
// ---- Department type (Body) ----
|
|
||||||
departmentType: "B",
|
departmentType: "B",
|
||||||
// ---- VIN variants ----
|
|
||||||
vin,
|
vin,
|
||||||
// ---- Customer number variants ----
|
|
||||||
customerNo: String(customerNo),
|
customerNo: String(customerNo),
|
||||||
// ---- Advisor number variants ----
|
|
||||||
advisorNo: adv,
|
advisorNo: adv,
|
||||||
// ---- Mileage In (new) ----
|
mileageIn: job.kmin
|
||||||
mileageIn
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (story) {
|
if (story) {
|
||||||
|
|||||||
@@ -598,7 +598,8 @@ const registerRREvents = ({ socket, redisHelpers }) => {
|
|||||||
selectedCustomer: { customerNo: effectiveCustNo, custNo: effectiveCustNo },
|
selectedCustomer: { customerNo: effectiveCustNo, custNo: effectiveCustNo },
|
||||||
advisorNo: String(advisorNo),
|
advisorNo: String(advisorNo),
|
||||||
txEnvelope,
|
txEnvelope,
|
||||||
socket
|
socket,
|
||||||
|
svId: ensured?.svId || null
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cache raw export result + pending RO number for finalize
|
// Cache raw export result + pending RO number for finalize
|
||||||
|
|||||||
Reference in New Issue
Block a user