IO-3605 Material Threshold Calculations

Signed-off-by: Allan Carr <allan@imexsystems.ca>
This commit is contained in:
Allan Carr
2026-03-06 17:56:21 -08:00
parent 8980d3716b
commit 7132465945
2 changed files with 31 additions and 48 deletions

View File

@@ -144,18 +144,11 @@ export default function JobTotalsTableLabor({ job }) {
{t("jobs.labels.mapa")} {t("jobs.labels.mapa")}
{InstanceRenderManager({ {InstanceRenderManager({
imex: imex:
job.materials?.mapa && (job.materials?.mapa ?? job.materials?.MAPA)?.cal_maxdlr > 0 &&
job.materials.mapa.cal_maxdlr && t("jobs.labels.threshhold", { amount: (job.materials.mapa ?? job.materials.MAPA).cal_maxdlr }),
job.materials.mapa.cal_maxdlr > 0 &&
t("jobs.labels.threshhold", {
amount: job.materials.mapa.cal_maxdlr
}),
rome: rome:
job.materials?.MAPA && job.materials?.MAPA?.cal_maxdlr !== undefined &&
job.materials.MAPA.cal_maxdlr !== undefined && t("jobs.labels.threshhold", { amount: job.materials.MAPA.cal_maxdlr })
t("jobs.labels.threshhold", {
amount: job.materials.MAPA.cal_maxdlr
})
})} })}
</Space> </Space>
</ResponsiveTable.Summary.Cell> </ResponsiveTable.Summary.Cell>
@@ -190,18 +183,11 @@ export default function JobTotalsTableLabor({ job }) {
{t("jobs.labels.mash")} {t("jobs.labels.mash")}
{InstanceRenderManager({ {InstanceRenderManager({
imex: imex:
job.materials?.mash && (job.materials?.mash ?? job.materials?.MASH)?.cal_maxdlr > 0 &&
job.materials.mash.cal_maxdlr && t("jobs.labels.threshhold", { amount: (job.materials.mash ?? job.materials.MASH).cal_maxdlr }),
job.materials.mash.cal_maxdlr > 0 &&
t("jobs.labels.threshhold", {
amount: job.materials.mash.cal_maxdlr
}),
rome: rome:
job.materials?.MASH && job.materials?.MASH?.cal_maxdlr !== undefined &&
job.materials.MASH.cal_maxdlr !== undefined && t("jobs.labels.threshhold", { amount: job.materials.MASH.cal_maxdlr })
t("jobs.labels.threshhold", {
amount: job.materials.MASH.cal_maxdlr
})
})} })}
</Space> </Space>
</ResponsiveTable.Summary.Cell> </ResponsiveTable.Summary.Cell>

View File

@@ -315,7 +315,12 @@ function CalculateRatesTotals(ratesList) {
if (item.mod_lbr_ty) { if (item.mod_lbr_ty) {
//Check to see if it has 0 hours and a price instead. //Check to see if it has 0 hours and a price instead.
//Extend for when there are hours and a price. //Extend for when there are hours and a price.
if (item.lbr_op === "OP14" && item.act_price > 0 && (!item.part_type || item.mod_lb_hrs === 0) && !IsAdditionalCost(item)) { if (
item.lbr_op === "OP14" &&
item.act_price > 0 &&
(!item.part_type || item.mod_lb_hrs === 0) &&
!IsAdditionalCost(item)
) {
//Scenario where SGI may pay out hours using a part price. //Scenario where SGI may pay out hours using a part price.
if (!ret[item.mod_lbr_ty.toLowerCase()].total) { if (!ret[item.mod_lbr_ty.toLowerCase()].total) {
ret[item.mod_lbr_ty.toLowerCase()].total = Dinero(); ret[item.mod_lbr_ty.toLowerCase()].total = Dinero();
@@ -339,38 +344,30 @@ function CalculateRatesTotals(ratesList) {
let subtotal = Dinero({ amount: 0 }); let subtotal = Dinero({ amount: 0 });
let rates_subtotal = Dinero({ amount: 0 }); let rates_subtotal = Dinero({ amount: 0 });
for (const property in ret) { for (const [property, values] of Object.entries(ret)) {
//Skip calculating mapa and mash if we got the amounts. //Skip calculating mapa and mash if we got the amounts.
if (!((property === "mapa" && hasMapaLine) || (property === "mash" && hasMashLine))) { const shouldSkipCalculation = (property === "mapa" && hasMapaLine) || (property === "mash" && hasMashLine);
if (!ret[property].total) {
ret[property].total = Dinero(); if (!shouldSkipCalculation) {
} values.total ??= Dinero();
let threshold;
//Check if there is a max for this type. //Check if there is a max for this type and apply it.
if (ratesList.materials && ratesList.materials[property]) { const maxDollar =
// ratesList.materials?.[property]?.cal_maxdlr || ratesList.materials?.[property.toUpperCase()]?.cal_maxdlr;
if (ratesList.materials[property].cal_maxdlr && ratesList.materials[property].cal_maxdlr > 0) { const threshold = maxDollar > 0 ? Dinero({ amount: Math.round(maxDollar * 100) }) : null;
//It has an upper threshhold.
threshold = Dinero({
amount: Math.round(ratesList.materials[property].cal_maxdlr * 100)
});
}
}
const total = Dinero({ const total = Dinero({
amount: Math.round((ret[property].rate || 0) * 100) amount: Math.round((values.rate || 0) * 100)
}).multiply(ret[property].hours); }).multiply(values.hours);
if (threshold && total.greaterThanOrEqual(threshold)) { values.total = values.total.add(threshold && total.greaterThanOrEqual(threshold) ? threshold : total);
ret[property].total = ret[property].total.add(threshold);
} else {
ret[property].total = ret[property].total.add(total);
}
} }
subtotal = subtotal.add(ret[property].total); subtotal = subtotal.add(values.total);
if (property !== "mapa" && property !== "mash") rates_subtotal = rates_subtotal.add(ret[property].total); if (property !== "mapa" && property !== "mash") {
rates_subtotal = rates_subtotal.add(values.total);
}
} }
ret.subtotal = subtotal; ret.subtotal = subtotal;