WIP for invoice list items on inovice enter

This commit is contained in:
Patrick Fic
2020-03-02 12:50:23 -08:00
parent 8c54de9a9f
commit ea000df34a
17 changed files with 573 additions and 446 deletions

View File

@@ -3,13 +3,7 @@ import { Button, Popover, Input, InputNumber, Form } from "antd";
import { SelectOutlined } from "@ant-design/icons";
import { useTranslation } from "react-i18next";
export default function InvoiceAddLineButton({
jobLine,
invoiceLineState,
form,
discount,
disabled
}) {
export default function InvoiceAddLineButton({ jobLine, discount, disabled }) {
const [visibility, setVisibility] = useState(false);
const { t } = useTranslation();

View File

@@ -1,19 +1,8 @@
import {
Select,
Button,
DatePicker,
Form,
Input,
InputNumber,
Modal,
Switch,
Row,
Col
} from "antd";
import { Button, DatePicker, Form, Input, Modal, Select, Switch } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import InvoiceEnterModalTableComponent from "./invoice-enter-modal.table.component";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
import InvoiceEnterModalLinesComponent from "./invoice-enter-modal.lines.component";
export default function InvoiceEnterModalComponent({
visible,
invoice,
@@ -145,22 +134,18 @@ export default function InvoiceEnterModalComponent({
{ required: true, message: t("general.validation.required") }
]}
>
<InputNumber precision={2} min={0} />
<CurrencyInput />
</Form.Item>
</div>
<Row>
<Col span={12}>
<InvoiceEnterModalTableComponent
lineData={lineData}
linesState={linesState}
form={form}
vendor={vendor}
/>
</Col>
<Col span={12}>Table of added items.</Col>
</Row>
);
</Modal>{" "}
<InvoiceEnterModalLinesComponent
lineData={lineData}
discount={vendor && vendor.discount}
form={form}
/>
<Button onClick={() => console.log(form.getFieldsValue())}>
Field Values
</Button>
</Modal>
</Form>
);
}

View File

@@ -69,7 +69,7 @@ function InvoiceEnterModalContainer({
const handleFinish = values => {
console.log("values", values);
alert("Closing this modal.");
toggleModalVisible();
// toggleModalVisible();
// if (!jobLineEditModal.context.id) {
// insertJobLine({
// variables: {

View File

@@ -0,0 +1,138 @@
import { DeleteFilled } from "@ant-design/icons";
import { Button, Form, Input, Select } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
export default function InvoiceEnterModalLinesComponent({
lineData,
discount,
form
}) {
const { t } = useTranslation();
const { setFieldsValue, getFieldsValue } = form;
return (
<Form.List name="invoicelines">
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item required={false} key={field.key}>
<div style={{ display: "flex" }}>
<Form.Item
label={t("invoicelines.fields.line_desc")}
key={`${index}line_desc`}
name={[field.name, "line_desc"]}
>
<Select
style={{ width: "300px" }}
onSelect={(value, opt) => {
setFieldsValue({
invoicelines: getFieldsValue([
"invoicelines"
]).invoicelines.map((item, idx) => {
if (idx === index) {
return {
...item,
joblineid: opt.key.includes("noline")
? null
: opt.key
};
}
return item;
})
});
}}
showSearch
>
<Select.Option
key={`${index}noline`}
value={t("invoicelines.labels.other")}
>
{t("invoicelines.labels.other")}
</Select.Option>
{lineData
? lineData.map(item => (
<Select.Option key={item.id} value={item.line_desc}>
{item.line_desc}
</Select.Option>
))
: null}
</Select>
</Form.Item>
{console.log(
'getFieldsValue("invoicelines").invoicelines[index]',
getFieldsValue("invoicelines").invoicelines[index]
)}
{getFieldsValue("invoicelines").invoicelines[index] &&
getFieldsValue("invoicelines").invoicelines[index]
.line_desc &&
!getFieldsValue("invoicelines").invoicelines[index].joblineid
? "Other"
: null}
<Form.Item
label={t("invoicelines.fields.actual")}
key={`${index}actual_price`}
name={[field.name, "actual_price"]}
>
<CurrencyInput
onBlur={e => {
setFieldsValue({
invoicelines: getFieldsValue(
"invoicelines"
).invoicelines.map((item, idx) => {
if (idx === index) {
return {
...item,
actual_cost:
parseFloat(e.target.value.substring(1)) * 1 -
discount
};
}
return item;
})
});
}}
/>
</Form.Item>
<Form.Item
label={t("invoicelines.fields.actual_cost")}
key={`${index}actual_cost`}
name={[field.name, "actual_cost"]}
>
<CurrencyInput />
</Form.Item>
<Form.Item
label={t("invoicelines.fields.cost_center")}
key={`${index}cost_center`}
name={[field.name, "cost_center"]}
>
<Input />
</Form.Item>
<DeleteFilled
onClick={() => {
remove(field.name);
}}
/>
</div>
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: "60%" }}
>
New liNe
</Button>
</Form.Item>
</div>
);
}}
</Form.List>
);
}

View File

@@ -7,11 +7,9 @@ import InvoiceAddLineButton from "../invoice-add-line-button/invoice-add-line-bu
export default function InvoiceEnterModalTableComponent({
lineData,
linesState,
form,
vendor
}) {
//const [selectedLines, setSelectedLines] = linesState;
const [state, setState] = useState({
sortedInfo: {}
});

View File

@@ -4,18 +4,19 @@ import "./loading-spinner.styles.scss";
export default function LoadingSpinner({ loading = true, message, ...props }) {
return (
<Spin
spinning={loading}
className="loading-spinner"
size="large"
style={{
position: "relative",
alignContent: "center"
}}
delay={200}
tip={message ? message : null}
>
{props.children}
</Spin>
<div className="loading-spinner">
<Spin
spinning={loading}
size="large"
style={{
position: "relative",
alignContent: "center"
}}
delay={200}
tip={message ? message : null}
>
{props.children}
</Spin>
</div>
);
}

View File

@@ -1,2 +1,7 @@
.loading-spinner {
display: flex;
height: 50%;
align-items: center;
justify-content: center;
margin: 1em;
}

View File

@@ -1,126 +1,91 @@
import { Button, Col, DatePicker, Form, Input, Row } from "antd";
import moment from "moment";
import React from "react";
import { useTranslation } from "react-i18next";
import ResetForm from "../form-items-formatted/reset-form-item.component";
export default function VehicleDetailFormComponent({ vehicle, form }) {
export default function VehicleDetailFormComponent() {
const { t } = useTranslation();
const { isFieldsTouched, resetFields, getFieldDecorator } = form;
return (
<div>
{isFieldsTouched() ? <ResetForm resetFields={resetFields} /> : null}
<Button type="primary" key="submit" htmlType="submit">
{t("general.labels.save")}
</Button>
<Row>
<Col span={8}>
<Form.Item label={t("vehicles.fields.v_vin")}>
{getFieldDecorator("v_vin", {
initialValue: vehicle.v_vin
})(<Input name="v_vin" />)}
<Form.Item label={t("vehicles.fields.v_vin")} name="v_vin">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.plate_no")}>
{getFieldDecorator("plate_no", {
initialValue: vehicle.plate_no
})(<Input name="plate_no" />)}
<Form.Item label={t("vehicles.fields.plate_no")} name="plate_no">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.plate_st")}>
{getFieldDecorator("plate_st", {
initialValue: vehicle.plate_st
})(<Input name="plate_st" />)}
<Form.Item label={t("vehicles.fields.plate_st")} name="plate_st">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_type")}>
{getFieldDecorator("v_type", {
initialValue: vehicle.v_type
})(<Input name="v_type" />)}
<Form.Item label={t("vehicles.fields.v_type")} name="v_type">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_trimcode")}>
{getFieldDecorator("v_trimcode", {
initialValue: vehicle.v_trimcode
})(<Input name="v_trimcode" />)}
<Form.Item label={t("vehicles.fields.v_trimcode")} name="v_trimcode">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_tone")}>
{getFieldDecorator("v_tone", {
initialValue: vehicle.v_tone
})(<Input name="v_tone" />)}
<Form.Item label={t("vehicles.fields.v_tone")} name="v_tone">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_bstyle")}>
{getFieldDecorator("v_bstyle", {
initialValue: vehicle.v_bstyle
})(<Input name="v_bstyle" />)}
<Form.Item label={t("vehicles.fields.v_bstyle")} name="v_bstyle">
<Input />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label={t("vehicles.fields.v_stage")}>
{getFieldDecorator("v_stage", {
initialValue: vehicle.v_stage
})(<Input name="v_stage" />)}
<Form.Item label={t("vehicles.fields.v_stage")} name="v_stage">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_prod_dt")}>
{getFieldDecorator("v_prod_dt", {
initialValue: vehicle.v_prod_dt ? moment(vehicle.v_prod_dt) : null
})(<DatePicker name="v_prod_dt" />)}
<Form.Item label={t("vehicles.fields.v_prod_dt")} name="v_prod_dt">
<DatePicker />
</Form.Item>
{
//TODO Add handling for paint code json
}
<Form.Item label={t("vehicles.fields.v_paint_codes")}>
{getFieldDecorator("v_paint_codes", {
initialValue: JSON.stringify(vehicle.v_paint_codes)
})(<Input name="v_paint_codes" />)}
<Form.Item
label={t("vehicles.fields.v_paint_codes")}
name="v_paint_codes"
>
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_options")}>
{getFieldDecorator("v_options", {
initialValue: vehicle.v_options
})(<Input name="v_options" />)}
<Form.Item label={t("vehicles.fields.v_options")} name="v_options">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_model_yr")}>
{getFieldDecorator("v_model_yr", {
initialValue: vehicle.v_model_yr
})(<Input name="v_model_yr" />)}
<Form.Item label={t("vehicles.fields.v_model_yr")} name="v_model_yr">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_model_desc")}>
{getFieldDecorator("v_model_desc", {
initialValue: vehicle.v_model_desc
})(<Input name="v_model_desc" />)}
<Form.Item
label={t("vehicles.fields.v_model_desc")}
name="v_model_desc"
>
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.trim_color")}>
{getFieldDecorator("trim_color", {
initialValue: vehicle.trim_color
})(<Input name="trim_color" />)}
<Form.Item label={t("vehicles.fields.trim_color")} name="trim_color">
<Input />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label={t("vehicles.fields.v_mldgcode")}>
{getFieldDecorator("v_mldgcode", {
initialValue: vehicle.v_mldgcode
})(<Input name="v_mldgcode" />)}
<Form.Item label={t("vehicles.fields.v_mldgcode")} name="v_mldgcode">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_makecode")}>
{getFieldDecorator("v_makecode", {
initialValue: vehicle.v_makecode
})(<Input name="v_makecode" />)}
<Form.Item label={t("vehicles.fields.v_makecode")} name="v_makecode">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_make_desc")}>
{getFieldDecorator("v_make_desc", {
initialValue: vehicle.v_make_desc
})(<Input name="v_make_desc" />)}
<Form.Item
label={t("vehicles.fields.v_make_desc")}
name="v_make_desc"
>
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_engine")}>
{getFieldDecorator("v_engine", {
initialValue: vehicle.v_engine
})(<Input name="v_engine" />)}
<Form.Item label={t("vehicles.fields.v_engine")} name="v_engine">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_cond")}>
{getFieldDecorator("v_cond", {
initialValue: vehicle.v_cond
})(<Input name="v_cond" />)}
<Form.Item label={t("vehicles.fields.v_cond")} name="v_cond">
<Input />
</Form.Item>
<Form.Item label={t("vehicles.fields.v_color")}>
{getFieldDecorator("v_color", {
initialValue: vehicle.v_color
})(<Input name="v_color" />)}
<Form.Item label={t("vehicles.fields.v_color")} name="v_color">
<Input />
</Form.Item>
</Col>
</Row>

View File

@@ -3,13 +3,13 @@ import { Form, notification } from "antd";
import { useMutation } from "react-apollo";
import VehicleDetailFormComponent from "./vehicle-detail-form.component";
import { useTranslation } from "react-i18next";
import moment from "moment";
import { UPDATE_VEHICLE } from "../../graphql/vehicles.queries";
function VehicleDetailFormContainer({ vehicle, refetch }) {
const { t } = useTranslation();
const [updateVehicle] = useMutation(UPDATE_VEHICLE);
const [form] = Form.useForm();
const { resetFields } = form;
const handleFinish = values => {
updateVehicle({
@@ -19,14 +19,21 @@ function VehicleDetailFormContainer({ vehicle, refetch }) {
message: t("vehicles.successes.save")
});
//TODO Better way to reset the field decorators?
if (refetch) refetch().then();
resetFields();
if (refetch) refetch();
});
};
return (
<Form onFinish={handleFinish} form={Form} autoComplete="off">
<VehicleDetailFormComponent vehicle={vehicle} form={form} />
<Form
onFinish={handleFinish}
form={form}
autoComplete="off"
initialValues={{
...vehicle,
v_prod_dt: vehicle.v_prod_dt ? moment(vehicle.v_prod_dt) : null
}}
>
<VehicleDetailFormComponent />
</Form>
);
}