refactor: re-structure financial reports components.

This commit is contained in:
a.bouhuolia
2022-02-12 12:21:05 +02:00
parent d445fec8c0
commit 526181aa68
18 changed files with 301 additions and 118 deletions

View File

@@ -1,8 +1,7 @@
import React, { useState, useCallback, useEffect } from 'react';
import moment from 'moment';
import 'style/pages/FinancialStatements/APAgingSummary.scss';
import { getDefaultAPAgingSummaryQuery } from './common';
import { FinancialStatement } from 'components';
import APAgingSummaryHeader from './APAgingSummaryHeader';
@@ -12,8 +11,8 @@ import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import { APAgingSummaryProvider } from './APAgingSummaryProvider';
import { APAgingSummarySheetLoadingBar } from './components';
import withCurrentOrganization from '../../Organization/withCurrentOrganization';
import withAPAgingSummaryActions from './withAPAgingSummaryActions';
import { compose } from 'utils';
/**
@@ -27,11 +26,7 @@ function APAgingSummary({
toggleAPAgingSummaryFilterDrawer: toggleDisplayFilterDrawer,
}) {
const [filter, setFilter] = useState({
asDate: moment().endOf('day').format('YYYY-MM-DD'),
agingDaysBefore: 30,
agingPeriods: 3,
vendorsIds: [],
filterByOption: 'without-zero-balance',
...getDefaultAPAgingSummaryQuery(),
});
// Handle filter submit.
@@ -50,7 +45,6 @@ function APAgingSummary({
numberFormat,
});
};
// Hide the report filter drawer once the page unmount.
useEffect(
() => () => {
@@ -73,18 +67,11 @@ function APAgingSummary({
pageFilter={filter}
onSubmitFilter={handleFilterSubmit}
/>
<div className={'financial-statement__body'}>
<APAgingSummaryTable organizationName={organizationName} />
</div>
<APAgingSummaryTable organizationName={organizationName} />
</FinancialStatement>
</DashboardPageContent>
</APAgingSummaryProvider>
);
}
export default compose(
withCurrentOrganization(({ organization }) => ({
organizationName: organization?.name,
})),
withAPAgingSummaryActions,
)(APAgingSummary);
export default compose(withAPAgingSummaryActions)(APAgingSummary);

View File

@@ -0,0 +1,37 @@
import React from 'react';
import * as R from 'ramda';
import { FinancialReportBody } from '../FinancialReportPage';
import APAgingSummaryTable from './APAgingSummaryTable';
import { FinancialSheetSkeleton } from '../../../components/FinancialSheet';
import withCurrentOrganization from '../../Organization/withCurrentOrganization';
import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
/**
* AP aging summary body.
* @returns {JSX.Element}
*/
function APAgingSummaryBodyJSX({
// #withCurrentOrganization
organizationName,
}) {
const { isLoading } = useAPAgingSummaryContext();
return (
<FinancialReportBody>
{isLoading ? (
<FinancialSheetSkeleton />
) : (
<APAgingSummaryTable organizationName={organizationName} />
)}
</FinancialReportBody>
);
}
export const APAgingSummaryBody = R.compose(
withCurrentOrganization(({ organization }) => ({
organizationName: organization?.name,
})),
)(APAgingSummaryBodyJSX);

View File

@@ -1,7 +1,9 @@
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components';
import { TableStyle } from 'common';
import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
import { useAPAgingSummaryColumns } from './components';
@@ -32,14 +34,26 @@ export default function APAgingSummaryTable({
asDate={new Date()}
loading={isAPAgingLoading}
>
<DataTable
className={'bigcapital-datatable--financial-report'}
<APAgingSummaryDataTable
columns={columns}
data={tableRows}
rowClassNames={rowClassNames}
noInitialFetch={true}
sticky={true}
styleName={TableStyle.Constrant}
/>
</FinancialSheet>
);
}
const APAgingSummaryDataTable = styled(DataTable)`
.table {
.tbody .tr {
.td {
border-bottom: 0;
padding-top: 0.32rem;
padding-bottom: 0.32rem;
}
}
}
`;

View File

@@ -1,5 +1,16 @@
import moment from 'moment';
import { transformToCamelCase, flatObject } from 'utils';
export const transformFilterFormToQuery = (form) => {
return flatObject(transformToCamelCase(form));
};
};
export const getDefaultAPAgingSummaryQuery = () => {
return {
asDate: moment().endOf('day').format('YYYY-MM-DD'),
agingDaysBefore: 30,
agingPeriods: 3,
vendorsIds: [],
filterByOption: 'without-zero-balance',
}
}

View File

@@ -1,38 +1,31 @@
import React, { useState, useCallback, useEffect } from 'react';
import moment from 'moment';
import 'style/pages/FinancialStatements/ARAgingSummary.scss';
// import 'style/pages/FinancialStatements/ARAgingSummary.scss';
import { FinancialStatement } from 'components';
import ARAgingSummaryHeader from './ARAgingSummaryHeader';
import ARAgingSummaryActionsBar from './ARAgingSummaryActionsBar';
import ARAgingSummaryTable from './ARAgingSummaryTable';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import { ARAgingSummaryProvider } from './ARAgingSummaryProvider';
import { ARAgingSummarySheetLoadingBar } from './components';
import { ARAgingSummaryBody } from './ARAgingSummaryBody';
import withARAgingSummaryActions from './withARAgingSummaryActions'
import withCurrentOrganization from '../../../containers/Organization/withCurrentOrganization';
import withARAgingSummaryActions from './withARAgingSummaryActions';
import { getDefaultARAgingSummaryQuery } from './common';
import { compose } from 'utils';
/**
* A/R aging summary report.
*/
function ReceivableAgingSummarySheet({
// #withSettings
organizationName,
// #withARAgingSummaryActions
toggleARAgingSummaryFilterDrawer: toggleDisplayFilterDrawer
toggleARAgingSummaryFilterDrawer: toggleDisplayFilterDrawer,
}) {
const [filter, setFilter] = useState({
asDate: moment().endOf('day').format('YYYY-MM-DD'),
agingDaysBefore: 30,
agingPeriods: 3,
customersIds: [],
filterByOption: 'without-zero-balance',
...getDefaultARAgingSummaryQuery(),
});
// Handle filter submit.
@@ -48,11 +41,13 @@ function ReceivableAgingSummarySheet({
const handleNumberFormatSubmit = (numberFormat) => {
setFilter({ ...filter, numberFormat });
};
// Hide the filter drawer once the page unmount.
useEffect(() => () => {
toggleDisplayFilterDrawer(false);
}, [toggleDisplayFilterDrawer]);
useEffect(
() => () => {
toggleDisplayFilterDrawer(false);
},
[toggleDisplayFilterDrawer],
);
return (
<ARAgingSummaryProvider filter={filter}>
@@ -68,18 +63,11 @@ function ReceivableAgingSummarySheet({
pageFilter={filter}
onSubmitFilter={handleFilterSubmit}
/>
<div class="financial-statement__body">
<ARAgingSummaryTable organizationName={organizationName} />
</div>
<ARAgingSummaryBody />
</FinancialStatement>
</DashboardPageContent>
</ARAgingSummaryProvider>
);
}
export default compose(
withCurrentOrganization(({ organization }) => ({
organizationName: organization.name,
})),
withARAgingSummaryActions
)(ReceivableAgingSummarySheet);
export default compose(withARAgingSummaryActions)(ReceivableAgingSummarySheet);

View File

@@ -0,0 +1,38 @@
import React from 'react';
import * as R from 'ramda';
import ARAgingSummaryTable from './ARAgingSummaryTable';
import {
FinancialReportBody,
FinancialSheetSkeleton,
} from '../../../components';
import withCurrentOrganization from '../../../containers/Organization/withCurrentOrganization';
import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
/**
* A/R Aging summary body.
* @returns {JSX.Element}
*/
function ARAgingSummaryBodyJSX({
// #withCurrentOrganization
organizationName,
}) {
const { isARAgingLoading } = useARAgingSummaryContext();
return (
<FinancialReportBody>
{isARAgingLoading ? (
<FinancialSheetSkeleton />
) : (
<ARAgingSummaryTable organizationName={organizationName} />
)}
</FinancialReportBody>
);
}
export const ARAgingSummaryBody = R.compose(
withCurrentOrganization(({ organization }) => ({
organizationName: organization.name,
})),
)(ARAgingSummaryBodyJSX);

View File

@@ -1,7 +1,9 @@
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import { DataTable, FinancialSheet } from 'components';
import { TableStyle } from 'common';
import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
import { useARAgingSummaryColumns } from './components';
@@ -29,14 +31,26 @@ export default function ReceivableAgingSummaryTable({
asDate={new Date()}
loading={isARAgingLoading}
>
<DataTable
className="bigcapital-datatable--financial-report"
<ARAgingSummaryDataTable
columns={columns}
data={ARAgingSummary.tableRows}
rowClassNames={rowClassNames}
noInitialFetch={true}
sticky={true}
styleName={TableStyle.Constrant}
/>
</FinancialSheet>
);
}
const ARAgingSummaryDataTable = styled(DataTable)`
.table {
.tbody .tr {
.td {
border-bottom: 0;
padding-top: 0.32rem;
padding-bottom: 0.32rem;
}
}
}
`;

View File

@@ -1,5 +1,19 @@
import moment from 'moment';
import { transformToCamelCase, flatObject } from 'utils';
export const transfromFilterFormToQuery = (form) => {
return flatObject(transformToCamelCase(form));
};
};
/**
* Retrieves the default A/R aging summary query.
*/
export const getDefaultARAgingSummaryQuery = () => {
return {
asDate: moment().endOf('day').format('YYYY-MM-DD'),
agingDaysBefore: 30,
agingPeriods: 3,
customersIds: [],
filterByOption: 'without-zero-balance',
};
};

View File

@@ -1,9 +1,11 @@
import React from 'react';
import intl from 'react-intl-universal';
import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
import { If, FormattedMessage as T } from 'components';
import { getColumnWidth } from 'utils';
import { FormattedMessage as T } from 'components';
import { If } from 'components';
import { Align } from 'common';
import FinancialLoadingBar from '../FinancialLoadingBar';
/**
@@ -40,6 +42,7 @@ export const useARAgingSummaryColumns = () => {
width: getColumnWidth(tableRows, `current`, {
minWidth: 120,
}),
align: Align.Right
},
...agingColumns.map((agingColumn, index) => ({
Header: agingColumn,
@@ -47,6 +50,7 @@ export const useARAgingSummaryColumns = () => {
width: getColumnWidth(tableRows, `aging-${index}`, {
minWidth: 120,
}),
align: Align.Right
})),
{
Header: <T id={'total'} />,
@@ -56,6 +60,7 @@ export const useARAgingSummaryColumns = () => {
width: getColumnWidth(tableRows, 'total', {
minWidth: 120,
}),
align: Align.Right
},
],
[tableRows, agingColumns],

View File

@@ -1,9 +1,7 @@
import React, { useCallback, useState } from 'react';
import moment from 'moment';
import 'style/pages/FinancialStatements/GeneralLedger.scss';
import GeneralLedgerTable from './GeneralLedgerTable';
import { FinancialStatement } from 'components';
import GeneralLedgerHeader from './GeneralLedgerHeader';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
@@ -13,12 +11,13 @@ import {
GeneralLedgerSheetAlerts,
GeneralLedgerSheetLoadingBar,
} from './components';
import { GeneralLedgerBody } from './GeneralLedgerBody';
import withGeneralLedgerActions from './withGeneralLedgerActions';
import withCurrentOrganization from '../../Organization/withCurrentOrganization';
import { transformFilterFormToQuery } from 'containers/FinancialStatements/common';
import { compose } from 'utils';
import { getDefaultGeneralLedgerQuery } from './common';
/**
* General Ledger (GL) sheet.
@@ -31,10 +30,7 @@ function GeneralLedger({
organizationName,
}) {
const [filter, setFilter] = useState({
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'accural',
filterByOption: 'with-transactions',
...getDefaultGeneralLedgerQuery(),
});
// Handle financial statement filter change.
@@ -63,29 +59,18 @@ function GeneralLedger({
<GeneralLedgerActionsBar />
<DashboardPageContent>
<div class="financial-statement financial-statement--general-ledger">
<FinancialStatement>
<GeneralLedgerHeader
pageFilter={filter}
onSubmitFilter={handleFilterSubmit}
/>
<GeneralLedgerSheetLoadingBar />
<GeneralLedgerSheetAlerts />
<div class="financial-statement__body">
<GeneralLedgerTable
companyName={organizationName}
generalLedgerQuery={filter}
/>
</div>
</div>
<GeneralLedgerBody />
</FinancialStatement>
</DashboardPageContent>
</GeneralLedgerProvider>
);
}
export default compose(
withGeneralLedgerActions,
withCurrentOrganization(({ organization }) => ({
organizationName: organization.name,
})),
)(GeneralLedger);
export default compose(withGeneralLedgerActions)(GeneralLedger);

View File

@@ -0,0 +1,36 @@
import React from 'react';
import * as R from 'ramda';
import GeneralLedgerTable from './GeneralLedgerTable';
import { FinancialSheetSkeleton } from '../../../components/FinancialSheet';
import withCurrentOrganization from '../../Organization/withCurrentOrganization';
import { FinancialReportBody } from '../FinancialReportPage';
import { useGeneralLedgerContext } from './GeneralLedgerProvider';
/**
* General ledger body JSX.
*/
function GeneralLedgerBodyJSX({
// #withCurrentOrganization
organizationName,
}) {
const { isLoading } = useGeneralLedgerContext();
return (
<FinancialReportBody>
{isLoading ? (
<FinancialSheetSkeleton />
) : (
<GeneralLedgerTable companyName={organizationName} />
)}
</FinancialReportBody>
);
}
export const GeneralLedgerBody = R.compose(
withCurrentOrganization(({ organization }) => ({
organizationName: organization.name,
})),
)(GeneralLedgerBodyJSX);

View File

@@ -11,6 +11,8 @@ import TableFastCell from 'components/Datatable/TableFastCell';
import { useGeneralLedgerContext } from './GeneralLedgerProvider';
import { useGeneralLedgerTableColumns } from './components';
import { TableStyle } from 'common';
/**
* General ledger table.
*/
@@ -41,7 +43,6 @@ export default function GeneralLedgerTable({ companyName }) {
fullWidth={true}
>
<DataTable
className="bigcapital-datatable--financial-report"
noResults={intl.get('this_report_does_not_contain_any_data_between_date_period')}
columns={columns}
data={tableRows}
@@ -54,10 +55,13 @@ export default function GeneralLedgerTable({ companyName }) {
expandToggleColumn={1}
sticky={true}
TableRowsRenderer={TableVirtualizedListRows}
// #TableVirtualizedListRows props.
vListrowHeight={28}
vListOverscanRowCount={0}
TableCellRenderer={TableFastCell}
styleName={TableStyle.Constrant}
/>
</FinancialSheet>
);

View File

@@ -1,4 +1,5 @@
import intl from 'react-intl-universal';
import moment from 'moment';
export const filterAccountsOptions = [
{
@@ -9,6 +10,20 @@ export const filterAccountsOptions = [
{
key: 'with-transactions',
name: intl.get('accounts_with_transactions'),
hint: intl.get('include_accounts_once_has_transactions_on_given_date_period'),
hint: intl.get(
'include_accounts_once_has_transactions_on_given_date_period',
),
},
];
/**
* Retrieves the default general ledger query.
*/
export const getDefaultGeneralLedgerQuery = () => {
return {
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'accural',
filterByOption: 'with-transactions',
};
};

View File

@@ -1,36 +1,29 @@
import React, { useState, useCallback, useEffect } from 'react';
import moment from 'moment';
import 'style/pages/FinancialStatements/Journal.scss';
import { FinancialStatement, DashboardPageContent } from 'components';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import JournalTable from './JournalTable';
import JournalHeader from './JournalHeader';
import JournalActionsBar from './JournalActionsBar';
import { JournalSheetProvider } from './JournalProvider';
import { JournalSheetLoadingBar, JournalSheetAlerts } from './components';
import { JournalBody } from './JournalBody';
import withCurrentOrganization from '../../Organization/withCurrentOrganization';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withJournalActions from './withJournalActions';
import { getDefaultJournalQuery } from './utils';
import { compose } from 'utils';
/**
* Journal sheet.
*/
function Journal({
// #withPreferences
organizationName,
// #withJournalActions
toggleJournalSheetFilter
toggleJournalSheetFilter,
}) {
const [filter, setFilter] = useState({
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'accural',
...getDefaultJournalQuery(),
});
// Handle financial statement filter change.
@@ -47,39 +40,30 @@ function Journal({
);
// Hide the journal sheet filter drawer once the page unmount.
useEffect(() => () => {
toggleJournalSheetFilter(false);
}, [toggleJournalSheetFilter]);
useEffect(
() => () => {
toggleJournalSheetFilter(false);
},
[toggleJournalSheetFilter],
);
return (
<JournalSheetProvider query={filter}>
<JournalActionsBar />
<DashboardPageContent>
<div class="financial-statement financial-statement--journal">
<FinancialStatement>
<JournalHeader
onSubmitFilter={handleFilterSubmit}
pageFilter={filter}
/>
<JournalSheetLoadingBar />
<JournalSheetAlerts />
<div class="financial-statement__body">
<JournalTable
companyName={organizationName}
journalQuery={filter}
/>
</div>
</div>
<JournalBody />
</FinancialStatement>
</DashboardPageContent>
</JournalSheetProvider>
);
}
export default compose(
withDashboardActions,
withJournalActions,
withCurrentOrganization(({ organization }) => ({
organizationName: organization.name,
})),
)(Journal);
export default compose(withDashboardActions, withJournalActions)(Journal);

View File

@@ -8,10 +8,11 @@ import {
PopoverInteractionKind,
Position,
} from '@blueprintjs/core';
import classNames from 'classnames';
import { FormattedMessage as T } from 'components';
import Icon from 'components/Icon';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import classNames from 'classnames';
import withJournalActions from './withJournalActions';
import withJournal from './withJournal';
@@ -56,7 +57,7 @@ function JournalActionsBar({
className={classNames(Classes.MINIMAL, 'button--table-views')}
icon={<Icon icon="cog-16" iconSize={16} />}
text={
(isFilterDrawerOpen) ? (
isFilterDrawerOpen ? (
<T id={'hide_customizer'} />
) : (
<T id={'customize_report'} />
@@ -97,7 +98,7 @@ function JournalActionsBar({
export default compose(
withJournal(({ journalSheetDrawerFilter }) => ({
isFilterDrawerOpen: journalSheetDrawerFilter
isFilterDrawerOpen: journalSheetDrawerFilter,
})),
withJournalActions,
)(JournalActionsBar);

View File

@@ -0,0 +1,37 @@
import React from 'react';
import * as R from 'ramda';
import { FinancialReportBody } from '../FinancialReportPage';
import { FinancialSheetSkeleton } from '../../../components/FinancialSheet';
import { JournalTable } from './JournalTable';
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
import { useJournalSheetContext } from './JournalProvider';
/**
* Journal report body.
* @returns {JSX.Element}
*/
function JournalBodyJSX({
// #withCurrentOrganization
organizationName,
}) {
const { isLoading } = useJournalSheetContext();
return (
<FinancialReportBody>
{isLoading ? (
<FinancialSheetSkeleton />
) : (
<JournalTable companyName={organizationName} />
)}
</FinancialReportBody>
);
}
export const JournalBody = R.compose(
withCurrentOrganization(({ organization }) => ({
organizationName: organization.name,
})),
)(JournalBodyJSX);

View File

@@ -10,11 +10,13 @@ import { useJournalSheetContext } from './JournalProvider';
import { defaultExpanderReducer } from 'utils';
export default function JournalSheetTable({
// #ownProps
onFetchData,
companyName,
}) {
import { TableStyle } from 'common';
/**
* Journal sheet table.
* @returns {JSX.Element}
*/
export function JournalTable({ companyName }) {
// Journal sheet context.
const {
journalSheet: { tableRows, query },
@@ -49,11 +51,9 @@ export default function JournalSheetTable({
toDate={query.to_date}
name="journal"
loading={isLoading}
// minimal={true}
fullWidth={true}
>
<DataTable
className="bigcapital-datatable--financial-report"
columns={columns}
data={tableRows}
rowClassNames={rowClassNames}
@@ -68,6 +68,7 @@ export default function JournalSheetTable({
vListOverscanRowCount={2}
TableCellRenderer={TableFastCell}
id={'journal'}
styleName={TableStyle.Constrant}
/>
</FinancialSheet>
);

View File

@@ -0,0 +1,12 @@
import moment from 'moment';
/**
* Retrieves the default journal report query.
*/
export const getDefaultJournalQuery = () => {
return {
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'accural',
}
}