Compare commits
1 Commits
feature/IO
...
feature/IO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7132465945 |
@@ -33,7 +33,7 @@ import JobLinesBillRefernece from "../job-lines-bill-reference/job-lines-bill-re
|
||||
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
|
||||
import _ from "lodash";
|
||||
import { FaTasks } from "react-icons/fa";
|
||||
import { selectAuthLevel, selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import dayjs from "../../utils/day";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import { HasFeatureAccess } from "../feature-wrapper/feature-wrapper.component";
|
||||
@@ -49,7 +49,6 @@ import JobLinesPartPriceChange from "./job-lines-part-price-change.component";
|
||||
import JobLinesExpanderSimple from "./jobs-lines-expander-simple.component";
|
||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
||||
import { HasRbacAccess } from "../rbac-wrapper/rbac-wrapper.component.jsx";
|
||||
|
||||
const UPDATE_JOB_LINES_LOCATION_BULK = gql`
|
||||
mutation UPDATE_JOB_LINES_LOCATION_BULK($ids: [uuid!]!, $location: String!) {
|
||||
@@ -67,8 +66,7 @@ const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
jobRO: selectJobReadOnly,
|
||||
technician: selectTechnician,
|
||||
isPartsEntry: selectIsPartsEntry,
|
||||
authLevel: selectAuthLevel
|
||||
isPartsEntry: selectIsPartsEntry
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
@@ -96,8 +94,7 @@ export function JobLinesComponent({
|
||||
setTaskUpsertContext,
|
||||
billsQuery,
|
||||
handlePartsOrderOnRowClick,
|
||||
isPartsEntry,
|
||||
authLevel
|
||||
isPartsEntry
|
||||
}) {
|
||||
const [deleteJobLine] = useMutation(DELETE_JOB_LINE_BY_PK);
|
||||
const [bulkUpdateLocations] = useMutation(UPDATE_JOB_LINES_LOCATION_BULK);
|
||||
@@ -389,20 +386,18 @@ export function JobLinesComponent({
|
||||
key: "actions",
|
||||
render: (text, record) => (
|
||||
<Space>
|
||||
{(record.manual_line || jobIsPrivate) &&
|
||||
!technician &&
|
||||
HasRbacAccess({ bodyshop, authLevel, action: "jobs:manual-line" }) && (
|
||||
<Button
|
||||
disabled={jobRO}
|
||||
onClick={() => {
|
||||
setJobLineEditContext({
|
||||
actions: { refetch: refetch, submit: form && form.submit },
|
||||
context: { ...record, jobid: job.id }
|
||||
});
|
||||
}}
|
||||
icon={<EditFilled />}
|
||||
/>
|
||||
)}
|
||||
{(record.manual_line || jobIsPrivate) && !technician && (
|
||||
<Button
|
||||
disabled={jobRO}
|
||||
onClick={() => {
|
||||
setJobLineEditContext({
|
||||
actions: { refetch: refetch, submit: form && form.submit },
|
||||
context: { ...record, jobid: job.id }
|
||||
});
|
||||
}}
|
||||
icon={<EditFilled />}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
title={t("tasks.buttons.create")}
|
||||
onClick={() => {
|
||||
@@ -415,30 +410,29 @@ export function JobLinesComponent({
|
||||
}}
|
||||
icon={<FaTasks />}
|
||||
/>
|
||||
{(record.manual_line || jobIsPrivate) &&
|
||||
!technician &&
|
||||
HasRbacAccess({ bodyshop, authLevel, action: "jobs:manual-line" }) && (
|
||||
<Button
|
||||
disabled={jobRO}
|
||||
onClick={async () => {
|
||||
await deleteJobLine({
|
||||
variables: { joblineId: record.id },
|
||||
update(cache) {
|
||||
cache.modify({
|
||||
fields: {
|
||||
joblines(existingJobLines, { readField }) {
|
||||
return existingJobLines.filter((jlRef) => record.id !== readField("id", jlRef));
|
||||
}
|
||||
|
||||
{(record.manual_line || jobIsPrivate) && !technician && (
|
||||
<Button
|
||||
disabled={jobRO}
|
||||
onClick={async () => {
|
||||
await deleteJobLine({
|
||||
variables: { joblineId: record.id },
|
||||
update(cache) {
|
||||
cache.modify({
|
||||
fields: {
|
||||
joblines(existingJobLines, { readField }) {
|
||||
return existingJobLines.filter((jlRef) => record.id !== readField("id", jlRef));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
await axios.post("/job/totalsssu", { id: job.id });
|
||||
if (refetch) refetch();
|
||||
}}
|
||||
icon={<DeleteFilled />}
|
||||
/>
|
||||
)}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
await axios.post("/job/totalsssu", { id: job.id });
|
||||
if (refetch) refetch();
|
||||
}}
|
||||
icon={<DeleteFilled />}
|
||||
/>
|
||||
)}
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
@@ -663,7 +657,7 @@ export function JobLinesComponent({
|
||||
<Button id="repair-data-mark-button">{t("jobs.actions.mark")}</Button>
|
||||
</Dropdown>
|
||||
|
||||
{!isPartsEntry && HasRbacAccess({ bodyshop, authLevel, action: "jobs:manual-line" }) && (
|
||||
{!isPartsEntry && (
|
||||
<Button
|
||||
disabled={jobRO || technician}
|
||||
onClick={() => {
|
||||
|
||||
@@ -144,18 +144,11 @@ export default function JobTotalsTableLabor({ job }) {
|
||||
{t("jobs.labels.mapa")}
|
||||
{InstanceRenderManager({
|
||||
imex:
|
||||
job.materials?.mapa &&
|
||||
job.materials.mapa.cal_maxdlr &&
|
||||
job.materials.mapa.cal_maxdlr > 0 &&
|
||||
t("jobs.labels.threshhold", {
|
||||
amount: job.materials.mapa.cal_maxdlr
|
||||
}),
|
||||
(job.materials?.mapa ?? job.materials?.MAPA)?.cal_maxdlr > 0 &&
|
||||
t("jobs.labels.threshhold", { amount: (job.materials.mapa ?? job.materials.MAPA).cal_maxdlr }),
|
||||
rome:
|
||||
job.materials?.MAPA &&
|
||||
job.materials.MAPA.cal_maxdlr !== undefined &&
|
||||
t("jobs.labels.threshhold", {
|
||||
amount: job.materials.MAPA.cal_maxdlr
|
||||
})
|
||||
job.materials?.MAPA?.cal_maxdlr !== undefined &&
|
||||
t("jobs.labels.threshhold", { amount: job.materials.MAPA.cal_maxdlr })
|
||||
})}
|
||||
</Space>
|
||||
</ResponsiveTable.Summary.Cell>
|
||||
@@ -190,18 +183,11 @@ export default function JobTotalsTableLabor({ job }) {
|
||||
{t("jobs.labels.mash")}
|
||||
{InstanceRenderManager({
|
||||
imex:
|
||||
job.materials?.mash &&
|
||||
job.materials.mash.cal_maxdlr &&
|
||||
job.materials.mash.cal_maxdlr > 0 &&
|
||||
t("jobs.labels.threshhold", {
|
||||
amount: job.materials.mash.cal_maxdlr
|
||||
}),
|
||||
(job.materials?.mash ?? job.materials?.MASH)?.cal_maxdlr > 0 &&
|
||||
t("jobs.labels.threshhold", { amount: (job.materials.mash ?? job.materials.MASH).cal_maxdlr }),
|
||||
rome:
|
||||
job.materials?.MASH &&
|
||||
job.materials.MASH.cal_maxdlr !== undefined &&
|
||||
t("jobs.labels.threshhold", {
|
||||
amount: job.materials.MASH.cal_maxdlr
|
||||
})
|
||||
job.materials?.MASH?.cal_maxdlr !== undefined &&
|
||||
t("jobs.labels.threshhold", { amount: job.materials.MASH.cal_maxdlr })
|
||||
})}
|
||||
</Space>
|
||||
</ResponsiveTable.Summary.Cell>
|
||||
|
||||
@@ -26,7 +26,6 @@ const ret = {
|
||||
"jobs:partsqueue": 4,
|
||||
"jobs:checklist-view": 2,
|
||||
"jobs:list-ready": 1,
|
||||
"jobs:manual-line": 1,
|
||||
"jobs:void": 5,
|
||||
|
||||
"bills:enter": 2,
|
||||
|
||||
@@ -435,19 +435,6 @@ export function ShopInfoRbacComponent({ bodyshop }) {
|
||||
>
|
||||
<InputNumber />
|
||||
</Form.Item>,
|
||||
<Form.Item
|
||||
key="jobs:manual-line"
|
||||
label={t("bodyshop.fields.rbac.jobs.manual-line")}
|
||||
rules={[
|
||||
{
|
||||
required: true
|
||||
//message: t("general.validation.required"),
|
||||
}
|
||||
]}
|
||||
name={["md_rbac", "jobs:manual-line"]}
|
||||
>
|
||||
<InputNumber />
|
||||
</Form.Item>,
|
||||
<Form.Item
|
||||
key="jobs:partsqueue"
|
||||
label={t("bodyshop.fields.rbac.jobs.partsqueue")}
|
||||
|
||||
@@ -519,7 +519,6 @@
|
||||
"list-active": "Jobs -> List Active",
|
||||
"list-all": "Jobs -> List All",
|
||||
"list-ready": "Jobs -> List Ready",
|
||||
"manual-line": "Jobs -> Manual Line",
|
||||
"partsqueue": "Jobs -> Parts Queue",
|
||||
"void": "Jobs -> Void"
|
||||
},
|
||||
|
||||
@@ -519,7 +519,6 @@
|
||||
"list-active": "",
|
||||
"list-all": "",
|
||||
"list-ready": "",
|
||||
"manual-line": "",
|
||||
"partsqueue": "",
|
||||
"void": ""
|
||||
},
|
||||
|
||||
@@ -519,7 +519,6 @@
|
||||
"list-active": "",
|
||||
"list-all": "",
|
||||
"list-ready": "",
|
||||
"manual-line": "",
|
||||
"partsqueue": "",
|
||||
"void": ""
|
||||
},
|
||||
|
||||
@@ -315,7 +315,12 @@ function CalculateRatesTotals(ratesList) {
|
||||
if (item.mod_lbr_ty) {
|
||||
//Check to see if it has 0 hours and a price instead.
|
||||
//Extend for when there are hours and a price.
|
||||
if (item.lbr_op === "OP14" && item.act_price > 0 && (!item.part_type || item.mod_lb_hrs === 0) && !IsAdditionalCost(item)) {
|
||||
if (
|
||||
item.lbr_op === "OP14" &&
|
||||
item.act_price > 0 &&
|
||||
(!item.part_type || item.mod_lb_hrs === 0) &&
|
||||
!IsAdditionalCost(item)
|
||||
) {
|
||||
//Scenario where SGI may pay out hours using a part price.
|
||||
if (!ret[item.mod_lbr_ty.toLowerCase()].total) {
|
||||
ret[item.mod_lbr_ty.toLowerCase()].total = Dinero();
|
||||
@@ -339,38 +344,30 @@ function CalculateRatesTotals(ratesList) {
|
||||
let subtotal = Dinero({ amount: 0 });
|
||||
let rates_subtotal = Dinero({ amount: 0 });
|
||||
|
||||
for (const property in ret) {
|
||||
for (const [property, values] of Object.entries(ret)) {
|
||||
//Skip calculating mapa and mash if we got the amounts.
|
||||
if (!((property === "mapa" && hasMapaLine) || (property === "mash" && hasMashLine))) {
|
||||
if (!ret[property].total) {
|
||||
ret[property].total = Dinero();
|
||||
}
|
||||
let threshold;
|
||||
//Check if there is a max for this type.
|
||||
if (ratesList.materials && ratesList.materials[property]) {
|
||||
//
|
||||
if (ratesList.materials[property].cal_maxdlr && ratesList.materials[property].cal_maxdlr > 0) {
|
||||
//It has an upper threshhold.
|
||||
threshold = Dinero({
|
||||
amount: Math.round(ratesList.materials[property].cal_maxdlr * 100)
|
||||
});
|
||||
}
|
||||
}
|
||||
const shouldSkipCalculation = (property === "mapa" && hasMapaLine) || (property === "mash" && hasMashLine);
|
||||
|
||||
if (!shouldSkipCalculation) {
|
||||
values.total ??= Dinero();
|
||||
|
||||
//Check if there is a max for this type and apply it.
|
||||
const maxDollar =
|
||||
ratesList.materials?.[property]?.cal_maxdlr || ratesList.materials?.[property.toUpperCase()]?.cal_maxdlr;
|
||||
const threshold = maxDollar > 0 ? Dinero({ amount: Math.round(maxDollar * 100) }) : null;
|
||||
|
||||
const total = Dinero({
|
||||
amount: Math.round((ret[property].rate || 0) * 100)
|
||||
}).multiply(ret[property].hours);
|
||||
amount: Math.round((values.rate || 0) * 100)
|
||||
}).multiply(values.hours);
|
||||
|
||||
if (threshold && total.greaterThanOrEqual(threshold)) {
|
||||
ret[property].total = ret[property].total.add(threshold);
|
||||
} else {
|
||||
ret[property].total = ret[property].total.add(total);
|
||||
}
|
||||
values.total = values.total.add(threshold && total.greaterThanOrEqual(threshold) ? threshold : total);
|
||||
}
|
||||
|
||||
subtotal = subtotal.add(ret[property].total);
|
||||
subtotal = subtotal.add(values.total);
|
||||
|
||||
if (property !== "mapa" && property !== "mash") rates_subtotal = rates_subtotal.add(ret[property].total);
|
||||
if (property !== "mapa" && property !== "mash") {
|
||||
rates_subtotal = rates_subtotal.add(values.total);
|
||||
}
|
||||
}
|
||||
|
||||
ret.subtotal = subtotal;
|
||||
|
||||
Reference in New Issue
Block a user