feature/IO-2968-Parts-Scanning-Extension

This commit is contained in:
Dave Richer
2024-12-10 11:15:24 -08:00
parent cec5f6e6e7
commit b8a298fc28
8 changed files with 311 additions and 119 deletions

View File

@@ -1,11 +1,4 @@
import isBetween from "dayjs/plugin/isBetween";
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
import isSameOrBefore from "dayjs/plugin/isSameOrBefore";
import localeData from "dayjs/plugin/localeData";
import localizedFormat from "dayjs/plugin/localizedFormat";
import minMax from "dayjs/plugin/minMax";
import utc from "dayjs/plugin/utc";
import { DateLocalizer } from "react-big-calendar";
import {DateLocalizer} from "react-big-calendar";
function arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
@@ -29,7 +22,9 @@ function iterableToArrayLimit(arr, i) {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
if (_d) { // noinspection ThrowInsideFinallyBlockJS
throw _e;
}
}
}
return _arr;

View File

@@ -1,75 +1,188 @@
import { DeleteFilled } from "@ant-design/icons";
import { Button, Form, Input, Space } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import {DeleteFilled} from "@ant-design/icons";
import {Button, Col, Form, Input, Row, Select, Space, Switch} from "antd";
import React, {useMemo} from "react";
import {useTranslation} from "react-i18next";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function ShopInfoPartsScan({ form }) {
const { t } = useTranslation();
const predefinedPartTypes = [
"PAN", "PAC", "PAR", "PAL", "PAA", "PAM", "PAP", "PAS", "PASL", "PAG"
];
const predefinedModLbrTypes = [
"LAA", "LAB", "LAD", "LAE", "LAF", "LAG", "LAM", "LAR", "LAS", "LAU",
"LA1", "LA2", "LA3", "LA4"
];
const getFieldType = (field) => {
if (["line_desc", "part_number"].includes(field)) return "string";
if (["act_price", "part_qty", "mod_lb_hrs"].includes(field)) return "number";
if (["part_type", "mod_lbr_ty"].includes(field)) return "predefined";
return null;
};
export default function ShopInfoPartsScan({form}) {
const {t} = useTranslation();
const watchedFields = Form.useWatch("md_parts_scan", form);
const operationOptions = useMemo(() => ({
string: [
{label: t("bodyshop.operations.contains"), value: "contains"},
{label: t("bodyshop.operations.equals"), value: "equals"},
{label: t("bodyshop.operations.starts_with"), value: "startsWith"},
{label: t("bodyshop.operations.ends_with"), value: "endsWith"},
],
number: [
{label: t("bodyshop.operations.equals"), value: "="},
{label: t("bodyshop.operations.greater_than"), value: ">"},
{label: t("bodyshop.operations.less_than"), value: "<"},
],
}), [t]);
return (
<div>
<LayoutFormRow header={t("bodyshop.labels.md_parts_scan")}>
<Form.List name={["md_parts_scan"]}>
{(fields, { add, remove, move }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item key={field.key}>
<LayoutFormRow noDivider>
<Form.Item
label={t("bodyshop.fields.md_parts_scan.expression")}
key={`${index}expression`}
name={[field.name, "expression"]}
rules={[
{
required: true
//message: t("general.validation.required"),
}
]}
>
<Input />
</Form.Item>
<Form.Item
label={t("bodyshop.fields.md_parts_scan.flags")}
key={`${index}flags`}
name={[field.name, "flags"]}
rules={[
{
required: true
//message: t("general.validation.required"),
}
]}
>
<Input />
</Form.Item>
{(fields, {add, remove, move}) => (
<div>
{fields.map((field, index) => {
const selectedField = watchedFields?.[index]?.field || "line_desc";
const fieldType = getFieldType(selectedField);
<Space wrap>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
<FormListMoveArrows move={move} index={index} total={fields.length} />
</Space>
</LayoutFormRow>
return (
<Form.Item key={field.key}>
<Row gutter={[16, 16]} align="middle">
{/* Select Field */}
<Col span={6}>
<Form.Item
label={t("bodyshop.fields.md_parts_scan.field")}
name={[field.name, "field"]}
rules={[
{
required: true,
message: t("general.validation.required", {
label: t("bodyshop.fields.md_parts_scan.field"),
}),
},
]}
>
<Select
options={[
{label: t("joblines.fields.line_desc"), value: "line_desc"},
{label: t("joblines.fields.part_type"), value: "part_type"},
{label: t("joblines.fields.act_price"), value: "act_price"},
{label: t("joblines.fields.part_qty"), value: "part_qty"},
{label: t("joblines.fields.mod_lbr_ty"), value: "mod_lbr_ty"},
{label: t("joblines.fields.mod_lb_hrs"), value: "mod_lb_hrs"},
{
label: `${t("joblines.fields.oem_partno")} / ${t("joblines.fields.alt_partno")}`,
value: "part_number"
},
]}
onChange={() => {
form.setFields([
{name: ["md_parts_scan", index, "operation"], value: "contains"},
{name: ["md_parts_scan", index, "value"], value: undefined},
]);
}}
/>
</Form.Item>
</Col>
{/* Operation */}
{fieldType !== "predefined" && fieldType && (
<Col span={6}>
<Form.Item
label={t("bodyshop.fields.md_parts_scan.operation")}
name={[field.name, "operation"]}
rules={[
{
required: true,
message: t("general.validation.required", {
label: t("bodyshop.fields.md_parts_scan.operation"),
}),
},
]}
>
<Select options={operationOptions[fieldType]}/>
</Form.Item>
</Col>
)}
{/* Value */}
{fieldType && (
<Col span={6}>
<Form.Item
label={t("bodyshop.fields.md_parts_scan.value")}
name={[field.name, "value"]}
rules={[
{
required: true,
message: t("general.validation.required", {
label: t("bodyshop.fields.md_parts_scan.value"),
}),
},
]}
>
{fieldType === "predefined" ? (
<Select
options={
selectedField === "part_type"
? predefinedPartTypes.map((type) => ({
label: type,
value: type
}))
: predefinedModLbrTypes.map((type) => ({
label: type,
value: type
}))
}
/>
) : (
<Input/>
)}
</Form.Item>
</Col>
)}
{/* Case Sensitivity */}
{fieldType === "string" && (
<Col span={4}>
<Form.Item
label={t("bodyshop.fields.md_parts_scan.caseInsensitive")}
name={[field.name, "caseInsensitive"]}
valuePropName="checked"
labelCol={{span: 14}}
wrapperCol={{span: 10}}
>
<Switch defaultChecked={true}/>
</Form.Item>
</Col>
)}
{/* Actions */}
<Col span={2}>
<Space>
<DeleteFilled onClick={() => remove(field.name)}/>
<FormListMoveArrows move={move} index={index} total={fields.length}/>
</Space>
</Col>
</Row>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "100%" }}
>
{t("bodyshop.actions.addpartsrule")}
</Button>
</Form.Item>
</div>
);
}}
);
})}
<Form.Item>
<Button
type="dashed"
onClick={() => add({field: "line_desc", operation: "contains"})}
style={{width: "100%"}}
>
{t("bodyshop.actions.addpartsrule")}
</Button>
</Form.Item>
</div>
)}
</Form.List>
</LayoutFormRow>
</div>

View File

@@ -1,31 +1,32 @@
import { Alert, Form, InputNumber, Switch } from "antd";
import {Alert, Form, Switch} from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import {useTranslation} from "react-i18next";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
import {connect} from "react-redux";
import {createStructuredSelector} from "reselect";
import {selectBodyshop} from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
const mapDispatchToProps = (dispatch) => ({
const mapDispatchToProps = () => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(ShopInfoIntellipay);
export function ShopInfoIntellipay({ bodyshop, form }) {
const { t } = useTranslation();
// noinspection JSUnusedLocalSymbols
export function ShopInfoIntellipay({bodyshop, form}) {
const {t} = useTranslation();
return (
<>
<Form.Item dependencies={[["intellipay_config", "enable_cash_discount"]]}>
{() => {
const { intellipay_config } = form.getFieldsValue();
const {intellipay_config} = form.getFieldsValue();
if (intellipay_config?.enable_cash_discount)
return <Alert message={t("bodyshop.labels.intellipay_cash_discount")} />;
return <Alert message={t("bodyshop.labels.intellipay_cash_discount")}/>;
}}
</Form.Item>
@@ -35,7 +36,7 @@ export function ShopInfoIntellipay({ bodyshop, form }) {
valuePropName="checked"
name={["intellipay_config", "enable_cash_discount"]}
>
<Switch />
<Switch/>
</Form.Item>
</LayoutFormRow>
</>