98 lines
3.3 KiB
JavaScript
98 lines
3.3 KiB
JavaScript
/**
|
|
* RR WSDL / SOAP XML Transport Layer (thin wrapper)
|
|
* -------------------------------------------------
|
|
* Delegates to rr-helpers.MakeRRCall (which handles:
|
|
* - fetching dealer config from DB via resolveRRConfig
|
|
* - rendering Mustache XML templates
|
|
* - building SOAP envelope + headers
|
|
* - axios POST + retries
|
|
*
|
|
* Use this when you prefer the "action + variables" style and (optionally)
|
|
* want a parsed Body node back instead of raw XML.
|
|
*/
|
|
|
|
const { XMLParser } = require("fast-xml-parser");
|
|
const logger = require("../utils/logger");
|
|
const { MakeRRCall, resolveRRConfig, renderXmlTemplate } = require("./rr-helpers");
|
|
|
|
// Map friendly action names to template filenames (no envelope here; helpers add it)
|
|
const RR_ACTION_MAP = {
|
|
CustomerInsert: { file: "InsertCustomer.xml" },
|
|
CustomerUpdate: { file: "UpdateCustomer.xml" },
|
|
ServiceVehicleInsert: { file: "InsertServiceVehicle.xml" },
|
|
CombinedSearch: { file: "CombinedSearch.xml" },
|
|
GetParts: { file: "GetParts.xml" },
|
|
GetAdvisors: { file: "GetAdvisors.xml" },
|
|
CreateRepairOrder: { file: "CreateRepairOrder.xml" },
|
|
UpdateRepairOrder: { file: "UpdateRepairOrder.xml" }
|
|
};
|
|
|
|
/**
|
|
* Optionally render just the body XML for a given action (no SOAP envelope).
|
|
* Mostly useful for diagnostics/tests.
|
|
*/
|
|
async function buildRRXml(action, variables = {}) {
|
|
const entry = RR_ACTION_MAP[action];
|
|
if (!entry) throw new Error(`Unknown RR action: ${action}`);
|
|
const templateName = entry.file.replace(/\.xml$/i, "");
|
|
return renderXmlTemplate(templateName, variables);
|
|
}
|
|
|
|
/**
|
|
* Send an RR SOAP request using helpers (action + variables).
|
|
* @param {object} opts
|
|
* @param {string} opts.action One of RR_ACTION_MAP keys (and RR_ACTIONS in rr-constants)
|
|
* @param {object} opts.variables Mustache variables for the body template
|
|
* @param {object} opts.socket Socket/req for context (bodyshopId + auth)
|
|
* @param {boolean} [opts.raw=false] If true, returns raw XML string
|
|
* @param {number} [opts.retries=1] Transient retry attempts (5xx/network)
|
|
* @returns {Promise<string|object>} Raw XML (raw=true) or parsed Body node
|
|
*/
|
|
async function sendRRRequest({ action, variables = {}, socket, raw = false, retries = 1 }) {
|
|
const entry = RR_ACTION_MAP[action];
|
|
if (!entry) throw new Error(`Unknown RR action: ${action}`);
|
|
|
|
const templateName = entry.file.replace(/\.xml$/i, "");
|
|
const dealerConfig = await resolveRRConfig(socket);
|
|
|
|
// Let MakeRRCall render + envelope + post
|
|
const xml = await MakeRRCall({
|
|
action,
|
|
body: { template: templateName, data: variables },
|
|
socket,
|
|
dealerConfig,
|
|
retries
|
|
});
|
|
|
|
if (raw) return xml;
|
|
|
|
try {
|
|
const parser = new XMLParser({ ignoreAttributes: false });
|
|
const parsed = parser.parse(xml);
|
|
|
|
// Try several common namespace variants for Envelope/Body
|
|
const bodyNode =
|
|
parsed?.Envelope?.Body ||
|
|
parsed?.["soapenv:Envelope"]?.["soapenv:Body"] ||
|
|
parsed?.["SOAP-ENV:Envelope"]?.["SOAP-ENV:Body"] ||
|
|
parsed?.["S:Envelope"]?.["S:Body"] ||
|
|
parsed;
|
|
|
|
return bodyNode;
|
|
} catch (err) {
|
|
logger.log("rr-wsdl-parse-error", "ERROR", "RR", null, {
|
|
action,
|
|
message: err.message,
|
|
stack: err.stack
|
|
});
|
|
// If parsing fails, return raw so caller can inspect
|
|
return xml;
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
sendRRRequest,
|
|
buildRRXml,
|
|
RR_ACTION_MAP
|
|
};
|