From 78c42acb175e6eba2e631f3ebad32269249a8060 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Tue, 7 Dec 2021 20:55:47 +0200 Subject: [PATCH] feat: add reconcile credit note. --- src/components/DialogsContainer.js | 2 + .../ReconcileCreditNoteDialogContent.js | 21 ++++ .../ReconcileCreditNoteEntriesTable.js | 75 ++++++++++++++ .../ReconcileCreditNoteForm.js | 99 +++++++++++++++++++ .../ReconcileCreditNoteForm.schema.js | 12 +++ .../ReconcileCreditNoteFormContent.js | 28 ++++++ .../ReconcileCreditNoteFormFields.js | 60 +++++++++++ .../ReconcileCreditNoteFormFloatingActions.js | 47 +++++++++ .../ReconcileCreditNoteFormProvider.js | 64 ++++++++++++ .../ReconcileCreditNoteDialog/index.js | 36 +++++++ .../ReconcileCreditNoteDialog/utils.js | 35 +++++++ .../VendorCreditNoteFloatingActions.js | 2 +- .../CreditNoteForm/VendorCreditNoteForm.js | 4 +- .../CreditNoteForm/CreditNoteForm.js | 2 +- .../CreditNotesDataTable.js | 6 ++ .../CreditNotesLanding/components.js | 9 +- src/hooks/query/creditNote.js | 88 +++++++++++++++++ src/hooks/query/types.js | 6 +- 18 files changed, 589 insertions(+), 7 deletions(-) create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteDialogContent.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteEntriesTable.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.schema.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormContent.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFields.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFloatingActions.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormProvider.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/index.js create mode 100644 src/containers/Dialogs/ReconcileCreditNoteDialog/utils.js diff --git a/src/components/DialogsContainer.js b/src/components/DialogsContainer.js index 2a32b532d..8ea35efde 100644 --- a/src/components/DialogsContainer.js +++ b/src/components/DialogsContainer.js @@ -28,6 +28,7 @@ import SMSMessageDialog from '../containers/Dialogs/SMSMessageDialog'; import TransactionsLockingDialog from '../containers/Dialogs/TransactionsLockingDialog'; import RefundCreditNoteDialog from '../containers/Dialogs/RefundCreditNoteDialog'; import RefundVendorCreditDialog from '../containers/Dialogs/RefundVendorCreditDialog'; +import ReconcileCreditNoteDialog from '../containers/Dialogs/ReconcileCreditNoteDialog'; /** * Dialogs container. @@ -64,6 +65,7 @@ export default function DialogsContainer() { + ); } diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteDialogContent.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteDialogContent.js new file mode 100644 index 000000000..62b18d718 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteDialogContent.js @@ -0,0 +1,21 @@ +import React from 'react'; +import { ReconcileCreditNoteFormProvider } from './ReconcileCreditNoteFormProvider'; +import ReconcileCreditNoteForm from './ReconcileCreditNoteForm'; + +/** + * Reconcile credit note dialog content. + */ +export default function ReconcileCreditNoteDialogContent({ + // #ownProps + dialogName, + creditNoteId, +}) { + return ( + + + + ); +} diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteEntriesTable.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteEntriesTable.js new file mode 100644 index 000000000..c268c7e00 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteEntriesTable.js @@ -0,0 +1,75 @@ +import React from 'react'; +import intl from 'react-intl-universal'; +import { MoneyFieldCell, DataTableEditable, FormatDateCell } from 'components'; +import { compose, updateTableCell } from 'utils'; + +/** + * Reconcile credit note entries table. + */ +export default function ReconcileCreditNoteEntriesTable({ + onUpdateData, + entries, + errors, +}) { + const columns = React.useMemo( + () => [ + { + Header: intl.get('invoice_date'), + accessor: 'formatted_invoice_date', + Cell: FormatDateCell, + disableSortBy: true, + width: '120', + }, + { + Header: intl.get('invoice_no'), + accessor: 'invoice_no', + disableSortBy: true, + width: '100', + }, + { + Header: intl.get('amount'), + accessor: 'formatted_amount', + disableSortBy: true, + align: 'right', + width: '100', + }, + { + Header: intl.get('reconcile_credit_note.column.remaining_amount'), + accessor: 'formatted_due_amount', + disableSortBy: true, + align: 'right', + width: '150', + }, + { + Header: intl.get('reconcile_credit_note.column.amount_to_credit'), + accessor: 'amount', + Cell: MoneyFieldCell, + disableSortBy: true, + width: '150', + }, + ], + [], + ); + + // Handle update data. + const handleUpdateData = React.useCallback( + (rowIndex, columnId, value) => { + const newRows = compose(updateTableCell(rowIndex, columnId, value))( + entries, + ); + onUpdateData(newRows); + }, + [onUpdateData, entries], + ); + + return ( + + ); +} diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.js new file mode 100644 index 000000000..a238911a3 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.js @@ -0,0 +1,99 @@ +import React from 'react'; +import { Formik } from 'formik'; +import { Intent } from '@blueprintjs/core'; +import intl from 'react-intl-universal'; + +import '../../../style/pages/ReconcileCreditNote/ReconcileCreditNoteForm.scss'; +import { AppToaster } from 'components'; +import { CreateReconcileCreditNoteFormSchema } from './ReconcileCreditNoteForm.schema'; +import { useReconcileCreditNoteContext } from './ReconcileCreditNoteFormProvider'; +import ReconcileCreditNoteFormContent from './ReconcileCreditNoteFormContent'; +import withDialogActions from 'containers/Dialog/withDialogActions'; +import { compose, transformToForm } from 'utils'; +import { transformErrors } from './utils'; + +// Default form initial values. +const defaultInitialValues = { + entries: [ + { + invoice_id: '', + amount: '', + }, + ], +}; + +/** + * Reconcile credit note form. + */ +function ReconcileCreditNoteForm({ + // #withDialogActions + closeDialog, +}) { + const { + dialogName, + creditNoteId, + reconcileCreditNotes, + createReconcileCreditNoteMutate, + } = useReconcileCreditNoteContext(); + + // Initial form values. + const initialValues = { + entries: reconcileCreditNotes.map((entry) => ({ + ...entry, + invoice_id: entry.id, + amount: '', + })), + }; + + // Handle form submit. + const handleFormSubmit = (values, { setSubmitting, setErrors }) => { + setSubmitting(false); + + // Filters the entries. + const entries = values.entries + .filter((entry) => entry.id && entry.amount) + .map((entry) => transformToForm(entry, defaultInitialValues.entries[0])); + + const form = { + ...values, + entries: entries, + }; + + // Handle the request success. + const onSuccess = (response) => { + AppToaster.show({ + message: intl.get('reconcile_credit_note.success_message'), + intent: Intent.SUCCESS, + }); + setSubmitting(false); + closeDialog(dialogName); + }; + + // Handle the request error. + const onError = ({ + response: { + data: { errors }, + }, + }) => { + if (errors) { + transformErrors(errors, { setErrors }); + } + setSubmitting(false); + }; + + createReconcileCreditNoteMutate([creditNoteId, form]) + .then(onSuccess) + .catch(onError); + }; + + return ( + + ); +} + +export default compose(withDialogActions)(ReconcileCreditNoteForm); diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.schema.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.schema.js new file mode 100644 index 000000000..a6cd9dc09 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteForm.schema.js @@ -0,0 +1,12 @@ +import * as Yup from 'yup'; + +const Schema = Yup.object().shape({ + entries: Yup.array().of( + Yup.object().shape({ + invoice_id: Yup.number().required(), + amount: Yup.number().nullable(), + }), + ), +}); + +export const CreateReconcileCreditNoteFormSchema = Schema; diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormContent.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormContent.js new file mode 100644 index 000000000..1c1e12d21 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormContent.js @@ -0,0 +1,28 @@ +import React from 'react'; +import { Form } from 'formik'; +import { Choose } from 'components'; + +import ReconcileCreditNoteFormFields from './ReconcileCreditNoteFormFields'; +import ReconcileCreditNoteFormFloatingActions from './ReconcileCreditNoteFormFloatingActions'; +import { EmptyStatuCallout } from './utils'; +import { useReconcileCreditNoteContext } from './ReconcileCreditNoteFormProvider'; + +/** + * Reconcile credit note form content. + */ +export default function ReconcileCreditNoteFormContent() { + const { isEmptyStatus } = useReconcileCreditNoteContext(); + return ( + + + + + +
+ + + +
+
+ ); +} diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFields.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFields.js new file mode 100644 index 000000000..a035fd95d --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFields.js @@ -0,0 +1,60 @@ +import React from 'react'; +import { FastField, useFormikContext } from 'formik'; +import { Classes } from '@blueprintjs/core'; +import { T, TotalLines, TotalLine } from 'components'; +import { getEntriesTotal } from 'containers/Entries/utils'; +import ReconcileCreditNoteEntriesTable from './ReconcileCreditNoteEntriesTable'; +import { useReconcileCreditNoteContext } from './ReconcileCreditNoteFormProvider'; +import { formattedAmount } from 'utils'; + +/** + * Reconcile credit note form fields. + */ +export default function ReconcileCreditNoteFormFields() { + const { + creditNote: { formatted_credits_remaining, currency_code }, + } = useReconcileCreditNoteContext(); + + const { values } = useFormikContext(); + + // Calculate the total amount. + const totalAmount = React.useMemo( + () => getEntriesTotal(values.entries), + [values.entries], + ); + + return ( +
+ {/*------------ Reconcile credit entries table -----------*/} + + {({ + form: { setFieldValue, values }, + field: { value }, + meta: { error, touched }, + }) => ( + { + setFieldValue('entries', newEntries); + }} + /> + )} + +
+ + + } + value={formattedAmount(totalAmount, currency_code)} + /> + } + value={formatted_credits_remaining} + /> + +
+
+ ); +} diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFloatingActions.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFloatingActions.js new file mode 100644 index 000000000..e885d0325 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormFloatingActions.js @@ -0,0 +1,47 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import { Intent, Button, Classes } from '@blueprintjs/core'; +import { FormattedMessage as T } from 'components'; + +import { useReconcileCreditNoteContext } from './ReconcileCreditNoteFormProvider'; +import withDialogActions from 'containers/Dialog/withDialogActions'; +import { compose } from 'utils'; + +/** + * Reconcile credit note floating actions. + */ +function ReconcileCreditNoteFormFloatingActions({ + // #withDialogActions + closeDialog, +}) { + // Formik context. + const { isSubmitting } = useFormikContext(); + + const { dialogName } = useReconcileCreditNoteContext(); + + // Handle cancel button click. + const handleCancelBtnClick = (event) => { + closeDialog(dialogName); + }; + + return ( +
+
+ + +
+
+ ); +} +export default compose(withDialogActions)( + ReconcileCreditNoteFormFloatingActions, +); diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormProvider.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormProvider.js new file mode 100644 index 000000000..92cc90bd1 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/ReconcileCreditNoteFormProvider.js @@ -0,0 +1,64 @@ +import React from 'react'; +import { DialogContent } from 'components'; +import { + useCreditNote, + useReconcileCreditNote, + useCreateReconcileCreditNote, +} from 'hooks/query'; +import { isEmpty } from 'lodash'; + +const ReconcileCreditNoteDialogContext = React.createContext(); + +/** + * Reconcile credit note provider. + */ +function ReconcileCreditNoteFormProvider({ + creditNoteId, + dialogName, + ...props +}) { + // Handle fetch reconcile credit note details. + const { isLoading: isReconcileCreditLoading, data: reconcileCreditNotes } = + useReconcileCreditNote(creditNoteId, { + enabled: !!creditNoteId, + }); + + // Handle fetch vendor credit details. + const { data: creditNote, isLoading: isCreditNoteLoading } = useCreditNote( + creditNoteId, + { + enabled: !!creditNoteId, + }, + ); + + // Create reconcile credit note mutations. + const { mutateAsync: createReconcileCreditNoteMutate } = + useCreateReconcileCreditNote(); + + // Detarmines the datatable empty status. + const isEmptyStatus = isEmpty(reconcileCreditNotes); + + // provider payload. + const provider = { + dialogName, + reconcileCreditNotes, + createReconcileCreditNoteMutate, + isEmptyStatus, + creditNote, + creditNoteId, + }; + + return ( + + + + ); +} + +const useReconcileCreditNoteContext = () => + React.useContext(ReconcileCreditNoteDialogContext); + +export { ReconcileCreditNoteFormProvider, useReconcileCreditNoteContext }; diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/index.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/index.js new file mode 100644 index 000000000..217d93b32 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/index.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { FormattedMessage as T, Dialog, DialogSuspense } from 'components'; +import withDialogRedux from 'components/DialogReduxConnect'; +import { compose } from 'utils'; + +const ReconcileCreditNoteDialogContent = React.lazy(() => + import('./ReconcileCreditNoteDialogContent'), +); + +/** + * Reconcile credit note dialog. + */ +function ReconcileCreditNoteDialog({ + dialogName, + payload: { creditNoteId }, + isOpen, +}) { + return ( + } + canEscapeKeyClose={true} + isOpen={isOpen} + className="dialog--reconcile-credit-form" + > + + + + + ); +} + +export default compose(withDialogRedux())(ReconcileCreditNoteDialog); diff --git a/src/containers/Dialogs/ReconcileCreditNoteDialog/utils.js b/src/containers/Dialogs/ReconcileCreditNoteDialog/utils.js new file mode 100644 index 000000000..4f9b6a8f1 --- /dev/null +++ b/src/containers/Dialogs/ReconcileCreditNoteDialog/utils.js @@ -0,0 +1,35 @@ +import React from 'react'; +import intl from 'react-intl-universal'; +import { Callout, Intent, Classes } from '@blueprintjs/core'; + +import { AppToaster, T } from 'components'; + +export const transformErrors = (errors, { setErrors }) => { + if (errors.some((e) => e.type === 'INVOICES_HAS_NO_REMAINING_AMOUNT')) { + AppToaster.show({ + message: 'INVOICES_HAS_NO_REMAINING_AMOUNT', + intent: Intent.DANGER, + }); + } + + if ( + errors.find((error) => error.type === 'CREDIT_NOTE_HAS_NO_REMAINING_AMOUNT') + ) { + AppToaster.show({ + message: 'CREDIT_NOTE_HAS_NO_REMAINING_AMOUNT', + intent: Intent.DANGER, + }); + } +}; + +export function EmptyStatuCallout() { + return ( +
+ +

+ +

+
+
+ ); +} diff --git a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFloatingActions.js b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFloatingActions.js index 0d2c7a72b..ca41694fb 100644 --- a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFloatingActions.js +++ b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFloatingActions.js @@ -27,6 +27,7 @@ export default function VendorCreditNoteFloatingActions() { // Credit note form context. const { setSubmitPayload, vendorCredit } = useVendorCreditNoteFormContext(); + // Handle submit as open button click. const handleSubmitOpenBtnClick = (event) => { setSubmitPayload({ redirect: true, open: true }); @@ -70,7 +71,6 @@ export default function VendorCreditNoteFloatingActions() { const handleClearBtnClick = (event) => { resetForm(); }; - return (
{/* ----------- Save And Open ----------- */} diff --git a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.js b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.js index dff4f9571..0a5639ba5 100644 --- a/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.js +++ b/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteForm.js @@ -1,9 +1,9 @@ import React from 'react'; import { useHistory } from 'react-router-dom'; import { Formik, Form } from 'formik'; -import { Button, Intent } from '@blueprintjs/core'; +import { Intent } from '@blueprintjs/core'; import intl from 'react-intl-universal'; -import { sumBy, omit, isEmpty } from 'lodash'; +import { isEmpty } from 'lodash'; import classNames from 'classnames'; import { CLASSES } from 'common/classes'; import { diff --git a/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteForm.js b/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteForm.js index 5e0aca734..25a636aa0 100644 --- a/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteForm.js +++ b/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteForm.js @@ -3,7 +3,7 @@ import { useHistory } from 'react-router-dom'; import { Formik, Form } from 'formik'; import { Intent } from '@blueprintjs/core'; import intl from 'react-intl-universal'; -import { sumBy, omit, isEmpty } from 'lodash'; +import { isEmpty } from 'lodash'; import classNames from 'classnames'; import { CLASSES } from 'common/classes'; import { diff --git a/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesDataTable.js b/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesDataTable.js index a1721a8bb..e3c8a903e 100644 --- a/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesDataTable.js +++ b/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesDataTable.js @@ -105,6 +105,11 @@ function CreditNotesDataTable({ openAlert('credit-note-open', { creditNoteId: id }); }; + // Handle reconcile credit note. + const handleReconcileCreditNote = ({ id }) => { + openDialog('reconcile-credit-note', { creditNoteId: id }); + }; + return ( diff --git a/src/containers/Sales/CreditNotes/CreditNotesLanding/components.js b/src/containers/Sales/CreditNotes/CreditNotesLanding/components.js index b1ea5a384..81adb4906 100644 --- a/src/containers/Sales/CreditNotes/CreditNotesLanding/components.js +++ b/src/containers/Sales/CreditNotes/CreditNotesLanding/components.js @@ -14,7 +14,7 @@ import { import { safeCallback } from 'utils'; export function ActionsMenu({ - payload: { onEdit, onDelete, onRefund, onOpen, onViewDetails }, + payload: { onEdit, onDelete, onRefund, onOpen, onReconcile, onViewDetails }, row: { original }, }) { return ( @@ -44,7 +44,12 @@ export function ActionsMenu({ onClick={safeCallback(onOpen, original)} /> - + } + // text={intl.get('credit_note.action.refund_credit_note')} + onClick={safeCallback(onReconcile, original)} + /> { // Invalidate refund credit queryClient.invalidateQueries(t.REFUND_CREDIT_NOTE); + // Invalidate reconcile. + queryClient.invalidateQueries(t.RECONCILE_CREDIT_NOTES); + // Invalidate financial reports. queryClient.invalidateQueries(t.FINANCIAL_REPORT); }; @@ -227,3 +230,88 @@ export function useOpenCreditNote(props) { ...props, }); } + +/** + * Retrieve reconcile credit note of the given id. + * @param {number} id + * + */ +export function useReconcileCreditNote(id, props, requestProps) { + return useRequestQuery( + [t.RECONCILE_CREDIT_NOTE, id], + { + method: 'get', + url: `sales/credit_notes/${id}/apply-to-invoices`, + ...requestProps, + }, + { + select: (res) => res.data.data, + defaultData: [], + ...props, + }, + ); +} + +/** + * Create Reconcile credit note. + */ +export function useCreateReconcileCreditNote(props) { + const queryClient = useQueryClient(); + const apiRequest = useApiRequest(); + + return useMutation( + ([id, values]) => + apiRequest.post(`sales/credit_notes/${id}/apply-to-invoices`, values), + { + onSuccess: (res, [id, values]) => { + // Common invalidate queries. + commonInvalidateQueries(queryClient); + + // Invalidate credit note query. + queryClient.invalidateQueries([t.CREDIT_NOTE, id]); + }, + ...props, + }, + ); +} + +/** + * Retrieve reconcile credit notes. + */ +export function useReconcileCreditNotes(id, props, requestProps) { + return useRequestQuery( + [t.RECONCILE_CREDIT_NOTES, id], + { + method: 'get', + url: `sales/credit_notes/${id}/applied-invoices`, + ...requestProps, + }, + { + select: (res) => res.data.data, + defaultData: {}, + ...props, + }, + ); +} + +/** + * Delete the given reconcile credit note. + */ +export function useDeleteReconcileCredit(props) { + const queryClient = useQueryClient(); + const apiRequest = useApiRequest(); + + return useMutation( + (id) => apiRequest.delete(`sales/credit_notes/applied-to-invoices/${id}`), + { + onSuccess: (res, id) => { + // Common invalidate queries. + commonInvalidateQueries(queryClient); + + // Invalidate vendor credit query. + queryClient.invalidateQueries([t.CREDIT_NOTE, id]); + }, + ...props, + }, + ); +} diff --git a/src/hooks/query/types.js b/src/hooks/query/types.js index 68d14a525..23e921237 100644 --- a/src/hooks/query/types.js +++ b/src/hooks/query/types.js @@ -112,12 +112,16 @@ const CREDIT_NOTES = { CREDIT_NOTE: 'CREDIT_NOTE', CREDIT_NOTES: 'CREDIT_NOTES', REFUND_CREDIT_NOTE: 'REFUND_CREDIT_NOTE', + RECONCILE_CREDIT_NOTE: 'RECONCILE_CREDIT_NOTE', + RECONCILE_CREDIT_NOTES: 'RECONCILE_CREDIT_NOTES', }; const VENDOR_CREDIT_NOTES = { VENDOR_CREDITS: 'VENDOR_CREDITS', VENDOR_CREDIT: 'VENDOR_CREDIT', - REFUND_VENDOR_CREDIT:'REFUND_VENDOR_CREDIT' + REFUND_VENDOR_CREDIT: 'REFUND_VENDOR_CREDIT', + RECONCILE_VENDOR_CREDIT: 'RECONCILE_VENDOR_CREDIT', + RECONCILE_VENDOR_CREDITS: 'RECONCILE_VENDOR_CREDITS', }; const SETTING = {