feature/IO-3255-simplified-parts-management - Notes are appended if they are not duplicates
This commit is contained in:
@@ -9,7 +9,8 @@ const {
|
|||||||
GET_JOB_BY_CLAIM,
|
GET_JOB_BY_CLAIM,
|
||||||
UPDATE_JOB_BY_ID,
|
UPDATE_JOB_BY_ID,
|
||||||
SOFT_DELETE_JOBLINES_BY_IDS,
|
SOFT_DELETE_JOBLINES_BY_IDS,
|
||||||
INSERT_JOBLINES
|
INSERT_JOBLINES,
|
||||||
|
GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ
|
||||||
} = require("../partsManagement.queries");
|
} = require("../partsManagement.queries");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,8 +61,9 @@ const extractUpdatedJobData = (rq) => {
|
|||||||
* - Keep part and labor on the same jobline
|
* - Keep part and labor on the same jobline
|
||||||
* - Aggregate RefinishLabor into secondary labor fields and add its amount to lbr_amt
|
* - Aggregate RefinishLabor into secondary labor fields and add its amount to lbr_amt
|
||||||
* - SUBLET-only lines become PAS part_type with act_price = SubletAmount
|
* - SUBLET-only lines become PAS part_type with act_price = SubletAmount
|
||||||
|
* Accepts currentJobLineNotes map for notes merging.
|
||||||
*/
|
*/
|
||||||
const extractUpdatedJobLines = (addsChgs = {}, jobId) => {
|
const extractUpdatedJobLines = (addsChgs = {}, jobId, currentJobLineNotes = {}) => {
|
||||||
const linesIn = Array.isArray(addsChgs.DamageLineInfo) ? addsChgs.DamageLineInfo : [addsChgs.DamageLineInfo || {}];
|
const linesIn = Array.isArray(addsChgs.DamageLineInfo) ? addsChgs.DamageLineInfo : [addsChgs.DamageLineInfo || {}];
|
||||||
|
|
||||||
const coerceManual = (val) =>
|
const coerceManual = (val) =>
|
||||||
@@ -83,12 +85,33 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId) => {
|
|||||||
unq_seq: parseInt(line.UniqueSequenceNum || 0, 10),
|
unq_seq: parseInt(line.UniqueSequenceNum || 0, 10),
|
||||||
status: line.LineStatusCode || null,
|
status: line.LineStatusCode || null,
|
||||||
line_desc: line.LineDesc || null,
|
line_desc: line.LineDesc || null,
|
||||||
notes: line.LineMemo || null,
|
// notes will be set below
|
||||||
manual_line: line.ManualLineInd !== undefined ? coerceManual(line.ManualLineInd) : null
|
manual_line: line.ManualLineInd !== undefined ? coerceManual(line.ManualLineInd) : null
|
||||||
};
|
};
|
||||||
|
|
||||||
const lineOut = { ...base };
|
const lineOut = { ...base };
|
||||||
|
|
||||||
|
// --- Notes merge logic ---
|
||||||
|
const unqSeq = lineOut.unq_seq;
|
||||||
|
const currentNotes = currentJobLineNotes?.[unqSeq] || null;
|
||||||
|
const newNotes = line.LineMemo || null;
|
||||||
|
if (newNotes && currentNotes) {
|
||||||
|
if (currentNotes === newNotes) {
|
||||||
|
lineOut.notes = currentNotes;
|
||||||
|
} else if (currentNotes.includes(newNotes)) {
|
||||||
|
lineOut.notes = currentNotes;
|
||||||
|
} else {
|
||||||
|
lineOut.notes = `${currentNotes} | ${newNotes}`;
|
||||||
|
}
|
||||||
|
} else if (newNotes) {
|
||||||
|
lineOut.notes = newNotes;
|
||||||
|
} else if (currentNotes) {
|
||||||
|
lineOut.notes = currentNotes;
|
||||||
|
} else {
|
||||||
|
lineOut.notes = null;
|
||||||
|
}
|
||||||
|
// --- End notes merge logic ---
|
||||||
|
|
||||||
const hasPart = Object.keys(partInfo).length > 0;
|
const hasPart = Object.keys(partInfo).length > 0;
|
||||||
const hasSublet = Object.keys(subletInfo).length > 0;
|
const hasSublet = Object.keys(subletInfo).length > 0;
|
||||||
|
|
||||||
@@ -198,17 +221,30 @@ const partsManagementVehicleDamageEstimateChgRq = async (req, res) => {
|
|||||||
const job = await findJob(shopId, claimNum, logger);
|
const job = await findJob(shopId, claimNum, logger);
|
||||||
if (!job) return res.status(404).send("Job not found");
|
if (!job) return res.status(404).send("Job not found");
|
||||||
|
|
||||||
|
// --- Get updated lines and their unq_seq ---
|
||||||
|
const linesIn = Array.isArray(rq.AddsChgs?.DamageLineInfo)
|
||||||
|
? rq.AddsChgs.DamageLineInfo
|
||||||
|
: [rq.AddsChgs?.DamageLineInfo || {}];
|
||||||
|
const updatedSeqs = Array.from(
|
||||||
|
new Set((linesIn || []).map((l) => parseInt(l?.UniqueSequenceNum || 0, 10)).filter((v) => Number.isInteger(v)))
|
||||||
|
);
|
||||||
|
let currentJobLineNotes = {};
|
||||||
|
if (updatedSeqs.length > 0) {
|
||||||
|
const resp = await client.request(GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ, { jobid: job.id, unqSeqs: updatedSeqs });
|
||||||
|
if (resp?.joblines) {
|
||||||
|
for (const jl of resp.joblines) {
|
||||||
|
currentJobLineNotes[jl.unq_seq] = jl.notes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// --- End fetch current notes ---
|
||||||
|
|
||||||
const updatedJobData = extractUpdatedJobData(rq);
|
const updatedJobData = extractUpdatedJobData(rq);
|
||||||
const updatedLines = extractUpdatedJobLines(rq.AddsChgs, job.id);
|
const updatedLines = extractUpdatedJobLines(rq.AddsChgs, job.id, currentJobLineNotes);
|
||||||
const deletedLineIds = extractDeletions(rq.Deletions);
|
const deletedLineIds = extractDeletions(rq.Deletions);
|
||||||
|
|
||||||
await client.request(UPDATE_JOB_BY_ID, { id: job.id, job: updatedJobData });
|
await client.request(UPDATE_JOB_BY_ID, { id: job.id, job: updatedJobData });
|
||||||
|
|
||||||
// Build a set of unq_seq that will be updated (replaced). We delete them first to avoid duplicates.
|
|
||||||
const updatedSeqs = Array.from(
|
|
||||||
new Set((updatedLines || []).map((l) => l?.unq_seq).filter((v) => Number.isInteger(v)))
|
|
||||||
);
|
|
||||||
|
|
||||||
if (deletedLineIds?.length || updatedSeqs?.length) {
|
if (deletedLineIds?.length || updatedSeqs?.length) {
|
||||||
const allToDelete = Array.from(new Set([...(deletedLineIds || []), ...(updatedSeqs || [])]));
|
const allToDelete = Array.from(new Set([...(deletedLineIds || []), ...(updatedSeqs || [])]));
|
||||||
if (allToDelete.length) {
|
if (allToDelete.length) {
|
||||||
|
|||||||
@@ -52,56 +52,6 @@ const UPDATE_JOB_BY_ID = `
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const UPSERT_JOBLINES = `
|
|
||||||
mutation UpsertJoblines($joblines: [joblines_insert_input!]!) {
|
|
||||||
insert_joblines(
|
|
||||||
objects: $joblines
|
|
||||||
on_conflict: {
|
|
||||||
constraint: joblines_pkey
|
|
||||||
update_columns: [
|
|
||||||
jobid
|
|
||||||
status
|
|
||||||
line_desc
|
|
||||||
part_type
|
|
||||||
part_qty
|
|
||||||
oem_partno
|
|
||||||
db_price
|
|
||||||
act_price
|
|
||||||
mod_lbr_ty
|
|
||||||
mod_lb_hrs
|
|
||||||
lbr_op
|
|
||||||
lbr_amt
|
|
||||||
notes
|
|
||||||
manual_line
|
|
||||||
]
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
affected_rows
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DELETE_JOBLINES_BY_JOBID = `
|
|
||||||
mutation DeleteJoblinesByJobId($jobid: uuid!) {
|
|
||||||
delete_joblines(where: { jobid: { _eq: $jobid } }) {
|
|
||||||
affected_rows
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DELETE_JOBLINES_BY_IDS = `
|
|
||||||
mutation DeleteJoblinesByIds($jobid: uuid!, $unqSeqs: [Int!]!) {
|
|
||||||
delete_joblines(
|
|
||||||
where: {
|
|
||||||
jobid: { _eq: $jobid },
|
|
||||||
unq_seq: { _in: $unqSeqs }
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
affected_rows
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
// Soft delete joblines by marking removed=true instead of hard-deleting
|
// Soft delete joblines by marking removed=true instead of hard-deleting
|
||||||
const SOFT_DELETE_JOBLINES_BY_IDS = `
|
const SOFT_DELETE_JOBLINES_BY_IDS = `
|
||||||
mutation SoftDeleteJoblinesByIds($jobid: uuid!, $unqSeqs: [Int!]!) {
|
mutation SoftDeleteJoblinesByIds($jobid: uuid!, $unqSeqs: [Int!]!) {
|
||||||
@@ -245,6 +195,15 @@ const DELETE_AUDIT_TRAIL_BY_SHOP = `
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ = `
|
||||||
|
query GetJoblinesNotesByJobIdUnqSeq($jobid: uuid!, $unqSeqs: [Int!]!) {
|
||||||
|
joblines(where: { jobid: { _eq: $jobid }, unq_seq: { _in: $unqSeqs }, removed: { _neq: true } }) {
|
||||||
|
unq_seq
|
||||||
|
notes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
GET_BODYSHOP_STATUS,
|
GET_BODYSHOP_STATUS,
|
||||||
GET_VEHICLE_BY_SHOP_VIN,
|
GET_VEHICLE_BY_SHOP_VIN,
|
||||||
@@ -252,9 +211,6 @@ module.exports = {
|
|||||||
INSERT_JOB_WITH_LINES,
|
INSERT_JOB_WITH_LINES,
|
||||||
GET_JOB_BY_CLAIM,
|
GET_JOB_BY_CLAIM,
|
||||||
UPDATE_JOB_BY_ID,
|
UPDATE_JOB_BY_ID,
|
||||||
UPSERT_JOBLINES,
|
|
||||||
DELETE_JOBLINES_BY_JOBID,
|
|
||||||
DELETE_JOBLINES_BY_IDS,
|
|
||||||
SOFT_DELETE_JOBLINES_BY_IDS,
|
SOFT_DELETE_JOBLINES_BY_IDS,
|
||||||
INSERT_JOBLINES,
|
INSERT_JOBLINES,
|
||||||
CHECK_EXTERNAL_SHOP_ID,
|
CHECK_EXTERNAL_SHOP_ID,
|
||||||
@@ -271,5 +227,6 @@ module.exports = {
|
|||||||
GET_JOBS_BY_SHOP,
|
GET_JOBS_BY_SHOP,
|
||||||
DELETE_JOBLINES_BY_JOB_IDS,
|
DELETE_JOBLINES_BY_JOB_IDS,
|
||||||
DELETE_JOBS_BY_IDS,
|
DELETE_JOBS_BY_IDS,
|
||||||
DELETE_AUDIT_TRAIL_BY_SHOP
|
DELETE_AUDIT_TRAIL_BY_SHOP,
|
||||||
|
GET_JOBLINES_NOTES_BY_JOBID_UNQSEQ
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user