Additional WIP on enter invoice modal
This commit is contained in:
@@ -1747,6 +1747,58 @@
|
||||
</folder_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>invoicelines</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>fields</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>actual</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>retail</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
<default_text></default_text>
|
||||
<translations>
|
||||
<translation>
|
||||
<language>en-US</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>es-MX</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
<translation>
|
||||
<language>fr-CA</language>
|
||||
<approved>false</approved>
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>invoices</name>
|
||||
<children>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import React, { useState } from "react";
|
||||
import { Button, Popover, Icon, Input, InputNumber, Form } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function InvoiceAddLineButton({
|
||||
jobLine,
|
||||
invoiceLineState,
|
||||
form,
|
||||
discount
|
||||
}) {
|
||||
const [visibility, setVisibility] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const { getFieldDecorator } = form;
|
||||
|
||||
const popContent = (
|
||||
<div style={{ display: "flex" }}>
|
||||
<Form.Item label={t("joblines.fields.line_desc")}>
|
||||
{getFieldDecorator("line_desc", {
|
||||
initialValue: jobLine.line_desc
|
||||
})(<Input name="line_desc" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("joblines.fields.oem_partno")}>
|
||||
{getFieldDecorator("oem_partno", {
|
||||
initialValue: jobLine.oem_partno
|
||||
})(<Input name="oem_partno" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("invoicelines.fields.retail")}>
|
||||
{getFieldDecorator("retail", { initialValue: jobLine.act_price })(
|
||||
<InputNumber precision={2} name="retail" />
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("invoicelines.fields.actual")}>
|
||||
{getFieldDecorator("actual", {
|
||||
initialValue: jobLine.act_price * (discount ? 1 - discount : 1)
|
||||
})(<InputNumber precision={2} name="actual" />)}
|
||||
</Form.Item>
|
||||
DISSC: {discount}
|
||||
<Button onClick={() => setVisibility(false)}>??</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover content={popContent} visible={visibility}>
|
||||
<Button onClick={() => setVisibility(true)}>
|
||||
<Icon type="select" />
|
||||
</Button>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
@@ -24,14 +24,15 @@ export default function InvoiceEnterModalComponent({
|
||||
handleRoSelect,
|
||||
roAutoCompleteOptions,
|
||||
handleVendorAutoComplete,
|
||||
handleVendorSelect,
|
||||
vendorAutoCompleteOptions,
|
||||
lineData,
|
||||
linesState
|
||||
linesState,
|
||||
vendor
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const { getFieldDecorator, resetFields } = form;
|
||||
|
||||
console.log("invoice", invoice);
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={
|
||||
@@ -87,6 +88,7 @@ export default function InvoiceEnterModalComponent({
|
||||
<AutoComplete
|
||||
name="vendor_id"
|
||||
dataSource={vendorAutoCompleteOptions}
|
||||
onSelect={handleVendorSelect}
|
||||
style={{ width: "300px" }}
|
||||
onSearch={handleVendorAutoComplete}
|
||||
backfill
|
||||
@@ -132,6 +134,8 @@ export default function InvoiceEnterModalComponent({
|
||||
<InvoiceEnterModalTableComponent
|
||||
lineData={lineData}
|
||||
linesState={linesState}
|
||||
form={form}
|
||||
vendor={vendor}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>Table of added items.</Col>
|
||||
|
||||
@@ -27,7 +27,7 @@ function InvoiceEnterModalContainer({
|
||||
bodyshop
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const linesState = useState([]);
|
||||
const linesState = useState([]);
|
||||
const roSearchState = useState({ text: "", selectedId: null });
|
||||
const [roSearch, setRoSearch] = roSearchState;
|
||||
const handleRoAutoComplete = e => {
|
||||
@@ -39,36 +39,42 @@ function InvoiceEnterModalContainer({
|
||||
skip: !roSearch.text || roSearch.text.length < 3
|
||||
});
|
||||
|
||||
const vendorSearchState = useState("");
|
||||
const vendorSearchState = useState({
|
||||
text: "",
|
||||
selectedId: null
|
||||
});
|
||||
const [vendorSearch, setVendorSearch] = vendorSearchState;
|
||||
const handleVendorAutoComplete = e => {
|
||||
setVendorSearch(e);
|
||||
setVendorSearch({ ...vendorSearch, text: e });
|
||||
};
|
||||
const { data: VendorAutoCompleteData } = useQuery(
|
||||
SEARCH_VENDOR_AUTOCOMPLETE,
|
||||
{
|
||||
fetchPolicy: "network-only",
|
||||
variables: { search: `%${vendorSearch}%` },
|
||||
skip: !vendorSearch || vendorSearch.length < 3
|
||||
variables: { search: `%${vendorSearch.text}%` },
|
||||
skip: !vendorSearch.text || vendorSearch.text.length < 3
|
||||
}
|
||||
);
|
||||
|
||||
const [
|
||||
loadLines,
|
||||
{ called, loading: lineLoading, data: lineData }
|
||||
] = useLazyQuery(GET_JOB_LINES_TO_ENTER_INVOICE, {
|
||||
fetchPolicy: "network-only",
|
||||
variables: { id: roSearch.selectedId }
|
||||
});
|
||||
const [loadLines, { called, data: lineData }] = useLazyQuery(
|
||||
GET_JOB_LINES_TO_ENTER_INVOICE,
|
||||
{
|
||||
fetchPolicy: "network-only",
|
||||
variables: { id: roSearch.selectedId }
|
||||
}
|
||||
);
|
||||
|
||||
if (roSearch.selectedId) {
|
||||
if (!called) loadLines();
|
||||
console.log("lineData", lineData);
|
||||
}
|
||||
const handleRoSelect = v => {
|
||||
setRoSearch({ ...roSearch, selectedId: v });
|
||||
};
|
||||
|
||||
const handleVendorSelect = v => {
|
||||
setVendorSearch({ ...vendorSearch, selectedId: v });
|
||||
};
|
||||
|
||||
const handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
form.validateFieldsAndScroll((err, values) => {
|
||||
@@ -134,6 +140,12 @@ function InvoiceEnterModalContainer({
|
||||
toggleModalVisible();
|
||||
};
|
||||
|
||||
console.log(
|
||||
"c",
|
||||
VendorAutoCompleteData?.vendors.filter(
|
||||
v => v.id === vendorSearch.selectedId
|
||||
)
|
||||
);
|
||||
return (
|
||||
<InvoiceEnterModalComponent
|
||||
visible={invoiceEnterModal.visible}
|
||||
@@ -158,6 +170,7 @@ function InvoiceEnterModalContainer({
|
||||
: null
|
||||
}
|
||||
handleVendorAutoComplete={handleVendorAutoComplete}
|
||||
handleVendorSelect={handleVendorSelect}
|
||||
vendorAutoCompleteOptions={
|
||||
VendorAutoCompleteData
|
||||
? VendorAutoCompleteData.vendors.reduce((acc, value) => {
|
||||
@@ -171,6 +184,13 @@ function InvoiceEnterModalContainer({
|
||||
}
|
||||
linesState={linesState}
|
||||
lineData={lineData ? lineData.joblines : null}
|
||||
vendor={
|
||||
vendorSearch.selectedId
|
||||
? VendorAutoCompleteData.vendors.filter(
|
||||
v => v.id === vendorSearch.selectedId
|
||||
)[0]
|
||||
: null
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { Table } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import { Table, Button, Icon } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import InvoiceAddLineButton from "../invoice-add-line-button/invoice-add-line-button.component";
|
||||
|
||||
export default function InvoiceEnterModalTableComponent({
|
||||
lineData,
|
||||
linesState
|
||||
linesState,
|
||||
form,
|
||||
vendor
|
||||
}) {
|
||||
const [selectedLines, setSelectedLines] = linesState;
|
||||
//const [selectedLines, setSelectedLines] = linesState;
|
||||
const [state, setState] = useState({
|
||||
sortedInfo: {}
|
||||
});
|
||||
@@ -94,9 +97,11 @@ export default function InvoiceEnterModalTableComponent({
|
||||
key: "actions",
|
||||
render: (text, record) => (
|
||||
<div>
|
||||
<Button>
|
||||
<Icon type="select" />
|
||||
</Button>
|
||||
<InvoiceAddLineButton
|
||||
jobLine={record}
|
||||
form={form}
|
||||
discount={vendor ? vendor.discount : null}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -144,6 +144,12 @@
|
||||
"required": "This field is required. "
|
||||
}
|
||||
},
|
||||
"invoicelines": {
|
||||
"fields": {
|
||||
"actual": "Actual",
|
||||
"retail": "Retail"
|
||||
}
|
||||
},
|
||||
"invoices": {
|
||||
"actions": {
|
||||
"receive": "Receive Part"
|
||||
|
||||
@@ -144,6 +144,12 @@
|
||||
"required": "Este campo es requerido."
|
||||
}
|
||||
},
|
||||
"invoicelines": {
|
||||
"fields": {
|
||||
"actual": "",
|
||||
"retail": ""
|
||||
}
|
||||
},
|
||||
"invoices": {
|
||||
"actions": {
|
||||
"receive": ""
|
||||
|
||||
@@ -144,6 +144,12 @@
|
||||
"required": "Ce champ est requis."
|
||||
}
|
||||
},
|
||||
"invoicelines": {
|
||||
"fields": {
|
||||
"actual": "",
|
||||
"retail": ""
|
||||
}
|
||||
},
|
||||
"invoices": {
|
||||
"actions": {
|
||||
"receive": ""
|
||||
|
||||
Reference in New Issue
Block a user