diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index c8da4e4d9..f00f14d7c 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -13753,6 +13753,48 @@ + + cost_labor + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + cost_parts + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + create diff --git a/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx b/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx index b90dc0eae..bbe5e49a7 100644 --- a/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx +++ b/client/src/components/invoice-enter-modal/invoice-enter-modal.container.jsx @@ -127,6 +127,10 @@ function InvoiceEnterModalContainer({ if (enterAgain) form.submit(); }, [enterAgain, form]); + useEffect(() => { + if (invoiceEnterModal.visible) form.resetFields(); + }, [invoiceEnterModal.visible, form]); + return ( diff --git a/client/src/components/job-costing-modal/job-costing-modal.component.jsx b/client/src/components/job-costing-modal/job-costing-modal.component.jsx index cd3f16930..d0c673f3a 100644 --- a/client/src/components/job-costing-modal/job-costing-modal.component.jsx +++ b/client/src/components/job-costing-modal/job-costing-modal.component.jsx @@ -19,12 +19,12 @@ export function JobCostingModalComponent({ bodyshop, job }) { const jobLineTotalsByProfitCenter = job.joblines.reduce( (acc, val) => { - const laborProfitCenter = defaultProfits[val.mod_lbr_ty]; - if (!!!laborProfitCenter) - console.log( - "Unknown cost/profit center mapping for labor.", - val.mod_lbr_ty - ); + const laborProfitCenter = defaultProfits[val.mod_lbr_ty] || "?"; + // if (!!!laborProfitCenter) + // console.log( + // "Unknown cost/profit center mapping for labor.", + // val.mod_lbr_ty + // ); const rateName = `rate_${(val.mod_lbr_ty || "").toLowerCase()}`; const laborAmount = Dinero({ @@ -36,7 +36,7 @@ export function JobCostingModalComponent({ bodyshop, job }) { laborAmount ); - const partsProfitCenter = defaultProfits[val.part_type]; + const partsProfitCenter = defaultProfits[val.part_type] || "?"; if (!!!partsProfitCenter) console.log( "Unknown cost/profit center mapping for parts.", @@ -79,10 +79,31 @@ export function JobCostingModalComponent({ bodyshop, job }) { {} ); + const ticketTotalsByProfitCenter = job.timetickets.reduce( + (ticket_acc, ticket_val) => { + //At the invoice level. + if (!!!ticket_acc[ticket_val.cost_center]) + ticket_acc[ticket_val.cost_center] = Dinero(); + + ticket_acc[ticket_val.cost_center] = ticket_acc[ + ticket_val.cost_center + ].add( + Dinero({ + amount: Math.round((ticket_val.rate || 0) * 100), + }).multiply(ticket_val.actualhrs || 0) + ); + + return ticket_acc; + }, + {} + ); + const summaryData = { totalLaborSales: Dinero({ amount: 0 }), totalPartsSales: Dinero({ amount: 0 }), totalSales: Dinero({ amount: 0 }), + totalLaborCost: Dinero({ amount: 0 }), + totalPartsCost: Dinero({ amount: 0 }), totalCost: Dinero({ amount: 0 }), gpdollars: Dinero({ amount: 0 }), gppercent: null, @@ -95,7 +116,15 @@ export function JobCostingModalComponent({ bodyshop, job }) { jobLineTotalsByProfitCenter.labor[ccVal] || Dinero({ amount: 0 }); const sale_parts = jobLineTotalsByProfitCenter.parts[ccVal] || Dinero({ amount: 0 }); - const cost = invoiceTotalsByProfitCenter[ccVal] || Dinero({ amount: 0 }); + + const cost_labor = + ticketTotalsByProfitCenter[ccVal] || Dinero({ amount: 0 }); + const cost_parts = + invoiceTotalsByProfitCenter[ccVal] || Dinero({ amount: 0 }); + + const cost = ( + invoiceTotalsByProfitCenter[ccVal] || Dinero({ amount: 0 }) + ).add(ticketTotalsByProfitCenter[ccVal] || Dinero({ amount: 0 })); const totalSales = sale_labor.add(sale_parts); const gpdollars = totalSales.subtract(cost); const gppercent = ( @@ -115,6 +144,8 @@ export function JobCostingModalComponent({ bodyshop, job }) { summaryData.totalSales = summaryData.totalSales .add(sale_labor) .add(sale_parts); + summaryData.totalLaborCost = summaryData.totalLaborCost.add(cost_labor); + summaryData.totalPartsCost = summaryData.totalPartsCost.add(cost_parts); summaryData.totalCost = summaryData.totalCost.add(cost); return { @@ -122,6 +153,8 @@ export function JobCostingModalComponent({ bodyshop, job }) { cost_center: ccVal, sale_labor: sale_labor && sale_labor.toFormat(), sale_parts: sale_parts && sale_parts.toFormat(), + cost_parts: cost_parts && cost_parts.toFormat(), + cost_labor: cost_labor && cost_labor.toFormat(), cost: cost && cost.toFormat(), gpdollars: gpdollars.toFormat(), gppercent: gppercentFormatted, @@ -143,8 +176,6 @@ export function JobCostingModalComponent({ bodyshop, job }) { summaryData.gppercentFormatted = summaryData.gppercent; } - console.log("JobCostingModalComponent -> summaryData", summaryData); - return (
diff --git a/client/src/components/job-costing-parts-table/job-costing-parts-table.component.jsx b/client/src/components/job-costing-parts-table/job-costing-parts-table.component.jsx index 473a79eee..fb81eb59a 100644 --- a/client/src/components/job-costing-parts-table/job-costing-parts-table.component.jsx +++ b/client/src/components/job-costing-parts-table/job-costing-parts-table.component.jsx @@ -40,12 +40,20 @@ export default function JobCostingPartsTable({ job, data }) { state.sortedInfo.columnKey === "sale_parts" && state.sortedInfo.order, }, { - title: t("jobs.labels.cost"), - dataIndex: "cost", - key: "cost", - sorter: (a, b) => a.cost - b.cost, + title: t("jobs.labels.cost_labor"), + dataIndex: "cost_labor", + key: "cost_labor", + sorter: (a, b) => a.cost_labor - b.cost_labor, sortOrder: - state.sortedInfo.columnKey === "cost" && state.sortedInfo.order, + state.sortedInfo.columnKey === "cost_labor" && state.sortedInfo.order, + }, + { + title: t("jobs.labels.cost_parts"), + dataIndex: "cost_parts", + key: "cost_parts", + sorter: (a, b) => a.cost_parts - b.cost_parts, + sortOrder: + state.sortedInfo.columnKey === "cost_parts" && state.sortedInfo.order, }, { title: t("jobs.labels.gpdollars"), diff --git a/client/src/components/job-costing-statistics/job-costing-statistics.component.jsx b/client/src/components/job-costing-statistics/job-costing-statistics.component.jsx index fd7f2fffe..730fc3d76 100644 --- a/client/src/components/job-costing-statistics/job-costing-statistics.component.jsx +++ b/client/src/components/job-costing-statistics/job-costing-statistics.component.jsx @@ -20,6 +20,14 @@ export default function JobCostingStatistics({ job, summaryData }) { value={summaryData.totalSales.toFormat()} title={t("jobs.labels.total_sales")} /> + + i.id === values.employeeid + )[0].base_rate; + insertTicket({ variables: { - timeTicketInput: [{ ...values, bodyshopid: bodyshop.id }], + timeTicketInput: [{ ...values, rate, bodyshopid: bodyshop.id }], }, }) .then(handleMutationSuccess) diff --git a/client/src/components/vendor-search-select/vendor-search-select.component.jsx b/client/src/components/vendor-search-select/vendor-search-select.component.jsx index e87b5d4f2..93a08215d 100644 --- a/client/src/components/vendor-search-select/vendor-search-select.component.jsx +++ b/client/src/components/vendor-search-select/vendor-search-select.component.jsx @@ -9,7 +9,6 @@ const VendorSearchSelect = ( { value, onChange, options, onSelect, disabled, preferredMake }, ref ) => { - console.log("preferredMake", preferredMake, options); const [option, setOption] = useState(value); useEffect(() => { @@ -25,8 +24,6 @@ const VendorSearchSelect = ( ) : []; - console.log("favorites", favorites); - return (