feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Checkpoint - Remove old attempt at Reynolds Integration in favor of new library.
This commit is contained in:
@@ -1,165 +1,17 @@
|
||||
/**
|
||||
* @file rr-repair-orders.js
|
||||
* @description Rome (Reynolds & Reynolds) Repair Order Integration.
|
||||
* Handles creation and updates of repair orders (BSMRepairOrderRq/Resp).
|
||||
*/
|
||||
const { withClient } = require("./withClient");
|
||||
|
||||
"use strict";
|
||||
|
||||
const { MakeRRCall } = require("./rr-helpers");
|
||||
const { mapRepairOrderCreate, mapRepairOrderUpdate } = require("./rr-mappers");
|
||||
const RRLogger = require("./rr-logger");
|
||||
const { RrApiError } = require("./rr-error");
|
||||
|
||||
/**
|
||||
* Very light sanity checks before we build XML.
|
||||
* We keep these minimal because the mapper may derive some fields.
|
||||
* Throws RrApiError when a required precondition is missing.
|
||||
* @param {"CreateRepairOrder"|"UpdateRepairOrder"} action
|
||||
* @param {Object} job
|
||||
*/
|
||||
function preflight(action, job) {
|
||||
if (!job || !job.id) {
|
||||
throw new RrApiError("Missing job payload or job.id", "RR_BAD_JOB_PAYLOAD");
|
||||
}
|
||||
// VIN is almost always required for BSM RO flows
|
||||
const vin = job?.vehicle?.vin || job?.vehicle?.VIN || job?.VIN || job?.vin;
|
||||
if (!vin) {
|
||||
throw new RrApiError("Missing VIN on job.vehicle", "RR_MISSING_VIN");
|
||||
}
|
||||
|
||||
if (action === "UpdateRepairOrder") {
|
||||
// If your mapper expects a DMS RO number or an external RO number,
|
||||
// you can tighten this guard based on your schema, e.g.:
|
||||
// const hasKey = job?.dms_ro_no || job?.external_ro_number || job?.roNumber;
|
||||
// if (!hasKey) throw new RrApiError("Missing RO key for update", "RR_MISSING_RO_KEY");
|
||||
}
|
||||
async function createRepairOrder({ bodyshopId, payload }) {
|
||||
return withClient(bodyshopId, async (client, routing) => {
|
||||
const res = await client.createRepairOrder(payload, { routing });
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an explicit ApplicationArea override so the envelope is always correct,
|
||||
* even if the helper falls back to defaults. We include routing info
|
||||
* and set Task/ReferenceId for BSM repair orders.
|
||||
* @param {"CreateRepairOrder"|"UpdateRepairOrder"} action
|
||||
* @param {Object} cfg
|
||||
*/
|
||||
function buildAppArea(action, cfg) {
|
||||
const isCreate = action === "CreateRepairOrder";
|
||||
return {
|
||||
Sender: {
|
||||
Component: "Rome",
|
||||
Task: "BSMRO",
|
||||
ReferenceId: isCreate ? "Insert" : "Update"
|
||||
},
|
||||
Destination: {
|
||||
DealerNumber: cfg?.DealerNumber || cfg?.dealerNumber,
|
||||
StoreNumber: cfg?.StoreNumber || cfg?.storeNumber,
|
||||
AreaNumber: cfg?.AreaNumber || cfg?.areaNumber,
|
||||
DestinationNameCode: "RR"
|
||||
}
|
||||
// CreationDateTime and BODId will be provided by rr-helpers if omitted.
|
||||
};
|
||||
async function updateRepairOrder({ bodyshopId, payload }) {
|
||||
return withClient(bodyshopId, async (client, routing) => {
|
||||
const res = await client.updateRepairOrder(payload, { routing });
|
||||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new repair order in Rome.
|
||||
* @param {Socket} socket - active socket connection
|
||||
* @param {Object} job - Hasura job object (including vehicle, customer, joblines)
|
||||
* @param {Object} bodyshopConfig - DMS config for current bodyshop
|
||||
* @returns {Promise<Object>} normalized result
|
||||
*/
|
||||
async function createRepairOrder(socket, job, bodyshopConfig) {
|
||||
const action = "CreateRepairOrder";
|
||||
const template = "CreateRepairOrder"; // maps to xml-templates/CreateRepairOrder.xml
|
||||
|
||||
try {
|
||||
RRLogger(socket, "info", `Starting RR ${action} for job ${job?.id}`, {
|
||||
jobid: job?.id,
|
||||
dealer: bodyshopConfig?.DealerNumber || bodyshopConfig?.dealerNumber,
|
||||
store: bodyshopConfig?.StoreNumber || bodyshopConfig?.storeNumber,
|
||||
area: bodyshopConfig?.AreaNumber || bodyshopConfig?.areaNumber
|
||||
});
|
||||
|
||||
preflight(action, job);
|
||||
const data = mapRepairOrderCreate(job, bodyshopConfig);
|
||||
|
||||
const resultXml = await MakeRRCall({
|
||||
action,
|
||||
body: { template, data },
|
||||
appArea: buildAppArea(action, bodyshopConfig),
|
||||
socket,
|
||||
dealerConfig: bodyshopConfig,
|
||||
jobid: job.id
|
||||
});
|
||||
|
||||
RRLogger(socket, "debug", `${action} completed successfully`, { jobid: job.id });
|
||||
|
||||
return {
|
||||
success: true,
|
||||
dms: "Rome",
|
||||
jobid: job.id,
|
||||
action,
|
||||
xml: resultXml
|
||||
};
|
||||
} catch (error) {
|
||||
RRLogger(socket, "error", `Error in ${action} for job ${job?.id}`, {
|
||||
message: error?.message,
|
||||
stack: error?.stack
|
||||
});
|
||||
throw new RrApiError(`RR CreateRepairOrder failed: ${error.message}`, "CREATE_RO_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing repair order in Rome.
|
||||
* @param {Socket} socket
|
||||
* @param {Object} job
|
||||
* @param {Object} bodyshopConfig
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
async function updateRepairOrder(socket, job, bodyshopConfig) {
|
||||
const action = "UpdateRepairOrder";
|
||||
const template = "UpdateRepairOrder";
|
||||
|
||||
try {
|
||||
RRLogger(socket, "info", `Starting RR ${action} for job ${job?.id}`, {
|
||||
jobid: job?.id,
|
||||
dealer: bodyshopConfig?.DealerNumber || bodyshopConfig?.dealerNumber,
|
||||
store: bodyshopConfig?.StoreNumber || bodyshopConfig?.storeNumber,
|
||||
area: bodyshopConfig?.AreaNumber || bodyshopConfig?.areaNumber
|
||||
});
|
||||
|
||||
preflight(action, job);
|
||||
const data = mapRepairOrderUpdate(job, bodyshopConfig);
|
||||
|
||||
const resultXml = await MakeRRCall({
|
||||
action,
|
||||
body: { template, data },
|
||||
appArea: buildAppArea(action, bodyshopConfig),
|
||||
socket,
|
||||
dealerConfig: bodyshopConfig,
|
||||
jobid: job.id
|
||||
});
|
||||
|
||||
RRLogger(socket, "debug", `${action} completed successfully`, { jobid: job.id });
|
||||
|
||||
return {
|
||||
success: true,
|
||||
dms: "Rome",
|
||||
jobid: job.id,
|
||||
action,
|
||||
xml: resultXml
|
||||
};
|
||||
} catch (error) {
|
||||
RRLogger(socket, "error", `Error in ${action} for job ${job?.id}`, {
|
||||
message: error?.message,
|
||||
stack: error?.stack
|
||||
});
|
||||
throw new RrApiError(`RR UpdateRepairOrder failed: ${error.message}`, "UPDATE_RO_ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createRepairOrder,
|
||||
updateRepairOrder
|
||||
};
|
||||
module.exports = { createRepairOrder, updateRepairOrder };
|
||||
|
||||
Reference in New Issue
Block a user