Additional WIP on enter invoice modal

This commit is contained in:
Patrick Fic
2020-02-26 18:58:36 -08:00
parent afeaeca1a1
commit 6785ff8aad
8 changed files with 171 additions and 23 deletions

View File

@@ -1747,6 +1747,58 @@
</folder_node> </folder_node>
</children> </children>
</folder_node> </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> <folder_node>
<name>invoices</name> <name>invoices</name>
<children> <children>

View File

@@ -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>
);
}

View File

@@ -24,14 +24,15 @@ export default function InvoiceEnterModalComponent({
handleRoSelect, handleRoSelect,
roAutoCompleteOptions, roAutoCompleteOptions,
handleVendorAutoComplete, handleVendorAutoComplete,
handleVendorSelect,
vendorAutoCompleteOptions, vendorAutoCompleteOptions,
lineData, lineData,
linesState linesState,
vendor
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { getFieldDecorator, resetFields } = form; const { getFieldDecorator, resetFields } = form;
console.log("invoice", invoice);
return ( return (
<Modal <Modal
title={ title={
@@ -87,6 +88,7 @@ export default function InvoiceEnterModalComponent({
<AutoComplete <AutoComplete
name="vendor_id" name="vendor_id"
dataSource={vendorAutoCompleteOptions} dataSource={vendorAutoCompleteOptions}
onSelect={handleVendorSelect}
style={{ width: "300px" }} style={{ width: "300px" }}
onSearch={handleVendorAutoComplete} onSearch={handleVendorAutoComplete}
backfill backfill
@@ -132,6 +134,8 @@ export default function InvoiceEnterModalComponent({
<InvoiceEnterModalTableComponent <InvoiceEnterModalTableComponent
lineData={lineData} lineData={lineData}
linesState={linesState} linesState={linesState}
form={form}
vendor={vendor}
/> />
</Col> </Col>
<Col span={12}>Table of added items.</Col> <Col span={12}>Table of added items.</Col>

View File

@@ -27,7 +27,7 @@ function InvoiceEnterModalContainer({
bodyshop bodyshop
}) { }) {
const { t } = useTranslation(); const { t } = useTranslation();
const linesState = useState([]); const linesState = useState([]);
const roSearchState = useState({ text: "", selectedId: null }); const roSearchState = useState({ text: "", selectedId: null });
const [roSearch, setRoSearch] = roSearchState; const [roSearch, setRoSearch] = roSearchState;
const handleRoAutoComplete = e => { const handleRoAutoComplete = e => {
@@ -39,36 +39,42 @@ function InvoiceEnterModalContainer({
skip: !roSearch.text || roSearch.text.length < 3 skip: !roSearch.text || roSearch.text.length < 3
}); });
const vendorSearchState = useState(""); const vendorSearchState = useState({
text: "",
selectedId: null
});
const [vendorSearch, setVendorSearch] = vendorSearchState; const [vendorSearch, setVendorSearch] = vendorSearchState;
const handleVendorAutoComplete = e => { const handleVendorAutoComplete = e => {
setVendorSearch(e); setVendorSearch({ ...vendorSearch, text: e });
}; };
const { data: VendorAutoCompleteData } = useQuery( const { data: VendorAutoCompleteData } = useQuery(
SEARCH_VENDOR_AUTOCOMPLETE, SEARCH_VENDOR_AUTOCOMPLETE,
{ {
fetchPolicy: "network-only", fetchPolicy: "network-only",
variables: { search: `%${vendorSearch}%` }, variables: { search: `%${vendorSearch.text}%` },
skip: !vendorSearch || vendorSearch.length < 3 skip: !vendorSearch.text || vendorSearch.text.length < 3
} }
); );
const [ const [loadLines, { called, data: lineData }] = useLazyQuery(
loadLines, GET_JOB_LINES_TO_ENTER_INVOICE,
{ called, loading: lineLoading, data: lineData } {
] = useLazyQuery(GET_JOB_LINES_TO_ENTER_INVOICE, { fetchPolicy: "network-only",
fetchPolicy: "network-only", variables: { id: roSearch.selectedId }
variables: { id: roSearch.selectedId } }
}); );
if (roSearch.selectedId) { if (roSearch.selectedId) {
if (!called) loadLines(); if (!called) loadLines();
console.log("lineData", lineData);
} }
const handleRoSelect = v => { const handleRoSelect = v => {
setRoSearch({ ...roSearch, selectedId: v }); setRoSearch({ ...roSearch, selectedId: v });
}; };
const handleVendorSelect = v => {
setVendorSearch({ ...vendorSearch, selectedId: v });
};
const handleSubmit = e => { const handleSubmit = e => {
e.preventDefault(); e.preventDefault();
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
@@ -134,6 +140,12 @@ function InvoiceEnterModalContainer({
toggleModalVisible(); toggleModalVisible();
}; };
console.log(
"c",
VendorAutoCompleteData?.vendors.filter(
v => v.id === vendorSearch.selectedId
)
);
return ( return (
<InvoiceEnterModalComponent <InvoiceEnterModalComponent
visible={invoiceEnterModal.visible} visible={invoiceEnterModal.visible}
@@ -158,6 +170,7 @@ function InvoiceEnterModalContainer({
: null : null
} }
handleVendorAutoComplete={handleVendorAutoComplete} handleVendorAutoComplete={handleVendorAutoComplete}
handleVendorSelect={handleVendorSelect}
vendorAutoCompleteOptions={ vendorAutoCompleteOptions={
VendorAutoCompleteData VendorAutoCompleteData
? VendorAutoCompleteData.vendors.reduce((acc, value) => { ? VendorAutoCompleteData.vendors.reduce((acc, value) => {
@@ -171,6 +184,13 @@ function InvoiceEnterModalContainer({
} }
linesState={linesState} linesState={linesState}
lineData={lineData ? lineData.joblines : null} lineData={lineData ? lineData.joblines : null}
vendor={
vendorSearch.selectedId
? VendorAutoCompleteData.vendors.filter(
v => v.id === vendorSearch.selectedId
)[0]
: null
}
/> />
); );
} }

View File

@@ -1,14 +1,17 @@
import { Table } from "antd";
import React, { useState } from "react"; import React, { useState } from "react";
import { Table, Button, Icon } from "antd";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
import CurrencyFormatter from "../../utils/CurrencyFormatter"; 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({ export default function InvoiceEnterModalTableComponent({
lineData, lineData,
linesState linesState,
form,
vendor
}) { }) {
const [selectedLines, setSelectedLines] = linesState; //const [selectedLines, setSelectedLines] = linesState;
const [state, setState] = useState({ const [state, setState] = useState({
sortedInfo: {} sortedInfo: {}
}); });
@@ -94,9 +97,11 @@ export default function InvoiceEnterModalTableComponent({
key: "actions", key: "actions",
render: (text, record) => ( render: (text, record) => (
<div> <div>
<Button> <InvoiceAddLineButton
<Icon type="select" /> jobLine={record}
</Button> form={form}
discount={vendor ? vendor.discount : null}
/>
</div> </div>
) )
} }

View File

@@ -144,6 +144,12 @@
"required": "This field is required. " "required": "This field is required. "
} }
}, },
"invoicelines": {
"fields": {
"actual": "Actual",
"retail": "Retail"
}
},
"invoices": { "invoices": {
"actions": { "actions": {
"receive": "Receive Part" "receive": "Receive Part"

View File

@@ -144,6 +144,12 @@
"required": "Este campo es requerido." "required": "Este campo es requerido."
} }
}, },
"invoicelines": {
"fields": {
"actual": "",
"retail": ""
}
},
"invoices": { "invoices": {
"actions": { "actions": {
"receive": "" "receive": ""

View File

@@ -144,6 +144,12 @@
"required": "Ce champ est requis." "required": "Ce champ est requis."
} }
}, },
"invoicelines": {
"fields": {
"actual": "",
"retail": ""
}
},
"invoices": { "invoices": {
"actions": { "actions": {
"receive": "" "receive": ""