IO-853 Added delete bill line.

This commit is contained in:
Patrick Fic
2021-04-09 10:39:37 -07:00
parent 9e13ea14e9
commit ab918902d4

View File

@@ -1,4 +1,4 @@
import { WarningOutlined } from "@ant-design/icons"; import { DeleteFilled, WarningOutlined } from "@ant-design/icons";
import { import {
Button, Button,
Form, Form,
@@ -36,375 +36,392 @@ export function BillEnterModalLinesComponent({
const { t } = useTranslation(); const { t } = useTranslation();
const { setFieldsValue, getFieldsValue, getFieldValue } = form; const { setFieldsValue, getFieldsValue, getFieldValue } = form;
const columns = [ const columns = (remove) => {
{ return [
title: t("billlines.fields.jobline"), {
dataIndex: "joblineid", title: t("billlines.fields.jobline"),
editable: true, dataIndex: "joblineid",
width: "10%", editable: true,
formItemProps: (field) => { width: "10%",
return { formItemProps: (field) => {
key: `${field.index}joblinename`, return {
name: [field.name, "joblineid"], key: `${field.index}joblinename`,
rules: [ name: [field.name, "joblineid"],
{ rules: [
required: true, {
message: t("general.validation.required"), required: true,
}, message: t("general.validation.required"),
], },
}; ],
}, };
formInput: (record, index) => ( },
<BillLineSearchSelect formInput: (record, index) => (
disabled={disabled} <BillLineSearchSelect
options={lineData} disabled={disabled}
onSelect={(value, opt) => { options={lineData}
setFieldsValue({ onSelect={(value, opt) => {
billlines: getFieldsValue(["billlines"]).billlines.map( setFieldsValue({
(item, idx) => { billlines: getFieldsValue(["billlines"]).billlines.map(
if (idx === index) { (item, idx) => {
return { if (idx === index) {
...item, return {
line_desc: opt.line_desc, ...item,
quantity: opt.part_qty || 1, line_desc: opt.line_desc,
actual_price: opt.cost, quantity: opt.part_qty || 1,
cost_center: opt.part_type actual_price: opt.cost,
? responsibilityCenters.defaults.costs[opt.part_type] || cost_center: opt.part_type
null ? responsibilityCenters.defaults.costs[
: null, opt.part_type
}; ] || null
: null,
};
}
return item;
} }
return item; ),
} });
), }}
}); />
}} ),
/>
),
},
{
title: t("billlines.fields.line_desc"),
dataIndex: "line_desc",
editable: true,
formItemProps: (field) => {
return {
key: `${field.index}line_desc`,
name: [field.name, "line_desc"],
rules: [
{
required: true,
message: t("general.validation.required"),
},
],
};
}, },
formInput: (record, index) => <Input disabled={disabled} />, {
}, title: t("billlines.fields.line_desc"),
{ dataIndex: "line_desc",
title: t("billlines.fields.quantity"), editable: true,
dataIndex: "quantity", formItemProps: (field) => {
editable: true, return {
formItemProps: (field) => { key: `${field.index}line_desc`,
return { name: [field.name, "line_desc"],
key: `${field.index}quantity`, rules: [
name: [field.name, "quantity"], {
rules: [ required: true,
{ message: t("general.validation.required"),
required: true, },
message: t("general.validation.required"), ],
}, };
], },
}; formInput: (record, index) => <Input disabled={disabled} />,
}, },
formInput: (record, index) => ( {
<InputNumber precision={0} min={0} disabled={disabled} /> title: t("billlines.fields.quantity"),
), dataIndex: "quantity",
}, editable: true,
{ width: "5rem",
title: t("billlines.fields.actual_price"), formItemProps: (field) => {
dataIndex: "actual_price", return {
editable: true, key: `${field.index}quantity`,
formItemProps: (field) => { name: [field.name, "quantity"],
return { rules: [
key: `${field.index}actual_price`, {
name: [field.name, "actual_price"], required: true,
rules: [ message: t("general.validation.required"),
{ },
required: true, ],
message: t("general.validation.required"), };
}, },
], formInput: (record, index) => (
}; <InputNumber precision={0} min={0} disabled={disabled} />
),
}, },
formInput: (record, index) => ( {
<CurrencyInput title: t("billlines.fields.actual_price"),
min={0} dataIndex: "actual_price",
disabled={disabled} width: "6rem",
onBlur={(e) => { editable: true,
setFieldsValue({ formItemProps: (field) => {
billlines: getFieldsValue("billlines").billlines.map( return {
(item, idx) => { key: `${field.index}actual_price`,
console.log("Checking", index, idx); name: [field.name, "actual_price"],
if (idx === index) { rules: [
console.log( {
"Found and setting.", required: true,
!!item.actual_cost message: t("general.validation.required"),
? item.actual_cost },
: Math.round( ],
(parseFloat(e.target.value) * (1 - discount) + };
Number.EPSILON) * },
100 formInput: (record, index) => (
) / 100 <CurrencyInput
); min={0}
return { disabled={disabled}
...item, onBlur={(e) => {
actual_cost: !!item.actual_cost setFieldsValue({
? item.actual_cost billlines: getFieldsValue("billlines").billlines.map(
: Math.round( (item, idx) => {
(parseFloat(e.target.value) * (1 - discount) + console.log("Checking", index, idx);
Number.EPSILON) * if (idx === index) {
100 console.log(
) / 100, "Found and setting.",
}; !!item.actual_cost
? item.actual_cost
: Math.round(
(parseFloat(e.target.value) * (1 - discount) +
Number.EPSILON) *
100
) / 100
);
return {
...item,
actual_cost: !!item.actual_cost
? item.actual_cost
: Math.round(
(parseFloat(e.target.value) * (1 - discount) +
Number.EPSILON) *
100
) / 100,
};
}
return item;
} }
return item; ),
} });
), }}
}); />
}} ),
/>
),
},
{
title: t("billlines.fields.actual_cost"),
dataIndex: "actual_cost",
editable: true,
formItemProps: (field) => {
return {
key: `${field.index}actual_cost`,
name: [field.name, "actual_cost"],
rules: [
{
required: true,
message: t("general.validation.required"),
},
],
};
}, },
formInput: (record, index) => ( {
<CurrencyInput min={0} disabled={disabled} /> title: t("billlines.fields.actual_cost"),
), dataIndex: "actual_cost",
additional: (record, index) => ( editable: true,
<Form.Item shouldUpdate> width: "7rem",
{() => { formItemProps: (field) => {
const line = getFieldsValue(["billlines"]).billlines[index]; return {
if (!!!line) return null; key: `${field.index}actual_cost`,
const lineDiscount = ( name: [field.name, "actual_cost"],
1 - rules: [
Math.round((line.actual_cost / line.actual_price) * 100) / 100 {
).toPrecision(2); required: true,
message: t("general.validation.required"),
},
],
};
},
formInput: (record, index) => (
<CurrencyInput min={0} disabled={disabled} />
),
additional: (record, index) => (
<Form.Item shouldUpdate>
{() => {
const line = getFieldsValue(["billlines"]).billlines[index];
if (!!!line) return null;
const lineDiscount = (
1 -
Math.round((line.actual_cost / line.actual_price) * 100) / 100
).toPrecision(2);
if (lineDiscount - discount === 0) return <div />; if (lineDiscount - discount === 0) return <div />;
return <WarningOutlined style={{ color: "red" }} />; return <WarningOutlined style={{ color: "red" }} />;
}} }}
</Form.Item> </Form.Item>
), ),
},
{
title: t("billlines.fields.cost_center"),
dataIndex: "cost_center",
editable: true,
formItemProps: (field) => {
return {
key: `${field.index}cost_center`,
name: [field.name, "cost_center"],
rules: [
{
required: true,
message: t("general.validation.required"),
},
],
};
}, },
formInput: (record, index) => ( {
<Select style={{ width: "150px" }} disabled={disabled}> title: t("billlines.fields.cost_center"),
{responsibilityCenters.costs.map((item) => ( dataIndex: "cost_center",
<Select.Option key={item.name}>{item.name}</Select.Option> editable: true,
))} formItemProps: (field) => {
</Select> return {
), key: `${field.index}cost_center`,
}, name: [field.name, "cost_center"],
{ rules: [
title: t("billlines.fields.federal_tax_applicable"), {
dataIndex: "applicable_taxes.federal", required: true,
editable: true, message: t("general.validation.required"),
formItemProps: (field) => { },
return { ],
key: `${field.index}fedtax`, };
valuePropName: "checked", },
initialValue: true, formInput: (record, index) => (
name: [field.name, "applicable_taxes", "federal"], <Select style={{ width: "150px" }} disabled={disabled}>
}; {responsibilityCenters.costs.map((item) => (
<Select.Option key={item.name}>{item.name}</Select.Option>
))}
</Select>
),
}, },
formInput: (record, index) => <Switch disabled={disabled} />, {
}, title: t("billlines.fields.federal_tax_applicable"),
{ dataIndex: "applicable_taxes.federal",
title: t("billlines.fields.state_tax_applicable"), editable: true,
dataIndex: "applicable_taxes.state", formItemProps: (field) => {
editable: true, return {
formItemProps: (field) => { key: `${field.index}fedtax`,
return { valuePropName: "checked",
key: `${field.index}statetax`, initialValue: true,
valuePropName: "checked", name: [field.name, "applicable_taxes", "federal"],
name: [field.name, "applicable_taxes", "state"], };
}; },
formInput: (record, index) => <Switch disabled={disabled} />,
}, },
formInput: (record, index) => <Switch disabled={disabled} />, {
}, title: t("billlines.fields.state_tax_applicable"),
{ dataIndex: "applicable_taxes.state",
title: t("billlines.fields.local_tax_applicable"), editable: true,
dataIndex: "applicable_taxes.local", formItemProps: (field) => {
editable: true, return {
formItemProps: (field) => { key: `${field.index}statetax`,
return { valuePropName: "checked",
key: `${field.index}localtax`, name: [field.name, "applicable_taxes", "state"],
valuePropName: "checked", };
name: [field.name, "applicable_taxes", "local"], },
}; formInput: (record, index) => <Switch disabled={disabled} />,
},
{
title: t("billlines.fields.local_tax_applicable"),
dataIndex: "applicable_taxes.local",
editable: true,
formItemProps: (field) => {
return {
key: `${field.index}localtax`,
valuePropName: "checked",
name: [field.name, "applicable_taxes", "local"],
};
},
formInput: (record, index) => <Switch disabled={disabled} />,
}, },
formInput: (record, index) => <Switch disabled={disabled} />,
},
{ {
title: t("billlines.fields.location"), title: t("billlines.fields.location"),
dataIndex: "location", dataIndex: "location",
editable: true, editable: true,
formItemProps: (field) => { formItemProps: (field) => {
return { return {
key: `${field.index}location`, key: `${field.index}location`,
name: [field.name, "location"], name: [field.name, "location"],
}; };
},
formInput: (record, index) => (
<Select style={{ width: "150px" }} disabled={disabled}>
{bodyshop.md_parts_locations.map((loc, idx) => (
<Select.Option key={idx} value={loc}>
{loc}
</Select.Option>
))}
</Select>
),
}, },
formInput: (record, index) => ( {
<Select style={{ width: "150px" }} disabled={disabled}> title: t("billlines.labels.deductedfromlbr"),
{bodyshop.md_parts_locations.map((loc, idx) => ( dataIndex: "deductedfromlbr",
<Select.Option key={idx} value={loc}> editable: true,
{loc} formItemProps: (field) => {
</Select.Option> return {
))} valuePropName: "checked",
</Select> key: `${field.index}deductedfromlbr`,
), name: [field.name, "deductedfromlbr"],
}, };
{ },
title: t("billlines.labels.deductedfromlbr"), formInput: (record, index) => <Switch disabled={disabled} />,
dataIndex: "deductedfromlbr", additional: (record, index) => (
editable: true, <Form.Item shouldUpdate style={{ display: "inline-block" }}>
formItemProps: (field) => { {() => {
return { if (getFieldValue(["billlines", record.name, "deductedfromlbr"]))
valuePropName: "checked", return (
key: `${field.index}deductedfromlbr`, <div>
name: [field.name, "deductedfromlbr"], <Form.Item
}; label={t("joblines.fields.mod_lbr_ty")}
key={`${index}modlbrty`}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
name={[record.name, "lbr_adjustment", "mod_lbr_ty"]}
>
<Select allowClear>
<Select.Option value="LAA">
{t("joblines.fields.lbr_types.LAA")}
</Select.Option>
<Select.Option value="LAB">
{t("joblines.fields.lbr_types.LAB")}
</Select.Option>
<Select.Option value="LAD">
{t("joblines.fields.lbr_types.LAD")}
</Select.Option>
<Select.Option value="LAE">
{t("joblines.fields.lbr_types.LAE")}
</Select.Option>
<Select.Option value="LAF">
{t("joblines.fields.lbr_types.LAF")}
</Select.Option>
<Select.Option value="LAG">
{t("joblines.fields.lbr_types.LAG")}
</Select.Option>
<Select.Option value="LAM">
{t("joblines.fields.lbr_types.LAM")}
</Select.Option>
<Select.Option value="LAR">
{t("joblines.fields.lbr_types.LAR")}
</Select.Option>
<Select.Option value="LAS">
{t("joblines.fields.lbr_types.LAS")}
</Select.Option>
<Select.Option value="LAU">
{t("joblines.fields.lbr_types.LAU")}
</Select.Option>
<Select.Option value="LA1">
{t("joblines.fields.lbr_types.LA1")}
</Select.Option>
<Select.Option value="LA2">
{t("joblines.fields.lbr_types.LA2")}
</Select.Option>
<Select.Option value="LA3">
{t("joblines.fields.lbr_types.LA3")}
</Select.Option>
<Select.Option value="LA4">
{t("joblines.fields.lbr_types.LA4")}
</Select.Option>
</Select>
</Form.Item>
<Form.Item
label={t("jobs.labels.adjustmentrate")}
name={[record.name, "lbr_adjustment", "rate"]}
initialValue={bodyshop.default_adjustment_rate}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber precision={2} min={0.01} />
</Form.Item>
</div>
);
return <span />;
}}
</Form.Item>
),
}, },
formInput: (record, index) => <Switch disabled={disabled} />, {
additional: (record, index) => ( title: t("general.labels.actions"),
<Form.Item shouldUpdate style={{ display: "inline-block" }}>
{() => {
if (getFieldValue(["billlines", record.name, "deductedfromlbr"]))
return (
<div>
<Form.Item
label={t("joblines.fields.mod_lbr_ty")}
key={`${index}modlbrty`}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
name={[record.name, "lbr_adjustment", "mod_lbr_ty"]}
>
<Select allowClear>
<Select.Option value="LAA">
{t("joblines.fields.lbr_types.LAA")}
</Select.Option>
<Select.Option value="LAB">
{t("joblines.fields.lbr_types.LAB")}
</Select.Option>
<Select.Option value="LAD">
{t("joblines.fields.lbr_types.LAD")}
</Select.Option>
<Select.Option value="LAE">
{t("joblines.fields.lbr_types.LAE")}
</Select.Option>
<Select.Option value="LAF">
{t("joblines.fields.lbr_types.LAF")}
</Select.Option>
<Select.Option value="LAG">
{t("joblines.fields.lbr_types.LAG")}
</Select.Option>
<Select.Option value="LAM">
{t("joblines.fields.lbr_types.LAM")}
</Select.Option>
<Select.Option value="LAR">
{t("joblines.fields.lbr_types.LAR")}
</Select.Option>
<Select.Option value="LAS">
{t("joblines.fields.lbr_types.LAS")}
</Select.Option>
<Select.Option value="LAU">
{t("joblines.fields.lbr_types.LAU")}
</Select.Option>
<Select.Option value="LA1">
{t("joblines.fields.lbr_types.LA1")}
</Select.Option>
<Select.Option value="LA2">
{t("joblines.fields.lbr_types.LA2")}
</Select.Option>
<Select.Option value="LA3">
{t("joblines.fields.lbr_types.LA3")}
</Select.Option>
<Select.Option value="LA4">
{t("joblines.fields.lbr_types.LA4")}
</Select.Option>
</Select>
</Form.Item>
<Form.Item
label={t("jobs.labels.adjustmentrate")}
name={[record.name, "lbr_adjustment", "rate"]}
initialValue={bodyshop.default_adjustment_rate}
rules={[
{
required: true,
message: t("general.validation.required"),
},
]}
>
<InputNumber precision={2} min={0.01} />
</Form.Item>
</div>
);
return <span />;
}}
</Form.Item>
),
},
];
const mergedColumns = columns.map((col) => { dataIndex: "actions",
if (!col.editable) return col; render: (text, record) => (
return { <Button disabled={disabled} onClick={() => remove(record.name)}>
...col, <DeleteFilled />
onCell: (record) => ({ </Button>
record, ),
formItemProps: col.formItemProps, },
formInput: col.formInput, ];
additional: col.additional, };
dataIndex: col.dataIndex,
title: col.title, const mergedColumns = (remove) =>
}), columns(remove).map((col) => {
}; if (!col.editable) return col;
}); return {
...col,
onCell: (record) => ({
record,
formItemProps: col.formItemProps,
formInput: col.formInput,
additional: col.additional,
dataIndex: col.dataIndex,
title: col.title,
}),
};
});
return ( return (
<Form.List name="billlines"> <Form.List name="billlines">
@@ -420,7 +437,7 @@ export function BillEnterModalLinesComponent({
size="small" size="small"
bordered bordered
dataSource={fields} dataSource={fields}
columns={mergedColumns} columns={mergedColumns(remove)}
scroll={{ x: true }} scroll={{ x: true }}
rowClassName="editable-row" rowClassName="editable-row"
/> />
@@ -467,7 +484,7 @@ const EditableCell = ({
name={dataIndex} name={dataIndex}
{...(formItemProps && formItemProps(record))} {...(formItemProps && formItemProps(record))}
> >
{formInput && formInput(record, record.key)} {(formInput && formInput(record, record.key)) || children}
</Form.Item> </Form.Item>
{additional && additional(record, record.key)} {additional && additional(record, record.key)}
</Space> </Space>
@@ -477,7 +494,7 @@ const EditableCell = ({
return ( return (
<td {...restProps}> <td {...restProps}>
<Form.Item name={dataIndex} {...(formItemProps && formItemProps(record))}> <Form.Item name={dataIndex} {...(formItemProps && formItemProps(record))}>
{formInput && formInput(record, record.key)} {(formInput && formInput(record, record.key)) || children}
</Form.Item> </Form.Item>
</td> </td>
); );