381 lines
12 KiB
JavaScript
381 lines
12 KiB
JavaScript
import { DeleteFilled, DownOutlined } from "@ant-design/icons";
|
|
import {
|
|
Button,
|
|
Card,
|
|
Divider,
|
|
Dropdown,
|
|
Form,
|
|
Input,
|
|
InputNumber,
|
|
Select,
|
|
Space,
|
|
Statistic,
|
|
Menu,
|
|
Typography,
|
|
} from "antd";
|
|
import Dinero from "dinero.js";
|
|
import React from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { connect } from "react-redux";
|
|
import { createStructuredSelector } from "reselect";
|
|
import { determineDmsType } from "../../pages/dms/dms.container";
|
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
|
import DmsCdkMakes from "../dms-cdk-makes/dms-cdk-makes.component";
|
|
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
|
import DmsCdkMakesRefetch from "../dms-cdk-makes/dms-cdk-makes.refetch.component";
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
bodyshop: selectBodyshop,
|
|
});
|
|
const mapDispatchToProps = (dispatch) => ({
|
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
|
});
|
|
export default connect(mapStateToProps, mapDispatchToProps)(DmsPostForm);
|
|
|
|
export function DmsPostForm({ bodyshop, socket, job }) {
|
|
const [form] = Form.useForm();
|
|
const { t } = useTranslation();
|
|
|
|
const handlePayerSelect = (value, index) => {
|
|
form.setFieldsValue({
|
|
payers: form.getFieldValue("payers").map((payer, mapIndex) => {
|
|
if (index !== mapIndex) return payer;
|
|
const cdkPayer =
|
|
bodyshop.cdk_configuration.payers &&
|
|
bodyshop.cdk_configuration.payers.find((i) => i.name === value);
|
|
|
|
if (!cdkPayer) return payer;
|
|
|
|
return {
|
|
...cdkPayer,
|
|
dms_acctnumber: cdkPayer.dms_acctnumber,
|
|
controlnumber: job && job[cdkPayer.control_type],
|
|
};
|
|
}),
|
|
});
|
|
};
|
|
|
|
const handleFinish = (values) => {
|
|
socket.emit(`${determineDmsType(bodyshop)}-export-job`, {
|
|
jobid: job.id,
|
|
txEnvelope: values,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<Card title={t("jobs.labels.dms.postingform")}>
|
|
<Form
|
|
form={form}
|
|
layout="vertical"
|
|
onFinish={handleFinish}
|
|
initialValues={{
|
|
story: t("jobs.labels.dms.defaultstory", {
|
|
ro_number: job.ro_number,
|
|
area_of_damage: job.area_of_damage && job.area_of_damage.impact1,
|
|
}).substr(0, 239),
|
|
}}
|
|
>
|
|
<LayoutFormRow grow>
|
|
<Form.Item
|
|
name="journal"
|
|
label={t("jobs.fields.dms.journal")}
|
|
initialValue={
|
|
bodyshop.cdk_configuration &&
|
|
bodyshop.cdk_configuration.default_journal
|
|
}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="kmin"
|
|
label={t("jobs.fields.kmin")}
|
|
initialValue={job && job.kmin}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<InputNumber disabled />
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="kmout"
|
|
label={t("jobs.fields.kmout")}
|
|
initialValue={job && job.kmout}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<InputNumber disabled />
|
|
</Form.Item>
|
|
</LayoutFormRow>
|
|
|
|
{bodyshop.cdk_dealerid && (
|
|
<LayoutFormRow style={{ justifyContent: "center" }} grow>
|
|
<Form.Item
|
|
name="dms_make"
|
|
label={t("jobs.fields.dms.dms_make")}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
>
|
|
<Input disabled />
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="dms_model"
|
|
label={t("jobs.fields.dms.dms_model")}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
>
|
|
<Input disabled />
|
|
</Form.Item>
|
|
|
|
<DmsCdkMakes form={form} socket={socket} job={job} />
|
|
<DmsCdkMakesRefetch />
|
|
</LayoutFormRow>
|
|
)}
|
|
<Form.Item
|
|
name="story"
|
|
label={t("jobs.fields.dms.story")}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
>
|
|
<Input.TextArea maxLength={240} />
|
|
</Form.Item>
|
|
|
|
<Divider />
|
|
<Form.List name={["payers"]}>
|
|
{(fields, { add, remove }) => {
|
|
return (
|
|
<div>
|
|
{fields.map((field, index) => (
|
|
<Form.Item key={field.key}>
|
|
<Space wrap>
|
|
<Form.Item
|
|
label={t("jobs.fields.dms.payer.name")}
|
|
key={`${index}name`}
|
|
name={[field.name, "name"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
>
|
|
<Select
|
|
style={{ minWidth: "15rem" }}
|
|
onSelect={(value) => handlePayerSelect(value, index)}
|
|
>
|
|
{bodyshop.cdk_configuration &&
|
|
bodyshop.cdk_configuration.payers &&
|
|
bodyshop.cdk_configuration.payers.map((payer) => (
|
|
<Select.Option key={payer.name}>
|
|
{payer.name}
|
|
</Select.Option>
|
|
))}
|
|
</Select>
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
label={t("jobs.fields.dms.payer.dms_acctnumber")}
|
|
key={`${index}dms_acctnumber`}
|
|
name={[field.name, "dms_acctnumber"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
>
|
|
<Input disabled />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
label={t("jobs.fields.dms.payer.amount")}
|
|
key={`${index}amount`}
|
|
name={[field.name, "amount"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
>
|
|
<CurrencyInput min={0} />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
label={t("jobs.fields.dms.payer.controlnumber")}
|
|
key={`${index}controlnumber`}
|
|
name={[field.name, "controlnumber"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
},
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
|
|
<Form.Item shouldUpdate>
|
|
{() => {
|
|
const payers = form.getFieldValue("payers");
|
|
|
|
const row = payers && payers[index];
|
|
|
|
const cdkPayer =
|
|
bodyshop.cdk_configuration.payers &&
|
|
bodyshop.cdk_configuration.payers.find(
|
|
(i) => i && row && i.name === row.name
|
|
);
|
|
|
|
return (
|
|
<div>
|
|
{cdkPayer &&
|
|
t(`jobs.fields.${cdkPayer.control_type}`)}
|
|
</div>
|
|
);
|
|
}}
|
|
</Form.Item>
|
|
|
|
<Dropdown
|
|
overlay={
|
|
<Menu>
|
|
{bodyshop.cdk_configuration.controllist &&
|
|
bodyshop.cdk_configuration.controllist.map(
|
|
(key, idx) => (
|
|
<Menu.Item
|
|
key={idx}
|
|
onClick={() => {
|
|
form.setFieldsValue({
|
|
payers: form
|
|
.getFieldValue("payers")
|
|
.map((row, mapIndex) => {
|
|
if (index !== mapIndex) return row;
|
|
|
|
return {
|
|
...row,
|
|
controlnumber: key.controlnumber,
|
|
};
|
|
}),
|
|
});
|
|
}}
|
|
>
|
|
{key.name}
|
|
</Menu.Item>
|
|
)
|
|
)}
|
|
</Menu>
|
|
}
|
|
>
|
|
<a href=" #" onClick={(e) => e.preventDefault()}>
|
|
{t("bodyshop.labels.dms.cdk.controllist")}{" "}
|
|
<DownOutlined />
|
|
</a>
|
|
</Dropdown>
|
|
|
|
<DeleteFilled
|
|
onClick={() => {
|
|
remove(field.name);
|
|
}}
|
|
/>
|
|
</Space>
|
|
</Form.Item>
|
|
))}
|
|
<Form.Item>
|
|
<Button
|
|
disabled={!(fields.length < 3)}
|
|
onClick={() => {
|
|
if (fields.length < 3) add();
|
|
}}
|
|
style={{ width: "100%" }}
|
|
>
|
|
{t("jobs.actions.dms.addpayer")}
|
|
</Button>
|
|
</Form.Item>
|
|
</div>
|
|
);
|
|
}}
|
|
</Form.List>
|
|
<Form.Item shouldUpdate>
|
|
{() => {
|
|
//Perform Calculation to determine discrepancy.
|
|
let totalAllocated = Dinero();
|
|
|
|
const payers = form.getFieldValue("payers");
|
|
payers &&
|
|
payers.forEach((payer) => {
|
|
totalAllocated = totalAllocated.add(
|
|
Dinero({ amount: Math.round((payer?.amount || 0) * 100) })
|
|
);
|
|
});
|
|
|
|
const totals =
|
|
socket.allocationsSummary &&
|
|
socket.allocationsSummary.reduce(
|
|
(acc, val) => {
|
|
return {
|
|
totalSale: acc.totalSale.add(Dinero(val.sale)),
|
|
totalCost: acc.totalCost.add(Dinero(val.cost)),
|
|
};
|
|
},
|
|
{
|
|
totalSale: Dinero(),
|
|
totalCost: Dinero(),
|
|
}
|
|
);
|
|
const discrep = totals
|
|
? totals.totalSale.subtract(totalAllocated)
|
|
: Dinero();
|
|
return (
|
|
<Space size="large" wrap align="center">
|
|
<Statistic
|
|
title={t("jobs.labels.subtotal")}
|
|
value={(totals ? totals.totalSale : Dinero()).toFormat()}
|
|
/>
|
|
<Typography.Title>-</Typography.Title>
|
|
<Statistic
|
|
title={t("jobs.labels.dms.totalallocated")}
|
|
value={totalAllocated.toFormat()}
|
|
/>
|
|
<Typography.Title>=</Typography.Title>
|
|
<Statistic
|
|
title={t("jobs.labels.dms.notallocated")}
|
|
valueStyle={{
|
|
color: discrep.getAmount() === 0 ? "green" : "red",
|
|
}}
|
|
value={discrep.toFormat()}
|
|
/>
|
|
<Button
|
|
disabled={
|
|
!socket.allocationsSummary || discrep.getAmount() !== 0
|
|
}
|
|
htmlType="submit"
|
|
>
|
|
{t("jobs.actions.dms.post")}
|
|
</Button>
|
|
</Space>
|
|
);
|
|
}}
|
|
</Form.Item>
|
|
</Form>
|
|
</Card>
|
|
);
|
|
}
|