Merged in release/2026-04-03 (pull request #3148)

Fix RR
This commit is contained in:
Dave Richer
2026-03-20 18:56:28 +00:00
4 changed files with 33 additions and 18 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -205,8 +205,7 @@ const updateRRRepairOrderWithFullData = async (args) => {
const { client, opts } = buildClientAndOpts(bodyshop); const { client, opts } = buildClientAndOpts(bodyshop);
// For full data update after early RO, we still use "Insert" referenceId // For full data update after early RO, use the RR update route.
// because we're inserting the job operations for the first time
const finalOpts = { const finalOpts = {
...opts, ...opts,
envelope: { envelope: {
@@ -214,7 +213,7 @@ const updateRRRepairOrderWithFullData = async (args) => {
sender: { sender: {
...(opts?.envelope?.sender || {}), ...(opts?.envelope?.sender || {}),
task: "BSMRO", task: "BSMRO",
referenceId: "Insert" referenceId: "Update"
} }
} }
}; };
@@ -317,32 +316,45 @@ const updateRRRepairOrderWithFullData = async (args) => {
opCode opCode
}); });
// Add roNo for linking to existing RO // Update the existing RO created during the early RO step.
payload.finalUpdate = "N";
payload.roNo = String(roNo); payload.roNo = String(roNo);
payload.outsdRoNo = job?.ro_number || job?.id || undefined; payload.outsdRoNo = job?.ro_number || job?.id || undefined;
// Keep rolabor - it's needed to register the job/OpCode accounts in Reynolds // RR update rejects placeholder non-labor ROLABOR rows with zero labor prices.
// Without this, Reynolds won't recognize the OpCode when we send rogg operations // Keep only the actual labor jobs in ROLABOR and let ROGOG carry parts/extras.
// The rolabor section tells Reynolds "these jobs exist" even with minimal data if (payload.rolabor?.ops?.length && payload.rogg?.ops?.length) {
const laborJobNos = new Set(
payload.rogg.ops
.filter((op) => op?.segmentKind === "laborTaxable" || op?.segmentKind === "laborNonTaxable")
.map((op) => String(op.jobNo))
);
CreateRRLogEvent(socket, "INFO", "Preparing full data for early RO (using create with roNo)", { payload.rolabor.ops = payload.rolabor.ops.filter((op) => laborJobNos.has(String(op?.jobNo)));
if (!payload.rolabor.ops.length) {
delete payload.rolabor;
}
}
CreateRRLogEvent(socket, "INFO", "Preparing full data update for existing RR RO", {
roNo: String(roNo), roNo: String(roNo),
hasRolabor: !!payload.rolabor, hasRolabor: !!payload.rolabor,
rolaborCount: payload.rolabor?.ops?.length || 0,
hasRogg: !!payload.rogg, hasRogg: !!payload.rogg,
payload payload
}); });
// Use createRepairOrder (not update) with the roNo to link to the existing early RO const response = await client.updateRepairOrder(payload, finalOpts);
// Reynolds will merge this with the existing RO header
const response = await client.createRepairOrder(payload, finalOpts);
CreateRRLogEvent( CreateRRLogEvent(
socket, socket,
"INFO", "INFO",
"Sending full data for early RO (using create with roNo)", "RR full data update sent for existing RO",
withRRRequestXml(response, { withRRRequestXml(response, {
roNo: String(roNo), roNo: String(roNo),
hasRolabor: !!payload.rolabor, hasRolabor: !!payload.rolabor,
rolaborCount: payload.rolabor?.ops?.length || 0,
hasRogg: !!payload.rogg, hasRogg: !!payload.rogg,
payload, payload,
response response

View File

@@ -368,8 +368,9 @@ const buildRogogFromAllocations = (allocations, { opCode, payType = "Cust", roNo
* *
* We still keep a 1:1 mapping with GOG ops: each op gets a corresponding * We still keep a 1:1 mapping with GOG ops: each op gets a corresponding
* OpCodeLaborInfo entry using the same JobNo and the same tax flag as its * OpCodeLaborInfo entry using the same JobNo and the same tax flag as its
* GOG line. Labor-specific details (hrs/rate) remain zeroed out, and the * GOG line. Labor-specific hours/rate remain zeroed out, but actual labor
* DMS can ignore non-labor ops by virtue of the zero hours/amounts. * sale amounts are mirrored into ROLABOR for labor segments so RR receives
* the expected labor pricing on updates. Non-labor ops remain zeroed.
* *
* @param {Object} rogg - result of buildRogogFromAllocations * @param {Object} rogg - result of buildRogogFromAllocations
* @param {Object} opts * @param {Object} opts
@@ -388,6 +389,8 @@ const buildRolaborFromRogog = (rogg, { payType = "Cust" } = {}) => {
const txFlag = firstLine.custTxblNtxblFlag ?? "N"; const txFlag = firstLine.custTxblNtxblFlag ?? "N";
const linePayType = firstLine.custPayTypeFlag || "C"; const linePayType = firstLine.custPayTypeFlag || "C";
const isLaborSegment = op.segmentKind === "laborTaxable" || op.segmentKind === "laborNonTaxable";
const laborAmount = isLaborSegment ? String(firstLine?.amount?.custPrice ?? "0") : "0";
return { return {
opCode: op.opCode, opCode: op.opCode,
@@ -403,8 +406,8 @@ const buildRolaborFromRogog = (rogg, { payType = "Cust" } = {}) => {
amount: { amount: {
payType, payType,
amtType: "Job", amtType: "Job",
custPrice: "0", custPrice: laborAmount,
totalAmt: "0" totalAmt: laborAmount
} }
}; };
}); });