From 88ae1fb1cc4d7293647b0eec92a58e38b48030c3 Mon Sep 17 00:00:00 2001 From: Dave Date: Tue, 5 May 2026 13:56:16 -0400 Subject: [PATCH] feature/IO-3673-Order-Parts-Receive-Bill-Bug - Fix --- .../parts-order-modal.component.jsx | 3 ++ .../parts-order-modal.container.jsx | 50 ++++++++----------- .../parts-order-modal.utils.js | 23 +++++++++ .../parts-order-modal.utils.test.js | 32 ++++++++++++ 4 files changed, 78 insertions(+), 30 deletions(-) create mode 100644 client/src/components/parts-order-modal/parts-order-modal.utils.js create mode 100644 client/src/components/parts-order-modal/parts-order-modal.utils.test.js diff --git a/client/src/components/parts-order-modal/parts-order-modal.component.jsx b/client/src/components/parts-order-modal/parts-order-modal.component.jsx index 3766b2e7b..f04b5f7bc 100644 --- a/client/src/components/parts-order-modal/parts-order-modal.component.jsx +++ b/client/src/components/parts-order-modal/parts-order-modal.component.jsx @@ -176,6 +176,9 @@ export function PartsOrderModalComponent({ > + { - const originalLine = linesToOrder?.[index]; - const jobLineId = isReturn ? originalLine?.joblineid : originalLine?.id; - - return { - ...p, - job_line_id: jobLineId, - ...(isReturn && { cm_received: false }) - }; + const forcedLines = buildSubmittedPartsOrderLines({ + submittedLines, + linesToOrder, + isReturn }); let insertResult; @@ -147,10 +143,7 @@ export function PartsOrderModalContainer({ type: isReturn ? "jobspartsreturn" : "jobspartsorder" }); - // Use linesToOrder from context instead of form values to preserve job line ids - const jobLineIds = (linesToOrder ?? []) - .filter((line) => (isReturn ? line.joblineid : line.id)) - .map((line) => (isReturn ? line.joblineid : line.id)); + const jobLineIds = getSubmittedPartsOrderJobLineIds(forcedLines); try { const jobLinesResult = await updateJobLines({ @@ -206,23 +199,20 @@ export function PartsOrderModalContainer({ isinhouse: true, date: dayjs(), total: 0, - billlines: forcedLines.map((p, index) => { - const originalLine = linesToOrder?.[index]; - return { - joblineid: isReturn ? originalLine?.joblineid : originalLine?.id, - actual_price: p.act_price, - actual_cost: 0, // p.act_price, - line_desc: p.line_desc, - line_remarks: p.line_remarks, - part_type: p.part_type, - quantity: p.quantity || 1, - applicable_taxes: { - local: false, - state: false, - federal: false - } - }; - }) + billlines: forcedLines.map((p) => ({ + joblineid: p.job_line_id, + actual_price: p.act_price, + actual_cost: 0, // p.act_price, + line_desc: p.line_desc, + line_remarks: p.line_remarks, + part_type: p.part_type, + quantity: p.quantity || 1, + applicable_taxes: { + local: false, + state: false, + federal: false + } + })) } } }); diff --git a/client/src/components/parts-order-modal/parts-order-modal.utils.js b/client/src/components/parts-order-modal/parts-order-modal.utils.js new file mode 100644 index 000000000..1517704ce --- /dev/null +++ b/client/src/components/parts-order-modal/parts-order-modal.utils.js @@ -0,0 +1,23 @@ +export const getPartsOrderJobLineId = ({ line, originalLine, isReturn }) => { + return line?.job_line_id || (isReturn ? originalLine?.joblineid : originalLine?.id); +}; + +export const buildSubmittedPartsOrderLines = ({ submittedLines = [], linesToOrder = [], isReturn }) => { + return submittedLines.map((line, index) => { + const jobLineId = getPartsOrderJobLineId({ + line, + originalLine: linesToOrder?.[index], + isReturn + }); + + return { + ...line, + job_line_id: jobLineId, + ...(isReturn && { cm_received: false }) + }; + }); +}; + +export const getSubmittedPartsOrderJobLineIds = (partsOrderLines = []) => { + return partsOrderLines.map((line) => line.job_line_id).filter(Boolean); +}; diff --git a/client/src/components/parts-order-modal/parts-order-modal.utils.test.js b/client/src/components/parts-order-modal/parts-order-modal.utils.test.js new file mode 100644 index 000000000..1c7309680 --- /dev/null +++ b/client/src/components/parts-order-modal/parts-order-modal.utils.test.js @@ -0,0 +1,32 @@ +import { describe, expect, it } from "vitest"; +import { buildSubmittedPartsOrderLines, getSubmittedPartsOrderJobLineIds } from "./parts-order-modal.utils.js"; + +describe("parts order modal utilities", () => { + it("preserves submitted job line ids after a row is removed", () => { + const submittedLines = [ + { line_desc: "second line", job_line_id: "job-line-2" }, + { line_desc: "third line", job_line_id: "job-line-3" } + ]; + const linesToOrder = [{ id: "job-line-1" }, { id: "job-line-2" }, { id: "job-line-3" }]; + + const result = buildSubmittedPartsOrderLines({ submittedLines, linesToOrder, isReturn: false }); + + expect(result.map((line) => line.job_line_id)).toEqual(["job-line-2", "job-line-3"]); + expect(getSubmittedPartsOrderJobLineIds(result)).toEqual(["job-line-2", "job-line-3"]); + }); + + it("falls back to original return line ids when the form omits hidden metadata", () => { + const submittedLines = [{ line_desc: "return line" }]; + const linesToOrder = [{ joblineid: "return-job-line-1" }]; + + const result = buildSubmittedPartsOrderLines({ submittedLines, linesToOrder, isReturn: true }); + + expect(result).toEqual([ + { + line_desc: "return line", + job_line_id: "return-job-line-1", + cm_received: false + } + ]); + }); +});