From f8b57ca9bdb500d1d95a7b12eb141c698c7c9cf1 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Wed, 18 Aug 2021 14:13:11 -0700 Subject: [PATCH] IO-1297 Adjust Job Costing after Invoicing --- server/accounting/qbxml/qbxml-receivables.js | 2 +- server/graphql-client/queries.js | 2 + server/job/job-costing.js | 69 +++++++++++--------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/server/accounting/qbxml/qbxml-receivables.js b/server/accounting/qbxml/qbxml-receivables.js index 82a32da51..861f366b9 100644 --- a/server/accounting/qbxml/qbxml-receivables.js +++ b/server/accounting/qbxml/qbxml-receivables.js @@ -215,7 +215,7 @@ const generateInvoiceQbxml = ( jobs_by_pk.joblines.map((jobline) => { //Parts Lines if (jobline.db_ref === "936008") { - //If either of these DB REFs change, they also need to change in job-totals calculations. + //If either of these DB REFs change, they also need to change in job-totals/job-costing calculations. hasMapaLine = true; } if (jobline.db_ref === "936007") { diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js index 087f45de7..4e8c7b421 100644 --- a/server/graphql-client/queries.js +++ b/server/graphql-client/queries.js @@ -751,6 +751,7 @@ exports.QUERY_JOB_COSTING_DETAILS = ` query QUERY_JOB_COSTING_DETAILS($id: uuid! ca_customer_gst joblines(where: { removed: { _eq: false } }) { id + db_ref unq_seq line_ind tax_part @@ -852,6 +853,7 @@ exports.QUERY_JOB_COSTING_DETAILS_MULTI = ` query QUERY_JOB_COSTING_DETAILS_MULT ca_customer_gst joblines(where: {removed: {_eq: false}}) { id + db_ref unq_seq line_ind tax_part diff --git a/server/job/job-costing.js b/server/job/job-costing.js index e9de9b5ff..619c75dd9 100644 --- a/server/job/job-costing.js +++ b/server/job/job-costing.js @@ -25,7 +25,6 @@ async function JobCosting(req, res) { .request(queries.QUERY_JOB_COSTING_DETAILS, { id: jobid, }); - console.timeEnd("querydata"); console.time(`generatecostingdata-${resp.jobs_by_pk.id}`); const ret = GenerateCostingData(resp.jobs_by_pk); @@ -242,12 +241,22 @@ function GenerateCostingData(job) { ); const materialsHours = { mapaHrs: 0, mashHrs: 0 }; + let hasMapaLine = false; + let hasMashLine = false; //Massage the data. const jobLineTotalsByProfitCenter = job && job.joblines.reduce( (acc, val) => { + //Parts Lines + if (val.db_ref === "936008") { + //If either of these DB REFs change, they also need to change in job-totals/job-costing calculations. + hasMapaLine = true; + } + if (val.db_ref === "936007") { + hasMashLine = true; + } if (val.mod_lbr_ty) { const laborProfitCenter = val.profitcenter_labor || defaultProfits[val.mod_lbr_ty] || "?"; @@ -265,32 +274,11 @@ function GenerateCostingData(job) { acc.labor[laborProfitCenter].add(laborAmount); if (val.mod_lbr_ty === "LAR") { - if (!acc.parts[defaultProfits["MAPA"]]) - acc.parts[defaultProfits["MAPA"]] = Dinero(); - materialsHours.mapaHrs += val.mod_lb_hrs || 0; - acc.parts[defaultProfits["MAPA"]] = acc.parts[ - defaultProfits["MAPA"] - ].add( - Dinero({ - amount: Math.round((job.rate_mapa || 0) * 100), - }).multiply(val.mod_lb_hrs || 0) - ); } - if (!acc.parts[defaultProfits["MASH"]]) - acc.parts[defaultProfits["MASH"]] = Dinero(); - if (val.mod_lbr_ty !== "LAR") { - acc.parts[defaultProfits["MASH"]] = acc.parts[ - defaultProfits["MASH"] - ].add( - Dinero({ - amount: Math.round((job.rate_mash || 0) * 100), - }).multiply(val.mod_lb_hrs || 0) - ); materialsHours.mashHrs += val.mod_lb_hrs || 0; } - //If labor line, add to paint and shop materials. } if (val.part_type && val.part_type !== "PAE") { @@ -358,6 +346,27 @@ function GenerateCostingData(job) { { parts: {}, labor: {} } ); + if (!hasMapaLine) { + if (!jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]]) + jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]] = Dinero(); + jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]] = + jobLineTotalsByProfitCenter.parts[defaultProfits["MAPA"]].add( + Dinero({ + amount: Math.round((job.rate_mapa || 0) * 100), + }).multiply(materialsHours.mapaHrs || 0) + ); + } + if (!hasMashLine) { + if (!jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]]) + jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]] = Dinero(); + jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]] = + jobLineTotalsByProfitCenter.parts[defaultProfits["MASH"]].add( + Dinero({ + amount: Math.round((job.rate_mash || 0) * 100), + }).multiply(materialsHours.mashHrs || 0) + ); + } + const billTotalsByCostCenters = job.bills.reduce((bill_acc, bill_val) => { //At the bill level. bill_val.billlines.map((line_val) => { @@ -603,17 +612,15 @@ const formatGpPercent = (gppercent) => { //Verify that this stays in line with jobs-close-auto-allocate logic from the application. const getAdditionalCostCenter = (jl, profitCenters) => { - console.log("Checking additional cost center", jl.line_desc); if (!jl.part_type && !jl.mod_lbr_ty) { const lineDesc = jl.line_desc.toLowerCase(); - //This logic is covered prior and assigned based on the labor type of the lines - // if (lineDesc.includes("shop materials")) { - // return profitCenters["MASH"]; - // } else if (lineDesc.includes("paint/materials")) { - // return profitCenters["MAPA"]; - // } else - //End covered logic - if (lineDesc.includes("ats amount")) { + console.log("Checking additional cost center", lineDesc); + + if (lineDesc.includes("shop mat")) { + return profitCenters["MASH"]; + } else if (lineDesc.includes("paint/mat")) { + return profitCenters["MAPA"]; + } else if (lineDesc.includes("ats amount")) { return profitCenters["ATS"]; } else { return null;