IO-3178 Flat Rate ATS
Signed-off-by: Allan Carr <allan.carr@thinkimex.com>
This commit is contained in:
@@ -5,6 +5,7 @@ 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 InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||||
import CABCpvrtCalculator from "../ca-bc-pvrt-calculator/ca-bc-pvrt-calculator.component";
|
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";
|
||||||
@@ -14,9 +15,8 @@ import JobsDetailRatesLabor from "./jobs-detail-rates.labor.component";
|
|||||||
import JobsDetailRatesMaterials from "./jobs-detail-rates.materials.component";
|
import JobsDetailRatesMaterials from "./jobs-detail-rates.materials.component";
|
||||||
import JobsDetailRatesOther from "./jobs-detail-rates.other.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";
|
import JobsDetailRatesProfileOVerride from "./jobs-detail-rates.profile-override.component";
|
||||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
import JobsDetailRatesTaxes from "./jobs-detail-rates.taxes.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
jobRO: selectJobReadOnly,
|
jobRO: selectJobReadOnly,
|
||||||
@@ -66,14 +66,48 @@ export function JobsDetailRates({ jobRO, form, job, bodyshop }) {
|
|||||||
</Space>
|
</Space>
|
||||||
)}
|
)}
|
||||||
<Form.Item label={t("jobs.fields.auto_add_ats")} name="auto_add_ats" valuePropName="checked">
|
<Form.Item label={t("jobs.fields.auto_add_ats")} name="auto_add_ats" valuePropName="checked">
|
||||||
<Switch disabled={jobRO} />
|
<Switch
|
||||||
|
disabled={jobRO}
|
||||||
|
onChange={(checked) => {
|
||||||
|
if (checked) {
|
||||||
|
form.setFieldsValue({ flat_rate_ats: false });
|
||||||
|
form.setFieldsValue({ rate_ats: form.getFieldValue('rate_ats') || bodyshop.shoprates.rate_ats });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item noStyle shouldUpdate={(prev, cur) => prev.auto_add_ats !== cur.auto_add_ats}>
|
<Form.Item noStyle shouldUpdate={(prev, cur) => prev.auto_add_ats !== cur.auto_add_ats}>
|
||||||
{() => {
|
{() => {
|
||||||
if (form.getFieldValue("auto_add_ats"))
|
if (form.getFieldValue("auto_add_ats"))
|
||||||
return (
|
return (
|
||||||
<Form.Item label={t("jobs.fields.rate_ats")} name="rate_ats" initialValue={bodyshop.shoprates.rate_atp}>
|
<Form.Item label={t("jobs.fields.rate_ats")} name="rate_ats">
|
||||||
|
<CurrencyInput disabled={jobRO} />
|
||||||
|
</Form.Item>
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("jobs.fields.flat_rate_ats")} name="flat_rate_ats" valuePropName="checked">
|
||||||
|
<Switch
|
||||||
|
disabled={jobRO}
|
||||||
|
onChange={(checked) => {
|
||||||
|
if (checked) {
|
||||||
|
form.setFieldsValue({ auto_add_ats: false });
|
||||||
|
form.setFieldsValue({ rate_ats_flat: form.getFieldValue('rate_ats_flat') || bodyshop.shoprates.rate_ats_flat });
|
||||||
|
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item noStyle shouldUpdate={(prev, cur) => prev.flat_rate_ats !== cur.flat_rate_ats}>
|
||||||
|
{() => {
|
||||||
|
if (form.getFieldValue("flat_rate_ats"))
|
||||||
|
return (
|
||||||
|
<Form.Item
|
||||||
|
label={t("jobs.fields.rate_ats_flat")}
|
||||||
|
name="rate_ats_flat"
|
||||||
|
>
|
||||||
<CurrencyInput disabled={jobRO} />
|
<CurrencyInput disabled={jobRO} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { DeleteFilled } from "@ant-design/icons";
|
import { DeleteFilled } from "@ant-design/icons";
|
||||||
import { Button, Form, Input } from "antd";
|
import { Button, Form, Input, Space } from "antd";
|
||||||
import React from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
||||||
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
|
||||||
@@ -10,326 +9,338 @@ export default function ShopInfoLaborRates({ form }) {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<Form.List name={["md_labor_rates"]}>
|
<LayoutFormRow header={t("bodyshop.labels.shoprates")}>
|
||||||
{(fields, { add, remove, move }) => {
|
<Form.Item label={t("jobs.fields.rate_ats")} name={["shoprates", "rate_ats"]}>
|
||||||
return (
|
<CurrencyInput min={0} />
|
||||||
<div>
|
</Form.Item>
|
||||||
{fields.map((field, index) => (
|
<Form.Item label={t("jobs.fields.rate_ats_flat")} name={["shoprates", "rate_ats_flat"]}>
|
||||||
<Form.Item key={field.key}>
|
<CurrencyInput min={0} />
|
||||||
<LayoutFormRow>
|
</Form.Item>
|
||||||
<Form.Item
|
</LayoutFormRow>
|
||||||
label={t("jobs.fields.labor_rate_desc")}
|
<LayoutFormRow header={t("bodyshop.labels.laborrates")}>
|
||||||
key={`${index}rate_label`}
|
<Form.List name={["md_labor_rates"]}>
|
||||||
name={[field.name, "rate_label"]}
|
{(fields, { add, remove, move }) => {
|
||||||
rules={[
|
return (
|
||||||
{
|
<div>
|
||||||
required: true
|
{fields.map((field, index) => (
|
||||||
//message: t("general.validation.required"),
|
<Form.Item key={field.key}>
|
||||||
}
|
<LayoutFormRow noDivider={index === 0}>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.labor_rate_desc")}
|
||||||
<Input />
|
key={`${index}rate_label`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_label"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_laa")}
|
{
|
||||||
key={`${index}rate_laa`}
|
required: true
|
||||||
name={[field.name, "rate_laa"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<Input />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_laa")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_laa`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_laa"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_lab")}
|
{
|
||||||
key={`${index}rate_lab`}
|
required: true
|
||||||
name={[field.name, "rate_lab"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_lab")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_lab`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_lab"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_lad")}
|
{
|
||||||
key={`${index}rate_lad`}
|
required: true
|
||||||
name={[field.name, "rate_lad"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_lad")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_lad`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_lad"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_lae")}
|
{
|
||||||
key={`${index}rate_lae`}
|
required: true
|
||||||
name={[field.name, "rate_lae"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_lae")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_lae`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_lae"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_laf")}
|
{
|
||||||
key={`${index}rate_laf`}
|
required: true
|
||||||
name={[field.name, "rate_laf"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_laf")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_laf`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_laf"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_lag")}
|
{
|
||||||
key={`${index}rate_lag`}
|
required: true
|
||||||
name={[field.name, "rate_lag"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_lag")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_lag`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_lag"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_lam")}
|
{
|
||||||
key={`${index}rate_lam`}
|
required: true
|
||||||
name={[field.name, "rate_lam"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_lam")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_lam`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_lam"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_lar")}
|
{
|
||||||
key={`${index}rate_lar`}
|
required: true
|
||||||
name={[field.name, "rate_lar"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_lar")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_lar`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_lar"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_las")}
|
{
|
||||||
key={`${index}rate_las`}
|
required: true
|
||||||
name={[field.name, "rate_las"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_las")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_las`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_las"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_la1")}
|
{
|
||||||
key={`${index}rate_la1`}
|
required: true
|
||||||
name={[field.name, "rate_la1"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_la1")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_la1`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_la1"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_la2")}
|
{
|
||||||
key={`${index}rate_la2`}
|
required: true
|
||||||
name={[field.name, "rate_la2"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_la2")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_la2`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_la2"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_la3")}
|
{
|
||||||
key={`${index}rate_la3`}
|
required: true
|
||||||
name={[field.name, "rate_la3"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_la3")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_la3`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_la3"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_la4")}
|
{
|
||||||
key={`${index}rate_la4`}
|
required: true
|
||||||
name={[field.name, "rate_la4"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_la4")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_la4`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_la4"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_mash")}
|
{
|
||||||
key={`${index}rate_mash`}
|
required: true
|
||||||
name={[field.name, "rate_mash"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_mash")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_mash`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_mash"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_mapa")}
|
{
|
||||||
key={`${index}rate_mapa`}
|
required: true
|
||||||
name={[field.name, "rate_mapa"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_mapa")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_mapa`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_mapa"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_ma2s")}
|
{
|
||||||
key={`${index}rate_ma2s`}
|
required: true
|
||||||
name={[field.name, "rate_ma2s"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_ma2s")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_ma2s`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_ma2s"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_ma3s")}
|
{
|
||||||
key={`${index}rate_ma3s`}
|
required: true
|
||||||
name={[field.name, "rate_ma3s"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_ma3s")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_ma3s`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_ma3s"]}
|
||||||
{
|
rules={[
|
||||||
// <Form.Item
|
{
|
||||||
// label={t("jobs.fields.rate_mabl")}
|
required: true
|
||||||
// key={`${index}rate_mabl`}
|
//message: t("general.validation.required"),
|
||||||
// name={[field.name, "rate_mabl"]}
|
}
|
||||||
// rules={[
|
]}
|
||||||
// {
|
>
|
||||||
// required: true,
|
<CurrencyInput min={0} />
|
||||||
// //message: t("general.validation.required"),
|
</Form.Item>
|
||||||
// },
|
{
|
||||||
// ]}
|
// <Form.Item
|
||||||
// >
|
// label={t("jobs.fields.rate_mabl")}
|
||||||
// <CurrencyInput min={0} />
|
// key={`${index}rate_mabl`}
|
||||||
// </Form.Item>
|
// name={[field.name, "rate_mabl"]}
|
||||||
// <Form.Item
|
// rules={[
|
||||||
// label={t("jobs.fields.rate_macs")}
|
// {
|
||||||
// key={`${index}rate_macs`}
|
// required: true,
|
||||||
// name={[field.name, "rate_macs"]}
|
// //message: t("general.validation.required"),
|
||||||
// rules={[
|
// },
|
||||||
// {
|
// ]}
|
||||||
// required: true,
|
// >
|
||||||
// //message: t("general.validation.required"),
|
// <CurrencyInput min={0} />
|
||||||
// },
|
// </Form.Item>
|
||||||
// ]}
|
// <Form.Item
|
||||||
// >
|
// label={t("jobs.fields.rate_macs")}
|
||||||
// <CurrencyInput min={0} />
|
// key={`${index}rate_macs`}
|
||||||
// </Form.Item>
|
// name={[field.name, "rate_macs"]}
|
||||||
}
|
// rules={[
|
||||||
<Form.Item
|
// {
|
||||||
label={t("jobs.fields.rate_matd")}
|
// required: true,
|
||||||
key={`${index}rate_matd`}
|
// //message: t("general.validation.required"),
|
||||||
name={[field.name, "rate_matd"]}
|
// },
|
||||||
rules={[
|
// ]}
|
||||||
{
|
// >
|
||||||
required: true
|
// <CurrencyInput min={0} />
|
||||||
//message: t("general.validation.required"),
|
// </Form.Item>
|
||||||
}
|
}
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_matd")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_matd`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_matd"]}
|
||||||
<Form.Item
|
rules={[
|
||||||
label={t("jobs.fields.rate_mahw")}
|
{
|
||||||
key={`${index}rate_mahw`}
|
required: true
|
||||||
name={[field.name, "rate_mahw"]}
|
//message: t("general.validation.required"),
|
||||||
rules={[
|
}
|
||||||
{
|
]}
|
||||||
required: true
|
>
|
||||||
//message: t("general.validation.required"),
|
<CurrencyInput min={0} />
|
||||||
}
|
</Form.Item>
|
||||||
]}
|
<Form.Item
|
||||||
>
|
label={t("jobs.fields.rate_mahw")}
|
||||||
<CurrencyInput min={0} />
|
key={`${index}rate_mahw`}
|
||||||
</Form.Item>
|
name={[field.name, "rate_mahw"]}
|
||||||
<DeleteFilled
|
rules={[
|
||||||
onClick={() => {
|
{
|
||||||
remove(field.name);
|
required: true
|
||||||
}}
|
//message: t("general.validation.required"),
|
||||||
/>
|
}
|
||||||
<FormListMoveArrows move={move} index={index} total={fields.rate_length} />
|
]}
|
||||||
</LayoutFormRow>
|
>
|
||||||
|
<CurrencyInput min={0} />
|
||||||
|
</Form.Item>
|
||||||
|
<Space>
|
||||||
|
<DeleteFilled
|
||||||
|
onClick={() => {
|
||||||
|
remove(field.name);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormListMoveArrows move={move} index={index} total={fields.rate_length} />
|
||||||
|
</Space>
|
||||||
|
</LayoutFormRow>
|
||||||
|
</Form.Item>
|
||||||
|
))}
|
||||||
|
<Form.Item>
|
||||||
|
<Button
|
||||||
|
type="dashed"
|
||||||
|
onClick={() => {
|
||||||
|
add();
|
||||||
|
}}
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
>
|
||||||
|
{t("bodyshop.actions.newlaborrate")}
|
||||||
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
))}
|
</div>
|
||||||
<Form.Item>
|
);
|
||||||
<Button
|
}}
|
||||||
type="dashed"
|
</Form.List>
|
||||||
onClick={() => {
|
</LayoutFormRow>
|
||||||
add();
|
</>
|
||||||
}}
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
>
|
|
||||||
{t("bodyshop.actions.newlaborrate")}
|
|
||||||
</Button>
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Form.List>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -509,6 +509,7 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
est_ct_ln
|
est_ct_ln
|
||||||
est_ea
|
est_ea
|
||||||
est_ph1
|
est_ph1
|
||||||
|
flat_rate_ats
|
||||||
federal_tax_rate
|
federal_tax_rate
|
||||||
id
|
id
|
||||||
inproduction
|
inproduction
|
||||||
@@ -649,6 +650,7 @@ export const GET_JOB_BY_PK = gql`
|
|||||||
policy_no
|
policy_no
|
||||||
production_vars
|
production_vars
|
||||||
rate_ats
|
rate_ats
|
||||||
|
rate_ats_flat
|
||||||
rate_la1
|
rate_la1
|
||||||
rate_la2
|
rate_la2
|
||||||
rate_la3
|
rate_la3
|
||||||
|
|||||||
@@ -722,6 +722,7 @@
|
|||||||
"scoreboardsetup": "Scoreboard Setup",
|
"scoreboardsetup": "Scoreboard Setup",
|
||||||
"shop_enabled_features": "Shop Enabled Features",
|
"shop_enabled_features": "Shop Enabled Features",
|
||||||
"shopinfo": "Shop Information",
|
"shopinfo": "Shop Information",
|
||||||
|
"shoprates": "Shop Rates",
|
||||||
"speedprint": "Speed Print Configuration",
|
"speedprint": "Speed Print Configuration",
|
||||||
"ssbuckets": "Job Size Definitions",
|
"ssbuckets": "Job Size Definitions",
|
||||||
"systemsettings": "System Settings",
|
"systemsettings": "System Settings",
|
||||||
@@ -1658,7 +1659,7 @@
|
|||||||
"08": "Left Rear Side",
|
"08": "Left Rear Side",
|
||||||
"09": "Left Side"
|
"09": "Left Side"
|
||||||
},
|
},
|
||||||
"auto_add_ats": "Automatically Add/Update ATS",
|
"auto_add_ats": "Automatically Add/Update ATS?",
|
||||||
"ca_bc_pvrt": "PVRT",
|
"ca_bc_pvrt": "PVRT",
|
||||||
"ca_customer_gst": "Customer Portion of GST",
|
"ca_customer_gst": "Customer Portion of GST",
|
||||||
"ca_gst_registrant": "GST Registrant",
|
"ca_gst_registrant": "GST Registrant",
|
||||||
@@ -1757,6 +1758,7 @@
|
|||||||
"est_ct_ln": "Estimator Last Name",
|
"est_ct_ln": "Estimator Last Name",
|
||||||
"est_ea": "Estimator Email",
|
"est_ea": "Estimator Email",
|
||||||
"est_ph1": "Estimator Phone #",
|
"est_ph1": "Estimator Phone #",
|
||||||
|
"flat_rate_ats": "Flat Rate ATS?",
|
||||||
"federal_tax_payable": "Federal Tax Payable",
|
"federal_tax_payable": "Federal Tax Payable",
|
||||||
"federal_tax_rate": "Federal Tax Rate",
|
"federal_tax_rate": "Federal Tax Rate",
|
||||||
"ins_addr1": "Insurance Co. Address",
|
"ins_addr1": "Insurance Co. Address",
|
||||||
@@ -1868,6 +1870,7 @@
|
|||||||
},
|
},
|
||||||
"queued_for_parts": "Queued for Parts",
|
"queued_for_parts": "Queued for Parts",
|
||||||
"rate_ats": "ATS Rate",
|
"rate_ats": "ATS Rate",
|
||||||
|
"rate_ats_flat": "ATS Flat Rate",
|
||||||
"rate_la1": "LA1",
|
"rate_la1": "LA1",
|
||||||
"rate_la2": "LA2",
|
"rate_la2": "LA2",
|
||||||
"rate_la3": "LA3",
|
"rate_la3": "LA3",
|
||||||
|
|||||||
@@ -722,6 +722,7 @@
|
|||||||
"scoreboardsetup": "",
|
"scoreboardsetup": "",
|
||||||
"shop_enabled_features": "",
|
"shop_enabled_features": "",
|
||||||
"shopinfo": "",
|
"shopinfo": "",
|
||||||
|
"shoprates": "",
|
||||||
"speedprint": "",
|
"speedprint": "",
|
||||||
"ssbuckets": "",
|
"ssbuckets": "",
|
||||||
"systemsettings": "",
|
"systemsettings": "",
|
||||||
@@ -1757,6 +1758,7 @@
|
|||||||
"est_ct_ln": "Apellido del tasador",
|
"est_ct_ln": "Apellido del tasador",
|
||||||
"est_ea": "Correo electrónico del tasador",
|
"est_ea": "Correo electrónico del tasador",
|
||||||
"est_ph1": "Número de teléfono del tasador",
|
"est_ph1": "Número de teléfono del tasador",
|
||||||
|
"flat_rate_ats": "",
|
||||||
"federal_tax_payable": "Impuesto federal por pagar",
|
"federal_tax_payable": "Impuesto federal por pagar",
|
||||||
"federal_tax_rate": "",
|
"federal_tax_rate": "",
|
||||||
"ins_addr1": "Dirección de Insurance Co.",
|
"ins_addr1": "Dirección de Insurance Co.",
|
||||||
@@ -1868,6 +1870,7 @@
|
|||||||
},
|
},
|
||||||
"queued_for_parts": "",
|
"queued_for_parts": "",
|
||||||
"rate_ats": "",
|
"rate_ats": "",
|
||||||
|
"rate_ats_flat": "",
|
||||||
"rate_la1": "Tarifa LA1",
|
"rate_la1": "Tarifa LA1",
|
||||||
"rate_la2": "Tarifa LA2",
|
"rate_la2": "Tarifa LA2",
|
||||||
"rate_la3": "Tarifa LA3",
|
"rate_la3": "Tarifa LA3",
|
||||||
|
|||||||
@@ -722,6 +722,7 @@
|
|||||||
"scoreboardsetup": "",
|
"scoreboardsetup": "",
|
||||||
"shop_enabled_features": "",
|
"shop_enabled_features": "",
|
||||||
"shopinfo": "",
|
"shopinfo": "",
|
||||||
|
"shoprates": "",
|
||||||
"speedprint": "",
|
"speedprint": "",
|
||||||
"ssbuckets": "",
|
"ssbuckets": "",
|
||||||
"systemsettings": "",
|
"systemsettings": "",
|
||||||
@@ -1757,6 +1758,7 @@
|
|||||||
"est_ct_ln": "Nom de l'évaluateur",
|
"est_ct_ln": "Nom de l'évaluateur",
|
||||||
"est_ea": "Courriel de l'évaluateur",
|
"est_ea": "Courriel de l'évaluateur",
|
||||||
"est_ph1": "Numéro de téléphone de l'évaluateur",
|
"est_ph1": "Numéro de téléphone de l'évaluateur",
|
||||||
|
"flat_rate_ats": "",
|
||||||
"federal_tax_payable": "Impôt fédéral à payer",
|
"federal_tax_payable": "Impôt fédéral à payer",
|
||||||
"federal_tax_rate": "",
|
"federal_tax_rate": "",
|
||||||
"ins_addr1": "Adresse Insurance Co.",
|
"ins_addr1": "Adresse Insurance Co.",
|
||||||
@@ -1868,6 +1870,7 @@
|
|||||||
},
|
},
|
||||||
"queued_for_parts": "",
|
"queued_for_parts": "",
|
||||||
"rate_ats": "",
|
"rate_ats": "",
|
||||||
|
"rate_ats_flat": "",
|
||||||
"rate_la1": "Taux LA1",
|
"rate_la1": "Taux LA1",
|
||||||
"rate_la2": "Taux LA2",
|
"rate_la2": "Taux LA2",
|
||||||
"rate_la3": "Taux LA3",
|
"rate_la3": "Taux LA3",
|
||||||
|
|||||||
@@ -3695,6 +3695,7 @@
|
|||||||
- est_st
|
- est_st
|
||||||
- est_zip
|
- est_zip
|
||||||
- federal_tax_rate
|
- federal_tax_rate
|
||||||
|
- flat_rate_ats
|
||||||
- g_bett_amt
|
- g_bett_amt
|
||||||
- id
|
- id
|
||||||
- inproduction
|
- inproduction
|
||||||
@@ -3789,6 +3790,7 @@
|
|||||||
- qb_multiple_payers
|
- qb_multiple_payers
|
||||||
- queued_for_parts
|
- queued_for_parts
|
||||||
- rate_ats
|
- rate_ats
|
||||||
|
- rate_ats_flat
|
||||||
- rate_la1
|
- rate_la1
|
||||||
- rate_la2
|
- rate_la2
|
||||||
- rate_la3
|
- rate_la3
|
||||||
@@ -3965,6 +3967,7 @@
|
|||||||
- est_st
|
- est_st
|
||||||
- est_zip
|
- est_zip
|
||||||
- federal_tax_rate
|
- federal_tax_rate
|
||||||
|
- flat_rate_ats
|
||||||
- g_bett_amt
|
- g_bett_amt
|
||||||
- id
|
- id
|
||||||
- inproduction
|
- inproduction
|
||||||
@@ -4060,6 +4063,7 @@
|
|||||||
- qb_multiple_payers
|
- qb_multiple_payers
|
||||||
- queued_for_parts
|
- queued_for_parts
|
||||||
- rate_ats
|
- rate_ats
|
||||||
|
- rate_ats_flat
|
||||||
- rate_la1
|
- rate_la1
|
||||||
- rate_la2
|
- rate_la2
|
||||||
- rate_la3
|
- rate_la3
|
||||||
@@ -4247,6 +4251,7 @@
|
|||||||
- est_st
|
- est_st
|
||||||
- est_zip
|
- est_zip
|
||||||
- federal_tax_rate
|
- federal_tax_rate
|
||||||
|
- flat_rate_ats
|
||||||
- g_bett_amt
|
- g_bett_amt
|
||||||
- id
|
- id
|
||||||
- inproduction
|
- inproduction
|
||||||
@@ -4342,6 +4347,7 @@
|
|||||||
- qb_multiple_payers
|
- qb_multiple_payers
|
||||||
- queued_for_parts
|
- queued_for_parts
|
||||||
- rate_ats
|
- rate_ats
|
||||||
|
- rate_ats_flat
|
||||||
- rate_la1
|
- rate_la1
|
||||||
- rate_la2
|
- rate_la2
|
||||||
- rate_la3
|
- rate_la3
|
||||||
|
|||||||
@@ -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 "flat_rate_ats" boolean
|
||||||
|
-- null default 'false';
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."jobs" add column "flat_rate_ats" boolean
|
||||||
|
null default 'false';
|
||||||
@@ -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 "rate_ats_flat" numeric
|
||||||
|
-- null;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
alter table "public"."jobs" add column "rate_ats_flat" numeric
|
||||||
|
null;
|
||||||
@@ -1485,6 +1485,8 @@ exports.GET_JOB_BY_PK = `query GET_JOB_BY_PK($id: uuid!) {
|
|||||||
materials
|
materials
|
||||||
auto_add_ats
|
auto_add_ats
|
||||||
rate_ats
|
rate_ats
|
||||||
|
flat_rate_ats
|
||||||
|
rate_ats_flat
|
||||||
joblines(where: { removed: { _eq: false } }){
|
joblines(where: { removed: { _eq: false } }){
|
||||||
id
|
id
|
||||||
line_no
|
line_no
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const Dinero = require("dinero.js");
|
const Dinero = require("dinero.js");
|
||||||
const queries = require("../graphql-client/queries");
|
const queries = require("../graphql-client/queries");
|
||||||
const adminClient = require("../graphql-client/graphql-client").client;
|
// const adminClient = require("../graphql-client/graphql-client").client;
|
||||||
const _ = require("lodash");
|
// const _ = require("lodash");
|
||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
const InstanceMgr = require("../utils/instanceMgr").default;
|
const InstanceMgr = require("../utils/instanceMgr").default;
|
||||||
|
|
||||||
@@ -45,7 +45,9 @@ exports.totalsSsu = async function (req, res) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
res.status(200).send();
|
if (result) {
|
||||||
|
res.status(200).send();
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("job-totals-ssu-USA-error", "ERROR", req?.user?.email, id, {
|
logger.log("job-totals-ssu-USA-error", "ERROR", req?.user?.email, id, {
|
||||||
jobid: id,
|
jobid: id,
|
||||||
@@ -59,7 +61,7 @@ exports.totalsSsu = async function (req, res) {
|
|||||||
//IMPORTANT*** These two functions MUST be mirrrored.
|
//IMPORTANT*** These two functions MUST be mirrrored.
|
||||||
async function TotalsServerSide(req, res) {
|
async function TotalsServerSide(req, res) {
|
||||||
const { job, client } = req.body;
|
const { job, client } = req.body;
|
||||||
await AutoAddAtsIfRequired({ job: job, client: client });
|
await AtsAdjustmentsIfRequired({ job: job, client: client, user: req?.user });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let ret = {
|
let ret = {
|
||||||
@@ -137,11 +139,12 @@ async function Totals(req, res) {
|
|||||||
const logger = req.logger;
|
const logger = req.logger;
|
||||||
const client = req.userGraphQLClient;
|
const client = req.userGraphQLClient;
|
||||||
|
|
||||||
logger.log("job-totals-ssu-USA", "DEBUG", req.user.email, job.id, {
|
logger.log("job-totals-USA", "DEBUG", req.user.email, job.id, {
|
||||||
jobid: job.id
|
jobid: job.id,
|
||||||
|
id: id
|
||||||
});
|
});
|
||||||
|
|
||||||
await AutoAddAtsIfRequired({ job, client });
|
await AtsAdjustmentsIfRequired({ job, client, user: req.user });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let ret = {
|
let ret = {
|
||||||
@@ -162,40 +165,45 @@ async function Totals(req, res) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function AutoAddAtsIfRequired({ job, client }) {
|
async function AtsAdjustmentsIfRequired({ job, client, user }) {
|
||||||
//Check if ATS should be automatically added.
|
if (job.auto_add_ats || job.flat_rate_ats) {
|
||||||
if (job.auto_add_ats) {
|
let atsAmount = 0;
|
||||||
//Get the total sum of hours that should be the ATS amount.
|
|
||||||
//Check to see if an ATS line exists.
|
|
||||||
let atsLineIndex = null;
|
let atsLineIndex = null;
|
||||||
const atsHours = job.joblines.reduce((acc, val, index) => {
|
|
||||||
if (val.line_desc && val.line_desc.toLowerCase() === "ats amount") {
|
|
||||||
atsLineIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
//Check if ATS should be automatically added.
|
||||||
val.mod_lbr_ty !== "LA1" &&
|
if (job.auto_add_ats) {
|
||||||
val.mod_lbr_ty !== "LA2" &&
|
const excludedLaborTypes = new Set(["LAA", "LAG", "LAS", "LAU", "LA1", "LA2", "LA3", "LA4"]);
|
||||||
val.mod_lbr_ty !== "LA3" &&
|
|
||||||
val.mod_lbr_ty !== "LA4" &&
|
|
||||||
val.mod_lbr_ty !== "LAU" &&
|
|
||||||
val.mod_lbr_ty !== "LAG" &&
|
|
||||||
val.mod_lbr_ty !== "LAS" &&
|
|
||||||
val.mod_lbr_ty !== "LAA"
|
|
||||||
) {
|
|
||||||
acc = acc + val.mod_lb_hrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
//Get the total sum of hours that should be the ATS amount.
|
||||||
}, 0);
|
//Check to see if an ATS line exists.
|
||||||
|
const atsHours = job.joblines.reduce((acc, val, index) => {
|
||||||
|
if (val.line_desc?.toLowerCase() === "ats amount") {
|
||||||
|
atsLineIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
const atsAmount = atsHours * (job.rate_ats || 0);
|
if (!excludedLaborTypes.has(val.mod_lbr_ty)) {
|
||||||
//If it does, update it in place, and make sure it is updated for local calculations.
|
acc = acc + val.mod_lb_hrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
atsAmount = atsHours * (job.rate_ats || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if a Flat Rate ATS should be added.
|
||||||
|
if (job.flat_rate_ats) {
|
||||||
|
atsLineIndex = ((i) => (i === -1 ? null : i))(
|
||||||
|
job.joblines.findIndex((line) => line.line_desc?.toLowerCase() === "ats amount")
|
||||||
|
);
|
||||||
|
atsAmount = job.rate_ats_flat || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If it does not, create one for local calculations and insert it.
|
||||||
if (atsLineIndex === null) {
|
if (atsLineIndex === null) {
|
||||||
const newAtsLine = {
|
const newAtsLine = {
|
||||||
jobid: job.id,
|
jobid: job.id,
|
||||||
alt_partm: null,
|
alt_partm: null,
|
||||||
line_no: 35,
|
|
||||||
unq_seq: 0,
|
unq_seq: 0,
|
||||||
line_ind: "E",
|
line_ind: "E",
|
||||||
line_desc: "ATS Amount",
|
line_desc: "ATS Amount",
|
||||||
@@ -220,19 +228,40 @@ async function AutoAddAtsIfRequired({ job, client }) {
|
|||||||
prt_dsmk_m: 0.0
|
prt_dsmk_m: 0.0
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await client.request(queries.INSERT_NEW_JOB_LINE, {
|
try {
|
||||||
lineInput: [newAtsLine]
|
const result = await client.request(queries.INSERT_NEW_JOB_LINE, {
|
||||||
});
|
lineInput: [newAtsLine]
|
||||||
|
});
|
||||||
|
|
||||||
job.joblines.push(newAtsLine);
|
if (result) {
|
||||||
|
job.joblines.push(newAtsLine);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
|
||||||
|
jobid: job.id,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//If it does not, create one for local calculations and insert it.
|
//If it does, update it in place, and make sure it is updated for local calculations.
|
||||||
else {
|
else {
|
||||||
const result = await client.request(queries.UPDATE_JOB_LINE, {
|
try {
|
||||||
line: { act_price: atsAmount },
|
const result = await client.request(queries.UPDATE_JOB_LINE, {
|
||||||
lineId: job.joblines[atsLineIndex].id
|
line: { act_price: atsAmount },
|
||||||
});
|
lineId: job.joblines[atsLineIndex].id
|
||||||
job.joblines[atsLineIndex].act_price = atsAmount;
|
});
|
||||||
|
if (result) {
|
||||||
|
job.joblines[atsLineIndex].act_price = atsAmount;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
|
||||||
|
jobid: job.id,
|
||||||
|
atsLineIndex: atsLineIndex,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,7 +343,7 @@ async function CalculateRatesTotals({ job, client }) {
|
|||||||
let hasMashLine = false;
|
let hasMashLine = false;
|
||||||
let hasMahwLine = false;
|
let hasMahwLine = false;
|
||||||
let hasCustomMahwLine;
|
let hasCustomMahwLine;
|
||||||
let mapaOpCodes = ParseCalopCode(job.materials["MAPA"]?.cal_opcode);
|
// let mapaOpCodes = ParseCalopCode(job.materials["MAPA"]?.cal_opcode);
|
||||||
let mashOpCodes = ParseCalopCode(job.materials["MASH"]?.cal_opcode);
|
let mashOpCodes = ParseCalopCode(job.materials["MASH"]?.cal_opcode);
|
||||||
|
|
||||||
jobLines.forEach((item) => {
|
jobLines.forEach((item) => {
|
||||||
@@ -564,7 +593,7 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
if (!value.part_type && value.db_ref !== "900510" && value.db_ref !== "900511") return acc;
|
if (!value.part_type && value.db_ref !== "900510" && value.db_ref !== "900511") return acc;
|
||||||
|
|
||||||
const discountAmount =
|
const discountAmount =
|
||||||
@@ -631,6 +660,7 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -652,7 +682,7 @@ function CalculatePartsTotals(jobLines, parts_tax_rates, job) {
|
|||||||
let adjustments = {};
|
let adjustments = {};
|
||||||
//Track all adjustments that need to be made.
|
//Track all adjustments that need to be made.
|
||||||
|
|
||||||
const linesToAdjustForDiscount = [];
|
//const linesToAdjustForDiscount = [];
|
||||||
Object.keys(parts_tax_rates).forEach((key) => {
|
Object.keys(parts_tax_rates).forEach((key) => {
|
||||||
//Check if there's a discount or a mark up.
|
//Check if there's a discount or a mark up.
|
||||||
let disc = Dinero(),
|
let disc = Dinero(),
|
||||||
@@ -1019,7 +1049,9 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("job-totals-USA Key with issue", "error", null, job.id, {
|
logger.log("job-totals-USA Key with issue", "error", null, job.id, {
|
||||||
key
|
key: key,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1158,6 +1190,8 @@ function CalculateTaxesTotals(job, otherTotals) {
|
|||||||
exports.default = Totals;
|
exports.default = Totals;
|
||||||
|
|
||||||
function DiscountNotAlreadyCounted(jobline, joblines) {
|
function DiscountNotAlreadyCounted(jobline, joblines) {
|
||||||
|
void jobline;
|
||||||
|
void joblines;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1172,27 +1206,35 @@ function IsTrueOrYes(value) {
|
|||||||
return value === true || value === "Y" || value === "y";
|
return value === true || value === "Y" || value === "y";
|
||||||
}
|
}
|
||||||
|
|
||||||
async function UpdateJobLines(joblinesToUpdate) {
|
// Function not in use from RO to IO Merger 02/05/2024
|
||||||
if (joblinesToUpdate.length === 0) return;
|
// async function UpdateJobLines(joblinesToUpdate) {
|
||||||
const updateQueries = joblinesToUpdate.map((line, index) =>
|
// if (joblinesToUpdate.length === 0) return;
|
||||||
generateUpdateQuery(_.pick(line, ["id", "prt_dsmk_m", "prt_dsmk_p"]), index)
|
// const updateQueries = joblinesToUpdate.map((line, index) =>
|
||||||
);
|
// generateUpdateQuery(_.pick(line, ["id", "prt_dsmk_m", "prt_dsmk_p"]), index)
|
||||||
const query = `
|
// );
|
||||||
mutation UPDATE_EST_LINES{
|
// const query = `
|
||||||
${updateQueries}
|
// mutation UPDATE_EST_LINES{
|
||||||
}
|
// ${updateQueries}
|
||||||
`;
|
// }
|
||||||
|
// `;
|
||||||
|
// try {
|
||||||
|
// const result = await adminClient.request(query);
|
||||||
|
// void result;
|
||||||
|
// } catch (error) {
|
||||||
|
// logger.log("update-job-lines", "error", null, null, {
|
||||||
|
// error: error.message,
|
||||||
|
// stack: error.stack
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
const result = await adminClient.request(query);
|
// const generateUpdateQuery = (lineToUpdate, index) => {
|
||||||
}
|
// return `
|
||||||
|
// update_joblines${index}: update_joblines(where: { id: { _eq: "${
|
||||||
const generateUpdateQuery = (lineToUpdate, index) => {
|
// lineToUpdate.id
|
||||||
return `
|
// }" } }, _set: ${JSON.stringify(lineToUpdate).replace(/"(\w+)"\s*:/g, "$1:")}) {
|
||||||
update_joblines${index}: update_joblines(where: { id: { _eq: "${
|
// returning {
|
||||||
lineToUpdate.id
|
// id
|
||||||
}" } }, _set: ${JSON.stringify(lineToUpdate).replace(/"(\w+)"\s*:/g, "$1:")}) {
|
// }
|
||||||
returning {
|
// }`;
|
||||||
id
|
// };
|
||||||
}
|
|
||||||
}`;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
const Dinero = require("dinero.js");
|
const Dinero = require("dinero.js");
|
||||||
const queries = require("../graphql-client/queries");
|
const queries = require("../graphql-client/queries");
|
||||||
const adminClient = require("../graphql-client/graphql-client").client;
|
|
||||||
const _ = require("lodash");
|
|
||||||
const logger = require("../utils/logger");
|
const logger = require("../utils/logger");
|
||||||
|
|
||||||
//****************************************************** */
|
//****************************************************** */
|
||||||
@@ -44,11 +42,16 @@ exports.totalsSsu = async function (req, res) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
throw new Error("Failed to update job totals");
|
||||||
|
}
|
||||||
|
|
||||||
res.status(200).send();
|
res.status(200).send();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("job-totals-ssu-error", "ERROR", req.user.email, id, {
|
logger.log("job-totals-ssu-error", "ERROR", req.user.email, id, {
|
||||||
jobid: id,
|
jobid: id,
|
||||||
error
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
});
|
});
|
||||||
res.status(503).send();
|
res.status(503).send();
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,7 @@ exports.totalsSsu = async function (req, res) {
|
|||||||
//IMPORTANT*** These two functions MUST be mirrrored.
|
//IMPORTANT*** These two functions MUST be mirrrored.
|
||||||
async function TotalsServerSide(req, res) {
|
async function TotalsServerSide(req, res) {
|
||||||
const { job, client } = req.body;
|
const { job, client } = req.body;
|
||||||
await AutoAddAtsIfRequired({ job: job, client: client });
|
await AtsAdjustmentsIfRequired({ job: job, client: client, user: req?.user });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let ret = {
|
let ret = {
|
||||||
@@ -71,7 +74,8 @@ async function TotalsServerSide(req, res) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("job-totals-ssu-error", "ERROR", req?.user?.email, job.id, {
|
logger.log("job-totals-ssu-error", "ERROR", req?.user?.email, job.id, {
|
||||||
jobid: job.id,
|
jobid: job.id,
|
||||||
error
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
});
|
});
|
||||||
res.status(400).send(JSON.stringify(error));
|
res.status(400).send(JSON.stringify(error));
|
||||||
}
|
}
|
||||||
@@ -83,13 +87,12 @@ async function Totals(req, res) {
|
|||||||
const logger = req.logger;
|
const logger = req.logger;
|
||||||
const client = req.userGraphQLClient;
|
const client = req.userGraphQLClient;
|
||||||
|
|
||||||
logger.log("job-totals", "DEBUG", req.user.email, job.id, {
|
logger.log("job-totals-", "DEBUG", req.user.email, job.id, {
|
||||||
jobid: job.id
|
jobid: job.id,
|
||||||
|
id: id
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.log("job-totals-ssu", "DEBUG", req.user.email, id, null);
|
await AtsAdjustmentsIfRequired({ job, client, user: req.user });
|
||||||
|
|
||||||
await AutoAddAtsIfRequired({ job, client });
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let ret = {
|
let ret = {
|
||||||
@@ -103,46 +106,52 @@ async function Totals(req, res) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.log("job-totals-error", "ERROR", req.user.email, job.id, {
|
logger.log("job-totals-error", "ERROR", req.user.email, job.id, {
|
||||||
jobid: job.id,
|
jobid: job.id,
|
||||||
error
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
});
|
});
|
||||||
res.status(400).send(JSON.stringify(error));
|
res.status(400).send(JSON.stringify(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function AutoAddAtsIfRequired({ job, client }) {
|
async function AtsAdjustmentsIfRequired({ job, client, user }) {
|
||||||
//Check if ATS should be automatically added.
|
if (job.auto_add_ats || job.flat_rate_ats) {
|
||||||
if (job.auto_add_ats) {
|
let atsAmount = 0;
|
||||||
//Get the total sum of hours that should be the ATS amount.
|
|
||||||
//Check to see if an ATS line exists.
|
|
||||||
let atsLineIndex = null;
|
let atsLineIndex = null;
|
||||||
const atsHours = job.joblines.reduce((acc, val, index) => {
|
|
||||||
if (val.line_desc && val.line_desc.toLowerCase() === "ats amount") {
|
|
||||||
atsLineIndex = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
//Check if ATS should be automatically added.
|
||||||
val.mod_lbr_ty !== "LA1" &&
|
if (job.auto_add_ats) {
|
||||||
val.mod_lbr_ty !== "LA2" &&
|
const excludedLaborTypes = new Set(["LAA", "LAG", "LAS", "LAU", "LA1", "LA2", "LA3", "LA4"]);
|
||||||
val.mod_lbr_ty !== "LA3" &&
|
|
||||||
val.mod_lbr_ty !== "LA4" &&
|
|
||||||
val.mod_lbr_ty !== "LAU" &&
|
|
||||||
val.mod_lbr_ty !== "LAG" &&
|
|
||||||
val.mod_lbr_ty !== "LAS" &&
|
|
||||||
val.mod_lbr_ty !== "LAA"
|
|
||||||
) {
|
|
||||||
acc = acc + val.mod_lb_hrs;
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
//Get the total sum of hours that should be the ATS amount.
|
||||||
}, 0);
|
//Check to see if an ATS line exists.
|
||||||
|
const atsHours = job.joblines.reduce((acc, val, index) => {
|
||||||
|
if (val.line_desc?.toLowerCase() === "ats amount") {
|
||||||
|
atsLineIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
const atsAmount = atsHours * (job.rate_ats || 0);
|
if (!excludedLaborTypes.has(val.mod_lbr_ty)) {
|
||||||
//If it does, update it in place, and make sure it is updated for local calculations.
|
acc = acc + val.mod_lb_hrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
atsAmount = atsHours * (job.rate_ats || 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check if a Flat Rate ATS should be added.
|
||||||
|
if (job.flat_rate_ats) {
|
||||||
|
atsLineIndex = ((i) => (i === -1 ? null : i))(
|
||||||
|
job.joblines.findIndex((line) => line.line_desc?.toLowerCase() === "ats amount")
|
||||||
|
);
|
||||||
|
atsAmount = job.rate_ats_flat || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If it does not, create one for local calculations and insert it.
|
||||||
if (atsLineIndex === null) {
|
if (atsLineIndex === null) {
|
||||||
const newAtsLine = {
|
const newAtsLine = {
|
||||||
jobid: job.id,
|
jobid: job.id,
|
||||||
alt_partm: null,
|
alt_partm: null,
|
||||||
line_no: 35,
|
|
||||||
unq_seq: 0,
|
unq_seq: 0,
|
||||||
line_ind: "E",
|
line_ind: "E",
|
||||||
line_desc: "ATS Amount",
|
line_desc: "ATS Amount",
|
||||||
@@ -167,22 +176,41 @@ async function AutoAddAtsIfRequired({ job, client }) {
|
|||||||
prt_dsmk_m: 0.0
|
prt_dsmk_m: 0.0
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await client.request(queries.INSERT_NEW_JOB_LINE, {
|
try {
|
||||||
lineInput: [newAtsLine]
|
const result = await client.request(queries.INSERT_NEW_JOB_LINE, {
|
||||||
});
|
lineInput: [newAtsLine]
|
||||||
|
});
|
||||||
|
|
||||||
job.joblines.push(newAtsLine);
|
if (result) {
|
||||||
|
job.joblines.push(newAtsLine);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
|
||||||
|
jobid: job.id,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//If it does not, create one for local calculations and insert it.
|
//If it does, update it in place, and make sure it is updated for local calculations.
|
||||||
else {
|
else {
|
||||||
const result = await client.request(queries.UPDATE_JOB_LINE, {
|
try {
|
||||||
line: { act_price: atsAmount },
|
const result = await client.request(queries.UPDATE_JOB_LINE, {
|
||||||
lineId: job.joblines[atsLineIndex].id
|
line: { act_price: atsAmount },
|
||||||
});
|
lineId: job.joblines[atsLineIndex].id
|
||||||
job.joblines[atsLineIndex].act_price = atsAmount;
|
});
|
||||||
|
if (result) {
|
||||||
|
job.joblines[atsLineIndex].act_price = atsAmount;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logger.log("job-totals-ssu-ats-error", "ERROR", user?.email, job.id, {
|
||||||
|
jobid: job.id,
|
||||||
|
atsLineIndex: atsLineIndex,
|
||||||
|
error: error.message,
|
||||||
|
stack: error.stack
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//console.log(job.jobLines);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user