diff --git a/src/components/DialogsContainer.js b/src/components/DialogsContainer.js
index 871e38a58..2a32b532d 100644
--- a/src/components/DialogsContainer.js
+++ b/src/components/DialogsContainer.js
@@ -26,6 +26,8 @@ import NotifyEstimateViaSMSDialog from '../containers/Dialogs/NotifyEstimateViaS
import NotifyPaymentReceiveViaSMSDialog from '../containers/Dialogs/NotifyPaymentReceiveViaSMSDialog';
import SMSMessageDialog from '../containers/Dialogs/SMSMessageDialog';
import TransactionsLockingDialog from '../containers/Dialogs/TransactionsLockingDialog';
+import RefundCreditNoteDialog from '../containers/Dialogs/RefundCreditNoteDialog';
+import RefundVendorCreditDialog from '../containers/Dialogs/RefundVendorCreditDialog';
/**
* Dialogs container.
@@ -60,6 +62,8 @@ export default function DialogsContainer() {
+
+
);
}
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteDialogContent.js b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteDialogContent.js
new file mode 100644
index 000000000..4cc99ae85
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteDialogContent.js
@@ -0,0 +1,23 @@
+import React from 'react';
+
+import 'style/pages/RefundCreditNote/RefundCreditNote.scss';
+import { RefundCreditNoteFormProvider } from './RefundCreditNoteFormProvider';
+import RefundCreditNoteForm from './RefundCreditNoteForm';
+
+/**
+ * Refund credit note dialog content.
+ */
+export default function RefundCreditNoteDialogContent({
+ // #ownProps
+ dialogName,
+ creditNoteId,
+}) {
+ return (
+
+
+
+ );
+}
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFloatingActions.js b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFloatingActions.js
new file mode 100644
index 000000000..13bed0a71
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFloatingActions.js
@@ -0,0 +1,45 @@
+import React from 'react';
+import { Intent, Button, Classes } from '@blueprintjs/core';
+import { useFormikContext } from 'formik';
+import { FormattedMessage as T } from 'components';
+
+import { useRefundCreditNoteContext } from './RefundCreditNoteFormProvider';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import { compose } from 'utils';
+
+/**
+ * Refund credit note floating actions.
+ */
+function RefundCreditNoteFloatingActions({
+ // #withDialogActions
+ closeDialog,
+}) {
+ // Formik context.
+ const { isSubmitting, values, errors } = useFormikContext();
+
+ // refund credit note dialog context.
+ const { dialogName } = useRefundCreditNoteContext();
+
+ // Handle close button click.
+ const handleCancelBtnClick = () => {
+ closeDialog(dialogName);
+ };
+
+ return (
+
+ );
+}
+export default compose(withDialogActions)(RefundCreditNoteFloatingActions);
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteForm.js b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteForm.js
new file mode 100644
index 000000000..d717dc0d0
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteForm.js
@@ -0,0 +1,77 @@
+import React from 'react';
+import { Formik } from 'formik';
+import { Intent } from '@blueprintjs/core';
+import intl from 'react-intl-universal';
+import moment from 'moment';
+import { omit, defaultTo } from 'lodash';
+
+import { AppToaster } from 'components';
+import { useRefundCreditNoteContext } from './RefundCreditNoteFormProvider';
+import { CreateRefundCreditNoteFormSchema } from './RefundCreditNoteForm.schema';
+import RefundCreditNoteFormContent from './RefundCreditNoteFormContent';
+
+import withSettings from 'containers/Settings/withSettings';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import { compose, transactionNumber } from 'utils';
+
+const defaultInitialValues = {
+ from_account_id: '',
+ date: moment(new Date()).format('YYYY-MM-DD'),
+ reference_no: '',
+ description: '',
+ amount: '',
+};
+
+/**
+ * Refund credit note form.
+ */
+function RefundCreditNoteForm({
+ // #withDialogActions
+ closeDialog,
+}) {
+ const { dialogName, creditNote, createRefundCreditNoteMutate } =
+ useRefundCreditNoteContext();
+
+ // Initial form values
+ const initialValues = {
+ ...defaultInitialValues,
+ ...creditNote,
+ };
+
+ // Handles the form submit.
+ const handleFormSubmit = (values, { setSubmitting, setFieldError }) => {
+ const form = {
+ ...omit(values, ['currency_code', 'formatted_amount']),
+ };
+
+ // Handle request response success.
+ const onSaved = (response) => {
+ AppToaster.show({
+ message: intl.get('refund_credit_note.dialog.success_message'),
+ intent: Intent.SUCCESS,
+ });
+ closeDialog(dialogName);
+ };
+ // Handle request response errors.
+ const onError = ({
+ response: {
+ data: { errors },
+ },
+ }) => {
+ setSubmitting(false);
+ };
+ createRefundCreditNoteMutate([creditNote.id, form])
+ .then(onSaved)
+ .catch(onError);
+ };
+
+ return (
+
+ );
+}
+export default compose(withDialogActions)(RefundCreditNoteForm);
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteForm.schema.js b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteForm.schema.js
new file mode 100644
index 000000000..8ada6b557
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteForm.schema.js
@@ -0,0 +1,12 @@
+import * as Yup from 'yup';
+import intl from 'react-intl-universal';
+import { DATATYPES_LENGTH } from 'common/dataTypes';
+
+const Schema = Yup.object().shape({
+ date: Yup.date().required().label(intl.get('date')),
+ amount: Yup.number().required(),
+ reference_no: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
+ from_account_id: Yup.number().required().label(intl.get('deposit_account_')),
+ description: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
+});
+export const CreateRefundCreditNoteFormSchema = Schema;
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormContent.js b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormContent.js
new file mode 100644
index 000000000..d763729bb
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormContent.js
@@ -0,0 +1,16 @@
+import React from 'react';
+import { Form } from 'formik';
+import RefundCreditNoteFormFields from './RefundCreditNoteFormFields';
+import RefundCreditNoteFloatingActions from './RefundCreditNoteFloatingActions';
+
+/**
+ * Refund credit note form content.
+ */
+export default function RefundCreditNoteFormContent() {
+ return (
+
+ );
+}
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormFields.js b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormFields.js
new file mode 100644
index 000000000..54e7f2730
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormFields.js
@@ -0,0 +1,160 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { FastField, ErrorMessage } from 'formik';
+import {
+ Classes,
+ FormGroup,
+ InputGroup,
+ TextArea,
+ Position,
+ ControlGroup,
+} from '@blueprintjs/core';
+import classNames from 'classnames';
+import { CLASSES } from 'common/classes';
+import { DateInput } from '@blueprintjs/datetime';
+import {
+ Icon,
+ FieldRequiredHint,
+ AccountsSuggestField,
+ InputPrependText,
+ MoneyInputGroup,
+ FormattedMessage as T,
+} from 'components';
+import {
+ inputIntent,
+ momentFormatter,
+ tansformDateValue,
+ handleDateChange,
+ compose,
+} from 'utils';
+import { useAutofocus } from 'hooks';
+import { useRefundCreditNoteContext } from './RefundCreditNoteFormProvider';
+import withSettings from 'containers/Settings/withSettings';
+
+/**
+ * Refund credit note form fields.
+ */
+function RefundCreditNoteFormFields() {
+ const { accounts } = useRefundCreditNoteContext();
+ const amountFieldRef = useAutofocus();
+ return (
+
+ {/* ------------- Refund date ------------- */}
+
+ {({ form, field: { value }, meta: { error, touched } }) => (
+ }
+ labelInfo={}
+ className={classNames('form-group--select-list', CLASSES.FILL)}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+ {
+ form.setFieldValue('date', formattedDate);
+ })}
+ popoverProps={{ position: Position.BOTTOM, minimal: true }}
+ inputProps={{
+ leftIcon: ,
+ }}
+ />
+
+ )}
+
+ {/* ------------- Amount ------------- */}
+
+ {({
+ form: { values, setFieldValue },
+ field: { value },
+ meta: { error, touched },
+ }) => (
+ }
+ labelInfo={}
+ className={classNames('form-group--amount', CLASSES.FILL)}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+
+
+ {
+ setFieldValue('amount', amount);
+ }}
+ intent={inputIntent({ error, touched })}
+ inputRef={(ref) => (amountFieldRef.current = ref)}
+ />
+
+
+ )}
+
+ {/* ------------ Reference No. ------------ */}
+
+ {({ form, field, meta: { error, touched } }) => (
+ }
+ className={classNames('form-group--reference', CLASSES.FILL)}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+
+
+ )}
+
+
+ {/* ------------ Form account ------------ */}
+
+ {({ form, field: { value }, meta: { error, touched } }) => (
+ }
+ className={classNames(
+ 'form-group--from_account_id',
+ 'form-group--select-list',
+ CLASSES.FILL,
+ )}
+ labelInfo={}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+
+ form.setFieldValue('from_account_id', id)
+ }
+ inputProps={{
+ placeholder: intl.get('select_account'),
+ }}
+ />
+
+ )}
+
+ {/* --------- Statement --------- */}
+
+ {({ form, field, meta: { error, touched } }) => (
+ }
+ className={'form-group--description'}
+ inline={true}
+ >
+
+
+ )}
+
+
+ );
+}
+
+export default RefundCreditNoteFormFields;
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormProvider.js b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormProvider.js
new file mode 100644
index 000000000..596bd4dd0
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/RefundCreditNoteFormProvider.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { DialogContent } from 'components';
+import { pick } from 'lodash';
+
+import {
+ useAccounts,
+ useCreditNote,
+ useCreateRefundCreditNote,
+} from 'hooks/query';
+
+const RefundCreditNoteContext = React.createContext();
+
+/**
+ * Refund credit note form provider.
+ */
+function RefundCreditNoteFormProvider({ creditNoteId, dialogName, ...props }) {
+ // Handle fetch accounts data.
+ const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
+
+ // Handle fetch credit note data.
+ const { data: creditNote, isLoading: isCreditNoteLoading } = useCreditNote(
+ creditNoteId,
+ {
+ enabled: !!creditNoteId,
+ },
+ );
+ // Create and edit credit note mutations.
+ const { mutateAsync: createRefundCreditNoteMutate } =
+ useCreateRefundCreditNote();
+
+ // State provider.
+ const provider = {
+ creditNote: {
+ ...pick(creditNote, ['id', 'formatted_amount', 'currency_code']),
+ amount: creditNote.formatted_amount,
+ },
+ accounts,
+ dialogName,
+ createRefundCreditNoteMutate,
+ };
+
+ return (
+
+
+
+ );
+}
+
+const useRefundCreditNoteContext = () =>
+ React.useContext(RefundCreditNoteContext);
+
+export { RefundCreditNoteFormProvider, useRefundCreditNoteContext };
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/index.js b/src/containers/Dialogs/RefundCreditNoteDialog/index.js
new file mode 100644
index 000000000..2f9d52d0f
--- /dev/null
+++ b/src/containers/Dialogs/RefundCreditNoteDialog/index.js
@@ -0,0 +1,37 @@
+import React from 'react';
+import { Dialog, DialogSuspense, FormattedMessage as T } from 'components';
+
+import withDialogRedux from 'components/DialogReduxConnect';
+import { compose } from 'redux';
+
+const RefundCreditNoteDialogContent = React.lazy(() =>
+ import('./RefundCreditNoteDialogContent'),
+);
+
+/**
+ * Refund credit note dialog.
+ */
+function RefundCreditNoteDialog({
+ dialogName,
+ payload: { creditNoteId },
+ isOpen,
+}) {
+ return (
+ }
+ isOpen={isOpen}
+ canEscapeJeyClose={true}
+ autoFocus={true}
+ className={'dialog--refund-credit-note'}
+ >
+
+
+
+
+ );
+}
+export default compose(withDialogRedux())(RefundCreditNoteDialog);
diff --git a/src/containers/Dialogs/RefundCreditNoteDialog/utils.js b/src/containers/Dialogs/RefundCreditNoteDialog/utils.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditDialogContent.js b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditDialogContent.js
new file mode 100644
index 000000000..a454c1388
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditDialogContent.js
@@ -0,0 +1,21 @@
+import React from 'react';
+
+import 'style/pages/RefundVendorCredit/RefundVendorCredit.scss';
+
+import { RefundVendorCreditFormProvider } from './RefundVendorCreditFormProvider';
+import RefundVendorCreditForm from './RefundVendorCreditForm';
+
+export default function RefundVendorCreditDialogContent({
+ // #ownProps
+ dialogName,
+ vendorCreditId,
+}) {
+ return (
+
+
+
+ );
+}
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFloatingActions.js b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFloatingActions.js
new file mode 100644
index 000000000..b0f4e8e53
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFloatingActions.js
@@ -0,0 +1,45 @@
+import React from 'react';
+import { Intent, Button, Classes } from '@blueprintjs/core';
+import { useFormikContext } from 'formik';
+import { FormattedMessage as T } from 'components';
+
+import { useRefundVendorCreditContext } from './RefundVendorCreditFormProvider';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import { compose } from 'utils';
+
+/**
+ * Refund vendor flaoting actions.
+ */
+function RefundVendorCreditFloatingActions({
+ // #withDialogActions
+ closeDialog,
+}) {
+ // Formik context.
+ const { isSubmitting } = useFormikContext();
+ // refund vendor credit dialog context.
+ const { dialogName } = useRefundVendorCreditContext();
+
+ // Handle close button click.
+ const handleCancelBtnClick = () => {
+ closeDialog(dialogName);
+ };
+
+ return (
+
+ );
+}
+
+export default compose(withDialogActions)(RefundVendorCreditFloatingActions);
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditForm.js b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditForm.js
new file mode 100644
index 000000000..048c3beb5
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditForm.js
@@ -0,0 +1,79 @@
+import React from 'react';
+import { Formik } from 'formik';
+import { Intent } from '@blueprintjs/core';
+import intl from 'react-intl-universal';
+import moment from 'moment';
+import { omit, defaultTo } from 'lodash';
+
+import { AppToaster } from 'components';
+import { useRefundVendorCreditContext } from './RefundVendorCreditFormProvider';
+import { CreateVendorRefundCreditFormSchema } from './RefundVendorCreditForm.schema';
+import RefundVendorCreditFormContent from './RefundVendorCreditFormContent';
+
+import withSettings from 'containers/Settings/withSettings';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import { compose, transactionNumber } from 'utils';
+
+const defaultInitialValues = {
+ deposit_account_id: '',
+ date: moment(new Date()).format('YYYY-MM-DD'),
+ reference_no: '',
+ description: '',
+ amount: '',
+};
+
+/**
+ * Refund Vendor credit form.
+ */
+function RefundVendorCreditForm({
+ // #withDialogActions
+ closeDialog,
+}) {
+ const { vendorCredit, dialogName, createRefundVendorCreditMutate } =
+ useRefundVendorCreditContext();
+
+ // Initial form values
+ const initialValues = {
+ ...defaultInitialValues,
+ ...vendorCredit,
+ };
+
+ // Handles the form submit.
+ const handleFormSubmit = (values, { setSubmitting, setFieldError }) => {
+ const form = {
+ ...omit(values, ['currency_code', 'formatted_amount']),
+ };
+
+ // Handle request response success.
+ const onSaved = (response) => {
+ AppToaster.show({
+ message: intl.get('refund_vendor_credit.dialog.success_message'),
+ intent: Intent.SUCCESS,
+ });
+ closeDialog(dialogName);
+ };
+ // Handle request response errors.
+ const onError = ({
+ response: {
+ data: { errors },
+ },
+ }) => {
+ setSubmitting(false);
+ };
+
+ createRefundVendorCreditMutate([vendorCredit.id, form])
+ .then(onSaved)
+ .catch(onError);
+ };
+
+ return (
+
+ );
+}
+
+export default compose(withDialogActions)(RefundVendorCreditForm);
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditForm.schema.js b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditForm.schema.js
new file mode 100644
index 000000000..57c0b9f2d
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditForm.schema.js
@@ -0,0 +1,14 @@
+import * as Yup from 'yup';
+import intl from 'react-intl-universal';
+import { DATATYPES_LENGTH } from 'common/dataTypes';
+
+const Schema = Yup.object().shape({
+ date: Yup.date().required().label(intl.get('date')),
+ amount: Yup.number().required(),
+ reference_no: Yup.string().min(1).max(DATATYPES_LENGTH.STRING).nullable(),
+ deposit_account_id: Yup.number()
+ .required()
+ .label(intl.get('deposit_account_')),
+ description: Yup.string().nullable().max(DATATYPES_LENGTH.TEXT),
+});
+export const CreateVendorRefundCreditFormSchema = Schema;
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormContent.js b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormContent.js
new file mode 100644
index 000000000..dfc391028
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormContent.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import { Form } from 'formik';
+import RefundVendorCreditFormFields from './RefundVendorCreditFormFields';
+import RefundVendorCreditFloatingActions from './RefundVendorCreditFloatingActions';
+
+export default function RefundVendorCreditFormContent() {
+ return (
+
+ );
+}
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormFields.js b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormFields.js
new file mode 100644
index 000000000..4b13496e3
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormFields.js
@@ -0,0 +1,161 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { FastField, ErrorMessage } from 'formik';
+import {
+ Classes,
+ FormGroup,
+ InputGroup,
+ TextArea,
+ Position,
+ ControlGroup,
+} from '@blueprintjs/core';
+import classNames from 'classnames';
+import { CLASSES } from 'common/classes';
+import { DateInput } from '@blueprintjs/datetime';
+import {
+ Icon,
+ FieldRequiredHint,
+ AccountsSuggestField,
+ InputPrependText,
+ MoneyInputGroup,
+ FormattedMessage as T,
+} from 'components';
+import {
+ inputIntent,
+ momentFormatter,
+ tansformDateValue,
+ handleDateChange,
+ compose,
+} from 'utils';
+import { useAutofocus } from 'hooks';
+import { useRefundVendorCreditContext } from './RefundVendorCreditFormProvider';
+import withSettings from 'containers/Settings/withSettings';
+
+/**
+ * Refund Vendor credit form fields.
+ */
+function RefundVendorCreditFormFields() {
+ const { accounts } = useRefundVendorCreditContext();
+ const amountFieldRef = useAutofocus();
+
+ return (
+
+ {/* ------------- Refund date ------------- */}
+
+ {({ form, field: { value }, meta: { error, touched } }) => (
+ }
+ labelInfo={}
+ className={classNames('form-group--select-list', CLASSES.FILL)}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+ {
+ form.setFieldValue('refund_date', formattedDate);
+ })}
+ popoverProps={{ position: Position.BOTTOM, minimal: true }}
+ inputProps={{
+ leftIcon: ,
+ }}
+ />
+
+ )}
+
+ {/* ------------- Amount ------------- */}
+
+ {({
+ form: { values, setFieldValue },
+ field: { value },
+ meta: { error, touched },
+ }) => (
+ }
+ labelInfo={}
+ className={classNames('form-group--amount', CLASSES.FILL)}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+
+
+ {
+ setFieldValue('amount', amount);
+ }}
+ intent={inputIntent({ error, touched })}
+ inputRef={(ref) => (amountFieldRef.current = ref)}
+ />
+
+
+ )}
+
+ {/* ------------ Reference No. ------------ */}
+
+ {({ form, field, meta: { error, touched } }) => (
+ }
+ className={classNames('form-group--reference', CLASSES.FILL)}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+
+
+ )}
+
+
+ {/* ------------ Form account ------------ */}
+
+ {({ form, field: { value }, meta: { error, touched } }) => (
+ }
+ className={classNames(
+ 'form-group--deposit_account_id',
+ 'form-group--select-list',
+ CLASSES.FILL,
+ )}
+ labelInfo={}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ inline={true}
+ >
+
+ form.setFieldValue('deposit_account_id', id)
+ }
+ inputProps={{
+ placeholder: intl.get('select_account'),
+ }}
+ />
+
+ )}
+
+ {/* --------- Statement --------- */}
+
+ {({ form, field, meta: { error, touched } }) => (
+ }
+ className={'form-group--description'}
+ inline={true}
+ >
+
+
+ )}
+
+
+ );
+}
+
+export default RefundVendorCreditFormFields;
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormProvider.js b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormProvider.js
new file mode 100644
index 000000000..c9cb6e779
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/RefundVendorCreditFormProvider.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { DialogContent } from 'components';
+import { pick } from 'lodash';
+
+import {
+ useAccounts,
+ useVendorCredit,
+ useCreateRefundVendorCredit,
+} from 'hooks/query';
+
+const RefundVendorCreditContext = React.createContext();
+
+function RefundVendorCreditFormProvider({
+ vendorCreditId,
+ dialogName,
+ ...props
+}) {
+ // Handle fetch accounts data.
+ const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
+
+ // Handle fetch vendor credit details.
+ const { data: vendorCredit, isLoading: isVendorCreditLoading } =
+ useVendorCredit(vendorCreditId, {
+ enabled: !!vendorCreditId,
+ });
+
+ // Create refund vendor credit mutations.
+ const { mutateAsync: createRefundVendorCreditMutate } =
+ useCreateRefundVendorCredit();
+
+ // State provider.
+ const provider = {
+ vendorCredit: {
+ ...pick(vendorCredit, ['id', 'formatted_amount', 'currency_code']),
+ amount: vendorCredit.formatted_amount,
+ },
+ accounts,
+ dialogName,
+ createRefundVendorCreditMutate,
+ };
+
+ return (
+
+
+
+ );
+}
+
+const useRefundVendorCreditContext = () =>
+ React.useContext(RefundVendorCreditContext);
+
+export { RefundVendorCreditFormProvider, useRefundVendorCreditContext };
diff --git a/src/containers/Dialogs/RefundVendorCreditDialog/index.js b/src/containers/Dialogs/RefundVendorCreditDialog/index.js
new file mode 100644
index 000000000..006dfe69f
--- /dev/null
+++ b/src/containers/Dialogs/RefundVendorCreditDialog/index.js
@@ -0,0 +1,38 @@
+import React from 'react';
+import { Dialog, DialogSuspense, FormattedMessage as T } from 'components';
+
+import withDialogRedux from 'components/DialogReduxConnect';
+import { compose } from 'redux';
+
+const RefundVendorCreditDialogContent = React.lazy(() =>
+ import('./RefundVendorCreditDialogContent'),
+);
+
+/**
+ * Refund vendor credit dialog.
+ */
+function RefundVendorCreditDialog({
+ dialogName,
+ payload: { vendorCreditId },
+ isOpen,
+}) {
+ return (
+ }
+ isOpen={isOpen}
+ canEscapeJeyClose={true}
+ autoFocus={true}
+ className={'dialog--refund-vendor-credit'}
+ >
+
+
+
+
+ );
+}
+
+export default compose(withDialogRedux())(RefundVendorCreditDialog);
diff --git a/src/style/pages/RefundCreditNote/RefundCreditNote.scss b/src/style/pages/RefundCreditNote/RefundCreditNote.scss
new file mode 100644
index 000000000..74c1fffa3
--- /dev/null
+++ b/src/style/pages/RefundCreditNote/RefundCreditNote.scss
@@ -0,0 +1,28 @@
+.dialog--refund-credit-note {
+ .bp3-dialog-body {
+ .bp3-form-group {
+ label.bp3-label {
+ min-width: 140px;
+ font-size: 13px;
+ }
+ .bp3-form-content {
+ width: 250px;
+ }
+ }
+
+ .form-group {
+ &--description {
+ .bp3-form-content {
+ textarea {
+ width: 100%;
+ min-width: 100%;
+ font-size: 14px;
+ }
+ }
+ }
+ }
+ }
+ .bp3-dialog-footer {
+ padding-top: 10px;
+ }
+}
diff --git a/src/style/pages/RefundVendorCredit/RefundVendorCredit.scss b/src/style/pages/RefundVendorCredit/RefundVendorCredit.scss
new file mode 100644
index 000000000..ac74dfa56
--- /dev/null
+++ b/src/style/pages/RefundVendorCredit/RefundVendorCredit.scss
@@ -0,0 +1,28 @@
+.dialog--refund-vendor-credit {
+ .bp3-dialog-body {
+ .bp3-form-group {
+ label.bp3-label {
+ min-width: 140px;
+ font-size: 13px;
+ }
+ .bp3-form-content {
+ width: 250px;
+ }
+ }
+
+ .form-group {
+ &--description {
+ .bp3-form-content {
+ textarea {
+ width: 100%;
+ min-width: 100%;
+ font-size: 14px;
+ }
+ }
+ }
+ }
+ }
+ .bp3-dialog-footer {
+ padding-top: 10px;
+ }
+}