mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
feat: balance sheet report.
feat: trial balance sheet. feat: general ledger report. feat: journal report. feat: profit/loss report.
This commit is contained in:
@@ -1,18 +1,24 @@
|
||||
import React from 'react';
|
||||
import { NavbarGroup, Button, Classes, NavbarDivider } from '@blueprintjs/core';
|
||||
import {
|
||||
NavbarGroup,
|
||||
Button,
|
||||
Classes,
|
||||
NavbarDivider,
|
||||
Popover,
|
||||
Position,
|
||||
PopoverInteractionKind,
|
||||
} from '@blueprintjs/core';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import Icon from 'components/Icon';
|
||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||
|
||||
import { If } from 'components';
|
||||
import withProfitLossActions from './withProfitLossActions';
|
||||
import withProfitLoss from './withProfitLoss';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
|
||||
function ProfitLossActionsBar({
|
||||
// #withProfitLoss
|
||||
profitLossSheetFilter,
|
||||
@@ -33,45 +39,43 @@ function ProfitLossActionsBar({
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--table-views')}
|
||||
icon={<Icon icon="cog-16" iconSize={16} />}
|
||||
text={<T id={'customize_report'} />}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(
|
||||
Classes.MINIMAL,
|
||||
'button--gray-highlight',
|
||||
)}
|
||||
text={'Re-calc Report'}
|
||||
className={classNames(Classes.MINIMAL, 'button--gray-highlight')}
|
||||
text={<T id={'recalc_report'} />}
|
||||
onClick={handleRecalcReport}
|
||||
icon={<Icon icon="refresh-16" iconSize={16} />}
|
||||
/>
|
||||
|
||||
<If condition={profitLossSheetFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
text={<T id={'hide_filter'} />}
|
||||
icon={<Icon icon="arrow-to-top" />}
|
||||
onClick={handleFilterClick}
|
||||
/>
|
||||
</If>
|
||||
|
||||
<If condition={!profitLossSheetFilter}>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
text={<T id={'show_filter'} />}
|
||||
icon={<Icon icon="arrow-to-bottom" />}
|
||||
onClick={handleFilterClick}
|
||||
/>
|
||||
</If>
|
||||
|
||||
<NavbarDivider />
|
||||
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--table-views')}
|
||||
icon={<Icon icon="cog-16" iconSize={16} />}
|
||||
text={
|
||||
profitLossSheetFilter ? (
|
||||
<T id={'hide_customizer'} />
|
||||
) : (
|
||||
<T id={'customize_report'} />
|
||||
)
|
||||
}
|
||||
onClick={handleFilterClick}
|
||||
active={profitLossSheetFilter}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
|
||||
<Popover
|
||||
// content={}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_LEFT}
|
||||
>
|
||||
<Button
|
||||
className={classNames(Classes.MINIMAL, 'button--filter')}
|
||||
text={<T id={'filter'} />}
|
||||
icon={<Icon icon="filter-16" iconSize={16} />}
|
||||
/>
|
||||
</Popover>
|
||||
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon='print-16' iconSize={16} />}
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
|
||||
@@ -2,6 +2,8 @@ import React, {useState, useCallback, useEffect} from 'react';
|
||||
import moment from 'moment';
|
||||
import {compose} from 'utils';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { queryCache } from 'react-query';
|
||||
|
||||
import ProfitLossSheetHeader from './ProfitLossSheetHeader';
|
||||
import ProfitLossSheetTable from './ProfitLossSheetTable';
|
||||
@@ -13,59 +15,71 @@ import DashboardPageContent from 'components/Dashboard/DashboardPageContent'
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withProfitLossActions from './withProfitLossActions';
|
||||
import withProfitLoss from './withProfitLoss';
|
||||
// import SettingsConnect from 'connectors/Settings.connect';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
|
||||
import { transformFilterFormToQuery } from 'containers/FinancialStatements/common';
|
||||
|
||||
function ProfitLossSheet({
|
||||
// #withDashboardActions
|
||||
changePageTitle,
|
||||
setDashboardBackLink,
|
||||
|
||||
// #withProfitLoss
|
||||
profitLossSheetRefresh,
|
||||
|
||||
// #withProfitLossActions
|
||||
fetchProfitLossSheet,
|
||||
refreshProfitLossSheet,
|
||||
|
||||
// #withPreferences
|
||||
organizationSettings,
|
||||
organizationName,
|
||||
}) {
|
||||
const [filter, setFilter] = useState({
|
||||
basis: 'cash',
|
||||
from_date: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
to_date: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
displayColumnsType: 'total',
|
||||
accountsFilter: 'all-accounts',
|
||||
});
|
||||
const [refresh, setRefresh] = useState(true);
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
// Change page title of the dashboard.
|
||||
useEffect(() => {
|
||||
changePageTitle('Profit/Loss Sheet');
|
||||
}, [changePageTitle]);
|
||||
changePageTitle(formatMessage({ id: 'profit_loss_sheet' }));
|
||||
}, [changePageTitle, formatMessage]);
|
||||
|
||||
// Observes the P&L sheet refresh to invalid the query to refresh it.
|
||||
useEffect(() => {
|
||||
if (profitLossSheetRefresh) {
|
||||
refreshProfitLossSheet(false);
|
||||
queryCache.invalidateQueries('profit-loss-sheet');
|
||||
}
|
||||
}, [profitLossSheetRefresh, refreshProfitLossSheet]);
|
||||
|
||||
useEffect(() => {
|
||||
// Show the back link on dashboard topbar.
|
||||
setDashboardBackLink(true);
|
||||
|
||||
return () => {
|
||||
// Hide the back link on dashboard topbar.
|
||||
setDashboardBackLink(false);
|
||||
};
|
||||
});
|
||||
|
||||
// Fetches profit/loss sheet.
|
||||
const fetchHook = useQuery(['profit-loss', filter],
|
||||
(key, query) => fetchProfitLossSheet(query),
|
||||
const fetchSheetHook = useQuery(['profit-loss-sheet', filter],
|
||||
(key, query) => fetchProfitLossSheet({ ...transformFilterFormToQuery(query) }),
|
||||
{ manual: true });
|
||||
|
||||
// Handle submit filter.
|
||||
const handleSubmitFilter = useCallback((filter) => {
|
||||
const _filter = {
|
||||
...filter,
|
||||
from_date: moment(filter.from_date).format('YYYY-MM-DD'),
|
||||
to_date: moment(filter.to_date).format('YYYY-MM-DD'),
|
||||
fromDate: moment(filter.fromDate).format('YYYY-MM-DD'),
|
||||
toDate: moment(filter.toDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(_filter);
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
// Handle fetch data of profit/loss sheet table.
|
||||
const handleFetchData = useCallback(() => {
|
||||
setRefresh(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (refresh) {
|
||||
fetchHook.refetch({ force: true });
|
||||
setRefresh(false);
|
||||
}
|
||||
}, [refresh, fetchHook]);
|
||||
}, [setFilter]);
|
||||
|
||||
return (
|
||||
<DashboardInsider>
|
||||
@@ -79,10 +93,9 @@ function ProfitLossSheet({
|
||||
|
||||
<div class="financial-statement__body">
|
||||
<ProfitLossSheetTable
|
||||
companyName={organizationSettings.name}
|
||||
profitLossQuery={filter}
|
||||
onFetchData={handleFetchData} />
|
||||
</div>
|
||||
companyName={organizationName}
|
||||
profitLossQuery={filter} />
|
||||
</div>
|
||||
</div>
|
||||
</DashboardPageContent>
|
||||
</DashboardInsider>
|
||||
@@ -92,5 +105,8 @@ function ProfitLossSheet({
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withProfitLossActions,
|
||||
withSettings,
|
||||
withProfitLoss(({ profitLossSheetRefresh }) => ({ profitLossSheetRefresh })),
|
||||
withSettings(({ organizationSettings }) => ({
|
||||
organizationName: organizationSettings.name,
|
||||
})),
|
||||
)(ProfitLossSheet);
|
||||
@@ -1,126 +1,102 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { Row, Col, Visible } from 'react-grid-system';
|
||||
import React, { useEffect } from 'react';
|
||||
import moment from 'moment';
|
||||
import { useFormik } from 'formik';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { FormGroup } from '@blueprintjs/core';
|
||||
import * as Yup from 'yup';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
import FinancialStatementHeader from 'containers/FinancialStatements/FinancialStatementHeader';
|
||||
import SelectsListColumnsBy from '../SelectDisplayColumnsBy';
|
||||
import RadiosAccountingBasis from '../RadiosAccountingBasis';
|
||||
import FinancialAccountsFilter from '../FinancialAccountsFilter';
|
||||
import ProfitLossSheetHeaderGeneralPane from './ProfitLossSheetHeaderGeneralPane';
|
||||
|
||||
import withProfitLoss from './withProfitLoss';
|
||||
import withProfitLossActions from './withProfitLossActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
|
||||
function ProfitLossHeader({
|
||||
// #ownProps
|
||||
pageFilter,
|
||||
onSubmitFilter,
|
||||
|
||||
// #withProfitLoss
|
||||
profitLossSheetFilter,
|
||||
profitLossSheetRefresh,
|
||||
|
||||
// #withProfitLossActions
|
||||
refreshProfitLossSheet,
|
||||
toggleProfitLossSheetFilter,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
initialValues: {
|
||||
...pageFilter,
|
||||
from_date: moment(pageFilter.from_date).toDate(),
|
||||
to_date: moment(pageFilter.to_date).toDate(),
|
||||
},
|
||||
validationSchema: Yup.object().shape({
|
||||
from_date: Yup.date()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'from_date' })),
|
||||
to_date: Yup.date()
|
||||
.min(Yup.ref('from_date'))
|
||||
.required()
|
||||
.label(formatMessage({ id: 'to_date' })),
|
||||
}),
|
||||
onSubmit: (values, actions) => {
|
||||
onSubmitFilter(values);
|
||||
actions.setSubmitting(false);
|
||||
},
|
||||
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
fromDate: Yup.date()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'from_date' })),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(formatMessage({ id: 'to_date' })),
|
||||
accountsFilter: Yup.string(),
|
||||
displayColumnsType: Yup.string(),
|
||||
});
|
||||
|
||||
// Handle item select of `display columns by` field.
|
||||
const handleItemSelectDisplayColumns = useCallback(
|
||||
(item) => {
|
||||
formik.setFieldValue('display_columns_type', item.type);
|
||||
formik.setFieldValue('display_columns_by', item.by);
|
||||
},
|
||||
[formik],
|
||||
);
|
||||
// Initial values.
|
||||
const initialValues = {
|
||||
...pageFilter,
|
||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||
toDate: moment(pageFilter.toDate).toDate(),
|
||||
};
|
||||
|
||||
const handleAccountingBasisChange = useCallback(
|
||||
(value) => {
|
||||
formik.setFieldValue('basis', value);
|
||||
},
|
||||
[formik],
|
||||
);
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, actions) => {
|
||||
onSubmitFilter(values);
|
||||
toggleProfitLossSheetFilter();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (profitLossSheetRefresh) {
|
||||
formik.submitForm();
|
||||
refreshProfitLossSheet(false);
|
||||
}
|
||||
}, [profitLossSheetRefresh]);
|
||||
|
||||
const handleAccountsFilterSelect = (filterType) => {
|
||||
const noneZero = filterType.key === 'without-zero-balance' ? true : false;
|
||||
formik.setFieldValue('none_zero', noneZero);
|
||||
// Handles the cancel button click.
|
||||
const handleCancelClick = () => {
|
||||
toggleProfitLossSheetFilter();
|
||||
};
|
||||
// Handles the drawer close action.
|
||||
const handleDrawerClose = () => {
|
||||
toggleProfitLossSheetFilter();
|
||||
};
|
||||
|
||||
return (
|
||||
<FinancialStatementHeader show={profitLossSheetFilter}>
|
||||
<Row>
|
||||
<FinancialStatementDateRange formik={formik} />
|
||||
<Visible xl><Col width={'100%'} /></Visible>
|
||||
|
||||
<Col width={260}>
|
||||
<SelectsListColumnsBy onItemSelect={handleItemSelectDisplayColumns} />
|
||||
</Col>
|
||||
|
||||
<Col width={260}>
|
||||
<FormGroup
|
||||
label={<T id={'filter_accounts'} />}
|
||||
className="form-group--select-list bp3-fill"
|
||||
inline={false}
|
||||
>
|
||||
<FinancialAccountsFilter
|
||||
initialSelectedItem={'all-accounts'}
|
||||
onItemSelect={handleAccountsFilterSelect}
|
||||
<FinancialStatementHeader
|
||||
isOpen={profitLossSheetFilter}
|
||||
drawerProps={{ onClose: handleDrawerClose }}
|
||||
>
|
||||
<Formik
|
||||
validationSchema={validationSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<Form>
|
||||
<Tabs animate={true} vertical={true} renderActiveTabPanelOnly={true}>
|
||||
<Tab
|
||||
id="general"
|
||||
title={<T id={'general'} />}
|
||||
panel={<ProfitLossSheetHeaderGeneralPane />}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Tabs>
|
||||
|
||||
<Col width={260}>
|
||||
<RadiosAccountingBasis
|
||||
selectedValue={formik.values.basis}
|
||||
onChange={handleAccountingBasisChange}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<div class="financial-header-drawer__footer">
|
||||
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>
|
||||
<T id={'calculate_report'} />
|
||||
</Button>
|
||||
<Button onClick={handleCancelClick} minimal={true}>
|
||||
<T id={'cancel'} />
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Formik>
|
||||
</FinancialStatementHeader>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withProfitLoss(({
|
||||
withProfitLoss(({ profitLossSheetFilter }) => ({
|
||||
profitLossSheetFilter,
|
||||
profitLossSheetRefresh,
|
||||
}) => ({
|
||||
profitLossSheetFilter,
|
||||
profitLossSheetRefresh,
|
||||
})),
|
||||
withProfitLossActions,
|
||||
)(ProfitLossHeader);
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
import SelectDisplayColumnsBy from '../SelectDisplayColumnsBy';
|
||||
import RadiosAccountingBasis from '../RadiosAccountingBasis';
|
||||
import FinancialAccountsFilter from '../FinancialAccountsFilter';
|
||||
|
||||
/**
|
||||
* Profit/Loss sheet - Drawer header - General panel.
|
||||
*/
|
||||
export default function ProfitLossSheetHeaderGeneralPane({}) {
|
||||
return (
|
||||
<div>
|
||||
<FinancialStatementDateRange />
|
||||
<SelectDisplayColumnsBy />
|
||||
<FinancialAccountsFilter initialSelectedItem={'all-accounts'} />
|
||||
<RadiosAccountingBasis key={'basis'} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +1,11 @@
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
|
||||
import FinancialSheet from 'components/FinancialSheet';
|
||||
import DataTable from 'components/DataTable';
|
||||
import Money from 'components/Money';
|
||||
|
||||
import { compose, defaultExpanderReducer } from 'utils';
|
||||
import { getFinancialSheetIndexByQuery } from 'store/financialStatement/financialStatements.selectors';
|
||||
import { compose, defaultExpanderReducer, getColumnWidth } from 'utils';
|
||||
import withProfitLossDetail from './withProfitLoss';
|
||||
|
||||
function ProfitLossSheetTable({
|
||||
@@ -18,7 +16,6 @@ function ProfitLossSheetTable({
|
||||
profitLossSheetLoading,
|
||||
|
||||
// #ownProps
|
||||
onFetchData,
|
||||
companyName,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
@@ -26,14 +23,10 @@ function ProfitLossSheetTable({
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: formatMessage({ id: 'account_name' }),
|
||||
accessor: 'name',
|
||||
Header: formatMessage({ id: 'account' }),
|
||||
accessor: (row) => (row.code ? `${row.name} - ${row.code}` : row.name),
|
||||
className: 'name',
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'account_code' }),
|
||||
accessor: 'code',
|
||||
className: 'account_code',
|
||||
width: 240,
|
||||
},
|
||||
...(profitLossQuery.display_columns_type === 'total'
|
||||
? [
|
||||
@@ -45,13 +38,14 @@ function ProfitLossSheetTable({
|
||||
return (
|
||||
<Money
|
||||
amount={row.total.formatted_amount}
|
||||
currency={'USD'}
|
||||
currency={row.total.currency_code}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
className: 'total',
|
||||
width: 140,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
@@ -60,40 +54,44 @@ function ProfitLossSheetTable({
|
||||
id: `date_period_${index}`,
|
||||
Header: column,
|
||||
accessor: (row) => {
|
||||
if (row.periods && row.periods[index]) {
|
||||
const amount = row.periods[index].formatted_amount;
|
||||
if (row.total_periods && row.total_periods[index]) {
|
||||
const amount = row.total_periods[index].formatted_amount;
|
||||
return <Money amount={amount} currency={'USD'} />;
|
||||
}
|
||||
return '';
|
||||
},
|
||||
width: 100,
|
||||
width: getColumnWidth(
|
||||
profitLossTableRows,
|
||||
`total_periods.${index}.formatted_amount`,
|
||||
{ minWidth: 100 },
|
||||
),
|
||||
className: 'total-period',
|
||||
}))
|
||||
: []),
|
||||
],
|
||||
[profitLossQuery.display_columns_type, profitLossColumns, formatMessage],
|
||||
);
|
||||
|
||||
// Handle data table fetch data.
|
||||
const handleFetchData = useCallback(
|
||||
(...args) => {
|
||||
onFetchData && onFetchData(...args);
|
||||
},
|
||||
[onFetchData],
|
||||
[profitLossQuery.display_columns_type, profitLossTableRows, profitLossColumns, formatMessage],
|
||||
);
|
||||
|
||||
// Retrieve default expanded rows of balance sheet.
|
||||
const expandedRows = useMemo(
|
||||
() => defaultExpanderReducer(profitLossTableRows, 1),
|
||||
() => defaultExpanderReducer(profitLossTableRows, 3),
|
||||
[profitLossTableRows],
|
||||
);
|
||||
|
||||
// Retrieve conditional datatable row classnames.
|
||||
const rowClassNames = useCallback(
|
||||
(row) => ({
|
||||
[`row--${row.rowType}`]: row.rowType,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
const rowClassNames = useCallback((row) => {
|
||||
const { original } = row;
|
||||
const rowTypes = Array.isArray(original.rowTypes)
|
||||
? original.rowTypes
|
||||
: [];
|
||||
|
||||
return {
|
||||
...rowTypes.reduce((acc, rowType) => {
|
||||
acc[`row_type--${rowType}`] = rowType;
|
||||
return acc;
|
||||
}, {}),
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<FinancialSheet
|
||||
@@ -109,7 +107,6 @@ function ProfitLossSheetTable({
|
||||
className="bigcapital-datatable--financial-report"
|
||||
columns={columns}
|
||||
data={profitLossTableRows}
|
||||
onFetchData={handleFetchData}
|
||||
noInitialFetch={true}
|
||||
expanded={expandedRows}
|
||||
rowClassNames={rowClassNames}
|
||||
@@ -121,19 +118,14 @@ function ProfitLossSheetTable({
|
||||
);
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
profitLossIndex: getFinancialSheetIndexByQuery(
|
||||
state.financialStatements.profitLoss.sheets,
|
||||
props.profitLossQuery,
|
||||
),
|
||||
});
|
||||
|
||||
const withProfitLossTable = connect(mapStateToProps);
|
||||
|
||||
export default compose(
|
||||
withProfitLossTable,
|
||||
withProfitLossDetail(
|
||||
({ profitLossQuery, profitLossColumns, profitLossTableRows, profitLossSheetLoading }) => ({
|
||||
({
|
||||
profitLossQuery,
|
||||
profitLossColumns,
|
||||
profitLossTableRows,
|
||||
profitLossSheetLoading,
|
||||
}) => ({
|
||||
profitLossColumns,
|
||||
profitLossQuery,
|
||||
profitLossTableRows,
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
getFinancialSheetIndexByQuery,
|
||||
getFinancialSheet,
|
||||
getFinancialSheetColumns,
|
||||
getFinancialSheetQuery,
|
||||
getFinancialSheetTableRows,
|
||||
getFinancialSheetFactory,
|
||||
getFinancialSheetColumnsFactory,
|
||||
getFinancialSheetQueryFactory,
|
||||
getFinancialSheetTableRowsFactory,
|
||||
} from 'store/financialStatement/financialStatements.selectors';
|
||||
|
||||
|
||||
export default (mapState) => {
|
||||
const mapStateToProps = (state, props) => {
|
||||
const { profitLossIndex } = props;
|
||||
const getProfitLossSheet = getFinancialSheetFactory('profitLoss');
|
||||
const getProfitLossColumns = getFinancialSheetColumnsFactory('profitLoss');
|
||||
const getProfitLossQuery = getFinancialSheetQueryFactory('profitLoss');
|
||||
const getProfitLossTableRows = getFinancialSheetTableRowsFactory('profitLoss');
|
||||
|
||||
const mapped = {
|
||||
profitLossSheet: getFinancialSheet(state.financialStatements.profitLoss.sheets, profitLossIndex),
|
||||
profitLossColumns: getFinancialSheetColumns(state.financialStatements.profitLoss.sheets, profitLossIndex),
|
||||
profitLossQuery: getFinancialSheetQuery(state.financialStatements.profitLoss.sheets, profitLossIndex),
|
||||
profitLossTableRows: getFinancialSheetTableRows(state.financialStatements.profitLoss.sheets, profitLossIndex),
|
||||
profitLossSheet: getProfitLossSheet(state, props),
|
||||
profitLossColumns: getProfitLossColumns(state, props),
|
||||
profitLossQuery: getProfitLossQuery(state, props),
|
||||
profitLossTableRows: getProfitLossTableRows(state, props),
|
||||
|
||||
profitLossSheetLoading: state.financialStatements.profitLoss.loading,
|
||||
profitLossSheetFilter: state.financialStatements.profitLoss.filter,
|
||||
|
||||
Reference in New Issue
Block a user