feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration - Checkpoint
This commit is contained in:
@@ -12,17 +12,20 @@ const axios = require("axios");
|
||||
const mustache = require("mustache");
|
||||
const { XMLParser } = require("fast-xml-parser");
|
||||
const RRLogger = require("./rr-logger");
|
||||
const { RR_ACTIONS, RR_SOAP_HEADERS, RR_STAR_SOAP_ACTION, RR_NS, getBaseRRConfig } = require("./rr-constants");
|
||||
const {
|
||||
RR_ACTIONS,
|
||||
RR_SOAP_HEADERS,
|
||||
RR_SOAP_ACTION,
|
||||
RR_NS,
|
||||
getBaseRRConfig,
|
||||
normalizeRRDealerFields
|
||||
} = require("./rr-constants");
|
||||
const { RrApiError } = require("./rr-error");
|
||||
const xmlFormatter = require("xml-formatter");
|
||||
|
||||
/**
|
||||
* Remove XML decl, collapse inter-tag whitespace, strip empty lines,
|
||||
* then pretty-print. Safe for XML because we only touch whitespace
|
||||
* BETWEEN tags, not inside text nodes.
|
||||
/**
|
||||
* Collapse Mustache-induced whitespace and pretty print.
|
||||
* - strips XML decl (inner)
|
||||
* - strips inner XML decl
|
||||
* - removes lines that are only whitespace
|
||||
* - collapses inter-tag whitespace
|
||||
* - formats with consistent indentation
|
||||
@@ -69,25 +72,37 @@ async function renderXmlTemplate(templateName, data) {
|
||||
return rendered.replace(/^\s*<\?xml[^>]*\?>\s*/i, "");
|
||||
}
|
||||
|
||||
// ---------- Config resolution (STAR only) ----------
|
||||
/**
|
||||
* Resolve RR config for STAR transport.
|
||||
*
|
||||
* Policy:
|
||||
* - Base (transport) settings (baseUrl, username, password, ppsysId, wssePasswordType, timeout) come from env.
|
||||
* - Dealer identifiers (dealer/store/branch) MUST be provided by the caller (DB-driven).
|
||||
* - We DO NOT fall back to env for dealer/store/branch here. Only rr-test.js is allowed to do that.
|
||||
*/
|
||||
async function resolveRRConfig(_socket, bodyshopConfig) {
|
||||
const envCfg = getBaseRRConfig();
|
||||
const baseEnv = getBaseRRConfig();
|
||||
|
||||
if (bodyshopConfig && typeof bodyshopConfig === "object") {
|
||||
return {
|
||||
...envCfg,
|
||||
baseUrl: bodyshopConfig.baseUrl || envCfg.baseUrl,
|
||||
username: bodyshopConfig.username || envCfg.username,
|
||||
password: bodyshopConfig.password || envCfg.password,
|
||||
ppsysId: bodyshopConfig.ppsysId || envCfg.ppsysId,
|
||||
dealerNumber: bodyshopConfig.dealer_number || envCfg.dealerNumber,
|
||||
storeNumber: bodyshopConfig.store_number || envCfg.storeNumber,
|
||||
branchNumber: bodyshopConfig.branch_number || envCfg.branchNumber,
|
||||
wssePasswordType: bodyshopConfig.wssePasswordType || envCfg.wssePasswordType || "Text",
|
||||
timeout: envCfg.timeout
|
||||
};
|
||||
const { dealerNumber, storeNumber, branchNumber } = normalizeRRDealerFields(bodyshopConfig || {});
|
||||
if (!dealerNumber || !storeNumber || !branchNumber) {
|
||||
throw new Error(
|
||||
"Missing dealer/store/branch in RR config. These must be loaded from the database (no env fallback here)."
|
||||
);
|
||||
}
|
||||
return envCfg;
|
||||
|
||||
return {
|
||||
baseUrl: bodyshopConfig?.baseUrl || baseEnv.baseUrl,
|
||||
username: bodyshopConfig?.username || baseEnv.username,
|
||||
password: bodyshopConfig?.password || baseEnv.password,
|
||||
ppsysId: bodyshopConfig?.ppsysId || baseEnv.ppsysId,
|
||||
wssePasswordType: bodyshopConfig?.wssePasswordType || baseEnv.wssePasswordType || "Text",
|
||||
timeout: baseEnv.timeout,
|
||||
|
||||
// canonical identifiers (DB-driven only)
|
||||
dealerNumber,
|
||||
storeNumber,
|
||||
branchNumber
|
||||
};
|
||||
}
|
||||
|
||||
// ---------- Response parsing ----------
|
||||
@@ -161,8 +176,7 @@ function parseRRResponse(xml) {
|
||||
|
||||
// ---------- STAR envelope helpers ----------
|
||||
function wrapWithApplicationArea(innerXml, { CreationDateTime, BODId, Sender, Destination }) {
|
||||
// Make sure we inject *inside* the STAR root, not before it.
|
||||
// 1) Strip any XML declaration just in case (idempotent)
|
||||
// Strip any inner XML declaration (idempotent)
|
||||
let xml = innerXml.replace(/^\s*<\?xml[^>]*\?>\s*/i, "");
|
||||
|
||||
const appArea = `
|
||||
@@ -182,8 +196,7 @@ function wrapWithApplicationArea(innerXml, { CreationDateTime, BODId, Sender, De
|
||||
</Destination>
|
||||
</ApplicationArea>`.trim();
|
||||
|
||||
// Inject right after the opening tag of the root element (skip processing instructions)
|
||||
// e.g. <rey_RomeGetAdvisorsReq ...> ==> insert ApplicationArea here
|
||||
// Inject right after the opening tag of the root element
|
||||
xml = xml.replace(/^(\s*<[^!?][^>]*>)/, `$1\n${appArea}\n`);
|
||||
|
||||
return xml;
|
||||
@@ -229,7 +242,7 @@ async function MakeRRCall({
|
||||
action,
|
||||
body,
|
||||
socket,
|
||||
dealerConfig, // optional per-shop overrides
|
||||
dealerConfig, // required in runtime code; rr-test.js can still pass env-inflated cfg
|
||||
retries = 1,
|
||||
jobid
|
||||
}) {
|
||||
@@ -237,6 +250,7 @@ async function MakeRRCall({
|
||||
throw new Error(`Invalid RR action: ${action}`);
|
||||
}
|
||||
|
||||
// Prefer explicit dealerConfig from caller; otherwise enforce DB-provided config via resolveRRConfig
|
||||
const cfg = dealerConfig || (await resolveRRConfig(socket, undefined));
|
||||
const baseUrl = cfg.baseUrl;
|
||||
if (!baseUrl) throw new Error("Missing RR base URL");
|
||||
@@ -246,8 +260,7 @@ async function MakeRRCall({
|
||||
const renderedBusiness = await renderXmlTemplate(templateName, body?.data || {});
|
||||
|
||||
// Build STAR envelope
|
||||
let envelope = await buildStarEnvelope(renderedBusiness, cfg, body?.appArea);
|
||||
|
||||
const envelope = await buildStarEnvelope(renderedBusiness, cfg, body?.appArea);
|
||||
const formattedEnvelope = prettyPrintXml(envelope);
|
||||
|
||||
// Guardrails
|
||||
@@ -255,11 +268,11 @@ async function MakeRRCall({
|
||||
throw new Error("STAR envelope malformed: missing ProcessMessage/ApplicationArea");
|
||||
}
|
||||
|
||||
const headers = { ...RR_SOAP_HEADERS, SOAPAction: RR_STAR_SOAP_ACTION };
|
||||
const headers = { ...RR_SOAP_HEADERS, SOAPAction: RR_SOAP_ACTION };
|
||||
|
||||
RRLogger(socket, "debug", `Sending RR SOAP request`, {
|
||||
action,
|
||||
soapAction: RR_STAR_SOAP_ACTION,
|
||||
soapAction: RR_SOAP_ACTION,
|
||||
endpoint: baseUrl,
|
||||
jobid,
|
||||
mode: "STAR"
|
||||
|
||||
Reference in New Issue
Block a user