mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feat: Edit make journal entries.
This commit is contained in:
@@ -13,21 +13,23 @@ import {compose} from 'utils';
|
||||
import useAsync from 'hooks/async';
|
||||
import moment from 'moment';
|
||||
import AppToaster from 'components/AppToaster';
|
||||
import {pick, omit} from 'lodash';
|
||||
|
||||
function MakeJournalEntriesForm({
|
||||
makeJournalEntries,
|
||||
fetchAccounts,
|
||||
requestMakeJournalEntries,
|
||||
requestEditManualJournal,
|
||||
changePageTitle,
|
||||
changePageSubtitle,
|
||||
editJournal,
|
||||
}) {
|
||||
useEffect(() => {
|
||||
changePageTitle('New Journal');
|
||||
}, []);
|
||||
|
||||
const fetchHook = useAsync(async () => {
|
||||
await Promise.all([
|
||||
fetchAccounts(),
|
||||
]);
|
||||
});
|
||||
if (editJournal && editJournal.id) {
|
||||
changePageTitle('Edit Journal');
|
||||
changePageSubtitle(`No. ${editJournal.journal_number}`);
|
||||
} else {
|
||||
changePageTitle('New Journal');
|
||||
}
|
||||
}, [changePageTitle, changePageSubtitle, editJournal]);
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
journal_number: Yup.string().required(),
|
||||
@@ -54,22 +56,31 @@ function MakeJournalEntriesForm({
|
||||
note: '',
|
||||
}), []);
|
||||
|
||||
const initialValues = useMemo(() => ({
|
||||
journal_number: '',
|
||||
date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
description: '',
|
||||
reference: '',
|
||||
entries: [
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
],
|
||||
}), [defaultEntry]);
|
||||
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
validationSchema,
|
||||
initialValues: {
|
||||
journal_number: '',
|
||||
date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
description: '',
|
||||
reference: '',
|
||||
entries: [
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
defaultEntry,
|
||||
],
|
||||
...(editJournal) ? {
|
||||
...pick(editJournal, Object.keys(initialValues)),
|
||||
entries: editJournal.entries.map((entry) => ({
|
||||
...pick(entry, Object.keys(defaultEntry)),
|
||||
}))
|
||||
} : {
|
||||
...initialValues,
|
||||
}
|
||||
},
|
||||
onSubmit: (values, actions) => {
|
||||
const form = values.entries.filter((entry) => (
|
||||
@@ -87,18 +98,31 @@ function MakeJournalEntriesForm({
|
||||
AppToaster.show({
|
||||
message: 'credit_and_debit_not_equal',
|
||||
});
|
||||
actions.setSubmitting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
makeJournalEntries({ ...values, entries: form })
|
||||
.then((response) => {
|
||||
AppToaster.show({
|
||||
message: 'manual_journal_has_been_submit',
|
||||
});
|
||||
actions.setSubmitting(false);
|
||||
}).catch((error) => {
|
||||
actions.setSubmitting(false);
|
||||
});
|
||||
|
||||
if (editJournal && editJournal.id) {
|
||||
requestEditManualJournal(editJournal.id, { ...values, entries: form })
|
||||
.then((response) => {
|
||||
AppToaster.show({
|
||||
message: 'manual_journal_has_been_edited',
|
||||
});
|
||||
actions.setSubmitting(false);
|
||||
}).catch((error) => {
|
||||
actions.setSubmitting(false);
|
||||
});
|
||||
} else {
|
||||
requestMakeJournalEntries({ ...values, entries: form })
|
||||
.then((response) => {
|
||||
AppToaster.show({
|
||||
message: 'manual_journal_has_been_submit',
|
||||
});
|
||||
actions.setSubmitting(false);
|
||||
}).catch((error) => {
|
||||
actions.setSubmitting(false);
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -21,12 +21,13 @@ export default function MakeJournalEntriesHeader({
|
||||
}) {
|
||||
const intl = useIntl();
|
||||
|
||||
const handleDateChange = (date) => {
|
||||
const handleDateChange = useCallback((date) => {
|
||||
const formatted = moment(date).format('YYYY-MM-DD');
|
||||
formik.setFieldValue('date', formatted);
|
||||
};
|
||||
}, [formik]);
|
||||
|
||||
const infoIcon = useMemo(() => (<Icon icon="info-circle" iconSize={12} />), []);
|
||||
const infoIcon = useMemo(() =>
|
||||
(<Icon icon="info-circle" iconSize={12} />), []);
|
||||
|
||||
return (
|
||||
<div class="make-journal-entries__header">
|
||||
|
||||
@@ -1,14 +1,39 @@
|
||||
import React from 'react';
|
||||
import React, {useMemo} from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useAsync } from 'react-use';
|
||||
import MakeJournalEntriesForm from './MakeJournalEntriesForm';
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
import DashboardConnect from 'connectors/Dashboard.connector';
|
||||
import {compose} from 'utils';
|
||||
import MakeJournalEntriesConnect from 'connectors/MakeJournalEntries.connect';
|
||||
import AccountsConnect from 'connectors/Accounts.connector';
|
||||
|
||||
function MakeJournalEntriesPage({
|
||||
fetchManualJournal,
|
||||
getManualJournal,
|
||||
fetchAccounts,
|
||||
}) {
|
||||
const { id } = useParams();
|
||||
|
||||
const fetchJournal = useAsync(() => {
|
||||
return Promise.all([
|
||||
fetchAccounts(),
|
||||
(id) && fetchManualJournal(id),
|
||||
]);
|
||||
});
|
||||
const editJournal = useMemo(() =>
|
||||
getManualJournal(id) || null,
|
||||
[getManualJournal, id]);
|
||||
|
||||
function MakeJournalEntriesPage() {
|
||||
return (
|
||||
<MakeJournalEntriesForm />
|
||||
<LoadingIndicator loading={fetchJournal.loading} mount={false}>
|
||||
<MakeJournalEntriesForm editJournal={editJournal} />
|
||||
</LoadingIndicator>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
DashboardConnect,
|
||||
AccountsConnect,
|
||||
MakeJournalEntriesConnect,
|
||||
)(MakeJournalEntriesPage);
|
||||
@@ -70,6 +70,9 @@ const NoteCellRenderer = (chainedComponent) => (props) => {
|
||||
return chainedComponent(props);
|
||||
};
|
||||
|
||||
/**
|
||||
* Make journal entries table component.
|
||||
*/
|
||||
function MakeJournalEntriesTable({
|
||||
formik,
|
||||
accounts,
|
||||
@@ -79,6 +82,8 @@ function MakeJournalEntriesTable({
|
||||
}) {
|
||||
const [rows, setRow] = useState([
|
||||
...formik.values.entries.map((e) => ({ ...e, rowType: 'editor'})),
|
||||
defaultRow,
|
||||
defaultRow,
|
||||
]);
|
||||
|
||||
// Handles update datatable data.
|
||||
@@ -101,11 +106,15 @@ function MakeJournalEntriesTable({
|
||||
// Handles click remove datatable row.
|
||||
const handleRemoveRow = useCallback((rowIndex) => {
|
||||
const removeIndex = parseInt(rowIndex, 10);
|
||||
setRow([
|
||||
...rows.filter((row, index) => index !== removeIndex),
|
||||
]);
|
||||
const newRows = rows.filter((row, index) => index !== removeIndex);
|
||||
|
||||
setRow([ ...newRows ]);
|
||||
formik.setFieldValue('entries', newRows
|
||||
.filter(row => row.rowType === 'editor')
|
||||
.map(row => ({ ...omit(row, ['rowType']) })
|
||||
));
|
||||
onClickRemoveRow && onClickRemoveRow(removeIndex);
|
||||
}, [rows, onClickRemoveRow]);
|
||||
}, [rows, formik, onClickRemoveRow]);
|
||||
|
||||
// Memorized data table columns.
|
||||
const columns = useMemo(() => [
|
||||
@@ -123,7 +132,7 @@ function MakeJournalEntriesTable({
|
||||
{
|
||||
Header: 'Account',
|
||||
id: 'account_id',
|
||||
accessor: 'account',
|
||||
accessor: 'account_id',
|
||||
Cell: TotalAccountCellRenderer(AccountsListFieldCell),
|
||||
className: "account",
|
||||
disableSortBy: true,
|
||||
|
||||
Reference in New Issue
Block a user