feature/IO-3357-Reynolds-and-Reynolds-DMS-API-Integration / Merges and adjustments

This commit is contained in:
Dave
2025-11-26 15:37:34 -05:00
parent f1bad01cec
commit fa7da3cad0
6 changed files with 73 additions and 23 deletions

View File

@@ -4,6 +4,7 @@ import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { resolveRROpCodeFromBodyshop } from "../../utils/dmsUtils.js";
import { selectBodyshop } from "../../redux/user/user.selectors";
@@ -97,7 +98,7 @@ export function RrAllocationsSummary({ socket, bodyshop, jobId, title }) {
fetchAllocations();
}, [fetchAllocations]);
const opCode = bodyshop?.rr_configuration?.baseOpCode || "28TOZ";
const opCode = resolveRROpCodeFromBodyshop(bodyshop);
const segmentLabelMap = {
partsExtras: "Parts/Extras",

View File

@@ -49,8 +49,8 @@ import {
validatePasswordResetSuccess
} from "./user.actions";
import UserActionTypes from "./user.types";
//import * as amplitude from '@amplitude/analytics-browser';
import posthog from "posthog-js";
import { bodyshopHasDmsKey, determineDMSTypeByBodyshop, DMS_MAP } from "../../utils/dmsUtils";
const fpPromise = FingerprintJS.load();
@@ -387,16 +387,15 @@ export function* SetAuthLevelFromShopDetails({ payload }) {
)
];
const hasDmsKey = bodyshopHasDmsKey(payload);
const dmsType = hasDmsKey ? determineDMSTypeByBodyshop(payload) : null;
const additionalSegments = [
payload.cdk_dealerid && "CDK",
payload.pbs_serialnumber && "PBS",
// payload.rr_dealerid && "Reynolds",
payload.accountingconfig.qbo === true && "QBO",
payload.accountingconfig.qbo === false &&
!payload.cdk_dealerid &&
!payload.pbs_serialnumber &&
// !payload.rr_dealerid &&
"QBD"
dmsType === DMS_MAP.cdk && DMS_MAP.cdk.toUpperCase(),
dmsType === DMS_MAP.pbs && DMS_MAP.pbs.toUpperCase(),
dmsType === DMS_MAP.reynolds && DMS_MAP.reynolds.toUpperCase(),
payload.accountingconfig?.qbo === true && "QBO",
payload.accountingconfig?.qbo === false && !hasDmsKey && "QBD"
].filter(Boolean);
featureSegments.push(...additionalSegments);

View File

@@ -70,3 +70,26 @@ export const isWssMode = (mode) => {
*/
export const bodyshopHasDmsKey = (bodyshop) =>
bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber || bodyshop.rr_dealerid;
/**
* Resolve RR OpCode from bodyshop.rr_configuration.defaults
* Is Duplicated on server/rr/rr-utils.js
* @param bodyshop
* @returns {`${string}${string}${string}`}
*/
export const resolveRROpCodeFromBodyshop = (bodyshop) => {
if (!bodyshop) throw new Error("bodyshop is required");
const cfg = bodyshop?.rr_configuration || {};
const defaults = cfg?.defaults || {};
const prefix = (defaults.prefix ?? "").toString().trim();
const base = (defaults.base ?? "").toString().trim();
const suffix = (defaults.suffix ?? "").toString().trim();
if (!prefix && !base && !suffix) {
throw new Error("No RR OpCode parts found in bodyshop configuration");
}
return `${prefix}${base}${suffix}`;
};

View File

@@ -3,7 +3,7 @@ const { buildClientAndOpts } = require("./rr-lookup");
const CreateRRLogEvent = require("./rr-logger-event");
const { extractRrResponsibilityCenters } = require("./rr-responsibility-centers");
const CdkCalculateAllocations = require("./rr-calculate-allocations").default;
const { resolveRROpCodeFromBodyshop } = require("./rr-utils");
/**
* Derive RR status information from response object.
* @param rrRes
@@ -137,19 +137,17 @@ const exportJobToRR = async (args) => {
allocations = [];
}
// 3) OpCode (global, but overridable)
// - baseOpCode can come from bodyshop or rrCentersConfig (you'll map it in onboarding)
// - txEnvelope can carry an explicit override field (opCode/opcode/op_code)
const baseOpCode = bodyshop?.rr_configuration?.baseOpCode || "28TOZ"; // TODO Change / implement default handling policy
const resolvedBaseOpCode = resolveRROpCodeFromBodyshop(bodyshop);
const opCodeOverride = txEnvelope?.opCode || txEnvelope?.opcode || txEnvelope?.op_code || null;
if (opCodeOverride || baseOpCode) {
opCode = String(opCodeOverride || baseOpCode).trim() || null;
if (opCodeOverride || resolvedBaseOpCode) {
opCode = String(opCodeOverride || resolvedBaseOpCode).trim() || null;
}
CreateRRLogEvent(socket, "SILLY", "RR OP config resolved", {
opCode
opCode,
baseFromConfig: resolvedBaseOpCode
});
// Build RO payload for create.

View File

@@ -16,6 +16,7 @@ const {
defaultRRTTL,
RRCacheEnums
} = require("./rr-utils");
const { resolveRROpCodeFromBodyshop } = require("./rr-utils");
const { GraphQLClient } = require("graphql-request");
const queries = require("../graphql-client/queries");
@@ -924,13 +925,17 @@ const registerRREvents = ({ socket, redisHelpers }) => {
jobAllocations = Array.isArray(ack.jobAllocations) ? ack.jobAllocations : [];
}
// Try to derive OpCode from bodyshop; fall back to default
let opCode = "28TOZ";
// Try to derive OpCode from bodyshop.rr_configuration.defaults; fall back to default
let opCode;
try {
const { bodyshopId } = await getSessionOrSocket(redisHelpers, socket);
const bodyshop = await getBodyshopForSocket({ bodyshopId, socket });
opCode = bodyshop?.rr_configuration?.baseOpCode || opCode;
opCode = resolveRROpCodeFromBodyshop(bodyshop, opCode);
CreateRRLogEvent(socket, "DEBUG", "rr-calculate-allocations: resolved OpCode", {
opCode
});
} catch (e) {
CreateRRLogEvent(socket, "WARN", "rr-calculate-allocations: bodyshop lookup failed, using default OpCode", {
error: e.message

View File

@@ -182,6 +182,29 @@ const getTransactionType = (jobid) => `rr:${jobid}`;
*/
const defaultRRTTL = 60 * 60;
/**
* Resolve RR OpCode from bodyshop.rr_configuration.defaults
* Is Duplicated on client/src/utils/dmsUtils.js
* @param bodyshop
* @returns {string}
*/
const resolveRROpCodeFromBodyshop = (bodyshop) => {
if (!bodyshop) throw new Error("bodyshop is required");
const cfg = bodyshop?.rr_configuration || {};
const defaults = cfg?.defaults || {};
const prefix = (defaults.prefix ?? "").toString().trim();
const base = (defaults.base ?? "").toString().trim();
const suffix = (defaults.suffix ?? "").toString().trim();
if (!prefix && !base && !suffix) {
throw new Error("No RR OpCode parts found in bodyshop configuration");
}
return `${prefix}${base}${suffix}`;
};
module.exports = {
RRCacheEnums,
defaultRRTTL,
@@ -189,5 +212,6 @@ module.exports = {
ownersFromVinBlocks,
makeVehicleSearchPayloadFromJob,
normalizeCustomerCandidates,
readAdvisorNo
readAdvisorNo,
resolveRROpCodeFromBodyshop
};