mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
feat: Financial statements enhancement.
This commit is contained in:
@@ -97,6 +97,7 @@ function MakeJournalEntriesForm({
|
||||
is: (credit, debit) => credit || debit,
|
||||
then: Yup.number().required(),
|
||||
}),
|
||||
contact_id: Yup.number().nullable(),
|
||||
note: Yup.string().nullable(),
|
||||
}),
|
||||
),
|
||||
@@ -114,6 +115,7 @@ function MakeJournalEntriesForm({
|
||||
const defaultEntry = useMemo(
|
||||
() => ({
|
||||
account_id: null,
|
||||
contact_id: null,
|
||||
credit: 0,
|
||||
debit: 0,
|
||||
note: '',
|
||||
|
||||
@@ -30,7 +30,7 @@ export default function MakeJournalEntriesHeader({
|
||||
return (
|
||||
<div class="make-journal-entries__header">
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={<T id={'journal_number'}/>}
|
||||
labelInfo={infoIcon}
|
||||
@@ -46,7 +46,7 @@ export default function MakeJournalEntriesHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={2}>
|
||||
<Col width={220}>
|
||||
<FormGroup
|
||||
label={<T id={'date'}/>}
|
||||
intent={(errors.date && touched.date) && Intent.DANGER}
|
||||
@@ -61,7 +61,7 @@ export default function MakeJournalEntriesHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={4}>
|
||||
<Col width={400}>
|
||||
<FormGroup
|
||||
label={<T id={'description'}/>}
|
||||
className={'form-group--description'}
|
||||
@@ -78,7 +78,7 @@ export default function MakeJournalEntriesHeader({
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={<T id={'reference'}/>}
|
||||
labelInfo={infoIcon}
|
||||
@@ -94,7 +94,7 @@ export default function MakeJournalEntriesHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={4}>
|
||||
<Col width={220}>
|
||||
<CurrenciesSelectList />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useParams, useHistory } from 'react-router-dom';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import MakeJournalEntriesForm from './MakeJournalEntriesForm';
|
||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||
|
||||
import withCustomersActions from 'containers/Customers/withCustomersActions';
|
||||
import withAccountsActions from 'containers/Accounts/withAccountsActions';
|
||||
import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
|
||||
|
||||
@@ -11,8 +13,14 @@ import {compose} from 'utils';
|
||||
|
||||
|
||||
function MakeJournalEntriesPage({
|
||||
requestFetchManualJournal,
|
||||
// #withCustomersActions
|
||||
requestFetchCustomers,
|
||||
|
||||
// #withAccountsActions
|
||||
requestFetchAccounts,
|
||||
|
||||
// #withManualJournalActions
|
||||
requestFetchManualJournal,
|
||||
}) {
|
||||
const history = useHistory();
|
||||
const { id } = useParams();
|
||||
@@ -20,6 +28,9 @@ function MakeJournalEntriesPage({
|
||||
const fetchAccounts = useQuery('accounts-list',
|
||||
(key) => requestFetchAccounts());
|
||||
|
||||
const fetchCustomers = useQuery('customers-list',
|
||||
(key) => requestFetchCustomers());
|
||||
|
||||
const fetchJournal = useQuery(
|
||||
id && ['manual-journal', id],
|
||||
(key, journalId) => requestFetchManualJournal(journalId));
|
||||
@@ -35,7 +46,11 @@ function MakeJournalEntriesPage({
|
||||
|
||||
return (
|
||||
<DashboardInsider
|
||||
loading={fetchJournal.isFetching || fetchAccounts.isFetching}
|
||||
loading={
|
||||
fetchJournal.isFetching ||
|
||||
fetchAccounts.isFetching ||
|
||||
fetchCustomers.isFetching
|
||||
}
|
||||
name={'make-journal-page'}>
|
||||
<MakeJournalEntriesForm
|
||||
onFormSubmit={handleFormSubmit}
|
||||
@@ -47,5 +62,6 @@ function MakeJournalEntriesPage({
|
||||
|
||||
export default compose(
|
||||
withAccountsActions,
|
||||
withCustomersActions,
|
||||
withManualJournalsActions,
|
||||
)(MakeJournalEntriesPage);
|
||||
@@ -1,17 +1,20 @@
|
||||
import React, { useState, useMemo, useEffect, useCallback } from 'react';
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import DataTable from 'components/DataTable';
|
||||
import Icon from 'components/Icon';
|
||||
import { Hint } from 'components';
|
||||
import { compose, formattedAmount } from 'utils';
|
||||
import {
|
||||
AccountsListFieldCell,
|
||||
MoneyFieldCell,
|
||||
InputGroupCell,
|
||||
ContactsListFieldCell,
|
||||
} from 'components/DataTableCells';
|
||||
import { omit } from 'lodash';
|
||||
import withAccounts from 'containers/Accounts/withAccounts';
|
||||
import withCustomers from 'containers/Customers/withCustomers';
|
||||
|
||||
// Actions cell renderer.
|
||||
const ActionsCellRenderer = ({
|
||||
@@ -73,6 +76,9 @@ const NoteCellRenderer = (chainedComponent) => (props) => {
|
||||
* Make journal entries table component.
|
||||
*/
|
||||
function MakeJournalEntriesTable({
|
||||
// #withCustomers
|
||||
customers,
|
||||
|
||||
// #withAccounts
|
||||
accounts,
|
||||
|
||||
@@ -142,6 +148,7 @@ function MakeJournalEntriesTable({
|
||||
width: 40,
|
||||
disableResizing: true,
|
||||
disableSortBy: true,
|
||||
sticky: 'left',
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'account' }),
|
||||
@@ -171,6 +178,16 @@ function MakeJournalEntriesTable({
|
||||
disableResizing: true,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
Header: (<><T id={'contact'} /><Hint /></>),
|
||||
id: 'contact_id',
|
||||
accessor: 'contact_id',
|
||||
Cell: NoteCellRenderer(ContactsListFieldCell),
|
||||
className: 'contact',
|
||||
disableResizing: true,
|
||||
disableSortBy: true,
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'note' }),
|
||||
accessor: 'note',
|
||||
@@ -216,6 +233,11 @@ function MakeJournalEntriesTable({
|
||||
errors: errors.entries || [],
|
||||
updateData: handleUpdateData,
|
||||
removeRow: handleRemoveRow,
|
||||
contacts: [
|
||||
...customers.map((customer) => ({
|
||||
...customer, contact_type: 'customer',
|
||||
})),
|
||||
],
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -244,4 +266,7 @@ export default compose(
|
||||
withAccounts(({ accounts }) => ({
|
||||
accounts,
|
||||
})),
|
||||
withCustomers(({ customersItems }) => ({
|
||||
customers: customersItems,
|
||||
})),
|
||||
)(MakeJournalEntriesTable);
|
||||
|
||||
@@ -7,6 +7,7 @@ export default (mapState) => {
|
||||
|
||||
const mapped = {
|
||||
customersViews: getResourceViews(state, 'customers'),
|
||||
customersItems: Object.values(state.customers.items),
|
||||
customers: getCustomersItems(state, state.customers.currentViewId),
|
||||
customersLoading: state.customers.loading,
|
||||
customerErrors: state.customers.errors,
|
||||
|
||||
@@ -121,6 +121,17 @@ function ExpenseDataTable({
|
||||
[handleEditExpense, handleDeleteExpense, handlePublishExpense],
|
||||
);
|
||||
|
||||
const expenseAccountAccessor = (expense) => {
|
||||
if (expense.categories.length === 1) {
|
||||
return expense.categories[0].expense_account.name;
|
||||
} else if (expense.categories.length > 1) {
|
||||
const mutliCategories = expense.categories.map(category =>
|
||||
(<div>- {category.expense_account.name} ${ category.amount }</div>)
|
||||
);
|
||||
return <Tooltip content={mutliCategories}>{ '- Multi Categories -' }</Tooltip>;
|
||||
}
|
||||
}
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -155,11 +166,10 @@ function ExpenseDataTable({
|
||||
{
|
||||
id: 'expense_account_id',
|
||||
Header: formatMessage({ id: 'expense_account' }),
|
||||
accessor:'expense_account_id',
|
||||
accessor: expenseAccountAccessor,
|
||||
width: 150,
|
||||
className: 'expense_account',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'publish',
|
||||
Header: formatMessage({ id: 'publish' }),
|
||||
|
||||
@@ -12,10 +12,11 @@ import { Intent, FormGroup, TextArea } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { pick } from 'lodash';
|
||||
import { useQuery } from 'react-query';
|
||||
import { Col, Row } from 'react-grid-system';
|
||||
|
||||
import ExpenseFormHeader from './ExpenseFormHeader';
|
||||
import ExpenseTable from './ExpenseTable';
|
||||
import ExpenseFooter from './ExpenseFooter';
|
||||
import ExpenseFloatingFooter from './ExpenseFooter';
|
||||
|
||||
import withExpensesActions from 'containers/Expenses/withExpensesActions';
|
||||
import withExpneseDetail from 'containers/Expenses/withExpenseDetail';
|
||||
@@ -76,11 +77,11 @@ function ExpenseForm({
|
||||
useEffect(() => {
|
||||
if (expenseDetail && expenseDetail.id) {
|
||||
changePageTitle(formatMessage({ id: 'edit_expense' }));
|
||||
changePageSubtitle(`No. ${expenseDetail.payment_account_id}`);
|
||||
// changePageSubtitle(`No. ${expenseDetail.payment_account_id}`);
|
||||
} else {
|
||||
changePageTitle(formatMessage({ id: 'new_expense' }));
|
||||
}
|
||||
// @todo not functions just states.
|
||||
// @todo not functions just states.
|
||||
}, [changePageTitle, changePageSubtitle, expenseDetail, formatMessage]);
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
@@ -137,7 +138,6 @@ function ExpenseForm({
|
||||
reference_no: '',
|
||||
currency_code: '',
|
||||
categories: [
|
||||
// @todo @mohamed index
|
||||
defaultCategory,
|
||||
defaultCategory,
|
||||
defaultCategory,
|
||||
@@ -154,7 +154,8 @@ function ExpenseForm({
|
||||
...pick(expenseDetail, Object.keys(defaultInitialValues)),
|
||||
categories: expenseDetail.categories.map((category) => ({
|
||||
...pick(category, Object.keys(defaultCategory)),
|
||||
})),
|
||||
}),
|
||||
),
|
||||
}
|
||||
: {
|
||||
...defaultInitialValues,
|
||||
@@ -257,7 +258,7 @@ function ExpenseForm({
|
||||
},
|
||||
});
|
||||
|
||||
console.log(formik.errors);
|
||||
console.log(formik.values, 'VALUES');
|
||||
|
||||
const handleSubmitClick = useCallback(
|
||||
(payload) => {
|
||||
@@ -298,29 +299,32 @@ function ExpenseForm({
|
||||
defaultRow={defaultCategory}
|
||||
/>
|
||||
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
{...formik.getFieldProps('description')}
|
||||
/>
|
||||
</FormGroup>
|
||||
<div class="expense-form-footer">
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
{...formik.getFieldProps('description')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<ExpenseFooter
|
||||
<Dragzone
|
||||
initialFiles={initialAttachmentFiles}
|
||||
onDrop={handleDropFiles}
|
||||
onDeleteFile={handleDeleteFile}
|
||||
hint={'Attachments: Maxiumum size: 20MB'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ExpenseFloatingFooter
|
||||
formik={formik}
|
||||
onSubmitClick={handleSubmitClick}
|
||||
onCancelClick={handleCancelClick}
|
||||
/>
|
||||
</form>
|
||||
<Dragzone
|
||||
initialFiles={initialAttachmentFiles}
|
||||
onDrop={handleDropFiles}
|
||||
onDeleteFile={handleDeleteFile}
|
||||
hint={'Attachments: Maxiumum size: 20MB'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ function ExpenseFormHeader({
|
||||
return (
|
||||
<div className={'dashboard__insider--expense-form__header'}>
|
||||
<Row>
|
||||
<Col sm={3.5}>
|
||||
<Col width={300}>
|
||||
<FormGroup
|
||||
label={<T id={'beneficiary'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
@@ -141,7 +141,8 @@ function ExpenseFormHeader({
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<Col sm={3}>
|
||||
|
||||
<Col width={400}>
|
||||
<FormGroup
|
||||
label={<T id={'payment_account'} />}
|
||||
className={classNames(
|
||||
@@ -177,8 +178,9 @@ function ExpenseFormHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col sm={3.5}>
|
||||
<Col width={300}>
|
||||
<FormGroup
|
||||
label={<T id={'payment_date'} />}
|
||||
labelInfo={infoIcon}
|
||||
@@ -189,17 +191,17 @@ function ExpenseFormHeader({
|
||||
helperText={
|
||||
<ErrorMessage name="payment_date" {...{ errors, touched }} />
|
||||
}
|
||||
minimal={true}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
defaultValue={new Date()}
|
||||
onChange={handleDateChange}
|
||||
popoverProps={{ position: Position.BOTTOM }}
|
||||
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<Col sm={2}>
|
||||
|
||||
<Col width={200}>
|
||||
<FormGroup
|
||||
label={<T id={'currency'} />}
|
||||
className={classNames(
|
||||
@@ -223,23 +225,25 @@ function ExpenseFormHeader({
|
||||
onItemSelect={onItemsSelect('currency_code')}
|
||||
selectedItem={values.currency_code}
|
||||
selectedItemProp={'currency_code'}
|
||||
defaultText={<T id={'select_currency_code'} />}
|
||||
defaultText={<T id={'select_currency'} />}
|
||||
labelProp={'currency_code'}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={200}>
|
||||
<FormGroup
|
||||
label={<T id={'ref_no'} />}
|
||||
className={'form-group--ref_no'}
|
||||
className={classNames(
|
||||
'form-group--ref_no',
|
||||
Classes.FILL,
|
||||
)}
|
||||
intent={
|
||||
errors.reference_no && touched.reference_no && Intent.DANGER
|
||||
}
|
||||
helperText={
|
||||
<ErrorMessage name="reference_no" {...{ errors, touched }} />
|
||||
}
|
||||
minimal={true}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { useState, useMemo, useEffect, useCallback } from 'react';
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { Button, Intent, Position, Tooltip } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
|
||||
import DataTable from 'components/DataTable';
|
||||
import Icon from 'components/Icon';
|
||||
import { Hint } from 'components';
|
||||
import { compose, formattedAmount } from 'utils';
|
||||
import {
|
||||
AccountsListFieldCell,
|
||||
@@ -88,14 +89,16 @@ function ExpenseTable({
|
||||
payload.removeRow(index);
|
||||
};
|
||||
return (
|
||||
<Button
|
||||
icon={<Icon icon="times-circle" iconSize={14} />}
|
||||
iconSize={14}
|
||||
className="ml2"
|
||||
minimal={true}
|
||||
intent={Intent.DANGER}
|
||||
onClick={onClickRemoveRole}
|
||||
/>
|
||||
<Tooltip content={<T id={'remove_the_line'} />} position={Position.LEFT}>
|
||||
<Button
|
||||
icon={<Icon icon="times-circle" iconSize={14} />}
|
||||
iconSize={14}
|
||||
className="ml2"
|
||||
minimal={true}
|
||||
intent={Intent.DANGER}
|
||||
onClick={onClickRemoveRole}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -144,8 +147,7 @@ function ExpenseTable({
|
||||
disableSortBy: true,
|
||||
},
|
||||
{
|
||||
// @todo Add hint component after the header label.
|
||||
Header: formatMessage({ id: 'expense_category' }),
|
||||
Header: (<>{ formatMessage({ id: 'expense_category' }) }<Hint /></>),
|
||||
id: 'expense_account_id',
|
||||
accessor: 'expense_account_id',
|
||||
Cell: TotalExpenseCellRenderer(AccountsListFieldCell),
|
||||
@@ -161,6 +163,7 @@ function ExpenseTable({
|
||||
disableSortBy: true,
|
||||
disableResizing: true,
|
||||
width: 150,
|
||||
className: 'amount',
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'description' }),
|
||||
@@ -195,7 +198,6 @@ function ExpenseTable({
|
||||
[rows],
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<div className={'dashboard__insider--expense-form__table'}>
|
||||
<DataTable
|
||||
@@ -235,5 +237,4 @@ export default compose(
|
||||
withAccounts(({ accounts }) => ({
|
||||
accounts,
|
||||
})),
|
||||
|
||||
)(ExpenseTable);
|
||||
|
||||
@@ -12,6 +12,7 @@ import ExpenseDataTable from 'containers/Expenses/ExpenseDataTable';
|
||||
import ExpenseActionsBar from 'containers/Expenses/ExpenseActionsBar';
|
||||
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withExpenses from 'containers/Expenses/withExpenses';
|
||||
import withExpensesActions from 'containers/Expenses/withExpensesActions';
|
||||
import withViewsActions from 'containers/Views/withViewsActions';
|
||||
|
||||
@@ -24,6 +25,9 @@ function ExpensesList({
|
||||
// #withViewsActions
|
||||
requestFetchResourceViews,
|
||||
|
||||
// #withExpenses
|
||||
expensesTableQuery,
|
||||
|
||||
//#withExpensesActions
|
||||
requestFetchExpensesTable,
|
||||
requestDeleteExpense,
|
||||
@@ -44,8 +48,9 @@ function ExpensesList({
|
||||
return requestFetchResourceViews('expenses');
|
||||
});
|
||||
|
||||
const fetchExpenses = useQuery('expenses-table', () =>
|
||||
requestFetchExpensesTable(),
|
||||
const fetchExpenses = useQuery(
|
||||
['expenses-table', expensesTableQuery],
|
||||
() => requestFetchExpensesTable(),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -53,7 +58,6 @@ function ExpensesList({
|
||||
}, [changePageTitle, formatMessage]);
|
||||
|
||||
// Handle delete expense click.
|
||||
|
||||
const handleDeleteExpense = useCallback(
|
||||
(expnese) => {
|
||||
setDeleteExpense(expnese);
|
||||
@@ -108,8 +112,6 @@ function ExpensesList({
|
||||
.catch((error) => {
|
||||
setBulkDelete(false);
|
||||
});
|
||||
|
||||
// @todo
|
||||
}, [requestDeleteBulkExpenses, bulkDelete, formatMessage, selectedRowsCount]);
|
||||
|
||||
// Handle cancel bulk delete alert.
|
||||
@@ -149,6 +151,7 @@ function ExpensesList({
|
||||
message: formatMessage({ id: 'the_expense_id_has_been_published' }),
|
||||
});
|
||||
});
|
||||
fetchExpenses.refetch();
|
||||
},
|
||||
[requestPublishExpense, formatMessage],
|
||||
);
|
||||
@@ -163,7 +166,7 @@ function ExpensesList({
|
||||
|
||||
return (
|
||||
<DashboardInsider
|
||||
loading={fetchViews.isFetching || fetchExpenses.isFetching}
|
||||
loading={fetchViews.isFetching}
|
||||
name={'expenses'}
|
||||
>
|
||||
<ExpenseActionsBar
|
||||
@@ -232,5 +235,6 @@ function ExpensesList({
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withExpensesActions,
|
||||
withExpenses(({ expensesTableQuery }) => ({ expensesTableQuery })),
|
||||
withViewsActions,
|
||||
)(ExpensesList);
|
||||
|
||||
@@ -26,7 +26,6 @@ function BalanceSheet({
|
||||
fetchBalanceSheet,
|
||||
|
||||
// #withBalanceSheetDetail
|
||||
balanceSheetLoading,
|
||||
balanceSheetFilter,
|
||||
|
||||
// #withPreferences
|
||||
@@ -41,6 +40,7 @@ function BalanceSheet({
|
||||
display_columns_by: '',
|
||||
none_zero: false,
|
||||
});
|
||||
const [refresh, setRefresh] = useState(true);
|
||||
|
||||
const fetchHook = useQuery(
|
||||
['balance-sheet', filter],
|
||||
@@ -50,7 +50,7 @@ function BalanceSheet({
|
||||
|
||||
// Handle fetch the data of balance sheet.
|
||||
const handleFetchData = useCallback(() => {
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -66,11 +66,18 @@ function BalanceSheet({
|
||||
to_date: moment(filter.to_date).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter({ ..._filter });
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(true);
|
||||
},
|
||||
[setFilter],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (refresh) {
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(false);
|
||||
}
|
||||
}, [refresh]);
|
||||
|
||||
return (
|
||||
<DashboardInsider>
|
||||
<BalanceSheetActionsBar />
|
||||
@@ -86,7 +93,6 @@ function BalanceSheet({
|
||||
<div class="financial-statement__body">
|
||||
<BalanceSheetTable
|
||||
companyName={organizationSettings.name}
|
||||
loading={balanceSheetLoading}
|
||||
balanceSheetQuery={filter}
|
||||
onFetchData={handleFetchData}
|
||||
/>
|
||||
@@ -100,8 +106,7 @@ function BalanceSheet({
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withBalanceSheetActions,
|
||||
withBalanceSheetDetail(({ balanceSheetLoading, balanceSheetFilter }) => ({
|
||||
balanceSheetLoading,
|
||||
withBalanceSheetDetail(({ balanceSheetFilter }) => ({
|
||||
balanceSheetFilter,
|
||||
})),
|
||||
withSettings,
|
||||
|
||||
@@ -22,8 +22,12 @@ import withBalanceSheetActions from './withBalanceSheetActions';
|
||||
|
||||
|
||||
function BalanceSheetActionsBar({
|
||||
// #withBalanceSheetDetail
|
||||
balanceSheetFilter,
|
||||
|
||||
// #withBalanceSheetActions
|
||||
toggleBalanceSheetFilter,
|
||||
refreshBalanceSheet
|
||||
}) {
|
||||
const filterDropdown = FilterDropdown({
|
||||
fields: [],
|
||||
@@ -34,6 +38,10 @@ function BalanceSheetActionsBar({
|
||||
toggleBalanceSheetFilter();
|
||||
};
|
||||
|
||||
const handleRecalcReport = () => {
|
||||
refreshBalanceSheet(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
@@ -44,6 +52,16 @@ function BalanceSheetActionsBar({
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(
|
||||
Classes.MINIMAL,
|
||||
'button--gray-highlight',
|
||||
)}
|
||||
text={<T id={'recalc_report'} />}
|
||||
onClick={handleRecalcReport}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
/>
|
||||
|
||||
<If condition={balanceSheetFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
@@ -61,7 +79,6 @@ function BalanceSheetActionsBar({
|
||||
icon={<Icon icon="arrow-to-bottom" />}
|
||||
/>
|
||||
</If>
|
||||
<NavbarDivider />
|
||||
|
||||
<Popover
|
||||
content={filterDropdown}
|
||||
@@ -75,6 +92,8 @@ function BalanceSheetActionsBar({
|
||||
/>
|
||||
</Popover>
|
||||
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon='print-16' iconSize={16} />}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import React, { useMemo, useCallback, useEffect } from 'react';
|
||||
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
import { Row, Col, Visible } from 'react-grid-system';
|
||||
import {
|
||||
Button,
|
||||
FormGroup,
|
||||
@@ -17,11 +17,19 @@ import FinancialStatementDateRange from 'containers/FinancialStatements/Financia
|
||||
import SelectDisplayColumnsBy from '../SelectDisplayColumnsBy';
|
||||
import RadiosAccountingBasis from '../RadiosAccountingBasis';
|
||||
|
||||
import withBalanceSheet from './withBalanceSheetDetail';
|
||||
import withBalanceSheetActions from './withBalanceSheetActions';
|
||||
|
||||
export default function BalanceSheetHeader({
|
||||
import { compose } from 'utils';
|
||||
|
||||
function BalanceSheetHeader({
|
||||
onSubmitFilter,
|
||||
pageFilter,
|
||||
show
|
||||
show,
|
||||
refresh,
|
||||
|
||||
// #withBalanceSheetActions
|
||||
refreshBalanceSheet
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
@@ -49,11 +57,6 @@ export default function BalanceSheetHeader({
|
||||
formik.setFieldValue('display_columns_by', item.by);
|
||||
}, [formik]);
|
||||
|
||||
// Handle submit filter submit button.
|
||||
const handleSubmitClick = useCallback(() => {
|
||||
formik.submitForm();
|
||||
}, [formik]);
|
||||
|
||||
const filterAccountsOptions = useMemo(() => [
|
||||
{ key: '', name: formatMessage({ id: 'accounts_with_zero_balance' }) },
|
||||
{ key: 'all-trans', name: formatMessage({ id: 'all_transactions' }) },
|
||||
@@ -63,24 +66,31 @@ export default function BalanceSheetHeader({
|
||||
return (<MenuItem text={item.name} key={item.id} onClick={handleClick} />);
|
||||
}, []);
|
||||
|
||||
const infoIcon = useMemo(() =>
|
||||
(<Icon icon="info-circle" iconSize={12} />), []);
|
||||
|
||||
const handleAccountingBasisChange = useCallback((value) => {
|
||||
formik.setFieldValue('basis', value);
|
||||
}, [formik]);
|
||||
|
||||
// Handle submit filter submit button.
|
||||
useEffect(() => {
|
||||
if (refresh) {
|
||||
formik.submitForm();
|
||||
refreshBalanceSheet(false);
|
||||
}
|
||||
}, [refresh]);
|
||||
|
||||
return (
|
||||
<FinancialStatementHeader show={show}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
|
||||
<Visible xl><Col width={'100%'} /></Visible>
|
||||
|
||||
<Col width={260} offset={10}>
|
||||
<SelectDisplayColumnsBy
|
||||
onItemSelect={onItemSelectDisplayColumns} />
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={<T id={'filter_accounts'} />}
|
||||
className="form-group--select-list bp3-fill"
|
||||
@@ -95,22 +105,19 @@ export default function BalanceSheetHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<RadiosAccountingBasis
|
||||
selectedValue={formik.values.basis}
|
||||
onChange={handleAccountingBasisChange} />
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmitClick}
|
||||
disabled={formik.isSubmitting}
|
||||
className={'button--submit-filter mt2'}>
|
||||
<T id={'calculate_report'} />
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</FinancialStatementHeader>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withBalanceSheet(({ balanceSheetRefresh }) => ({
|
||||
refresh: balanceSheetRefresh,
|
||||
})),
|
||||
withBalanceSheetActions,
|
||||
)(BalanceSheetHeader);
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import React, { useMemo, useEffect, useState, useCallback } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { useIntl } from 'react-intl';
|
||||
|
||||
@@ -20,23 +20,26 @@ function BalanceSheetTable({
|
||||
balanceSheetAccounts,
|
||||
balanceSheetColumns,
|
||||
balanceSheetQuery,
|
||||
balanceSheetLoading,
|
||||
|
||||
// #ownProps
|
||||
onFetchData,
|
||||
loading,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: formatMessage({ id: 'account_name' }),
|
||||
accessor: 'name',
|
||||
className: 'account_name',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'code' }),
|
||||
Header: formatMessage({ id: 'account_code' }),
|
||||
accessor: 'code',
|
||||
className: 'code',
|
||||
width: 80,
|
||||
},
|
||||
...(balanceSheetQuery.display_columns_type === 'total'
|
||||
? [
|
||||
@@ -55,7 +58,8 @@ function BalanceSheetTable({
|
||||
}
|
||||
return '';
|
||||
},
|
||||
className: 'credit',
|
||||
className: 'total',
|
||||
width: 80,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
@@ -70,7 +74,7 @@ function BalanceSheetTable({
|
||||
}
|
||||
return '';
|
||||
},
|
||||
width: 100,
|
||||
width: 80,
|
||||
}))
|
||||
: []),
|
||||
],
|
||||
@@ -89,18 +93,20 @@ function BalanceSheetTable({
|
||||
|
||||
return (
|
||||
<FinancialSheet
|
||||
name="balance-sheet"
|
||||
companyName={organizationSettings.name}
|
||||
sheetType={formatMessage({ id: 'balance_sheet' })}
|
||||
fromDate={balanceSheetQuery.from_date}
|
||||
toDate={balanceSheetQuery.to_date}
|
||||
basis={balanceSheetQuery.basis}
|
||||
loading={loading}
|
||||
loading={balanceSheetLoading}
|
||||
>
|
||||
<DataTable
|
||||
className="bigcapital-datatable--financial-report"
|
||||
columns={columns}
|
||||
data={balanceSheetAccounts}
|
||||
onFetchData={handleFetchData}
|
||||
noInitialFetch={true}
|
||||
expanded={expandedRows}
|
||||
expandSubRows={true}
|
||||
sticky={true}
|
||||
@@ -124,10 +130,16 @@ const withBalanceSheetTable = connect(mapStateToProps);
|
||||
export default compose(
|
||||
withBalanceSheetTable,
|
||||
withBalanceSheetDetail(
|
||||
({ balanceSheetAccounts, balanceSheetColumns, balanceSheetQuery }) => ({
|
||||
({
|
||||
balanceSheetAccounts,
|
||||
balanceSheetColumns,
|
||||
balanceSheetQuery,
|
||||
balanceSheetLoading,
|
||||
}) => ({
|
||||
balanceSheetAccounts,
|
||||
balanceSheetColumns,
|
||||
balanceSheetQuery,
|
||||
balanceSheetLoading,
|
||||
}),
|
||||
),
|
||||
withSettings,
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import {connect} from 'react-redux';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
fetchBalanceSheet,
|
||||
balanceSheetRefresh,
|
||||
} from 'store/financialStatement/financialStatements.actions';
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
fetchBalanceSheet: (query = {}) => dispatch(fetchBalanceSheet({ query })),
|
||||
toggleBalanceSheetFilter: () => dispatch({ type: 'BALANCE_SHEET_FILTER_TOGGLE' }),
|
||||
fetchBalanceSheet: (query = {}) => dispatch(fetchBalanceSheet({ query })),
|
||||
toggleBalanceSheetFilter: () =>
|
||||
dispatch({ type: 'BALANCE_SHEET_FILTER_TOGGLE' }),
|
||||
refreshBalanceSheet: (refresh) => dispatch(balanceSheetRefresh(refresh)),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
export default connect(null, mapDispatchToProps);
|
||||
|
||||
@@ -17,6 +17,7 @@ export default (mapState) => {
|
||||
balanceSheetQuery: getFinancialSheetQuery(state.financialStatements.balanceSheet.sheets, balanceSheetIndex),
|
||||
balanceSheetLoading: state.financialStatements.balanceSheet.loading,
|
||||
balanceSheetFilter: state.financialStatements.balanceSheet.filter,
|
||||
balanceSheetRefresh: state.financialStatements.balanceSheet.refresh,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { For } from 'components';
|
||||
|
||||
import financialReportMenus from 'config/financialReportsMenu';
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
|
||||
function FinancialReportsItem({
|
||||
title,
|
||||
desc,
|
||||
link
|
||||
}) {
|
||||
return (
|
||||
<div class="financial-reports__item">
|
||||
<Link class="title" to={link}>{ title }</Link>
|
||||
<p class="desc">{ desc }</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function FinancialReportsSection({
|
||||
sectionTitle,
|
||||
reports
|
||||
}) {
|
||||
return (
|
||||
<div class="financial-reports__section">
|
||||
<div class="section-title">{ sectionTitle }</div>
|
||||
|
||||
<div class="financial-reports__list">
|
||||
<For render={FinancialReportsItem} of={reports} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function FinancialReports({
|
||||
// #withDashboardActions
|
||||
changePageTitle,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
useEffect(() => {
|
||||
changePageTitle(formatMessage({ id: 'all_financial_reports' }));
|
||||
}, [changePageTitle, formatMessage]);
|
||||
|
||||
return (
|
||||
<div class="financial-reports">
|
||||
<For render={FinancialReportsSection} of={financialReportMenus} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDashboardActions
|
||||
)(FinancialReports);
|
||||
@@ -1,96 +1,98 @@
|
||||
import React, {useState, useCallback, useMemo} from 'react';
|
||||
import {Row, Col} from 'react-grid-system';
|
||||
import {momentFormatter} from 'utils';
|
||||
import {DateInput} from '@blueprintjs/datetime';
|
||||
import React, { useState, useCallback, useMemo } from 'react';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
import { momentFormatter } from 'utils';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { useIntl } from 'react-intl';
|
||||
import {
|
||||
HTMLSelect,
|
||||
FormGroup,
|
||||
Intent,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import { HTMLSelect, FormGroup, Intent, Position } from '@blueprintjs/core';
|
||||
import Icon from 'components/Icon';
|
||||
import { FieldHint } from 'components';
|
||||
import {
|
||||
parseDateRangeQuery
|
||||
} from 'utils';
|
||||
import { parseDateRangeQuery } from 'utils';
|
||||
|
||||
export default function FinancialStatementDateRange({
|
||||
formik,
|
||||
}) {
|
||||
export default function FinancialStatementDateRange({ formik }) {
|
||||
const intl = useIntl();
|
||||
const [reportDateRange, setReportDateRange] = useState('this_year');
|
||||
|
||||
const dateRangeOptions = useMemo(() => [
|
||||
{value: 'today', label: 'Today', },
|
||||
{value: 'this_week', label: 'This Week'},
|
||||
{value: 'this_month', label: 'This Month'},
|
||||
{value: 'this_quarter', label: 'This Quarter'},
|
||||
{value: 'this_year', label: 'This Year'},
|
||||
{value: 'custom', label: 'Custom Range'},
|
||||
], []);
|
||||
const dateRangeOptions = useMemo(
|
||||
() => [
|
||||
{ value: 'today', label: 'Today' },
|
||||
{ value: 'this_week', label: 'This Week' },
|
||||
{ value: 'this_month', label: 'This Month' },
|
||||
{ value: 'this_quarter', label: 'This Quarter' },
|
||||
{ value: 'this_year', label: 'This Year' },
|
||||
{ value: 'custom', label: 'Custom Range' },
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
const handleDateChange = useCallback((name) => (date) => {
|
||||
setReportDateRange('custom');
|
||||
formik.setFieldValue(name, date);
|
||||
}, [setReportDateRange, formik]);
|
||||
const handleDateChange = useCallback(
|
||||
(name) => (date) => {
|
||||
setReportDateRange('custom');
|
||||
formik.setFieldValue(name, date);
|
||||
},
|
||||
[setReportDateRange, formik],
|
||||
);
|
||||
|
||||
// Handles date range field change.
|
||||
const handleDateRangeChange = useCallback((e) => {
|
||||
const value = e.target.value;
|
||||
if (value !== 'custom') {
|
||||
const dateRange = parseDateRangeQuery(value);
|
||||
if (dateRange) {
|
||||
formik.setFieldValue('from_date', dateRange.from_date);
|
||||
formik.setFieldValue('to_date', dateRange.to_date);
|
||||
const handleDateRangeChange = useCallback(
|
||||
(e) => {
|
||||
const value = e.target.value;
|
||||
if (value !== 'custom') {
|
||||
const dateRange = parseDateRangeQuery(value);
|
||||
if (dateRange) {
|
||||
formik.setFieldValue('from_date', dateRange.from_date);
|
||||
formik.setFieldValue('to_date', dateRange.to_date);
|
||||
}
|
||||
}
|
||||
}
|
||||
setReportDateRange(value);
|
||||
}, [formik]);
|
||||
setReportDateRange(value);
|
||||
},
|
||||
[formik],
|
||||
);
|
||||
|
||||
const infoIcon = useMemo(() => (<Icon icon="info-circle" iconSize={12} />), []);
|
||||
const infoIcon = useMemo(() => <Icon icon="info-circle" iconSize={12} />, []);
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={intl.formatMessage({'id': 'report_date_range'})}
|
||||
label={intl.formatMessage({ id: 'report_date_range' })}
|
||||
labelInfo={infoIcon}
|
||||
minimal={true}
|
||||
fill={true}>
|
||||
|
||||
fill={true}
|
||||
>
|
||||
<HTMLSelect
|
||||
fill={true}
|
||||
options={dateRangeOptions}
|
||||
value={reportDateRange}
|
||||
onChange={handleDateRangeChange} />
|
||||
onChange={handleDateRangeChange}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={intl.formatMessage({'id': 'from_date'})}
|
||||
label={intl.formatMessage({ id: 'from_date' })}
|
||||
labelInfo={infoIcon}
|
||||
fill={true}
|
||||
intent={formik.errors.from_date && Intent.DANGER}>
|
||||
|
||||
intent={formik.errors.from_date && Intent.DANGER}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
value={formik.values.from_date}
|
||||
onChange={handleDateChange('from_date')}
|
||||
popoverProps={{ position: Position.BOTTOM }}
|
||||
minimal={true}
|
||||
fill={true} />
|
||||
fill={true}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={intl.formatMessage({'id': 'to_date'})}
|
||||
labelInfo={<FieldHint />}
|
||||
label={intl.formatMessage({ id: 'to_date' })}
|
||||
labelInfo={<FieldHint />}
|
||||
fill={true}
|
||||
intent={formik.errors.to_date && Intent.DANGER}>
|
||||
|
||||
intent={formik.errors.to_date && Intent.DANGER}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
value={formik.values.to_date}
|
||||
@@ -98,9 +100,10 @@ export default function FinancialStatementDateRange({
|
||||
popoverProps={{ position: Position.BOTTOM }}
|
||||
fill={true}
|
||||
minimal={true}
|
||||
intent={formik.errors.to_date && Intent.DANGER} />
|
||||
intent={formik.errors.to_date && Intent.DANGER}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ function GeneralLedgerActionsBar({
|
||||
|
||||
// #withGeneralLedgerActions
|
||||
toggleGeneralLedgerSheetFilter,
|
||||
refreshGeneralLedgerSheet
|
||||
}) {
|
||||
const filterDropdown = FilterDropdown({
|
||||
fields: [],
|
||||
@@ -41,6 +42,10 @@ function GeneralLedgerActionsBar({
|
||||
toggleGeneralLedgerSheetFilter();
|
||||
};
|
||||
|
||||
const handleRecalcReport = () => {
|
||||
refreshGeneralLedgerSheet(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
@@ -52,6 +57,16 @@ function GeneralLedgerActionsBar({
|
||||
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(
|
||||
Classes.MINIMAL,
|
||||
'button--gray-highlight',
|
||||
)}
|
||||
text={'Re-calc Report'}
|
||||
onClick={handleRecalcReport}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
/>
|
||||
|
||||
<If condition={generalLedgerSheetFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
@@ -69,7 +84,6 @@ function GeneralLedgerActionsBar({
|
||||
onClick={handleFilterClick}
|
||||
/>
|
||||
</If>
|
||||
<NavbarDivider />
|
||||
|
||||
<Popover
|
||||
content={filterDropdown}
|
||||
@@ -82,6 +96,8 @@ function GeneralLedgerActionsBar({
|
||||
icon={<Icon icon="filter-16" iconSize={16} /> } />
|
||||
</Popover>
|
||||
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon='print-16' iconSize={16} />}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import { Button, FormGroup, Classes } from '@blueprintjs/core';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
import { Row, Col, Visible } from 'react-grid-system';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import { useFormik } from 'formik';
|
||||
@@ -13,9 +13,12 @@ import withAccounts from 'containers/Accounts/withAccounts';
|
||||
import classNames from 'classnames';
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
import RadiosAccountingBasis from '../RadiosAccountingBasis';
|
||||
import { compose } from 'utils';
|
||||
|
||||
import withGeneralLedger from './withGeneralLedger';
|
||||
import withGeneralLedgerActions from './withGeneralLedgerActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
|
||||
function GeneralLedgerHeader({
|
||||
onSubmitFilter,
|
||||
@@ -24,8 +27,12 @@ function GeneralLedgerHeader({
|
||||
// #withAccounts
|
||||
accounts,
|
||||
|
||||
// #withGeneralLedgerActions
|
||||
refreshGeneralLedgerSheet,
|
||||
|
||||
// #withGeneralLedger
|
||||
generalLedgerSheetFilter,
|
||||
generalLedgerSheetRefresh
|
||||
}) {
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
@@ -44,13 +51,8 @@ function GeneralLedgerHeader({
|
||||
},
|
||||
});
|
||||
|
||||
// handle submit filter submit button.
|
||||
const handleSubmitClick = useCallback(() => {
|
||||
formik.submitForm();
|
||||
}, []);
|
||||
|
||||
const onAccountSelected = useCallback((selectedAccounts) => {
|
||||
console.log(selectedAccounts);
|
||||
|
||||
}, []);
|
||||
|
||||
const handleAccountingBasisChange = useCallback(
|
||||
@@ -59,13 +61,23 @@ function GeneralLedgerHeader({
|
||||
},
|
||||
[formik],
|
||||
);
|
||||
|
||||
// handle submit filter submit button.
|
||||
useEffect(() => {
|
||||
if (generalLedgerSheetRefresh) {
|
||||
formik.submitForm();
|
||||
refreshGeneralLedgerSheet(false);
|
||||
}
|
||||
}, [formik, generalLedgerSheetRefresh])
|
||||
|
||||
return (
|
||||
<FinancialStatementHeader show={generalLedgerSheetFilter}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
|
||||
<Visible xl><Col width={'100%'} /></Visible>
|
||||
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={<T id={'specific_accounts'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
@@ -77,23 +89,13 @@ function GeneralLedgerHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<RadiosAccountingBasis
|
||||
onChange={handleAccountingBasisChange}
|
||||
selectedValue={formik.values.basis}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmitClick}
|
||||
disabled={formik.isSubmitting}
|
||||
className={'button--submit-filter mt2'}
|
||||
>
|
||||
<T id={'calculate_report'} />
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</FinancialStatementHeader>
|
||||
);
|
||||
@@ -103,7 +105,9 @@ export default compose(
|
||||
withAccounts(({ accounts }) => ({
|
||||
accounts,
|
||||
})),
|
||||
withGeneralLedger(({ generalLedgerSheetFilter }) => ({
|
||||
withGeneralLedger(({ generalLedgerSheetFilter, generalLedgerSheetRefresh }) => ({
|
||||
generalLedgerSheetFilter,
|
||||
generalLedgerSheetRefresh,
|
||||
})),
|
||||
withGeneralLedgerActions,
|
||||
)(GeneralLedgerHeader);
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {connect} from 'react-redux';
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
getFinancialSheet,
|
||||
getFinancialSheetQuery,
|
||||
getFinancialSheetTableRows,
|
||||
} from 'store/financialStatement/financialStatements.selectors';
|
||||
|
||||
|
||||
export default (mapState) => {
|
||||
const mapStateToProps = (state, props) => {
|
||||
const { generalLedgerIndex } = props;
|
||||
@@ -23,8 +22,11 @@ export default (mapState) => {
|
||||
state.financialStatements.generalLedger.sheets,
|
||||
generalLedgerIndex,
|
||||
),
|
||||
generalLedgerSheetLoading: state.financialStatements.generalLedger.loading,
|
||||
generalLedgerSheetLoading:
|
||||
state.financialStatements.generalLedger.loading,
|
||||
generalLedgerSheetFilter: state.financialStatements.generalLedger.filter,
|
||||
generalLedgerSheetRefresh:
|
||||
state.financialStatements.generalLedger.refresh,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
fetchGeneralLedger,
|
||||
refreshGeneralLedgerSheet,
|
||||
} from 'store/financialStatement/financialStatements.actions';
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
fetchGeneralLedger: (query = {}) => dispatch(fetchGeneralLedger({ query })),
|
||||
toggleGeneralLedgerSheetFilter: () => dispatch({ type: 'GENERAL_LEDGER_FILTER_TOGGLE' }),
|
||||
refreshGeneralLedgerSheet: (refresh) => dispatch(refreshGeneralLedgerSheet(refresh)),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
@@ -27,6 +27,7 @@ function JournalActionsBar({
|
||||
|
||||
// #withJournalActions
|
||||
toggleJournalSheetFilter,
|
||||
refreshJournalSheet,
|
||||
}) {
|
||||
const filterDropdown = FilterDropdown({
|
||||
fields: [],
|
||||
@@ -37,6 +38,10 @@ function JournalActionsBar({
|
||||
toggleJournalSheetFilter();
|
||||
};
|
||||
|
||||
const handleRecalcReport = () => {
|
||||
refreshJournalSheet(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
@@ -47,6 +52,13 @@ function JournalActionsBar({
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--gray-highlight')}
|
||||
text={'Re-calc Report'}
|
||||
onClick={handleRecalcReport}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
/>
|
||||
|
||||
<If condition={journalSheetFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
@@ -64,7 +76,6 @@ function JournalActionsBar({
|
||||
onClick={handleFilterToggleClick}
|
||||
/>
|
||||
</If>
|
||||
<NavbarDivider />
|
||||
|
||||
<Popover
|
||||
content={filterDropdown}
|
||||
@@ -78,9 +89,11 @@ function JournalActionsBar({
|
||||
/>
|
||||
</Popover>
|
||||
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon='print-16' iconSize={16} />}
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
import {
|
||||
Button,
|
||||
} from '@blueprintjs/core';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import moment from 'moment';
|
||||
import { useFormik } from 'formik';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
@@ -12,24 +10,30 @@ import FinancialStatementDateRange from 'containers/FinancialStatements/Financia
|
||||
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
||||
|
||||
import withJournal from './withJournal';
|
||||
import withJournalActions from './withJournalActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
/**
|
||||
* Journal sheet header.
|
||||
* Journal sheet header.
|
||||
*/
|
||||
function JournalHeader({
|
||||
pageFilter,
|
||||
onSubmitFilter,
|
||||
|
||||
// #withJournalActions
|
||||
refreshJournalSheet,
|
||||
|
||||
// #withJournal
|
||||
journalSheetFilter,
|
||||
journalSheetRefresh,
|
||||
}) {
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
initialValues: {
|
||||
...pageFilter,
|
||||
from_date: moment(pageFilter.from_date).toDate(),
|
||||
to_date: moment(pageFilter.to_date).toDate()
|
||||
to_date: moment(pageFilter.to_date).toDate(),
|
||||
},
|
||||
validationSchema: Yup.object().shape({
|
||||
from_date: Yup.date().required(),
|
||||
@@ -41,29 +45,29 @@ function JournalHeader({
|
||||
},
|
||||
});
|
||||
|
||||
const handleSubmitClick = useCallback(() => {
|
||||
formik.submitForm();
|
||||
}, [formik]);
|
||||
useEffect(() => {
|
||||
if (journalSheetRefresh) {
|
||||
formik.submitForm();
|
||||
refreshJournalSheet(false);
|
||||
}
|
||||
}, [formik, journalSheetRefresh]);
|
||||
|
||||
return (
|
||||
<FinancialStatementHeader show={journalSheetFilter}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmitClick}
|
||||
className={'button--submit-filter'}>
|
||||
<T id={'run_report'} />
|
||||
</Button>
|
||||
</Col>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
</Row>
|
||||
|
||||
</FinancialStatementHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withJournal(({ journalSheetFilter }) => ({ journalSheetFilter })),
|
||||
)(JournalHeader);
|
||||
withJournal(({
|
||||
journalSheetFilter,
|
||||
journalSheetRefresh
|
||||
}) => ({
|
||||
journalSheetFilter,
|
||||
journalSheetRefresh,
|
||||
})),
|
||||
withJournalActions,
|
||||
)(JournalHeader);
|
||||
|
||||
@@ -25,6 +25,7 @@ export default (mapState) => {
|
||||
),
|
||||
journalSheetLoading: state.financialStatements.journal.loading,
|
||||
journalSheetFilter: state.financialStatements.journal.filter,
|
||||
journalSheetRefresh: state.financialStatements.journal.refresh,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
fetchJournalSheet
|
||||
fetchJournalSheet,
|
||||
refreshJournalSheet,
|
||||
} from 'store/financialStatement/financialStatements.actions';
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
requestFetchJournalSheet: (query) => dispatch(fetchJournalSheet({ query })),
|
||||
toggleJournalSheetFilter: () => dispatch({ type: 'JOURNAL_FILTER_TOGGLE' }),
|
||||
refreshJournalSheet: (refresh) => dispatch(refreshJournalSheet(refresh)),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
@@ -19,11 +19,16 @@ function ProfitLossActionsBar({
|
||||
|
||||
// #withProfitLossActions
|
||||
toggleProfitLossSheetFilter,
|
||||
refreshProfitLossSheet,
|
||||
}) {
|
||||
const handleFilterClick = () => {
|
||||
toggleProfitLossSheetFilter();
|
||||
};
|
||||
|
||||
const handleRecalcReport = () => {
|
||||
refreshProfitLossSheet(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
@@ -34,6 +39,16 @@ function ProfitLossActionsBar({
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(
|
||||
Classes.MINIMAL,
|
||||
'button--gray-highlight',
|
||||
)}
|
||||
text={'Re-calc Report'}
|
||||
onClick={handleRecalcReport}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
/>
|
||||
|
||||
<If condition={profitLossSheetFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
|
||||
@@ -24,9 +24,6 @@ function ProfitLossSheet({
|
||||
// #withProfitLossActions
|
||||
fetchProfitLossSheet,
|
||||
|
||||
// #withProfitLoss
|
||||
profitLossSheetLoading,
|
||||
|
||||
// #withPreferences
|
||||
organizationSettings,
|
||||
}) {
|
||||
@@ -35,6 +32,7 @@ function ProfitLossSheet({
|
||||
from_date: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
to_date: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
});
|
||||
const [refresh, setRefresh] = useState(true);
|
||||
|
||||
// Change page title of the dashboard.
|
||||
useEffect(() => {
|
||||
@@ -54,14 +52,21 @@ function ProfitLossSheet({
|
||||
to_date: moment(filter.to_date).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(_filter);
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
// Handle fetch data of profit/loss sheet table.
|
||||
const handleFetchData = useCallback(() => {
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (refresh) {
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(false);
|
||||
}
|
||||
}, [refresh, fetchHook]);
|
||||
|
||||
return (
|
||||
<DashboardInsider>
|
||||
<ProfitLossActionsBar />
|
||||
@@ -76,8 +81,7 @@ function ProfitLossSheet({
|
||||
<ProfitLossSheetTable
|
||||
companyName={organizationSettings.name}
|
||||
profitLossQuery={filter}
|
||||
onFetchData={handleFetchData}
|
||||
loading={profitLossSheetLoading} />
|
||||
onFetchData={handleFetchData} />
|
||||
</div>
|
||||
</div>
|
||||
</DashboardPageContent>
|
||||
@@ -88,8 +92,5 @@ function ProfitLossSheet({
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withProfitLossActions,
|
||||
withProfitLoss(({ profitLossSheetLoading }) => ({
|
||||
profitLossSheetLoading,
|
||||
})),
|
||||
withSettings,
|
||||
)(ProfitLossSheet);
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { Row, Col, Visible } from 'react-grid-system';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import moment from 'moment';
|
||||
import { useFormik } from 'formik';
|
||||
@@ -11,6 +11,7 @@ import SelectsListColumnsBy from '../SelectDisplayColumnsBy';
|
||||
import RadiosAccountingBasis from '../RadiosAccountingBasis';
|
||||
|
||||
import withProfitLoss from './withProfitLoss';
|
||||
import withProfitLossActions from './withProfitLossActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
@@ -21,6 +22,10 @@ function ProfitLossHeader({
|
||||
|
||||
// #withProfitLoss
|
||||
profitLossSheetFilter,
|
||||
profitLossSheetRefresh,
|
||||
|
||||
// #withProfitLossActions
|
||||
refreshProfitLossSheet,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const formik = useFormik({
|
||||
@@ -54,10 +59,6 @@ function ProfitLossHeader({
|
||||
[formik],
|
||||
);
|
||||
|
||||
const handleSubmitClick = useCallback(() => {
|
||||
formik.submitForm();
|
||||
}, [formik]);
|
||||
|
||||
const handleAccountingBasisChange = useCallback(
|
||||
(value) => {
|
||||
formik.setFieldValue('basis', value);
|
||||
@@ -65,36 +66,41 @@ function ProfitLossHeader({
|
||||
[formik],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (profitLossSheetRefresh) {
|
||||
formik.submitForm();
|
||||
refreshProfitLossSheet(false);
|
||||
}
|
||||
}, [profitLossSheetRefresh]);
|
||||
|
||||
return (
|
||||
<FinancialStatementHeader show={profitLossSheetFilter}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
<Visible xl><Col width={'100%'} /></Visible>
|
||||
|
||||
<Col width={260}>
|
||||
<SelectsListColumnsBy onItemSelect={handleItemSelectDisplayColumns} />
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<RadiosAccountingBasis
|
||||
selectedValue={formik.values.basis}
|
||||
onChange={handleAccountingBasisChange}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmitClick}
|
||||
className={'button--submit-filter mt2'}
|
||||
>
|
||||
<T id={'run_report'} />
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</FinancialStatementHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withProfitLoss(({ profitLossSheetFilter }) => ({ profitLossSheetFilter })),
|
||||
withProfitLoss(({
|
||||
profitLossSheetFilter,
|
||||
profitLossSheetRefresh,
|
||||
}) => ({
|
||||
profitLossSheetFilter,
|
||||
profitLossSheetRefresh,
|
||||
})),
|
||||
withProfitLossActions,
|
||||
)(ProfitLossHeader);
|
||||
|
||||
@@ -15,9 +15,9 @@ function ProfitLossSheetTable({
|
||||
profitLossTableRows,
|
||||
profitLossQuery,
|
||||
profitLossColumns,
|
||||
profitLossSheetLoading,
|
||||
|
||||
// #ownProps
|
||||
loading,
|
||||
onFetchData,
|
||||
companyName,
|
||||
}) {
|
||||
@@ -31,7 +31,7 @@ function ProfitLossSheetTable({
|
||||
className: 'name',
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'acc_code' }),
|
||||
Header: formatMessage({ id: 'account_code' }),
|
||||
accessor: 'code',
|
||||
className: 'account_code',
|
||||
},
|
||||
@@ -102,7 +102,7 @@ function ProfitLossSheetTable({
|
||||
fromDate={profitLossQuery.from_date}
|
||||
toDate={profitLossQuery.to_date}
|
||||
name="profit-loss-sheet"
|
||||
loading={loading}
|
||||
loading={profitLossSheetLoading}
|
||||
basis={profitLossQuery.basis}
|
||||
>
|
||||
<DataTable
|
||||
@@ -110,6 +110,7 @@ function ProfitLossSheetTable({
|
||||
columns={columns}
|
||||
data={profitLossTableRows}
|
||||
onFetchData={handleFetchData}
|
||||
noInitialFetch={true}
|
||||
expanded={expandedRows}
|
||||
rowClassNames={rowClassNames}
|
||||
expandable={true}
|
||||
@@ -132,10 +133,11 @@ const withProfitLossTable = connect(mapStateToProps);
|
||||
export default compose(
|
||||
withProfitLossTable,
|
||||
withProfitLossDetail(
|
||||
({ profitLossQuery, profitLossColumns, profitLossTableRows }) => ({
|
||||
({ profitLossQuery, profitLossColumns, profitLossTableRows, profitLossSheetLoading }) => ({
|
||||
profitLossColumns,
|
||||
profitLossQuery,
|
||||
profitLossTableRows,
|
||||
profitLossSheetLoading,
|
||||
}),
|
||||
),
|
||||
)(ProfitLossSheetTable);
|
||||
|
||||
@@ -20,6 +20,7 @@ export default (mapState) => {
|
||||
|
||||
profitLossSheetLoading: state.financialStatements.profitLoss.loading,
|
||||
profitLossSheetFilter: state.financialStatements.profitLoss.filter,
|
||||
profitLossSheetRefresh: state.financialStatements.profitLoss.refresh,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
fetchProfitLossSheet,
|
||||
profitLossRefresh,
|
||||
} from 'store/financialStatement/financialStatements.actions';
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
fetchProfitLossSheet: (query = {}) => dispatch(fetchProfitLossSheet({ query })),
|
||||
toggleProfitLossSheetFilter: () => dispatch({ type: 'PROFIT_LOSS_FILTER_TOGGLE' }),
|
||||
refreshProfitLossSheet: (refresh) => dispatch(profitLossRefresh(refresh)),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
@@ -25,23 +25,25 @@ function ReceivableAgingSummarySheet({
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const [query, setQuery] = useState({
|
||||
as_date: moment().format('YYYY-MM-DD'),
|
||||
as_date: moment().endOf('day').format('YYYY-MM-DD'),
|
||||
aging_before_days: 30,
|
||||
aging_periods: 3,
|
||||
});
|
||||
const [refresh, setRefresh] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
changePageTitle(formatMessage({ id: 'receivable_aging_summary' }));
|
||||
}, []);
|
||||
|
||||
const fetchSheet = useQuery(['receivable-aging-summary', query],
|
||||
const fetchSheet = useQuery(
|
||||
['receivable-aging-summary', query],
|
||||
(key, q) => requestReceivableAgingSummary(q),
|
||||
{ manual: true });
|
||||
|
||||
// Handle fetch the data of receivable aging summary sheet.
|
||||
const handleFetchData = useCallback(() => {
|
||||
fetchSheet.refetch({ force: true });
|
||||
}, [fetchSheet]);
|
||||
const handleFetchData = useCallback((...args) => {
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
const handleFilterSubmit = useCallback((filter) => {
|
||||
const _filter = {
|
||||
@@ -49,8 +51,15 @@ function ReceivableAgingSummarySheet({
|
||||
as_date: moment(filter.as_date).format('YYYY-MM-DD'),
|
||||
};
|
||||
setQuery(_filter);
|
||||
fetchSheet.refetch({ force: true });
|
||||
}, [fetchSheet]);
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (refresh) {
|
||||
fetchSheet.refetch({ force: true });
|
||||
setRefresh(false);
|
||||
}
|
||||
}, [fetchSheet, refresh]);
|
||||
|
||||
return (
|
||||
<DashboardInsider>
|
||||
@@ -59,6 +68,7 @@ function ReceivableAgingSummarySheet({
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement>
|
||||
<ReceivableAgingSummaryHeader
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit} />
|
||||
|
||||
<div class="financial-statement__body">
|
||||
|
||||
@@ -23,8 +23,12 @@ import { compose } from 'utils';
|
||||
|
||||
|
||||
function ReceivableAgingSummaryActionsBar({
|
||||
toggleFilterReceivableAgingSummary,
|
||||
// #withReceivableAging
|
||||
receivableAgingFilter,
|
||||
|
||||
// #withReceivableAgingActions
|
||||
toggleFilterReceivableAgingSummary,
|
||||
refreshReceivableAgingSummary,
|
||||
}) {
|
||||
const filterDropdown = FilterDropdown({
|
||||
fields: [],
|
||||
@@ -35,6 +39,10 @@ function ReceivableAgingSummaryActionsBar({
|
||||
toggleFilterReceivableAgingSummary();
|
||||
};
|
||||
|
||||
const handleRecalcReport = () => {
|
||||
refreshReceivableAgingSummary(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
@@ -45,6 +53,16 @@ function ReceivableAgingSummaryActionsBar({
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(
|
||||
Classes.MINIMAL,
|
||||
'button--gray-highlight',
|
||||
)}
|
||||
text={<T id={'recalc_report'} />}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
onClick={handleRecalcReport}
|
||||
/>
|
||||
|
||||
<If condition={receivableAgingFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
@@ -62,7 +80,6 @@ function ReceivableAgingSummaryActionsBar({
|
||||
icon={<Icon icon="arrow-to-bottom" />}
|
||||
/>
|
||||
</If>
|
||||
<NavbarDivider />
|
||||
|
||||
<Popover
|
||||
content={filterDropdown}
|
||||
@@ -76,6 +93,8 @@ function ReceivableAgingSummaryActionsBar({
|
||||
/>
|
||||
</Popover>
|
||||
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon='print-16' iconSize={16} />}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { useIntl, FormattedMessage as T, } from 'react-intl';
|
||||
import { useFormik } from "formik";
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useIntl, FormattedMessage as T } from 'react-intl';
|
||||
import { useFormik } from 'formik';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
import * as Yup from 'yup';
|
||||
import {
|
||||
@@ -11,22 +11,27 @@ import {
|
||||
Button,
|
||||
} from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import moment from 'moment';
|
||||
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
||||
import {
|
||||
ErrorMessage,
|
||||
FieldHint,
|
||||
FieldRequiredHint,
|
||||
} from 'components';
|
||||
import {
|
||||
momentFormatter,
|
||||
} from 'utils';
|
||||
import { ErrorMessage, FieldHint, FieldRequiredHint } from 'components';
|
||||
import { momentFormatter } from 'utils';
|
||||
|
||||
import withReceivableAging from './withReceivableAgingSummary';
|
||||
import withReceivableAgingActions from './withReceivableAgingSummaryActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
|
||||
function ReceivableAgingSummaryHeader({
|
||||
onSubmitFilter,
|
||||
pageFilter,
|
||||
onSubmitFilter,
|
||||
receivableAgingFilter,
|
||||
|
||||
// #withReceivableAgingSummary
|
||||
receivableAgingRefresh,
|
||||
|
||||
// #withReceivableAgingSummaryActions
|
||||
refreshReceivableAgingSummary
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
@@ -37,61 +42,75 @@ function ReceivableAgingSummaryHeader({
|
||||
setFieldValue,
|
||||
getFieldProps,
|
||||
submitForm,
|
||||
isSubmitting
|
||||
isSubmitting,
|
||||
} = useFormik({
|
||||
enableReinitialize: true,
|
||||
initialValues: {
|
||||
// as_date: new Date(),
|
||||
as_date: moment(pageFilter.as_date).toDate(),
|
||||
aging_before_days: 30,
|
||||
aging_periods: 3,
|
||||
},
|
||||
validationSchema: Yup.object().shape({
|
||||
as_date: Yup.date().required().label('As date'),
|
||||
aging_before_days: Yup.number().required().integer().positive().label('aging_before_days'),
|
||||
aging_periods: Yup.number().required().integer().positive().label('aging_periods'),
|
||||
as_date: Yup.date().required().label('as_date'),
|
||||
aging_before_days: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('aging_before_days'),
|
||||
aging_periods: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('aging_periods'),
|
||||
}),
|
||||
onSubmit: (values, { setSubmitting }) => {
|
||||
onSubmitFilter(values);
|
||||
setSubmitting(false);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const handleDateChange = useCallback((name) => (date) => {
|
||||
setFieldValue(name, date);
|
||||
}, []);
|
||||
const handleDateChange = useCallback(
|
||||
(name) => (date) => {
|
||||
setFieldValue(name, date);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
// Handle submit filter submit button.
|
||||
const handleSubmitClick = useCallback(() => {
|
||||
submitForm();
|
||||
}, [submitForm]);
|
||||
useEffect(() => {
|
||||
if (receivableAgingRefresh) {
|
||||
submitForm();
|
||||
refreshReceivableAgingSummary(false);
|
||||
}
|
||||
}, [submitForm, receivableAgingRefresh]);
|
||||
|
||||
return (
|
||||
<FinancialStatementHeader show={receivableAgingFilter}>
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={formatMessage({'id': 'as_date'})}
|
||||
label={formatMessage({ id: 'as_date' })}
|
||||
labelInfo={<FieldHint />}
|
||||
fill={true}
|
||||
intent={errors.as_date && Intent.DANGER}>
|
||||
|
||||
intent={errors.as_date && Intent.DANGER}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
// value={values.as_date}
|
||||
value={values.as_date}
|
||||
onChange={handleDateChange('as_date')}
|
||||
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||
minimal={true}
|
||||
fill={true} />
|
||||
fill={true}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={<T id={'aging_before_days'} />}
|
||||
labelInfo={<FieldHint />}
|
||||
className={'form-group--aging-before-days'}
|
||||
intent={errors.aging_before_days && Intent.DANGER}
|
||||
helperText={<ErrorMessage name="aging_before_days" {...{ errors, touched }} />}
|
||||
>
|
||||
<InputGroup
|
||||
medium={true}
|
||||
@@ -101,13 +120,12 @@ function ReceivableAgingSummaryHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={<T id={'aging_periods'} />}
|
||||
labelInfo={<FieldHint />}
|
||||
className={'form-group--aging-periods'}
|
||||
intent={errors.aging_before_days && Intent.DANGER}
|
||||
helperText={<ErrorMessage name="aging_periods" {...{ errors, touched }} />}
|
||||
>
|
||||
<InputGroup
|
||||
medium={true}
|
||||
@@ -117,24 +135,14 @@ function ReceivableAgingSummaryHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmitClick}
|
||||
disabled={isSubmitting}
|
||||
className={'button--submit-filter'}>
|
||||
<T id={'calculate_report'} />
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</FinancialStatementHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withReceivableAging(({ receivableAgingSummaryFilter }) => ({
|
||||
withReceivableAgingActions,
|
||||
withReceivableAging(({ receivableAgingSummaryFilter, receivableAgingSummaryRefresh }) => ({
|
||||
receivableAgingFilter: receivableAgingSummaryFilter,
|
||||
receivableAgingRefresh: receivableAgingSummaryRefresh
|
||||
})),
|
||||
)(ReceivableAgingSummaryHeader);
|
||||
)(ReceivableAgingSummaryHeader);
|
||||
|
||||
@@ -15,19 +15,18 @@ function ReceivableAgingSummaryTable({
|
||||
organizationSettings,
|
||||
|
||||
// #withReceivableAgingSummary
|
||||
receviableAgingRows = [],
|
||||
receivableAgingRows,
|
||||
receivableAgingLoading,
|
||||
receivableAgingColumns,
|
||||
|
||||
// #ownProps
|
||||
receivableAgingSummaryQuery,
|
||||
onFetchData,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const agingColumns = useMemo(() => {
|
||||
return receivableAgingColumns.map((agingColumn) => {
|
||||
return `${agingColumn.before_days} - ${agingColumn.to_days || '<'}`;
|
||||
return `${agingColumn.before_days} - ${agingColumn.to_days || 'And Over'}`;
|
||||
});
|
||||
}, [receivableAgingColumns]);
|
||||
|
||||
@@ -36,25 +35,38 @@ function ReceivableAgingSummaryTable({
|
||||
Header: (<T id={'customer_name'} />),
|
||||
accessor: 'customer_name',
|
||||
className: 'customer_name',
|
||||
sticky: 'left',
|
||||
},
|
||||
...agingColumns.map((agingColumn, index) => ({
|
||||
Header: agingColumn,
|
||||
id: `asd-${index}`,
|
||||
accessor: (row) => {
|
||||
const amount = row[`aging-${index}`];
|
||||
if (row.rowType === 'total') {
|
||||
return <Money amount={amount} currency={'USD'} />
|
||||
}
|
||||
return amount > 0 ? amount : '';
|
||||
},
|
||||
})),
|
||||
{
|
||||
Header: (<T id={'total'} />),
|
||||
accessor: 'total',
|
||||
id: 'total',
|
||||
accessor: (row) => {
|
||||
return <Money amount={row.total} currency={'USD'} />;
|
||||
},
|
||||
className: 'total',
|
||||
},
|
||||
]), [agingColumns]);
|
||||
|
||||
const rowClassNames = (row) => [`row-type--${row.original.rowType}`];
|
||||
|
||||
const handleFetchData = useCallback((...args) => {
|
||||
onFetchData && onFetchData(...args);
|
||||
}, [onFetchData]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<FinancialSheet
|
||||
companyName={organizationSettings.name}
|
||||
name={'receivable-aging-summary'}
|
||||
sheetType={formatMessage({ id: 'receivable_aging_summary' })}
|
||||
asDate={new Date()}
|
||||
loading={receivableAgingLoading}>
|
||||
@@ -62,8 +74,10 @@ function ReceivableAgingSummaryTable({
|
||||
<DataTable
|
||||
className="bigcapital-datatable--financial-report"
|
||||
columns={columns}
|
||||
data={receviableAgingRows}
|
||||
data={receivableAgingRows}
|
||||
rowClassNames={rowClassNames}
|
||||
onFetchData={handleFetchData}
|
||||
noInitialFetch={true}
|
||||
sticky={true}
|
||||
/>
|
||||
</FinancialSheet>
|
||||
@@ -75,8 +89,11 @@ export default compose(
|
||||
withReceivableAgingSummaryTable,
|
||||
withReceivableAgingSummary(({
|
||||
receivableAgingSummaryLoading,
|
||||
receivableAgingSummaryColumns }) => ({
|
||||
receivableAgingSummaryColumns,
|
||||
receivableAgingSummaryRows,
|
||||
}) => ({
|
||||
receivableAgingLoading: receivableAgingSummaryLoading,
|
||||
receivableAgingColumns: receivableAgingSummaryColumns
|
||||
receivableAgingColumns: receivableAgingSummaryColumns,
|
||||
receivableAgingRows: receivableAgingSummaryRows,
|
||||
})),
|
||||
)(ReceivableAgingSummaryTable);
|
||||
@@ -2,6 +2,7 @@ import { connect } from 'react-redux';
|
||||
import {
|
||||
getFinancialSheet,
|
||||
getFinancialSheetColumns,
|
||||
getFinancialSheetTableRows,
|
||||
} from 'store/financialStatement/financialStatements.selectors';
|
||||
|
||||
export default (mapState) => {
|
||||
@@ -17,10 +18,16 @@ export default (mapState) => {
|
||||
state.financialStatements.receivableAgingSummary.sheets,
|
||||
receivableAgingSummaryIndex,
|
||||
),
|
||||
receivableAgingSummaryRows: getFinancialSheetTableRows(
|
||||
state.financialStatements.receivableAgingSummary.sheets,
|
||||
receivableAgingSummaryIndex,
|
||||
),
|
||||
receivableAgingSummaryLoading:
|
||||
state.financialStatements.receivableAgingSummary.loading,
|
||||
receivableAgingSummaryFilter:
|
||||
state.financialStatements.receivableAgingSummary.filter,
|
||||
receivableAgingSummaryRefresh:
|
||||
state.financialStatements.receivableAgingSummary.refresh,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { fetchReceivableAgingSummary } from 'store/financialStatement/financialStatements.actions';
|
||||
import {
|
||||
fetchReceivableAgingSummary,
|
||||
receivableAgingSummaryRefresh,
|
||||
} from 'store/financialStatement/financialStatements.actions';
|
||||
|
||||
const mapActionsToProps = (dispatch) => ({
|
||||
requestReceivableAgingSummary: (query) =>
|
||||
dispatch(fetchReceivableAgingSummary({ query })),
|
||||
toggleFilterReceivableAgingSummary: () => dispatch({
|
||||
type: 'RECEIVABLE_AGING_SUMMARY_FILTER_TOGGLE',
|
||||
}),
|
||||
toggleFilterReceivableAgingSummary: () =>
|
||||
dispatch({
|
||||
type: 'RECEIVABLE_AGING_SUMMARY_FILTER_TOGGLE',
|
||||
}),
|
||||
refreshReceivableAgingSummary: (refresh) =>
|
||||
dispatch(receivableAgingSummaryRefresh(refresh)),
|
||||
});
|
||||
|
||||
export default connect(null, mapActionsToProps);
|
||||
|
||||
@@ -20,12 +20,17 @@ function TrialBalanceActionsBar({
|
||||
|
||||
// #withTrialBalanceActions
|
||||
toggleTrialBalanceFilter,
|
||||
refreshTrialBalance,
|
||||
}) {
|
||||
|
||||
const handleFilterToggleClick = () => {
|
||||
toggleTrialBalanceFilter();
|
||||
};
|
||||
|
||||
const handleRecalcReport = () => {
|
||||
refreshTrialBalance(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
@@ -36,6 +41,16 @@ function TrialBalanceActionsBar({
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(
|
||||
Classes.MINIMAL,
|
||||
'button--gray-highlight',
|
||||
)}
|
||||
text={'Re-calc Report'}
|
||||
onClick={handleRecalcReport}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
/>
|
||||
|
||||
<If condition={trialBalanceSheetFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
|
||||
@@ -13,10 +13,8 @@ import { compose } from 'utils';
|
||||
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withTrialBalanceActions from './withTrialBalanceActions';
|
||||
import withTrialBalance from './withTrialBalance';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
|
||||
|
||||
function TrialBalanceSheet({
|
||||
// #withDashboardActions
|
||||
changePageTitle,
|
||||
@@ -24,9 +22,6 @@ function TrialBalanceSheet({
|
||||
// #withTrialBalanceActions
|
||||
fetchTrialBalanceSheet,
|
||||
|
||||
// #withTrialBalance
|
||||
trialBalanceSheetLoading,
|
||||
|
||||
// #withPreferences
|
||||
organizationSettings,
|
||||
}) {
|
||||
@@ -36,6 +31,7 @@ function TrialBalanceSheet({
|
||||
basis: 'accural',
|
||||
none_zero: false,
|
||||
});
|
||||
const [refresh, setRefresh] = useState(true);
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const fetchHook = useQuery(
|
||||
@@ -46,7 +42,7 @@ function TrialBalanceSheet({
|
||||
|
||||
// handle fetch data of trial balance table.
|
||||
const handleFetchData = useCallback(() => {
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
// Change page title of the dashboard.
|
||||
@@ -62,11 +58,18 @@ function TrialBalanceSheet({
|
||||
to_date: moment(filter.to_date).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(parsedFilter);
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(true);
|
||||
},
|
||||
[fetchHook],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (refresh) {
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(false);
|
||||
}
|
||||
}, [refresh, fetchHook.refetch]);
|
||||
|
||||
return (
|
||||
<DashboardInsider>
|
||||
<TrialBalanceActionsBar />
|
||||
@@ -83,7 +86,6 @@ function TrialBalanceSheet({
|
||||
companyName={organizationSettings.name}
|
||||
trialBalanceQuery={filter}
|
||||
onFetchData={handleFetchData}
|
||||
loading={trialBalanceSheetLoading}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -95,8 +97,5 @@ function TrialBalanceSheet({
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withTrialBalanceActions,
|
||||
withTrialBalance(({ trialBalanceSheetLoading }) => ({
|
||||
trialBalanceSheetLoading,
|
||||
})),
|
||||
withSettings,
|
||||
)(TrialBalanceSheet);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import moment from 'moment';
|
||||
import { Row, Col } from 'react-grid-system';
|
||||
@@ -9,6 +9,7 @@ import { Button } from "@blueprintjs/core";
|
||||
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
import withTrialBalance from './withTrialBalance';
|
||||
import withTrialBalanceActions from './withTrialBalanceActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
@@ -19,6 +20,10 @@ function TrialBalanceSheetHeader({
|
||||
|
||||
// #withTrialBalance
|
||||
trialBalanceSheetFilter,
|
||||
trialBalanceSheetRefresh,
|
||||
|
||||
// #withTrialBalanceActions
|
||||
refreshTrialBalance,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const formik = useFormik({
|
||||
@@ -38,29 +43,29 @@ function TrialBalanceSheetHeader({
|
||||
}
|
||||
});
|
||||
|
||||
const handleSubmitClick = useCallback(() => {
|
||||
formik.submitForm();
|
||||
}, [formik]);
|
||||
useEffect(() => {
|
||||
if (trialBalanceSheetRefresh) {
|
||||
formik.submitForm();
|
||||
refreshTrialBalance(false);
|
||||
}
|
||||
}, [formik, trialBalanceSheetRefresh]);
|
||||
|
||||
return (
|
||||
<FinancialStatementHeader show={trialBalanceSheetFilter}>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
|
||||
<Row>
|
||||
<Col sm={3}>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmitClick}
|
||||
disabled={formik.isSubmitting}
|
||||
className={'button--submit-filter'}>
|
||||
<T id={'run_report'} />
|
||||
</Button>
|
||||
</Col>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
</Row>
|
||||
</FinancialStatementHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withTrialBalance(({ trialBalanceSheetFilter }) => ({ trialBalanceSheetFilter })),
|
||||
withTrialBalance(({
|
||||
trialBalanceSheetFilter,
|
||||
trialBalanceSheetRefresh,
|
||||
}) => ({
|
||||
trialBalanceSheetFilter,
|
||||
trialBalanceSheetRefresh
|
||||
})),
|
||||
withTrialBalanceActions,
|
||||
)(TrialBalanceSheetHeader);
|
||||
@@ -14,13 +14,13 @@ import { compose } from 'utils';
|
||||
function TrialBalanceSheetTable({
|
||||
// #withTrialBalanceDetail
|
||||
trialBalanceAccounts,
|
||||
trialBalanceSheetLoading,
|
||||
|
||||
// #withTrialBalanceTable
|
||||
trialBalanceIndex,
|
||||
trialBalanceQuery,
|
||||
|
||||
onFetchData,
|
||||
loading,
|
||||
companyName,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
@@ -31,30 +31,41 @@ function TrialBalanceSheetTable({
|
||||
Header: formatMessage({ id: 'account_name' }),
|
||||
accessor: 'name',
|
||||
className: 'name',
|
||||
minWidth: 150,
|
||||
maxWidth: 150,
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'code' }),
|
||||
accessor: 'code',
|
||||
className: 'code',
|
||||
width: 120,
|
||||
minWidth: 80,
|
||||
maxWidth: 80,
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'credit' }),
|
||||
accessor: (r) => <Money amount={r.credit} currency="USD" />,
|
||||
className: 'credit',
|
||||
width: 120,
|
||||
minWidth: 95,
|
||||
maxWidth: 95,
|
||||
width: 95,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'debit' }),
|
||||
accessor: (r) => <Money amount={r.debit} currency="USD" />,
|
||||
className: 'debit',
|
||||
width: 120,
|
||||
minWidth: 95,
|
||||
maxWidth: 95,
|
||||
width: 95,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'balance' }),
|
||||
accessor: (r) => <Money amount={r.balance} currency="USD" />,
|
||||
className: 'balance',
|
||||
width: 120,
|
||||
minWidth: 95,
|
||||
maxWidth: 95,
|
||||
width: 95,
|
||||
},
|
||||
],
|
||||
[formatMessage],
|
||||
@@ -71,7 +82,7 @@ function TrialBalanceSheetTable({
|
||||
fromDate={trialBalanceQuery.from_date}
|
||||
toDate={trialBalanceQuery.to_date}
|
||||
name="trial-balance"
|
||||
loading={loading}
|
||||
loading={trialBalanceSheetLoading}
|
||||
>
|
||||
<DataTable
|
||||
className="bigcapital-datatable--financial-report"
|
||||
@@ -100,7 +111,11 @@ const withTrialBalanceTable = connect(mapStateToProps);
|
||||
|
||||
export default compose(
|
||||
withTrialBalanceTable,
|
||||
withTrialBalance(({ trialBalanceAccounts }) => ({
|
||||
withTrialBalance(({
|
||||
trialBalanceAccounts,
|
||||
trialBalanceSheetLoading,
|
||||
}) => ({
|
||||
trialBalanceAccounts,
|
||||
trialBalanceSheetLoading
|
||||
})),
|
||||
)(TrialBalanceSheetTable);
|
||||
|
||||
@@ -19,6 +19,7 @@ export default (mapState) => {
|
||||
),
|
||||
trialBalanceSheetLoading: state.financialStatements.trialBalance.loading,
|
||||
trialBalanceSheetFilter: state.financialStatements.trialBalance.filter,
|
||||
trialBalanceSheetRefresh: state.financialStatements.trialBalance.refresh,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
fetchTrialBalanceSheet
|
||||
fetchTrialBalanceSheet,
|
||||
trialBalanceRefresh,
|
||||
} from 'store/financialStatement/financialStatements.actions';
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
fetchTrialBalanceSheet: (query = {}) => dispatch(fetchTrialBalanceSheet({ query })),
|
||||
toggleTrialBalanceFilter: () => dispatch({ type: 'TRIAL_BALANCE_FILTER_TOGGLE' }),
|
||||
refreshTrialBalance: (refresh) => dispatch(trialBalanceRefresh(refresh)),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
Reference in New Issue
Block a user