From 6060def9f4c0ee5f97c3c4a7814f6f1d124a751f Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Tue, 2 Jun 2020 16:43:00 -0700 Subject: [PATCH] Restricted invoice export to 1 at a time BOD-139 --- .../accounting-payables-table.component.jsx | 36 ++++++++++-- .../invoice-export-button.component.jsx | 55 +++++++++++-------- .../jobs-close-export-button.component.jsx | 2 +- client/src/graphql/accounting.queries.js | 5 ++ client/src/graphql/appointments.queries.js | 4 ++ server/accounting/qbxml/qbxml-payables.js | 4 +- 6 files changed, 75 insertions(+), 31 deletions(-) diff --git a/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx b/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx index 7a26b14bf..613e9a151 100644 --- a/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx +++ b/client/src/components/accounting-payables-table/accounting-payables-table.component.jsx @@ -13,7 +13,8 @@ export default function AccountingPayablesTableComponent({ invoices, }) { const { t } = useTranslation(); - + const [selectedInvoices, setSelectedInvoices] = useState([]); + const [transInProgress, setTransInProgress] = useState(false); const [state, setState] = useState({ sortedInfo: {}, search: "", @@ -64,6 +65,17 @@ export default function AccountingPayablesTableComponent({ ), }, + { + title: t("jobs.fields.ro_number"), + dataIndex: "ro_number", + key: "ro_number", + sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number), + sortOrder: + state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order, + render: (text, record) => ( + {record.job.ro_number} + ), + }, { title: t("invoices.fields.date"), dataIndex: "date", @@ -107,14 +119,16 @@ export default function AccountingPayablesTableComponent({ render: (text, record) => (
), }, ]; - +console.log('transInProgress', transInProgress) const handleSearch = (e) => { setState({ ...state, search: e.target.value }); }; @@ -149,10 +163,22 @@ export default function AccountingPayablesTableComponent({ }} dataSource={dataSource} size="small" - pagination={{ position: "top" }} + pagination={{ position: "top", pageSize: 50 }} columns={columns} rowKey="id" onChange={handleTableChange} + rowSelection={{ + onSelectAll: (selected, selectedRows) => + setSelectedInvoices(selectedRows.map((i) => i.id)), + onSelect: (record, selected, selectedRows, nativeEvent) => { + setSelectedInvoices(selectedRows.map((i) => i.id)); + }, + getCheckboxProps: (record) => ({ + disabled: record.exported, + }), + selectedRowKeys: selectedInvoices, + type: "checkbox", + }} /> ); diff --git a/client/src/components/invoice-export-button/invoice-export-button.component.jsx b/client/src/components/invoice-export-button/invoice-export-button.component.jsx index e1496c560..e9ee6f068 100644 --- a/client/src/components/invoice-export-button/invoice-export-button.component.jsx +++ b/client/src/components/invoice-export-button/invoice-export-button.component.jsx @@ -12,13 +12,20 @@ const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, }); -export function InvoiceExportButton({ bodyshop, invoiceId, disabled }) { +export function InvoiceExportButton({ + bodyshop, + invoiceId, + disabled, + loadingCallback, +}) { const { t } = useTranslation(); const [updateInvoice] = useMutation(UPDATE_INVOICE); const [loading, setLoading] = useState(false); const handleQbxml = async () => { setLoading(true); + if (!!loadingCallback) loadingCallback(true); + let QbXmlResponse; try { QbXmlResponse = await axios.post( @@ -38,6 +45,7 @@ export function InvoiceExportButton({ bodyshop, invoiceId, disabled }) { error: "Unable to retrieve QBXML. " + JSON.stringify(error.message), }), }); + if (loadingCallback) loadingCallback(false); setLoading(false); return; } @@ -45,7 +53,7 @@ export function InvoiceExportButton({ bodyshop, invoiceId, disabled }) { let PartnerResponse; try { PartnerResponse = await axios.post( - "http://e9c5a8ed9079.ngrok.io/qb/receivables", + "http://e9c5a8ed9079.ngrok.io/qb/", QbXmlResponse.data ); } catch (error) { @@ -53,33 +61,34 @@ export function InvoiceExportButton({ bodyshop, invoiceId, disabled }) { notification["error"]({ message: t("invoices.errors.exporting-partner"), }); + if (!!loadingCallback) loadingCallback(false); setLoading(false); return; } - console.log("PartnerResponse", PartnerResponse); - // const invoiceUpdateResponse = await updateInvoice({ - // variables: { - // invoiceId: invoiceId, - // invoice: { - // exported: true, - // exported_at: new Date(), - // }, - // }, - // }); + const invoiceUpdateResponse = await updateInvoice({ + variables: { + invoiceId: invoiceId, + invoice: { + exported: true, + exported_at: new Date(), + }, + }, + }); - // if (!!!invoiceUpdateResponse.errors) { - // notification["success"]({ - // message: t("jobs.successes.exported"), - // }); - // } else { - // notification["error"]({ - // message: t("jobs.errors.exporting", { - // error: JSON.stringify(invoiceUpdateResponse.error), - // }), - // }); - // } + if (!!!invoiceUpdateResponse.errors) { + notification["success"]({ + message: t("jobs.successes.exported"), + }); + } else { + notification["error"]({ + message: t("jobs.errors.exporting", { + error: JSON.stringify(invoiceUpdateResponse.error), + }), + }); + } + if (!!loadingCallback) loadingCallback(false); setLoading(false); }; diff --git a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx index 4784397ed..405e9c877 100644 --- a/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx +++ b/client/src/components/jobs-close-export-button/jobs-close-export-button.component.jsx @@ -44,7 +44,7 @@ export function JobsCloseExportButton({ bodyshop, jobId, disabled }) { let PartnerResponse; try { PartnerResponse = await axios.post( - "http://localhost:1337/qb/receivables", + "http://localhost:1337/qb/", QbXmlResponse.data, { headers: { diff --git a/client/src/graphql/accounting.queries.js b/client/src/graphql/accounting.queries.js index 8519e1f6d..6e5105a8b 100644 --- a/client/src/graphql/accounting.queries.js +++ b/client/src/graphql/accounting.queries.js @@ -35,7 +35,12 @@ export const QUERY_INVOICES_FOR_EXPORT = gql` exported date invoice_number + is_credit_memo total + job { + id + ro_number + } vendor { name id diff --git a/client/src/graphql/appointments.queries.js b/client/src/graphql/appointments.queries.js index 520579b65..701e96588 100644 --- a/client/src/graphql/appointments.queries.js +++ b/client/src/graphql/appointments.queries.js @@ -160,6 +160,10 @@ export const MARK_LATEST_APPOINTMENT_AS_ARRIVED = gql` _set: { arrived: true } ) { affected_rows + returning { + id + arrived + } } } `; diff --git a/server/accounting/qbxml/qbxml-payables.js b/server/accounting/qbxml/qbxml-payables.js index 7198e7627..478e61987 100644 --- a/server/accounting/qbxml/qbxml-payables.js +++ b/server/accounting/qbxml/qbxml-payables.js @@ -49,8 +49,8 @@ const generateBill = (invoice) => { QBXML: { QBXMLMsgsRq: { "@onError": "continueOnError", - BillAddRq: { - BillAdd: { + [`${invoice.is_credit_memo ? "VendorCreditAddRq" : "BillAddRq"}`]: { + [`${invoice.is_credit_memo ? "VendorCreditAdd" : "BillAdd"}`]: { VendorRef: { FullName: invoice.vendor.name, },