mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 05:10:31 +00:00
Merge branch 'feature/manual-journals' of https://github.com/abouolia/Ratteb
This commit is contained in:
@@ -7,6 +7,8 @@ import { FormattedList } from 'react-intl';
|
||||
|
||||
export default function MakeJournalEntriesFooter({
|
||||
formik,
|
||||
onSubmitClick,
|
||||
onCancelClick,
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
@@ -14,28 +16,38 @@ export default function MakeJournalEntriesFooter({
|
||||
<Button
|
||||
disabled={formik.isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
type="submit">
|
||||
name={'save'}
|
||||
onClick={() => {
|
||||
onSubmitClick({ publish: true, redirect: true });
|
||||
}}>
|
||||
Save
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
disabled={formik.isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
type="submit"
|
||||
className={'ml1'}>
|
||||
className={'ml1'}
|
||||
name={'save_and_new'}
|
||||
onClick={() => {
|
||||
onSubmitClick({ publish: true, redirect: false });
|
||||
}}>
|
||||
Save & New
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
disabled={formik.isSubmitting}
|
||||
type="submit"
|
||||
className={'button-secondary ml1'}>
|
||||
className={'button-secondary ml1'}
|
||||
onClick={() => {
|
||||
onSubmitClick({ publish: false, redirect: false });
|
||||
}}>
|
||||
Save as Draft
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
className={'button-secondary ml1'}>
|
||||
className={'button-secondary ml1'}
|
||||
onClick={() => {
|
||||
onCancelClick && onCancelClick();
|
||||
}}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
|
||||
import React, {useMemo, useEffect} from 'react';
|
||||
import React, {useMemo, useState, useEffect, useCallback} from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import MakeJournalEntriesHeader from './MakeJournalEntriesHeader';
|
||||
import MakeJournalEntriesFooter from './MakeJournalEntriesFooter';
|
||||
@@ -10,10 +8,9 @@ import MakeJournalEntriesConnect from 'connectors/MakeJournalEntries.connect';
|
||||
import AccountsConnect from 'connectors/Accounts.connector';
|
||||
import DashboardConnect from 'connectors/Dashboard.connector';
|
||||
import {compose} from 'utils';
|
||||
import useAsync from 'hooks/async';
|
||||
import moment from 'moment';
|
||||
import AppToaster from 'components/AppToaster';
|
||||
import {pick, omit} from 'lodash';
|
||||
import {pick} from 'lodash';
|
||||
|
||||
function MakeJournalEntriesForm({
|
||||
requestMakeJournalEntries,
|
||||
@@ -21,6 +18,8 @@ function MakeJournalEntriesForm({
|
||||
changePageTitle,
|
||||
changePageSubtitle,
|
||||
editJournal,
|
||||
onFormSubmit,
|
||||
onCancelForm,
|
||||
}) {
|
||||
useEffect(() => {
|
||||
if (editJournal && editJournal.id) {
|
||||
@@ -49,6 +48,12 @@ function MakeJournalEntriesForm({
|
||||
)
|
||||
});
|
||||
|
||||
const saveInvokeSubmit = useCallback((payload) => {
|
||||
onFormSubmit && onFormSubmit(payload)
|
||||
}, [onFormSubmit]);
|
||||
|
||||
const [payload, setPayload] = useState({});
|
||||
|
||||
const defaultEntry = useMemo(() => ({
|
||||
account_id: null,
|
||||
credit: 0,
|
||||
@@ -83,11 +88,11 @@ function MakeJournalEntriesForm({
|
||||
}
|
||||
},
|
||||
onSubmit: (values, actions) => {
|
||||
const form = values.entries.filter((entry) => (
|
||||
const entries = values.entries.filter((entry) => (
|
||||
(entry.credit || entry.debit)
|
||||
));
|
||||
const getTotal = (type = 'credit') => {
|
||||
return form.reduce((total, item) => {
|
||||
return entries.reduce((total, item) => {
|
||||
return item[type] ? item[type] + total : total;
|
||||
}, 0);
|
||||
}
|
||||
@@ -101,24 +106,27 @@ function MakeJournalEntriesForm({
|
||||
actions.setSubmitting(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const form = { ...values, status: payload.publish, entries };
|
||||
|
||||
if (editJournal && editJournal.id) {
|
||||
requestEditManualJournal(editJournal.id, { ...values, entries: form })
|
||||
requestEditManualJournal(editJournal.id, form)
|
||||
.then((response) => {
|
||||
AppToaster.show({
|
||||
message: 'manual_journal_has_been_edited',
|
||||
});
|
||||
actions.setSubmitting(false);
|
||||
saveInvokeSubmit({ action: 'update', ...payload });
|
||||
}).catch((error) => {
|
||||
actions.setSubmitting(false);
|
||||
});
|
||||
} else {
|
||||
requestMakeJournalEntries({ ...values, entries: form })
|
||||
requestMakeJournalEntries(form)
|
||||
.then((response) => {
|
||||
AppToaster.show({
|
||||
message: 'manual_journal_has_been_submit',
|
||||
});
|
||||
actions.setSubmitting(false);
|
||||
saveInvokeSubmit({ action: 'new', ...payload });
|
||||
}).catch((error) => {
|
||||
actions.setSubmitting(false);
|
||||
});
|
||||
@@ -126,12 +134,24 @@ function MakeJournalEntriesForm({
|
||||
},
|
||||
});
|
||||
|
||||
const handleSubmitClick = useCallback((payload) => {
|
||||
setPayload(payload);
|
||||
formik.handleSubmit();
|
||||
}, [setPayload, formik]);
|
||||
|
||||
const handleCancelClick = useCallback((payload) => {
|
||||
onCancelForm && onCancelForm(payload);
|
||||
}, [onCancelForm]);
|
||||
|
||||
return (
|
||||
<div class="make-journal-entries">
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<MakeJournalEntriesHeader formik={formik} />
|
||||
<MakeJournalEntriesTable formik={formik} defaultRow={defaultEntry} />
|
||||
<MakeJournalEntriesFooter formik={formik} />
|
||||
<MakeJournalEntriesFooter
|
||||
formik={formik}
|
||||
onSubmitClick={handleSubmitClick}
|
||||
onCancelClick={handleCancelClick} />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import React, {useMemo, useCallback} from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import {
|
||||
InputGroup,
|
||||
FormGroup,
|
||||
Intent,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import {DatePicker, DateInput} from '@blueprintjs/datetime';
|
||||
import {Formik, useFormik} from "formik";
|
||||
import {DateInput} from '@blueprintjs/datetime';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Row, Col} from 'react-grid-system';
|
||||
import moment from 'moment';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, {useMemo} from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import React, {useMemo, useCallback} from 'react';
|
||||
import { useParams, useHistory } from 'react-router-dom';
|
||||
import { useAsync } from 'react-use';
|
||||
import MakeJournalEntriesForm from './MakeJournalEntriesForm';
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
@@ -13,6 +13,7 @@ function MakeJournalEntriesPage({
|
||||
getManualJournal,
|
||||
fetchAccounts,
|
||||
}) {
|
||||
const history = useHistory();
|
||||
const { id } = useParams();
|
||||
|
||||
const fetchJournal = useAsync(() => {
|
||||
@@ -25,9 +26,21 @@ function MakeJournalEntriesPage({
|
||||
getManualJournal(id) || null,
|
||||
[getManualJournal, id]);
|
||||
|
||||
const handleFormSubmit = useCallback((payload) => {
|
||||
payload.redirect &&
|
||||
history.push('/dashboard/accounting/manual-journals');
|
||||
}, [history]);
|
||||
|
||||
const handleCancel = useCallback(() => {
|
||||
history.push('/dashboard/accounting/manual-journals');
|
||||
}, [history]);
|
||||
|
||||
return (
|
||||
<LoadingIndicator loading={fetchJournal.loading} mount={false}>
|
||||
<MakeJournalEntriesForm editJournal={editJournal} />
|
||||
<MakeJournalEntriesForm
|
||||
onFormSubmit={handleFormSubmit}
|
||||
editJournal={editJournal}
|
||||
onCancelForm={handleCancel} />
|
||||
</LoadingIndicator>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import { Route, Switch, useHistory } from 'react-router-dom';
|
||||
import useAsync from 'hooks/async';
|
||||
import { Alert, Intent } from '@blueprintjs/core';
|
||||
import AppToaster from 'components/AppToaster';
|
||||
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
|
||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||
import ManualJournalsViewTabs from 'components/JournalEntry/ManualJournalsViewTabs';
|
||||
import ManualJournalsDataTable from 'components/JournalEntry/ManualJournalsDataTable';
|
||||
import DashboardActionsBar from 'components/JournalEntry/ManualJournalActionsBar';
|
||||
import ManualJournalsConnect from 'connectors/ManualJournals.connect';
|
||||
import DashboardConnect from 'connectors/Dashboard.connector';
|
||||
import CustomViewConnect from 'connectors/CustomView.connector';
|
||||
import ResourceConnect from 'connectors/Resource.connector';
|
||||
import { compose } from 'utils';
|
||||
|
||||
function ManualJournalsTable({
|
||||
changePageTitle,
|
||||
fetchResourceViews,
|
||||
fetchManualJournalsTable,
|
||||
requestDeleteManualJournal,
|
||||
requestPublishManualJournal,
|
||||
}) {
|
||||
const history = useHistory();
|
||||
const [deleteManualJournal, setDeleteManualJournal] = useState(false);
|
||||
|
||||
const fetchHook = useAsync(async () => {
|
||||
await Promise.all([
|
||||
fetchResourceViews('manual_journals'),
|
||||
]);
|
||||
});
|
||||
|
||||
const fetchManualJournalsHook = useAsync(async () => {
|
||||
return fetchManualJournalsTable();
|
||||
}, false);
|
||||
|
||||
useEffect(() => {
|
||||
changePageTitle('Manual Journals');
|
||||
}, []);
|
||||
|
||||
const handleCancelManualJournalDelete = () => {
|
||||
setDeleteManualJournal(false);
|
||||
};
|
||||
|
||||
const handleConfirmManualJournalDelete = useCallback(() => {
|
||||
requestDeleteManualJournal(deleteManualJournal.id).then(() => {
|
||||
setDeleteManualJournal(false);
|
||||
AppToaster.show({ message: 'the_manual_Journal_has_been_deleted' });
|
||||
});
|
||||
}, [deleteManualJournal, requestDeleteManualJournal]);
|
||||
|
||||
const handleEditJournal = useCallback((journal) => {
|
||||
history.push(`/dashboard/accounting/manual-journals/${journal.id}/edit`);
|
||||
}, [history]);
|
||||
|
||||
const handleDeleteJournal = useCallback((journal) => {
|
||||
setDeleteManualJournal(journal);
|
||||
}, []);
|
||||
|
||||
const handleFilterChanged = useCallback(() => {
|
||||
fetchManualJournalsHook.execute();
|
||||
}, []);
|
||||
|
||||
const handleViewChanged = useCallback(() => {
|
||||
fetchManualJournalsHook.execute();
|
||||
}, []);
|
||||
|
||||
const handleFetchData = useCallback(() => {
|
||||
fetchManualJournalsHook.execute();
|
||||
}, []);
|
||||
|
||||
const handlePublishJournal = useCallback((journal) => {
|
||||
requestPublishManualJournal(journal.id).then(() => {
|
||||
AppToaster.show({ message: 'the_manual_journal_id_has_been_published' });
|
||||
})
|
||||
}, [requestPublishManualJournal]);
|
||||
|
||||
return (
|
||||
<DashboardInsider loading={fetchHook.pending} name={'manual-journals'}>
|
||||
<DashboardActionsBar
|
||||
onFilterChanged={handleFilterChanged} />
|
||||
|
||||
<DashboardPageContent>
|
||||
<Switch>
|
||||
<Route
|
||||
exact={true}
|
||||
path={[
|
||||
'/dashboard/accounting/manual-journals/:custom_view_id/custom_view',
|
||||
'/dashboard/accounting/manual-journals',
|
||||
]}>
|
||||
<ManualJournalsViewTabs
|
||||
onViewChanged={handleViewChanged} />
|
||||
</Route>
|
||||
</Switch>
|
||||
|
||||
<ManualJournalsDataTable
|
||||
onDeleteJournal={handleDeleteJournal}
|
||||
onFetchData={handleFetchData}
|
||||
onEditJournal={handleEditJournal}
|
||||
onPublishJournal={handlePublishJournal} />
|
||||
|
||||
<Alert
|
||||
cancelButtonText='Cancel'
|
||||
confirmButtonText='Move to Trash'
|
||||
icon='trash'
|
||||
intent={Intent.DANGER}
|
||||
isOpen={deleteManualJournal}
|
||||
onCancel={handleCancelManualJournalDelete}
|
||||
onConfirm={handleConfirmManualJournalDelete}
|
||||
>
|
||||
<p>
|
||||
Are you sure you want to move <b>filename</b> to Trash? You will be
|
||||
able to restore it later, but it will become private to you.
|
||||
</p>
|
||||
</Alert>
|
||||
</DashboardPageContent>
|
||||
</DashboardInsider>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
ManualJournalsConnect,
|
||||
CustomViewConnect,
|
||||
ResourceConnect,
|
||||
DashboardConnect
|
||||
)(ManualJournalsTable);
|
||||
Reference in New Issue
Block a user