204 lines
7.6 KiB
JavaScript
204 lines
7.6 KiB
JavaScript
import { DeleteFilled } from "@ant-design/icons";
|
|
import { Button, Form, Input, Select, Switch } from "antd";
|
|
import React from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
|
import InvoiceLineSearchSelect from "../invoice-line-search-select/invoice-line-search-select.component";
|
|
import { WarningOutlined } from "@ant-design/icons";
|
|
|
|
export default function InvoiceEnterModalLinesComponent({
|
|
lineData,
|
|
discount,
|
|
form,
|
|
responsibilityCenters,
|
|
}) {
|
|
const { t } = useTranslation();
|
|
const { setFieldsValue, getFieldsValue } = form;
|
|
|
|
return (
|
|
<Form.List name="invoicelines">
|
|
{(fields, { add, remove }) => {
|
|
return (
|
|
<div className="invoice-form-lines-wrapper">
|
|
{fields.map((field, index) => (
|
|
<Form.Item required={false} key={field.key}>
|
|
<div className="invoice-form-line">
|
|
<Form.Item
|
|
label={t("invoicelines.fields.jobline")}
|
|
key={`${index}joblinename`}
|
|
name={[field.name, "joblineid"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<InvoiceLineSearchSelect
|
|
options={lineData}
|
|
onBlur={null}
|
|
onSelect={(value, opt) => {
|
|
setFieldsValue({
|
|
invoicelines: getFieldsValue([
|
|
"invoicelines",
|
|
]).invoicelines.map((item, idx) => {
|
|
if (idx === index) {
|
|
return {
|
|
...item,
|
|
line_desc: opt.line_desc,
|
|
actual_price: opt.cost,
|
|
cost_center: opt.part_type
|
|
? responsibilityCenters.defaults[
|
|
opt.part_type
|
|
] || null
|
|
: null,
|
|
};
|
|
}
|
|
return item;
|
|
}),
|
|
});
|
|
}}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoicelines.fields.line_desc")}
|
|
key={`${index}line_desc`}
|
|
name={[field.name, "line_desc"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoicelines.fields.actual")}
|
|
key={`${index}actual_price`}
|
|
name={[field.name, "actual_price"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<CurrencyInput
|
|
onBlur={(e) => {
|
|
setFieldsValue({
|
|
invoicelines: getFieldsValue(
|
|
"invoicelines"
|
|
).invoicelines.map((item, idx) => {
|
|
if (idx === index) {
|
|
return {
|
|
...item,
|
|
actual_cost: !!item.actual_cost
|
|
? item.actual_cost
|
|
: parseFloat(e.target.value) * (1 - discount),
|
|
};
|
|
}
|
|
return item;
|
|
}),
|
|
});
|
|
}}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoicelines.fields.actual_cost")}
|
|
key={`${index}actual_cost`}
|
|
name={[field.name, "actual_cost"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<CurrencyInput />
|
|
</Form.Item>
|
|
<Form.Item shouldUpdate>
|
|
{() => {
|
|
const line = getFieldsValue(["invoicelines"])
|
|
.invoicelines[index];
|
|
if (!!!line) return null;
|
|
const lineDiscount = +(
|
|
1 -
|
|
Math.round(
|
|
(line.actual_cost / line.actual_price) * 100
|
|
) /
|
|
100
|
|
).toFixed(2);
|
|
|
|
if (lineDiscount === discount) return null;
|
|
return <WarningOutlined style={{ color: "red" }} />;
|
|
}}
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoicelines.fields.cost_center")}
|
|
key={`${index}cost_center`}
|
|
name={[field.name, "cost_center"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<Select style={{ width: "150px" }}>
|
|
{responsibilityCenters.costs.map((item) => (
|
|
<Select.Option key={item.name}>{item.name}</Select.Option>
|
|
))}
|
|
</Select>
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoicelines.fields.federal_tax_applicable")}
|
|
key={`${index}fedtax`}
|
|
initialValue={true}
|
|
valuePropName="checked"
|
|
name={[field.name, "applicable_taxes", "federal"]}
|
|
>
|
|
<Switch />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoicelines.fields.state_tax_applicable")}
|
|
key={`${index}statetax`}
|
|
valuePropName="checked"
|
|
name={[field.name, "applicable_taxes", "state"]}
|
|
>
|
|
<Switch />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoicelines.fields.local_tax_applicable")}
|
|
key={`${index}localtax`}
|
|
valuePropName="checked"
|
|
name={[field.name, "applicable_taxes", "local"]}
|
|
>
|
|
<Switch />
|
|
</Form.Item>
|
|
<DeleteFilled
|
|
onClick={() => {
|
|
remove(field.name);
|
|
}}
|
|
/>
|
|
</div>
|
|
</Form.Item>
|
|
))}
|
|
<Form.Item>
|
|
<Button
|
|
type="dashed"
|
|
onClick={() => {
|
|
add();
|
|
}}
|
|
style={{ width: "50%" }}
|
|
>
|
|
{t("invoicelines.actions.newline")}
|
|
</Button>
|
|
</Form.Item>
|
|
</div>
|
|
);
|
|
}}
|
|
</Form.List>
|
|
);
|
|
}
|