From a0f06ffdc21588e45d4ab48c3c7c0663587d075b Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Thu, 20 Jan 2022 13:10:45 -0800 Subject: [PATCH 1/3] IO-1558 Add past due indicator to Kanban card. --- .../production-board-kanban-card.component.jsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx index 817627ec8..5fb2275cb 100644 --- a/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx +++ b/client/src/components/production-board-kanban-card/production-board-kanban-card.component.jsx @@ -12,6 +12,7 @@ import ProductionAlert from "../production-list-columns/production-list-columns. import ProductionListColumnProductionNote from "../production-list-columns/production-list-columns.productionnote.component"; import ProductionSubletsManageComponent from "../production-sublets-manage/production-sublets-manage.component"; import "./production-board-card.styles.scss"; +import moment from "moment"; export default function ProductionBoardCard( technician, @@ -37,6 +38,15 @@ export default function ProductionBoardCard( // employee_csr = bodyshop.employees.find((e) => e.id === card.employee_csr); // } + const pastDueAlert = + !!card.scheduled_completion && + ((moment().isSameOrAfter(moment(card.scheduled_completion), "day") && + "production-completion-past") || + (moment() + .add(1, "day") + .isSame(moment(card.scheduled_completion), "day") && + "production-completion-soon")); + return ( - + {card.scheduled_completion} From 4704fd9ce1b75400134df10460e814e886e44418 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Thu, 20 Jan 2022 15:04:57 -0800 Subject: [PATCH 2/3] IO-1573 Resolve CDK job costing error. --- server/job/job-costing.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/server/job/job-costing.js b/server/job/job-costing.js index 4a7ebadb4..e5c4c5883 100644 --- a/server/job/job-costing.js +++ b/server/job/job-costing.js @@ -375,9 +375,11 @@ function GenerateCostingData(job) { //Is it a DMS Setup? const selectedDmsAllocationConfig = - job.bodyshop.md_responsibility_centers.dms_defaults.find( - (d) => d.name === job.dms_allocation - ) || job.bodyshop.md_responsibility_centers.defaults; + (job.bodyshop.md_responsibility_centers.dms_defaults && + job.bodyshop.md_responsibility_centers.dms_defaults.find( + (d) => d.name === job.dms_allocation + )) || + job.bodyshop.md_responsibility_centers.defaults; const billTotalsByCostCenters = job.bills.reduce((bill_acc, bill_val) => { //At the bill level. @@ -466,12 +468,16 @@ function GenerateCostingData(job) { //At the invoice level. if (job.bodyshop.pbs_serialnumber || job.bodyshop.cdk_dealerid) { - if (!ticket_acc[selectedDmsAllocationConfig.costs[ticket_val.ciecacode]]) + if ( + !ticket_acc[selectedDmsAllocationConfig.costs[ticket_val.ciecacode]] + ) ticket_acc[selectedDmsAllocationConfig.costs[ticket_val.ciecacode]] = Dinero(); ticket_acc[selectedDmsAllocationConfig.costs[ticket_val.ciecacode]] = - ticket_acc[selectedDmsAllocationConfig.costs[ticket_val.ciecacode]].add( + ticket_acc[ + selectedDmsAllocationConfig.costs[ticket_val.ciecacode] + ].add( Dinero({ amount: Math.round((ticket_val.rate || 0) * 100), }).multiply( From 9aa85b3ab515bba6010c0c4aaf785f29690162e9 Mon Sep 17 00:00:00 2001 From: Patrick Fic <> Date: Thu, 20 Jan 2022 16:20:09 -0800 Subject: [PATCH 3/3] IO-1552 AH Updates. --- server/data/autohouse.js | 72 +++++++++++++++++--------------- server/graphql-client/queries.js | 33 ++++++++------- 2 files changed, 57 insertions(+), 48 deletions(-) diff --git a/server/data/autohouse.js b/server/data/autohouse.js index c91081805..d4def25b8 100644 --- a/server/data/autohouse.js +++ b/server/data/autohouse.js @@ -37,6 +37,7 @@ exports.default = async (req, res) => { //Query for the List of Bodyshop Clients. logger.log("autohouse-start", "DEBUG", "api", null, null); const { bodyshops } = await client.request(queries.GET_AUTOHOUSE_SHOPS); + 639; const allxmlsToUpload = []; const allErrors = []; @@ -47,16 +48,19 @@ exports.default = async (req, res) => { }); const erroredJobs = []; try { - const { jobs } = await client.request(queries.AUTOHOUSE_QUERY, { - bodyshopid: bodyshop.id, - start: moment().subtract(3, "days").startOf("day"), - }); + const { jobs, bodyshops_by_pk } = await client.request( + queries.AUTOHOUSE_QUERY, + { + bodyshopid: bodyshop.id, + start: moment().subtract(3, "days").startOf("day"), + } + ); const autoHouseObject = { AutoHouseExport: { RepairOrder: jobs.map((j) => CreateRepairOrderTag( - { ...j, bodyshop }, + { ...j, bodyshop: bodyshops_by_pk }, function ({ job, error }) { erroredJobs.push({ job: job, error: error.toString() }); } @@ -114,12 +118,12 @@ exports.default = async (req, res) => { } } - // for (const xmlObj of allxmlsToUpload) { - // fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml); - // } + for (const xmlObj of allxmlsToUpload) { + fs.writeFileSync(`./logs/${xmlObj.filename}`, xmlObj.xml); + } - // res.json(allxmlsToUpload); - // return; + res.json(allxmlsToUpload); + return; let sftp = new Client(); sftp.on("error", (errors) => @@ -403,21 +407,23 @@ const CreateRepairOrderTag = (job, errorCallback) => { // AmountDue: null, // }, RevisedTotals: { - BodyHours: job.job_totals.rates.lab.hours, + BodyHours: job.job_totals.rates.lab.hours.toFixed(2), BodyRepairHours: job.joblines .filter((line) => repairOpCodes.includes(line.lbr_op)) - .reduce((acc, val) => acc + val.mod_lb_hrs, 0), + .reduce((acc, val) => acc + val.mod_lb_hrs, 0) + .toFixed(2), BodyReplaceHours: job.joblines .filter((line) => replaceOpCodes.includes(line.lbr_op)) - .reduce((acc, val) => acc + val.mod_lb_hrs, 0), - RefinishHours: job.job_totals.rates.lar.hours, - MechanicalHours: job.job_totals.rates.lam.hours, - StructuralHours: job.job_totals.rates.las.hours, + .reduce((acc, val) => acc + val.mod_lb_hrs, 0) + .toFixed(2), + RefinishHours: job.job_totals.rates.lar.hours.toFixed(2), + MechanicalHours: job.job_totals.rates.lam.hours.toFixed(2), + StructuralHours: job.job_totals.rates.las.hours.toFixed(2), - ElectricalHours: job.job_totals.rates.lae.hours, - FrameHours: job.job_totals.rates.laf.hours, - GlassHours: job.job_totals.rates.lag.hours, - DetailHours: job.job_totals.rates.lad.hours, + ElectricalHours: job.job_totals.rates.lae.hours.toFixed(2), + FrameHours: job.job_totals.rates.laf.hours.toFixed(2), + GlassHours: job.job_totals.rates.lag.hours.toFixed(2), + DetailHours: job.job_totals.rates.lad.hours.toFixed(2), LaborMiscHours: 0, PartsTotal: Dinero(job.job_totals.parts.parts.total).toFormat( @@ -508,11 +514,11 @@ const CreateRepairOrderTag = (job, errorCallback) => { PMTotal: Dinero(job.job_totals.rates.mapa.total).toFormat( AHDineroFormat ), - PMTotalCost: 0, + PMTotalCost: repairCosts.PMTotalCost.toFormat(AHDineroFormat), BMTotal: Dinero(job.job_totals.rates.mash.total).toFormat( AHDineroFormat ), - BMTotalCost: 0, + BMTotalCost: repairCosts.BMTotalCost.toFormat(AHDineroFormat), MiscTotal: 0, MiscTotalCost: 0, TowingTotal: Dinero(job.job_totals.additional.towing).toFormat( @@ -729,7 +735,7 @@ const StatusMapping = (status, md_ro_statuses) => { else if (status === default_delivered) return "DEL"; else if (status === default_invoiced || status === default_exported) return "CLO"; - else if (status === default_void) return "CLO"; + else if (status === default_void) return "VOID"; else if (md_ro_statuses.production_statuses.includes(status)) return "IPR"; else return "UNDEFINED"; @@ -739,12 +745,7 @@ const StatusMapping = (status, md_ro_statuses) => { const GenerateDetailLines = (line, statuses) => { const ret = { BackOrdered: line.status === statuses.default_bo ? "1" : "0", - Cost: - (line.billlines[0] && - (line.billlines[0].actual_cost * line.billlines[0].quantity).toFixed( - 2 - )) || - 0, + Cost: (line.billlines[0] && line.billlines[0].actual_cost.toFixed(2)) || 0, //Critical: null, Description: line.line_desc || "", DiscountMarkup: line.prt_dsmk_m || 0, @@ -760,17 +761,22 @@ const GenerateDetailLines = (line, statuses) => { "", OriginalCost: null, OriginalInvoiceNumber: null, - PriceEach: (line.billlines[0] && line.billlines[0].retail_price) || 0, + PriceEach: line.act_price || 0, PartNumber: _.escape(line.oem_partno), ProfitPercent: null, PurchaseOrderNumber: null, Qty: line.part_qty || 0, Status: line.status || "", - SupplementNumber: line.line_ind || "", + SupplementNumber: line.line_ind ? line.line_ind.replace(/[^\d.-]/g, "") : 0, Type: line.part_type || "", Vendor: (line.billlines[0] && line.billlines[0].bill.vendor.name) || "", VendorPaid: null, - VendorPrice: (line.billlines[0] && line.billlines[0].actual_price) || 0, + VendorPrice: + (line.billlines[0] && + (line.billlines[0].actual_price * line.billlines[0].quantity).toFixed( + 2 + )) || + 0, Deleted: null, ExpectedOn: null, ReceivedOn: @@ -779,7 +785,7 @@ const GenerateDetailLines = (line, statuses) => { OrderedBy: null, ShipVia: null, VendorContact: null, - EstimateAmount: line.act_price * line.part_qty || 0, //Rebecca + EstimateAmount: (line.act_price * line.part_qty).toFixed(2) || 0, //Rebecca }; return ret; }; diff --git a/server/graphql-client/queries.js b/server/graphql-client/queries.js index d53e56a44..9be777295 100644 --- a/server/graphql-client/queries.js +++ b/server/graphql-client/queries.js @@ -543,6 +543,23 @@ exports.QUERY_EMPLOYEE_PIN = `query QUERY_EMPLOYEE_PIN($shopId: uuid!, $employee }`; exports.AUTOHOUSE_QUERY = `query AUTOHOUSE_EXPORT($start: timestamptz, $bodyshopid: uuid!) { + bodyshops_by_pk(id: $bodyshopid){ + + id + shopname + address1 + city + state + zip_post + country + phone + md_ro_statuses + md_order_statuses + autohouseid + md_responsibility_centers + jc_hourly_rates + + } jobs(where: {_and: [{converted: {_eq: true}}, {updated_at: {_gt: $start}}, {shopid: {_eq: $bodyshopid}}]}) { id ro_number @@ -608,21 +625,7 @@ exports.AUTOHOUSE_QUERY = `query AUTOHOUSE_EXPORT($start: timestamptz, $bodyshop job_totals driveable parts_tax_rates - bodyshop { - id - shopname - address1 - city - state - zip_post - country - phone - md_ro_statuses - md_order_statuses - autohouseid - md_responsibility_centers - jc_hourly_rates - } + joblines(where: {removed: {_eq: false}}) { id line_no