@@ -132,6 +132,57 @@ jobs:
|
|||||||
to: "s3://rome-online-production/"
|
to: "s3://rome-online-production/"
|
||||||
- jira/notify
|
- jira/notify
|
||||||
|
|
||||||
|
test-rome-hasura-migrate:
|
||||||
|
docker:
|
||||||
|
- image: cimg/node:16.15.0
|
||||||
|
parameters:
|
||||||
|
secret:
|
||||||
|
type: string
|
||||||
|
default: $HASURA_ROME_TEST_SECRET
|
||||||
|
working_directory: ~/repo/hasura
|
||||||
|
steps:
|
||||||
|
- checkout:
|
||||||
|
path: ~/repo
|
||||||
|
- run:
|
||||||
|
name: Execute migration
|
||||||
|
command: |
|
||||||
|
npm install hasura-cli -g
|
||||||
|
echo ${HASURA_TEST_SECRET}
|
||||||
|
hasura migrate apply --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||||
|
hasura metadata apply --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||||
|
hasura metadata reload --endpoint https://db.test.romeonline.io/ --admin-secret << parameters.secret >>
|
||||||
|
|
||||||
|
test-rome-app-build:
|
||||||
|
docker:
|
||||||
|
- image: cimg/node:16.15.0
|
||||||
|
|
||||||
|
working_directory: ~/repo/client
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- checkout:
|
||||||
|
path: ~/repo
|
||||||
|
|
||||||
|
- restore_cache:
|
||||||
|
name: Restore Yarn Package Cache
|
||||||
|
keys:
|
||||||
|
- yarn-packages-{{ checksum "yarn.lock" }}
|
||||||
|
- run:
|
||||||
|
name: Install Dependencies
|
||||||
|
command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
|
||||||
|
- save_cache:
|
||||||
|
name: Save Yarn Package Cache
|
||||||
|
key: yarn-packages-{{ checksum "yarn.lock" }}
|
||||||
|
paths:
|
||||||
|
- ~/.cache/yarn
|
||||||
|
|
||||||
|
- run: yarn run build:test
|
||||||
|
|
||||||
|
- aws-s3/sync:
|
||||||
|
from: build
|
||||||
|
to: "s3://rome-online-test/"
|
||||||
|
- jira/notify
|
||||||
|
|
||||||
|
|
||||||
test-hasura-migrate:
|
test-hasura-migrate:
|
||||||
docker:
|
docker:
|
||||||
- image: cimg/node:16.15.0
|
- image: cimg/node:16.15.0
|
||||||
@@ -250,6 +301,15 @@ workflows:
|
|||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: test
|
only: test
|
||||||
|
- test-rome-app-build:
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only: rome/test
|
||||||
|
- test-rome-hasura-migrate:
|
||||||
|
secret: ${HASURA_ROME_TEST_SECRET}
|
||||||
|
filters:
|
||||||
|
branches:
|
||||||
|
only: rome/test
|
||||||
#- admin-app-build:
|
#- admin-app-build:
|
||||||
#filters:
|
#filters:
|
||||||
#branches:
|
#branches:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,14 @@
|
|||||||
REACT_APP_GRAPHQL_ENDPOINT=https://db.test.bodyshop.app/v1/graphql
|
REACT_APP_GRAPHQL_ENDPOINT=https://db.test.romeonline.io/v1/graphql
|
||||||
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.bodyshop.app/v1/graphql
|
REACT_APP_GRAPHQL_ENDPOINT_WS=wss://db.test.romeonline.io/v1/graphql
|
||||||
REACT_APP_GA_CODE=231099835
|
REACT_APP_GA_CODE=231103507
|
||||||
REACT_APP_FIREBASE_CONFIG={ "apiKey":"AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c", "authDomain":"imex-test.firebaseapp.com", "projectId":"imex-test", "storageBucket":"imex-test.appspot.com", "messagingSenderId":"991923618608", "appId":"1:991923618608:web:633437569cdad78299bef5", "measurementId":"G-TW0XLZEH18"}
|
REACT_APP_FIREBASE_CONFIG={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE", "authDomain": "rome-prod-1.firebaseapp.com", "projectId": "rome-prod-1", "storageBucket": "rome-prod-1.appspot.com", "messagingSenderId": "147786367145", "appId": "1:147786367145:web:9d4cba68071c3f29a8a9b8", "measurementId": "G-G8Z9DRHTZS"}
|
||||||
REACT_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
|
REACT_APP_CLOUDINARY_ENDPOINT_API=https://api.cloudinary.com/v1_1/bodyshop
|
||||||
REACT_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
|
REACT_APP_CLOUDINARY_ENDPOINT=https://res.cloudinary.com/bodyshop
|
||||||
REACT_APP_CLOUDINARY_API_KEY=473322739956866
|
REACT_APP_CLOUDINARY_API_KEY=473322739956866
|
||||||
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
|
REACT_APP_CLOUDINARY_THUMB_TRANSFORMATIONS=c_fill,h_250,w_250
|
||||||
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BN2GcDPjipR5MTEosO5dT4CfQ3cmrdBIsI4juoOQrRijn_5aRiHlwj1mlq0W145mOusx6xynEKl_tvYJhpCc9lo'
|
REACT_APP_FIREBASE_PUBLIC_VAPID_KEY='BP1B7ZTYpn-KMt6nOxlld6aS8Skt3Q7ZLEqP0hAvGHxG4UojPYiXZ6kPlzZkUC5jH-EcWXomTLtmadAIxurfcHo'
|
||||||
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
|
REACT_APP_STRIPE_PUBLIC_KEY=pk_test_51GqB4TJl3nQjrZ0wCQWAxAhlNF8jKe0tipIa6ExBaxwJGitwvFsIZUEua4dUzaMIAuXp4qwYHXx7lgjyQSwP0Pe900vzm38C7g
|
||||||
REACT_APP_AXIOS_BASE_API_URL=https://api.romeonline.io/
|
REACT_APP_AXIOS_BASE_API_URL=https://api.test.romeonline.io/
|
||||||
REACT_APP_REPORTS_SERVER_URL=https://reports.romeonline.io
|
REACT_APP_REPORTS_SERVER_URL=https://reports.test.romeonline.io
|
||||||
REACT_APP_IS_TEST=true
|
REACT_APP_IS_TEST=true
|
||||||
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
|
REACT_APP_SPLIT_API=ts615lqgnmk84thn72uk18uu5pgce6e0l4rc
|
||||||
@@ -364,13 +364,15 @@ export function BillFormComponent({
|
|||||||
)}
|
)}
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow>
|
<LayoutFormRow>
|
||||||
<Form.Item
|
{
|
||||||
span={3}
|
// <Form.Item
|
||||||
label={t("bills.fields.federal_tax_rate")}
|
// span={3}
|
||||||
name="federal_tax_rate"
|
// label={t("bills.fields.federal_tax_rate")}
|
||||||
>
|
// name="federal_tax_rate"
|
||||||
<CurrencyInput min={0} disabled={disabled} />
|
// >
|
||||||
</Form.Item>
|
// <CurrencyInput min={0} disabled={disabled} />
|
||||||
|
// </Form.Item>
|
||||||
|
}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
span={3}
|
span={3}
|
||||||
label={t("bills.fields.state_tax_rate")}
|
label={t("bills.fields.state_tax_rate")}
|
||||||
@@ -378,13 +380,15 @@ export function BillFormComponent({
|
|||||||
>
|
>
|
||||||
<CurrencyInput min={0} disabled={disabled} />
|
<CurrencyInput min={0} disabled={disabled} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
{
|
||||||
span={3}
|
// <Form.Item
|
||||||
label={t("bills.fields.local_tax_rate")}
|
// span={3}
|
||||||
name="local_tax_rate"
|
// label={t("bills.fields.local_tax_rate")}
|
||||||
>
|
// name="local_tax_rate"
|
||||||
<CurrencyInput min={0} />
|
// >
|
||||||
</Form.Item>
|
// <CurrencyInput min={0} />
|
||||||
|
// </Form.Item>
|
||||||
|
}
|
||||||
<Form.Item shouldUpdate span={15}>
|
<Form.Item shouldUpdate span={15}>
|
||||||
{() => {
|
{() => {
|
||||||
const values = form.getFieldsValue([
|
const values = form.getFieldsValue([
|
||||||
@@ -410,21 +414,25 @@ export function BillFormComponent({
|
|||||||
value={totals.subtotal.toFormat()}
|
value={totals.subtotal.toFormat()}
|
||||||
precision={2}
|
precision={2}
|
||||||
/>
|
/>
|
||||||
<Statistic
|
{
|
||||||
title={t("bills.labels.federal_tax")}
|
// <Statistic
|
||||||
value={totals.federalTax.toFormat()}
|
// title={t("bills.labels.federal_tax")}
|
||||||
precision={2}
|
// value={totals.federalTax.toFormat()}
|
||||||
/>
|
// precision={2}
|
||||||
|
// />
|
||||||
|
}
|
||||||
<Statistic
|
<Statistic
|
||||||
title={t("bills.labels.state_tax")}
|
title={t("bills.labels.state_tax")}
|
||||||
value={totals.stateTax.toFormat()}
|
value={totals.stateTax.toFormat()}
|
||||||
precision={2}
|
precision={2}
|
||||||
/>
|
/>
|
||||||
<Statistic
|
{
|
||||||
title={t("bills.labels.local_tax")}
|
// <Statistic
|
||||||
value={totals.localTax.toFormat()}
|
// title={t("bills.labels.local_tax")}
|
||||||
precision={2}
|
// value={totals.localTax.toFormat()}
|
||||||
/>
|
// precision={2}
|
||||||
|
// />
|
||||||
|
}
|
||||||
<Statistic
|
<Statistic
|
||||||
title={t("bills.labels.entered_total")}
|
title={t("bills.labels.entered_total")}
|
||||||
value={totals.enteredTotal.toFormat()}
|
value={totals.enteredTotal.toFormat()}
|
||||||
|
|||||||
@@ -458,21 +458,21 @@ export function BillEnterModalLinesComponent({
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: t("billlines.fields.federal_tax_applicable"),
|
// title: t("billlines.fields.federal_tax_applicable"),
|
||||||
dataIndex: "applicable_taxes.federal",
|
// dataIndex: "applicable_taxes.federal",
|
||||||
editable: true,
|
// editable: true,
|
||||||
|
|
||||||
formItemProps: (field) => {
|
// formItemProps: (field) => {
|
||||||
return {
|
// return {
|
||||||
key: `${field.index}fedtax`,
|
// key: `${field.index}fedtax`,
|
||||||
valuePropName: "checked",
|
// valuePropName: "checked",
|
||||||
// initialValue: true,
|
// // initialValue: true,
|
||||||
name: [field.name, "applicable_taxes", "federal"],
|
// name: [field.name, "applicable_taxes", "federal"],
|
||||||
};
|
// };
|
||||||
},
|
// },
|
||||||
formInput: (record, index) => <Switch disabled={disabled} />,
|
// formInput: (record, index) => <Switch disabled={disabled} />,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: t("billlines.fields.state_tax_applicable"),
|
title: t("billlines.fields.state_tax_applicable"),
|
||||||
dataIndex: "applicable_taxes.state",
|
dataIndex: "applicable_taxes.state",
|
||||||
@@ -487,20 +487,20 @@ export function BillEnterModalLinesComponent({
|
|||||||
},
|
},
|
||||||
formInput: (record, index) => <Switch disabled={disabled} />,
|
formInput: (record, index) => <Switch disabled={disabled} />,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: t("billlines.fields.local_tax_applicable"),
|
// title: t("billlines.fields.local_tax_applicable"),
|
||||||
dataIndex: "applicable_taxes.local",
|
// dataIndex: "applicable_taxes.local",
|
||||||
editable: true,
|
// editable: true,
|
||||||
|
|
||||||
formItemProps: (field) => {
|
// formItemProps: (field) => {
|
||||||
return {
|
// return {
|
||||||
key: `${field.index}localtax`,
|
// key: `${field.index}localtax`,
|
||||||
valuePropName: "checked",
|
// valuePropName: "checked",
|
||||||
name: [field.name, "applicable_taxes", "local"],
|
// name: [field.name, "applicable_taxes", "local"],
|
||||||
};
|
// };
|
||||||
},
|
// },
|
||||||
formInput: (record, index) => <Switch disabled={disabled} />,
|
// formInput: (record, index) => <Switch disabled={disabled} />,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
title: t("general.labels.actions"),
|
title: t("general.labels.actions"),
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
import { useMutation, useQuery } from "@apollo/client";
|
import { DeleteFilled } from "@ant-design/icons";
|
||||||
|
import { useLazyQuery, useMutation } from "@apollo/client";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
|
Col,
|
||||||
Form,
|
Form,
|
||||||
Input,
|
Input,
|
||||||
InputNumber,
|
|
||||||
Row,
|
Row,
|
||||||
|
Space,
|
||||||
Spin,
|
Spin,
|
||||||
|
Statistic,
|
||||||
notification,
|
notification,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
@@ -17,7 +20,7 @@ import { connect } from "react-redux";
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import {
|
import {
|
||||||
INSERT_PAYMENT_RESPONSE,
|
INSERT_PAYMENT_RESPONSE,
|
||||||
QUERY_RO_AND_OWNER_BY_JOB_PK,
|
QUERY_RO_AND_OWNER_BY_JOB_PKS,
|
||||||
} from "../../graphql/payment_response.queries";
|
} from "../../graphql/payment_response.queries";
|
||||||
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
||||||
import { insertAuditTrail } from "../../redux/application/application.actions";
|
import { insertAuditTrail } from "../../redux/application/application.actions";
|
||||||
@@ -25,9 +28,8 @@ import { toggleModalVisible } from "../../redux/modals/modals.actions";
|
|||||||
import { selectCardPayment } from "../../redux/modals/modals.selectors";
|
import { selectCardPayment } from "../../redux/modals/modals.selectors";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
import AuditTrailMapping from "../../utils/AuditTrailMappings";
|
||||||
import DataLabel from "../data-label/data-label.component";
|
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
||||||
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
|
import JobSearchSelectComponent from "../job-search-select/job-search-select.component";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
cardPaymentModal: selectCardPayment,
|
cardPaymentModal: selectCardPayment,
|
||||||
@@ -49,18 +51,21 @@ const CardPaymentModalComponent = ({
|
|||||||
const { context } = cardPaymentModal;
|
const { context } = cardPaymentModal;
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const amount = Form.useWatch("amount", form);
|
|
||||||
const jobid = Form.useWatch("jobid", form);
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
const [insertPayment] = useMutation(INSERT_NEW_PAYMENT);
|
||||||
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
|
const [insertPaymentResponse] = useMutation(INSERT_PAYMENT_RESPONSE);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { data, refetch } = useQuery(QUERY_RO_AND_OWNER_BY_JOB_PK, {
|
const [, { data, refetch, queryLoading }] = useLazyQuery(
|
||||||
variables: { jobid: context?.jobid ?? "" },
|
QUERY_RO_AND_OWNER_BY_JOB_PKS,
|
||||||
skip: !context?.jobid,
|
{
|
||||||
});
|
variables: { jobids: [context.jobid] },
|
||||||
|
skip: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("🚀 ~ file: card-payment-modal.component..jsx:61 ~ data:", data);
|
||||||
//Initialize the intellipay window.
|
//Initialize the intellipay window.
|
||||||
const SetIntellipayCallbackFunctions = () => {
|
const SetIntellipayCallbackFunctions = () => {
|
||||||
console.log("*** Set IntelliPay callback functions.");
|
console.log("*** Set IntelliPay callback functions.");
|
||||||
@@ -76,69 +81,68 @@ const CardPaymentModalComponent = ({
|
|||||||
|
|
||||||
window.intellipay.runOnNonApproval(async function (response) {
|
window.intellipay.runOnNonApproval(async function (response) {
|
||||||
// Mutate unsuccessful payment
|
// Mutate unsuccessful payment
|
||||||
|
|
||||||
|
const { payments } = form.getFieldsValue();
|
||||||
|
|
||||||
await insertPaymentResponse({
|
await insertPaymentResponse({
|
||||||
variables: {
|
variables: {
|
||||||
paymentResponse: {
|
paymentResponse: payments.map((payment) => ({
|
||||||
amount: response.amount,
|
amount: payment.amount,
|
||||||
bodyshopid: bodyshop.id,
|
bodyshopid: bodyshop.id,
|
||||||
jobid: jobid || context.jobid,
|
jobid: payment.jobid,
|
||||||
declinereason: response.declinereason,
|
declinereason: response.declinereason,
|
||||||
ext_paymentid: response.paymentid.toString(),
|
ext_paymentid: response.paymentid.toString(),
|
||||||
successful: false,
|
successful: false,
|
||||||
response,
|
response,
|
||||||
},
|
})),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
insertAuditTrail({
|
|
||||||
jobid: jobid || context?.jobid,
|
payments.forEach((payment) =>
|
||||||
operation: AuditTrailMapping.failedpayment(),
|
insertAuditTrail({
|
||||||
});
|
jobid: payment.jobid,
|
||||||
|
operation: AuditTrailMapping.failedpayment(),
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
try {
|
try {
|
||||||
const paymentResult = await insertPayment({
|
await insertPayment({
|
||||||
variables: {
|
variables: {
|
||||||
paymentInput: {
|
paymentInput: values.payments.map((payment) => ({
|
||||||
amount: values.amount,
|
amount: payment.amount,
|
||||||
transactionid: (values.paymentResponse.paymentid || "").toString(),
|
transactionid: (values.paymentResponse.paymentid || "").toString(),
|
||||||
payer: t("payments.labels.customer"),
|
payer: t("payments.labels.customer"),
|
||||||
type: values.paymentResponse.cardbrand,
|
type: values.paymentResponse.cardbrand,
|
||||||
jobid: values.jobid,
|
jobid: payment.jobid,
|
||||||
date: moment(Date.now()),
|
date: moment(Date.now()),
|
||||||
},
|
payment_responses: {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
amount: payment.amount,
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
|
||||||
|
jobid: payment.jobid,
|
||||||
|
declinereason: values.paymentResponse.declinereason,
|
||||||
|
ext_paymentid: values.paymentResponse.paymentid.toString(),
|
||||||
|
successful: true,
|
||||||
|
response: values.paymentResponse,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})),
|
||||||
},
|
},
|
||||||
refetchQueries: ["GET_JOB_BY_PK"],
|
refetchQueries: ["GET_JOB_BY_PK"],
|
||||||
update(cache, { data }) {
|
|
||||||
cache.modify({
|
|
||||||
id: cache.identify({ id: values.jobid, __typename: "jobs" }),
|
|
||||||
fields: {
|
|
||||||
payments(cachedPayments) {
|
|
||||||
return [...data.insert_payments.returning, ...cachedPayments];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
await insertPaymentResponse({
|
|
||||||
variables: {
|
|
||||||
paymentResponse: {
|
|
||||||
amount: values.amount,
|
|
||||||
bodyshopid: bodyshop.id,
|
|
||||||
paymentid: paymentResult.data.insert_payments.returning[0].id,
|
|
||||||
jobid: values.jobid,
|
|
||||||
declinereason: values.paymentResponse.declinereason,
|
|
||||||
ext_paymentid: values.paymentResponse.paymentid.toString(),
|
|
||||||
successful: true,
|
|
||||||
response: values.paymentResponse,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
toggleModalVisible();
|
toggleModalVisible();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
notification.open({
|
||||||
|
type: "error",
|
||||||
|
message: t("payments.errors.inserting", { error: error.message }),
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -146,9 +150,16 @@ const CardPaymentModalComponent = ({
|
|||||||
|
|
||||||
const handleIntelliPayCharge = async () => {
|
const handleIntelliPayCharge = async () => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
|
||||||
console.warn("*** Window.Intellipay", !!window.intellipay);
|
|
||||||
|
|
||||||
|
//Validate
|
||||||
|
try {
|
||||||
|
await form.validateFields();
|
||||||
|
} catch (error) {
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
const response = await axios.post("/intellipay/lightbox_credentials", {
|
const response = await axios.post("/intellipay/lightbox_credentials", {
|
||||||
bodyshop,
|
bodyshop,
|
||||||
refresh: !!window.intellipay,
|
refresh: !!window.intellipay,
|
||||||
@@ -182,93 +193,175 @@ const CardPaymentModalComponent = ({
|
|||||||
<Form
|
<Form
|
||||||
onFinish={handleFinish}
|
onFinish={handleFinish}
|
||||||
form={form}
|
form={form}
|
||||||
initialValues={{ jobid: context?.jobid }}
|
layout="vertical"
|
||||||
|
initialValues={{
|
||||||
|
payments: context.jobid ? [{ jobid: context.jobid }] : [],
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<LayoutFormRow grow noDivider>
|
<Form.List name={["payments"]}>
|
||||||
<Form.Item
|
{(fields, { add, remove, move }) => {
|
||||||
name="jobid"
|
return (
|
||||||
label={t("bills.fields.ro_number")}
|
<div>
|
||||||
rules={[
|
{fields.map((field, index) => (
|
||||||
{
|
<Form.Item key={field.key}>
|
||||||
required: true,
|
<Row gutter={[16, 16]}>
|
||||||
// message: t("general.validation.required"),
|
<Col span={16}>
|
||||||
},
|
<Form.Item
|
||||||
]}
|
key={`${index}jobid`}
|
||||||
>
|
label={t("jobs.fields.ro_number")}
|
||||||
<JobSearchSelectComponent
|
name={[field.name, "jobid"]}
|
||||||
disabled={context?.jobid}
|
rules={[
|
||||||
notExported={false}
|
{
|
||||||
clm_no
|
required: true,
|
||||||
onChange={(e) => {
|
//message: t("general.validation.required"),
|
||||||
refetch({ jobid: e });
|
},
|
||||||
}}
|
]}
|
||||||
/>
|
>
|
||||||
</Form.Item>
|
<JobSearchSelectComponent
|
||||||
</LayoutFormRow>
|
notExported={false}
|
||||||
|
clm_no
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={6}>
|
||||||
|
<Form.Item
|
||||||
|
key={`${index}amount`}
|
||||||
|
label={t("payments.fields.amount")}
|
||||||
|
name={[field.name, "amount"]}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<CurrencyFormItemComponent />
|
||||||
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col span={2}>
|
||||||
|
<DeleteFilled
|
||||||
|
style={{ margin: "1rem" }}
|
||||||
|
onClick={() => {
|
||||||
|
remove(field.name);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Form.Item>
|
||||||
|
))}
|
||||||
|
<Form.Item>
|
||||||
|
<Button
|
||||||
|
type="dashed"
|
||||||
|
onClick={() => {
|
||||||
|
add();
|
||||||
|
}}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
{t("general.actions.add")}
|
||||||
|
</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Form.List>
|
||||||
|
|
||||||
{/* Lighbox Input amount needs to be hidden */}
|
<Form.Item
|
||||||
<Input
|
shouldUpdate={(prevValues, curValues) =>
|
||||||
className="ipayfield"
|
prevValues.payments?.map((p) => p?.jobid).join() !==
|
||||||
data-ipayname="amount"
|
curValues.payments?.map((p) => p?.jobid).join()
|
||||||
type="hidden"
|
}
|
||||||
value={amount}
|
>
|
||||||
hidden
|
{() => {
|
||||||
/>
|
console.log("Updating the owner info section.");
|
||||||
<Input
|
//If all of the job ids have been fileld in, then query and update the IP field.
|
||||||
className="ipayfield"
|
const { payments } = form.getFieldsValue();
|
||||||
data-ipayname="account"
|
if (
|
||||||
type="hidden"
|
payments?.length > 0 &&
|
||||||
value={data?.jobs_by_pk.ro_number}
|
payments?.filter((p) => p?.jobid).length === payments?.length
|
||||||
hidden
|
) {
|
||||||
/>
|
console.log("**Calling refetch.");
|
||||||
<Input
|
refetch({ jobids: payments.map((p) => p.jobid) });
|
||||||
className="ipayfield"
|
}
|
||||||
data-ipayname="email"
|
console.log(
|
||||||
type="hidden"
|
"Acc info",
|
||||||
value={data?.jobs_by_pk.owner.ownr_ea}
|
data,
|
||||||
hidden
|
payments && data && data.jobs.length > 0
|
||||||
/>
|
? data.jobs.map((j) => j.ro_number).join(", ")
|
||||||
{/* Lightbox payment response when it is completed */}
|
: null
|
||||||
<Form.Item name="paymentResponse" hidden>
|
);
|
||||||
<Input type="hidden" value={amount} />
|
return (
|
||||||
|
<>
|
||||||
|
<Input
|
||||||
|
className="ipayfield"
|
||||||
|
data-ipayname="account"
|
||||||
|
//type="hidden"
|
||||||
|
value={
|
||||||
|
payments && data && data.jobs.length > 0
|
||||||
|
? data.jobs.map((j) => j.ro_number).join(", ")
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
className="ipayfield"
|
||||||
|
data-ipayname="email"
|
||||||
|
// type="hidden"
|
||||||
|
value={
|
||||||
|
payments && data && data.jobs.length > 0
|
||||||
|
? data.jobs.filter((j) => j.ownr_ea)[0]?.ownr_ea
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
shouldUpdate={(prevValues, curValues) =>
|
||||||
|
prevValues.payments?.map((p) => p?.amount).join() !==
|
||||||
|
curValues.payments?.map((p) => p?.amount).join()
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{() => {
|
||||||
|
const { payments } = form.getFieldsValue();
|
||||||
|
const totalAmountToCharge = payments?.reduce((acc, val) => {
|
||||||
|
return acc + (val?.amount || 0);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space style={{ float: "right" }}>
|
||||||
|
<Statistic
|
||||||
|
title="Amount To Charge"
|
||||||
|
value={totalAmountToCharge}
|
||||||
|
precision={2}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
className="ipayfield"
|
||||||
|
data-ipayname="amount"
|
||||||
|
//type="hidden"
|
||||||
|
value={totalAmountToCharge?.toFixed(2)}
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
// data-ipayname="submit"
|
||||||
|
className="ipayfield"
|
||||||
|
loading={queryLoading || loading}
|
||||||
|
disabled={!(totalAmountToCharge > 0)}
|
||||||
|
onClick={handleIntelliPayCharge}
|
||||||
|
>
|
||||||
|
{t("job_payments.buttons.proceedtopayment")}
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<LayoutFormRow grow>
|
{/* Lightbox payment response when it is completed */}
|
||||||
<Form.Item
|
<Form.Item name="paymentResponse" hidden>
|
||||||
label="Amount"
|
<Input type="hidden" />
|
||||||
name="amount"
|
</Form.Item>
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
// message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber />
|
|
||||||
</Form.Item>
|
|
||||||
|
|
||||||
<Row justify="space-around">
|
|
||||||
<Button
|
|
||||||
type="primary"
|
|
||||||
// data-ipayname="submit"
|
|
||||||
className="ipayfield"
|
|
||||||
disabled={!amount || !jobid}
|
|
||||||
onClick={handleIntelliPayCharge}
|
|
||||||
>
|
|
||||||
{t("job_payments.buttons.proceedtopayment")}
|
|
||||||
</Button>
|
|
||||||
{context?.balance && (
|
|
||||||
<DataLabel
|
|
||||||
valueStyle={{
|
|
||||||
color: context?.balance.getAmount() !== 0 ? "red" : "green",
|
|
||||||
}}
|
|
||||||
label={t("payments.labels.balance")}
|
|
||||||
>
|
|
||||||
{context?.balance.toFormat()}
|
|
||||||
</DataLabel>
|
|
||||||
)}
|
|
||||||
</Row>
|
|
||||||
</LayoutFormRow>
|
|
||||||
</Form>
|
</Form>
|
||||||
</Spin>
|
</Spin>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function CardPaymentModalContainer({
|
|||||||
{t("job_payments.buttons.goback")}
|
{t("job_payments.buttons.goback")}
|
||||||
</Button>,
|
</Button>,
|
||||||
]}
|
]}
|
||||||
width="60%"
|
width="80%"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
>
|
>
|
||||||
<CardPaymentModalComponent />
|
<CardPaymentModalComponent />
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ function Header({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCardPaymentContext({
|
setCardPaymentContext({
|
||||||
actions: {},
|
actions: {},
|
||||||
context: null,
|
context: {},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
icon={<Icon component={FaCreditCard} />}
|
icon={<Icon component={FaCreditCard} />}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { Alert } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
export default function JobProfileDataWarning({ job }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
let missingProfileInfo =
|
||||||
|
Object.keys(job.cieca_pft).length === 0 ||
|
||||||
|
Object.keys(job.cieca_pfl).length === 0 ||
|
||||||
|
Object.keys(job.materials).length === 0;
|
||||||
|
|
||||||
|
if (missingProfileInfo)
|
||||||
|
return (
|
||||||
|
<Alert type="error" message={t("jobs.labels.missingprofileinfo")}></Alert>
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
@@ -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,46 @@ 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:
|
||||||
total: job.job_totals.additional.pvrt,
|
bodyshop.md_responsibility_centers.taxes.tax_ty1?.tax_type1 ||
|
||||||
|
"T1",
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty1Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key:
|
||||||
|
bodyshop.md_responsibility_centers.taxes.tax_ty2?.tax_type2 ||
|
||||||
|
"T2",
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty2Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key:
|
||||||
|
bodyshop.md_responsibility_centers.taxes.tax_ty3?.tax_type3 ||
|
||||||
|
"T3",
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty3Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key:
|
||||||
|
bodyshop.md_responsibility_centers.taxes.tax_ty4?.tax_type4 ||
|
||||||
|
"T4",
|
||||||
|
total: job.job_totals.totals.us_sales_tax_breakdown.ty4Tax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key:
|
||||||
|
bodyshop.md_responsibility_centers.taxes.tax_ty5?.tax_type5 ||
|
||||||
|
"T5",
|
||||||
|
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,
|
||||||
@@ -57,10 +77,10 @@ export function JobTotalsTableTotals({ bodyshop, job }) {
|
|||||||
key: t("jobs.fields.ded_amt"),
|
key: t("jobs.fields.ded_amt"),
|
||||||
total: job.job_totals.totals.custPayable.deductible,
|
total: job.job_totals.totals.custPayable.deductible,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
key: t("jobs.fields.federal_tax_payable"),
|
// key: t("jobs.fields.federal_tax_payable"),
|
||||||
total: job.job_totals.totals.custPayable.federal_tax,
|
// total: job.job_totals.totals.custPayable.federal_tax,
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
key: t("jobs.fields.other_amount_payable"),
|
key: t("jobs.fields.other_amount_payable"),
|
||||||
total: job.job_totals.totals.custPayable.other_customer_amount,
|
total: job.job_totals.totals.custPayable.other_customer_amount,
|
||||||
@@ -81,7 +101,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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ export function JobsCloseExportButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) {
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "jobsuccessexport",
|
key: "jobsuccessexport",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Collapse, Form, Input, InputNumber, Select, Switch } from "antd";
|
import { Collapse, Form, Input, Select, 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";
|
||||||
@@ -12,6 +12,12 @@ import FormItemPhone, {
|
|||||||
} from "../form-items-formatted/phone-form-item.component";
|
} from "../form-items-formatted/phone-form-item.component";
|
||||||
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
|
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
|
||||||
import JobsDetailRatesParts from "../jobs-detail-rates/jobs-detail-rates.parts.component";
|
import JobsDetailRatesParts from "../jobs-detail-rates/jobs-detail-rates.parts.component";
|
||||||
|
|
||||||
|
import JobsDetailRatesLabor from "../jobs-detail-rates/jobs-detail-rates.labor.component";
|
||||||
|
import JobsDetailRatesMaterials from "../jobs-detail-rates/jobs-detail-rates.materials.component";
|
||||||
|
import JobsDetailRatesOther from "../jobs-detail-rates/jobs-detail-rates.other.component";
|
||||||
|
import JobsDetailRatesTaxes from "../jobs-detail-rates/jobs-detail-rates.taxes.component";
|
||||||
|
|
||||||
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 LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
@@ -258,26 +264,28 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
|||||||
<CurrencyInput />
|
<CurrencyInput />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow>
|
{
|
||||||
<Form.Item
|
// <LayoutFormRow>
|
||||||
label={t("jobs.fields.federal_tax_rate")}
|
// <Form.Item
|
||||||
name="federal_tax_rate"
|
// label={t("jobs.fields.federal_tax_rate")}
|
||||||
>
|
// name="federal_tax_rate"
|
||||||
<InputNumber min={0} max={1} precision={2} />
|
// >
|
||||||
</Form.Item>
|
// <InputNumber min={0} max={1} precision={2} />
|
||||||
<Form.Item
|
// </Form.Item>
|
||||||
label={t("jobs.fields.state_tax_rate")}
|
// <Form.Item
|
||||||
name="state_tax_rate"
|
// label={t("jobs.fields.state_tax_rate")}
|
||||||
>
|
// name="state_tax_rate"
|
||||||
<InputNumber min={0} max={1} precision={2} />
|
// >
|
||||||
</Form.Item>
|
// <InputNumber min={0} max={1} precision={2} />
|
||||||
<Form.Item
|
// </Form.Item>
|
||||||
label={t("jobs.fields.local_tax_rate")}
|
// <Form.Item
|
||||||
name="local_tax_rate"
|
// label={t("jobs.fields.local_tax_rate")}
|
||||||
>
|
// name="local_tax_rate"
|
||||||
<InputNumber min={0} max={1} precision={2} />
|
// >
|
||||||
</Form.Item>
|
// <InputNumber min={0} max={1} precision={2} />
|
||||||
</LayoutFormRow>
|
// </Form.Item>
|
||||||
|
// </LayoutFormRow>
|
||||||
|
}
|
||||||
<LayoutFormRow>
|
<LayoutFormRow>
|
||||||
<Form.Item label={t("jobs.fields.rate_lab")} name="rate_lab">
|
<Form.Item label={t("jobs.fields.rate_lab")} name="rate_lab">
|
||||||
<CurrencyInput />
|
<CurrencyInput />
|
||||||
@@ -356,6 +364,10 @@ export function JobsCreateJobsInfo({ bodyshop, form, selected }) {
|
|||||||
required={selected && true}
|
required={selected && true}
|
||||||
form={form}
|
form={form}
|
||||||
/>
|
/>
|
||||||
|
<JobsDetailRatesLabor form={form} />
|
||||||
|
<JobsDetailRatesMaterials form={form} />
|
||||||
|
<JobsDetailRatesOther form={form} />
|
||||||
|
<JobsDetailRatesTaxes form={form} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,21 @@
|
|||||||
import {
|
import { Divider, Form, Input, Select, Space, Switch, Tooltip } from "antd";
|
||||||
Divider,
|
|
||||||
Form,
|
|
||||||
Input,
|
|
||||||
InputNumber,
|
|
||||||
Select,
|
|
||||||
Space,
|
|
||||||
Switch,
|
|
||||||
Tooltip,
|
|
||||||
} 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";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
import { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import CABCpvrtCalculator from "../ca-bc-pvrt-calculator/ca-bc-pvrt-calculator.component";
|
|
||||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||||
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
|
import JobsDetailRatesChangeButton from "../jobs-detail-rates-change-button/jobs-detail-rates-change-button.component";
|
||||||
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 JobsDetailRatesLabor from "./jobs-detail-rates.labor.component";
|
||||||
|
import JobsDetailRatesMaterials from "./jobs-detail-rates.materials.component";
|
||||||
|
import JobsDetailRatesOther from "./jobs-detail-rates.other.component";
|
||||||
import JobsDetailRatesParts from "./jobs-detail-rates.parts.component";
|
import JobsDetailRatesParts from "./jobs-detail-rates.parts.component";
|
||||||
|
import JobsDetailRatesTaxes from "./jobs-detail-rates.taxes.component";
|
||||||
|
import JobsDetailRatesProfileOVerride from "./jobs-detail-rates.profile-override.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
jobRO: selectJobReadOnly,
|
jobRO: selectJobReadOnly,
|
||||||
@@ -84,14 +80,7 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<CurrencyInput disabled={jobRO || bodyshop.cdk_dealerid} />
|
<CurrencyInput disabled={jobRO || bodyshop.cdk_dealerid} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
{bodyshop.region_config === "CA_BC" && (
|
|
||||||
<Space align="center">
|
|
||||||
<Form.Item label={t("jobs.fields.ca_bc_pvrt")} name="ca_bc_pvrt">
|
|
||||||
<CurrencyInput disabled={jobRO} min={0} />
|
|
||||||
</Form.Item>
|
|
||||||
<CABCpvrtCalculator form={form} disabled={jobRO} />
|
|
||||||
</Space>
|
|
||||||
)}
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("jobs.fields.auto_add_ats")}
|
label={t("jobs.fields.auto_add_ats")}
|
||||||
name="auto_add_ats"
|
name="auto_add_ats"
|
||||||
@@ -120,41 +109,7 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
}}
|
}}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
<FormRow>
|
|
||||||
<Form.Item
|
|
||||||
label={t("jobs.fields.federal_tax_rate")}
|
|
||||||
name="federal_tax_rate"
|
|
||||||
>
|
|
||||||
<InputNumber min={0} max={1} precision={2} disabled={jobRO} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t("jobs.fields.state_tax_rate")}
|
|
||||||
name="state_tax_rate"
|
|
||||||
>
|
|
||||||
<InputNumber
|
|
||||||
min={0}
|
|
||||||
max={1}
|
|
||||||
precision={2}
|
|
||||||
disabled={jobRO}
|
|
||||||
autoComplete="new-password"
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t("jobs.fields.local_tax_rate")}
|
|
||||||
name="local_tax_rate"
|
|
||||||
>
|
|
||||||
<InputNumber min={0} max={1} precision={2} disabled={jobRO} />
|
|
||||||
</Form.Item>
|
|
||||||
{bodyshop.region_config.toLowerCase().startsWith("ca") && (
|
|
||||||
<Form.Item
|
|
||||||
label={t("jobs.fields.ca_gst_registrant")}
|
|
||||||
name="ca_gst_registrant"
|
|
||||||
valuePropName="checked"
|
|
||||||
>
|
|
||||||
<Switch disabled={jobRO} />
|
|
||||||
</Form.Item>
|
|
||||||
)}
|
|
||||||
</FormRow>
|
|
||||||
<Divider
|
<Divider
|
||||||
orientation="left"
|
orientation="left"
|
||||||
type="horizontal"
|
type="horizontal"
|
||||||
@@ -242,7 +197,15 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
<CurrencyInput min={0} disabled={jobRO} />
|
<CurrencyInput min={0} disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</FormRow>
|
</FormRow>
|
||||||
|
<Divider orientation="left">Tax Profile</Divider>
|
||||||
|
|
||||||
|
<JobsDetailRatesProfileOVerride form={form} />
|
||||||
|
|
||||||
<JobsDetailRatesParts form={form} />
|
<JobsDetailRatesParts form={form} />
|
||||||
|
<JobsDetailRatesLabor form={form} />
|
||||||
|
<JobsDetailRatesMaterials form={form} />
|
||||||
|
<JobsDetailRatesOther form={form} />
|
||||||
|
<JobsDetailRatesTaxes 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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAB", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAD", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAE", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAF", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAG", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAM", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAR", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAS", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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 disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in1")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in1"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in2")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in2"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in3")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in3"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in4")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in4"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.cieca_pfl.lbr_tx_in5")}
|
||||||
|
name={["cieca_pfl", "LAU", "lbr_tx_in5"]}
|
||||||
|
valuePropName="checked"
|
||||||
|
>
|
||||||
|
<Switch disabled={jobRO} />
|
||||||
|
</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.fields.materials.materials")}
|
||||||
|
key="materials"
|
||||||
|
>
|
||||||
|
<LayoutFormRow header={t("jobs.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("jobs.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 noDivider>
|
||||||
|
<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);
|
||||||
@@ -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,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", "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>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("joblines.fields.part_types.PAO")}>
|
<LayoutFormRow header={t("joblines.fields.part_types.PAO")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -368,11 +608,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 +698,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 +788,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 +878,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 +968,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
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { Button, Popconfirm } 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({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(JobsDetailRatesProfileOVerride);
|
||||||
|
|
||||||
|
export function JobsDetailRatesProfileOVerride({ bodyshop, form }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<Popconfirm
|
||||||
|
onConfirm={() => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
cieca_pft: {
|
||||||
|
...bodyshop.md_responsibility_centers.taxes.tax_ty1,
|
||||||
|
...bodyshop.md_responsibility_centers.taxes.tax_ty2,
|
||||||
|
...bodyshop.md_responsibility_centers.taxes.tax_ty3,
|
||||||
|
...bodyshop.md_responsibility_centers.taxes.tax_ty4,
|
||||||
|
...bodyshop.md_responsibility_centers.taxes.tax_ty5,
|
||||||
|
},
|
||||||
|
materials: bodyshop.md_responsibility_centers.cieca_pfm,
|
||||||
|
cieca_pfl: bodyshop.md_responsibility_centers.cieca_pfl,
|
||||||
|
parts_tax_rates: bodyshop.md_responsibility_centers.parts_tax_rates,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
title={t("jobs.actions.taxprofileoverride_confirm")}
|
||||||
|
>
|
||||||
|
<Button type="link">{t("jobs.actions.taxprofileoverride")}</Button>
|
||||||
|
</Popconfirm>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,155 @@
|
|||||||
|
import { Collapse, 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 { selectJobReadOnly } from "../../redux/application/application.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
jobRO: selectJobReadOnly,
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
|
||||||
|
export function JobsDetailRatesTaxes({
|
||||||
|
jobRO,
|
||||||
|
expanded,
|
||||||
|
bodyshop,
|
||||||
|
required = true,
|
||||||
|
form,
|
||||||
|
}) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const formItems = [];
|
||||||
|
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
|
||||||
|
const section = [];
|
||||||
|
|
||||||
|
section.push(
|
||||||
|
TaxFormItems({
|
||||||
|
typeNum: tyCounter,
|
||||||
|
rootElements: true,
|
||||||
|
bodyshop,
|
||||||
|
jobRO,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
for (let iterator = 1; iterator <= 5; iterator++) {
|
||||||
|
section.push(
|
||||||
|
TaxFormItems({
|
||||||
|
typeNum: tyCounter,
|
||||||
|
typeNumIterator: iterator,
|
||||||
|
rootElements: false,
|
||||||
|
jobRO,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
formItems.push(Space({ children: section, wrap: true }));
|
||||||
|
formItems.push(<Divider />);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Collapse defaultActiveKey={expanded && "rates"}>
|
||||||
|
<Collapse.Panel
|
||||||
|
forceRender
|
||||||
|
header={t("jobs.labels.cieca_pft")}
|
||||||
|
key="cieca_pft"
|
||||||
|
>
|
||||||
|
{formItems}
|
||||||
|
</Collapse.Panel>
|
||||||
|
</Collapse>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(mapStateToProps, null)(JobsDetailRatesTaxes);
|
||||||
|
|
||||||
|
function TaxFormItems({
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
rootElements,
|
||||||
|
bodyshopjobRO,
|
||||||
|
jobRO,
|
||||||
|
}) {
|
||||||
|
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={["cieca_pft", `tax_type${typeNum}`]}
|
||||||
|
>
|
||||||
|
<Input disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_tier", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={["cieca_pft", `ty${typeNum}_tier${typeNumIterator}`]}
|
||||||
|
>
|
||||||
|
<InputNumber precision={0} min={0} disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_thres", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={["cieca_pft", `ty${typeNum}_thres${typeNumIterator}`]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_rate", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={["cieca_pft", `ty${typeNum}_rate${typeNumIterator}`]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("bodyshop.fields.responsibilitycenter_tax_sur", {
|
||||||
|
typeNum,
|
||||||
|
typeNumIterator,
|
||||||
|
})}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
//message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
name={["cieca_pft", `ty${typeNum}_sur${typeNumIterator}`]}
|
||||||
|
>
|
||||||
|
<InputNumber min={0} precision={2} disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -190,7 +190,7 @@ export function JobsExportAllButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) {
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "jobsuccessexport",
|
key: "jobsuccessexport",
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ export function PayableExportAll({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) {
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "billsuccessexport",
|
key: "billsuccessexport",
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ export function PayableExportButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) {
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "billsuccessexport",
|
key: "billsuccessexport",
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
import React, { useState } from "react";
|
|
||||||
import { useMutation, useQuery } from "@apollo/client";
|
import { useMutation, useQuery } from "@apollo/client";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Descriptions,
|
||||||
|
InputNumber,
|
||||||
|
Modal,
|
||||||
|
Space,
|
||||||
|
notification,
|
||||||
|
} from "antd";
|
||||||
|
import axios from "axios";
|
||||||
|
import moment from "moment";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import {
|
import {
|
||||||
GET_REFUNDABLE_AMOUNT_BY_JOBID,
|
GET_REFUNDABLE_AMOUNT_BY_JOBID,
|
||||||
INSERT_PAYMENT_RESPONSE,
|
INSERT_PAYMENT_RESPONSE,
|
||||||
QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID,
|
QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID,
|
||||||
} from "../../graphql/payment_response.queries";
|
} from "../../graphql/payment_response.queries";
|
||||||
import { Button, Descriptions, InputNumber, Modal, notification } from "antd";
|
|
||||||
import moment from "moment";
|
|
||||||
import axios from "axios";
|
|
||||||
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
import { INSERT_NEW_PAYMENT } from "../../graphql/payments.queries";
|
||||||
import { useTranslation } from "react-i18next";
|
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||||
|
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||||
|
|
||||||
const { confirm } = Modal;
|
const { confirm } = Modal;
|
||||||
|
|
||||||
@@ -137,10 +146,10 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => {
|
|||||||
{payment_response?.response?.nameOnCard ?? ""}
|
{payment_response?.response?.nameOnCard ?? ""}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={t("job_payments.titles.amount")}>
|
<Descriptions.Item label={t("job_payments.titles.amount")}>
|
||||||
{record.amount}
|
<CurrencyFormatter>{record.amount}</CurrencyFormatter>
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={t("job_payments.titles.dateOfPayment")}>
|
<Descriptions.Item label={t("job_payments.titles.dateOfPayment")}>
|
||||||
{moment(record.created_at).format("YYYY-MM-DD HH:mm:ss")}
|
{<DateTimeFormatter>{record.created_at}</DateTimeFormatter>}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
<Descriptions.Item label={t("job_payments.titles.transactionid")}>
|
<Descriptions.Item label={t("job_payments.titles.transactionid")}>
|
||||||
{record.transactionid}
|
{record.transactionid}
|
||||||
@@ -151,17 +160,22 @@ const PaymentExpandedRowComponent = ({ record, bodyshop }) => {
|
|||||||
<Descriptions.Item label={t("job_payments.titles.paymenttype")}>
|
<Descriptions.Item label={t("job_payments.titles.paymenttype")}>
|
||||||
{record.type}
|
{record.type}
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={t("job_payments.titles.paymentnum")}>
|
||||||
|
{record.paymentnum}
|
||||||
|
</Descriptions.Item>
|
||||||
{payment_response && (
|
{payment_response && (
|
||||||
<Descriptions.Item label={t("job_payments.titles.refundamount")}>
|
<Descriptions.Item label={t("job_payments.titles.refundamount")}>
|
||||||
<InputNumber
|
<Space>
|
||||||
onChange={setRefundAmount}
|
<InputNumber
|
||||||
max={max_refundable_amount}
|
onChange={setRefundAmount}
|
||||||
min={0}
|
max={max_refundable_amount}
|
||||||
/>
|
min={0}
|
||||||
|
/>
|
||||||
|
|
||||||
<Button onClick={() => showConfirm(payment_response)}>
|
<Button onClick={() => showConfirm(payment_response)}>
|
||||||
{t("job_payments.buttons.refundpayment")}
|
{t("job_payments.buttons.refundpayment")}
|
||||||
</Button>
|
</Button>
|
||||||
|
</Space>
|
||||||
</Descriptions.Item>
|
</Descriptions.Item>
|
||||||
)}
|
)}
|
||||||
</Descriptions>
|
</Descriptions>
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ export function PaymentExportButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) {
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "paymentsuccessexport",
|
key: "paymentsuccessexport",
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ export function PaymentsExportAllButton({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo) {
|
if (bodyshop.accountingconfig && bodyshop.accountingconfig.qbo && successfulTransactions.length > 0) {
|
||||||
notification.open({
|
notification.open({
|
||||||
type: "success",
|
type: "success",
|
||||||
key: "paymentsuccessexport",
|
key: "paymentsuccessexport",
|
||||||
|
|||||||
@@ -188,20 +188,22 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
|||||||
<Switch />
|
<Switch />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item shouldUpdate noStyle>
|
{
|
||||||
{() => (
|
// <Form.Item shouldUpdate noStyle>
|
||||||
<Form.Item
|
// {() => (
|
||||||
label={t("bodyshop.labels.qbo_usa")}
|
// <Form.Item
|
||||||
shouldUpdate
|
// label={t("bodyshop.labels.qbo_usa")}
|
||||||
valuePropName="checked"
|
// shouldUpdate
|
||||||
name={["accountingconfig", "qbo_usa"]}
|
// valuePropName="checked"
|
||||||
>
|
// name={["accountingconfig", "qbo_usa"]}
|
||||||
<Switch
|
// >
|
||||||
disabled={!form.getFieldValue(["accountingconfig", "qbo"])}
|
// <Switch
|
||||||
/>
|
// disabled={!form.getFieldValue(["accountingconfig", "qbo"])}
|
||||||
</Form.Item>
|
// />
|
||||||
)}
|
// </Form.Item>
|
||||||
</Form.Item>
|
// )}
|
||||||
|
// </Form.Item>
|
||||||
|
}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.labels.qbo_departmentid")}
|
label={t("bodyshop.labels.qbo_departmentid")}
|
||||||
name={["accountingconfig", "qbo_departmentid"]}
|
name={["accountingconfig", "qbo_departmentid"]}
|
||||||
@@ -290,30 +292,34 @@ export function ShopInfoGeneral({ form, bodyshop }) {
|
|||||||
>
|
>
|
||||||
<InputNumber min={0} precision={2} />
|
<InputNumber min={0} precision={2} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
{
|
||||||
label={t("bodyshop.fields.federal_tax_id")}
|
// <Form.Item
|
||||||
name="federal_tax_id"
|
// label={t("bodyshop.fields.federal_tax_id")}
|
||||||
>
|
// name="federal_tax_id"
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
|
// </Form.Item>
|
||||||
|
}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.state_tax_id")}
|
label={t("bodyshop.fields.state_tax_id")}
|
||||||
name="state_tax_id"
|
name="state_tax_id"
|
||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
{
|
||||||
label={t("bodyshop.fields.invoice_federal_tax_rate")}
|
// <Form.Item
|
||||||
name={["bill_tax_rates", "federal_tax_rate"]}
|
// label={t("bodyshop.fields.invoice_federal_tax_rate")}
|
||||||
rules={[
|
// name={["bill_tax_rates", "federal_tax_rate"]}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
>
|
// ]}
|
||||||
<InputNumber />
|
// >
|
||||||
</Form.Item>
|
// <InputNumber />
|
||||||
|
// </Form.Item>
|
||||||
|
}
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.invoice_state_tax_rate")}
|
label={t("bodyshop.fields.invoice_state_tax_rate")}
|
||||||
name={["bill_tax_rates", "state_tax_rate"]}
|
name={["bill_tax_rates", "state_tax_rate"]}
|
||||||
|
|||||||
@@ -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 {
|
||||||
@@ -4116,122 +4117,124 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
|
|||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
</SelectorDiv>
|
</SelectorDiv>
|
||||||
|
|
||||||
<LayoutFormRow
|
{
|
||||||
header={t("bodyshop.labels.responsibilitycenters.tax_accounts")}
|
// <LayoutFormRow
|
||||||
id="tax_accounts"
|
// header={t("bodyshop.labels.responsibilitycenters.tax_accounts")}
|
||||||
>
|
// id="tax_accounts"
|
||||||
<Form.Item
|
// >
|
||||||
label={t("bodyshop.fields.responsibilitycenters.federal_tax")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenters.federal_tax")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "federal", "name"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "federal", "name"]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
{/* <Form.Item
|
// </Form.Item>
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountnumber")}
|
// {/* <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountnumber")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"federal",
|
// "taxes",
|
||||||
"accountnumber",
|
// "federal",
|
||||||
]}
|
// "accountnumber",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item> */}
|
// <Input />
|
||||||
{/* <Form.Item
|
// </Form.Item> */}
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountname")}
|
// {/* <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountname")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"federal",
|
// "taxes",
|
||||||
"accountname",
|
// "federal",
|
||||||
]}
|
// "accountname",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item> */}
|
// <Input />
|
||||||
<Form.Item
|
// </Form.Item> */}
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"federal",
|
// "taxes",
|
||||||
"accountdesc",
|
// "federal",
|
||||||
]}
|
// "accountdesc",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
<Form.Item
|
// </Form.Item>
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountitem")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountitem")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"federal",
|
// "taxes",
|
||||||
"accountitem",
|
// "federal",
|
||||||
]}
|
// "accountitem",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
// </Form.Item>
|
||||||
<Form.Item
|
// {(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
||||||
label={t("bodyshop.fields.dms.dms_acctnumber")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.dms.dms_acctnumber")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"federal",
|
// "taxes",
|
||||||
"dms_acctnumber",
|
// "federal",
|
||||||
]}
|
// "dms_acctnumber",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
)}
|
// </Form.Item>
|
||||||
<Form.Item
|
// )}
|
||||||
label={t("bodyshop.fields.responsibilitycenter_rate")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_rate")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "federal", "rate"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "federal", "rate"]}
|
||||||
<InputNumber precision={2} />
|
// >
|
||||||
</Form.Item>
|
// <InputNumber precision={2} />
|
||||||
</LayoutFormRow>
|
// </Form.Item>
|
||||||
|
// </LayoutFormRow>
|
||||||
|
}
|
||||||
{DmsAp.treatment === "on" && (
|
{DmsAp.treatment === "on" && (
|
||||||
<LayoutFormRow id="federal_tax_itc">
|
<LayoutFormRow id="federal_tax_itc">
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@@ -4347,104 +4350,107 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
)}
|
)}
|
||||||
<LayoutFormRow id="state_tax">
|
{
|
||||||
<Form.Item
|
// <LayoutFormRow id="state_tax">
|
||||||
label={t("bodyshop.fields.responsibilitycenters.state_tax")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenters.state_tax")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "state", "name"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "state", "name"]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
{/* <Form.Item
|
// </Form.Item>
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountnumber")}
|
// {/* <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountnumber")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"state",
|
// "taxes",
|
||||||
"accountnumber",
|
// "state",
|
||||||
]}
|
// "accountnumber",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
<Form.Item
|
// </Form.Item>
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountname")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountname")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "state", "accountname"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "state", "accountname"]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item> */}
|
// <Input />
|
||||||
<Form.Item
|
// </Form.Item> */}
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "state", "accountdesc"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "state", "accountdesc"]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
<Form.Item
|
// </Form.Item>
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountitem")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountitem")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "state", "accountitem"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "state", "accountitem"]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
// </Form.Item>
|
||||||
<Form.Item
|
// {(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
||||||
label={t("bodyshop.fields.dms.dms_acctnumber")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.dms.dms_acctnumber")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"state",
|
// "taxes",
|
||||||
"dms_acctnumber",
|
// "state",
|
||||||
]}
|
// "dms_acctnumber",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
)}
|
// </Form.Item>
|
||||||
<Form.Item
|
// )}
|
||||||
label={t("bodyshop.fields.responsibilitycenter_rate")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_rate")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "state", "rate"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "state", "rate"]}
|
||||||
<InputNumber precision={2} />
|
// >
|
||||||
</Form.Item>
|
// <InputNumber precision={2} />
|
||||||
</LayoutFormRow>
|
// </Form.Item>
|
||||||
|
// </LayoutFormRow>
|
||||||
|
}
|
||||||
|
<ShopInfoResponsibilitycentersTaxesComponent form={form} />
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("bodyshop.fields.responsibilitycenters.itemexemptcode")}
|
label={t("bodyshop.fields.responsibilitycenters.itemexemptcode")}
|
||||||
rules={[
|
rules={[
|
||||||
@@ -4470,104 +4476,116 @@ export function ShopInfoResponsibilityCenterComponent({ bodyshop, form }) {
|
|||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<LayoutFormRow id="local_tax">
|
{
|
||||||
<Form.Item
|
// <LayoutFormRow id="local_tax">
|
||||||
label={t("bodyshop.fields.responsibilitycenters.local_tax")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenters.local_tax")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "local", "name"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "local", "name"]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
{/* <Form.Item
|
// </Form.Item>
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountnumber")}
|
// {/* <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountnumber")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={[
|
// ]}
|
||||||
"md_responsibility_centers",
|
// name={[
|
||||||
"taxes",
|
// "md_responsibility_centers",
|
||||||
"local",
|
// "taxes",
|
||||||
"accountnumber",
|
// "local",
|
||||||
]}
|
// "accountnumber",
|
||||||
>
|
// ]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item>
|
// <Input />
|
||||||
<Form.Item
|
// </Form.Item>
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountname")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountname")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "local", "accountname"]}
|
// ]}
|
||||||
>
|
// name={["md_responsibility_centers", "taxes", "local", "accountname"]}
|
||||||
<Input />
|
// >
|
||||||
</Form.Item> */}
|
// <Input />
|
||||||
<Form.Item
|
// </Form.Item> */}
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
|
// <Form.Item
|
||||||
rules={[
|
// label={t("bodyshop.fields.responsibilitycenter_accountdesc")}
|
||||||
{
|
// rules={[
|
||||||
required: true,
|
// {
|
||||||
//message: t("general.validation.required"),
|
// required: true,
|
||||||
},
|
// //message: t("general.validation.required"),
|
||||||
]}
|
// },
|
||||||
name={["md_responsibility_centers", "taxes", "local", "accountdesc"]}
|
// ]}
|
||||||
>
|
// name={[
|
||||||
<Input />
|
// "md_responsibility_centers",
|
||||||
</Form.Item>
|
// "taxes",
|
||||||
<Form.Item
|
// "local",
|
||||||
label={t("bodyshop.fields.responsibilitycenter_accountitem")}
|
// "accountdesc",
|
||||||
rules={[
|
// ]}
|
||||||
{
|
// >
|
||||||
required: true,
|
// <Input />
|
||||||
//message: t("general.validation.required"),
|
// </Form.Item>
|
||||||
},
|
// <Form.Item
|
||||||
]}
|
// label={t("bodyshop.fields.responsibilitycenter_accountitem")}
|
||||||
name={["md_responsibility_centers", "taxes", "local", "accountitem"]}
|
// rules={[
|
||||||
>
|
// {
|
||||||
<Input />
|
// required: true,
|
||||||
</Form.Item>
|
// //message: t("general.validation.required"),
|
||||||
{(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
// },
|
||||||
<Form.Item
|
// ]}
|
||||||
label={t("bodyshop.fields.dms.dms_acctnumber")}
|
// name={[
|
||||||
rules={[
|
// "md_responsibility_centers",
|
||||||
{
|
// "taxes",
|
||||||
required: true,
|
// "local",
|
||||||
//message: t("general.validation.required"),
|
// "accountitem",
|
||||||
},
|
// ]}
|
||||||
]}
|
// >
|
||||||
name={[
|
// <Input />
|
||||||
"md_responsibility_centers",
|
// </Form.Item>
|
||||||
"taxes",
|
// {(bodyshop.cdk_dealerid || bodyshop.pbs_serialnumber) && (
|
||||||
"local",
|
// <Form.Item
|
||||||
"dms_acctnumber",
|
// label={t("bodyshop.fields.dms.dms_acctnumber")}
|
||||||
]}
|
// rules={[
|
||||||
>
|
// {
|
||||||
<Input />
|
// required: true,
|
||||||
</Form.Item>
|
// //message: t("general.validation.required"),
|
||||||
)}
|
// },
|
||||||
<Form.Item
|
// ]}
|
||||||
label={t("bodyshop.fields.responsibilitycenter_rate")}
|
// name={[
|
||||||
rules={[
|
// "md_responsibility_centers",
|
||||||
{
|
// "taxes",
|
||||||
required: true,
|
// "local",
|
||||||
//message: t("general.validation.required"),
|
// "dms_acctnumber",
|
||||||
},
|
// ]}
|
||||||
]}
|
// >
|
||||||
name={["md_responsibility_centers", "taxes", "local", "rate"]}
|
// <Input />
|
||||||
>
|
// </Form.Item>
|
||||||
<InputNumber precision={2} />
|
// )}
|
||||||
</Form.Item>
|
// <Form.Item
|
||||||
</LayoutFormRow>
|
// label={t("bodyshop.fields.responsibilitycenter_rate")}
|
||||||
|
// rules={[
|
||||||
|
// {
|
||||||
|
// required: true,
|
||||||
|
// //message: t("general.validation.required"),
|
||||||
|
// },
|
||||||
|
// ]}
|
||||||
|
// name={["md_responsibility_centers", "taxes", "local", "rate"]}
|
||||||
|
// >
|
||||||
|
// <InputNumber precision={2} />
|
||||||
|
// </Form.Item>
|
||||||
|
// </LayoutFormRow>
|
||||||
|
}
|
||||||
<LayoutFormRow header={<div>AR</div>} id="AR">
|
<LayoutFormRow header={<div>AR</div>} id="AR">
|
||||||
{/* <Form.Item
|
{/* <Form.Item
|
||||||
label={t("bodyshop.fields.responsibilitycenters.ar")}
|
label={t("bodyshop.fields.responsibilitycenters.ar")}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -574,7 +574,6 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
est_co_nm
|
est_co_nm
|
||||||
est_ct_fn
|
est_ct_fn
|
||||||
est_ct_ln
|
est_ct_ln
|
||||||
|
|
||||||
est_ph1
|
est_ph1
|
||||||
est_ea
|
est_ea
|
||||||
selling_dealer
|
selling_dealer
|
||||||
@@ -756,6 +755,7 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
jobid
|
jobid
|
||||||
amount
|
amount
|
||||||
payer
|
payer
|
||||||
|
paymentnum
|
||||||
created_at
|
created_at
|
||||||
transactionid
|
transactionid
|
||||||
memo
|
memo
|
||||||
@@ -779,6 +779,10 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cieca_ttl
|
cieca_ttl
|
||||||
|
cieca_pfo
|
||||||
|
cieca_pfl
|
||||||
|
cieca_pft
|
||||||
|
materials
|
||||||
csiinvites {
|
csiinvites {
|
||||||
id
|
id
|
||||||
completedon
|
completedon
|
||||||
|
|||||||
@@ -28,16 +28,14 @@ export const QUERY_PAYMENT_RESPONSE_BY_PAYMENT_ID = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const QUERY_RO_AND_OWNER_BY_JOB_PK = gql`
|
export const QUERY_RO_AND_OWNER_BY_JOB_PKS = gql`
|
||||||
query QUERY_RO_AND_OWNER_BY_JOB_PK($jobid: uuid!) {
|
query QUERY_RO_AND_OWNER_BY_JOB_PKS($jobids: [uuid!]!) {
|
||||||
jobs_by_pk(id: $jobid) {
|
jobs(where: { id: { _in: $jobids } }) {
|
||||||
ro_number
|
ro_number
|
||||||
owner {
|
ownr_fn
|
||||||
ownr_fn
|
ownr_ln
|
||||||
ownr_ln
|
ownr_ea
|
||||||
ownr_ea
|
ownr_zip
|
||||||
ownr_zip
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ const mapDispatchToProps = (dispatch) => ({
|
|||||||
export default connect(mapStateToProps, mapDispatchToProps)(DmsContainer);
|
export default connect(mapStateToProps, mapDispatchToProps)(DmsContainer);
|
||||||
|
|
||||||
export const socket = SocketIO(
|
export const socket = SocketIO(
|
||||||
process.env.NODE_ENV === "production"
|
// process.env.NODE_ENV === "production"
|
||||||
? process.env.REACT_APP_AXIOS_BASE_API_URL
|
// ? process.env.REACT_APP_AXIOS_BASE_API_URL
|
||||||
: window.location.origin,
|
// : window.location.origin,
|
||||||
// "http://localhost:4000", // for dev testing,
|
"http://localhost:4000", // for dev testing,
|
||||||
{
|
{
|
||||||
path: "/ws",
|
path: "/ws",
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
|
|||||||
@@ -169,96 +169,16 @@ function JobsCreateContainer({ bodyshop, setBreadcrumbs, setSelectedHeader }) {
|
|||||||
federal_tax_rate: bodyshop.bill_tax_rates.federal_tax_rate / 100,
|
federal_tax_rate: bodyshop.bill_tax_rates.federal_tax_rate / 100,
|
||||||
state_tax_rate: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
state_tax_rate: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
||||||
local_tax_rate: bodyshop.bill_tax_rates.local_tax_rate / 100,
|
local_tax_rate: bodyshop.bill_tax_rates.local_tax_rate / 100,
|
||||||
parts_tax_rates: {
|
cieca_pft: {
|
||||||
PAA: {
|
...bodyshop.md_responsibility_centers.taxes.tax_ty1,
|
||||||
prt_type: "PAA",
|
...bodyshop.md_responsibility_centers.taxes.tax_ty2,
|
||||||
prt_discp: 0,
|
...bodyshop.md_responsibility_centers.taxes.tax_ty3,
|
||||||
prt_mktyp: false,
|
...bodyshop.md_responsibility_centers.taxes.tax_ty4,
|
||||||
prt_mkupp: 0,
|
...bodyshop.md_responsibility_centers.taxes.tax_ty5,
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAC: {
|
|
||||||
prt_type: "PAC",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAG: {
|
|
||||||
prt_type: "PAG",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAL: {
|
|
||||||
prt_type: "PAL",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAM: {
|
|
||||||
prt_type: "PAM",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAN: {
|
|
||||||
prt_type: "PAN",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAR: {
|
|
||||||
prt_type: "PAR",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAS: {
|
|
||||||
prt_type: "PAS",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PASL: {
|
|
||||||
prt_type: "PASL",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAP: {
|
|
||||||
prt_type: "PAP",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
PAO: {
|
|
||||||
prt_type: "PAO",
|
|
||||||
prt_discp: 0,
|
|
||||||
prt_mktyp: false,
|
|
||||||
prt_mkupp: 0,
|
|
||||||
prt_tax_in: true,
|
|
||||||
prt_tax_rt: bodyshop.bill_tax_rates.state_tax_rate / 100,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
materials: bodyshop.md_responsibility_centers.cieca_pfm,
|
||||||
|
cieca_pfl: bodyshop.md_responsibility_centers.cieca_pfl,
|
||||||
|
parts_tax_rates: bodyshop.md_responsibility_centers.parts_tax_rates,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<JobsCreateComponent form={form} />
|
<JobsCreateComponent form={form} />
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ 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";
|
||||||
|
import JobProfileDataWarning from "../../components/job-profile-data-warning/job-profile-data-warning.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -103,86 +105,121 @@ 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", {
|
try {
|
||||||
id: job.id,
|
const newTotals = await Axios.post("/job/totalsssu", {
|
||||||
});
|
id: job.id,
|
||||||
|
});
|
||||||
|
|
||||||
if (newTotals.status !== 200 || result.errors) {
|
if (newTotals.status !== 200 || result.errors) {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("jobs.errors.totalscalc"),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notification["success"]({
|
||||||
|
message: t("jobs.successes.savetitle"),
|
||||||
|
});
|
||||||
|
const changedAuditFields = form.getFieldsValue(
|
||||||
|
[
|
||||||
|
"scheduled_in",
|
||||||
|
"actual_in",
|
||||||
|
"scheduled_completion",
|
||||||
|
"actual_completion",
|
||||||
|
"scheduled_delivery",
|
||||||
|
"actual_delivery",
|
||||||
|
"date_invoiced",
|
||||||
|
"ins_co_nm",
|
||||||
|
"ded_amt",
|
||||||
|
"ded_status",
|
||||||
|
"date_exported",
|
||||||
|
"special_coverage_policy",
|
||||||
|
"ca_gst_registrant",
|
||||||
|
"ca_bc_pvrt",
|
||||||
|
"scheduled_in",
|
||||||
|
"rate_la1",
|
||||||
|
"rate_la2",
|
||||||
|
"rate_la3",
|
||||||
|
"rate_la4",
|
||||||
|
"rate_laa",
|
||||||
|
"rate_lab",
|
||||||
|
"rate_lad",
|
||||||
|
"rate_lae",
|
||||||
|
"rate_laf",
|
||||||
|
"rate_lag",
|
||||||
|
"rate_lam",
|
||||||
|
"rate_lar",
|
||||||
|
"rate_las",
|
||||||
|
"rate_lau",
|
||||||
|
"rate_ma2s",
|
||||||
|
"rate_ma2t",
|
||||||
|
"rate_ma3s",
|
||||||
|
"rate_mabl",
|
||||||
|
"rate_macs",
|
||||||
|
"rate_mapa",
|
||||||
|
"rate_mahw",
|
||||||
|
"rate_mash",
|
||||||
|
"rate_matd",
|
||||||
|
],
|
||||||
|
(meta) => meta && meta.touched
|
||||||
|
);
|
||||||
|
|
||||||
|
Object.keys(changedAuditFields).forEach((key) => {
|
||||||
|
insertAuditTrail({
|
||||||
|
jobid: job.id,
|
||||||
|
operation: AuditTrailMapping.jobfieldchange(
|
||||||
|
key,
|
||||||
|
changedAuditFields[key] instanceof moment
|
||||||
|
? moment(changedAuditFields[key]).format("MM/DD/YYYY hh:mm a")
|
||||||
|
: changedAuditFields[key]
|
||||||
|
),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await refetch();
|
||||||
|
form.setFieldsValue(transormJobToForm(job));
|
||||||
|
form.resetFields();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("jobs.errors.totalscalc"),
|
message: t("jobs.errors.totalscalc"),
|
||||||
});
|
});
|
||||||
} else {
|
} finally {
|
||||||
notification["success"]({
|
setLoading(false);
|
||||||
message: t("jobs.successes.savetitle"),
|
|
||||||
});
|
|
||||||
const changedAuditFields = form.getFieldsValue(
|
|
||||||
[
|
|
||||||
"scheduled_in",
|
|
||||||
"actual_in",
|
|
||||||
"scheduled_completion",
|
|
||||||
"actual_completion",
|
|
||||||
"scheduled_delivery",
|
|
||||||
"actual_delivery",
|
|
||||||
"date_invoiced",
|
|
||||||
"ins_co_nm",
|
|
||||||
"ded_amt",
|
|
||||||
"ded_status",
|
|
||||||
"date_exported",
|
|
||||||
"special_coverage_policy",
|
|
||||||
"ca_gst_registrant",
|
|
||||||
"ca_bc_pvrt",
|
|
||||||
"scheduled_in",
|
|
||||||
"rate_la1",
|
|
||||||
"rate_la2",
|
|
||||||
"rate_la3",
|
|
||||||
"rate_la4",
|
|
||||||
"rate_laa",
|
|
||||||
"rate_lab",
|
|
||||||
"rate_lad",
|
|
||||||
"rate_lae",
|
|
||||||
"rate_laf",
|
|
||||||
"rate_lag",
|
|
||||||
"rate_lam",
|
|
||||||
"rate_lar",
|
|
||||||
"rate_las",
|
|
||||||
"rate_lau",
|
|
||||||
"rate_ma2s",
|
|
||||||
"rate_ma2t",
|
|
||||||
"rate_ma3s",
|
|
||||||
"rate_mabl",
|
|
||||||
"rate_macs",
|
|
||||||
"rate_mapa",
|
|
||||||
"rate_mahw",
|
|
||||||
"rate_mash",
|
|
||||||
"rate_matd",
|
|
||||||
],
|
|
||||||
(meta) => meta && meta.touched
|
|
||||||
);
|
|
||||||
|
|
||||||
Object.keys(changedAuditFields).forEach((key) => {
|
|
||||||
insertAuditTrail({
|
|
||||||
jobid: job.id,
|
|
||||||
operation: AuditTrailMapping.jobfieldchange(
|
|
||||||
key,
|
|
||||||
changedAuditFields[key] instanceof moment
|
|
||||||
? moment(changedAuditFields[key]).format("MM/DD/YYYY hh:mm a")
|
|
||||||
: changedAuditFields[key]
|
|
||||||
),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
await refetch();
|
|
||||||
form.setFieldsValue(transormJobToForm(job));
|
|
||||||
form.resetFields();
|
|
||||||
}
|
}
|
||||||
setLoading(false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const menuExtra = (
|
const menuExtra = (
|
||||||
@@ -252,6 +289,7 @@ export function JobsDetailPage({
|
|||||||
/>
|
/>
|
||||||
<JobsDetailHeader job={job} />
|
<JobsDetailHeader job={job} />
|
||||||
<Divider type="horizontal" />
|
<Divider type="horizontal" />
|
||||||
|
<JobProfileDataWarning job={job} />
|
||||||
<FormFieldsChanged form={form} />
|
<FormFieldsChanged form={form} />
|
||||||
<Tabs
|
<Tabs
|
||||||
defaultActiveKey={search.tab}
|
defaultActiveKey={search.tab}
|
||||||
@@ -389,6 +427,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",
|
||||||
@@ -1217,6 +1222,7 @@
|
|||||||
"payer": "Payer",
|
"payer": "Payer",
|
||||||
"payername": "Payer Name",
|
"payername": "Payer Name",
|
||||||
"paymentid": "Payment Reference ID",
|
"paymentid": "Payment Reference ID",
|
||||||
|
"paymentnum": "Payment Number",
|
||||||
"paymenttype": "Payment Type",
|
"paymenttype": "Payment Type",
|
||||||
"refundamount": "Refund Amount",
|
"refundamount": "Refund Amount",
|
||||||
"transactionid": "Transaction ID"
|
"transactionid": "Transaction ID"
|
||||||
@@ -1367,6 +1373,8 @@
|
|||||||
"sendpartspricechange": "Send Parts Price Change",
|
"sendpartspricechange": "Send Parts Price Change",
|
||||||
"sendtodms": "Send to DMS",
|
"sendtodms": "Send to DMS",
|
||||||
"sync": "Sync",
|
"sync": "Sync",
|
||||||
|
"taxprofileoverride": "Override Tax Profile with Shop Configuration",
|
||||||
|
"taxprofileoverride_confirm": "Are you sure you want to override the tax profile information? This cannot be undone without re-importing the job. ",
|
||||||
"uninvoice": "Uninvoice",
|
"uninvoice": "Uninvoice",
|
||||||
"unvoid": "Unvoid Job",
|
"unvoid": "Unvoid Job",
|
||||||
"viewchecklist": "View Checklists",
|
"viewchecklist": "View Checklists",
|
||||||
@@ -1438,6 +1446,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 #",
|
||||||
@@ -1551,6 +1579,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",
|
||||||
@@ -1573,6 +1614,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",
|
||||||
@@ -1700,6 +1746,9 @@
|
|||||||
"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",
|
||||||
|
"cieca_pfo": "Profile - Other",
|
||||||
|
"cieca_pft": "Profile - Taxes",
|
||||||
"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.",
|
||||||
@@ -1772,6 +1821,10 @@
|
|||||||
"mapa": "Paint Materials",
|
"mapa": "Paint Materials",
|
||||||
"markforreexport": "Mark for Re-export",
|
"markforreexport": "Mark for Re-export",
|
||||||
"mash": "Shop Materials",
|
"mash": "Shop Materials",
|
||||||
|
"materials": {
|
||||||
|
"mapa": ""
|
||||||
|
},
|
||||||
|
"missingprofileinfo": "This job has missing tax profile info. To ensure correct totals calculations, re-import the job.",
|
||||||
"multipayers": "Additional Payers",
|
"multipayers": "Additional Payers",
|
||||||
"net_repairs": "Net Repairs",
|
"net_repairs": "Net Repairs",
|
||||||
"notes": "Notes",
|
"notes": "Notes",
|
||||||
@@ -1798,7 +1851,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",
|
||||||
@@ -2240,7 +2293,8 @@
|
|||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"exporting": "Error exporting payment(s). {{error}}",
|
"exporting": "Error exporting payment(s). {{error}}",
|
||||||
"exporting-partner": "Error exporting to partner. Please check the partner interaction log for more errors."
|
"exporting-partner": "Error exporting to partner. Please check the partner interaction log for more errors.",
|
||||||
|
"inserting": "Error inserting payment. {{error}}"
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "Amount",
|
"amount": "Amount",
|
||||||
|
|||||||
@@ -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": "",
|
||||||
@@ -1216,6 +1222,7 @@
|
|||||||
"payer": "",
|
"payer": "",
|
||||||
"payername": "",
|
"payername": "",
|
||||||
"paymentid": "",
|
"paymentid": "",
|
||||||
|
"paymentnum": "",
|
||||||
"paymenttype": "",
|
"paymenttype": "",
|
||||||
"refundamount": "",
|
"refundamount": "",
|
||||||
"transactionid": ""
|
"transactionid": ""
|
||||||
@@ -1366,6 +1373,8 @@
|
|||||||
"sendpartspricechange": "",
|
"sendpartspricechange": "",
|
||||||
"sendtodms": "",
|
"sendtodms": "",
|
||||||
"sync": "",
|
"sync": "",
|
||||||
|
"taxprofileoverride": "",
|
||||||
|
"taxprofileoverride_confirm": "",
|
||||||
"uninvoice": "",
|
"uninvoice": "",
|
||||||
"unvoid": "",
|
"unvoid": "",
|
||||||
"viewchecklist": "",
|
"viewchecklist": "",
|
||||||
@@ -1437,6 +1446,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 #",
|
||||||
@@ -1550,6 +1579,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",
|
||||||
@@ -1572,6 +1614,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": "",
|
||||||
@@ -1699,6 +1746,9 @@
|
|||||||
"checklistcompletedby": "",
|
"checklistcompletedby": "",
|
||||||
"checklistdocuments": "",
|
"checklistdocuments": "",
|
||||||
"checklists": "",
|
"checklists": "",
|
||||||
|
"cieca_pfl": "",
|
||||||
|
"cieca_pfo": "",
|
||||||
|
"cieca_pft": "",
|
||||||
"closeconfirm": "",
|
"closeconfirm": "",
|
||||||
"closejob": "",
|
"closejob": "",
|
||||||
"closingperiod": "",
|
"closingperiod": "",
|
||||||
@@ -1771,6 +1821,10 @@
|
|||||||
"mapa": "",
|
"mapa": "",
|
||||||
"markforreexport": "",
|
"markforreexport": "",
|
||||||
"mash": "",
|
"mash": "",
|
||||||
|
"materials": {
|
||||||
|
"mapa": ""
|
||||||
|
},
|
||||||
|
"missingprofileinfo": "",
|
||||||
"multipayers": "",
|
"multipayers": "",
|
||||||
"net_repairs": "",
|
"net_repairs": "",
|
||||||
"notes": "Notas",
|
"notes": "Notas",
|
||||||
@@ -2239,7 +2293,8 @@
|
|||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"exporting": "",
|
"exporting": "",
|
||||||
"exporting-partner": ""
|
"exporting-partner": "",
|
||||||
|
"inserting": ""
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "",
|
"amount": "",
|
||||||
|
|||||||
@@ -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": "",
|
||||||
@@ -1216,6 +1222,7 @@
|
|||||||
"payer": "",
|
"payer": "",
|
||||||
"payername": "",
|
"payername": "",
|
||||||
"paymentid": "",
|
"paymentid": "",
|
||||||
|
"paymentnum": "",
|
||||||
"paymenttype": "",
|
"paymenttype": "",
|
||||||
"refundamount": "",
|
"refundamount": "",
|
||||||
"transactionid": ""
|
"transactionid": ""
|
||||||
@@ -1366,6 +1373,8 @@
|
|||||||
"sendpartspricechange": "",
|
"sendpartspricechange": "",
|
||||||
"sendtodms": "",
|
"sendtodms": "",
|
||||||
"sync": "",
|
"sync": "",
|
||||||
|
"taxprofileoverride": "",
|
||||||
|
"taxprofileoverride_confirm": "",
|
||||||
"uninvoice": "",
|
"uninvoice": "",
|
||||||
"unvoid": "",
|
"unvoid": "",
|
||||||
"viewchecklist": "",
|
"viewchecklist": "",
|
||||||
@@ -1437,6 +1446,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 #",
|
||||||
@@ -1550,6 +1579,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",
|
||||||
@@ -1572,6 +1614,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": "",
|
||||||
@@ -1699,6 +1746,9 @@
|
|||||||
"checklistcompletedby": "",
|
"checklistcompletedby": "",
|
||||||
"checklistdocuments": "",
|
"checklistdocuments": "",
|
||||||
"checklists": "",
|
"checklists": "",
|
||||||
|
"cieca_pfl": "",
|
||||||
|
"cieca_pfo": "",
|
||||||
|
"cieca_pft": "",
|
||||||
"closeconfirm": "",
|
"closeconfirm": "",
|
||||||
"closejob": "",
|
"closejob": "",
|
||||||
"closingperiod": "",
|
"closingperiod": "",
|
||||||
@@ -1771,6 +1821,10 @@
|
|||||||
"mapa": "",
|
"mapa": "",
|
||||||
"markforreexport": "",
|
"markforreexport": "",
|
||||||
"mash": "",
|
"mash": "",
|
||||||
|
"materials": {
|
||||||
|
"mapa": ""
|
||||||
|
},
|
||||||
|
"missingprofileinfo": "",
|
||||||
"multipayers": "",
|
"multipayers": "",
|
||||||
"net_repairs": "",
|
"net_repairs": "",
|
||||||
"notes": "Remarques",
|
"notes": "Remarques",
|
||||||
@@ -2239,7 +2293,8 @@
|
|||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"exporting": "",
|
"exporting": "",
|
||||||
"exporting-partner": ""
|
"exporting-partner": "",
|
||||||
|
"inserting": ""
|
||||||
},
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"amount": "",
|
"amount": "",
|
||||||
|
|||||||
@@ -3274,6 +3274,8 @@
|
|||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
- cieca_pfl
|
- cieca_pfl
|
||||||
|
- cieca_pfo
|
||||||
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
- ciecaid
|
- ciecaid
|
||||||
@@ -3541,6 +3543,8 @@
|
|||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
- cieca_pfl
|
- cieca_pfl
|
||||||
|
- cieca_pfo
|
||||||
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
- ciecaid
|
- ciecaid
|
||||||
@@ -3819,6 +3823,8 @@
|
|||||||
- cat_no
|
- cat_no
|
||||||
- category
|
- category
|
||||||
- cieca_pfl
|
- cieca_pfl
|
||||||
|
- cieca_pfo
|
||||||
|
- cieca_pft
|
||||||
- cieca_stl
|
- cieca_stl
|
||||||
- cieca_ttl
|
- cieca_ttl
|
||||||
- ciecaid
|
- ciecaid
|
||||||
|
|||||||
@@ -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_pft" jsonb
|
||||||
|
-- null default jsonb_build_object();
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."jobs" add column "cieca_pft" jsonb
|
||||||
|
null default jsonb_build_object();
|
||||||
@@ -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 = ["52b7357c-0edd-4c95-85c3-dfdbcdfad9ac"];
|
||||||
const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImM2MGI5ZGUwODBmZmFmYmZjMTgzMzllY2Q0NGFjNzdmN2ZhNGU4ZDMiLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiUm9tZSBEZXZlbG9wbWVudCIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoiYWRtaW4iLCJ4LWhhc3VyYS1hbGxvd2VkLXJvbGVzIjpbImFkbWluIl0sIngtaGFzdXJhLXVzZXItaWQiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIn0sImlvYWRtaW4iOnRydWUsImlzcyI6Imh0dHBzOi8vc2VjdXJldG9rZW4uZ29vZ2xlLmNvbS9yb21lLXByb2QtMSIsImF1ZCI6InJvbWUtcHJvZC0xIiwiYXV0aF90aW1lIjoxNjkyODk5ODE2LCJ1c2VyX2lkIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiIsInN1YiI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIiLCJpYXQiOjE2OTMyNTA1NjIsImV4cCI6MTY5MzI1NDE2MiwiZW1haWwiOiJwYXRyaWNrQHJvbWUuZGV2IiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7ImVtYWlsIjpbInBhdHJpY2tAcm9tZS5kZXYiXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.POr8U2pP4XtTJEDRJ_BveRkCs92CIfDDdfU24OYe_aZh6LFPN0bQukNHXrLt3gaD30SUcg5mgmI2VUphgmwviMEGY-zizPC9o6GUKEEppZWQXfrfTyJNa1VKKH9h5zZPPFFW8UJRMi131pCc0ev26GS8Do-FJAgwHLJd6Jp2RbbqiCIeafNMhQCEoXohOk-VArNe7tPAb6-IjxqGVyNqvVyIo6niSXYvmgNjyF1WnnIw0CsnPoJlc5kVMtRdYeshJI7V117MOlUwZicF62vsm32eCunjn3qhN5XsujI7gy9us3vzwhdR1lxISZCLhLOXEYHPL373HJh7I_KN1C3NuA`;
|
const bearerToken = `Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjlhNTE5MDc0NmU5M2JhZTI0OWIyYWE3YzJhYTRlMzA2M2UzNDFlYzciLCJ0eXAiOiJKV1QifQ.eyJuYW1lIjoiUm9tZSBEZXZlbG9wbWVudCIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoidXNlciIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsidXNlciJdLCJ4LWhhc3VyYS11c2VyLWlkIjoidDZZbTFORGxDRE9QWnIzRjliZ3VXSDRMaFNYMiJ9LCJpb2FkbWluIjp0cnVlLCJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vcm9tZS1wcm9kLTEiLCJhdWQiOiJyb21lLXByb2QtMSIsImF1dGhfdGltZSI6MTY5NTkxNDQ5NywidXNlcl9pZCI6InQ2WW0xTkRsQ0RPUFpyM0Y5Ymd1V0g0TGhTWDIiLCJzdWIiOiJ0NlltMU5EbENET1BacjNGOWJndVdINExoU1gyIiwiaWF0IjoxNjk2NjAzMTUwLCJleHAiOjE2OTY2MDY3NTAsImVtYWlsIjoicGF0cmlja0Byb21lLmRldiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyJwYXRyaWNrQHJvbWUuZGV2Il19LCJzaWduX2luX3Byb3ZpZGVyIjoicGFzc3dvcmQifX0.YYSEG1_Iwoqrelj0Fz5f04b78ABrueaFHVG1bBi-2c9kfkfrSiobgSs4jmYRlUHx1pRY58sFoNWvjci3cpFLwdaFSRAei5LwVFHllXlT8sMmWpxOMD4xU_fLRX9_hGM4SySlsBLAekytU5wCrtYF-BwEubYwPc7nkfi61BbaX1rBxVU3FAX123ToO7zN6VIzbTQRlrpBPBsCa3LWjhi1y-2V9vRsshOMMyezmKNMwknGvuoLwEeh9HYM4O0gDbtLYosFb5zsMRSPdrq4wjECge_psxF6QJ5p2JpKFAVyoYjK6lavM4QXZhTx05ssOj7pRz13NbYYX9of2pabhWjDSw`;
|
||||||
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,14 @@ 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}. Failed jobs: ${
|
||||||
|
results.filter((r) => r.result !== "PASS").length
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await axios.post(
|
await axios.post(
|
||||||
`http://localhost:4000/job/totalsssu`,
|
`http://localhost:4000/job/totalsssu`,
|
||||||
@@ -61,6 +68,7 @@ async function RunTheTest() {
|
|||||||
ownr_ln
|
ownr_ln
|
||||||
ownr_co_nm
|
ownr_co_nm
|
||||||
ins_co_nm
|
ins_co_nm
|
||||||
|
comment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
@@ -73,19 +81,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 +106,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 +124,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,10 @@ 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 +443,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 +453,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 +477,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 +502,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",
|
||||||
@@ -573,123 +574,117 @@ exports.default = function ({
|
|||||||
//Add tax lines
|
//Add tax lines
|
||||||
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);
|
//Handle insurance profile adjustments
|
||||||
const state_tax = Dinero(job_totals.totals.state_tax);
|
Object.keys(job_totals.parts.adjustments).forEach((key) => {
|
||||||
const local_tax = Dinero(job_totals.totals.local_tax);
|
|
||||||
|
|
||||||
if (federal_tax.getAmount() > 0) {
|
|
||||||
if (qbo) {
|
if (qbo) {
|
||||||
// do qbo
|
//Going to always assume that we need to apply GST and PST for labor.
|
||||||
} else {
|
const taxAccountCode = findTaxCode(
|
||||||
InvoiceLineAdd.push({
|
{
|
||||||
ItemRef: {
|
local: false,
|
||||||
FullName:
|
federal: process.env.COUNTRY === "USA" ? false : true,
|
||||||
bodyshop.md_responsibility_centers.taxes.federal.accountitem,
|
state: jobs_by_pk.state_tax_rate === 0 ? false : true,
|
||||||
},
|
},
|
||||||
Desc: bodyshop.md_responsibility_centers.taxes.federal.accountdesc,
|
bodyshop.md_responsibility_centers.sales_tax_codes
|
||||||
Amount: federal_tax.toFormat(DineroQbFormat),
|
);
|
||||||
});
|
const account = responsibilityCenters.profits.find(
|
||||||
}
|
(c) => c.name === responsibilityCenters.defaults.profits[key]
|
||||||
}
|
);
|
||||||
|
const QboTaxId =
|
||||||
if (state_tax.getAmount() > 0) {
|
process.env.COUNTRY === "USA"
|
||||||
if (qbo) {
|
? CheckQBOUSATaxID({
|
||||||
// do qbo
|
// jobline: jobline,
|
||||||
} else {
|
job: jobs_by_pk,
|
||||||
InvoiceLineAdd.push({
|
type: "storage",
|
||||||
ItemRef: {
|
})
|
||||||
FullName: bodyshop.md_responsibility_centers.taxes.state.accountitem,
|
: taxCodes[taxAccountCode];
|
||||||
},
|
|
||||||
Desc: bodyshop.md_responsibility_centers.taxes.state.accountdesc,
|
|
||||||
Amount: state_tax.toFormat(DineroQbFormat),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (local_tax.getAmount() > 0) {
|
|
||||||
if (qbo) {
|
|
||||||
// do qbo
|
|
||||||
} else {
|
|
||||||
InvoiceLineAdd.push({
|
|
||||||
ItemRef: {
|
|
||||||
FullName: bodyshop.md_responsibility_centers.taxes.local.accountitem,
|
|
||||||
},
|
|
||||||
Desc: bodyshop.md_responsibility_centers.taxes.local.accountdesc,
|
|
||||||
Amount: local_tax.toFormat(DineroQbFormat),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Region Specific
|
|
||||||
const { ca_bc_pvrt } = jobs_by_pk;
|
|
||||||
if (ca_bc_pvrt) {
|
|
||||||
if (qbo) {
|
|
||||||
InvoiceLineAdd.push({
|
InvoiceLineAdd.push({
|
||||||
DetailType: "SalesItemLineDetail",
|
DetailType: "SalesItemLineDetail",
|
||||||
Amount: Dinero({ amount: (ca_bc_pvrt || 0) * 100 }).toFormat(
|
Amount: Dinero(job_totals.parts.adjustments[key]).toFormat(
|
||||||
DineroQbFormat
|
DineroQbFormat
|
||||||
),
|
),
|
||||||
|
Description: `${account.accountdesc} - Adjustment`,
|
||||||
SalesItemLineDetail: {
|
SalesItemLineDetail: {
|
||||||
...(jobs_by_pk.class
|
...(jobs_by_pk.class
|
||||||
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||||
: {}),
|
: {}),
|
||||||
ItemRef: {
|
ItemRef: {
|
||||||
value: items["PVRT"],
|
value: items[account.accountitem],
|
||||||
|
},
|
||||||
|
TaxCodeRef: {
|
||||||
|
value: QboTaxId,
|
||||||
},
|
},
|
||||||
Qty: 1,
|
Qty: 1,
|
||||||
TaxCodeRef: {
|
|
||||||
value:
|
|
||||||
taxCodes[
|
|
||||||
findTaxCode(
|
|
||||||
{
|
|
||||||
local: false,
|
|
||||||
federal: process.env.COUNTRY === "USA" ? false : true,
|
|
||||||
state: false,
|
|
||||||
},
|
|
||||||
bodyshop.md_responsibility_centers.sales_tax_codes
|
|
||||||
)
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
InvoiceLineAdd.push({
|
InvoiceLineAdd.push({
|
||||||
ItemRef: {
|
ItemRef: {
|
||||||
FullName: bodyshop.md_responsibility_centers.taxes.state.accountitem,
|
FullName: responsibilityCenters.profits.find(
|
||||||
|
(c) => c.name === responsibilityCenters.defaults.profits[key]
|
||||||
|
).accountitem,
|
||||||
},
|
},
|
||||||
Desc: "PVRT",
|
Desc: "Storage",
|
||||||
Amount: Dinero({ amount: (ca_bc_pvrt || 0) * 100 }).toFormat(
|
Quantity: 1,
|
||||||
|
Amount: Dinero(job_totals.parts.adjustments[key]).toFormat(
|
||||||
DineroQbFormat
|
DineroQbFormat
|
||||||
),
|
),
|
||||||
|
SalesTaxCodeRef: {
|
||||||
|
FullName:
|
||||||
|
bodyshop.md_responsibility_centers.taxes.itemexemptcode || "NON",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
//QB USA with GST
|
const federal_tax = Dinero(job_totals.totals.federal_tax);
|
||||||
//This was required for the No. 1 Collision Group.
|
const QboTaxId =
|
||||||
// if (
|
process.env.COUNTRY === "USA"
|
||||||
// bodyshop.accountingconfig &&
|
? CheckQBOUSATaxID({
|
||||||
// bodyshop.accountingconfig.qbo &&
|
// jobline: jobline,
|
||||||
// bodyshop.accountingconfig.qbo_usa &&
|
type: "adjustment",
|
||||||
// bodyshop.region_config.includes("CA_")
|
job: jobs_by_pk,
|
||||||
// ) {
|
})
|
||||||
// InvoiceLineAdd.push({
|
: taxCodes[taxAccountCode];
|
||||||
// DetailType: "SalesItemLineDetail",
|
for (let tyCounter = 1; tyCounter <= 5; tyCounter++) {
|
||||||
// Amount: Dinero(jobs_by_pk.job_totals.totals.federal_tax).toFormat(
|
const taxAmount = Dinero(
|
||||||
// DineroQbFormat
|
job_totals.totals.us_sales_tax_breakdown[`ty${tyCounter}Tax`]
|
||||||
// ),
|
);
|
||||||
// SalesItemLineDetail: {
|
console.log(`Tax ${tyCounter}`, taxAmount.toFormat());
|
||||||
// ...(jobs_by_pk.class
|
if (taxAmount.getAmount() > 0) {
|
||||||
// ? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
if (qbo) {
|
||||||
// : {}),
|
InvoiceLineAdd.push({
|
||||||
// ItemRef: {
|
DetailType: "SalesItemLineDetail",
|
||||||
// value:
|
Amount: taxAmount.toFormat(DineroQbFormat),
|
||||||
// items[bodyshop.md_responsibility_centers.taxes.federal.accountitem],
|
SalesItemLineDetail: {
|
||||||
// },
|
...(jobs_by_pk.class
|
||||||
// Qty: 1,
|
? { ClassRef: { value: classes[jobs_by_pk.class] } }
|
||||||
// },
|
: {}),
|
||||||
// });
|
ItemRef: {
|
||||||
// }
|
value:
|
||||||
|
items[
|
||||||
|
responsibilityCenters.taxes[`tax_ty${tyCounter}`].accountitem
|
||||||
|
],
|
||||||
|
},
|
||||||
|
TaxCodeRef: {
|
||||||
|
value: QboTaxId,
|
||||||
|
},
|
||||||
|
Qty: 1,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
InvoiceLineAdd.push({
|
||||||
|
ItemRef: {
|
||||||
|
FullName:
|
||||||
|
bodyshop.md_responsibility_centers.taxes[`tax_ty${tyCounter}`]
|
||||||
|
.accountitem,
|
||||||
|
},
|
||||||
|
Desc: bodyshop.md_responsibility_centers.taxes[`tax_ty${tyCounter}`]
|
||||||
|
.accountdesc,
|
||||||
|
Amount: taxAmount.toFormat(DineroQbFormat),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
||||||
@@ -832,17 +827,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} `);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,6 +242,11 @@ exports.default = async (req, res) => {
|
|||||||
(error && error.authResponse && error.authResponse.body) ||
|
(error && error.authResponse && error.authResponse.body) ||
|
||||||
(error && error.message),
|
(error && error.message),
|
||||||
});
|
});
|
||||||
|
console.log(error);
|
||||||
|
logger.log("qbo-receivable-create-error", "ERROR", req.user.email, {
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack,
|
||||||
|
});
|
||||||
//Add the export log error.
|
//Add the export log error.
|
||||||
if (elgen) {
|
if (elgen) {
|
||||||
const result = await client
|
const result = await client
|
||||||
|
|||||||
@@ -25,26 +25,40 @@ exports.default = async function (socket, jobid) {
|
|||||||
const { bodyshop } = job;
|
const { bodyshop } = job;
|
||||||
|
|
||||||
const taxAllocations = {
|
const taxAllocations = {
|
||||||
local: {
|
tax_ty1: {
|
||||||
center: bodyshop.md_responsibility_centers.taxes.local.name,
|
center: bodyshop.md_responsibility_centers.taxes[`tax_ty1`].name,
|
||||||
sale: Dinero(job.job_totals.totals.local_tax),
|
sale: Dinero(job.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.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.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.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.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`],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -328,6 +342,30 @@ exports.default = async function (socket, jobid) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//profile level adjustments
|
||||||
|
Object.keys(job.job_totals.parts.adjustments).forEach((key) => {
|
||||||
|
const accountName = selectedDmsAllocationConfig.profits[key];
|
||||||
|
|
||||||
|
const otherAccount = bodyshop.md_responsibility_centers.profits.find(
|
||||||
|
(c) => c.name === accountName
|
||||||
|
);
|
||||||
|
|
||||||
|
if (otherAccount) {
|
||||||
|
if (!profitCenterHash[accountName])
|
||||||
|
profitCenterHash[accountName] = Dinero();
|
||||||
|
|
||||||
|
profitCenterHash[accountName] = profitCenterHash[accountName].add(
|
||||||
|
Dinero(job.job_totals.parts.adjustments[key])
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
CdkBase.createLogEvent(
|
||||||
|
socket,
|
||||||
|
"ERROR",
|
||||||
|
`Error encountered in CdkCalculateAllocations. Unable to find adjustment account. ${error}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const jobAllocations = _.union(
|
const jobAllocations = _.union(
|
||||||
Object.keys(profitCenterHash),
|
Object.keys(profitCenterHash),
|
||||||
Object.keys(costCenterHash)
|
Object.keys(costCenterHash)
|
||||||
|
|||||||
@@ -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,34 +392,56 @@ 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.
|
||||||
let matTotalLine = job.cieca_stl.data.find((l) => l.ttl_typecd === "MAT");
|
let matTotalLine = job.cieca_stl?.data?.find((l) => l.ttl_typecd === "MAT");
|
||||||
let shopMatLine = job.cieca_stl.data.find((l) => l.ttl_typecd === "MASH");
|
let shopMatLine = job.cieca_stl?.data?.find((l) => l.ttl_typecd === "MASH");
|
||||||
|
|
||||||
if (matTotalLine && shopMatLine) {
|
if (matTotalLine && shopMatLine) {
|
||||||
//Check to see if theyre different
|
//Check to see if theyre different
|
||||||
@@ -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,26 @@ 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 +535,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),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -600,36 +596,29 @@ function CalculatePartsTotals(jobLines, parts_tax_rates) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
//Apply insurance based parts discuounts/markups.
|
//Apply insurance based parts discounts/markups.
|
||||||
let adjustments = {
|
let adjustments = {};
|
||||||
PAA: Dinero(),
|
//Track all adjustments that need to be made.
|
||||||
PAC: Dinero(),
|
|
||||||
PAG: Dinero(),
|
const linesToAdjustForDiscount = [];
|
||||||
PAL: Dinero(),
|
|
||||||
PAN: Dinero(),
|
|
||||||
PAO: Dinero(),
|
|
||||||
PAP: Dinero(),
|
|
||||||
PAR: Dinero(),
|
|
||||||
PAS: Dinero(),
|
|
||||||
PAT: Dinero(),
|
|
||||||
};
|
|
||||||
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 +627,33 @@ 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);
|
const correspondingCiecaStlTotalLine = job.cieca_stl?.data.find(
|
||||||
adjustments[key] = adjustment;
|
(c) => c.ttl_typecd === key
|
||||||
});
|
);
|
||||||
|
|
||||||
//Temporarily commenting this out since these totals appear to be already included in the calculation.
|
//If the difference is greater than a penny, fix it.
|
||||||
// Object.keys(adjustments).forEach((key) => {
|
//This usually ties into whether or not the profile has part type discounts overall in the PFP.
|
||||||
// if (ret.parts.list[key] !== undefined) {
|
if (
|
||||||
// ret.parts.list[key].total = ret.parts.list[key].total.add(
|
correspondingCiecaStlTotalLine &&
|
||||||
// adjustments[key]
|
Math.abs(
|
||||||
// );
|
ret.parts.list[key]?.total.getAmount() -
|
||||||
// ret.parts.subtotal = ret.parts.subtotal.add(adjustments[key]);
|
correspondingCiecaStlTotalLine.ttl_amt * 100
|
||||||
// }
|
) > 1
|
||||||
// });
|
) {
|
||||||
|
let adjustment = disc.add(markup);
|
||||||
|
adjustments[key] = adjustment;
|
||||||
|
ret.parts.subtotal = ret.parts.subtotal.add(adjustment);
|
||||||
|
ret.parts.total = ret.parts.total.add(adjustment);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
adjustments,
|
adjustments,
|
||||||
@@ -691,6 +687,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 +700,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 +729,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 +741,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 +751,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 +767,288 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
job.parts_tax_rates.PAGQ ||
|
job.parts_tax_rates.PAGQ ||
|
||||||
job.parts_tax_rates.PAGR);
|
job.parts_tax_rates.PAGR);
|
||||||
|
|
||||||
|
const taxableAmounts = {
|
||||||
|
PAA: Dinero(),
|
||||||
|
PAN: Dinero(),
|
||||||
|
PAL: Dinero(),
|
||||||
|
PAR: Dinero(),
|
||||||
|
PAC: Dinero(),
|
||||||
|
PAG: Dinero(),
|
||||||
|
PAO: Dinero(),
|
||||||
|
PAS: Dinero(),
|
||||||
|
PAP: Dinero(),
|
||||||
|
PAM: Dinero(),
|
||||||
|
|
||||||
|
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(),
|
||||||
|
};
|
||||||
|
|
||||||
|
//For each line, determine if it's taxable, and if it is, add the line amount to the taxable amounts total.
|
||||||
job.joblines
|
job.joblines
|
||||||
.filter((jl) => !jl.removed)
|
.filter((jl) => !jl.removed)
|
||||||
.forEach((val) => {
|
.forEach((val) => {
|
||||||
if (!val.tax_part) return;
|
if (!val.tax_part) return;
|
||||||
if (!val.part_type && IsAdditionalCost(val)) {
|
if (!val.part_type && IsAdditionalCost(val)) {
|
||||||
additionalItemsTax = additionalItemsTax.add(
|
taxableAmounts.PAO = taxableAmounts.PAO.add(
|
||||||
Dinero({ amount: Math.round((val.act_price || 0) * 100) })
|
Dinero({ amount: Math.round((val.act_price || 0) * 100) }).multiply(
|
||||||
.multiply(val.part_qty || 0)
|
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 if (!val.part_type) {
|
||||||
|
//Do nothing for now.
|
||||||
} else {
|
} else {
|
||||||
statePartsTax = statePartsTax.add(
|
const typeOfPart = val.part_type;
|
||||||
Dinero({ amount: Math.round((val.act_price || 0) * 100) })
|
|
||||||
.multiply(val.part_qty || 0)
|
const discMarkupAmount =
|
||||||
.add(
|
val.prt_dsmk_m &&
|
||||||
val.prt_dsmk_m &&
|
val.prt_dsmk_m !== 0 &&
|
||||||
val.prt_dsmk_m !== 0 &&
|
DiscountNotAlreadyCounted(val, job.joblines) // DO WE NEED TO COUNT PFP DISCOUNT HERE?
|
||||||
DiscountNotAlreadyCounted(val, job.joblines)
|
? val.prt_dsmk_m
|
||||||
? val.prt_dsmk_m
|
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
||||||
? Dinero({ amount: Math.round(val.prt_dsmk_m * 100) })
|
: Dinero({
|
||||||
: Dinero({
|
amount: Math.round(val.act_price * 100),
|
||||||
amount: Math.round(val.act_price * 100),
|
})
|
||||||
})
|
.multiply(val.part_qty || 0)
|
||||||
.multiply(val.part_qty || 0)
|
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
||||||
.percentage(Math.abs(val.prt_dsmk_p || 0))
|
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
||||||
.multiply(val.prt_dsmk_p > 0 ? 1 : -1)
|
: Dinero();
|
||||||
: Dinero()
|
|
||||||
)
|
const partAmount = Dinero({
|
||||||
.percentage(
|
amount: Math.round((val.act_price || 0) * 100),
|
||||||
((job.parts_tax_rates &&
|
})
|
||||||
job.parts_tax_rates[val.part_type] &&
|
.multiply(val.part_qty || 0)
|
||||||
job.parts_tax_rates[val.part_type].prt_tax_rt) ||
|
.add(discMarkupAmount);
|
||||||
(val.part_type &&
|
taxableAmounts[typeOfPart] = taxableAmounts[typeOfPart].add(partAmount);
|
||||||
val.part_type.startsWith("PAG") &&
|
}
|
||||||
BackupGlassTax &&
|
});
|
||||||
BackupGlassTax.prt_tax_rt) ||
|
|
||||||
(!val.part_type &&
|
//Check in the PFL file which types of labor are taxable. Add the amount that is considered taxable to the taxable amounts total.
|
||||||
val.db_ref === "900510" &&
|
Object.keys(taxableAmounts)
|
||||||
job.parts_tax_rates["PAN"] &&
|
.filter((key) => key.startsWith("LA"))
|
||||||
job.parts_tax_rates["PAN"].prt_tax_rt) ||
|
.map((key) => {
|
||||||
0) * 100
|
const isLaborTypeTaxable = job.cieca_pfl[key]?.lbr_tax_in;
|
||||||
)
|
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),
|
||||||
|
});
|
||||||
|
|
||||||
|
const pfp = job.parts_tax_rates;
|
||||||
|
|
||||||
|
//For any profile level markups/discounts, add them in now as well.
|
||||||
|
Object.keys(otherTotals.parts.adjustments).forEach((key) => {
|
||||||
|
const adjustmentAmount = otherTotals.parts.adjustments[key];
|
||||||
|
if (adjustmentAmount.getAmount() !== 0 && pfp[key]?.prt_tax_in) {
|
||||||
|
taxableAmounts[key] = taxableAmounts[key].add(adjustmentAmount);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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 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());
|
||||||
|
|
||||||
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 +1059,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,34 +1097,7 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
exports.default = Totals;
|
exports.default = Totals;
|
||||||
|
|
||||||
function DiscountNotAlreadyCounted(jobline, joblines) {
|
function DiscountNotAlreadyCounted(jobline, joblines) {
|
||||||
//CCC already factors in the discount. If the difference between the 2 is exactly the discount, it's all good.
|
return false;
|
||||||
if (
|
|
||||||
Math.round(
|
|
||||||
(jobline.prt_dsmk_m / (jobline.act_price - jobline.prt_dsmk_m)) * 100
|
|
||||||
) === Math.abs(jobline.prt_dsmk_p)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Check it against the database price too? If it's an OE part.
|
|
||||||
if (
|
|
||||||
Math.abs(jobline.db_price - jobline.act_price) -
|
|
||||||
Math.abs(jobline.prt_dsmk_m) <
|
|
||||||
0.01
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
//If it's not a discount line, then it definitely hasn't been counted yet.
|
|
||||||
jobline.db_ref !== "900510" &&
|
|
||||||
jobline.db_ref !== "900511"
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
const ParentLine = joblines.find((j) => j.unq_seq === jobline.line_ref);
|
|
||||||
|
|
||||||
return ParentLine && !(ParentLine.prt_dsmk_m && ParentLine.prt_dsmk_m !== 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.DiscountNotAlreadyCounted = DiscountNotAlreadyCounted;
|
exports.DiscountNotAlreadyCounted = DiscountNotAlreadyCounted;
|
||||||
@@ -964,3 +1106,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