diff --git a/client/src/components/AccountsSelectList.js b/client/src/components/AccountsSelectList.js
index e1bc9de96..57a78c856 100644
--- a/client/src/components/AccountsSelectList.js
+++ b/client/src/components/AccountsSelectList.js
@@ -1,17 +1,35 @@
-import React, { useCallback, useState } from 'react';
+import React, { useCallback, useState, useEffect, useMemo } from 'react';
import { MenuItem, Button } from '@blueprintjs/core';
import { Select } from '@blueprintjs/select';
+import { FormattedMessage as T } from 'react-intl';
export default function AccountsSelectList({
accounts,
onAccountSelected,
error = [],
- initialAccount,
- defautlSelectText = 'Select account',
+ initialAccountId,
+ selectedAccountId,
+ defaultSelectText = 'Select account',
}) {
+ // Find initial account object to set it as default account in initial render.
+ const initialAccount = useMemo(
+ () => accounts.find((a) => a.id === initialAccountId),
+ [initialAccountId],
+ );
+
const [selectedAccount, setSelectedAccount] = useState(
initialAccount || null,
);
+
+ useEffect(() => {
+ if (typeof selectedAccountId !== 'undefined') {
+ const account = selectedAccountId
+ ? accounts.find((a) => a.id === selectedAccountId)
+ : null;
+ setSelectedAccount(account);
+ }
+ }, [selectedAccountId, accounts, setSelectedAccount]);
+
// Account item of select accounts field.
const accountItem = useCallback((item, { handleClick, modifiers, query }) => {
return (
@@ -52,7 +70,7 @@ export default function AccountsSelectList({
return (
}
+ noResults={} />}
itemRenderer={accountItem}
itemPredicate={filterAccountsPredicater}
popoverProps={{ minimal: true }}
@@ -60,7 +78,7 @@ export default function AccountsSelectList({
onItemSelect={onAccountSelect}
>
);
diff --git a/client/src/components/DataTableCells/AccountsListFieldCell.js b/client/src/components/DataTableCells/AccountsListFieldCell.js
index 6cee2c770..c4c5e33a5 100644
--- a/client/src/components/DataTableCells/AccountsListFieldCell.js
+++ b/client/src/components/DataTableCells/AccountsListFieldCell.js
@@ -9,7 +9,7 @@ import {
// Account cell renderer.
const AccountCellRenderer = ({
- column: { id, value },
+ column: { id },
row: { index, original },
cell: { value: initialValue },
payload: { accounts, updateData, errors },
@@ -20,9 +20,9 @@ const AccountCellRenderer = ({
const { account_id = false } = (errors[index] || {});
- const initialAccount = useMemo(() =>
- accounts.find(a => a.id === initialValue),
- [accounts, initialValue]);
+ // const initialAccount = useMemo(() =>
+ // accounts.find(a => a.id === initialValue),
+ // [accounts, initialValue]);
return (
+ selectedAccountId={initialValue} />
);
};
diff --git a/client/src/components/index.js b/client/src/components/index.js
index fbdd3b084..7db273f77 100644
--- a/client/src/components/index.js
+++ b/client/src/components/index.js
@@ -18,6 +18,7 @@ import FieldRequiredHint from './FieldRequiredHint';
import Dialog from './Dialog';
import AppToaster from './AppToaster';
import DataTable from './DataTable';
+import AccountsSelectList from './AccountsSelectList';
const Hint = FieldHint;
@@ -43,4 +44,5 @@ export {
Dialog,
AppToaster,
DataTable,
+ AccountsSelectList,
};
\ No newline at end of file
diff --git a/client/src/containers/Accounting/MakeJournalEntriesForm.js b/client/src/containers/Accounting/MakeJournalEntriesForm.js
index 2d1a9ff2c..3afe8950e 100644
--- a/client/src/containers/Accounting/MakeJournalEntriesForm.js
+++ b/client/src/containers/Accounting/MakeJournalEntriesForm.js
@@ -26,7 +26,15 @@ import Dragzone from 'components/Dragzone';
import withMediaActions from 'containers/Media/withMediaActions';
import useMedia from 'hooks/useMedia';
-import { compose } from 'utils';
+import { compose, repeatValue } from 'utils';
+
+const ERROR = {
+ JOURNAL_NUMBER_ALREADY_EXISTS: 'JOURNAL.NUMBER.ALREADY.EXISTS',
+ CUSTOMERS_NOT_WITH_RECEVIABLE_ACC: 'CUSTOMERS.NOT.WITH.RECEIVABLE.ACCOUNT',
+ VENDORS_NOT_WITH_PAYABLE_ACCOUNT: 'VENDORS.NOT.WITH.PAYABLE.ACCOUNT',
+ PAYABLE_ENTRIES_HAS_NO_VENDORS: 'PAYABLE.ENTRIES.HAS.NO.VENDORS',
+ RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS: 'RECEIVABLE.ENTRIES.HAS.NO.CUSTOMERS',
+};
/**
* Journal entries form.
@@ -139,7 +147,7 @@ function MakeJournalEntriesForm({
date: moment(new Date()).format('YYYY-MM-DD'),
description: '',
reference: '',
- entries: [defaultEntry, defaultEntry, defaultEntry, defaultEntry],
+ entries: [...repeatValue(defaultEntry, 4)],
}),
[defaultEntry],
);
@@ -171,44 +179,50 @@ function MakeJournalEntriesForm({
: [];
}, [manualJournal]);
+ // Transform API errors in toasts messages.
const transformErrors = (errors, { setErrors }) => {
const hasError = (errorType) => errors.some((e) => e.type === errorType);
- if (hasError('CUSTOMERS.NOT.WITH.RECEIVABLE.ACCOUNT')) {
+ if (hasError(ERROR.CUSTOMERS_NOT_WITH_RECEVIABLE_ACC)) {
AppToaster.show({
- message:
- 'customers_should_assign_with_receivable_account_only',
+ message: formatMessage({
+ id: 'customers_should_assign_with_receivable_account_only',
+ }),
intent: Intent.DANGER,
});
}
- if (hasError('VENDORS.NOT.WITH.PAYABLE.ACCOUNT')) {
+ if (hasError(ERROR.PAYABLE_ENTRIES_HAS_NO_VENDORS)) {
AppToaster.show({
- message: 'vendors_should_assign_with_payable_account_only',
+ message: formatMessage({
+ id: 'vendors_should_assign_with_payable_account_only',
+ }),
intent: Intent.DANGER,
});
}
- if (hasError('RECEIVABLE.ENTRIES.HAS.NO.CUSTOMERS')) {
+ if (hasError(ERROR.RECEIVABLE_ENTRIES_HAS_NO_CUSTOMERS)) {
AppToaster.show({
- message:
- 'entries_with_receivable_account_no_assigned_with_customers',
- intent: Intent.DANGER,
- });
- }
- if (hasError('PAYABLE.ENTRIES.HAS.NO.VENDORS')) {
- AppToaster.show({
- message:
- 'entries_with_payable_account_no_assigned_with_vendors',
+ message: formatMessage({
+ id: 'entries_with_receivable_account_no_assigned_with_customers',
+ }),
intent: Intent.DANGER,
});
}
- if (hasError('JOURNAL.NUMBER.ALREADY.EXISTS')) {
+ if (hasError(ERROR.PAYABLE_ENTRIES_HAS_NO_VENDORS)) {
+ AppToaster.show({
+ message: formatMessage({
+ id: 'entries_with_payable_account_no_assigned_with_vendors',
+ }),
+ intent: Intent.DANGER,
+ });
+ }
+ if (hasError(ERROR.JOURNAL_NUMBER_ALREADY_EXISTS)) {
setErrors({
journal_number: formatMessage({
id: 'journal_number_is_already_used',
}),
});
}
- }
+ };
const formik = useFormik({
enableReinitialize: true,
@@ -313,6 +327,7 @@ function MakeJournalEntriesForm({
const handleSubmitClick = useCallback(
(payload) => {
setPayload(payload);
+ // formik.resetForm();
formik.handleSubmit();
},
[setPayload, formik],
@@ -336,15 +351,30 @@ function MakeJournalEntriesForm({
[setDeletedFiles, deletedFiles],
);
+ // Handle click on add a new line/row.
+ const handleClickAddNewRow = () => {
+ formik.setFieldValue('entries', [...formik.values.entries, defaultEntry]);
+ };
+
+ // Handle click `Clear all lines` button.
+ const handleClickClearLines = () => {
+ formik.setFieldValue(
+ 'entries',
+ reorderingEntriesIndex([...repeatValue(defaultEntry, 4)]),
+ );
+ };
+
return (