WIP for invoice list items on inovice enter
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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: {}
|
||||
});
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
.loading-spinner {
|
||||
display: flex;
|
||||
height: 50%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,13 @@
|
||||
"invoicelines": {
|
||||
"fields": {
|
||||
"actual": "Actual",
|
||||
"actual_cost": "Actual Cost",
|
||||
"cost_center": "Cost Center",
|
||||
"line_desc": "Line Description",
|
||||
"retail": "Retail"
|
||||
},
|
||||
"labels": {
|
||||
"other": "Other Item"
|
||||
}
|
||||
},
|
||||
"invoices": {
|
||||
|
||||
@@ -147,7 +147,13 @@
|
||||
"invoicelines": {
|
||||
"fields": {
|
||||
"actual": "",
|
||||
"actual_cost": "",
|
||||
"cost_center": "",
|
||||
"line_desc": "",
|
||||
"retail": ""
|
||||
},
|
||||
"labels": {
|
||||
"other": ""
|
||||
}
|
||||
},
|
||||
"invoices": {
|
||||
|
||||
@@ -147,7 +147,13 @@
|
||||
"invoicelines": {
|
||||
"fields": {
|
||||
"actual": "",
|
||||
"actual_cost": "",
|
||||
"cost_center": "",
|
||||
"line_desc": "",
|
||||
"retail": ""
|
||||
},
|
||||
"labels": {
|
||||
"other": ""
|
||||
}
|
||||
},
|
||||
"invoices": {
|
||||
|
||||
Reference in New Issue
Block a user