Fixed up job details lines table + jobs totals page.
This commit is contained in:
@@ -10775,6 +10775,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>dedinfo</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>inscoinfo</name>
|
<name>inscoinfo</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -10796,6 +10817,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>laborrates</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>lossinfo</name>
|
<name>lossinfo</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -11588,6 +11630,48 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>mapa</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>mash</name>
|
||||||
|
<definition_loaded>false</definition_loaded>
|
||||||
|
<description></description>
|
||||||
|
<comment></comment>
|
||||||
|
<default_text></default_text>
|
||||||
|
<translations>
|
||||||
|
<translation>
|
||||||
|
<language>en-US</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>es-MX</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
<translation>
|
||||||
|
<language>fr-CA</language>
|
||||||
|
<approved>false</approved>
|
||||||
|
</translation>
|
||||||
|
</translations>
|
||||||
|
</concept_node>
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>net_repairs</name>
|
<name>net_repairs</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -11651,27 +11735,6 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
<concept_node>
|
|
||||||
<name>paint_mat</name>
|
|
||||||
<definition_loaded>false</definition_loaded>
|
|
||||||
<description></description>
|
|
||||||
<comment></comment>
|
|
||||||
<default_text></default_text>
|
|
||||||
<translations>
|
|
||||||
<translation>
|
|
||||||
<language>en-US</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>es-MX</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>fr-CA</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
</translations>
|
|
||||||
</concept_node>
|
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>parts</name>
|
<name>parts</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -11819,27 +11882,6 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
<concept_node>
|
|
||||||
<name>shop_mat</name>
|
|
||||||
<definition_loaded>false</definition_loaded>
|
|
||||||
<description></description>
|
|
||||||
<comment></comment>
|
|
||||||
<default_text></default_text>
|
|
||||||
<translations>
|
|
||||||
<translation>
|
|
||||||
<language>en-US</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>es-MX</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
<translation>
|
|
||||||
<language>fr-CA</language>
|
|
||||||
<approved>false</approved>
|
|
||||||
</translation>
|
|
||||||
</translations>
|
|
||||||
</concept_node>
|
|
||||||
<concept_node>
|
<concept_node>
|
||||||
<name>state_tax_amt</name>
|
<name>state_tax_amt</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { checkUserSession } from "../redux/user/user.actions";
|
|||||||
import { selectCurrentUser } from "../redux/user/user.selectors";
|
import { selectCurrentUser } from "../redux/user/user.selectors";
|
||||||
import PrivateRoute from "../utils/private-route";
|
import PrivateRoute from "../utils/private-route";
|
||||||
import "antd/dist/antd.css";
|
import "antd/dist/antd.css";
|
||||||
|
import "./App.styles.scss";
|
||||||
|
|
||||||
const LandingPage = lazy(() => import("../pages/landing/landing.page"));
|
const LandingPage = lazy(() => import("../pages/landing/landing.page"));
|
||||||
const ManagePage = lazy(() => import("../pages/manage/manage.page.container"));
|
const ManagePage = lazy(() => import("../pages/manage/manage.page.container"));
|
||||||
|
|||||||
10
client/src/App/App.styles.scss
Normal file
10
client/src/App/App.styles.scss
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
//Global Styles.
|
||||||
|
|
||||||
|
.imex-table-header {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
&__search {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,10 +4,11 @@ import { MdRemoveCircleOutline } from "react-icons/md";
|
|||||||
|
|
||||||
export default function AllocationsLabelComponent({ allocation, handleClick }) {
|
export default function AllocationsLabelComponent({ allocation, handleClick }) {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex", alignItems: "center" }}>
|
||||||
<span>
|
<span>
|
||||||
{`${allocation.employee.first_name || ""} ${allocation.employee
|
{`${allocation.employee.first_name || ""} ${
|
||||||
.last_name || ""} (${allocation.hours || ""})`}
|
allocation.employee.last_name || ""
|
||||||
|
} (${allocation.hours || ""})`}
|
||||||
</span>
|
</span>
|
||||||
<Icon
|
<Icon
|
||||||
style={{ color: "red", padding: "0px 4px" }}
|
style={{ color: "red", padding: "0px 4px" }}
|
||||||
|
|||||||
@@ -8,19 +8,21 @@ import { useTranslation } from "react-i18next";
|
|||||||
export default function AllocationsLabelContainer({ allocation, refetch }) {
|
export default function AllocationsLabelContainer({ allocation, refetch }) {
|
||||||
const [deleteAllocation] = useMutation(DELETE_ALLOCATION);
|
const [deleteAllocation] = useMutation(DELETE_ALLOCATION);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const handleClick = e => {
|
|
||||||
|
const handleClick = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
deleteAllocation({ variables: { id: allocation.id } })
|
deleteAllocation({ variables: { id: allocation.id } })
|
||||||
.then(r => {
|
.then((r) => {
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("allocations.successes.deleted")
|
message: t("allocations.successes.deleted"),
|
||||||
});
|
});
|
||||||
if (refetch) refetch();
|
if (refetch) refetch();
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
notification["error"]({ message: t("allocations.errors.deleting") });
|
notification["error"]({ message: t("allocations.errors.deleting") });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AllocationsLabelComponent
|
<AllocationsLabelComponent
|
||||||
allocation={allocation}
|
allocation={allocation}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ class FcmNotificationComponent extends Component {
|
|||||||
.requestPermission()
|
.requestPermission()
|
||||||
.then(async function () {
|
.then(async function () {
|
||||||
const token = await messaging.getToken();
|
const token = await messaging.getToken();
|
||||||
console.log("Instance Token", token);
|
|
||||||
client.mutate({
|
client.mutate({
|
||||||
mutation: UPDATE_FCM_TOKEN,
|
mutation: UPDATE_FCM_TOKEN,
|
||||||
variables: { authEmail: currentUser.email, token: { [token]: true } },
|
variables: { authEmail: currentUser.email, token: { [token]: true } },
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ function FormItemCurrency(props, ref) {
|
|||||||
return (
|
return (
|
||||||
<InputNumber
|
<InputNumber
|
||||||
{...props}
|
{...props}
|
||||||
//formatter={value => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
|
style={{ width: "initial" }}
|
||||||
// parser={value => value.replace(/\$\s?|(,*)/g, "")}
|
formatter={(value) => `$ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
|
||||||
|
parser={(value) => value.replace(/\$\s?|(,*)/g, "")}
|
||||||
precision={2}
|
precision={2}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ import AllocationsAssignmentContainer from "../allocations-assignment/allocation
|
|||||||
import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container";
|
import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container";
|
||||||
import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
|
import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
|
||||||
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
|
import PartsOrderModalContainer from "../parts-order-modal/parts-order-modal.container";
|
||||||
|
import { onlyUnique } from "../../utils/arrayHelper";
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
setJobLineEditContext: (context) =>
|
||||||
|
dispatch(setModalContext({ context: context, modal: "jobLineEdit" })),
|
||||||
setPartsOrderContext: (context) =>
|
setPartsOrderContext: (context) =>
|
||||||
dispatch(setModalContext({ context: context, modal: "partsOrder" })),
|
dispatch(setModalContext({ context: context, modal: "partsOrder" })),
|
||||||
});
|
});
|
||||||
@@ -34,30 +37,20 @@ export function JobLinesComponent({
|
|||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: t("joblines.fields.line_no"),
|
title: "#",
|
||||||
dataIndex: "line_no",
|
dataIndex: "line_no",
|
||||||
key: "line_no",
|
key: "line_no",
|
||||||
// onFilter: (value, record) => record.ro_number.includes(value),
|
|
||||||
// filteredValue: state.filteredInfo.text || null,
|
|
||||||
sorter: (a, b) => a.line_no - b.line_no,
|
sorter: (a, b) => a.line_no - b.line_no,
|
||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "line_no" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "line_no" && state.sortedInfo.order,
|
||||||
//ellipsis: true,
|
|
||||||
editable: true,
|
|
||||||
width: 75,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("joblines.fields.unq_seq"),
|
title: t("joblines.fields.line_ind"),
|
||||||
dataIndex: "unq_seq",
|
dataIndex: "line_ind",
|
||||||
key: "unq_seq",
|
key: "line_ind",
|
||||||
// onFilter: (value, record) => record.ro_number.includes(value),
|
sorter: (a, b) => alphaSort(a.line_ind, b.line_ind),
|
||||||
// filteredValue: state.filteredInfo.text || null,
|
|
||||||
sorter: (a, b) => a.unq_seq - b.unq_seq,
|
|
||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "unq_seq" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "line_ind" && state.sortedInfo.order,
|
||||||
//ellipsis: true,
|
|
||||||
editable: true,
|
|
||||||
width: 75,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("joblines.fields.line_desc"),
|
title: t("joblines.fields.line_desc"),
|
||||||
@@ -67,7 +60,6 @@ export function JobLinesComponent({
|
|||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "line_desc" && state.sortedInfo.order,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
editable: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("joblines.fields.oem_partno"),
|
title: t("joblines.fields.oem_partno"),
|
||||||
@@ -81,8 +73,6 @@ export function JobLinesComponent({
|
|||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "oem_partno" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "oem_partno" && state.sortedInfo.order,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
editable: true,
|
|
||||||
|
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<span>
|
<span>
|
||||||
{record.oem_partno ? record.oem_partno : record.op_code_desc}
|
{record.oem_partno ? record.oem_partno : record.op_code_desc}
|
||||||
@@ -99,24 +89,28 @@ export function JobLinesComponent({
|
|||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
text: t("jobs.labels.partsfilter"),
|
text: t("jobs.labels.partsfilter"),
|
||||||
value: "parts",
|
value: ["PAN", "PAL", "PAA", "PAS", "PASL"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "PAN",
|
||||||
|
value: ["PAN"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "PAL",
|
||||||
|
value: ["PAL"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "PAA",
|
||||||
|
value: ["PAA"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "PAS/PASL",
|
||||||
|
value: ["PAS", "PASL"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
// specify the condition of filtering result
|
onFilter: (value, record) => value.includes(record.part_type),
|
||||||
// here is that finding the name started with `value`
|
|
||||||
onFilter: (value, record) =>
|
|
||||||
["PAN", "PAL", "PAA", "PAS", "PASL"].includes(record.part_type),
|
|
||||||
ellipsis: true,
|
|
||||||
editable: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: t("joblines.fields.line_ind"),
|
|
||||||
dataIndex: "line_ind",
|
|
||||||
key: "line_ind",
|
|
||||||
sorter: (a, b) => alphaSort(a.line_ind, b.line_ind),
|
|
||||||
sortOrder:
|
|
||||||
state.sortedInfo.columnKey === "line_ind" && state.sortedInfo.order,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: t("joblines.fields.act_price"),
|
title: t("joblines.fields.act_price"),
|
||||||
dataIndex: "act_price",
|
dataIndex: "act_price",
|
||||||
@@ -125,7 +119,6 @@ export function JobLinesComponent({
|
|||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "act_price" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "act_price" && state.sortedInfo.order,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
|
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<CurrencyFormatter>{record.act_price}</CurrencyFormatter>
|
<CurrencyFormatter>{record.act_price}</CurrencyFormatter>
|
||||||
),
|
),
|
||||||
@@ -134,7 +127,6 @@ export function JobLinesComponent({
|
|||||||
title: t("joblines.fields.part_qty"),
|
title: t("joblines.fields.part_qty"),
|
||||||
dataIndex: "part_qty",
|
dataIndex: "part_qty",
|
||||||
key: "part_qty",
|
key: "part_qty",
|
||||||
ellipsis: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("joblines.fields.total"),
|
title: t("joblines.fields.total"),
|
||||||
@@ -144,7 +136,6 @@ export function JobLinesComponent({
|
|||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "total" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "total" && state.sortedInfo.order,
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
|
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<CurrencyFormatter>
|
<CurrencyFormatter>
|
||||||
{record.act_price * record.part_qty}
|
{record.act_price * record.part_qty}
|
||||||
@@ -155,6 +146,7 @@ export function JobLinesComponent({
|
|||||||
title: t("joblines.fields.mod_lb_hrs"),
|
title: t("joblines.fields.mod_lb_hrs"),
|
||||||
dataIndex: "mod_lb_hrs",
|
dataIndex: "mod_lb_hrs",
|
||||||
key: "mod_lb_hrs",
|
key: "mod_lb_hrs",
|
||||||
|
responsive: ["lg"],
|
||||||
sorter: (a, b) => a.mod_lb_hrs - b.mod_lb_hrs,
|
sorter: (a, b) => a.mod_lb_hrs - b.mod_lb_hrs,
|
||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "mod_lb_hrs" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "mod_lb_hrs" && state.sortedInfo.order,
|
||||||
@@ -166,12 +158,24 @@ export function JobLinesComponent({
|
|||||||
sorter: (a, b) => alphaSort(a.status, b.status),
|
sorter: (a, b) => alphaSort(a.status, b.status),
|
||||||
sortOrder:
|
sortOrder:
|
||||||
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
||||||
|
filters:
|
||||||
|
(jobLines &&
|
||||||
|
jobLines
|
||||||
|
.map((l) => l.status)
|
||||||
|
.filter(onlyUnique)
|
||||||
|
.map((s) => {
|
||||||
|
return {
|
||||||
|
text: s || "No Status*",
|
||||||
|
value: [s],
|
||||||
|
};
|
||||||
|
})) ||
|
||||||
|
[],
|
||||||
|
onFilter: (value, record) => value.includes(record.status),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t("allocations.fields.employee"),
|
title: t("allocations.fields.employee"),
|
||||||
dataIndex: "employee",
|
dataIndex: "employee",
|
||||||
key: "employee",
|
key: "employee",
|
||||||
|
|
||||||
sorter: (a, b) =>
|
sorter: (a, b) =>
|
||||||
alphaSort(
|
alphaSort(
|
||||||
a.allocations[0] &&
|
a.allocations[0] &&
|
||||||
@@ -194,12 +198,6 @@ export function JobLinesComponent({
|
|||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
: null}
|
: null}
|
||||||
<AllocationsAssignmentContainer
|
|
||||||
key={record.id}
|
|
||||||
refetch={refetch}
|
|
||||||
jobLineId={record.id}
|
|
||||||
hours={record.mod_lb_hrs}
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -208,7 +206,7 @@ export function JobLinesComponent({
|
|||||||
dataIndex: "actions",
|
dataIndex: "actions",
|
||||||
key: "actions",
|
key: "actions",
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<span>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setJobLineEditContext({
|
setJobLineEditContext({
|
||||||
@@ -218,7 +216,13 @@ export function JobLinesComponent({
|
|||||||
}}>
|
}}>
|
||||||
{t("general.actions.edit")}
|
{t("general.actions.edit")}
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
<AllocationsAssignmentContainer
|
||||||
|
key={record.id}
|
||||||
|
refetch={refetch}
|
||||||
|
jobLineId={record.id}
|
||||||
|
hours={record.mod_lb_hrs}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -243,16 +247,17 @@ export function JobLinesComponent({
|
|||||||
<div>
|
<div>
|
||||||
<PartsOrderModalContainer />
|
<PartsOrderModalContainer />
|
||||||
<Table
|
<Table
|
||||||
|
columns={columns}
|
||||||
|
rowKey='id'
|
||||||
|
loading={loading}
|
||||||
|
size='small'
|
||||||
|
pagination={{ position: "top", defaultPageSize: 50 }}
|
||||||
|
dataSource={jobLines}
|
||||||
|
onChange={handleTableChange}
|
||||||
|
scroll={{ x: true, y: "40rem" }}
|
||||||
title={() => {
|
title={() => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='imex-table-header'>
|
||||||
<Input.Search
|
|
||||||
placeholder={t("general.labels.search")}
|
|
||||||
onChange={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
setSearchText(e.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Button
|
<Button
|
||||||
disabled={selectedLines.length > 0 ? false : true}
|
disabled={selectedLines.length > 0 ? false : true}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -282,11 +287,18 @@ export function JobLinesComponent({
|
|||||||
}}>
|
}}>
|
||||||
{t("joblines.actions.new")}
|
{t("joblines.actions.new")}
|
||||||
</Button>
|
</Button>
|
||||||
|
<div className='imex-table-header__search'>
|
||||||
|
<Input.Search
|
||||||
|
placeholder={t("general.labels.search")}
|
||||||
|
onChange={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setSearchText(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
loading={loading}
|
|
||||||
size='small'
|
|
||||||
expandedRowRender={(record) => (
|
expandedRowRender={(record) => (
|
||||||
<div style={{ margin: 0 }}>
|
<div style={{ margin: 0 }}>
|
||||||
<strong>{t("parts_orders.labels.orderhistory")}</strong>
|
<strong>{t("parts_orders.labels.orderhistory")}</strong>
|
||||||
@@ -301,7 +313,6 @@ export function JobLinesComponent({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
pagination={{ position: "top", defaultPageSize: 25 }}
|
|
||||||
rowSelection={{
|
rowSelection={{
|
||||||
selectedRowKeys: selectedLines.map((item) => item.id),
|
selectedRowKeys: selectedLines.map((item) => item.id),
|
||||||
onSelectAll: (selected, selectedRows, changeRows) => {
|
onSelectAll: (selected, selectedRows, changeRows) => {
|
||||||
@@ -310,10 +321,6 @@ export function JobLinesComponent({
|
|||||||
onSelect: (record, selected, selectedRows, nativeEvent) =>
|
onSelect: (record, selected, selectedRows, nativeEvent) =>
|
||||||
setSelectedLines(selectedRows),
|
setSelectedLines(selectedRows),
|
||||||
}}
|
}}
|
||||||
columns={columns}
|
|
||||||
rowKey='id'
|
|
||||||
dataSource={jobLines}
|
|
||||||
onChange={handleTableChange}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,70 +1,59 @@
|
|||||||
import { useQuery } from "@apollo/react-hooks";
|
import { useQuery } from "@apollo/react-hooks";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { GET_JOB_LINES_BY_PK } from "../../graphql/jobs-lines.queries";
|
import { GET_JOB_LINES_BY_PK } from "../../graphql/jobs-lines.queries";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import JobLinesComponent from "./job-lines.component";
|
import JobLinesComponent from "./job-lines.component";
|
||||||
|
|
||||||
import { connect } from "react-redux";
|
function JobLinesContainer({ jobId }) {
|
||||||
import { setModalContext } from "../../redux/modals/modals.actions";
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
|
||||||
setJobLineEditContext: context =>
|
|
||||||
dispatch(setModalContext({ context: context, modal: "jobLineEdit" }))
|
|
||||||
});
|
|
||||||
|
|
||||||
export function JobLinesContainer({ jobId, setJobLineEditContext }) {
|
|
||||||
const { loading, error, data, refetch } = useQuery(GET_JOB_LINES_BY_PK, {
|
const { loading, error, data, refetch } = useQuery(GET_JOB_LINES_BY_PK, {
|
||||||
variables: { id: jobId },
|
variables: { id: jobId },
|
||||||
fetchPolicy: "network-only"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const [searchText, setSearchText] = useState("");
|
const [searchText, setSearchText] = useState("");
|
||||||
const [selectedLines, setSelectedLines] = useState([]);
|
const [selectedLines, setSelectedLines] = useState([]);
|
||||||
|
|
||||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
if (error) return <AlertComponent message={error.message} type='error' />;
|
||||||
|
|
||||||
|
const jobLines =
|
||||||
|
data && data.joblines
|
||||||
|
? searchText
|
||||||
|
? data.joblines.filter(
|
||||||
|
(jl) =>
|
||||||
|
(jl.unq_seq || "")
|
||||||
|
.toString()
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(jl.line_desc || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(jl.part_type || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(jl.oem_partno || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(jl.op_code_desc || "")
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(jl.db_price || "")
|
||||||
|
.toString()
|
||||||
|
.includes(searchText.toLowerCase()) ||
|
||||||
|
(jl.act_price || "").toString().includes(searchText.toLowerCase())
|
||||||
|
)
|
||||||
|
: data.joblines
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<JobLinesComponent
|
<JobLinesComponent
|
||||||
loading={loading}
|
loading={loading}
|
||||||
refetch={refetch}
|
refetch={refetch}
|
||||||
jobLines={
|
jobLines={jobLines}
|
||||||
data && data.joblines
|
|
||||||
? searchText
|
|
||||||
? data.joblines.filter(
|
|
||||||
jl =>
|
|
||||||
(jl.unq_seq || "")
|
|
||||||
.toString()
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchText.toLowerCase()) ||
|
|
||||||
(jl.line_desc || "")
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchText.toLowerCase()) ||
|
|
||||||
(jl.part_type || "")
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchText.toLowerCase()) ||
|
|
||||||
(jl.oem_partno || "")
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchText.toLowerCase()) ||
|
|
||||||
(jl.op_code_desc || "")
|
|
||||||
.toLowerCase()
|
|
||||||
.includes(searchText.toLowerCase()) ||
|
|
||||||
(jl.db_price || "")
|
|
||||||
.toString()
|
|
||||||
.includes(searchText.toLowerCase()) ||
|
|
||||||
(jl.act_price || "")
|
|
||||||
.toString()
|
|
||||||
.includes(searchText.toLowerCase())
|
|
||||||
)
|
|
||||||
: data.joblines
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
setSearchText={setSearchText}
|
setSearchText={setSearchText}
|
||||||
selectedLines={selectedLines}
|
selectedLines={selectedLines}
|
||||||
setSelectedLines={setSelectedLines}
|
setSelectedLines={setSelectedLines}
|
||||||
jobId={jobId}
|
jobId={jobId}
|
||||||
setJobLineEditContext={setJobLineEditContext}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(JobLinesContainer);
|
export default JobLinesContainer;
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import { createStructuredSelector } from "reselect";
|
|||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||||
import { CalculateJob } from "./job-totals.utility";
|
import { CalculateJob } from "./job-totals.utility";
|
||||||
|
import "./job-totals-table.styles.scss";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
//currentUser: selectCurrentUser
|
//currentUser: selectCurrentUser
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -23,231 +25,186 @@ export function JobsTotalsTableComponent({ bodyshop, job }) {
|
|||||||
console.log("Totals was falsey.");
|
console.log("Totals was falsey.");
|
||||||
return <LoadingSkeleton />;
|
return <LoadingSkeleton />;
|
||||||
}
|
}
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Row>
|
|
||||||
<Descriptions
|
|
||||||
bordered
|
|
||||||
size="small"
|
|
||||||
column={3}
|
|
||||||
title={t("jobs.labels.rates")}
|
|
||||||
>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_laa")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.laa.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.laa.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.laa.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_lab")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.lab.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.lab.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.lab.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_lad")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.lad.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.lad.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.lad.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_lae")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.lae.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.lae.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.lae.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_laf")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.laf.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.laf.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.laf.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_lag")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.lag.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.lag.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.lag.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_lam")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.lam.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.lam.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.lam.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_lar")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.lar.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.lar.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.lar.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_las")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.las.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.las.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.las.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_lau")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.lau.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.lau.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.lau.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_la1")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.la1.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.la1.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.la1.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_la2")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.la2.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.la2.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.la2.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_la3")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.la3.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.la3.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.la3.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_la4")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.la4.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.la4.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.la4.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.fields.rate_atp")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.atp.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.atp.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.atp.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.labels.mapa")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.mapa.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.mapa.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.mapa.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.labels.shop_mat")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.rates.mash.total.toFormat()}
|
|
||||||
precision={2}
|
|
||||||
suffix={`(${totals.rates.mash.hours.toFixed(2)} @ ${
|
|
||||||
totals.rates.mash.rate
|
|
||||||
})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item
|
|
||||||
style={{ color: "red" }}
|
|
||||||
label={t("jobs.labels.rates_subtotal")}
|
|
||||||
>
|
|
||||||
<Statistic value={totals.rates.subtotal.toFormat()} />
|
|
||||||
</Descriptions.Item>
|
|
||||||
</Descriptions>
|
|
||||||
</Row>
|
|
||||||
<Row>
|
|
||||||
<Col span={8}>
|
|
||||||
<Descriptions
|
|
||||||
bordered
|
|
||||||
size="small"
|
|
||||||
column={1}
|
|
||||||
title={t("jobs.labels.partssubletstotal")}
|
|
||||||
>
|
|
||||||
<Descriptions.Item label={t("jobs.labels.partstotal")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.parts.parts.total.toFormat()}
|
|
||||||
suffix={`(${totals.parts.parts.subtotal.toFormat()} ± ${totals.parts.parts.adjustments.toFormat()})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={t("jobs.labels.subletstotal")}>
|
|
||||||
<Statistic
|
|
||||||
value={totals.parts.sublets.total.toFormat()}
|
|
||||||
suffix={`(${totals.parts.sublets.subtotal.toFormat()} ± ${totals.parts.sublets.adjustments.toFormat()})`}
|
|
||||||
/>
|
|
||||||
</Descriptions.Item>
|
|
||||||
</Descriptions>
|
|
||||||
</Col>
|
|
||||||
|
|
||||||
<Col span={8}>
|
return (
|
||||||
<Descriptions
|
<div className='job-totals-container'>
|
||||||
bordered
|
<div className='job-totals-tables'>
|
||||||
size="small"
|
<table className='job-totals-rates-table'>
|
||||||
column={1}
|
<thead>
|
||||||
title={t("jobs.labels.totals")}
|
<tr>
|
||||||
>
|
<th>{t("jobs.labels.rates")}</th>
|
||||||
<Descriptions.Item label={t("jobs.labels.subtotal")}>
|
<th>$</th>
|
||||||
<Statistic value={totals.totals.subtotal.toFormat()} />
|
<th></th>
|
||||||
</Descriptions.Item>
|
</tr>
|
||||||
<Descriptions.Item label={t("jobs.labels.federal_tax_amt")}>
|
</thead>
|
||||||
<Statistic value={totals.totals.federal_tax.toFormat()} />
|
<tbody>
|
||||||
</Descriptions.Item>
|
<tr>
|
||||||
<Descriptions.Item label={t("jobs.labels.state_tax_amt")}>
|
<td>{t("jobs.fields.rate_laa")}</td>
|
||||||
<Statistic value={totals.totals.state_tax.toFormat()} />
|
<td>{totals.rates.laa.total.toFormat()}</td>
|
||||||
</Descriptions.Item>
|
<td>{`(${totals.rates.laa.hours.toFixed(2)} @ ${
|
||||||
<Descriptions.Item label={t("jobs.labels.local_tax_amt")}>
|
totals.rates.laa.rate
|
||||||
<Statistic value={totals.totals.local_tax.toFormat()} />
|
})`}</td>
|
||||||
</Descriptions.Item>
|
</tr>
|
||||||
</Descriptions>
|
<tr>
|
||||||
</Col>
|
<td>{t("jobs.fields.rate_lab")}</td>
|
||||||
<Col span={8}>
|
<td>{totals.rates.lab.total.toFormat()}</td>
|
||||||
<Statistic
|
<td>{`(${totals.rates.lab.hours.toFixed(2)} @ ${
|
||||||
title={t("jobs.labels.total_repairs")}
|
totals.rates.lab.rate
|
||||||
value={totals.totals.total_repairs.toFormat()}
|
})`}</td>
|
||||||
/>
|
</tr>
|
||||||
<Statistic
|
<tr>
|
||||||
title={t("jobs.labels.net_repairs")}
|
<td>{t("jobs.fields.rate_lad")}</td>
|
||||||
value={totals.totals.net_repairs.toFormat()}
|
<td>{totals.rates.lad.total.toFormat()}</td>
|
||||||
/>
|
<td>{`(${totals.rates.lad.hours.toFixed(2)} @ ${
|
||||||
</Col>
|
totals.rates.lad.rate
|
||||||
</Row>
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_lae")}</td>
|
||||||
|
<td>{totals.rates.lae.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.lae.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.lae.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_laf")}</td>
|
||||||
|
<td>{totals.rates.laf.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.laf.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.laf.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_lag")}</td>
|
||||||
|
<td>{totals.rates.lag.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.lag.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.lag.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_lam")}</td>
|
||||||
|
<td>{totals.rates.lam.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.lam.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.lam.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_lar")}</td>
|
||||||
|
<td>{totals.rates.lar.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.lar.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.lar.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_las")}</td>
|
||||||
|
<td>{totals.rates.las.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.las.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.las.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_lau")}</td>
|
||||||
|
<td>{totals.rates.lau.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.lau.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.lau.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_la1")}</td>
|
||||||
|
<td>{totals.rates.la1.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.la1.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.la1.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_la2")}</td>
|
||||||
|
<td>{totals.rates.la2.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.la2.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.la2.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_la3")}</td>
|
||||||
|
<td>{totals.rates.la3.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.la3.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.la3.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_la4")}</td>
|
||||||
|
<td>{totals.rates.la4.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.la4.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.la4.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.fields.rate_atp")}</td>
|
||||||
|
<td>{totals.rates.atp.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.atp.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.atp.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.labels.mapa")}</td>
|
||||||
|
<td>{totals.rates.mapa.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.mapa.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.mapa.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.labels.mash")}</td>
|
||||||
|
<td>{totals.rates.mash.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.rates.mash.hours.toFixed(2)} @ ${
|
||||||
|
totals.rates.mash.rate
|
||||||
|
})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.labels.rates_subtotal")}</td>
|
||||||
|
<td>{totals.rates.subtotal.toFormat()}</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table className='job-totals-parts-table'>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.labels.partstotal")}</td>
|
||||||
|
<td>{totals.parts.parts.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.parts.parts.subtotal.toFormat()} ± ${totals.parts.parts.adjustments.toFormat()})`}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>{t("jobs.labels.subletstotal")}</td>
|
||||||
|
<td>{totals.parts.sublets.total.toFormat()}</td>
|
||||||
|
<td>{`(${totals.parts.sublets.subtotal.toFormat()} ± ${totals.parts.sublets.adjustments.toFormat()})`}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div className='job-totals-stats'>
|
||||||
|
<Statistic
|
||||||
|
title={t("jobs.labels.subtotal")}
|
||||||
|
value={totals.totals.subtotal.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("jobs.labels.state_tax_amt")}
|
||||||
|
value={totals.totals.state_tax.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("jobs.labels.local_tax_amt")}
|
||||||
|
value={totals.totals.local_tax.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("jobs.labels.federal_tax_amt")}
|
||||||
|
value={totals.totals.federal_tax.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("jobs.labels.total_repairs")}
|
||||||
|
value={totals.totals.total_repairs.toFormat()}
|
||||||
|
/>
|
||||||
|
<Statistic
|
||||||
|
title={t("jobs.labels.net_repairs")}
|
||||||
|
value={totals.totals.net_repairs.toFormat()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
.job-totals-container {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: wrap;
|
||||||
|
}
|
||||||
|
.job-totals-tables {
|
||||||
|
flex: 1;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-totals-rates-table,
|
||||||
|
.job-totals-parts-table {
|
||||||
|
border: black;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job-totals-stats {
|
||||||
|
margin: 1rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-content: center;
|
||||||
|
.ant-statistic {
|
||||||
|
margin: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Form, Input, Switch, InputNumber, Typography } from "antd";
|
import { 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 FormRow from "../layout-form-row/layout-form-row.component";
|
import FormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
|||||||
@@ -2,131 +2,128 @@ import { Col, Divider, Form, Input, InputNumber, Row } from "antd";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import JobTotalsTable from "../job-totals-table/job-totals-table.component";
|
import JobTotalsTable from "../job-totals-table/job-totals-table.component";
|
||||||
|
import FormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||||
export default function JobsDetailFinancials({ job }) {
|
export default function JobsDetailFinancials({ job }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row gutter={[32, 32]}>
|
||||||
<Col offset={1} span={7}>
|
<Col span={12}>
|
||||||
<Form.Item label={t("jobs.fields.ded_amt")} name='ded_amt'>
|
<FormRow header={t("jobs.forms.dedinfo")}>
|
||||||
<InputNumber />
|
<Form.Item label={t("jobs.fields.ded_status")} name='ded_status'>
|
||||||
</Form.Item>
|
<Input />
|
||||||
<Form.Item label={t("jobs.fields.ded_status")} name='ded_status'>
|
</Form.Item>
|
||||||
<Input />
|
<Form.Item label={t("jobs.fields.ded_amt")} name='ded_amt'>
|
||||||
</Form.Item>
|
<CurrencyInput />
|
||||||
<Form.Item
|
</Form.Item>
|
||||||
label={t("jobs.fields.depreciation_taxes")}
|
</FormRow>
|
||||||
name='depreciation_taxes'>
|
<FormRow>
|
||||||
<InputNumber />
|
<Form.Item
|
||||||
</Form.Item>
|
label={t("jobs.fields.depreciation_taxes")}
|
||||||
TODO This is equivalent of GST payable.
|
name='depreciation_taxes'>
|
||||||
<Form.Item
|
<CurrencyInput />
|
||||||
label={t("jobs.fields.federal_tax_payable")}
|
</Form.Item>
|
||||||
name='federal_tax_payable'>
|
<Form.Item
|
||||||
<InputNumber />
|
label={t("jobs.fields.other_amount_payable")}
|
||||||
</Form.Item>
|
name='other_amount_payable'>
|
||||||
TODO equivalent of other customer amount
|
<CurrencyInput />
|
||||||
<Form.Item
|
</Form.Item>
|
||||||
label={t("jobs.fields.other_amount_payable")}
|
<Form.Item
|
||||||
name='other_amount_payable'>
|
label={t("jobs.fields.towing_payable")}
|
||||||
<InputNumber />
|
name='towing_payable'>
|
||||||
</Form.Item>
|
<CurrencyInput />
|
||||||
<Form.Item
|
</Form.Item>
|
||||||
label={t("jobs.fields.towing_payable")}
|
<Form.Item
|
||||||
name='towing_payable'>
|
label={t("jobs.fields.storage_payable")}
|
||||||
<InputNumber />
|
name='storage_payable'>
|
||||||
</Form.Item>
|
<CurrencyInput />
|
||||||
<Form.Item
|
</Form.Item>
|
||||||
label={t("jobs.fields.storage_payable")}
|
<Form.Item
|
||||||
name='storage_payable'>
|
label={t("jobs.fields.federal_tax_payable")}
|
||||||
<InputNumber />
|
name='federal_tax_payable'>
|
||||||
</Form.Item>
|
<CurrencyInput />
|
||||||
<Form.Item
|
</Form.Item>
|
||||||
label={t("jobs.fields.adjustment_bottom_line")}
|
<Form.Item
|
||||||
name='adjustment_bottom_line'>
|
label={t("jobs.fields.adjustment_bottom_line")}
|
||||||
<InputNumber />
|
name='adjustment_bottom_line'>
|
||||||
</Form.Item>
|
<CurrencyInput />
|
||||||
<Divider />
|
</Form.Item>
|
||||||
<Form.Item
|
</FormRow>
|
||||||
label={t("jobs.fields.labor_rate_desc")}
|
<FormRow header={t("jobs.forms.laborrates")}>
|
||||||
name='labor_rate_desc'>
|
<Form.Item label={t("jobs.fields.rate_laa")} name='rate_laa'>
|
||||||
<Input />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_lab")} name='rate_lab'>
|
<Form.Item label={t("jobs.fields.rate_lab")} name='rate_lab'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_lad")} name='rate_lad'>
|
<Form.Item label={t("jobs.fields.rate_lad")} name='rate_lad'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_lae")} name='rate_lae'>
|
<Form.Item label={t("jobs.fields.rate_lae")} name='rate_lae'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_lar")} name='rate_lar'>
|
<Form.Item label={t("jobs.fields.rate_lar")} name='rate_lar'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_las")} name='rate_las'>
|
<Form.Item label={t("jobs.fields.rate_las")} name='rate_las'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_laf")} name='rate_laf'>
|
<Form.Item label={t("jobs.fields.rate_laf")} name='rate_laf'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_lam")} name='rate_lam'>
|
<Form.Item label={t("jobs.fields.rate_lam")} name='rate_lam'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("jobs.fields.rate_lag")} name='rate_lag'>
|
<Form.Item label={t("jobs.fields.rate_lag")} name='rate_lag'>
|
||||||
<InputNumber />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
Note //TODO Remove ATP rate?
|
<Form.Item label={t("jobs.fields.rate_la1")} name='rate_la1'>
|
||||||
<Form.Item label={t("jobs.fields.rate_atp")} name='rate_atp'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_la2")} name='rate_la2'>
|
||||||
<Form.Item label={t("jobs.fields.rate_lau")} name='rate_lau'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_la3")} name='rate_la3'>
|
||||||
<Form.Item label={t("jobs.fields.rate_la1")} name='rate_la1'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_la4")} name='rate_la4'>
|
||||||
<Form.Item label={t("jobs.fields.rate_la2")} name='rate_la2'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_atp")} name='rate_atp'>
|
||||||
<Form.Item label={t("jobs.fields.rate_la3")} name='rate_la3'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_lau")} name='rate_lau'>
|
||||||
<Form.Item label={t("jobs.fields.rate_la4")} name='rate_la4'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_mapa")} name='rate_mapa'>
|
||||||
<Form.Item label={t("jobs.fields.rate_mapa")} name='rate_mapa'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_mash")} name='rate_mash'>
|
||||||
<Form.Item label={t("jobs.fields.rate_mash")} name='rate_mash'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_mahw")} name='rate_mahw'>
|
||||||
<Form.Item label={t("jobs.fields.rate_mahw")} name='rate_mahw'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_ma2s")} name='rate_ma2s'>
|
||||||
<Form.Item label={t("jobs.fields.rate_ma2s")} name='rate_ma2s'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_ma3s")} name='rate_ma3s'>
|
||||||
<Form.Item label={t("jobs.fields.rate_ma3s")} name='rate_ma3s'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_mabl")} name='rate_mabl'>
|
||||||
<Form.Item label={t("jobs.fields.rate_mabl")} name='rate_mabl'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_macs")} name='rate_macs'>
|
||||||
<Form.Item label={t("jobs.fields.rate_macs")} name='rate_macs'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label={t("jobs.fields.rate_matd")} name='rate_matd'>
|
||||||
<Form.Item label={t("jobs.fields.rate_matd")} name='rate_matd'>
|
<CurrencyInput />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
</FormRow>
|
||||||
<Form.Item label={t("jobs.fields.rate_laa")} name='rate_laa'>
|
|
||||||
<InputNumber />
|
|
||||||
</Form.Item>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col offset={1} span={15}>
|
<Col span={12}>
|
||||||
<JobTotalsTable job={job} />
|
<JobTotalsTable job={job} />
|
||||||
<p>Mitchell: {JSON.stringify(job.cieca_ttl, null, "\t")}</p>
|
|
||||||
<p>Mine:{JSON.stringify(job.job_totals, null, "\t")}</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { DatePicker, Divider, Form, Input, Typography } from "antd";
|
import { DatePicker, Form, Input } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||||
import FormItemPhone from "../form-items-formatted/phone-form-item.component";
|
import FormItemPhone from "../form-items-formatted/phone-form-item.component";
|
||||||
import FormRow from "../layout-form-row/layout-form-row.component";
|
|
||||||
import Car from "../job-damage-visual/job-damage-visual.component";
|
import Car from "../job-damage-visual/job-damage-visual.component";
|
||||||
|
import FormRow from "../layout-form-row/layout-form-row.component";
|
||||||
|
|
||||||
export default function JobsDetailInsurance({ job, form }) {
|
export default function JobsDetailInsurance({ job, form }) {
|
||||||
const { getFieldValue } = form;
|
const { getFieldValue } = form;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Row, Col, Typography } from "antd";
|
import { Row, Col, Typography } from "antd";
|
||||||
|
import "./layout-form-row.styles.scss";
|
||||||
|
|
||||||
export default function LayoutFormRow({ header, children }) {
|
export default function LayoutFormRow({ header, children }) {
|
||||||
if (!!!children.length) {
|
if (!!!children.length) {
|
||||||
@@ -8,7 +9,6 @@ export default function LayoutFormRow({ header, children }) {
|
|||||||
}
|
}
|
||||||
const rowGutter = { gutter: [32, 32] };
|
const rowGutter = { gutter: [32, 32] };
|
||||||
const colSpan = (maxspan) => {
|
const colSpan = (maxspan) => {
|
||||||
console.log("maxspan", maxspan);
|
|
||||||
return {
|
return {
|
||||||
xs: {
|
xs: {
|
||||||
span: 24,
|
span: 24,
|
||||||
@@ -25,7 +25,7 @@ export default function LayoutFormRow({ header, children }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='imex-form-row'>
|
||||||
{header ? <Typography.Title level={4}>{header}</Typography.Title> : null}
|
{header ? <Typography.Title level={4}>{header}</Typography.Title> : null}
|
||||||
<Row {...rowGutter}>
|
<Row {...rowGutter}>
|
||||||
{children.map((c, idx) => (
|
{children.map((c, idx) => (
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
//Override Antd Row margin to save space on forms.
|
||||||
|
.imex-form-row {
|
||||||
|
.ant-row {
|
||||||
|
margin-bottom: 0rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -364,7 +364,7 @@
|
|||||||
"instanceconflictext": "Your $t(titles.app) account can only be used on one device at any given time. Refresh your session to take control.",
|
"instanceconflictext": "Your $t(titles.app) account can only be used on one device at any given time. Refresh your session to take control.",
|
||||||
"instanceconflictitle": "Your account is being used elsewhere.",
|
"instanceconflictitle": "Your account is being used elsewhere.",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"loadingapp": "Loading Bodyshop.app",
|
"loadingapp": "Loading $t(titles.app)",
|
||||||
"loadingshop": "Loading shop data...",
|
"loadingshop": "Loading shop data...",
|
||||||
"loggingin": "Authorizing...",
|
"loggingin": "Authorizing...",
|
||||||
"na": "N/A",
|
"na": "N/A",
|
||||||
@@ -487,14 +487,14 @@
|
|||||||
"fields": {
|
"fields": {
|
||||||
"act_price": "Actual Price",
|
"act_price": "Actual Price",
|
||||||
"db_price": "Database Price",
|
"db_price": "Database Price",
|
||||||
"line_desc": "Line Description",
|
"line_desc": "Line Desc.",
|
||||||
"line_ind": "S#",
|
"line_ind": "S#",
|
||||||
"line_no": "Line #",
|
"line_no": "Line #",
|
||||||
"mod_lb_hrs": "Labor Hours",
|
"mod_lb_hrs": "Hrs",
|
||||||
"mod_lbr_ty": "Labor Type",
|
"mod_lbr_ty": "Labor Type",
|
||||||
"oem_partno": "OEM Part #",
|
"oem_partno": "OEM Part #",
|
||||||
"op_code_desc": "Operation Code Description",
|
"op_code_desc": "Operation Code Description",
|
||||||
"part_qty": "Quantity",
|
"part_qty": "Qty.",
|
||||||
"part_type": "Part Type",
|
"part_type": "Part Type",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"total": "Total",
|
"total": "Total",
|
||||||
@@ -669,7 +669,9 @@
|
|||||||
"forms": {
|
"forms": {
|
||||||
"appraiserinfo": "Appraiser Info",
|
"appraiserinfo": "Appraiser Info",
|
||||||
"claiminfo": "Claim Information",
|
"claiminfo": "Claim Information",
|
||||||
|
"dedinfo": "Deductible Info",
|
||||||
"inscoinfo": "Insurance Company Information",
|
"inscoinfo": "Insurance Company Information",
|
||||||
|
"laborrates": "Labor Rates",
|
||||||
"lossinfo": "Loss Information"
|
"lossinfo": "Loss Information"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
@@ -713,10 +715,11 @@
|
|||||||
"laborallocations": "Labor Allocations",
|
"laborallocations": "Labor Allocations",
|
||||||
"lines": "Estimate Lines",
|
"lines": "Estimate Lines",
|
||||||
"local_tax_amt": "Local Taxes",
|
"local_tax_amt": "Local Taxes",
|
||||||
|
"mapa": "Paint Materials",
|
||||||
|
"mash": "Shop Materials",
|
||||||
"net_repairs": "Net Repairs",
|
"net_repairs": "Net Repairs",
|
||||||
"notes": "Notes",
|
"notes": "Notes",
|
||||||
"override_header": "Override estimate header on import?",
|
"override_header": "Override estimate header on import?",
|
||||||
"paint_mat": "Paint Materials",
|
|
||||||
"parts": "Parts",
|
"parts": "Parts",
|
||||||
"partsfilter": "Parts Only",
|
"partsfilter": "Parts Only",
|
||||||
"partssubletstotal": "Parts & Sublets Total",
|
"partssubletstotal": "Parts & Sublets Total",
|
||||||
@@ -724,7 +727,6 @@
|
|||||||
"rates": "Rates",
|
"rates": "Rates",
|
||||||
"rates_subtotal": "Rates Subtotal",
|
"rates_subtotal": "Rates Subtotal",
|
||||||
"reconciliationheader": "Parts & Sublet Reconciliation",
|
"reconciliationheader": "Parts & Sublet Reconciliation",
|
||||||
"shop_mat": "Shop Materials",
|
|
||||||
"state_tax_amt": "State/Provincial Taxes",
|
"state_tax_amt": "State/Provincial Taxes",
|
||||||
"subletstotal": "Sublets Total",
|
"subletstotal": "Sublets Total",
|
||||||
"subtotal": "Subtotal",
|
"subtotal": "Subtotal",
|
||||||
|
|||||||
@@ -364,7 +364,7 @@
|
|||||||
"instanceconflictext": "",
|
"instanceconflictext": "",
|
||||||
"instanceconflictitle": "",
|
"instanceconflictitle": "",
|
||||||
"loading": "Cargando...",
|
"loading": "Cargando...",
|
||||||
"loadingapp": "Cargando Bodyshop.app",
|
"loadingapp": "Cargando $t(titles.app)",
|
||||||
"loadingshop": "Cargando datos de la tienda ...",
|
"loadingshop": "Cargando datos de la tienda ...",
|
||||||
"loggingin": "Iniciando sesión ...",
|
"loggingin": "Iniciando sesión ...",
|
||||||
"na": "N / A",
|
"na": "N / A",
|
||||||
@@ -669,7 +669,9 @@
|
|||||||
"forms": {
|
"forms": {
|
||||||
"appraiserinfo": "",
|
"appraiserinfo": "",
|
||||||
"claiminfo": "",
|
"claiminfo": "",
|
||||||
|
"dedinfo": "",
|
||||||
"inscoinfo": "",
|
"inscoinfo": "",
|
||||||
|
"laborrates": "",
|
||||||
"lossinfo": ""
|
"lossinfo": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
@@ -713,10 +715,11 @@
|
|||||||
"laborallocations": "",
|
"laborallocations": "",
|
||||||
"lines": "Líneas estimadas",
|
"lines": "Líneas estimadas",
|
||||||
"local_tax_amt": "",
|
"local_tax_amt": "",
|
||||||
|
"mapa": "",
|
||||||
|
"mash": "",
|
||||||
"net_repairs": "",
|
"net_repairs": "",
|
||||||
"notes": "Notas",
|
"notes": "Notas",
|
||||||
"override_header": "¿Anular encabezado estimado al importar?",
|
"override_header": "¿Anular encabezado estimado al importar?",
|
||||||
"paint_mat": "",
|
|
||||||
"parts": "Partes",
|
"parts": "Partes",
|
||||||
"partsfilter": "",
|
"partsfilter": "",
|
||||||
"partssubletstotal": "",
|
"partssubletstotal": "",
|
||||||
@@ -724,7 +727,6 @@
|
|||||||
"rates": "Tarifas",
|
"rates": "Tarifas",
|
||||||
"rates_subtotal": "",
|
"rates_subtotal": "",
|
||||||
"reconciliationheader": "",
|
"reconciliationheader": "",
|
||||||
"shop_mat": "",
|
|
||||||
"state_tax_amt": "",
|
"state_tax_amt": "",
|
||||||
"subletstotal": "",
|
"subletstotal": "",
|
||||||
"subtotal": "",
|
"subtotal": "",
|
||||||
|
|||||||
@@ -364,7 +364,7 @@
|
|||||||
"instanceconflictext": "",
|
"instanceconflictext": "",
|
||||||
"instanceconflictitle": "",
|
"instanceconflictitle": "",
|
||||||
"loading": "Chargement...",
|
"loading": "Chargement...",
|
||||||
"loadingapp": "Chargement de Bodyshop.app",
|
"loadingapp": "Chargement de $t(titles.app)",
|
||||||
"loadingshop": "Chargement des données de la boutique ...",
|
"loadingshop": "Chargement des données de la boutique ...",
|
||||||
"loggingin": "Vous connecter ...",
|
"loggingin": "Vous connecter ...",
|
||||||
"na": "N / A",
|
"na": "N / A",
|
||||||
@@ -669,7 +669,9 @@
|
|||||||
"forms": {
|
"forms": {
|
||||||
"appraiserinfo": "",
|
"appraiserinfo": "",
|
||||||
"claiminfo": "",
|
"claiminfo": "",
|
||||||
|
"dedinfo": "",
|
||||||
"inscoinfo": "",
|
"inscoinfo": "",
|
||||||
|
"laborrates": "",
|
||||||
"lossinfo": ""
|
"lossinfo": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
@@ -713,10 +715,11 @@
|
|||||||
"laborallocations": "",
|
"laborallocations": "",
|
||||||
"lines": "Estimer les lignes",
|
"lines": "Estimer les lignes",
|
||||||
"local_tax_amt": "",
|
"local_tax_amt": "",
|
||||||
|
"mapa": "",
|
||||||
|
"mash": "",
|
||||||
"net_repairs": "",
|
"net_repairs": "",
|
||||||
"notes": "Remarques",
|
"notes": "Remarques",
|
||||||
"override_header": "Remplacer l'en-tête d'estimation à l'importation?",
|
"override_header": "Remplacer l'en-tête d'estimation à l'importation?",
|
||||||
"paint_mat": "",
|
|
||||||
"parts": "les pièces",
|
"parts": "les pièces",
|
||||||
"partsfilter": "",
|
"partsfilter": "",
|
||||||
"partssubletstotal": "",
|
"partssubletstotal": "",
|
||||||
@@ -724,7 +727,6 @@
|
|||||||
"rates": "Les taux",
|
"rates": "Les taux",
|
||||||
"rates_subtotal": "",
|
"rates_subtotal": "",
|
||||||
"reconciliationheader": "",
|
"reconciliationheader": "",
|
||||||
"shop_mat": "",
|
|
||||||
"state_tax_amt": "",
|
"state_tax_amt": "",
|
||||||
"subletstotal": "",
|
"subletstotal": "",
|
||||||
"subtotal": "",
|
"subtotal": "",
|
||||||
|
|||||||
3
client/src/utils/arrayHelper.js
Normal file
3
client/src/utils/arrayHelper.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function onlyUnique(value, index, self, key) {
|
||||||
|
return self.indexOf(value) === index;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user