diff --git a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesFooter.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesFooter.js
index 63057c804..8752d8ff6 100644
--- a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesFooter.js
+++ b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesFooter.js
@@ -10,79 +10,70 @@ import {
MenuItem,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl';
+import { useFormikContext } from 'formik';
import { CLASSES } from 'common/classes';
import classNames from 'classnames';
-import { saveInvoke } from 'utils';
import { If, Icon } from 'components';
+import { useMakeJournalFormContext } from './MakeJournalProvider';
+import { useHistory } from 'react-router-dom';
/**
* Make Journal floating actions bar.
*/
-export default function MakeJournalEntriesFooter({
- isSubmitting,
- onSubmitClick,
- onCancelClick,
- manualJournalId,
- onSubmitForm,
- onResetForm,
- manualJournalPublished,
-}) {
+export default function MakeJournalEntriesFooter() {
+ const history = useHistory();
+
+ // Formik context.
+ const { isSubmitting, submitForm } = useFormikContext();
+
+ // Make journal form context.
+ const {
+ manualJournalId,
+ setSubmitPayload,
+ manualJournalPublished = false,
+ } = useMakeJournalFormContext();
+
+ // Handle `submit & publish` button click.
const handleSubmitPublishBtnClick = (event) => {
- saveInvoke(onSubmitClick, event, {
- redirect: true,
- publish: true,
- });
+ setSubmitPayload({ redirect: true, publish: true });
+ submitForm();
};
+ // Handle `submit, publish & new` button click.
const handleSubmitPublishAndNewBtnClick = (event) => {
- onSubmitForm();
- saveInvoke(onSubmitClick, event, {
- redirect: false,
- publish: true,
- resetForm: true,
- });
+ setSubmitPayload({ redirect: false, publish: true, resetForm: true });
+ submitForm();
};
+ // Handle `submit, publish & continue editing` button click.
const handleSubmitPublishContinueEditingBtnClick = (event) => {
- onSubmitForm();
- saveInvoke(onSubmitClick, event, {
- redirect: false,
- publish: true,
- });
+ setSubmitPayload({ redirect: false, publish: true });
+ submitForm();
};
+ // Handle `submit as draft` button click.
const handleSubmitDraftBtnClick = (event) => {
- saveInvoke(onSubmitClick, event, {
- redirect: true,
- publish: false,
- });
+ setSubmitPayload({ redirect: true, publish: false });
};
+ // Handle `submit as draft & new` button click.
const handleSubmitDraftAndNewBtnClick = (event) => {
- onSubmitForm();
- saveInvoke(onSubmitClick, event, {
- redirect: false,
- publish: false,
- resetForm: true,
- });
+ setSubmitPayload({ redirect: false, publish: false, resetForm: true });
+ submitForm();
};
+ // Handles submit as draft & continue editing button click.
const handleSubmitDraftContinueEditingBtnClick = (event) => {
- onSubmitForm();
- saveInvoke(onSubmitClick, event, {
- redirect: false,
- publish: false,
- });
+ setSubmitPayload({ redirect: false, publish: false });
+ submitForm();
};
+ // Handle cancel button action click.
const handleCancelBtnClick = (event) => {
- saveInvoke(onCancelClick, event);
+ history.goBack();
};
- const handleClearBtnClick = (event) => {
- // saveInvoke(onClearClick, event);
- onResetForm();
- };
+ const handleClearBtnClick = (event) => {};
return (
diff --git a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
index 673105ef1..be6ef6452 100644
--- a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
+++ b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js
@@ -1,9 +1,8 @@
-import React, { useMemo, useState, useEffect, useCallback } from 'react';
+import React, { useMemo } from 'react';
import { Formik, Form } from 'formik';
-import moment from 'moment';
import { Intent } from '@blueprintjs/core';
import { useIntl } from 'react-intl';
-import { pick, defaultTo } from 'lodash';
+import { defaultTo, isEmpty } from 'lodash';
import classNames from 'classnames';
import { useHistory } from 'react-router-dom';
@@ -15,56 +14,30 @@ import {
import MakeJournalEntriesHeader from './MakeJournalEntriesHeader';
import MakeJournalFormFloatingActions from './MakeJournalFormFloatingActions';
import MakeJournalEntriesField from './MakeJournalEntriesField';
-import MakeJournalNumberWatcher from './MakeJournalNumberWatcher';
import MakeJournalFormFooter from './MakeJournalFormFooter';
-import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withSettings from 'containers/Settings/withSettings';
import AppToaster from 'components/AppToaster';
import withMediaActions from 'containers/Media/withMediaActions';
+import { compose, orderingLinesIndexes, transactionNumber } from 'utils';
import {
- compose,
- repeatValue,
- orderingLinesIndexes,
- defaultToTransform,
- transactionNumber,
-} from 'utils';
-import { transformErrors } from './utils';
+ transformErrors,
+ transformToEditForm,
+ defaultManualJournal,
+} from './utils';
import { useMakeJournalFormContext } from './MakeJournalProvider';
-const defaultEntry = {
- index: 0,
- account_id: '',
- credit: '',
- debit: '',
- contact_id: '',
- note: '',
-};
-const defaultInitialValues = {
- journal_number: '',
- journal_type: 'Journal',
- date: moment(new Date()).format('YYYY-MM-DD'),
- description: '',
- reference: '',
- currency_code: '',
- publish: '',
- entries: [...repeatValue(defaultEntry, 4)],
-};
-
/**
* Journal entries form.
*/
function MakeJournalEntriesForm({
- // #withDashboard
- changePageTitle,
- changePageSubtitle,
-
// #withSettings
journalNextNumber,
journalNumberPrefix,
baseCurrency,
}) {
+ // Journal form context.
const {
createJournalMutate,
editJournalMutate,
@@ -81,58 +54,23 @@ function MakeJournalEntriesForm({
journalNumberPrefix,
journalNextNumber,
);
- // Changes the page title based on the form in new and edit mode.
- useEffect(() => {
- const transactionNumber = manualJournal
- ? manualJournal.journal_number
- : journalNumber;
-
- if (isNewMode) {
- changePageTitle(formatMessage({ id: 'new_journal' }));
- } else {
- changePageTitle(formatMessage({ id: 'edit_journal' }));
- }
- changePageSubtitle(
- defaultToTransform(transactionNumber, `No. ${transactionNumber}`, ''),
- );
- }, [
- changePageTitle,
- changePageSubtitle,
- journalNumber,
- manualJournal,
- formatMessage,
- isNewMode,
- ]);
-
+ // Form initial values.
const initialValues = useMemo(
() => ({
- ...(manualJournal
+ ...(!isEmpty(manualJournal)
? {
- ...pick(manualJournal, Object.keys(defaultInitialValues)),
- entries: manualJournal.entries.map((entry) => ({
- ...pick(entry, Object.keys(defaultEntry)),
- })),
+ ...transformToEditForm(manualJournal),
}
: {
- ...defaultInitialValues,
+ ...defaultManualJournal,
journal_number: defaultTo(journalNumber, ''),
currency_code: defaultTo(baseCurrency, ''),
- entries: orderingLinesIndexes(defaultInitialValues.entries),
+ entries: orderingLinesIndexes(defaultManualJournal.entries),
}),
}),
[manualJournal, baseCurrency, journalNumber],
);
- // Handle journal number field change.
- const handleJournalNumberChanged = useCallback(
- (journalNumber) => {
- changePageSubtitle(
- defaultToTransform(journalNumber, `No. ${journalNumber}`, ''),
- );
- },
- [changePageSubtitle],
- );
-
// Handle the form submiting.
const handleSubmit = (values, { setErrors, setSubmitting, resetForm }) => {
setSubmitting(true);
@@ -170,8 +108,12 @@ function MakeJournalEntriesForm({
const form = { ...values, publish: submitPayload.publish, entries };
// Handle the request error.
- const handleError = (error) => {
- transformErrors(error, { setErrors });
+ const handleError = ({
+ response: {
+ data: { errors },
+ },
+ }) => {
+ transformErrors(errors, { setErrors });
setSubmitting(false);
};
@@ -201,7 +143,7 @@ function MakeJournalEntriesForm({
if (isNewMode) {
createJournalMutate(form).then(handleSuccess).catch(handleError);
} else {
- editJournalMutate(manualJournal.id, form)
+ editJournalMutate([manualJournal.id, form])
.then(handleSuccess)
.catch(handleError);
}
@@ -221,11 +163,8 @@ function MakeJournalEntriesForm({
onSubmit={handleSubmit}
>
@@ -235,7 +174,6 @@ function MakeJournalEntriesForm({
}
export default compose(
- withDashboardActions,
withMediaActions,
withSettings(({ manualJournalsSettings, organizationSettings }) => ({
journalNextNumber: parseInt(manualJournalsSettings?.nextNumber, 10),
diff --git a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
index dfc405bf3..ea2f3ff86 100644
--- a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
+++ b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesPage.js
@@ -1,62 +1,20 @@
-import React, { useCallback, useEffect } from 'react';
-import { useParams, useHistory } from 'react-router-dom';
+import React from 'react';
+import { useParams } from 'react-router-dom';
import MakeJournalEntriesForm from './MakeJournalEntriesForm';
import { MakeJournalProvider } from './MakeJournalProvider';
-import withDashboardActions from 'containers/Dashboard/withDashboardActions';
-
-import { compose } from 'utils';
-
import 'style/pages/ManualJournal/MakeJournal.scss';
/**
* Make journal entries page.
*/
-function MakeJournalEntriesPage({
- // #withDashboardActions
- setSidebarShrink,
- resetSidebarPreviousExpand,
- setDashboardBackLink,
-}) {
- const history = useHistory();
+export default function MakeJournalEntriesPage() {
const { id: journalId } = useParams();
-
- useEffect(() => {
- // Shrink the sidebar by foce.
- setSidebarShrink();
- // Show the back link on dashboard topbar.
- setDashboardBackLink('/manual-journals');
-
- return () => {
- // Reset the sidebar to the previous status.
- resetSidebarPreviousExpand();
- // Hide the back link on dashboard topbar.
- setDashboardBackLink(false);
- };
- }, [resetSidebarPreviousExpand, setDashboardBackLink, setSidebarShrink]);
-
- const handleFormSubmit = useCallback(
- (payload) => {
- payload.redirect && history.push('/manual-journals');
- },
- [history],
- );
-
- const handleCancel = useCallback(() => {
- history.goBack();
- }, [history]);
-
+
return (
-
+
);
}
-
-export default compose(
- withDashboardActions,
-)(MakeJournalEntriesPage);
diff --git a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
index dbc089489..974735e57 100644
--- a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
+++ b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesTable.js
@@ -1,205 +1,111 @@
-import React, { useState, useMemo, useEffect, useCallback } from 'react';
+import React from 'react';
import { Button } from '@blueprintjs/core';
-import { FormattedMessage as T, useIntl } from 'react-intl';
-import { omit } from 'lodash';
-import { saveInvoke } from 'utils';
-import {
- AccountsListFieldCell,
- MoneyFieldCell,
- InputGroupCell,
- ContactsListFieldCell,
-} from 'components/DataTableCells';
-import {
- ContactHeaderCell,
- ActionsCellRenderer,
- TotalAccountCellRenderer,
- TotalCreditDebitCellRenderer,
- NoteCellRenderer,
-} from './components';
+import { FormattedMessage as T } from 'react-intl';
+import { saveInvoke, removeRowsByIndex } from 'utils';
import { DataTableEditable } from 'components';
+import withAlertActions from 'containers/Alert/withAlertActions';
import { updateDataReducer } from './utils';
import { useMakeJournalFormContext } from './MakeJournalProvider';
+import { useJournalTableEntriesColumns } from './components';
+
+import JournalDeleteEntriesAlert from 'containers/Alerts/ManualJournals/JournalDeleteEntriesAlert';
+import { compose } from 'redux';
+import { repeatValue } from 'utils';
/**
* Make journal entries table component.
*/
-export default function MakeJournalEntriesTable({
+function MakeJournalEntriesTable({
+ // #withAlertsActions
+ openAlert,
+
// #ownPorps
- onClickRemoveRow,
- onClickAddNewRow,
- onClickClearAllLines,
onChange,
entries,
+ defaultEntry,
error,
+ initialLinesNumber = 4,
+ minLinesNumber = 4,
}) {
- const [rows, setRows] = useState([]);
- const { formatMessage } = useIntl();
-
const { accounts, customers } = useMakeJournalFormContext();
- useEffect(() => {
- setRows([...entries.map((e) => ({ ...e, rowType: 'editor' }))]);
- }, [entries, setRows]);
-
- // Final table rows editor rows and total and final blank row.
- const tableRows = useMemo(() => [...rows, { rowType: 'total' }], [rows]);
-
// Memorized data table columns.
- const columns = useMemo(
- () => [
- {
- Header: '#',
- accessor: 'index',
- Cell: ({ row: { index } }) =>
{index + 1},
- className: 'index',
- width: 40,
- disableResizing: true,
- disableSortBy: true,
- sticky: 'left',
- },
- {
- Header: formatMessage({ id: 'account' }),
- id: 'account_id',
- accessor: 'account_id',
- Cell: TotalAccountCellRenderer(AccountsListFieldCell),
- className: 'account',
- disableSortBy: true,
- width: 140,
- },
- {
- Header: formatMessage({ id: 'credit_currency' }, { currency: 'USD' }),
- accessor: 'credit',
- Cell: TotalCreditDebitCellRenderer(MoneyFieldCell, 'credit'),
- className: 'credit',
- disableSortBy: true,
- width: 100,
- },
- {
- Header: formatMessage({ id: 'debit_currency' }, { currency: 'USD' }),
- accessor: 'debit',
- Cell: TotalCreditDebitCellRenderer(MoneyFieldCell, 'debit'),
- className: 'debit',
- disableSortBy: true,
- width: 100,
- },
- {
- Header: ContactHeaderCell,
- id: 'contact_id',
- accessor: 'contact_id',
- Cell: NoteCellRenderer(ContactsListFieldCell),
- className: 'contact',
- disableSortBy: true,
- width: 120,
- },
- {
- Header: formatMessage({ id: 'note' }),
- accessor: 'note',
- Cell: NoteCellRenderer(InputGroupCell),
- disableSortBy: true,
- className: 'note',
- width: 200,
- },
- {
- Header: '',
- accessor: 'action',
- Cell: ActionsCellRenderer,
- className: 'actions',
- disableSortBy: true,
- disableResizing: true,
- width: 45,
- },
- ],
- [formatMessage],
- );
+ const columns = useJournalTableEntriesColumns();
// Handles click new line.
const onClickNewRow = () => {
- saveInvoke(onClickAddNewRow);
+ const newRows = [...entries, defaultEntry];
+ saveInvoke(onChange, newRows);
};
// Handles update datatable data.
const handleUpdateData = (rowIndex, columnId, value) => {
- const newRows = updateDataReducer(rows, rowIndex, columnId, value);
-
- saveInvoke(
- onChange,
- newRows
- .filter((row) => row.rowType === 'editor')
- .map((row) => ({
- ...omit(row, ['rowType']),
- })),
- );
+ const newRows = updateDataReducer(entries, rowIndex, columnId, value);
+ saveInvoke(onChange, newRows);
};
+
// Handle remove datatable row.
const handleRemoveRow = (rowIndex) => {
- // Can't continue if there is just one row line or less.
- if (rows.length <= 2) {
- return;
- }
- const removeIndex = parseInt(rowIndex, 10);
- const newRows = rows.filter((row, index) => index !== removeIndex);
-
- saveInvoke(
- onChange,
- newRows
- .filter((row) => row.rowType === 'editor')
- .map((row) => ({ ...omit(row, ['rowType']) })),
- );
- saveInvoke(onClickRemoveRow, removeIndex);
+ const newRows = removeRowsByIndex(entries, rowIndex);
+ saveInvoke(onChange, newRows);
};
- // Rows class names callback.
- const rowClassNames = useCallback(
- (row) => ({
- 'row--total': rows.length === row.index + 2,
- }),
- [rows],
- );
-
+ // Handle clear all lines action.
const handleClickClearAllLines = () => {
- saveInvoke(onClickClearAllLines);
+ openAlert('make-journal-delete-all-entries');
+ };
+
+ // Handle clear all lines alaert confirm.
+ const handleCofirmClearEntriesAlert = () => {
+ const newRows = repeatValue(defaultEntry, initialLinesNumber);
+ saveInvoke(onChange, newRows);
};
return (
-
({
+ <>
+ ({
...customer,
contact_type: 'customer',
})),
- ],
- autoFocus: ['account_id', 0],
- }}
- actions={
- <>
-
+ autoFocus: ['account_id', 0],
+ }}
+ actions={
+ <>
+
-
- >
- }
- />
+
+ >
+ }
+ />
+
+ >
);
}
+
+export default compose(withAlertActions)(MakeJournalEntriesTable);
diff --git a/client/src/containers/Accounting/MakeJournal/MakeJournalFormFloatingActions.js b/client/src/containers/Accounting/MakeJournal/MakeJournalFormFloatingActions.js
index 1d367b614..80f42ace7 100644
--- a/client/src/containers/Accounting/MakeJournal/MakeJournalFormFloatingActions.js
+++ b/client/src/containers/Accounting/MakeJournal/MakeJournalFormFloatingActions.js
@@ -80,8 +80,8 @@ export default function MakeJournalFloatingAction() {
}
@@ -146,6 +146,7 @@ export default function MakeJournalFloatingAction() {