/** * @file rr-lookup.js * @description Reynolds & Reynolds lookup operations * (Combined Search, Get Advisors, Get Parts) via SOAP/XML templates. */ const { MakeRRCall, RRActions, getDealerConfig } = require("./rr-helpers"); const { assertRrOkXml, extractRrResponseData } = require("./rr-error"); const { mapCombinedSearchVars, mapGetAdvisorsVars, mapGetPartsVars } = require("./rr-mappers"); const RRLogger = require("./rr-logger"); /** * Combined Search * Maps to "Search Customer Service Vehicle Combined" spec (Rome) * * @param {object} options * @param {object} options.socket - Socket or Express req (used for auth + bodyshopId) * @param {object} options.redisHelpers - (unused, kept for parity) * @param {string} options.jobid - Job reference for correlation * @param {Array<[string, string]>} [options.params] - e.g. [["VIN","1HG..."],["LastName","DOE"]] */ async function RrCombinedSearch({ socket, redisHelpers, jobid, params = [] }) { try { RRLogger(socket, "info", "Starting RR Combined Search", { jobid, params }); const bodyshopId = socket?.bodyshopId || socket?.user?.bodyshopid; const dealerConfig = bodyshopId ? await getDealerConfig(bodyshopId) : {}; // Build Mustache variables for server/rr/xml-templates/CombinedSearch.xml const variables = mapCombinedSearchVars({ params, dealerConfig }); const xml = await MakeRRCall({ action: RRActions.CombinedSearch, body: { template: "CombinedSearch", data: variables }, redisHelpers, socket, jobid }); // Validate + normalize const ok = assertRrOkXml(xml, { apiName: "RR Combined Search", allowEmpty: true }); const normalized = extractRrResponseData(ok, { action: "CombinedSearch" }); RRLogger(socket, "debug", "RR Combined Search complete", { jobid, count: Array.isArray(normalized) ? normalized.length : 0 }); return normalized; } catch (error) { RRLogger(socket, "error", `RR Combined Search failed: ${error.message}`, { jobid }); throw error; } } /** * Get Advisors * Maps to "Get Advisors Specification" (Rome) * * @param {object} options * @param {object} options.socket * @param {object} options.redisHelpers * @param {string} options.jobid * @param {Array<[string, string]>} [options.params] */ async function RrGetAdvisors({ socket, redisHelpers, jobid, params = [] }) { try { RRLogger(socket, "info", "Starting RR Get Advisors", { jobid, params }); const bodyshopId = socket?.bodyshopId || socket?.user?.bodyshopid; const dealerConfig = bodyshopId ? await getDealerConfig(bodyshopId) : {}; // Build Mustache variables for server/rr/xml-templates/GetAdvisors.xml const variables = mapGetAdvisorsVars({ params, dealerConfig }); const xml = await MakeRRCall({ action: RRActions.GetAdvisors, body: { template: "GetAdvisors", data: variables }, redisHelpers, socket, jobid }); const ok = assertRrOkXml(xml, { apiName: "RR Get Advisors", allowEmpty: true }); const normalized = extractRrResponseData(ok, { action: "GetAdvisors" }); RRLogger(socket, "debug", "RR Get Advisors complete", { jobid, count: Array.isArray(normalized) ? normalized.length : 0 }); return normalized; } catch (error) { RRLogger(socket, "error", `RR Get Advisors failed: ${error.message}`, { jobid }); throw error; } } /** * Get Parts * Maps to "Get Part Specification" (Rome) * * @param {object} options * @param {object} options.socket * @param {object} options.redisHelpers * @param {string} options.jobid * @param {Array<[string, string]>} [options.params] */ async function RrGetParts({ socket, redisHelpers, jobid, params = [] }) { try { RRLogger(socket, "info", "Starting RR Get Parts", { jobid, params }); const bodyshopId = socket?.bodyshopId || socket?.user?.bodyshopid; const dealerConfig = bodyshopId ? await getDealerConfig(bodyshopId) : {}; // Build Mustache variables for server/rr/xml-templates/GetParts.xml const variables = mapGetPartsVars({ params, dealerConfig }); const xml = await MakeRRCall({ action: RRActions.GetParts, body: { template: "GetParts", data: variables }, redisHelpers, socket, jobid }); const ok = assertRrOkXml(xml, { apiName: "RR Get Parts", allowEmpty: true }); const normalized = extractRrResponseData(ok, { action: "GetParts" }); RRLogger(socket, "debug", "RR Get Parts complete", { jobid, count: Array.isArray(normalized) ? normalized.length : 0 }); return normalized; } catch (error) { RRLogger(socket, "error", `RR Get Parts failed: ${error.message}`, { jobid }); throw error; } } module.exports = { RrCombinedSearch, RrGetAdvisors, RrGetParts };