Updates to QuickBooks and DMS export.

This commit is contained in:
Patrick Fic
2023-09-26 12:35:49 -07:00
parent eff4f82ad7
commit d2fe9b0590
5 changed files with 280 additions and 284 deletions

View File

@@ -422,98 +422,98 @@ function replaceEmpty(someObj, replaceValue = null) {
} }
async function CheckTaxRates(estData, bodyshop) { async function CheckTaxRates(estData, bodyshop) {
//LKQ Check // //LKQ Check
if ( // if (
!estData.parts_tax_rates?.PAL || // !estData.parts_tax_rates?.PAL ||
estData.parts_tax_rates?.PAL?.prt_tax_rt === null || // estData.parts_tax_rates?.PAL?.prt_tax_rt === null ||
estData.parts_tax_rates?.PAL?.prt_tax_rt === 0 // estData.parts_tax_rates?.PAL?.prt_tax_rt === 0
) { // ) {
const res = await confirmDialog( // const res = await confirmDialog(
`Rome Online has detected that there is a missing tax rate for LKQ parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.` // `Rome Online has detected that there is a missing tax rate for LKQ parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.`
); // );
if (res) { // if (res) {
if (!estData.parts_tax_rates.PAL) { // if (!estData.parts_tax_rates.PAL) {
estData.parts_tax_rates.PAL = { // estData.parts_tax_rates.PAL = {
prt_discp: 0, // prt_discp: 0,
prt_mktyp: true, // prt_mktyp: true,
prt_mkupp: 0, // prt_mkupp: 0,
prt_type: "PAL", // prt_type: "PAL",
}; // };
} // }
estData.parts_tax_rates.PAL.prt_tax_rt = // estData.parts_tax_rates.PAL.prt_tax_rt =
bodyshop.bill_tax_rates.state_tax_rate / 100; // bodyshop.bill_tax_rates.state_tax_rate / 100;
estData.parts_tax_rates.PAL.prt_tax_in = true; // estData.parts_tax_rates.PAL.prt_tax_in = true;
} // }
} // }
//PAC Check // //PAC Check
if ( // if (
!estData.parts_tax_rates?.PAC || // !estData.parts_tax_rates?.PAC ||
estData.parts_tax_rates?.PAC?.prt_tax_rt === null || // estData.parts_tax_rates?.PAC?.prt_tax_rt === null ||
estData.parts_tax_rates?.PAC?.prt_tax_rt === 0 // estData.parts_tax_rates?.PAC?.prt_tax_rt === 0
) { // ) {
const res = await confirmDialog( // const res = await confirmDialog(
`Rome Online has detected that there is a missing tax rate for rechromed parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.` // `Rome Online has detected that there is a missing tax rate for rechromed parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.`
); // );
if (res) { // if (res) {
if (!estData.parts_tax_rates.PAC) { // if (!estData.parts_tax_rates.PAC) {
estData.parts_tax_rates.PAC = { // estData.parts_tax_rates.PAC = {
prt_discp: 0, // prt_discp: 0,
prt_mktyp: true, // prt_mktyp: true,
prt_mkupp: 0, // prt_mkupp: 0,
prt_type: "PAC", // prt_type: "PAC",
}; // };
} // }
estData.parts_tax_rates.PAC.prt_tax_rt = // estData.parts_tax_rates.PAC.prt_tax_rt =
bodyshop.bill_tax_rates.state_tax_rate / 100; // bodyshop.bill_tax_rates.state_tax_rate / 100;
estData.parts_tax_rates.PAC.prt_tax_in = true; // estData.parts_tax_rates.PAC.prt_tax_in = true;
} // }
} // }
//PAM Check // //PAM Check
if ( // if (
!estData.parts_tax_rates?.PAM || // !estData.parts_tax_rates?.PAM ||
estData.parts_tax_rates?.PAM?.prt_tax_rt === null || // estData.parts_tax_rates?.PAM?.prt_tax_rt === null ||
estData.parts_tax_rates?.PAM?.prt_tax_rt === 0 // estData.parts_tax_rates?.PAM?.prt_tax_rt === 0
) { // ) {
const res = await confirmDialog( // const res = await confirmDialog(
`Rome Online has detected that there is a missing tax rate for remanufactured parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.` // `Rome Online has detected that there is a missing tax rate for remanufactured parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.`
); // );
if (res) { // if (res) {
if (!estData.parts_tax_rates.PAM) { // if (!estData.parts_tax_rates.PAM) {
estData.parts_tax_rates.PAM = { // estData.parts_tax_rates.PAM = {
prt_discp: 0, // prt_discp: 0,
prt_mktyp: true, // prt_mktyp: true,
prt_mkupp: 0, // prt_mkupp: 0,
prt_type: "PAM", // prt_type: "PAM",
}; // };
} // }
estData.parts_tax_rates.PAM.prt_tax_rt = // estData.parts_tax_rates.PAM.prt_tax_rt =
bodyshop.bill_tax_rates.state_tax_rate / 100; // bodyshop.bill_tax_rates.state_tax_rate / 100;
estData.parts_tax_rates.PAM.prt_tax_in = true; // estData.parts_tax_rates.PAM.prt_tax_in = true;
} // }
} // }
if ( // if (
!estData.parts_tax_rates?.PAR || // !estData.parts_tax_rates?.PAR ||
estData.parts_tax_rates?.PAR?.prt_tax_rt === null || // estData.parts_tax_rates?.PAR?.prt_tax_rt === null ||
estData.parts_tax_rates?.PAR?.prt_tax_rt === 0 // estData.parts_tax_rates?.PAR?.prt_tax_rt === 0
) { // ) {
const res = await confirmDialog( // const res = await confirmDialog(
`Rome Online has detected that there is a missing tax rate for recored parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.` // `Rome Online has detected that there is a missing tax rate for recored parts. Pressing OK will set the tax rate to ${bodyshop.bill_tax_rates.state_tax_rate}% and enable the rate. Pressing cancel will keep the tax rate as is.`
); // );
if (res) { // if (res) {
if (!estData.parts_tax_rates.PAR) { // if (!estData.parts_tax_rates.PAR) {
estData.parts_tax_rates.PAR = { // estData.parts_tax_rates.PAR = {
prt_discp: 0, // prt_discp: 0,
prt_mktyp: true, // prt_mktyp: true,
prt_mkupp: 0, // prt_mkupp: 0,
prt_type: "PAR", // prt_type: "PAR",
}; // };
} // }
estData.parts_tax_rates.PAR.prt_tax_rt = // estData.parts_tax_rates.PAR.prt_tax_rt =
bodyshop.bill_tax_rates.state_tax_rate / 100; // bodyshop.bill_tax_rates.state_tax_rate / 100;
estData.parts_tax_rates.PAR.prt_tax_in = true; // estData.parts_tax_rates.PAR.prt_tax_in = true;
} // }
} // }
//IO-1387 If a sublet line is NOT R&R, use the labor tax. If it is, use the sublet tax rate. //IO-1387 If a sublet line is NOT R&R, use the labor tax. If it is, use the sublet tax rate.
//Currently limited to SK shops only. //Currently limited to SK shops only.

View File

@@ -20,7 +20,7 @@ require("dotenv").config({
async function RunTheTest() { async function RunTheTest() {
const bodyshopids = ["a7ee1503-ee05-4a02-b80e-bdb11d1cc8ac"]; const bodyshopids = ["a7ee1503-ee05-4a02-b80e-bdb11d1cc8ac"];
const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjE5MGFkMTE4YTk0MGFkYzlmMmY1Mzc2YjM1MjkyZmVkZThjMmQwZWUiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiUm9tZSBEZXZlbG9wbWVudCIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoidXNlciIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsidXNlciJdLCJ4LWhhc3VyYS11c2VyLWlkIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiJ9LCJpb2FkbWluIjp0cnVlLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vcm9tZS1wcm9kLTEiLCJhdWQiOiJyb21lLXByb2QtMSIsImF1dGhfdGltZSI6MTY5NDQ2NjM3OCwidXNlcl9pZCI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIiLCJzdWIiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIiwiaWF0IjoxNjk0NTQ4MTIwLCJleHAiOjE2OTQ1NTE3MjAsImVtYWlsIjoicGF0cmlja0Byb21lLmRldiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJwYXRyaWNrQHJvbWUuZGV2Il19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifX0.hIR3tAIOZFydmuCC5OS1KmIAG3Rq3mB1ZJAcnWUrJRuioNw1DeezAiUvXlb2iQ3Pow3zpyTkZgNMrLhWNpZmywyjPQQaTU7krw2gNhmRfrILmIWjODepvRcp4mcwvdf65WkqXm88S82b-8nkgvPhogvXmYWHrrDFl9EP4nMXdhjJ8rZ-euBcH9wz9o4BehsW4x91JJxeTU_jk4Fa0h6ppG6XdTmPyTlQb79g-WgLbqtyXEIjQr9q_ZbE4br_PLLhFd7SnUV0e-raw3FcK9m4Mc-n37M4KtKEpDbhXM_2MtGSCWbKZ7m3lfydFaV8LlgnCTiX_gSCvoAmCeRyH5w1yQ`; const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImFhMDhlN2M3ODNkYjhjOGFjNGNhNzJhZjdmOWRkN2JiMzk4ZjE2ZGMiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiUm9tZSBEZXZlbG9wbWVudCIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoidXNlciIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsidXNlciJdLCJ4LWhhc3VyYS11c2VyLWlkIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiJ9LCJpb2FkbWluIjp0cnVlLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vcm9tZS1wcm9kLTEiLCJhdWQiOiJyb21lLXByb2QtMSIsImF1dGhfdGltZSI6MTY5NTE1MDU0NywidXNlcl9pZCI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIiLCJzdWIiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIiwiaWF0IjoxNjk1Mzk5MTM0LCJleHAiOjE2OTU0MDI3MzQsImVtYWlsIjoicGF0cmlja0Byb21lLmRldiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJwYXRyaWNrQHJvbWUuZGV2Il19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifX0.X8PeG0Y0TW08Tx1sBqpWw9N1YYxJWd4lOEAH2KA7Xel6ehg50WdHf42W4RXdGBc-TPzbJgzLJg4jc8_cmSiDiDojSnVzrmfBrbugLRd1Hk31784SvYKb_i1GU1p3s5W-rBHbi1htnNyXqV0nhOgbnOJphJL2l91WG_YaBRA_QiGgy4rAdBhi12LLS5KWGlrP9T99hOfL7o8kG1rhO5y1bGadlpmXAjUpMQAlMX8QVXAe6DB-61vDJPyTpTbfT3yUZfNppNSqqu1wK2c08QwniXf5qhIyGBNeB6qunlDQhFBP-grGcUvVb9ijHHtX7WiFb7wd-AY3oNCx1i5hi5UdPQ`;
const { jobs } = await client.request( const { jobs } = await client.request(
gql` gql`
query GET_JOBS($bodyshopids: [uuid!]!) { query GET_JOBS($bodyshopids: [uuid!]!) {
@@ -87,7 +87,7 @@ async function RunTheTest() {
} else { } else {
result.result = "PASS"; result.result = "PASS";
} }
console.log(`${result.result} => RO ${job.ro_number} - ${job.id} `); // console.log(`${result.result} => RO ${job.ro_number} - ${job.id} `);
results.push(result); results.push(result);
} catch (error) { } catch (error) {

View File

@@ -574,123 +574,54 @@ exports.default = function ({
const job_totals = jobs_by_pk.job_totals; const job_totals = jobs_by_pk.job_totals;
const federal_tax = Dinero(job_totals.totals.federal_tax); const federal_tax = Dinero(job_totals.totals.federal_tax);
const state_tax = Dinero(job_totals.totals.state_tax); const QboTaxId =
const local_tax = Dinero(job_totals.totals.local_tax); process.env.COUNTRY === "USA"
? CheckQBOUSATaxID({
if (federal_tax.getAmount() > 0) { // jobline: jobline,
if (qbo) { type: "adjustment",
// do qbo job: jobs_by_pk,
} else { })
InvoiceLineAdd.push({ : taxCodes[taxAccountCode];
ItemRef: { for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
FullName: const taxAmount = Dinero(
bodyshop.md_responsibility_centers.taxes.federal.accountitem, job_totals.totals.us_sales_tax_breakdown[`ty${tyCounter}Tax`]
}, );
Desc: bodyshop.md_responsibility_centers.taxes.federal.accountdesc, if (taxAmount.getAmount() > 0) {
Amount: federal_tax.toFormat(DineroQbFormat), if (qbo) {
}); InvoiceLineAdd.push({
} DetailType: "SalesItemLineDetail",
} Amount: taxAmount.toFormat(DineroQbFormat),
SalesItemLineDetail: {
if (state_tax.getAmount() > 0) { ...(jobs_by_pk.class
if (qbo) { ? { ClassRef: { value: classes[jobs_by_pk.class] } }
// do qbo : {}),
} else { ItemRef: {
InvoiceLineAdd.push({ value:
ItemRef: { items[
FullName: bodyshop.md_responsibility_centers.taxes.state.accountitem, responsibilityCenters.taxes[`tax_ty${tyCounter}`].accountitem
}, ],
Desc: bodyshop.md_responsibility_centers.taxes.state.accountdesc, },
Amount: state_tax.toFormat(DineroQbFormat), TaxCodeRef: {
}); value: QboTaxId,
} },
} Qty: 1,
},
if (local_tax.getAmount() > 0) { });
if (qbo) { } else {
// do qbo InvoiceLineAdd.push({
} else {
InvoiceLineAdd.push({
ItemRef: {
FullName: bodyshop.md_responsibility_centers.taxes.local.accountitem,
},
Desc: bodyshop.md_responsibility_centers.taxes.local.accountdesc,
Amount: local_tax.toFormat(DineroQbFormat),
});
}
}
//Region Specific
const { ca_bc_pvrt } = jobs_by_pk;
if (ca_bc_pvrt) {
if (qbo) {
InvoiceLineAdd.push({
DetailType: "SalesItemLineDetail",
Amount: Dinero({ amount: (ca_bc_pvrt || 0) * 100 }).toFormat(
DineroQbFormat
),
SalesItemLineDetail: {
...(jobs_by_pk.class
? { ClassRef: { value: classes[jobs_by_pk.class] } }
: {}),
ItemRef: { ItemRef: {
value: items["PVRT"], FullName:
bodyshop.md_responsibility_centers.taxes[`tax_ty${tyCounter}`]
.accountitem,
}, },
Qty: 1, Desc: bodyshop.md_responsibility_centers.taxes[`tax_ty${tyCounter}`]
TaxCodeRef: { .accountdesc,
value: Amount: taxAmount.toFormat(DineroQbFormat),
taxCodes[ });
findTaxCode( }
{
local: false,
federal: process.env.COUNTRY === "USA" ? false : true,
state: false,
},
bodyshop.md_responsibility_centers.sales_tax_codes
)
],
},
},
});
} else {
InvoiceLineAdd.push({
ItemRef: {
FullName: bodyshop.md_responsibility_centers.taxes.state.accountitem,
},
Desc: "PVRT",
Amount: Dinero({ amount: (ca_bc_pvrt || 0) * 100 }).toFormat(
DineroQbFormat
),
});
} }
} }
//QB USA with GST
//This was required for the No. 1 Collision Group.
// if (
// bodyshop.accountingconfig &&
// bodyshop.accountingconfig.qbo &&
// bodyshop.accountingconfig.qbo_usa &&
// bodyshop.region_config.includes("CA_")
// ) {
// InvoiceLineAdd.push({
// DetailType: "SalesItemLineDetail",
// Amount: Dinero(jobs_by_pk.job_totals.totals.federal_tax).toFormat(
// DineroQbFormat
// ),
// SalesItemLineDetail: {
// ...(jobs_by_pk.class
// ? { ClassRef: { value: classes[jobs_by_pk.class] } }
// : {}),
// ItemRef: {
// value:
// items[bodyshop.md_responsibility_centers.taxes.federal.accountitem],
// },
// Qty: 1,
// },
// });
// }
if (!qbo && InvoiceLineAdd.length === 0) { if (!qbo && InvoiceLineAdd.length === 0) {
//Handle the scenario where there is a $0 sale invoice. //Handle the scenario where there is a $0 sale invoice.
InvoiceLineAdd.push({ InvoiceLineAdd.push({
@@ -832,17 +763,19 @@ exports.createMultiQbPayerLines = function ({
}; };
function CheckQBOUSATaxID({ jobline, job, type }) { function CheckQBOUSATaxID({ jobline, job, type }) {
if (type === "labor") { //Replacing this to be all non-taxable items with the refactor of parts tax rates.
return jobline.lbr_tax ? "TAX" : "NON"; return "NON";
} else if (type === "part") { // if (type === "labor") {
return jobline.tax_part ? "TAX" : "NON"; // return jobline.lbr_tax ? "TAX" : "NON";
} else if (type === "materials") { // } else if (type === "part") {
return job.tax_paint_mat_rt > 0 ? "TAX" : "NON"; // return jobline.tax_part ? "TAX" : "NON";
} else if (type === " towing") { // } else if (type === "materials") {
return true ? "TAX" : "NON"; // return job.tax_paint_mat_rt > 0 ? "TAX" : "NON";
} else if (type === "adjustment") { // } else if (type === " towing") {
return false ? "TAX" : "NON"; // return true ? "TAX" : "NON";
} else { // } else if (type === "adjustment") {
throw new Error(`Unknown type to calculate tax id: ${type} `); // return false ? "TAX" : "NON";
} // } else {
// throw new Error(`Unknown type to calculate tax id: ${type} `);
// }
} }

View File

@@ -25,26 +25,61 @@ exports.default = async function (socket, jobid) {
const { bodyshop } = job; const { bodyshop } = job;
const taxAllocations = { const taxAllocations = {
local: { // local: {
center: bodyshop.md_responsibility_centers.taxes.local.name, // center: bodyshop.md_responsibility_centers.taxes.local.name,
sale: Dinero(job.job_totals.totals.local_tax), // sale: Dinero(job.job_totals.totals.local_tax),
// cost: Dinero(),
// profitCenter: bodyshop.md_responsibility_centers.taxes.local,
// costCenter: bodyshop.md_responsibility_centers.taxes.local,
// },
// state: {
// center: bodyshop.md_responsibility_centers.taxes.state.name,
// sale: Dinero(job.job_totals.totals.state_tax),
// cost: Dinero(),
// profitCenter: bodyshop.md_responsibility_centers.taxes.state,
// costCenter: bodyshop.md_responsibility_centers.taxes.state,
// },
// federal: {
// center: bodyshop.md_responsibility_centers.taxes.federal.name,
// sale: Dinero(job.job_totals.totals.federal_tax),
// cost: Dinero(),
// profitCenter: bodyshop.md_responsibility_centers.taxes.federal,
// costCenter: bodyshop.md_responsibility_centers.taxes.federal,
// },
tax_ty1: {
center: bodyshop.md_responsibility_centers.taxes[`tax_ty1`].name,
sale: Dinero(job_totals.totals.us_sales_tax_breakdown[`ty1Tax`]),
cost: Dinero(), cost: Dinero(),
profitCenter: bodyshop.md_responsibility_centers.taxes.local, profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty1`],
costCenter: bodyshop.md_responsibility_centers.taxes.local, costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty1`],
}, },
state: { tax_ty2: {
center: bodyshop.md_responsibility_centers.taxes.state.name, center: bodyshop.md_responsibility_centers.taxes[`tax_ty2`].name,
sale: Dinero(job.job_totals.totals.state_tax), sale: Dinero(job_totals.totals.us_sales_tax_breakdown[`ty2Tax`]),
cost: Dinero(), cost: Dinero(),
profitCenter: bodyshop.md_responsibility_centers.taxes.state, profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty2`],
costCenter: bodyshop.md_responsibility_centers.taxes.state, costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty2`],
}, },
federal: { tax_ty3: {
center: bodyshop.md_responsibility_centers.taxes.federal.name, center: bodyshop.md_responsibility_centers.taxes[`tax_ty3`].name,
sale: Dinero(job.job_totals.totals.federal_tax), sale: Dinero(job_totals.totals.us_sales_tax_breakdown[`ty3Tax`]),
cost: Dinero(), cost: Dinero(),
profitCenter: bodyshop.md_responsibility_centers.taxes.federal, profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty3`],
costCenter: bodyshop.md_responsibility_centers.taxes.federal, costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty3`],
},
tax_ty4: {
center: bodyshop.md_responsibility_centers.taxes[`tax_ty4`].name,
sale: Dinero(job_totals.totals.us_sales_tax_breakdown[`ty4Tax`]),
cost: Dinero(),
profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty4`],
costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty4`],
},
tax_ty5: {
center: bodyshop.md_responsibility_centers.taxes[`tax_ty5`].name,
sale: Dinero(job_totals.totals.us_sales_tax_breakdown[`ty5Tax`]),
cost: Dinero(),
profitCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty5`],
costCenter: bodyshop.md_responsibility_centers.taxes[`tax_ty5`],
}, },
}; };

View File

@@ -483,24 +483,25 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
value.db_ref !== "900511" value.db_ref !== "900511"
) )
return acc; return acc;
const discountAmount =
((value.prt_dsmk_m && value.prt_dsmk_m !== 0) ||
(value.prt_dsmk_p && value.prt_dsmk_p !== 0)) &&
DiscountNotAlreadyCounted(value, jl)
? value.prt_dsmk_m
? Dinero({ amount: Math.round(value.prt_dsmk_m * 100) })
: Dinero({
amount: Math.round(value.act_price * 100),
})
.multiply(value.part_qty || 0)
.percentage(Math.abs(value.prt_dsmk_p || 0))
.multiply(value.prt_dsmk_p > 0 ? 1 : -1)
: Dinero();
return { return {
...acc, ...acc,
parts: { parts: {
...acc.parts, ...acc.parts,
prt_dsmk_total: acc.parts.prt_dsmk_total.add( prt_dsmk_total: acc.parts.prt_dsmk_total.add(discountAmount),
((value.prt_dsmk_m && value.prt_dsmk_m !== 0) ||
(value.prt_dsmk_p && value.prt_dsmk_p !== 0)) &&
DiscountNotAlreadyCounted(value, jl)
? value.prt_dsmk_m
? Dinero({ amount: Math.round(value.prt_dsmk_m * 100) })
: Dinero({
amount: Math.round(value.act_price * 100),
})
.multiply(value.part_qty || 0)
.percentage(Math.abs(value.prt_dsmk_p || 0))
.multiply(value.prt_dsmk_p > 0 ? 1 : -1)
: Dinero()
),
...(value.part_type ...(value.part_type
? { ? {
list: { list: {
@@ -509,20 +510,24 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
acc.parts.list[value.part_type] && acc.parts.list[value.part_type] &&
acc.parts.list[value.part_type].total acc.parts.list[value.part_type].total
? { ? {
total: acc.parts.list[value.part_type].total.add( total: acc.parts.list[value.part_type].total
Dinero({ .add(
amount: Math.round( Dinero({
(value.act_price || 0) * 100 amount: Math.round(
), (value.act_price || 0) * 100
}).multiply(value.part_qty || 0) ),
), }).multiply(value.part_qty || 0)
)
.add(discountAmount),
} }
: { : {
total: Dinero({ total: Dinero({
amount: Math.round( amount: Math.round(
(value.act_price || 0) * 100 (value.act_price || 0) * 100
), ),
}).multiply(value.part_qty || 0), })
.multiply(value.part_qty || 0)
.add(discountAmount),
}, },
}, },
} }
@@ -624,7 +629,7 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
); );
//If the difference is greater than a penny, fix it. //If the difference is greater than a penny, fix it.
//This usually ties into whether or not the profile has part type discounts overall in the PFP.
if ( if (
correspondingCiecaStlTotalLine && correspondingCiecaStlTotalLine &&
Math.abs( Math.abs(
@@ -663,7 +668,7 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
// ret.parts.list[key].total = ret.parts.list[key]?.total.subtract( // ret.parts.list[key].total = ret.parts.list[key]?.total.subtract(
// totalDiscountToAdjustBy // totalDiscountToAdjustBy
// ); // );
ret.parts.prt_dsmk_total = ret.parts.prt_dsmk_total.add( ret.parts.prt_dsmk_total = ret.parts.prt_dsmk_total.subtract(
totalDiscountToAdjustBy totalDiscountToAdjustBy
); );
ret.parts.subtotal = ret.parts.subtotal.subtract(totalDiscountToAdjustBy); ret.parts.subtotal = ret.parts.subtotal.subtract(totalDiscountToAdjustBy);
@@ -671,7 +676,7 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
} }
}); });
//UpdateJobLines(linesToAdjustForDiscount.filter((l) => l.prt_dsmk_m !== 0)); UpdateJobLines(linesToAdjustForDiscount.filter((l) => l.prt_dsmk_m !== 0));
return { return {
adjustments, adjustments,
@@ -804,6 +809,9 @@ function CalculateTaxesTotals(job, otherTotals) {
LAM: Dinero(), LAM: Dinero(),
LAR: Dinero(), LAR: Dinero(),
LAS: Dinero(), LAS: Dinero(),
MAPA: Dinero(),
MASH: Dinero(),
}; };
if ( if (
@@ -824,14 +832,14 @@ function CalculateTaxesTotals(job, otherTotals) {
} else if (!val.part_type) { } else if (!val.part_type) {
//Do nothing for now. //Do nothing for now.
} else { } else {
const typeOfPart = val.part_type; // === "PAM" ? "PAC" : val.part_type; const typeOfPart = val.part_type;
taxableAmounts[typeOfPart] = taxableAmounts[typeOfPart].add( taxableAmounts[typeOfPart] = taxableAmounts[typeOfPart].add(
Dinero({ amount: Math.round((val.act_price || 0) * 100) }) Dinero({ amount: Math.round((val.act_price || 0) * 100) })
.multiply(val.part_qty || 0) .multiply(val.part_qty || 0)
.add( .add(
val.prt_dsmk_m && val.prt_dsmk_m &&
val.prt_dsmk_m !== 0 && val.prt_dsmk_m !== 0 &&
DiscountNotAlreadyCounted(val, job.joblines) DiscountNotAlreadyCounted(val, job.joblines) // DO WE NEED TO COUNT PFP DISCOUNT HERE?
? val.prt_dsmk_m ? val.prt_dsmk_m
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) }) ? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
: Dinero({ : Dinero({
@@ -858,6 +866,17 @@ function CalculateTaxesTotals(job, otherTotals) {
} }
}); });
Object.keys(taxableAmounts)
.filter((key) => key.startsWith("MA"))
.map((key) => {
const isTypeTaxable = job.materials[key]?.tax_ind;
if (isTypeTaxable) {
taxableAmounts[key] = taxableAmounts[key].add(
otherTotals.rates[key.toLowerCase()].total
);
}
});
console.log("*** Taxable Amounts***"); console.log("*** Taxable Amounts***");
console.table(JSON.parse(JSON.stringify(taxableAmounts))); console.table(JSON.parse(JSON.stringify(taxableAmounts)));
@@ -883,6 +902,7 @@ function CalculateTaxesTotals(job, otherTotals) {
const pfp = job.parts_tax_rates; const pfp = job.parts_tax_rates;
const pfl = job.cieca_pfl; const pfl = job.cieca_pfl;
const pfm = job.materials;
Object.keys(taxableAmounts).map((key) => { Object.keys(taxableAmounts).map((key) => {
try { try {
if (key.startsWith("PA")) { if (key.startsWith("PA")) {
@@ -896,6 +916,16 @@ function CalculateTaxesTotals(job, otherTotals) {
].add(taxableAmounts[typeOfPart]); ].add(taxableAmounts[typeOfPart]);
} }
} }
} else if (key.startsWith("MA")) {
//Materials Handling
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
if (IsTrueOrYes(pfm[key][`mat_tx_in${tyCounter}`])) {
//This amount is taxable for this type.
taxableAmountsByTier[`ty${tyCounter}Tax`] = taxableAmountsByTier[
`ty${tyCounter}Tax`
].add(taxableAmounts[key]);
}
}
} else { } else {
//Labor. //Labor.
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) { for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
@@ -1060,7 +1090,7 @@ function CalculateTaxesTotals(job, otherTotals) {
statePartsTax, statePartsTax,
us_sales_tax_breakdown, us_sales_tax_breakdown,
state_tax: statePartsTax state_tax: statePartsTax
.add(laborTaxTotal) //.add(laborTaxTotal)
.add( .add(
otherTotals.additional.adjustments.percentage( otherTotals.additional.adjustments.percentage(
(job.tax_lbr_rt || 0) * 100 (job.tax_lbr_rt || 0) * 100
@@ -1071,22 +1101,22 @@ function CalculateTaxesTotals(job, otherTotals) {
) )
.add( .add(
otherTotals.additional.storage.percentage((job.tax_str_rt || 0) * 100) otherTotals.additional.storage.percentage((job.tax_str_rt || 0) * 100)
)
.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(
(job.tax_paint_mat_rt || 0) * 100
)
: Dinero()
)
.add(
otherTotals.rates.mash.hasMashLine === false //If parts and materials were not added as lines, we must calculate the taxes on them.
? otherTotals.rates.mash.total.percentage(
(job.tax_shop_mat_rt || 0) * 100
)
: Dinero()
), ),
// .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(
// (job.tax_paint_mat_rt || 0) * 100
// )
// : Dinero()
// )
// .add(
// otherTotals.rates.mash.hasMashLine === false //If parts and materials were not added as lines, we must calculate the taxes on them.
// ? otherTotals.rates.mash.total.percentage(
// (job.tax_shop_mat_rt || 0) * 100
// )
// : Dinero()
// )
local_tax: subtotal.percentage((job.local_tax_rate || 0) * 100), local_tax: subtotal.percentage((job.local_tax_rate || 0) * 100),
}; };
ret.total_repairs = ret.subtotal ret.total_repairs = ret.subtotal
@@ -1132,14 +1162,12 @@ function DiscountNotAlreadyCounted(jobline, joblines) {
return false; return false;
} }
//Check it against the database price too? If it's an OE part. if (
// if ( jobline.db_price !== jobline.act_price &&
// Math.abs(jobline.db_price - jobline.act_price) - jobline.db_price - jobline.act_price - Math.abs(jobline.prt_dsmk_m) < 0.02
// Math.abs(jobline.prt_dsmk_m) < ) {
// 0.01 return false;
// ) { }
// return false;
// }
if ( if (
//If it's not a discount line, then it definitely hasn't been counted yet. //If it's not a discount line, then it definitely hasn't been counted yet.