File diff suppressed because it is too large
Load Diff
@@ -123,10 +123,10 @@ export default function JobTotalsTableLabor({ job }) {
|
|||||||
<Space>
|
<Space>
|
||||||
{t("jobs.labels.mapa")}
|
{t("jobs.labels.mapa")}
|
||||||
{job.materials &&
|
{job.materials &&
|
||||||
job.materials.mapa &&
|
job.materials.MAPA &&
|
||||||
job.materials.mapa.cal_maxdlr !== undefined &&
|
job.materials.MAPA.cal_maxdlr !== undefined &&
|
||||||
t("jobs.labels.threshhold", {
|
t("jobs.labels.threshhold", {
|
||||||
amount: job.materials.mapa.cal_maxdlr,
|
amount: job.materials.MAPA.cal_maxdlr,
|
||||||
})}
|
})}
|
||||||
</Space>
|
</Space>
|
||||||
</Table.Summary.Cell>
|
</Table.Summary.Cell>
|
||||||
@@ -147,10 +147,10 @@ export default function JobTotalsTableLabor({ job }) {
|
|||||||
<Space wrap>
|
<Space wrap>
|
||||||
{t("jobs.labels.mash")}
|
{t("jobs.labels.mash")}
|
||||||
{job.materials &&
|
{job.materials &&
|
||||||
job.materials.mash &&
|
job.materials.MASH &&
|
||||||
job.materials.mash.cal_maxdlr !== undefined &&
|
job.materials.MASH.cal_maxdlr !== undefined &&
|
||||||
t("jobs.labels.threshhold", {
|
t("jobs.labels.threshhold", {
|
||||||
amount: job.materials.mash.cal_maxdlr,
|
amount: job.materials.MASH.cal_maxdlr,
|
||||||
})}
|
})}
|
||||||
</Space>
|
</Space>
|
||||||
</Table.Summary.Cell>
|
</Table.Summary.Cell>
|
||||||
|
|||||||
@@ -28,26 +28,36 @@ export function JobTotalsTableTotals({ bodyshop, job }) {
|
|||||||
total: job.job_totals.totals.subtotal,
|
total: job.job_totals.totals.subtotal,
|
||||||
bold: true,
|
bold: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: t("jobs.labels.local_tax_amt"),
|
...(job.job_totals.totals.us_sales_tax_breakdown
|
||||||
total: job.job_totals.totals.local_tax,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: t("jobs.labels.state_tax_amt"),
|
|
||||||
total: job.job_totals.totals.state_tax,
|
|
||||||
},
|
|
||||||
...(bodyshop.region_config === "CA_BC"
|
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
key: t("jobs.fields.ca_bc_pvrt"),
|
key: bodyshop.md_responsibility_centers.taxes.tax_ty1.tax_type1,
|
||||||
total: job.job_totals.additional.pvrt,
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty1Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: bodyshop.md_responsibility_centers.taxes.tax_ty2.tax_type2,
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty2Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: bodyshop.md_responsibility_centers.taxes.tax_ty3.tax_type3,
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty3Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: bodyshop.md_responsibility_centers.taxes.tax_ty4.tax_type4,
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty4Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: bodyshop.md_responsibility_centers.taxes.tax_ty5.tax_type5,
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty5Tax,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: [
|
||||||
{
|
{
|
||||||
key: t("jobs.labels.federal_tax_amt"),
|
key: t("jobs.labels.state_tax_amt"),
|
||||||
total: job.job_totals.totals.federal_tax,
|
total: job.job_totals.totals.state_tax,
|
||||||
},
|
},
|
||||||
|
]),
|
||||||
{
|
{
|
||||||
key: t("jobs.labels.total_repairs"),
|
key: t("jobs.labels.total_repairs"),
|
||||||
total: job.job_totals.totals.total_repairs,
|
total: job.job_totals.totals.total_repairs,
|
||||||
@@ -81,7 +91,7 @@ export function JobTotalsTableTotals({ bodyshop, job }) {
|
|||||||
bold: true,
|
bold: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [job.job_totals, t, bodyshop.region_config]);
|
}, [job.job_totals, t, bodyshop.md_responsibility_centers]);
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
useQuery,
|
useQuery,
|
||||||
} from "@apollo/client";
|
} from "@apollo/client";
|
||||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
import { Col, Row, notification } from "antd";
|
import { Button, Col, Row, notification } from "antd";
|
||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
@@ -31,7 +31,6 @@ import {
|
|||||||
selectCurrentUser,
|
selectCurrentUser,
|
||||||
} from "../../redux/user/user.selectors";
|
} from "../../redux/user/user.selectors";
|
||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
import confirmDialog from "../../utils/asyncConfirm";
|
|
||||||
import CriticalPartsScan from "../../utils/criticalPartsScan";
|
import CriticalPartsScan from "../../utils/criticalPartsScan";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
|
import JobsAvailableScan from "../jobs-available-scan/jobs-available-scan.component";
|
||||||
@@ -90,13 +89,14 @@ export function JobsAvailableContainer({
|
|||||||
const modalSearchState = useState("");
|
const modalSearchState = useState("");
|
||||||
|
|
||||||
//Import Scenario
|
//Import Scenario
|
||||||
const onOwnerFindModalOk = async () => {
|
const onOwnerFindModalOk = async (lazyData) => {
|
||||||
logImEXEvent("job_import_new");
|
logImEXEvent("job_import_new");
|
||||||
|
|
||||||
setOwnerModalVisible(false);
|
setOwnerModalVisible(false);
|
||||||
setInsertLoading(true);
|
setInsertLoading(true);
|
||||||
|
const estData = replaceEmpty(
|
||||||
const estData = replaceEmpty(estDataRaw.data.available_jobs_by_pk);
|
lazyData?.available_jobs_by_pk || estDataRaw.data.available_jobs_by_pk
|
||||||
|
);
|
||||||
|
|
||||||
if (!(estData && estData.est_data)) {
|
if (!(estData && estData.est_data)) {
|
||||||
//We don't have the right data. Error!
|
//We don't have the right data. Error!
|
||||||
@@ -165,47 +165,46 @@ export function JobsAvailableContainer({
|
|||||||
newJob.kmin = null;
|
newJob.kmin = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
insertNewJob({
|
try {
|
||||||
variables: {
|
const r = await insertNewJob({
|
||||||
job: newJob,
|
variables: {
|
||||||
},
|
job: newJob,
|
||||||
})
|
},
|
||||||
.then((r) => {
|
});
|
||||||
Axios.post("/job/totalsssu", {
|
await Axios.post("/job/totalsssu", {
|
||||||
id: r.data.insert_jobs.returning[0].id,
|
id: r.data.insert_jobs.returning[0].id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (CriticalPartsScanning.treatment === "on") {
|
if (CriticalPartsScanning.treatment === "on") {
|
||||||
CriticalPartsScan(r.data.insert_jobs.returning[0].id);
|
CriticalPartsScan(r.data.insert_jobs.returning[0].id);
|
||||||
}
|
}
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("jobs.successes.created"),
|
message: t("jobs.successes.created"),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
history.push(`/manage/jobs/${r.data.insert_jobs.returning[0].id}`);
|
history.push(`/manage/jobs/${r.data.insert_jobs.returning[0].id}`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
//Job has been inserted. Clean up the available jobs record.
|
//Job has been inserted. Clean up the available jobs record.
|
||||||
|
|
||||||
insertAuditTrail({
|
insertAuditTrail({
|
||||||
jobid: r.data.insert_jobs.returning[0].id,
|
jobid: r.data.insert_jobs.returning[0].id,
|
||||||
operation: AuditTrailMapping.jobimported(),
|
operation: AuditTrailMapping.jobimported(),
|
||||||
});
|
});
|
||||||
|
|
||||||
deleteJob({
|
await deleteJob({
|
||||||
variables: { id: estData.id },
|
variables: { id: estData.id },
|
||||||
}).then((r) => {
|
}).then((r) => {
|
||||||
refetch();
|
|
||||||
setInsertLoading(false);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((r) => {
|
|
||||||
//error while inserting
|
|
||||||
notification["error"]({
|
|
||||||
message: t("jobs.errors.creating", { error: r.message }),
|
|
||||||
});
|
|
||||||
refetch();
|
refetch();
|
||||||
setInsertLoading(false);
|
setInsertLoading(false);
|
||||||
});
|
});
|
||||||
|
} catch (r) {
|
||||||
|
//error while inserting
|
||||||
|
notification["error"]({
|
||||||
|
message: t("jobs.errors.creating", { error: r.message }),
|
||||||
|
});
|
||||||
|
refetch();
|
||||||
|
setInsertLoading(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//Suplement scenario
|
//Suplement scenario
|
||||||
@@ -392,6 +391,25 @@ export function JobsAvailableContainer({
|
|||||||
onCancel={onJobModalCancel}
|
onCancel={onJobModalCancel}
|
||||||
modalSearchState={modalSearchState}
|
modalSearchState={modalSearchState}
|
||||||
/>
|
/>
|
||||||
|
{currentUser.email.includes("@rome.") ||
|
||||||
|
currentUser.email.includes("@imex.") ? (
|
||||||
|
<Button
|
||||||
|
onClick={async () => {
|
||||||
|
for (const record of data.available_jobs) {
|
||||||
|
//Query the data
|
||||||
|
console.log("Start Job", record.id);
|
||||||
|
const { data } = await loadEstData({
|
||||||
|
variables: { id: record.id },
|
||||||
|
});
|
||||||
|
console.log("Query has been awaited and is complete");
|
||||||
|
await onOwnerFindModalOk(data);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add all jobs as new.
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<JobsAvailableTableComponent
|
<JobsAvailableTableComponent
|
||||||
@@ -423,98 +441,104 @@ 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 = estData.parts_tax_rates.PAC;
|
||||||
estData.parts_tax_rates?.PAM?.prt_tax_rt === null ||
|
|
||||||
estData.parts_tax_rates?.PAM?.prt_tax_rt === 0
|
|
||||||
) {
|
|
||||||
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.`
|
|
||||||
);
|
|
||||||
if (res) {
|
|
||||||
if (!estData.parts_tax_rates.PAM) {
|
|
||||||
estData.parts_tax_rates.PAM = {
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: true,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_type: "PAM",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
estData.parts_tax_rates.PAM.prt_tax_rt =
|
|
||||||
bodyshop.bill_tax_rates.state_tax_rate / 100;
|
|
||||||
estData.parts_tax_rates.PAM.prt_tax_in = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
// //PAM Check
|
||||||
!estData.parts_tax_rates?.PAR ||
|
// if (
|
||||||
estData.parts_tax_rates?.PAR?.prt_tax_rt === null ||
|
// !estData.parts_tax_rates?.PAM ||
|
||||||
estData.parts_tax_rates?.PAR?.prt_tax_rt === 0
|
// estData.parts_tax_rates?.PAM?.prt_tax_rt === null ||
|
||||||
) {
|
// estData.parts_tax_rates?.PAM?.prt_tax_rt === 0
|
||||||
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.`
|
// 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.`
|
||||||
if (res) {
|
// );
|
||||||
if (!estData.parts_tax_rates.PAR) {
|
// if (res) {
|
||||||
estData.parts_tax_rates.PAR = {
|
// if (!estData.parts_tax_rates.PAM) {
|
||||||
prt_discp: 0,
|
// estData.parts_tax_rates.PAM = {
|
||||||
prt_mktyp: true,
|
// prt_discp: 0,
|
||||||
prt_mkupp: 0,
|
// prt_mktyp: true,
|
||||||
prt_type: "PAR",
|
// prt_mkupp: 0,
|
||||||
};
|
// prt_type: "PAM",
|
||||||
}
|
// };
|
||||||
estData.parts_tax_rates.PAR.prt_tax_rt =
|
// }
|
||||||
bodyshop.bill_tax_rates.state_tax_rate / 100;
|
// estData.parts_tax_rates.PAM.prt_tax_rt =
|
||||||
estData.parts_tax_rates.PAR.prt_tax_in = true;
|
// bodyshop.bill_tax_rates.state_tax_rate / 100;
|
||||||
}
|
// estData.parts_tax_rates.PAM.prt_tax_in = true;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (
|
||||||
|
// !estData.parts_tax_rates?.PAR ||
|
||||||
|
// estData.parts_tax_rates?.PAR?.prt_tax_rt === null ||
|
||||||
|
// estData.parts_tax_rates?.PAR?.prt_tax_rt === 0
|
||||||
|
// ) {
|
||||||
|
// 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.`
|
||||||
|
// );
|
||||||
|
// if (res) {
|
||||||
|
// if (!estData.parts_tax_rates.PAR) {
|
||||||
|
// estData.parts_tax_rates.PAR = {
|
||||||
|
// prt_discp: 0,
|
||||||
|
// prt_mktyp: true,
|
||||||
|
// prt_mkupp: 0,
|
||||||
|
// prt_type: "PAR",
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
// estData.parts_tax_rates.PAR.prt_tax_rt =
|
||||||
|
// bodyshop.bill_tax_rates.state_tax_rate / 100;
|
||||||
|
// 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.
|
||||||
@@ -542,8 +566,7 @@ async function ResolveCCCLineIssues(estData, bodyshop) {
|
|||||||
//This needs to be done before cleansing unq_seq since some misc prices could move over.
|
//This needs to be done before cleansing unq_seq since some misc prices could move over.
|
||||||
estData.joblines.data.forEach((line) => {
|
estData.joblines.data.forEach((line) => {
|
||||||
if (line.misc_amt && line.misc_amt !== 0) {
|
if (line.misc_amt && line.misc_amt !== 0) {
|
||||||
line.act_price = line.misc_amt;
|
line.act_price = line.act_price + line.misc_amt;
|
||||||
line.part_type = "PAS";
|
|
||||||
line.tax_part = !!line.misc_tax;
|
line.tax_part = !!line.misc_tax;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ export function JobsCloseAutoAllocate({ bodyshop, joblines, form, disabled }) {
|
|||||||
ret.profitcenter_part = defaults.profits["MAPA"];
|
ret.profitcenter_part = defaults.profits["MAPA"];
|
||||||
} else if (lineDesc.includes("ats amount")) {
|
} else if (lineDesc.includes("ats amount")) {
|
||||||
ret.profitcenter_part = defaults.profits["ATS"];
|
ret.profitcenter_part = defaults.profits["ATS"];
|
||||||
|
} else if (jl.act_price > 0) {
|
||||||
|
ret.profitcenter_part = defaults.profits["PAO"];
|
||||||
} else {
|
} else {
|
||||||
ret.profitcenter_part = null;
|
ret.profitcenter_part = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs
|
|||||||
import JobsMarkPstExempt from "../jobs-mark-pst-exempt/jobs-mark-pst-exempt.component";
|
import JobsMarkPstExempt from "../jobs-mark-pst-exempt/jobs-mark-pst-exempt.component";
|
||||||
import FormRow from "../layout-form-row/layout-form-row.component";
|
import FormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import JobsDetailRatesParts from "./jobs-detail-rates.parts.component";
|
import JobsDetailRatesParts from "./jobs-detail-rates.parts.component";
|
||||||
|
import JobsDetailRatesLabor from "./jobs-detail-rates.labor.component";
|
||||||
|
import JobsDetailRatesMaterials from "./jobs-detail-rates.materials.component";
|
||||||
|
import JobsDetailRatesOther from "./jobs-detail-rates.other.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
jobRO: selectJobReadOnly,
|
jobRO: selectJobReadOnly,
|
||||||
@@ -243,6 +246,9 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<JobsDetailRatesParts form={form} />
|
<JobsDetailRatesParts form={form} />
|
||||||
|
<JobsDetailRatesLabor form={form} />
|
||||||
|
<JobsDetailRatesMaterials form={form} />
|
||||||
|
<JobsDetailRatesOther form={form} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,427 @@
|
|||||||
|
import { Collapse, Form, Switch } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
jobRO: selectJobReadOnly,
|
||||||
|
});
|
||||||
|
|
||||||
|
export function JobsDetailRatesLabor({
|
||||||
|
jobRO,
|
||||||
|
expanded,
|
||||||
|
required = true,
|
||||||
|
form,
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Collapse defaultActiveKey={expanded && "rates"}>
|
||||||
|
<Collapse.Panel
|
||||||
|
forceRender
|
||||||
|
header={t("jobs.labels.cieca_pfl")}
|
||||||
|
key="cieca_pfl"
|
||||||
|
>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAB")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAD")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAE")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAF")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAG")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAM")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAR")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAS")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("joblines.fields.lbr_types.LAU")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tax_in")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tax_in"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(mapStateToProps, null)(JobsDetailRatesLabor);
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
import { Collapse, Form, Input, InputNumber, Switch } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
jobRO: selectJobReadOnly,
|
||||||
|
});
|
||||||
|
|
||||||
|
export function JobsDetailRatesMaterials({
|
||||||
|
jobRO,
|
||||||
|
expanded,
|
||||||
|
required = true,
|
||||||
|
form,
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Collapse defaultActiveKey={expanded && "rates"}>
|
||||||
|
<Collapse.Panel
|
||||||
|
forceRender
|
||||||
|
header={t("jobs.labels.materials.materials")}
|
||||||
|
key="materials"
|
||||||
|
>
|
||||||
|
<LayoutFormRow header={t("job.fields.materials.MAPA")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.cal_maxdlr")}
|
||||||
|
name={["materials", "MAPA", "cal_maxdlr"]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.cal_opcode")}
|
||||||
|
name={["materials", "MAPA", "cal_opcode"]}
|
||||||
|
>
|
||||||
|
<Input disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.tax_ind")}
|
||||||
|
name={["materials", "MAPA", "tax_ind"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in1")}
|
||||||
|
name={["materials", "MAPA", "mat_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in2")}
|
||||||
|
name={["materials", "MAPA", "mat_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in3")}
|
||||||
|
name={["materials", "MAPA", "mat_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in4")}
|
||||||
|
name={["materials", "MAPA", "mat_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in5")}
|
||||||
|
name={["materials", "MAPA", "mat_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow header={t("job.fields.materials.MASH")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.cal_maxdlr")}
|
||||||
|
name={["materials", "MASH", "cal_maxdlr"]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.cal_opcode")}
|
||||||
|
name={["materials", "MASH", "cal_opcode"]}
|
||||||
|
>
|
||||||
|
<Input disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.tax_ind")}
|
||||||
|
name={["materials", "MASH", "tax_ind"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in1")}
|
||||||
|
name={["materials", "MASH", "mat_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in2")}
|
||||||
|
name={["materials", "MASH", "mat_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in3")}
|
||||||
|
name={["materials", "MASH", "mat_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in4")}
|
||||||
|
name={["materials", "MASH", "mat_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.materials.mat_tx_in5")}
|
||||||
|
name={["materials", "MASH", "mat_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(mapStateToProps, null)(JobsDetailRatesMaterials);
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
import { Collapse, Form, Switch } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
jobRO: selectJobReadOnly,
|
||||||
|
});
|
||||||
|
|
||||||
|
export function JobsDetailRatesOther({
|
||||||
|
jobRO,
|
||||||
|
expanded,
|
||||||
|
required = true,
|
||||||
|
form,
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Collapse defaultActiveKey={expanded && "rates"}>
|
||||||
|
<Collapse.Panel
|
||||||
|
forceRender
|
||||||
|
header={t("jobs.labels.cieca_pfo")}
|
||||||
|
key="cieca_pfo"
|
||||||
|
>
|
||||||
|
<LayoutFormRow header={t("jobs.fields.cieca_pfo")}>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.tow_t_in1")}
|
||||||
|
name={["cieca_pfo", "tow_t_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.tow_t_in2")}
|
||||||
|
name={["cieca_pfo", "tow_t_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.tow_t_in3")}
|
||||||
|
name={["cieca_pfo", "tow_t_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.tow_t_in4")}
|
||||||
|
name={["cieca_pfo", "tow_t_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.tow_t_in5")}
|
||||||
|
name={["cieca_pfo", "tow_t_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.stor_t_in1")}
|
||||||
|
name={["cieca_pfo", "stor_t_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.stor_t_in2")}
|
||||||
|
name={["cieca_pfo", "stor_t_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.stor_t_in3")}
|
||||||
|
name={["cieca_pfo", "stor_t_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.stor_t_in4")}
|
||||||
|
name={["cieca_pfo", "stor_t_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfo.stor_t_in5")}
|
||||||
|
name={["cieca_pfo", "stor_t_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
</LayoutFormRow>
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(mapStateToProps, null)(JobsDetailRatesOther);
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Collapse, Form, InputNumber, Switch } from "antd";
|
import { Collapse, Form, Input, InputNumber, Switch } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -68,11 +68,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAA", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAA", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAA", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAA", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAA", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAC")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAC")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -118,11 +158,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAC", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAC", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAC", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAC", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAC", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAL")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAL")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -168,11 +248,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAL", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAL", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAL", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAL", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAL", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAG")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAG")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -218,11 +338,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAG", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAG", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAG", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAG", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAG", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAM")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAM")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -268,11 +428,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAM", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAM", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAM", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAM", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAM", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAN")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAN")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -318,11 +518,58 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAN", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAN", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAN", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAN", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAN", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
style={{ display: "none" }}
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_ty1")}
|
||||||
|
name={["parts_tax_rates", "PAN", "prt_tx_ty1"]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAO")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAO")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -368,11 +615,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAO", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAO", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAO", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAO", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAO", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAP")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAP")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -418,11 +705,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAP", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAP", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAP", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAP", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAP", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAR")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAR")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -468,11 +795,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAR", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAR", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAR", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAR", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAR", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAS")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAS")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -518,11 +885,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PAS", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PAS", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PAS", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PAS", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PAS", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PASL")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PASL")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -568,11 +975,51 @@ export function JobsDetailRatesParts({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<InputNumber min={0} max={100} precision={4} disabled={jobRO} />
|
<InputNumber
|
||||||
|
min={0}
|
||||||
|
max={100}
|
||||||
|
precision={4}
|
||||||
|
disabled={jobRO}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in1")}
|
||||||
|
name={["parts_tax_rates", "PASL", "prt_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in2")}
|
||||||
|
name={["parts_tax_rates", "PASL", "prt_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in3")}
|
||||||
|
name={["parts_tax_rates", "PASL", "prt_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in4")}
|
||||||
|
name={["parts_tax_rates", "PASL", "prt_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.parts_tax_rates.prt_tx_in5")}
|
||||||
|
name={["parts_tax_rates", "PASL", "prt_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch />
|
||||||
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.CCDR")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.CCDR")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { selectBodyshop } from "../../redux/user/user.selectors";
|
|||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { useTreatments } from "@splitsoftware/splitio-react";
|
import { useTreatments } from "@splitsoftware/splitio-react";
|
||||||
|
import ShopInfoResponsibilitycentersTaxesComponent from "./shop-info.responsibilitycenters.taxes.component";
|
||||||
|
|
||||||
const SelectorDiv = styled.div`
|
const SelectorDiv = styled.div`
|
||||||
.ant-form-item .ant-select {
|
.ant-form-item .ant-select {
|
||||||
@@ -4445,6 +4446,7 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
|
|||||||
<InputNumber precision={2} />
|
<InputNumber precision={2} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
|
<ShopInfoResponsibilitycentersTaxesComponent />
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.responsibilitycenters.itemexemptcode")}
|
label={t("bodyshop.fields.responsibilitycenters.itemexemptcode")}
|
||||||
rules={[
|
rules={[
|
||||||
|
|||||||
@@ -0,0 +1,232 @@
|
|||||||
|
import { Divider, Form, Input, InputNumber, Space } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
//currentUser: selectCurrentUser
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ShopInfoResponsibilityCenters);
|
||||||
|
|
||||||
|
export function ShopInfoResponsibilityCenters({ bodyshop }) {
|
||||||
|
//Iteratively build the form items.
|
||||||
|
const formItems = [];
|
||||||
|
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
|
||||||
|
const section = [];
|
||||||
|
|
||||||
|
section.push(
|
||||||
|
TaxFormItems({
|
||||||
|
typeNum: tyCounter,
|
||||||
|
rootElements: true,
|
||||||
|
bodyshop,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
for (let iterator = 1; iterator <= 5; iterator++) {
|
||||||
|
section.push(
|
||||||
|
TaxFormItems({
|
||||||
|
typeNum: tyCounter,
|
||||||
|
typeNumIterator: iterator,
|
||||||
|
rootElements: false,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
formItems.push(Space({ children: section, wrap: true }));
|
||||||
|
formItems.push(<Divider />);
|
||||||
|
}
|
||||||
|
return formItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
function TaxFormItems({ typeNum, typeNumIterator, rootElements, bodyshop }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
if (rootElements)
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_type", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
`tax_type${typeNum}`,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenters.state_tax")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
"name",
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
"accountdesc",
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_accountitem")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
"accountitem",
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.dms.dms_acctnumber")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
"dms_acctnumber",
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_tier", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
`ty${typeNum}_tier${typeNumIterator}`,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<InputNumber precision={0} min={0} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_thres", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
`ty${typeNum}_thres${typeNumIterator}`,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_rate", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
`ty${typeNum}_rate${typeNumIterator}`,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_sur", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={[
|
||||||
|
"md_responsibility_centers",
|
||||||
|
"taxes",
|
||||||
|
`tax_ty${typeNum}`,
|
||||||
|
`ty${typeNum}_sur${typeNumIterator}`,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} />
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -779,6 +779,9 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cieca_ttl
|
cieca_ttl
|
||||||
|
cieca_pfo
|
||||||
|
cieca_pfl
|
||||||
|
materials
|
||||||
csiinvites {
|
csiinvites {
|
||||||
id
|
id
|
||||||
completedon
|
completedon
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import { insertAuditTrail } from "../../redux/application/application.actions";
|
|||||||
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
import JobsDocumentsLocalGallery from "../../components/jobs-documents-local-gallery/jobs-documents-local-gallery.container";
|
||||||
import UndefinedToNull from "../../utils/undefinedtonull";
|
import UndefinedToNull from "../../utils/undefinedtonull";
|
||||||
import NoteUpsertModalComponent from "../../components/note-upsert-modal/note-upsert-modal.container";
|
import NoteUpsertModalComponent from "../../components/note-upsert-modal/note-upsert-modal.container";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -103,13 +104,42 @@ export function JobsDetailPage({
|
|||||||
"category",
|
"category",
|
||||||
"referral_source",
|
"referral_source",
|
||||||
]),
|
]),
|
||||||
parts_tax_rates: {
|
// The union and spread is required to keep values coming in from the estimating system that aren't displayed.
|
||||||
...job.parts_tax_rates,
|
parts_tax_rates: _.union(
|
||||||
...values.parts_tax_rates,
|
Object.keys(job.parts_tax_rates),
|
||||||
},
|
Object.keys(values.parts_tax_rates)
|
||||||
|
).reduce((acc, val) => {
|
||||||
|
acc[val] = {
|
||||||
|
...job.parts_tax_rates[val],
|
||||||
|
...values.parts_tax_rates[val],
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
|
materials: _.union(
|
||||||
|
Object.keys(job.materials),
|
||||||
|
Object.keys(values.materials)
|
||||||
|
).reduce((acc, val) => {
|
||||||
|
acc[val] = {
|
||||||
|
...job.materials[val],
|
||||||
|
...values.materials[val],
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
|
cieca_pfl: _.union(
|
||||||
|
Object.keys(job.cieca_pfl),
|
||||||
|
Object.keys(values.cieca_pfl)
|
||||||
|
).reduce((acc, val) => {
|
||||||
|
acc[val] = {
|
||||||
|
...job.cieca_pfl[val],
|
||||||
|
...values.cieca_pfl[val],
|
||||||
|
};
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
|
cieca_pfo: { ...job.cieca_pfo, ...values.cieca_pfo },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const newTotals = await Axios.post("/job/totalsssu", {
|
const newTotals = await Axios.post("/job/totalsssu", {
|
||||||
id: job.id,
|
id: job.id,
|
||||||
});
|
});
|
||||||
@@ -389,6 +419,21 @@ export function JobsDetailPage({
|
|||||||
export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailPage);
|
export default connect(mapStateToProps, mapDispatchToProps)(JobsDetailPage);
|
||||||
|
|
||||||
const transormJobToForm = (job) => {
|
const transormJobToForm = (job) => {
|
||||||
|
Object.keys(job.parts_tax_rates).forEach((parttype) => {
|
||||||
|
Object.keys(job.parts_tax_rates[parttype]).forEach((key) => {
|
||||||
|
if (key.includes("tx_in")) {
|
||||||
|
if (
|
||||||
|
job.parts_tax_rates[parttype][key] === "Y" ||
|
||||||
|
job.parts_tax_rates[parttype][key] === true
|
||||||
|
) {
|
||||||
|
job.parts_tax_rates[parttype][key] = true;
|
||||||
|
} else {
|
||||||
|
job.parts_tax_rates[parttype][key] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...job,
|
...job,
|
||||||
loss_date: job.loss_date ? moment(job.loss_date) : null,
|
loss_date: job.loss_date ? moment(job.loss_date) : null,
|
||||||
|
|||||||
@@ -473,6 +473,11 @@
|
|||||||
"responsibilitycenter_accountname": "Account Name",
|
"responsibilitycenter_accountname": "Account Name",
|
||||||
"responsibilitycenter_accountnumber": "Account Number",
|
"responsibilitycenter_accountnumber": "Account Number",
|
||||||
"responsibilitycenter_rate": "Rate",
|
"responsibilitycenter_rate": "Rate",
|
||||||
|
"responsibilitycenter_tax_rate": "Tax {{typeNum}} Tier {{typeNumIterator}} Rate",
|
||||||
|
"responsibilitycenter_tax_sur": "Tax {{typeNum}} Tier {{typeNumIterator}} Surcharge",
|
||||||
|
"responsibilitycenter_tax_thres": "Tax {{typeNum}} Tier {{typeNumIterator}} Threshold",
|
||||||
|
"responsibilitycenter_tax_tier": "Tax {{typeNum}} Tier {{typeNumIterator}}",
|
||||||
|
"responsibilitycenter_tax_type": "Tax {{typeNum}} Type",
|
||||||
"responsibilitycenters": {
|
"responsibilitycenters": {
|
||||||
"ap": "Accounts Payable",
|
"ap": "Accounts Payable",
|
||||||
"ar": "Accounts Receivable",
|
"ar": "Accounts Receivable",
|
||||||
@@ -613,8 +618,8 @@
|
|||||||
"jobstatuses": "Job Statuses",
|
"jobstatuses": "Job Statuses",
|
||||||
"laborrates": "Labor Rates",
|
"laborrates": "Labor Rates",
|
||||||
"licensing": "Licensing",
|
"licensing": "Licensing",
|
||||||
"md_tasks_presets": "Tasks Presets",
|
|
||||||
"md_parts_scan": "Parts Scan Rules",
|
"md_parts_scan": "Parts Scan Rules",
|
||||||
|
"md_tasks_presets": "Tasks Presets",
|
||||||
"md_to_emails": "Preset To Emails",
|
"md_to_emails": "Preset To Emails",
|
||||||
"md_to_emails_emails": "Emails",
|
"md_to_emails_emails": "Emails",
|
||||||
"messagingpresets": "Messaging Presets",
|
"messagingpresets": "Messaging Presets",
|
||||||
@@ -1439,6 +1444,26 @@
|
|||||||
"ccf": "CC Refuel",
|
"ccf": "CC Refuel",
|
||||||
"ccm": "CC Mileage",
|
"ccm": "CC Mileage",
|
||||||
"cieca_id": "CIECA ID",
|
"cieca_id": "CIECA ID",
|
||||||
|
"cieca_pfl": {
|
||||||
|
"lbr_tax_in": "Tax Labor Indicator",
|
||||||
|
"lbr_tx_in1": "Tax 1 Indicator",
|
||||||
|
"lbr_tx_in2": "Tax 2 Indicator",
|
||||||
|
"lbr_tx_in3": "Tax 3 Indicator",
|
||||||
|
"lbr_tx_in4": "Tax 4 Indicator",
|
||||||
|
"lbr_tx_in5": "Tax 5 Indicator"
|
||||||
|
},
|
||||||
|
"cieca_pfo": {
|
||||||
|
"stor_t_in1": "Storage Tax 1 Indicator",
|
||||||
|
"stor_t_in2": "Storage Tax 2 Indicator",
|
||||||
|
"stor_t_in3": "Storage Tax 3 Indicator",
|
||||||
|
"stor_t_in4": "Storage Tax 4 Indicator",
|
||||||
|
"stor_t_in5": "Storage Tax 5 Indicator",
|
||||||
|
"tow_t_in1": "Tow Tax 1 Indicator",
|
||||||
|
"tow_t_in2": "Tow Tax 2 Indicator",
|
||||||
|
"tow_t_in3": "Tow Tax 3 Indicator",
|
||||||
|
"tow_t_in4": "Tow Tax 4 Indicator",
|
||||||
|
"tow_t_in5": "Tow Tax 5 Indicator"
|
||||||
|
},
|
||||||
"claim_total": "Claim Total",
|
"claim_total": "Claim Total",
|
||||||
"class": "Class",
|
"class": "Class",
|
||||||
"clm_no": "Claim #",
|
"clm_no": "Claim #",
|
||||||
@@ -1552,6 +1577,19 @@
|
|||||||
"mapa": "Paint Materials",
|
"mapa": "Paint Materials",
|
||||||
"mash": "Shop Materials",
|
"mash": "Shop Materials",
|
||||||
"matd": "Tire Disposal",
|
"matd": "Tire Disposal",
|
||||||
|
"materials": {
|
||||||
|
"MAPA": "Paint Materials",
|
||||||
|
"MASH": "Shop Materials",
|
||||||
|
"cal_maxdlr": "Threshhold",
|
||||||
|
"cal_opcode": "OP Codes",
|
||||||
|
"mat_tx_in1": "Tax 1 Indicator",
|
||||||
|
"mat_tx_in2": "Tax 2 Indicator",
|
||||||
|
"mat_tx_in3": "Tax 3 Indicator",
|
||||||
|
"mat_tx_in4": "Tax 4 Indicator",
|
||||||
|
"mat_tx_in5": "Tax 5 Indicator",
|
||||||
|
"materials": "Profile - Materials",
|
||||||
|
"tax_ind": "Tax Indicator"
|
||||||
|
},
|
||||||
"other_amount_payable": "Other Amount Payable",
|
"other_amount_payable": "Other Amount Payable",
|
||||||
"owner": "Owner",
|
"owner": "Owner",
|
||||||
"owner_owing": "Cust. Owes",
|
"owner_owing": "Cust. Owes",
|
||||||
@@ -1574,6 +1612,11 @@
|
|||||||
"prt_mkupp": "Markup %",
|
"prt_mkupp": "Markup %",
|
||||||
"prt_tax_in": "Tax Indicator",
|
"prt_tax_in": "Tax Indicator",
|
||||||
"prt_tax_rt": "Part Tax Rate",
|
"prt_tax_rt": "Part Tax Rate",
|
||||||
|
"prt_tx_in1": "Tax 1 Indicator",
|
||||||
|
"prt_tx_in2": "Tax 2 Indicator",
|
||||||
|
"prt_tx_in3": "Tax 3 Indicator",
|
||||||
|
"prt_tx_in4": "Tax 4 Indicator",
|
||||||
|
"prt_tx_in5": "Tax 5 Indicator",
|
||||||
"prt_type": "Part Type"
|
"prt_type": "Part Type"
|
||||||
},
|
},
|
||||||
"partsstatus": "Parts Status",
|
"partsstatus": "Parts Status",
|
||||||
@@ -1701,6 +1744,7 @@
|
|||||||
"checklistcompletedby": "Checklist completed by {{by}} at {{at}}",
|
"checklistcompletedby": "Checklist completed by {{by}} at {{at}}",
|
||||||
"checklistdocuments": "Checklist Documents",
|
"checklistdocuments": "Checklist Documents",
|
||||||
"checklists": "Checklists",
|
"checklists": "Checklists",
|
||||||
|
"cieca_pfl": "Profile - Labor",
|
||||||
"closeconfirm": "Are you sure you want to close this job? This cannot be easily undone.",
|
"closeconfirm": "Are you sure you want to close this job? This cannot be easily undone.",
|
||||||
"closejob": "Close Job {{ro_number}}",
|
"closejob": "Close Job {{ro_number}}",
|
||||||
"closingperiod": "This Invoice Date is outside of the Closing Period.",
|
"closingperiod": "This Invoice Date is outside of the Closing Period.",
|
||||||
@@ -1773,6 +1817,9 @@
|
|||||||
"mapa": "Paint Materials",
|
"mapa": "Paint Materials",
|
||||||
"markforreexport": "Mark for Re-export",
|
"markforreexport": "Mark for Re-export",
|
||||||
"mash": "Shop Materials",
|
"mash": "Shop Materials",
|
||||||
|
"materials": {
|
||||||
|
"mapa": ""
|
||||||
|
},
|
||||||
"multipayers": "Additional Payers",
|
"multipayers": "Additional Payers",
|
||||||
"net_repairs": "Net Repairs",
|
"net_repairs": "Net Repairs",
|
||||||
"notes": "Notes",
|
"notes": "Notes",
|
||||||
@@ -1799,7 +1846,7 @@
|
|||||||
"totalreturns": "The total <b>retail</b> amount of returns created for this job."
|
"totalreturns": "The total <b>retail</b> amount of returns created for this job."
|
||||||
},
|
},
|
||||||
"ppc": "This line contains a part price change.",
|
"ppc": "This line contains a part price change.",
|
||||||
"profileadjustments": "Profile Disc./Mkup (Already included above)",
|
"profileadjustments": "Profile Disc./Mkup",
|
||||||
"prt_dsmk_total": "Line Item Adjustment",
|
"prt_dsmk_total": "Line Item Adjustment",
|
||||||
"rates": "Rates",
|
"rates": "Rates",
|
||||||
"rates_subtotal": "All Rates Subtotal",
|
"rates_subtotal": "All Rates Subtotal",
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"scheduledfor": "Cita programada para:",
|
"scheduledfor": "Cita programada para:",
|
||||||
"severalerrorsfound": "",
|
"severalerrorsfound": "",
|
||||||
"smartscheduling": "",
|
"smartscheduling": "",
|
||||||
|
"smspaymentreminder": "",
|
||||||
"suggesteddates": ""
|
"suggesteddates": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -472,6 +473,11 @@
|
|||||||
"responsibilitycenter_accountname": "",
|
"responsibilitycenter_accountname": "",
|
||||||
"responsibilitycenter_accountnumber": "",
|
"responsibilitycenter_accountnumber": "",
|
||||||
"responsibilitycenter_rate": "",
|
"responsibilitycenter_rate": "",
|
||||||
|
"responsibilitycenter_tax_rate": "",
|
||||||
|
"responsibilitycenter_tax_sur": "",
|
||||||
|
"responsibilitycenter_tax_thres": "",
|
||||||
|
"responsibilitycenter_tax_tier": "",
|
||||||
|
"responsibilitycenter_tax_type": "",
|
||||||
"responsibilitycenters": {
|
"responsibilitycenters": {
|
||||||
"ap": "",
|
"ap": "",
|
||||||
"ar": "",
|
"ar": "",
|
||||||
@@ -1438,6 +1444,26 @@
|
|||||||
"ccf": "",
|
"ccf": "",
|
||||||
"ccm": "",
|
"ccm": "",
|
||||||
"cieca_id": "CIECA ID",
|
"cieca_id": "CIECA ID",
|
||||||
|
"cieca_pfl": {
|
||||||
|
"lbr_tax_in": "",
|
||||||
|
"lbr_tx_in1": "",
|
||||||
|
"lbr_tx_in2": "",
|
||||||
|
"lbr_tx_in3": "",
|
||||||
|
"lbr_tx_in4": "",
|
||||||
|
"lbr_tx_in5": ""
|
||||||
|
},
|
||||||
|
"cieca_pfo": {
|
||||||
|
"stor_t_in1": "",
|
||||||
|
"stor_t_in2": "",
|
||||||
|
"stor_t_in3": "",
|
||||||
|
"stor_t_in4": "",
|
||||||
|
"stor_t_in5": "",
|
||||||
|
"tow_t_in1": "",
|
||||||
|
"tow_t_in2": "",
|
||||||
|
"tow_t_in3": "",
|
||||||
|
"tow_t_in4": "",
|
||||||
|
"tow_t_in5": ""
|
||||||
|
},
|
||||||
"claim_total": "Reclamar total",
|
"claim_total": "Reclamar total",
|
||||||
"class": "",
|
"class": "",
|
||||||
"clm_no": "Reclamación #",
|
"clm_no": "Reclamación #",
|
||||||
@@ -1551,6 +1577,19 @@
|
|||||||
"mapa": "",
|
"mapa": "",
|
||||||
"mash": "",
|
"mash": "",
|
||||||
"matd": "",
|
"matd": "",
|
||||||
|
"materials": {
|
||||||
|
"MAPA": "",
|
||||||
|
"MASH": "",
|
||||||
|
"cal_maxdlr": "",
|
||||||
|
"cal_opcode": "",
|
||||||
|
"mat_tx_in1": "",
|
||||||
|
"mat_tx_in2": "",
|
||||||
|
"mat_tx_in3": "",
|
||||||
|
"mat_tx_in4": "",
|
||||||
|
"mat_tx_in5": "",
|
||||||
|
"materials": "",
|
||||||
|
"tax_ind": ""
|
||||||
|
},
|
||||||
"other_amount_payable": "Otra cantidad a pagar",
|
"other_amount_payable": "Otra cantidad a pagar",
|
||||||
"owner": "Propietario",
|
"owner": "Propietario",
|
||||||
"owner_owing": "Cust. Debe",
|
"owner_owing": "Cust. Debe",
|
||||||
@@ -1573,6 +1612,11 @@
|
|||||||
"prt_mkupp": "",
|
"prt_mkupp": "",
|
||||||
"prt_tax_in": "",
|
"prt_tax_in": "",
|
||||||
"prt_tax_rt": "",
|
"prt_tax_rt": "",
|
||||||
|
"prt_tx_in1": "",
|
||||||
|
"prt_tx_in2": "",
|
||||||
|
"prt_tx_in3": "",
|
||||||
|
"prt_tx_in4": "",
|
||||||
|
"prt_tx_in5": "",
|
||||||
"prt_type": ""
|
"prt_type": ""
|
||||||
},
|
},
|
||||||
"partsstatus": "",
|
"partsstatus": "",
|
||||||
@@ -1700,6 +1744,7 @@
|
|||||||
"checklistcompletedby": "",
|
"checklistcompletedby": "",
|
||||||
"checklistdocuments": "",
|
"checklistdocuments": "",
|
||||||
"checklists": "",
|
"checklists": "",
|
||||||
|
"cieca_pfl": "",
|
||||||
"closeconfirm": "",
|
"closeconfirm": "",
|
||||||
"closejob": "",
|
"closejob": "",
|
||||||
"closingperiod": "",
|
"closingperiod": "",
|
||||||
@@ -1772,6 +1817,9 @@
|
|||||||
"mapa": "",
|
"mapa": "",
|
||||||
"markforreexport": "",
|
"markforreexport": "",
|
||||||
"mash": "",
|
"mash": "",
|
||||||
|
"materials": {
|
||||||
|
"mapa": ""
|
||||||
|
},
|
||||||
"multipayers": "",
|
"multipayers": "",
|
||||||
"net_repairs": "",
|
"net_repairs": "",
|
||||||
"notes": "Notas",
|
"notes": "Notas",
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
"scheduledfor": "Rendez-vous prévu pour:",
|
"scheduledfor": "Rendez-vous prévu pour:",
|
||||||
"severalerrorsfound": "",
|
"severalerrorsfound": "",
|
||||||
"smartscheduling": "",
|
"smartscheduling": "",
|
||||||
|
"smspaymentreminder": "",
|
||||||
"suggesteddates": ""
|
"suggesteddates": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
@@ -472,6 +473,11 @@
|
|||||||
"responsibilitycenter_accountname": "",
|
"responsibilitycenter_accountname": "",
|
||||||
"responsibilitycenter_accountnumber": "",
|
"responsibilitycenter_accountnumber": "",
|
||||||
"responsibilitycenter_rate": "",
|
"responsibilitycenter_rate": "",
|
||||||
|
"responsibilitycenter_tax_rate": "",
|
||||||
|
"responsibilitycenter_tax_sur": "",
|
||||||
|
"responsibilitycenter_tax_thres": "",
|
||||||
|
"responsibilitycenter_tax_tier": "",
|
||||||
|
"responsibilitycenter_tax_type": "",
|
||||||
"responsibilitycenters": {
|
"responsibilitycenters": {
|
||||||
"ap": "",
|
"ap": "",
|
||||||
"ar": "",
|
"ar": "",
|
||||||
@@ -1438,6 +1444,26 @@
|
|||||||
"ccf": "",
|
"ccf": "",
|
||||||
"ccm": "",
|
"ccm": "",
|
||||||
"cieca_id": "CIECA ID",
|
"cieca_id": "CIECA ID",
|
||||||
|
"cieca_pfl": {
|
||||||
|
"lbr_tax_in": "",
|
||||||
|
"lbr_tx_in1": "",
|
||||||
|
"lbr_tx_in2": "",
|
||||||
|
"lbr_tx_in3": "",
|
||||||
|
"lbr_tx_in4": "",
|
||||||
|
"lbr_tx_in5": ""
|
||||||
|
},
|
||||||
|
"cieca_pfo": {
|
||||||
|
"stor_t_in1": "",
|
||||||
|
"stor_t_in2": "",
|
||||||
|
"stor_t_in3": "",
|
||||||
|
"stor_t_in4": "",
|
||||||
|
"stor_t_in5": "",
|
||||||
|
"tow_t_in1": "",
|
||||||
|
"tow_t_in2": "",
|
||||||
|
"tow_t_in3": "",
|
||||||
|
"tow_t_in4": "",
|
||||||
|
"tow_t_in5": ""
|
||||||
|
},
|
||||||
"claim_total": "Total réclamation",
|
"claim_total": "Total réclamation",
|
||||||
"class": "",
|
"class": "",
|
||||||
"clm_no": "Prétendre #",
|
"clm_no": "Prétendre #",
|
||||||
@@ -1551,6 +1577,19 @@
|
|||||||
"mapa": "",
|
"mapa": "",
|
||||||
"mash": "",
|
"mash": "",
|
||||||
"matd": "",
|
"matd": "",
|
||||||
|
"materials": {
|
||||||
|
"MAPA": "",
|
||||||
|
"MASH": "",
|
||||||
|
"cal_maxdlr": "",
|
||||||
|
"cal_opcode": "",
|
||||||
|
"mat_tx_in1": "",
|
||||||
|
"mat_tx_in2": "",
|
||||||
|
"mat_tx_in3": "",
|
||||||
|
"mat_tx_in4": "",
|
||||||
|
"mat_tx_in5": "",
|
||||||
|
"materials": "",
|
||||||
|
"tax_ind": ""
|
||||||
|
},
|
||||||
"other_amount_payable": "Autre montant à payer",
|
"other_amount_payable": "Autre montant à payer",
|
||||||
"owner": "Propriétaire",
|
"owner": "Propriétaire",
|
||||||
"owner_owing": "Cust. Owes",
|
"owner_owing": "Cust. Owes",
|
||||||
@@ -1573,6 +1612,11 @@
|
|||||||
"prt_mkupp": "",
|
"prt_mkupp": "",
|
||||||
"prt_tax_in": "",
|
"prt_tax_in": "",
|
||||||
"prt_tax_rt": "",
|
"prt_tax_rt": "",
|
||||||
|
"prt_tx_in1": "",
|
||||||
|
"prt_tx_in2": "",
|
||||||
|
"prt_tx_in3": "",
|
||||||
|
"prt_tx_in4": "",
|
||||||
|
"prt_tx_in5": "",
|
||||||
"prt_type": ""
|
"prt_type": ""
|
||||||
},
|
},
|
||||||
"partsstatus": "",
|
"partsstatus": "",
|
||||||
@@ -1700,6 +1744,7 @@
|
|||||||
"checklistcompletedby": "",
|
"checklistcompletedby": "",
|
||||||
"checklistdocuments": "",
|
"checklistdocuments": "",
|
||||||
"checklists": "",
|
"checklists": "",
|
||||||
|
"cieca_pfl": "",
|
||||||
"closeconfirm": "",
|
"closeconfirm": "",
|
||||||
"closejob": "",
|
"closejob": "",
|
||||||
"closingperiod": "",
|
"closingperiod": "",
|
||||||
@@ -1772,6 +1817,9 @@
|
|||||||
"mapa": "",
|
"mapa": "",
|
||||||
"markforreexport": "",
|
"markforreexport": "",
|
||||||
"mash": "",
|
"mash": "",
|
||||||
|
"materials": {
|
||||||
|
"mapa": ""
|
||||||
|
},
|
||||||
"multipayers": "",
|
"multipayers": "",
|
||||||
"net_repairs": "",
|
"net_repairs": "",
|
||||||
"notes": "Remarques",
|
"notes": "Remarques",
|
||||||
|
|||||||
@@ -3274,6 +3274,7 @@
|
|||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
- cieca_pfl
|
- cieca_pfl
|
||||||
|
- cieca_pfo
|
||||||
- cieca_pft
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
@@ -3542,6 +3543,7 @@
|
|||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
- cieca_pfl
|
- cieca_pfl
|
||||||
|
- cieca_pfo
|
||||||
- cieca_pft
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
@@ -3821,6 +3823,7 @@
|
|||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
- cieca_pfl
|
- cieca_pfl
|
||||||
|
- cieca_pfo
|
||||||
- cieca_pft
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Could not auto-generate a down migration.
|
||||||
|
-- Please write an appropriate down migration for the SQL below:
|
||||||
|
-- alter table "public"."jobs" add column "cieca_pfo" jsonb
|
||||||
|
-- null default jsonb_build_object();
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."jobs" add column "cieca_pfo" jsonb
|
||||||
|
null default jsonb_build_object();
|
||||||
@@ -19,8 +19,8 @@ require("dotenv").config({
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function RunTheTest() {
|
async function RunTheTest() {
|
||||||
const bodyshopids = ["6c63a820-542c-497e-8c82-0cc38fb2bbca"];
|
const bodyshopids = ["a7ee1503-ee05-4a02-b80e-bdb11d1cc8ac"];
|
||||||
const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImM2MGI5ZGUwODBmZmFmYmZjMTgzMzllY2Q0NGFjNzdmN2ZhNGU4ZDMiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiUm9tZSBEZXZlbG9wbWVudCIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoiYWRtaW4iLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbImFkbWluIl0sIngtaGFzdXJhLXVzZXItaWQiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIn0sImlvYWRtaW4iOnRydWUsImlzcyI6Imh0dHBzOi8vc2VjdXJldG9rZW4uZ29vZ2xlLmNvbS9yb21lLXByb2QtMSIsImF1ZCI6InJvbWUtcHJvZC0xIiwiYXV0aF90aW1lIjoxNjkyODk5ODE2LCJ1c2VyX2lkIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiIsInN1YiI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIiLCJpYXQiOjE2OTMyNTA1NjIsImV4cCI6MTY5MzI1NDE2MiwiZW1haWwiOiJwYXRyaWNrQHJvbWUuZGV2IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7ImVtYWlsIjpbInBhdHJpY2tAcm9tZS5kZXYiXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.POr8U2pP4XtTJEDRJ_BveRkCs92CIfDDdfU24OYe_aZh6LFPN0bQukNHXrLt3gaD30SUcg5mgmI2VUphgmwviMEGY-zizPC9o6GUKEEppZWQXfrfTyJNa1VKKH9h5zZPPFFW8UJRMi131pCc0ev26GS8Do-FJAgwHLJd6Jp2RbbqiCIeafNMhQCEoXohOk-VArNe7tPAb6-IjxqGVyNqvVyIo6niSXYvmgNjyF1WnnIw0CsnPoJlc5kVMtRdYeshJI7V117MOlUwZicF62vsm32eCunjn3qhN5XsujI7gy9us3vzwhdR1lxISZCLhLOXEYHPL373HJh7I_KN1C3NuA`;
|
const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImFkNWM1ZTlmNTdjOWI2NDYzYzg1ODQ1YTA4OTlhOWQ0MTI5MmM4YzMiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiUm9tZSBEZXZlbG9wbWVudCIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoidXNlciIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsidXNlciJdLCJ4LWhhc3VyYS11c2VyLWlkIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiJ9LCJpb2FkbWluIjp0cnVlLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vcm9tZS1wcm9kLTEiLCJhdWQiOiJyb21lLXByb2QtMSIsImF1dGhfdGltZSI6MTY5NTE1MDU0NywidXNlcl9pZCI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIiLCJzdWIiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIiwiaWF0IjoxNjk1ODUzNTI5LCJleHAiOjE2OTU4NTcxMjksImVtYWlsIjoicGF0cmlja0Byb21lLmRldiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJwYXRyaWNrQHJvbWUuZGV2Il19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifX0.cLDqjTy7dyo3MYwRuWaDxFz0faqDqK5elCFy78qgr4IMhWQEZKdO1FIJoBmxuGn7qbJUfgSRettkYx5YcY3AzrzlTu7UbL6yz7yMyCUjIOF189OLhN-IZH8sHbyb4xvpP4GvYLkaEoBjTCvMaSW-9ycpM3uvYbjgCO81p2gGjo56E2TGoT8tfWE-NGO2nGv_-UacTrZWh_8CGijeZrC9QXeY3DSXTykRV1_xWA7UQNi8IeKphgXsVkOsQI6xC5fXCBWThOfx2RN5af36fU-b3aVXCq21M5y3tJg1IZbzlcYyyBw8Gc71wfp5bjKU92EPH8yCnbic7B5c5Yzk2ikWZg`;
|
||||||
const { jobs } = await client.request(
|
const { jobs } = await client.request(
|
||||||
gql`
|
gql`
|
||||||
query GET_JOBS($bodyshopids: [uuid!]!) {
|
query GET_JOBS($bodyshopids: [uuid!]!) {
|
||||||
@@ -42,7 +42,10 @@ async function RunTheTest() {
|
|||||||
|
|
||||||
const results = [];
|
const results = [];
|
||||||
|
|
||||||
for (const job of jobs) {
|
for (const [index, job] of jobs.entries()) {
|
||||||
|
process.stdout.cursorTo(0);
|
||||||
|
process.stdout.write(`Processing job ${index + 1} of ${jobs.length}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
await axios.post(
|
||||||
`http://localhost:4000/job/totalsssu`,
|
`http://localhost:4000/job/totalsssu`,
|
||||||
@@ -61,6 +64,7 @@ async function RunTheTest() {
|
|||||||
ownr_ln
|
ownr_ln
|
||||||
ownr_co_nm
|
ownr_co_nm
|
||||||
ins_co_nm
|
ins_co_nm
|
||||||
|
comment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@@ -73,19 +77,20 @@ async function RunTheTest() {
|
|||||||
id: newjob.id,
|
id: newjob.id,
|
||||||
owner: `${newjob.ownr_fn} ${newjob.ownr_ln} ${job.ownr_co_nm || ""}`,
|
owner: `${newjob.ownr_fn} ${newjob.ownr_ln} ${job.ownr_co_nm || ""}`,
|
||||||
ins_co: newjob.ins_co_nm,
|
ins_co: newjob.ins_co_nm,
|
||||||
|
comment: newjob.comment,
|
||||||
};
|
};
|
||||||
|
|
||||||
const calcTotal = newjob.job_totals.totals.total_repairs.amount;
|
const calcTotal = newjob.job_totals.totals.total_repairs.amount;
|
||||||
const ttlTotal = newjob.cieca_ttl.data.g_ttl_amt * 100;
|
const ttlTotal = newjob.cieca_ttl.data.g_ttl_amt * 100;
|
||||||
result.difference = (calcTotal - ttlTotal) / 100;
|
result.difference = (calcTotal - ttlTotal) / 100;
|
||||||
|
|
||||||
if (Math.abs(calcTotal - ttlTotal) > 5) {
|
if (Math.abs(calcTotal - ttlTotal) > 3) {
|
||||||
//Diff is greater than 5 cents. Fail it.
|
//Diff is greater than 5 cents. Fail it.
|
||||||
result.result = "***FAIL***";
|
result.result = "***FAIL***";
|
||||||
} else {
|
} else {
|
||||||
result.result = "PASS";
|
result.result = "PASS";
|
||||||
}
|
}
|
||||||
console.log(`${result.result} => RO ${job.ro_number}`);
|
// console.log(`${result.result} => RO ${job.ro_number} - ${job.id} `);
|
||||||
|
|
||||||
results.push(result);
|
results.push(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -97,7 +102,7 @@ async function RunTheTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.table(results);
|
console.table(results.filter((r) => r.result !== "PASS"));
|
||||||
const summary = results.reduce(
|
const summary = results.reduce(
|
||||||
(acc, val) => {
|
(acc, val) => {
|
||||||
if (val.result === "PASS") {
|
if (val.result === "PASS") {
|
||||||
@@ -115,3 +120,15 @@ async function RunTheTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RunTheTest();
|
RunTheTest();
|
||||||
|
|
||||||
|
// mutation {
|
||||||
|
// delete_jobs(where: {shopid: {_eq: "a7ee1503-ee05-4a02-b80e-bdb11d1cc8ac"}}) {
|
||||||
|
// affected_rows
|
||||||
|
// }
|
||||||
|
// delete_owners(where: {shopid: {_eq: "a7ee1503-ee05-4a02-b80e-bdb11d1cc8ac"}}) {
|
||||||
|
// affected_rows
|
||||||
|
// }
|
||||||
|
// delete_vehicles(where: {shopid: {_eq: "a7ee1503-ee05-4a02-b80e-bdb11d1cc8ac"}}) {
|
||||||
|
// affected_rows
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|||||||
@@ -34,15 +34,10 @@ exports.default = function ({
|
|||||||
}
|
}
|
||||||
//Parts Lines Mappings.
|
//Parts Lines Mappings.
|
||||||
if (jobline.profitcenter_part) {
|
if (jobline.profitcenter_part) {
|
||||||
let DineroAmount = Dinero({
|
const discountAmount =
|
||||||
amount: Math.round((jobline.act_price || 0) * 100),
|
|
||||||
}).multiply(jobline.part_qty || 1);
|
|
||||||
|
|
||||||
// console.log("Have a part discount", jobline);
|
|
||||||
DineroAmount = DineroAmount.add(
|
|
||||||
((jobline.prt_dsmk_m && jobline.prt_dsmk_m !== 0) ||
|
((jobline.prt_dsmk_m && jobline.prt_dsmk_m !== 0) ||
|
||||||
(jobline.prt_dsmk_p && jobline.prt_dsmk_p !== 0)) &&
|
(jobline.prt_dsmk_p && jobline.prt_dsmk_p !== 0)) &&
|
||||||
DiscountNotAlreadyCounted(jobline, jobs_by_pk.joblines)
|
DiscountNotAlreadyCounted(jobline, jobs_by_pk.joblines)
|
||||||
? jobline.prt_dsmk_m
|
? jobline.prt_dsmk_m
|
||||||
? Dinero({ amount: Math.round(jobline.prt_dsmk_m * 100) })
|
? Dinero({ amount: Math.round(jobline.prt_dsmk_m * 100) })
|
||||||
: Dinero({
|
: Dinero({
|
||||||
@@ -51,8 +46,13 @@ exports.default = function ({
|
|||||||
.multiply(jobline.part_qty || 0)
|
.multiply(jobline.part_qty || 0)
|
||||||
.percentage(Math.abs(jobline.prt_dsmk_p || 0))
|
.percentage(Math.abs(jobline.prt_dsmk_p || 0))
|
||||||
.multiply(jobline.prt_dsmk_p > 0 ? 1 : -1)
|
.multiply(jobline.prt_dsmk_p > 0 ? 1 : -1)
|
||||||
: Dinero()
|
: Dinero();
|
||||||
);
|
|
||||||
|
let DineroAmount = Dinero({
|
||||||
|
amount: Math.round((jobline.act_price || 0) * 100),
|
||||||
|
})
|
||||||
|
.multiply(jobline.part_qty || 0)
|
||||||
|
.add(discountAmount);
|
||||||
|
|
||||||
const account = responsibilityCenters.profits.find(
|
const account = responsibilityCenters.profits.find(
|
||||||
(i) => jobline.profitcenter_part.toLowerCase() === i.name.toLowerCase()
|
(i) => jobline.profitcenter_part.toLowerCase() === i.name.toLowerCase()
|
||||||
@@ -393,7 +393,7 @@ exports.default = function ({
|
|||||||
|
|
||||||
//Add Towing, storage and adjustment lines.
|
//Add Towing, storage and adjustment lines.
|
||||||
|
|
||||||
if (jobs_by_pk.towing_payable && jobs_by_pk.towing_payable !== 0) {
|
if (jobs_by_pk.job_totals.additional.towing.amount > 0) {
|
||||||
if (qbo) {
|
if (qbo) {
|
||||||
//Going to always assume that we need to apply GST and PST for labor.
|
//Going to always assume that we need to apply GST and PST for labor.
|
||||||
const taxAccountCode = findTaxCode(
|
const taxAccountCode = findTaxCode(
|
||||||
@@ -417,9 +417,9 @@ exports.default = function ({
|
|||||||
: taxCodes[taxAccountCode];
|
: taxCodes[taxAccountCode];
|
||||||
InvoiceLineAdd.push({
|
InvoiceLineAdd.push({
|
||||||
DetailType: "SalesItemLineDetail",
|
DetailType: "SalesItemLineDetail",
|
||||||
Amount: Dinero({
|
Amount: Dinero(jobs_by_pk.job_totals.additional.towing).toFormat(
|
||||||
amount: Math.round((jobs_by_pk.towing_payable || 0) * 100),
|
DineroQbFormat
|
||||||
}).toFormat(DineroQbFormat),
|
),
|
||||||
SalesItemLineDetail: {
|
SalesItemLineDetail: {
|
||||||
...(jobs_by_pk.class
|
...(jobs_by_pk.class
|
||||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||||
@@ -442,9 +442,9 @@ exports.default = function ({
|
|||||||
},
|
},
|
||||||
Desc: "Towing",
|
Desc: "Towing",
|
||||||
Quantity: 1,
|
Quantity: 1,
|
||||||
Amount: Dinero({
|
Amount: Dinero(jobs_by_pk.job_totals.additional.towing).toFormat(
|
||||||
amount: Math.round((jobs_by_pk.towing_payable || 0) * 100),
|
DineroQbFormat
|
||||||
}).toFormat(DineroQbFormat),
|
),
|
||||||
SalesTaxCodeRef: {
|
SalesTaxCodeRef: {
|
||||||
FullName:
|
FullName:
|
||||||
bodyshop.md_responsibility_centers.taxes.itemexemptcode || "NON",
|
bodyshop.md_responsibility_centers.taxes.itemexemptcode || "NON",
|
||||||
@@ -452,7 +452,7 @@ exports.default = function ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (jobs_by_pk.storage_payable && jobs_by_pk.storage_payable !== 0) {
|
if (jobs_by_pk.job_totals.additional.storage.amount > 0) {
|
||||||
if (qbo) {
|
if (qbo) {
|
||||||
//Going to always assume that we need to apply GST and PST for labor.
|
//Going to always assume that we need to apply GST and PST for labor.
|
||||||
const taxAccountCode = findTaxCode(
|
const taxAccountCode = findTaxCode(
|
||||||
@@ -476,9 +476,9 @@ exports.default = function ({
|
|||||||
: taxCodes[taxAccountCode];
|
: taxCodes[taxAccountCode];
|
||||||
InvoiceLineAdd.push({
|
InvoiceLineAdd.push({
|
||||||
DetailType: "SalesItemLineDetail",
|
DetailType: "SalesItemLineDetail",
|
||||||
Amount: Dinero({
|
Amount: Dinero(
|
||||||
amount: Math.round((jobs_by_pk.storage_payable || 0) * 100),
|
jobs_by_pk.job_totals.additional.storage.amount
|
||||||
}).toFormat(DineroQbFormat),
|
).toFormat(DineroQbFormat),
|
||||||
SalesItemLineDetail: {
|
SalesItemLineDetail: {
|
||||||
...(jobs_by_pk.class
|
...(jobs_by_pk.class
|
||||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||||
@@ -501,9 +501,9 @@ exports.default = function ({
|
|||||||
},
|
},
|
||||||
Desc: "Storage",
|
Desc: "Storage",
|
||||||
Quantity: 1,
|
Quantity: 1,
|
||||||
Amount: Dinero({
|
Amount: Dinero(
|
||||||
amount: Math.round((jobs_by_pk.storage_payable || 0) * 100),
|
jobs_by_pk.job_totals.additional.storage.amount
|
||||||
}).toFormat(DineroQbFormat),
|
).toFormat(DineroQbFormat),
|
||||||
SalesTaxCodeRef: {
|
SalesTaxCodeRef: {
|
||||||
FullName:
|
FullName:
|
||||||
bodyshop.md_responsibility_centers.taxes.itemexemptcode || "NON",
|
bodyshop.md_responsibility_centers.taxes.itemexemptcode || "NON",
|
||||||
@@ -574,123 +574,55 @@ 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,
|
console.log(`Tax ${tyCounter}`, taxAmount.toFormat());
|
||||||
Amount: federal_tax.toFormat(DineroQbFormat),
|
if (taxAmount.getAmount() > 0) {
|
||||||
});
|
if (qbo) {
|
||||||
}
|
InvoiceLineAdd.push({
|
||||||
}
|
DetailType: "SalesItemLineDetail",
|
||||||
|
Amount: taxAmount.toFormat(DineroQbFormat),
|
||||||
if (state_tax.getAmount() > 0) {
|
SalesItemLineDetail: {
|
||||||
if (qbo) {
|
...(jobs_by_pk.class
|
||||||
// do qbo
|
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||||
} else {
|
: {}),
|
||||||
InvoiceLineAdd.push({
|
ItemRef: {
|
||||||
ItemRef: {
|
value:
|
||||||
FullName: bodyshop.md_responsibility_centers.taxes.state.accountitem,
|
items[
|
||||||
},
|
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) {
|
});
|
||||||
// do qbo
|
} else {
|
||||||
} else {
|
InvoiceLineAdd.push({
|
||||||
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 +764,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} `);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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`],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1168,10 +1168,8 @@ exports.GET_JOB_BY_PK = `query GET_JOB_BY_PK($id: uuid!) {
|
|||||||
shopid
|
shopid
|
||||||
est_ct_ln
|
est_ct_ln
|
||||||
cieca_pfl
|
cieca_pfl
|
||||||
vehicle{
|
cieca_pft
|
||||||
id
|
cieca_pfo
|
||||||
notes
|
|
||||||
}
|
|
||||||
est_ph1
|
est_ph1
|
||||||
est_ea
|
est_ea
|
||||||
selling_dealer
|
selling_dealer
|
||||||
@@ -1292,19 +1290,6 @@ vehicle{
|
|||||||
prt_dsmk_m
|
prt_dsmk_m
|
||||||
misc_amt
|
misc_amt
|
||||||
misc_tax
|
misc_tax
|
||||||
parts_order_lines {
|
|
||||||
id
|
|
||||||
parts_order {
|
|
||||||
id
|
|
||||||
order_number
|
|
||||||
order_date
|
|
||||||
user_email
|
|
||||||
vendor {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}`;
|
}`;
|
||||||
|
|||||||
@@ -972,6 +972,8 @@ const getAdditionalCostCenter = (jl, profitCenters) => {
|
|||||||
return profitCenters["ATS"];
|
return profitCenters["ATS"];
|
||||||
} else if (lineDesc.includes("towing")) {
|
} else if (lineDesc.includes("towing")) {
|
||||||
return profitCenters["TOW"];
|
return profitCenters["TOW"];
|
||||||
|
} else if (jl.act_price > 0) {
|
||||||
|
ret.profitcenter_part = defaults.profits["PAO"];
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
const Dinero = require("dinero.js");
|
const Dinero = require("dinero.js");
|
||||||
const queries = require("../graphql-client/queries");
|
const queries = require("../graphql-client/queries");
|
||||||
const GraphQLClient = require("graphql-request").GraphQLClient;
|
const GraphQLClient = require("graphql-request").GraphQLClient;
|
||||||
|
const adminClient = require("../graphql-client/graphql-client").client;
|
||||||
|
const _ = require("lodash");
|
||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
// Dinero.defaultCurrency = "USD";
|
// Dinero.defaultCurrency = "USD";
|
||||||
// Dinero.globalLocale = "en-CA";
|
// Dinero.globalLocale = "en-CA";
|
||||||
@@ -59,9 +61,9 @@ async function TotalsServerSide(req, res) {
|
|||||||
try {
|
try {
|
||||||
let ret = {
|
let ret = {
|
||||||
rates: await CalculateRatesTotals({ job, client }),
|
rates: await CalculateRatesTotals({ job, client }),
|
||||||
parts: CalculatePartsTotals(job.joblines, job.parts_tax_rates),
|
parts: CalculatePartsTotals(job.joblines, job.parts_tax_rates, job),
|
||||||
additional: CalculateAdditional(job),
|
|
||||||
};
|
};
|
||||||
|
ret.additional = CalculateAdditional(job);
|
||||||
ret.totals = CalculateTaxesTotals(job, ret);
|
ret.totals = CalculateTaxesTotals(job, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -93,9 +95,9 @@ async function Totals(req, res) {
|
|||||||
try {
|
try {
|
||||||
let ret = {
|
let ret = {
|
||||||
rates: await CalculateRatesTotals({ job, client }),
|
rates: await CalculateRatesTotals({ job, client }),
|
||||||
parts: CalculatePartsTotals(job.joblines, job.parts_tax_rates),
|
parts: CalculatePartsTotals(job.joblines, job.parts_tax_rates, job),
|
||||||
additional: CalculateAdditional(job),
|
|
||||||
};
|
};
|
||||||
|
ret.additional = CalculateAdditional(job);
|
||||||
ret.totals = CalculateTaxesTotals(job, ret);
|
ret.totals = CalculateTaxesTotals(job, ret);
|
||||||
|
|
||||||
res.status(200).json(ret);
|
res.status(200).json(ret);
|
||||||
@@ -259,8 +261,9 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
let hasMapaLine = false;
|
let hasMapaLine = false;
|
||||||
let hasMashLine = false;
|
let hasMashLine = false;
|
||||||
let hasMahwLine = false;
|
let hasMahwLine = false;
|
||||||
let mapaOpCodes = ParseCalopCode(job.materials["mapa"]?.cal_opcode);
|
let hasCustomMahwLine;
|
||||||
let mashOpCodes = ParseCalopCode(job.materials["mash"]?.cal_opcode);
|
let mapaOpCodes = ParseCalopCode(job.materials["MAPA"]?.cal_opcode);
|
||||||
|
let mashOpCodes = ParseCalopCode(job.materials["MASH"]?.cal_opcode);
|
||||||
|
|
||||||
jobLines.forEach((item) => {
|
jobLines.forEach((item) => {
|
||||||
//IO-1317 Use the lines on the estimate if they exist instead.
|
//IO-1317 Use the lines on the estimate if they exist instead.
|
||||||
@@ -277,9 +280,21 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
amount: Math.round((item.act_price || 0) * 100),
|
amount: Math.round((item.act_price || 0) * 100),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (item.line_desc?.toLowerCase().includes("hazardous waste")) {
|
//We might add a hazardous waste line. So we'll need to make sure we only pick up the CCC one.
|
||||||
|
if (
|
||||||
|
item.line_desc?.toLowerCase().includes("hazardous waste") &&
|
||||||
|
!item.manual_line &&
|
||||||
|
item.part_type === null &&
|
||||||
|
item.lbr_op !== "OP16" //Seems to be that it is OP16 for sublet lines.
|
||||||
|
) {
|
||||||
hasMahwLine = item;
|
hasMahwLine = item;
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
item.line_desc?.toLowerCase().includes("hazardous waste") &&
|
||||||
|
item.manual_line
|
||||||
|
) {
|
||||||
|
hasCustomMahwLine = item;
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
||||||
@@ -337,16 +352,18 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
}
|
}
|
||||||
let threshold;
|
let threshold;
|
||||||
//Check if there is a max for this type.
|
//Check if there is a max for this type.
|
||||||
if (job.materials && job.materials[property]) {
|
if (job.materials && job.materials[property.toUpperCase()]) {
|
||||||
//
|
//
|
||||||
|
|
||||||
if (
|
if (
|
||||||
job.materials[property].cal_maxdlr !== undefined &&
|
job.materials[property.toUpperCase()].cal_maxdlr !== undefined &&
|
||||||
job.materials[property].cal_maxdlr >= 0
|
job.materials[property.toUpperCase()].cal_maxdlr >= 0
|
||||||
) {
|
) {
|
||||||
//It has an upper threshhold.
|
//It has an upper threshhold.
|
||||||
threshold = Dinero({
|
threshold = Dinero({
|
||||||
amount: Math.round(job.materials[property].cal_maxdlr * 100),
|
amount: Math.round(
|
||||||
|
job.materials[property.toUpperCase()].cal_maxdlr * 100
|
||||||
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,29 +392,51 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
stlMahw.ttl_amt !== 0 &&
|
stlMahw.ttl_amt !== 0 &&
|
||||||
(!hasMahwLine || hasMahwLine.act_price !== stlMahw.ttl_amt)
|
(!hasMahwLine || hasMahwLine.act_price !== stlMahw.ttl_amt)
|
||||||
) {
|
) {
|
||||||
|
//The Mahw line that has been added doesn't match with what we have in the STL. Add/update the adjusting line so that the balance is correct.
|
||||||
|
|
||||||
//Add a hazardous waste material line in case there isn't one on the estimate.
|
//Add a hazardous waste material line in case there isn't one on the estimate.
|
||||||
const newMahwLine = {
|
let newPrice = stlMahw.ttl_amt;
|
||||||
line_desc: "Hazardous Waste Removal*",
|
if (hasCustomMahwLine) {
|
||||||
part_type: "PAS",
|
//Update it
|
||||||
oem_partno: null,
|
job.joblines.forEach((jl) => {
|
||||||
db_price: 0,
|
if (jl.id === hasCustomMahwLine.id) {
|
||||||
act_price: stlMahw.ttl_amt,
|
jl.act_price = newPrice;
|
||||||
part_qty: 1,
|
jl.manual_line = true;
|
||||||
//mod_lbr_ty: "LAB",
|
jl.tax_part = stlMahw.tax_amt > 0 ? true : false;
|
||||||
db_hrs: 0,
|
}
|
||||||
mod_lb_hrs: 0,
|
});
|
||||||
lbr_op: "OP11",
|
await client.request(queries.UPDATE_JOB_LINE, {
|
||||||
lbr_amt: 0,
|
lineId: hasCustomMahwLine.id,
|
||||||
op_code_desc: "REMOVE / REPLACE",
|
line: {
|
||||||
tax_part: hasMahwLine.tax_amt > 0 ? true : false,
|
act_price: newPrice,
|
||||||
db_ref: null,
|
manual_line: true,
|
||||||
manual_line: true,
|
tax_part: stlMahw.tax_amt > 0 ? true : false,
|
||||||
jobid: job.id,
|
},
|
||||||
};
|
});
|
||||||
job.joblines.push(newMahwLine);
|
} else {
|
||||||
await client.request(queries.INSERT_NEW_JOB_LINE, {
|
const newMahwLine = {
|
||||||
lineInput: [newMahwLine],
|
line_desc: "Hazardous Waste Removal*",
|
||||||
});
|
part_type: null,
|
||||||
|
oem_partno: null,
|
||||||
|
db_price: 0,
|
||||||
|
act_price: newPrice,
|
||||||
|
part_qty: 1,
|
||||||
|
mod_lbr_ty: "LAB",
|
||||||
|
db_hrs: 0,
|
||||||
|
mod_lb_hrs: 0,
|
||||||
|
lbr_op: "OP0",
|
||||||
|
lbr_amt: 0,
|
||||||
|
op_code_desc: "REMOVE / REPLACE",
|
||||||
|
tax_part: stlMahw.tax_amt > 0 ? true : false,
|
||||||
|
db_ref: null,
|
||||||
|
manual_line: true,
|
||||||
|
jobid: job.id,
|
||||||
|
};
|
||||||
|
job.joblines.push(newMahwLine);
|
||||||
|
await client.request(queries.INSERT_NEW_JOB_LINE, {
|
||||||
|
lineInput: [newMahwLine],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Materials Scrubbing as required by CCC.
|
//Materials Scrubbing as required by CCC.
|
||||||
@@ -427,57 +466,8 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function CalculatePartsTotals(jobLines, parts_tax_rates) {
|
function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
|
||||||
const jl = jobLines.filter((jl) => !jl.removed);
|
const jl = jobLines.filter((jl) => !jl.removed);
|
||||||
// jl.forEach((line) => {
|
|
||||||
// //Some profile based estimates don't automatically add the discount to the line, some do.
|
|
||||||
// //Clean up the ones that don't to add it in.
|
|
||||||
|
|
||||||
// //Apply a discount to the line if there is a profile discount, but it isn't added to the line itself.
|
|
||||||
// const partTax = parts_tax_rates[line.part_type];
|
|
||||||
// if (
|
|
||||||
// line.act_price > 0 &&
|
|
||||||
// partTax &&
|
|
||||||
// partTax.prt_discp &&
|
|
||||||
// partTax.prt_discp > 0
|
|
||||||
// ) {
|
|
||||||
// //apply a discount
|
|
||||||
// const discount = Dinero({
|
|
||||||
// amount: Math.round(line.act_price * 100),
|
|
||||||
// }).percentage(
|
|
||||||
// Math.abs(partTax.prt_discp) > 1
|
|
||||||
// ? partTax.prt_discp
|
|
||||||
// : partTax.prt_discp * 100
|
|
||||||
// );
|
|
||||||
// line.prt_dsmk_m = discount.toFormat("0.0");
|
|
||||||
// line.prt_dsmk_p = partTax.prt_discp;
|
|
||||||
// line.act_price = Dinero({
|
|
||||||
// amount: Math.round(line.act_price * 100),
|
|
||||||
// })
|
|
||||||
// .subtract(discount)
|
|
||||||
// .toFormat("0.0");
|
|
||||||
// } else if (
|
|
||||||
// line.act_price > 0 &&
|
|
||||||
// partTax &&
|
|
||||||
// partTax.prt_mkupp &&
|
|
||||||
// partTax.prt_mkupp > 0
|
|
||||||
// ) {
|
|
||||||
// //apply a mark up
|
|
||||||
// const markup = Dinero({
|
|
||||||
// amount: Math.round(line.act_price * 100),
|
|
||||||
// }).percentage(
|
|
||||||
// Math.abs(partTax.prt_mkupp) > 1
|
|
||||||
// ? partTax.prt_mkupp
|
|
||||||
// : partTax.prt_mkupp * 100
|
|
||||||
// );
|
|
||||||
// line.prt_dsmk_m = markup.toFormat("0.0");
|
|
||||||
// line.prt_dsmk_p = partTax.prt_mkupp;
|
|
||||||
// line.act_price = Dinero({ amount: Math.round(line.act_price * 100) })
|
|
||||||
// .add(markup)
|
|
||||||
// .toFormat("0.0");
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
const ret = jl.reduce(
|
const ret = jl.reduce(
|
||||||
(acc, value) => {
|
(acc, value) => {
|
||||||
switch (value.part_type) {
|
switch (value.part_type) {
|
||||||
@@ -517,24 +507,25 @@ function CalculatePartsTotals(jobLines, parts_tax_rates) {
|
|||||||
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: {
|
||||||
@@ -543,20 +534,24 @@ function CalculatePartsTotals(jobLines, parts_tax_rates) {
|
|||||||
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),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -613,23 +608,27 @@ function CalculatePartsTotals(jobLines, parts_tax_rates) {
|
|||||||
PAS: Dinero(),
|
PAS: Dinero(),
|
||||||
PAT: Dinero(),
|
PAT: Dinero(),
|
||||||
};
|
};
|
||||||
|
//Track all adjustments that need to be made.
|
||||||
|
|
||||||
|
const linesToAdjustForDiscount = [];
|
||||||
Object.keys(parts_tax_rates).forEach((key) => {
|
Object.keys(parts_tax_rates).forEach((key) => {
|
||||||
//Check if there's a discount or a mark up.
|
//Check if there's a discount or a mark up.
|
||||||
let disc = Dinero(),
|
let disc = Dinero(),
|
||||||
markup = Dinero();
|
markup = Dinero();
|
||||||
|
|
||||||
|
let discountRate, markupRate;
|
||||||
if (
|
if (
|
||||||
parts_tax_rates[key].prt_discp !== undefined &&
|
parts_tax_rates[key].prt_discp !== undefined &&
|
||||||
parts_tax_rates[key].prt_discp >= 0
|
parts_tax_rates[key].prt_discp >= 0
|
||||||
) {
|
) {
|
||||||
//Check if there's any parts in this part type.
|
//Check if there's any parts in this part type.
|
||||||
if (ret.parts.list[key] !== undefined) {
|
if (ret.parts.list[key] !== undefined) {
|
||||||
disc = ret.parts.list[key].total
|
discountRate =
|
||||||
.percentage(
|
Math.abs(parts_tax_rates[key].prt_discp) > 1
|
||||||
Math.abs(parts_tax_rates[key].prt_discp) > 1
|
? parts_tax_rates[key].prt_discp
|
||||||
? parts_tax_rates[key].prt_discp
|
: parts_tax_rates[key].prt_discp * 100;
|
||||||
: parts_tax_rates[key].prt_discp * 100
|
|
||||||
)
|
disc = ret.parts.list[key].total.percentage(discountRate).multiply(-1);
|
||||||
.multiply(-1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@@ -638,26 +637,70 @@ function CalculatePartsTotals(jobLines, parts_tax_rates) {
|
|||||||
) {
|
) {
|
||||||
//Check if there's any parts in this part type.
|
//Check if there's any parts in this part type.
|
||||||
if (ret.parts.list[key] !== undefined) {
|
if (ret.parts.list[key] !== undefined) {
|
||||||
markup = ret.parts.list[key].total.percentage(
|
markupRate =
|
||||||
Math.abs(parts_tax_rates[key].prt_mkupp) > 1
|
Math.abs(parts_tax_rates[key].prt_mkupp) > 1
|
||||||
? parts_tax_rates[key].prt_mkupp
|
? parts_tax_rates[key].prt_mkupp
|
||||||
: parts_tax_rates[key].prt_mkupp * 100 //Seems that mark up is written as decimal not %.
|
: parts_tax_rates[key].prt_mkupp * 100; //Seems that mark up is written as decimal not %.
|
||||||
);
|
|
||||||
|
markup = ret.parts.list[key].total.percentage(markupRate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let adjustment = disc.add(markup);
|
let adjustment = disc.add(markup);
|
||||||
adjustments[key] = adjustment;
|
adjustments[key] = adjustment;
|
||||||
|
|
||||||
|
const correspondingCiecaStlTotalLine = job.cieca_stl?.data.find(
|
||||||
|
(c) => c.ttl_typecd === key
|
||||||
|
);
|
||||||
|
|
||||||
|
//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 (
|
||||||
|
correspondingCiecaStlTotalLine &&
|
||||||
|
Math.abs(
|
||||||
|
ret.parts.list[key]?.total.getAmount() -
|
||||||
|
correspondingCiecaStlTotalLine.ttl_amt * 100
|
||||||
|
) > 1
|
||||||
|
) {
|
||||||
|
// Update the total.
|
||||||
|
console.log(
|
||||||
|
key,
|
||||||
|
ret.parts.list[key]?.total.getAmount(),
|
||||||
|
correspondingCiecaStlTotalLine?.ttl_amt
|
||||||
|
);
|
||||||
|
//Find the corresponding lines. Update the discount/markup for them.
|
||||||
|
|
||||||
|
console.warn("There's a difference! Type: ", key);
|
||||||
|
let totalDiscountToAdjustBy = Dinero();
|
||||||
|
job.joblines.forEach((jobline) => {
|
||||||
|
//Modify the line in place to add the mark up/discount.
|
||||||
|
if (jobline.part_type === key) {
|
||||||
|
const discountAmountDinero = Dinero({
|
||||||
|
amount: Math.round(jobline.act_price * 100),
|
||||||
|
}).percentage(discountRate);
|
||||||
|
|
||||||
|
const discountAmount = parseFloat(
|
||||||
|
discountAmountDinero.toFormat("0.00")
|
||||||
|
);
|
||||||
|
totalDiscountToAdjustBy =
|
||||||
|
totalDiscountToAdjustBy.add(discountAmountDinero);
|
||||||
|
jobline.prt_dsmk_m = discountAmount * -1;
|
||||||
|
jobline.prt_dsmk_p = discountRate * -1;
|
||||||
|
|
||||||
|
linesToAdjustForDiscount.push(jobline);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// ret.parts.list[key].total = ret.parts.list[key]?.total.subtract(
|
||||||
|
// totalDiscountToAdjustBy
|
||||||
|
// );
|
||||||
|
ret.parts.prt_dsmk_total = ret.parts.prt_dsmk_total.subtract(
|
||||||
|
totalDiscountToAdjustBy
|
||||||
|
);
|
||||||
|
ret.parts.subtotal = ret.parts.subtotal.subtract(totalDiscountToAdjustBy);
|
||||||
|
ret.parts.total = ret.parts.total.subtract(totalDiscountToAdjustBy);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Temporarily commenting this out since these totals appear to be already included in the calculation.
|
UpdateJobLines(linesToAdjustForDiscount.filter((l) => l.prt_dsmk_m !== 0));
|
||||||
// Object.keys(adjustments).forEach((key) => {
|
|
||||||
// if (ret.parts.list[key] !== undefined) {
|
|
||||||
// ret.parts.list[key].total = ret.parts.list[key].total.add(
|
|
||||||
// adjustments[key]
|
|
||||||
// );
|
|
||||||
// ret.parts.subtotal = ret.parts.subtotal.add(adjustments[key]);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
adjustments,
|
adjustments,
|
||||||
@@ -691,6 +734,9 @@ function IsAdditionalCost(jobLine) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function CalculateAdditional(job) {
|
function CalculateAdditional(job) {
|
||||||
|
const stlTowing = job.cieca_stl?.data.find((c) => c.ttl_type === "OTTW");
|
||||||
|
const stlStorage = job.cieca_stl?.data.find((c) => c.ttl_type === "OTST");
|
||||||
|
|
||||||
let ret = {
|
let ret = {
|
||||||
additionalCosts: null,
|
additionalCosts: null,
|
||||||
additionalCostItems: [],
|
additionalCostItems: [],
|
||||||
@@ -701,9 +747,11 @@ function CalculateAdditional(job) {
|
|||||||
pvrt: null,
|
pvrt: null,
|
||||||
total: null,
|
total: null,
|
||||||
};
|
};
|
||||||
ret.towing = Dinero({
|
ret.towing = stlTowing
|
||||||
amount: Math.round((job.towing_payable || 0) * 100),
|
? Dinero({ amount: Math.round(stlTowing.ttl_amt * 100) })
|
||||||
});
|
: Dinero({
|
||||||
|
amount: Math.round((job.towing_payable || 0) * 100),
|
||||||
|
});
|
||||||
|
|
||||||
ret.additionalCosts = job.joblines
|
ret.additionalCosts = job.joblines
|
||||||
.filter((jl) => !jl.removed && IsAdditionalCost(jl))
|
.filter((jl) => !jl.removed && IsAdditionalCost(jl))
|
||||||
@@ -728,9 +776,11 @@ function CalculateAdditional(job) {
|
|||||||
ret.adjustments = Dinero({
|
ret.adjustments = Dinero({
|
||||||
amount: Math.round((job.adjustment_bottom_line || 0) * 100),
|
amount: Math.round((job.adjustment_bottom_line || 0) * 100),
|
||||||
});
|
});
|
||||||
ret.storage = Dinero({
|
ret.storage = stlStorage
|
||||||
amount: Math.round((job.storage_payable || 0) * 100),
|
? Dinero({ amount: Math.round(stlStorage.ttl_amt * 100) })
|
||||||
});
|
: Dinero({
|
||||||
|
amount: Math.round((job.storage_payable || 0) * 100),
|
||||||
|
});
|
||||||
ret.pvrt = Dinero({
|
ret.pvrt = Dinero({
|
||||||
amount: Math.round((job.ca_bc_pvrt || 0) * 100),
|
amount: Math.round((job.ca_bc_pvrt || 0) * 100),
|
||||||
});
|
});
|
||||||
@@ -738,7 +788,6 @@ function CalculateAdditional(job) {
|
|||||||
.add(ret.adjustments) //IO-813 Adjustment takes care of GST & PST at labor rate.
|
.add(ret.adjustments) //IO-813 Adjustment takes care of GST & PST at labor rate.
|
||||||
.add(ret.towing)
|
.add(ret.towing)
|
||||||
.add(ret.storage);
|
.add(ret.storage);
|
||||||
//.add(ret.pvrt);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -749,14 +798,12 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
.add(otherTotals.rates.subtotal) //No longer using just rates subtotal to include mapa/mash.
|
.add(otherTotals.rates.subtotal) //No longer using just rates subtotal to include mapa/mash.
|
||||||
.add(otherTotals.additional.total);
|
.add(otherTotals.additional.total);
|
||||||
|
|
||||||
// .add(Dinero({ amount: (job.towing_payable || 0) * 100 }))
|
|
||||||
// .add(Dinero({ amount: (job.storage_payable || 0) * 100 }));
|
|
||||||
|
|
||||||
//Potential issue here with Sublet Calculation. Sublets are calculated under labor in Mitchell, but it's done in IO
|
//Potential issue here with Sublet Calculation. Sublets are calculated under labor in Mitchell, but it's done in IO
|
||||||
//Under the parts rates.
|
//Under the parts rates.
|
||||||
|
|
||||||
let statePartsTax = Dinero();
|
let statePartsTax = Dinero();
|
||||||
let additionalItemsTax = Dinero();
|
let additionalItemsTax = Dinero();
|
||||||
|
let us_sales_tax_breakdown;
|
||||||
|
|
||||||
//Audatex sends additional glass part types. IO-774
|
//Audatex sends additional glass part types. IO-774
|
||||||
const BackupGlassTax =
|
const BackupGlassTax =
|
||||||
@@ -767,92 +814,334 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
job.parts_tax_rates.PAGQ ||
|
job.parts_tax_rates.PAGQ ||
|
||||||
job.parts_tax_rates.PAGR);
|
job.parts_tax_rates.PAGR);
|
||||||
|
|
||||||
job.joblines
|
const taxableAmounts = {
|
||||||
.filter((jl) => !jl.removed)
|
PAA: Dinero(),
|
||||||
.forEach((val) => {
|
PAN: Dinero(),
|
||||||
if (!val.tax_part) return;
|
PAL: Dinero(),
|
||||||
if (!val.part_type && IsAdditionalCost(val)) {
|
PAR: Dinero(),
|
||||||
additionalItemsTax = additionalItemsTax.add(
|
PAC: Dinero(),
|
||||||
Dinero({ amount: Math.round((val.act_price || 0) * 100) })
|
PAG: Dinero(),
|
||||||
.multiply(val.part_qty || 0)
|
PAO: Dinero(),
|
||||||
.percentage(
|
PAS: Dinero(),
|
||||||
((job.parts_tax_rates &&
|
PAP: Dinero(),
|
||||||
job.parts_tax_rates["PAN"] &&
|
PAM: Dinero(),
|
||||||
job.parts_tax_rates["PAN"].prt_tax_rt) ||
|
|
||||||
0) * 100
|
LA1: Dinero(),
|
||||||
|
LA2: Dinero(),
|
||||||
|
LA3: Dinero(),
|
||||||
|
LA4: Dinero(),
|
||||||
|
LAU: Dinero(),
|
||||||
|
LAA: Dinero(),
|
||||||
|
LAB: Dinero(),
|
||||||
|
LAD: Dinero(),
|
||||||
|
LAE: Dinero(),
|
||||||
|
LAF: Dinero(),
|
||||||
|
LAG: Dinero(),
|
||||||
|
LAM: Dinero(),
|
||||||
|
LAR: Dinero(),
|
||||||
|
LAS: Dinero(),
|
||||||
|
|
||||||
|
MAPA: Dinero(),
|
||||||
|
MASH: Dinero(),
|
||||||
|
TOW: Dinero(),
|
||||||
|
STOR: 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 {
|
} else if (!val.part_type) {
|
||||||
statePartsTax = statePartsTax.add(
|
//Do nothing for now.
|
||||||
Dinero({ amount: Math.round((val.act_price || 0) * 100) })
|
} else {
|
||||||
.multiply(val.part_qty || 0)
|
const typeOfPart = val.part_type;
|
||||||
.add(
|
taxableAmounts[typeOfPart] = taxableAmounts[typeOfPart].add(
|
||||||
val.prt_dsmk_m &&
|
Dinero({ amount: Math.round((val.act_price || 0) * 100) })
|
||||||
val.prt_dsmk_m !== 0 &&
|
.multiply(val.part_qty || 0)
|
||||||
DiscountNotAlreadyCounted(val, job.joblines)
|
.add(
|
||||||
? val.prt_dsmk_m
|
val.prt_dsmk_m &&
|
||||||
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
val.prt_dsmk_m !== 0 &&
|
||||||
: Dinero({
|
DiscountNotAlreadyCounted(val, job.joblines) // DO WE NEED TO COUNT PFP DISCOUNT HERE?
|
||||||
amount: Math.round(val.act_price * 100),
|
? val.prt_dsmk_m
|
||||||
})
|
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
||||||
.multiply(val.part_qty || 0)
|
: Dinero({
|
||||||
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
amount: Math.round(val.act_price * 100),
|
||||||
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
})
|
||||||
: Dinero()
|
.multiply(val.part_qty || 0)
|
||||||
)
|
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
||||||
.percentage(
|
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
||||||
((job.parts_tax_rates &&
|
: Dinero()
|
||||||
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) ||
|
//Check in the PFL file which types of labor are taxable. Add the amount that is considered taxable to the taxable amounts total.
|
||||||
(!val.part_type &&
|
Object.keys(taxableAmounts)
|
||||||
val.db_ref === "900510" &&
|
.filter((key) => key.startsWith("LA"))
|
||||||
job.parts_tax_rates["PAN"] &&
|
.map((key) => {
|
||||||
job.parts_tax_rates["PAN"].prt_tax_rt) ||
|
const isLaborTypeTaxable = job.cieca_pfl[key]?.lbr_tax_in;
|
||||||
0) * 100
|
if (isLaborTypeTaxable) {
|
||||||
)
|
taxableAmounts[key] = taxableAmounts[key].add(
|
||||||
);
|
otherTotals.rates[key.toLowerCase()].total
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//Add towing and storage taxable amounts
|
||||||
|
const stlTowing = job.cieca_stl?.data.find((c) => c.ttl_typecd === "OTTW");
|
||||||
|
const stlStorage = job.cieca_stl?.data.find((c) => c.ttl_typecd === "OTST");
|
||||||
|
|
||||||
|
if (stlTowing)
|
||||||
|
taxableAmounts.TOW = Dinero({
|
||||||
|
amount: Math.round(stlTowing.t_amt * 100),
|
||||||
|
});
|
||||||
|
if (stlStorage)
|
||||||
|
taxableAmounts.TOW = Dinero({
|
||||||
|
amount: Math.round(stlStorage.t_amt * 100),
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log("*** Taxable Amounts***");
|
||||||
|
// console.table(JSON.parse(JSON.stringify(taxableAmounts)));
|
||||||
|
|
||||||
|
//For the taxable amounts, figure out which tax type applies.
|
||||||
|
//Then sum up the total of that tax type and then calculate the thresholds.
|
||||||
|
|
||||||
|
const taxableAmountsByTier = {
|
||||||
|
ty1Tax: Dinero(),
|
||||||
|
ty2Tax: Dinero(),
|
||||||
|
ty3Tax: Dinero(),
|
||||||
|
ty4Tax: Dinero(),
|
||||||
|
ty5Tax: Dinero(),
|
||||||
|
ty6Tax: Dinero(),
|
||||||
|
};
|
||||||
|
const totalTaxByTier = {
|
||||||
|
ty1Tax: Dinero(),
|
||||||
|
ty2Tax: Dinero(),
|
||||||
|
ty3Tax: Dinero(),
|
||||||
|
ty4Tax: Dinero(),
|
||||||
|
ty5Tax: Dinero(),
|
||||||
|
ty6Tax: Dinero(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const pfp = job.parts_tax_rates;
|
||||||
|
const pfl = job.cieca_pfl;
|
||||||
|
const pfm = job.materials;
|
||||||
|
const pfo = job.cieca_pfo;
|
||||||
|
Object.keys(taxableAmounts).map((key) => {
|
||||||
|
try {
|
||||||
|
if (key.startsWith("PA")) {
|
||||||
|
const typeOfPart = key; // === "PAM" ? "PAC" : key;
|
||||||
|
//At least one of these scenarios must be taxable.
|
||||||
|
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
|
||||||
|
if (IsTrueOrYes(pfp[typeOfPart][`prt_tx_in${tyCounter}`])) {
|
||||||
|
//This amount is taxable for this type.
|
||||||
|
taxableAmountsByTier[`ty${tyCounter}Tax`] = taxableAmountsByTier[
|
||||||
|
`ty${tyCounter}Tax`
|
||||||
|
].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 if (key.startsWith("LA")) {
|
||||||
|
//Labor.
|
||||||
|
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
|
||||||
|
if (IsTrueOrYes(pfl[key][`lbr_tx_in${tyCounter}`])) {
|
||||||
|
//This amount is taxable for this type.
|
||||||
|
taxableAmountsByTier[`ty${tyCounter}Tax`] = taxableAmountsByTier[
|
||||||
|
`ty${tyCounter}Tax`
|
||||||
|
].add(taxableAmounts[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (key === "TOW") {
|
||||||
|
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
|
||||||
|
if (IsTrueOrYes(pfo[`tow_t_in${tyCounter}`])) {
|
||||||
|
//This amount is taxable for this type.
|
||||||
|
taxableAmountsByTier[`ty${tyCounter}Tax`] = taxableAmountsByTier[
|
||||||
|
`ty${tyCounter}Tax`
|
||||||
|
].add(taxableAmounts[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (key === "STOR") {
|
||||||
|
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
|
||||||
|
if (IsTrueOrYes(pfo[`stor_t_in${tyCounter}`])) {
|
||||||
|
//This amount is taxable for this type.
|
||||||
|
taxableAmountsByTier[`ty${tyCounter}Tax`] = taxableAmountsByTier[
|
||||||
|
`ty${tyCounter}Tax`
|
||||||
|
].add(taxableAmounts[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Key with issue", key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const remainingTaxableAmounts = taxableAmountsByTier;
|
||||||
|
// console.log("*** Taxable Amounts by Tier***");
|
||||||
|
// console.table(JSON.parse(JSON.stringify(taxableAmountsByTier)));
|
||||||
|
|
||||||
|
Object.keys(taxableAmountsByTier).forEach((taxTierKey) => {
|
||||||
|
try {
|
||||||
|
let tyCounter = taxTierKey[2]; //Get the number from the key.
|
||||||
|
//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[taxTierKey];
|
||||||
|
remainingTaxableAmounts[taxTierKey] = Dinero();
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
thresholdAmount >=
|
||||||
|
remainingTaxableAmounts[taxTierKey].getAmount() / 100
|
||||||
|
) {
|
||||||
|
//This threshold is bigger than the remaining taxable balance. Add it all.
|
||||||
|
taxableAmountInThisThreshold =
|
||||||
|
remainingTaxableAmounts[taxTierKey];
|
||||||
|
remainingTaxableAmounts[taxTierKey] = 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[taxTierKey] = remainingTaxableAmounts[
|
||||||
|
taxTierKey
|
||||||
|
].subtract(
|
||||||
|
Dinero({
|
||||||
|
amount: Math.round(taxableAmountInThisThreshold * 100),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const taxAmountToAdd =
|
||||||
|
taxableAmountInThisThreshold.percentage(thresholdTaxRate);
|
||||||
|
|
||||||
|
totalTaxByTier[taxTierKey] =
|
||||||
|
totalTaxByTier[taxTierKey].add(taxAmountToAdd);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("PFP Calculation error", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log("*** Total Tax by Tier Amounts***");
|
||||||
|
// console.table(JSON.parse(JSON.stringify(totalTaxByTier)));
|
||||||
|
|
||||||
|
statePartsTax = statePartsTax
|
||||||
|
.add(totalTaxByTier.ty1Tax)
|
||||||
|
.add(totalTaxByTier.ty2Tax)
|
||||||
|
.add(totalTaxByTier.ty3Tax)
|
||||||
|
.add(totalTaxByTier.ty4Tax)
|
||||||
|
.add(totalTaxByTier.ty5Tax)
|
||||||
|
.add(totalTaxByTier.ty6Tax);
|
||||||
|
us_sales_tax_breakdown = totalTaxByTier;
|
||||||
|
//console.log("Tiered Taxes Total for Parts/Labor", 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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let laborTaxTotal = Dinero();
|
let laborTaxTotal = Dinero();
|
||||||
|
|
||||||
if (Object.keys(job.cieca_pfl).length > 0) {
|
if (Object.keys(job.cieca_pfl).length > 0) {
|
||||||
//Do it by labor type
|
//Ignore it now, we have calculated it above.
|
||||||
const types = [
|
//This was previously used for JCS before parts were also calculated at a different rate.
|
||||||
"la1",
|
|
||||||
"la2",
|
|
||||||
"la3",
|
|
||||||
"la4",
|
|
||||||
"lau",
|
|
||||||
"laa",
|
|
||||||
"lab",
|
|
||||||
"lad",
|
|
||||||
"lae",
|
|
||||||
"laf",
|
|
||||||
"lag",
|
|
||||||
"lam",
|
|
||||||
"lar",
|
|
||||||
"las",
|
|
||||||
];
|
|
||||||
types.forEach((type) => {
|
|
||||||
laborTaxTotal = laborTaxTotal.add(
|
|
||||||
otherTotals.rates[type].total.percentage(
|
|
||||||
job.cieca_pfl[type.toUpperCase()]
|
|
||||||
? job.cieca_pfl[type.toUpperCase()].lbr_taxp
|
|
||||||
: (job.tax_lbr_rt || 0) * 100
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
//We don't have it, just add in how it was before.
|
//We don't have it, just add in how it was before.
|
||||||
laborTaxTotal = otherTotals.rates.subtotal.percentage(
|
laborTaxTotal = otherTotals.rates.subtotal.percentage(
|
||||||
(job.tax_lbr_rt || 0) * 100
|
(job.tax_lbr_rt || 0) * 100
|
||||||
); // THis is currently using the lbr tax rate from PFH not PFL.
|
); // THis is currently using the lbr tax rate from PFH not PFL.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//console.log("Labor Tax Total", laborTaxTotal.toFormat());
|
||||||
|
|
||||||
let ret = {
|
let ret = {
|
||||||
subtotal: subtotal,
|
subtotal: subtotal,
|
||||||
federal_tax: subtotal
|
federal_tax: subtotal
|
||||||
@@ -863,35 +1152,8 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
statePartsTax,
|
statePartsTax,
|
||||||
state_tax: statePartsTax
|
us_sales_tax_breakdown,
|
||||||
.add(laborTaxTotal)
|
state_tax: statePartsTax,
|
||||||
.add(
|
|
||||||
otherTotals.additional.adjustments.percentage(
|
|
||||||
(job.tax_lbr_rt || 0) * 100
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.add(
|
|
||||||
otherTotals.additional.towing.percentage((job.tax_tow_rt || 0) * 100)
|
|
||||||
)
|
|
||||||
.add(
|
|
||||||
otherTotals.additional.storage.percentage((job.tax_str_rt || 0) * 100)
|
|
||||||
)
|
|
||||||
.add(additionalItemsTax)
|
|
||||||
.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
|
||||||
@@ -928,6 +1190,7 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
exports.default = Totals;
|
exports.default = Totals;
|
||||||
|
|
||||||
function DiscountNotAlreadyCounted(jobline, joblines) {
|
function DiscountNotAlreadyCounted(jobline, joblines) {
|
||||||
|
return false;
|
||||||
//CCC already factors in the discount. If the difference between the 2 is exactly the discount, it's all good.
|
//CCC already factors in the discount. If the difference between the 2 is exactly the discount, it's all good.
|
||||||
if (
|
if (
|
||||||
Math.round(
|
Math.round(
|
||||||
@@ -937,11 +1200,9 @@ function DiscountNotAlreadyCounted(jobline, joblines) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check it against the database price too? If it's an OE part.
|
|
||||||
if (
|
if (
|
||||||
Math.abs(jobline.db_price - jobline.act_price) -
|
jobline.db_price !== jobline.act_price &&
|
||||||
Math.abs(jobline.prt_dsmk_m) <
|
jobline.db_price - jobline.act_price - Math.abs(jobline.prt_dsmk_m) < 0.02
|
||||||
0.01
|
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -964,3 +1225,35 @@ function ParseCalopCode(opcode) {
|
|||||||
if (!opcode) return [];
|
if (!opcode) return [];
|
||||||
return opcode.trim().split(" ");
|
return opcode.trim().split(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function IsTrueOrYes(value) {
|
||||||
|
return value === true || value === "Y" || value === "y";
|
||||||
|
}
|
||||||
|
|
||||||
|
async function UpdateJobLines(joblinesToUpdate) {
|
||||||
|
if (joblinesToUpdate.length === 0) return;
|
||||||
|
const updateQueries = joblinesToUpdate.map((line, index) =>
|
||||||
|
generateUpdateQuery(_.pick(line, ["id", "prt_dsmk_m", "prt_dsmk_p"]), index)
|
||||||
|
);
|
||||||
|
const query = `
|
||||||
|
mutation UPDATE_EST_LINES{
|
||||||
|
${updateQueries}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const result = await adminClient.request(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
const generateUpdateQuery = (lineToUpdate, index) => {
|
||||||
|
return `
|
||||||
|
update_joblines${index}: update_joblines(where: { id: { _eq: "${
|
||||||
|
lineToUpdate.id
|
||||||
|
}" } }, _set: ${JSON.stringify(lineToUpdate).replace(
|
||||||
|
/"(\w+)"\s*:/g,
|
||||||
|
"$1:"
|
||||||
|
)}) {
|
||||||
|
returning {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
var { admin } = require("./server/firebase/firebase-handler");
|
var { admin } = require("./server/firebase/firebase-handler");
|
||||||
|
|
||||||
const uidToMakeAdmin = "yTvpfkcNnGckLd1JnoXC7bTdvtu1";
|
const uidToMakeAdmin = "fIaZcVQQfUR12Fu14I2fyA5vXbp1";
|
||||||
|
|
||||||
admin
|
admin
|
||||||
.auth()
|
.auth()
|
||||||
|
|||||||
Reference in New Issue
Block a user