feature/IO-3255-simplified-parts-management - Checkpoint

This commit is contained in:
Dave Richer
2025-06-27 13:48:49 -04:00
parent 8de92403ee
commit 646c42b8c7
2 changed files with 150 additions and 2 deletions

View File

@@ -32,9 +32,76 @@ const INSERT_JOB_WITH_LINES = `
}
`;
const GET_JOB_BY_CLAIM = `
query GetJobByClaim($shopid: uuid!, $clm_no: String!) {
jobs(
where: { shopid: { _eq: $shopid }, clm_no: { _eq: $clm_no } }
order_by: { created_at: desc }
limit: 1
) {
id
}
}
`;
const UPDATE_JOB_BY_ID = `
mutation UpdateJobById($id: uuid!, $job: jobs_set_input!) {
update_jobs_by_pk(pk_columns: { id: $id }, _set: $job) {
id
}
}
`;
const UPSERT_JOBLINES = `
mutation UpsertJoblines($joblines: [joblines_insert_input!]!) {
insert_joblines(
objects: $joblines
on_conflict: {
constraint: joblines_jobid_line_no_unq_seq_key
update_columns: [
status
line_desc
part_type
part_qty
oem_partno
db_price
act_price
mod_lbr_ty
mod_lb_hrs
lbr_op
lbr_amt
notes
]
}
) {
affected_rows
}
}
`;
const DELETE_JOBLINES_BY_JOBID = `
mutation DeleteJoblinesByJobId($jobid: uuid!) {
delete_joblines(where: { jobid: { _eq: $jobid } }) {
affected_rows
}
}
`;
const INSERT_JOBLINES = `
mutation InsertJoblines($joblines: [joblines_insert_input!]!) {
insert_joblines(objects: $joblines) {
affected_rows
}
}
`;
module.exports = {
GET_BODYSHOP_STATUS,
GET_VEHICLE_BY_SHOP_VIN,
INSERT_OWNER,
INSERT_JOB_WITH_LINES
INSERT_JOB_WITH_LINES,
GET_JOB_BY_CLAIM,
UPDATE_JOB_BY_ID,
DELETE_JOBLINES_BY_JOBID,
UPSERT_JOBLINES,
INSERT_JOBLINES
};

View File

@@ -9,7 +9,11 @@ const {
GET_BODYSHOP_STATUS,
GET_VEHICLE_BY_SHOP_VIN,
INSERT_OWNER,
INSERT_JOB_WITH_LINES
INSERT_JOB_WITH_LINES,
GET_JOB_BY_CLAIM,
UPDATE_JOB_BY_ID,
INSERT_JOBLINES,
DELETE_JOBLINES_BY_JOBID
} = require("./partsManagement.queries");
// Defaults
@@ -436,6 +440,18 @@ const extractJobLines = (rq) => {
});
};
/**
* Checks if the request is a supplement or a document portion delta.
* TODO: This is a temporary check, should be replaced with a proper field in the XML.
* @param rq
* @returns {boolean}
*/
const isSupplement = (rq) => {
const docStatus = rq.DocumentInfo?.DocumentStatus;
const historyType = rq.RepairTotalsHistory?.HistoryTotalType;
return docStatus === "S" || historyType === "DocumentPortionDelta";
};
/**
* Finds an existing vehicle by shopId and VIN.
* @param {string} shopId - The bodyshop UUID.
@@ -458,6 +474,26 @@ const findExistingVehicle = async (shopId, v_vin, logger) => {
return null;
};
/**
* Finds an existing job by shopid and claim number.
* @param shopid
* @param clm_no
* @param logger
* @returns {Promise<*|null>}
*/
const findExistingJob = async (shopid, clm_no, logger) => {
try {
const { jobs } = await client.request(GET_JOB_BY_CLAIM, {
shopid,
clm_no
});
return jobs?.[0] || null;
} catch (err) {
logger.log("parts-job-fetch-failed", "warn", null, null, { error: err });
return null;
}
};
/**
* Inserts an owner and returns the owner ID.
* @param {object} ownerInput - The owner data to insert.
@@ -532,6 +568,21 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => {
const joblinesData = extractJobLines(rq);
const insuranceData = extractInsuranceData(rq);
// Uncomment for debugging
// console.dir(
// {
// joblinesData,
// lossInfo,
// insuranceData,
// vehicleData,
// ownerData,
// adjusterData,
// repairFacilityData,
// estimatorData
// },
// { depth: null }
// );
// Find or create relationships
const ownerid = await insertOwner(ownerData, logger);
const vehicleid = await findExistingVehicle(shopId, vehicleData.v_vin, logger);
@@ -577,6 +628,36 @@ const partsManagementVehicleDamageEstimateAddRq = async (req, res) => {
joblines: { data: joblinesData }
};
// Check if this is a supplement or document portion delta.
if (isSupplement(rq)) {
console.log("----------------------IS SUPPLEMENT----------------------");
const existingJob = await findExistingJob(shopId, clm_no, logger);
if (existingJob) {
const { joblines, ...jobWithoutLines } = jobInput;
await client.request(UPDATE_JOB_BY_ID, {
id: existingJob.id,
job: jobWithoutLines
});
await client.request(DELETE_JOBLINES_BY_JOBID, {
jobid: existingJob.id
});
if (joblines?.data?.length) {
const joblinesWithJobId = joblines.data.map((line) => ({
...line,
jobid: existingJob.id
}));
await client.request(INSERT_JOBLINES, { joblines: joblinesWithJobId });
}
logger.log("parts-job-updated", "info", existingJob.id);
return res.status(200).json({ success: true, jobId: existingJob.id });
}
}
// Insert job
const { insert_jobs_one: newJob } = await client.request(INSERT_JOB_WITH_LINES, { job: jobInput });
logger.log("parts-job-created", "info", newJob.id, null);