236 lines
7.0 KiB
JavaScript
236 lines
7.0 KiB
JavaScript
import {
|
|
Button,
|
|
DatePicker,
|
|
Form,
|
|
Input,
|
|
Statistic,
|
|
Switch,
|
|
Upload,
|
|
} from "antd";
|
|
import React, { useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import CurrencyInput from "../form-items-formatted/currency-form-item.component";
|
|
import JobSearchSelect from "../job-search-select/job-search-select.component";
|
|
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
|
|
import InvoiceFormLines from "./invoice-form.lines.component";
|
|
import "./invoice-form.styles.scss";
|
|
import { CalculateInvoiceTotal } from "./invoice-form.totals.utility";
|
|
|
|
export default function InvoiceFormComponent({
|
|
form,
|
|
roAutoCompleteOptions,
|
|
vendorAutoCompleteOptions,
|
|
lineData,
|
|
responsibilityCenters,
|
|
loadLines,
|
|
invoiceEdit,
|
|
}) {
|
|
const { t } = useTranslation();
|
|
|
|
const [discount, setDiscount] = useState(0);
|
|
|
|
const handleVendorSelect = (props, opt) => {
|
|
setDiscount(opt.discount);
|
|
};
|
|
|
|
//TODO: Test this further. Required to set discount when viewing an invoice.
|
|
useEffect(() => {
|
|
if (form.getFieldValue("vendorid") && vendorAutoCompleteOptions) {
|
|
const vendorId = form.getFieldValue("vendorid");
|
|
const matchingVendors = vendorAutoCompleteOptions.filter(
|
|
(v) => v.id === vendorId
|
|
);
|
|
if (matchingVendors.length === 1) {
|
|
setDiscount(matchingVendors[0].discount);
|
|
}
|
|
}
|
|
if (form.getFieldValue("jobid")) {
|
|
loadLines({ variables: { id: form.getFieldValue("jobid") } });
|
|
}
|
|
}, [form, setDiscount, vendorAutoCompleteOptions, loadLines]);
|
|
|
|
return (
|
|
<div className='invoice-form-wrapper'>
|
|
<div className='invoice-form-invoice-details'>
|
|
<Form.Item
|
|
name='jobid'
|
|
label={t("invoices.fields.ro_number")}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}>
|
|
<JobSearchSelect
|
|
options={roAutoCompleteOptions}
|
|
disabled={invoiceEdit}
|
|
onBlur={() => {
|
|
if (form.getFieldValue("jobid") !== null) {
|
|
loadLines({ variables: { id: form.getFieldValue("jobid") } });
|
|
}
|
|
}}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoices.fields.vendor")}
|
|
name='vendorid'
|
|
style={{ display: invoiceEdit ? "none" : null }}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}>
|
|
<VendorSearchSelect
|
|
options={vendorAutoCompleteOptions}
|
|
onSelect={handleVendorSelect}
|
|
/>
|
|
</Form.Item>
|
|
</div>
|
|
<div className='invoice-form-invoice-details'>
|
|
<Form.Item
|
|
label={t("invoices.fields.invoice_number")}
|
|
name='invoice_number'
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}>
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoices.fields.date")}
|
|
name='date'
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}>
|
|
<DatePicker />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoices.fields.is_credit_memo")}
|
|
name='is_credit_memo'
|
|
valuePropName='checked'>
|
|
<Switch />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoices.fields.total")}
|
|
name='total'
|
|
rules={[
|
|
{
|
|
required: true,
|
|
message: t("general.validation.required"),
|
|
},
|
|
]}>
|
|
<CurrencyInput />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoices.fields.federal_tax_rate")}
|
|
name='federal_tax_rate'>
|
|
<CurrencyInput />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoices.fields.state_tax_rate")}
|
|
name='state_tax_rate'>
|
|
<CurrencyInput />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("invoices.fields.local_tax_rate")}
|
|
name='local_tax_rate'>
|
|
<CurrencyInput />
|
|
</Form.Item>
|
|
</div>
|
|
<InvoiceFormLines
|
|
lineData={lineData}
|
|
discount={discount}
|
|
form={form}
|
|
responsibilityCenters={responsibilityCenters}
|
|
/>
|
|
|
|
<Form.Item
|
|
name='upload'
|
|
label='Upload'
|
|
style={{ display: invoiceEdit ? "none" : null }}
|
|
valuePropName='fileList'
|
|
getValueFromEvent={(e) => {
|
|
console.log("Upload event:", e);
|
|
if (Array.isArray(e)) {
|
|
return e;
|
|
}
|
|
return e && e.fileList;
|
|
}}>
|
|
<Upload name='logo' beforeUpload={() => false} listType='picture'>
|
|
<Button>Click to upload</Button>
|
|
</Upload>
|
|
</Form.Item>
|
|
|
|
<Form.Item shouldUpdate>
|
|
{() => {
|
|
const values = form.getFieldsValue([
|
|
"invoicelines",
|
|
"total",
|
|
"federal_tax_rate",
|
|
"state_tax_rate",
|
|
"local_tax_rate",
|
|
]);
|
|
let totals;
|
|
if (
|
|
!!values.total &&
|
|
!!values.invoicelines &&
|
|
values.invoicelines.length > 0
|
|
)
|
|
totals = CalculateInvoiceTotal(values);
|
|
if (!!totals)
|
|
return (
|
|
<div className='invoice-form-totals'>
|
|
<Statistic
|
|
title={t("invoices.labels.subtotal")}
|
|
value={totals.subtotal.toFormat()}
|
|
precision={2}
|
|
/>
|
|
<Statistic
|
|
title={t("invoices.labels.federal_tax")}
|
|
value={totals.federalTax.toFormat()}
|
|
precision={2}
|
|
/>
|
|
<Statistic
|
|
title={t("invoices.labels.state_tax")}
|
|
value={totals.stateTax.toFormat()}
|
|
precision={2}
|
|
/>
|
|
<Statistic
|
|
title={t("invoices.labels.local_tax")}
|
|
value={totals.localTax.toFormat()}
|
|
precision={2}
|
|
/>
|
|
<Statistic
|
|
title={t("invoices.labels.entered_total")}
|
|
value={totals.enteredTotal.toFormat()}
|
|
precision={2}
|
|
/>
|
|
<Statistic
|
|
title={t("invoices.labels.invoice_total")}
|
|
value={totals.invoiceTotal.toFormat()}
|
|
precision={2}
|
|
/>
|
|
<Statistic
|
|
title={t("invoices.labels.discrepancy")}
|
|
valueStyle={{
|
|
color:
|
|
totals.discrepancy.getAmount() === 0 ? "green" : "red",
|
|
}}
|
|
value={totals.discrepancy.toFormat()}
|
|
precision={2}
|
|
/>
|
|
</div>
|
|
);
|
|
return null;
|
|
}}
|
|
</Form.Item>
|
|
</div>
|
|
);
|
|
}
|