feature/IO-3255-simplified-parts-management - DO NOT SPLIT LABOR / PARTS
This commit is contained in:
@@ -56,11 +56,10 @@ const extractUpdatedJobData = (rq) => {
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts updated job lines from the request payload, mirroring the AddRq splitting rules:
|
||||
* - PART lines carry only part pricing (act_price) and related fields
|
||||
* - If LaborInfo exists on a part line, add a separate LABOR line at unq_seq + 400000
|
||||
* - If RefinishLaborInfo exists, add a separate LABOR line at unq_seq + 500000 with mod_lbr_ty=LAR
|
||||
* - SUBLET lines become PAS part_type with act_price=SubletAmount
|
||||
* Extracts updated job lines from the request payload without splitting parts and labor:
|
||||
* - Keep part and labor on the same jobline
|
||||
* - Aggregate RefinishLabor into secondary labor fields and add its amount to lbr_amt
|
||||
* - SUBLET-only lines become PAS part_type with act_price = SubletAmount
|
||||
*/
|
||||
const extractUpdatedJobLines = (addsChgs = {}, jobId) => {
|
||||
const linesIn = Array.isArray(addsChgs.DamageLineInfo) ? addsChgs.DamageLineInfo : [addsChgs.DamageLineInfo || {}];
|
||||
@@ -88,74 +87,74 @@ const extractUpdatedJobLines = (addsChgs = {}, jobId) => {
|
||||
manual_line: line.ManualLineInd !== undefined ? coerceManual(line.ManualLineInd) : null
|
||||
};
|
||||
|
||||
const lineOut = { ...base };
|
||||
|
||||
const hasPart = Object.keys(partInfo).length > 0;
|
||||
const hasLaborOnly = Object.keys(laborInfo).length > 0 && !hasPart && Object.keys(subletInfo).length === 0;
|
||||
const hasSublet = Object.keys(subletInfo).length > 0;
|
||||
|
||||
if (hasPart) {
|
||||
const price = parseFloat(partInfo.PartPrice || partInfo.ListPrice || 0);
|
||||
out.push({
|
||||
...base,
|
||||
part_type: partInfo.PartType ? String(partInfo.PartType).toUpperCase() : null,
|
||||
part_qty: parseFloat(partInfo.Quantity || 0) || 1,
|
||||
oem_partno: partInfo.OEMPartNum || partInfo.PartNum || null,
|
||||
db_price: isNaN(price) ? 0 : price,
|
||||
act_price: isNaN(price) ? 0 : price
|
||||
});
|
||||
lineOut.part_type = partInfo.PartType ? String(partInfo.PartType).toUpperCase() : null;
|
||||
lineOut.part_qty = parseFloat(partInfo.Quantity || 0) || 1;
|
||||
lineOut.oem_partno = partInfo.OEMPartNum || partInfo.PartNum || null;
|
||||
lineOut.db_price = isNaN(price) ? 0 : price;
|
||||
lineOut.act_price = isNaN(price) ? 0 : price;
|
||||
|
||||
// Split any attached labor on the part line into a derived labor jobline
|
||||
const hrs = parseFloat(laborInfo.LaborHours || 0);
|
||||
const amt = parseFloat(laborInfo.LaborAmt || 0);
|
||||
const hasLabor =
|
||||
(!!laborInfo.LaborType && String(laborInfo.LaborType).length > 0) ||
|
||||
(!isNaN(hrs) && hrs !== 0) ||
|
||||
(!isNaN(amt) && amt !== 0);
|
||||
if (hasLabor) {
|
||||
out.push({
|
||||
...base,
|
||||
unq_seq: (parseInt(line.UniqueSequenceNum || 0, 10) || 0) + 400000,
|
||||
mod_lbr_ty: laborInfo.LaborType || null,
|
||||
mod_lb_hrs: isNaN(hrs) ? 0 : hrs,
|
||||
lbr_op: laborInfo.LaborOperation || null,
|
||||
lbr_amt: isNaN(amt) ? 0 : amt
|
||||
});
|
||||
// Optional: taxability flag for parts
|
||||
if (
|
||||
partInfo.TaxableInd !== undefined &&
|
||||
(typeof partInfo.TaxableInd === "string" ||
|
||||
typeof partInfo.TaxableInd === "number" ||
|
||||
typeof partInfo.TaxableInd === "boolean")
|
||||
) {
|
||||
lineOut.tax_part =
|
||||
partInfo.TaxableInd === true ||
|
||||
partInfo.TaxableInd === 1 ||
|
||||
partInfo.TaxableInd === "1" ||
|
||||
(typeof partInfo.TaxableInd === "string" && partInfo.TaxableInd.toUpperCase() === "Y");
|
||||
}
|
||||
} else if (hasSublet) {
|
||||
out.push({
|
||||
...base,
|
||||
part_type: "PAS",
|
||||
part_qty: 1,
|
||||
act_price: parseFloat(subletInfo.SubletAmount || 0) || 0
|
||||
});
|
||||
const amt = parseFloat(subletInfo.SubletAmount || 0);
|
||||
lineOut.part_type = "PAS";
|
||||
lineOut.part_qty = 1;
|
||||
lineOut.act_price = isNaN(amt) ? 0 : amt;
|
||||
}
|
||||
|
||||
// Labor-only line (no PartInfo): still upsert as a labor entry
|
||||
if (hasLaborOnly) {
|
||||
out.push({
|
||||
...base,
|
||||
mod_lbr_ty: laborInfo.LaborType || null,
|
||||
mod_lb_hrs: parseFloat(laborInfo.LaborHours || 0) || 0,
|
||||
lbr_op: laborInfo.LaborOperation || null,
|
||||
lbr_amt: parseFloat(laborInfo.LaborAmt || 0) || 0
|
||||
});
|
||||
// Primary labor on same line
|
||||
const hrs = parseFloat(laborInfo.LaborHours || 0);
|
||||
const amt = parseFloat(laborInfo.LaborAmt || 0);
|
||||
const hasLabor =
|
||||
(!!laborInfo.LaborType && String(laborInfo.LaborType).length > 0) ||
|
||||
(!isNaN(hrs) && hrs !== 0) ||
|
||||
(!isNaN(amt) && amt !== 0);
|
||||
if (hasLabor) {
|
||||
lineOut.mod_lbr_ty = laborInfo.LaborType || null;
|
||||
lineOut.mod_lb_hrs = isNaN(hrs) ? 0 : hrs;
|
||||
lineOut.lbr_op = laborInfo.LaborOperation || null;
|
||||
lineOut.lbr_amt = isNaN(amt) ? 0 : amt;
|
||||
}
|
||||
|
||||
// Separate refinish labor line
|
||||
if (Object.keys(refinishInfo).length > 0) {
|
||||
const rHrs = parseFloat(refinishInfo.LaborHours || 0);
|
||||
const rAmt = parseFloat(refinishInfo.LaborAmt || 0);
|
||||
if (!isNaN(rHrs) || !isNaN(rAmt)) {
|
||||
out.push({
|
||||
...base,
|
||||
unq_seq: (parseInt(line.UniqueSequenceNum || 0, 10) || 0) + 500000,
|
||||
line_desc: base.line_desc || "Refinish",
|
||||
mod_lbr_ty: "LAR",
|
||||
mod_lb_hrs: isNaN(rHrs) ? 0 : rHrs,
|
||||
lbr_op: refinishInfo.LaborOperation || null,
|
||||
lbr_amt: isNaN(rAmt) ? 0 : rAmt
|
||||
});
|
||||
// Refinish labor on same line using secondary fields; aggregate amount into lbr_amt
|
||||
const rHrs = parseFloat(refinishInfo.LaborHours || 0);
|
||||
const rAmt = parseFloat(refinishInfo.LaborAmt || 0);
|
||||
const hasRefinish =
|
||||
Object.keys(refinishInfo).length > 0 &&
|
||||
((refinishInfo.LaborType && String(refinishInfo.LaborType).length > 0) ||
|
||||
!isNaN(rHrs) ||
|
||||
!isNaN(rAmt) ||
|
||||
!!refinishInfo.LaborOperation);
|
||||
if (hasRefinish) {
|
||||
lineOut.lbr_typ_j = refinishInfo.LaborType || "LAR";
|
||||
lineOut.lbr_hrs_j = isNaN(rHrs) ? 0 : rHrs;
|
||||
lineOut.lbr_op_j = refinishInfo.LaborOperation || null;
|
||||
if (!isNaN(rAmt)) {
|
||||
lineOut.lbr_amt = (Number.isFinite(lineOut.lbr_amt) ? lineOut.lbr_amt : 0) + rAmt;
|
||||
}
|
||||
if (refinishInfo.PaintStagesNum !== undefined) lineOut.paint_stg = refinishInfo.PaintStagesNum;
|
||||
if (refinishInfo.PaintTonesNum !== undefined) lineOut.paint_tone = refinishInfo.PaintTonesNum;
|
||||
}
|
||||
|
||||
out.push(lineOut);
|
||||
}
|
||||
|
||||
return out;
|
||||
|
||||
Reference in New Issue
Block a user