diff --git a/client/src/components/jobs-detail-rates/jobs-detail-rates.parts.component.jsx b/client/src/components/jobs-detail-rates/jobs-detail-rates.parts.component.jsx index 2cd2b8917..71f2103c7 100644 --- a/client/src/components/jobs-detail-rates/jobs-detail-rates.parts.component.jsx +++ b/client/src/components/jobs-detail-rates/jobs-detail-rates.parts.component.jsx @@ -1,4 +1,4 @@ -import { Collapse, Form, InputNumber, Switch } from "antd"; +import { Collapse, Form, Input, InputNumber, Switch } from "antd"; import React from "react"; import { useTranslation } from "react-i18next"; import { connect } from "react-redux"; @@ -563,6 +563,13 @@ export function JobsDetailRatesParts({ > + + + !jl.removed) - .forEach((val) => { - if (!val.tax_part) return; - if (!val.part_type && IsAdditionalCost(val)) { - taxableAmounts.PAO = taxableAmounts.PAO.add( - Dinero({ amount: Math.round((val.act_price || 0) * 100) }).multiply( - val.part_qty || 0 - ) - ); - } else if (!val.part_type) { - //Do nothing for now. - } else { - const typeOfPart = val.part_type === "PAM" ? "PAC" : val.part_type; - taxableAmounts[typeOfPart] = taxableAmounts[typeOfPart].add( - Dinero({ amount: Math.round((val.act_price || 0) * 100) }) - .multiply(val.part_qty || 0) - .add( - val.prt_dsmk_m && - val.prt_dsmk_m !== 0 && - DiscountNotAlreadyCounted(val, job.joblines) - ? val.prt_dsmk_m - ? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) }) - : Dinero({ - amount: Math.round(val.act_price * 100), - }) - .multiply(val.part_qty || 0) - .percentage(Math.abs(val.prt_dsmk_p || 0)) - .multiply(val.prt_dsmk_p > 0 ? 1 : -1) - : Dinero() + if ( + job.parts_tax_rates.PAN.prt_tx_ty1 && + job.parts_tax_rates.PAN.prt_tx_ty1 !== "" + ) { + //For each line, determine if it's taxable, and if it is, add the line amount to the taxable amounts total. + job.joblines + .filter((jl) => !jl.removed) + .forEach((val) => { + if (!val.tax_part) return; + if (!val.part_type && IsAdditionalCost(val)) { + taxableAmounts.PAO = taxableAmounts.PAO.add( + Dinero({ amount: Math.round((val.act_price || 0) * 100) }).multiply( + val.part_qty || 0 ) - ); - } - }); + ); + } else if (!val.part_type) { + //Do nothing for now. + } else { + const typeOfPart = val.part_type === "PAM" ? "PAC" : val.part_type; + taxableAmounts[typeOfPart] = taxableAmounts[typeOfPart].add( + Dinero({ amount: Math.round((val.act_price || 0) * 100) }) + .multiply(val.part_qty || 0) + .add( + val.prt_dsmk_m && + val.prt_dsmk_m !== 0 && + DiscountNotAlreadyCounted(val, job.joblines) + ? val.prt_dsmk_m + ? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) }) + : Dinero({ + amount: Math.round(val.act_price * 100), + }) + .multiply(val.part_qty || 0) + .percentage(Math.abs(val.prt_dsmk_p || 0)) + .multiply(val.prt_dsmk_p > 0 ? 1 : -1) + : Dinero() + ) + ); + } + }); - //Taxable amounts should match with what is in the STL file. - //Now that we have the taxable amounts, apply the tax. + //Taxable amounts should match with what is in the STL file. + //Now that we have the taxable amounts, apply the tax. - const tieredTaxAmounts = { - ty1Tax: Dinero(), - ty2Tax: Dinero(), - ty3Tax: Dinero(), - ty4Tax: Dinero(), - ty5Tax: Dinero(), - ty6Tax: Dinero(), - }; + const tieredTaxAmounts = { + ty1Tax: Dinero(), + ty2Tax: Dinero(), + ty3Tax: Dinero(), + ty4Tax: Dinero(), + ty5Tax: Dinero(), + ty6Tax: Dinero(), + }; - const remainingTaxableAmounts = taxableAmounts; - console.log("Taxable Amounts"); - console.table(JSON.parse(JSON.stringify(taxableAmounts))); - Object.keys(taxableAmounts).forEach((part_type) => { - //Check it's taxability in the PFP - try { - const pfp = job.parts_tax_rates; + const remainingTaxableAmounts = taxableAmounts; + console.log("Taxable Amounts"); + console.table(JSON.parse(JSON.stringify(taxableAmounts))); + Object.keys(taxableAmounts).forEach((part_type) => { + //Check it's taxability in the PFP + try { + const pfp = job.parts_tax_rates; - const typeOfPart = part_type === "PAM" ? "PAC" : part_type; - if (IsTrueOrYes(pfp[typeOfPart].prt_tax_in)) { - //At least one of these scenarios must be taxable. - for (let tyCounter = 1; tyCounter <= 5; tyCounter++) { - if (IsTrueOrYes(pfp[typeOfPart][`prt_tx_in${tyCounter}`])) { - //i represents the tax number. If we got here, this type of tax is applicable. Now we need to add based on the thresholds. - for (let threshCounter = 1; threshCounter <= 5; threshCounter++) { - const thresholdAmount = parseFloat( - job.cieca_pft[`ty${tyCounter}_thres${threshCounter}`] - ); - const thresholdTaxRate = parseFloat( - job.cieca_pft[`ty${tyCounter}_rate${threshCounter}`] - ); + const typeOfPart = part_type === "PAM" ? "PAC" : part_type; + if (IsTrueOrYes(pfp[typeOfPart].prt_tax_in)) { + //At least one of these scenarios must be taxable. + for (let tyCounter = 1; tyCounter <= 5; tyCounter++) { + if (IsTrueOrYes(pfp[typeOfPart][`prt_tx_in${tyCounter}`])) { + //i represents the tax number. If we got here, this type of tax is applicable. Now we need to add based on the thresholds. + for (let threshCounter = 1; threshCounter <= 5; threshCounter++) { + const thresholdAmount = parseFloat( + job.cieca_pft[`ty${tyCounter}_thres${threshCounter}`] + ); + const thresholdTaxRate = parseFloat( + job.cieca_pft[`ty${tyCounter}_rate${threshCounter}`] + ); - let taxableAmountInThisThreshold; - if (thresholdAmount === 9999.99) { - // THis is the last threshold. Tax the entire remaining amount. - taxableAmountInThisThreshold = - remainingTaxableAmounts[typeOfPart]; - remainingTaxableAmounts[typeOfPart] = Dinero(); - } else { - if ( - thresholdAmount >= - remainingTaxableAmounts[typeOfPart].getAmount() / 100 - ) { - //This threshold is bigger than the remaining taxable balance. Add it all. + let taxableAmountInThisThreshold; + if (thresholdAmount === 9999.99) { + // THis is the last threshold. Tax the entire remaining amount. taxableAmountInThisThreshold = remainingTaxableAmounts[typeOfPart]; remainingTaxableAmounts[typeOfPart] = Dinero(); } else { - //Take the size of the threshold from the remaining amount, tax it, and do it all over. - taxableAmountInThisThreshold = Dinero({ - amount: Math.round(thresholdAmount * 100), - }); - remainingTaxableAmounts[typeOfPart] = remainingTaxableAmounts[ - typeOfPart - ].subtract( - Dinero({ - amount: Math.round(taxableAmountInThisThreshold * 100), - }) - ); + if ( + thresholdAmount >= + remainingTaxableAmounts[typeOfPart].getAmount() / 100 + ) { + //This threshold is bigger than the remaining taxable balance. Add it all. + taxableAmountInThisThreshold = + remainingTaxableAmounts[typeOfPart]; + remainingTaxableAmounts[typeOfPart] = Dinero(); + } else { + //Take the size of the threshold from the remaining amount, tax it, and do it all over. + taxableAmountInThisThreshold = Dinero({ + amount: Math.round(thresholdAmount * 100), + }); + remainingTaxableAmounts[typeOfPart] = + remainingTaxableAmounts[typeOfPart].subtract( + Dinero({ + amount: Math.round( + taxableAmountInThisThreshold * 100 + ), + }) + ); + } } + + const taxAmountToAdd = + taxableAmountInThisThreshold.percentage(thresholdTaxRate); + + tieredTaxAmounts[`ty${tyCounter}Tax`] = + tieredTaxAmounts[`ty${tyCounter}Tax`].add(taxAmountToAdd); } - - const taxAmountToAdd = - taxableAmountInThisThreshold.percentage(thresholdTaxRate); - - tieredTaxAmounts[`ty${tyCounter}Tax`] = - tieredTaxAmounts[`ty${tyCounter}Tax`].add(taxAmountToAdd); } } } + } catch (error) { + console.error("Shit the bed."); } - } catch (error) { - console.error("Shit the bed."); - } - }); + }); + + statePartsTax = statePartsTax + .add(tieredTaxAmounts.ty1Tax) + .add(tieredTaxAmounts.ty2Tax) + .add(tieredTaxAmounts.ty3Tax) + .add(tieredTaxAmounts.ty4Tax) + .add(tieredTaxAmounts.ty5Tax) + .add(tieredTaxAmounts.ty6Tax); + console.log("Tiered Taxes Total for Parts", statePartsTax.toFormat()); + } else { + //Use the old thing. + job.joblines + .filter((jl) => !jl.removed) + .forEach((val) => { + if (!val.tax_part) return; + if (!val.part_type && IsAdditionalCost(val)) { + additionalItemsTax = additionalItemsTax.add( + Dinero({ amount: Math.round((val.act_price || 0) * 100) }) + .multiply(val.part_qty || 0) + .percentage( + ((job.parts_tax_rates && + job.parts_tax_rates["PAN"] && + job.parts_tax_rates["PAN"].prt_tax_rt) || + 0) * 100 + ) + ); + } else { + statePartsTax = statePartsTax.add( + Dinero({ amount: Math.round((val.act_price || 0) * 100) }) + .multiply(val.part_qty || 0) + .add( + val.prt_dsmk_m && + val.prt_dsmk_m !== 0 && + DiscountNotAlreadyCounted(val, job.joblines) + ? val.prt_dsmk_m + ? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) }) + : Dinero({ + amount: Math.round(val.act_price * 100), + }) + .multiply(val.part_qty || 0) + .percentage(Math.abs(val.prt_dsmk_p || 0)) + .multiply(val.prt_dsmk_p > 0 ? 1 : -1) + : Dinero() + ) + .percentage( + ((job.parts_tax_rates && + job.parts_tax_rates[val.part_type] && + job.parts_tax_rates[val.part_type].prt_tax_rt) || + (val.part_type && + val.part_type.startsWith("PAG") && + BackupGlassTax && + BackupGlassTax.prt_tax_rt) || + (!val.part_type && + val.db_ref === "900510" && + job.parts_tax_rates["PAN"] && + job.parts_tax_rates["PAN"].prt_tax_rt) || + 0) * 100 + ) + ); + } + console.log(statePartsTax.toFormat(), val.line_desc); + }); + } - statePartsTax = statePartsTax - .add(tieredTaxAmounts.ty1Tax) - .add(tieredTaxAmounts.ty2Tax) - .add(tieredTaxAmounts.ty3Tax) - .add(tieredTaxAmounts.ty4Tax) - .add(tieredTaxAmounts.ty5Tax) - .add(tieredTaxAmounts.ty6Tax); - console.log("Tiered Taxes Total for Parts", statePartsTax.toFormat()); let laborTaxTotal = Dinero(); if (Object.keys(job.cieca_pfl).length > 0) { @@ -975,7 +1035,7 @@ function CalculateTaxesTotals(job, otherTotals) { .add( otherTotals.additional.storage.percentage((job.tax_str_rt || 0) * 100) ) - // .add(additionalItemsTax) + .add(additionalItemsTax) // 0 if using PFP method. .add( otherTotals.rates.mapa.hasMapaLine === false //If parts and materials were not added as lines, we must calculate the taxes on them. ? otherTotals.rates.mapa.total.percentage(