fix: bugs in financial statements.

This commit is contained in:
Ahmed Bouhuolia
2020-05-26 19:50:30 +02:00
parent 2321c3be99
commit 1e663b6e49
9 changed files with 393 additions and 459 deletions

View File

@@ -16,8 +16,7 @@ import withSettings from 'containers/Settings/withSettings';
import withBalanceSheetActions from './withBalanceSheetActions'; import withBalanceSheetActions from './withBalanceSheetActions';
import withBalanceSheetDetail from './withBalanceSheetDetail'; import withBalanceSheetDetail from './withBalanceSheetDetail';
import {useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
function BalanceSheet({ function BalanceSheet({
// #withDashboard // #withDashboard
@@ -30,7 +29,7 @@ function BalanceSheet({
balanceSheetLoading, balanceSheetLoading,
// #withPreferences // #withPreferences
organizationSettings organizationSettings,
}) { }) {
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const [filter, setFilter] = useState({ const [filter, setFilter] = useState({
@@ -41,39 +40,35 @@ function BalanceSheet({
display_columns_by: '', display_columns_by: '',
none_zero: false, none_zero: false,
}); });
const [refetch, setRefetch] = useState(false);
const fetchHook = useQuery(
const fetchHook = useQuery(['balance-sheet', filter], ['balance-sheet', filter],
(key, query) => fetchBalanceSheet({ ...query }), (key, query) => fetchBalanceSheet({ ...query }),
{ manual: true }); { manual: true },
);
// Handle fetch the data of balance sheet. // Handle fetch the data of balance sheet.
const handleFetchData = useCallback(() => { const handleFetchData = useCallback(() => {
setRefetch(true); fetchHook.refetch({ force: true });
}, []); }, []);
useEffect(() => { useEffect(() => {
changePageTitle(formatMessage({ id: 'balance_sheet' })); changePageTitle(formatMessage({ id: 'balance_sheet' }));
}, [changePageTitle,formatMessage]); }, [changePageTitle, formatMessage]);
// Handle re-fetch balance sheet after filter change. // Handle re-fetch balance sheet after filter change.
const handleFilterSubmit = useCallback((filter) => { const handleFilterSubmit = useCallback(
const _filter = { (filter) => {
...filter, const _filter = {
from_date: moment(filter.from_date).format('YYYY-MM-DD'), ...filter,
to_date: moment(filter.to_date).format('YYYY-MM-DD'), from_date: moment(filter.from_date).format('YYYY-MM-DD'),
}; to_date: moment(filter.to_date).format('YYYY-MM-DD'),
setFilter({ ..._filter }); };
setRefetch(true); setFilter({ ..._filter });
}, [setFilter]);
// Refetch sheet effect.
useEffect(() => {
if (refetch) {
fetchHook.refetch({ force: true }); fetchHook.refetch({ force: true });
setRefetch(false); },
} [setFilter],
}, [refetch]) );
return ( return (
<DashboardInsider> <DashboardInsider>
@@ -83,14 +78,16 @@ function BalanceSheet({
<div class="financial-statement"> <div class="financial-statement">
<BalanceSheetHeader <BalanceSheetHeader
pageFilter={filter} pageFilter={filter}
onSubmitFilter={handleFilterSubmit} /> onSubmitFilter={handleFilterSubmit}
/>
<div class="financial-statement__body"> <div class="financial-statement__body">
<BalanceSheetTable <BalanceSheetTable
companyName={organizationSettings.name} companyName={organizationSettings.name}
loading={balanceSheetLoading} loading={balanceSheetLoading}
balanceSheetQuery={filter} balanceSheetQuery={filter}
onFetchData={handleFetchData} /> onFetchData={handleFetchData}
/>
</div> </div>
</div> </div>
</DashboardPageContent> </DashboardPageContent>
@@ -105,4 +102,4 @@ export default compose(
balanceSheetLoading, balanceSheetLoading,
})), })),
withSettings, withSettings,
)(BalanceSheet); )(BalanceSheet);

View File

@@ -1,4 +1,4 @@
import React, {useMemo, useCallback } from 'react'; import React, { useMemo, useCallback } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
@@ -8,13 +8,10 @@ import DataTable from 'components/DataTable';
import SettingsConnect from 'connectors/Settings.connect'; import SettingsConnect from 'connectors/Settings.connect';
import withBalanceSheetDetail from './withBalanceSheetDetail'; import withBalanceSheetDetail from './withBalanceSheetDetail';
import { import { getFinancialSheetIndexByQuery } from 'store/financialStatement/financialStatements.selectors';
getFinancialSheetIndexByQuery,
} from 'store/financialStatement/financialStatements.selectors';
import { compose, defaultExpanderReducer } from 'utils'; import { compose, defaultExpanderReducer } from 'utils';
function BalanceSheetTable({ function BalanceSheetTable({
// #withPreferences // #withPreferences
organizationSettings, organizationSettings,
@@ -28,113 +25,85 @@ function BalanceSheetTable({
onFetchData, onFetchData,
loading, loading,
}) { }) {
const { formatMessage } = useIntl();
const {formatMessage} = useIntl(); const columns = useMemo(
const columns = useMemo(() => [ () => [
{
// Build our expander column
id: 'expander', // Make sure it has an ID
className: 'expander',
Header: ({
getToggleAllRowsExpandedProps,
isAllRowsExpanded
}) => (
<span {...getToggleAllRowsExpandedProps()} className="toggle">
{isAllRowsExpanded ?
(<span class="arrow-down" />) :
(<span class="arrow-right" />)
}
</span>
),
Cell: ({ row }) =>
// Use the row.canExpand and row.getToggleRowExpandedProps prop getter
// to build the toggle for expanding a row
row.canExpand ? (
<span
{...row.getToggleRowExpandedProps({
style: {
// We can even use the row.depth property
// and paddingLeft to indicate the depth
// of the row
paddingLeft: `${row.depth * 2}rem`,
},
className: 'toggle',
})}
>
{row.isExpanded ?
(<span class="arrow-down" />) :
(<span class="arrow-right" />)
}
</span>
) : null,
width: 20,
disableResizing: true,
},
{
Header: formatMessage({id:'account_name'}),
accessor: 'name',
className: "account_name",
},
{
Header: formatMessage({id:'code'}),
accessor: 'code',
className: "code",
},
...(balanceSheetQuery.display_columns_type === 'total') ? [
{ {
Header: formatMessage({id:'total'}), Header: formatMessage({ id: 'account_name' }),
accessor: 'balance.formatted_amount', accessor: 'name',
Cell: ({ cell }) => { className: 'account_name',
const row = cell.row.original; },
if (row.total) { {
return (<Money amount={row.total.formatted_amount} currency={'USD'} />); Header: formatMessage({ id: 'code' }),
} accessor: 'code',
return ''; className: 'code',
}, },
className: "credit", ...(balanceSheetQuery.display_columns_type === 'total'
} ? [
] : [], {
...(balanceSheetQuery.display_columns_type === 'date_periods') ? Header: formatMessage({ id: 'total' }),
(balanceSheetColumns.map((column, index) => ({ accessor: 'balance.formatted_amount',
id: `date_period_${index}`, Cell: ({ cell }) => {
Header: column, const row = cell.row.original;
accessor: (row) => { if (row.total) {
if (row.total_periods && row.total_periods[index]) { return (
const amount = row.total_periods[index].formatted_amount; <Money
return (<Money amount={amount} currency={'USD'} />); amount={row.total.formatted_amount}
} currency={'USD'}
return ''; />
}, );
width: 100, }
}))) return '';
: [], },
], [balanceSheetQuery, balanceSheetColumns,formatMessage]); className: 'credit',
},
]
: []),
...(balanceSheetQuery.display_columns_type === 'date_periods'
? balanceSheetColumns.map((column, index) => ({
id: `date_period_${index}`,
Header: column,
accessor: (row) => {
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,
}))
: []),
],
[balanceSheetQuery, balanceSheetColumns, formatMessage],
);
const handleFetchData = useCallback(() => { const handleFetchData = useCallback(() => {
onFetchData && onFetchData(); onFetchData && onFetchData();
}, [onFetchData]); }, [onFetchData]);
// Calculates the default expanded rows of balance sheet table. // Calculates the default expanded rows of balance sheet table.
const expandedRows = useMemo(() => const expandedRows = useMemo(
defaultExpanderReducer(balanceSheetAccounts, 1), () => defaultExpanderReducer(balanceSheetAccounts, 1),
[balanceSheetAccounts]); [balanceSheetAccounts],
);
return ( return (
<FinancialSheet <FinancialSheet
companyName={organizationSettings.name} companyName={organizationSettings.name}
sheetType={'Balance Sheet'} sheetType={formatMessage({ id: 'balance_sheet' })}
fromDate={balanceSheetQuery.from_date} fromDate={balanceSheetQuery.from_date}
toDate={balanceSheetQuery.to_date} toDate={balanceSheetQuery.to_date}
basis={balanceSheetQuery.basis} basis={balanceSheetQuery.basis}
loading={loading}> loading={loading}
>
<DataTable <DataTable
className="bigcapital-datatable--financial-report" className="bigcapital-datatable--financial-report"
columns={columns} columns={columns}
data={balanceSheetAccounts} data={balanceSheetAccounts}
onFetchData={handleFetchData} onFetchData={handleFetchData}
expanded={expandedRows} expanded={expandedRows}
expandSubRows={true} /> expandSubRows={true}
/>
</FinancialSheet> </FinancialSheet>
); );
} }
@@ -153,13 +122,12 @@ const withBalanceSheetTable = connect(mapStateToProps);
export default compose( export default compose(
withBalanceSheetTable, withBalanceSheetTable,
withBalanceSheetDetail(({ withBalanceSheetDetail(
balanceSheetAccounts, ({ balanceSheetAccounts, balanceSheetColumns, balanceSheetQuery }) => ({
balanceSheetColumns,
balanceSheetQuery }) => ({
balanceSheetAccounts, balanceSheetAccounts,
balanceSheetColumns, balanceSheetColumns,
balanceSheetQuery, balanceSheetQuery,
})), }),
),
SettingsConnect, SettingsConnect,
)(BalanceSheetTable); )(BalanceSheetTable);

View File

@@ -38,7 +38,6 @@ function GeneralLedger({
basis: 'accural', basis: 'accural',
none_zero: true, none_zero: true,
}); });
const [refetch, setRefetch] = useState(false);
// Change page title of the dashboard. // Change page title of the dashboard.
useEffect(() => { useEffect(() => {
@@ -52,17 +51,9 @@ function GeneralLedger({
(key, query) => fetchGeneralLedger(query), (key, query) => fetchGeneralLedger(query),
{ manual: true }); { manual: true });
// Refetch general ledger sheet effect.
useEffect(() => {
if (refetch) {
fetchSheet.refetch({ force: true });
setRefetch(false);
}
}, [fetchSheet, refetch]);
// Handle fetch data of trial balance table. // Handle fetch data of trial balance table.
const handleFetchData = useCallback(() => { const handleFetchData = useCallback(() => {
setRefetch(true); fetchSheet.refetch({ force: true });
}, []); }, []);
// Handle financial statement filter change. // Handle financial statement filter change.
@@ -73,7 +64,7 @@ function GeneralLedger({
to_date: moment(filter.to_date).format('YYYY-MM-DD'), to_date: moment(filter.to_date).format('YYYY-MM-DD'),
}; };
setFilter(parsedFilter); setFilter(parsedFilter);
setRefetch(true); fetchSheet.refetch({ force: true });
}, [setFilter]); }, [setFilter]);
const handleFilterChanged = () => { }; const handleFilterChanged = () => { };

View File

@@ -1,22 +1,16 @@
import React, {useCallback, useMemo} from 'react'; import React, { useCallback, useMemo } from 'react';
import moment from 'moment'; import moment from 'moment';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import { defaultExpanderReducer, compose } from 'utils';
defaultExpanderReducer,
compose
} from 'utils';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import FinancialSheet from 'components/FinancialSheet'; import FinancialSheet from 'components/FinancialSheet';
import DataTable from 'components/DataTable'; import DataTable from 'components/DataTable';
import Money from 'components/Money'; import Money from 'components/Money';
import { import { getFinancialSheetIndexByQuery } from 'store/financialStatement/financialStatements.selectors';
getFinancialSheetIndexByQuery,
} from 'store/financialStatement/financialStatements.selectors';
import withGeneralLedger from './withGeneralLedger'; import withGeneralLedger from './withGeneralLedger';
const ROW_TYPE = { const ROW_TYPE = {
CLOSING_BALANCE: 'closing_balance', CLOSING_BALANCE: 'closing_balance',
OPENING_BALANCE: 'opening_balance', OPENING_BALANCE: 'opening_balance',
@@ -32,121 +26,97 @@ function GeneralLedgerTable({
generalLedgerTableRows, generalLedgerTableRows,
generalLedgerQuery, generalLedgerQuery,
}) { }) {
const { formatMessage } = useIntl();
// Account name column accessor. // Account name column accessor.
const accountNameAccessor = useCallback((row) => { const accountNameAccessor = useCallback(
switch (row.rowType) { (row) => {
case ROW_TYPE.OPENING_BALANCE: switch (row.rowType) {
return 'Opening Balance'; case ROW_TYPE.OPENING_BALANCE:
case ROW_TYPE.CLOSING_BALANCE: return 'Opening Balance';
return 'Closing Balance'; case ROW_TYPE.CLOSING_BALANCE:
default: return 'Closing Balance';
return row.name; default:
} return row.name;
}, [ROW_TYPE]); }
},
[ROW_TYPE],
);
// Date accessor. // Date accessor.
const dateAccessor = useCallback((row) => { const dateAccessor = useCallback(
const TYPES = [ (row) => {
ROW_TYPE.OPENING_BALANCE, const TYPES = [
ROW_TYPE.CLOSING_BALANCE, ROW_TYPE.OPENING_BALANCE,
ROW_TYPE.TRANSACTION]; ROW_TYPE.CLOSING_BALANCE,
ROW_TYPE.TRANSACTION,
];
return (TYPES.indexOf(row.rowType) !== -1) return TYPES.indexOf(row.rowType) !== -1
? moment(row.date).format('DD-MM-YYYY') : ''; ? moment(row.date).format('DD-MM-YYYY')
}, [moment, ROW_TYPE]); : '';
},
[moment, ROW_TYPE],
);
// Amount cell // Amount cell
const amountCell = useCallback(({ cell }) => { const amountCell = useCallback(({ cell }) => {
const transaction = cell.row.original const transaction = cell.row.original;
if (transaction.rowType === ROW_TYPE.ACCOUNT) { if (transaction.rowType === ROW_TYPE.ACCOUNT) {
return (!cell.row.isExpanded) ? return !cell.row.isExpanded ? (
(<Money amount={transaction.closing.amount} currency={"USD"} />) : ''; <Money amount={transaction.closing.amount} currency={'USD'} />
) : (
''
);
} }
return (<Money amount={transaction.amount} currency={"USD"} />); return <Money amount={transaction.amount} currency={'USD'} />;
}, []); }, []);
const referenceLink = useCallback((row) => { const referenceLink = useCallback((row) => {
return (<a href="">{row.referenceId}</a>); return <a href="">{row.referenceId}</a>;
}); });
const { formatMessage } = useIntl();
const columns = useMemo(() => [ const columns = useMemo(
{ () => [
// Build our expander column {
id: 'expander', // Make sure it has an ID Header: formatMessage({ id: 'account_name' }),
className: 'expander', accessor: accountNameAccessor,
Header: ({ className: 'name',
getToggleAllRowsExpandedProps, },
isAllRowsExpanded {
}) => ( Header: formatMessage({ id: 'date' }),
<span {...getToggleAllRowsExpandedProps()} className="toggle"> accessor: dateAccessor,
{isAllRowsExpanded ? className: 'date',
(<span class="arrow-down" />) : },
(<span class="arrow-right" />) {
} Header: formatMessage({ id: 'transaction_type' }),
</span> accessor: 'referenceType',
), className: 'transaction_type',
Cell: ({ row }) => },
// Use the row.canExpand and row.getToggleRowExpandedProps prop getter {
// to build the toggle for expanding a row Header: formatMessage({ id: 'trans_num' }),
row.canExpand ? ( accessor: referenceLink,
<span className: 'transaction_number',
{...row.getToggleRowExpandedProps({ },
style: { {
// We can even use the row.depth property Header: formatMessage({ id: 'description' }),
// and paddingLeft to indicate the depth accessor: 'note',
// of the row className: 'description',
paddingLeft: `${row.depth * 2}rem`, },
}, {
className: 'toggle', Header: formatMessage({ id: 'amount' }),
})} Cell: amountCell,
> className: 'amount',
{row.isExpanded ? },
(<span class="arrow-down" />) : {
(<span class="arrow-right" />) Header: formatMessage({ id: 'balance' }),
} Cell: amountCell,
</span> className: 'balance',
) : null, },
width: 20, ],
disableResizing: true, [],
}, );
{
Header: formatMessage({id:'account_name'}),
accessor: accountNameAccessor,
className: "name",
},
{
Header: formatMessage({id:'date'}),
accessor: dateAccessor,
className: "date",
},
{
Header: formatMessage({id:'transaction_type'}),
accessor: 'referenceType',
className: 'transaction_type',
},
{
Header: formatMessage({id:'trans_num'}),
accessor: referenceLink,
className: 'transaction_number'
},
{
Header: formatMessage({id:'description'}),
accessor: 'note',
className: 'description',
},
{
Header: formatMessage({id:'amount'}),
Cell: amountCell,
className: 'amount'
},
{
Header: formatMessage({id:'balance'}),
Cell: amountCell,
className: 'balance',
},
], []);
const handleFetchData = useCallback(() => { const handleFetchData = useCallback(() => {
onFetchData && onFetchData(); onFetchData && onFetchData();
@@ -155,23 +125,25 @@ function GeneralLedgerTable({
// Default expanded rows of general ledger table. // Default expanded rows of general ledger table.
const expandedRows = useMemo( const expandedRows = useMemo(
() => defaultExpanderReducer(generalLedgerTableRows, 1), () => defaultExpanderReducer(generalLedgerTableRows, 1),
[generalLedgerTableRows]); [generalLedgerTableRows],
);
const rowClassNames = (row) => ([ const rowClassNames = (row) => [`row-type--${row.original.rowType}`];
`row-type--${row.original.rowType}`,
]);
return ( return (
<FinancialSheet <FinancialSheet
companyName={companyName} companyName={companyName}
sheetType={'General Ledger Sheet'} sheetType={formatMessage({ id: 'general_ledger_sheet' })}
fromDate={generalLedgerQuery.from_date} fromDate={generalLedgerQuery.from_date}
toDate={generalLedgerQuery.to_date} toDate={generalLedgerQuery.to_date}
name="general-ledger" name="general-ledger"
loading={generalLedgerSheetLoading}> loading={generalLedgerSheetLoading}
>
<DataTable <DataTable
className="bigcapital-datatable--financial-report" className="bigcapital-datatable--financial-report"
noResults={formatMessage({
id: 'this_report_does_not_contain_any_data_between_date_period',
})}
columns={columns} columns={columns}
data={generalLedgerTableRows} data={generalLedgerTableRows}
onFetchData={handleFetchData} onFetchData={handleFetchData}
@@ -181,9 +153,10 @@ function GeneralLedgerTable({
fixedItemSize={37} fixedItemSize={37}
fixedSizeHeight={1000} fixedSizeHeight={1000}
expandable={true} expandable={true}
expandToggleColumn={1} /> expandToggleColumn={1}
/>
</FinancialSheet> </FinancialSheet>
); );
} }
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
@@ -201,13 +174,15 @@ const withGeneralLedgerTable = connect(mapStateToProps);
export default compose( export default compose(
withGeneralLedgerTable, withGeneralLedgerTable,
withGeneralLedger(({ withGeneralLedger(
generalLedgerTableRows, ({
generalLedgerSheetLoading, generalLedgerTableRows,
generalLedgerQuery, generalLedgerSheetLoading,
}) => ({ generalLedgerQuery,
generalLedgerTableRows, }) => ({
generalLedgerSheetLoading, generalLedgerTableRows,
generalLedgerQuery generalLedgerSheetLoading,
})), generalLedgerQuery,
}),
),
)(GeneralLedgerTable); )(GeneralLedgerTable);

View File

@@ -15,13 +15,12 @@ import SettingsConnect from 'connectors/Settings.connect';
import withDashboard from 'containers/Dashboard/withDashboard'; import withDashboard from 'containers/Dashboard/withDashboard';
import withJournalActions from './withJournalActions'; import withJournalActions from './withJournalActions';
function Journal({ function Journal({
// #withJournalActions // #withJournalActions
requestFetchJournalSheet, requestFetchJournalSheet,
// #withDashboard // #withDashboard
changePageTitle, changePageTitle,
// #withPreferences // #withPreferences
organizationSettings, organizationSettings,
@@ -29,76 +28,72 @@ function Journal({
const [filter, setFilter] = useState({ const [filter, setFilter] = useState({
from_date: moment().startOf('year').format('YYYY-MM-DD'), from_date: moment().startOf('year').format('YYYY-MM-DD'),
to_date: moment().endOf('year').format('YYYY-MM-DD'), to_date: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'accural' basis: 'accural',
}); });
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const [refetch, setRefetch] = useState(false);
useEffect(() => { useEffect(() => {
changePageTitle(formatMessage({id:'journal_sheet'})); changePageTitle(formatMessage({ id: 'journal_sheet' }));
}, [changePageTitle,formatMessage]); }, [changePageTitle, formatMessage]);
const fetchHook = useQuery(['journal', filter], const fetchHook = useQuery(
['journal', filter],
(key, query) => requestFetchJournalSheet(query), (key, query) => requestFetchJournalSheet(query),
{ manual: true }); { manual: true },
);
// Handle financial statement filter change. // Handle financial statement filter change.
const handleFilterSubmit = useCallback((filter) => { const handleFilterSubmit = useCallback(
const _filter = { (filter) => {
...filter, const _filter = {
from_date: moment(filter.from_date).format('YYYY-MM-DD'), ...filter,
to_date: moment(filter.to_date).format('YYYY-MM-DD'), from_date: moment(filter.from_date).format('YYYY-MM-DD'),
}; to_date: moment(filter.to_date).format('YYYY-MM-DD'),
setFilter(_filter); };
setRefetch(true); setFilter(_filter);
}, [fetchHook]); fetchHook.refetch({ force: true });
},
[fetchHook],
);
const handlePrintClick = useCallback(() => { const handlePrintClick = useCallback(() => {}, []);
}, []); const handleExportClick = useCallback(() => {}, []);
const handleExportClick = useCallback(() => {
}, []);
const handleFetchData = useCallback(({ sortBy, pageIndex, pageSize }) => { const handleFetchData = useCallback(({ sortBy, pageIndex, pageSize }) => {
setRefetch(true); fetchHook.refetch({ force: true });
}, []); }, []);
useEffect(() => {
if (refetch) {
fetchHook.refetch({ force: true });
setRefetch(false);
}
}, [refetch, fetchHook])
return ( return (
<DashboardInsider> <DashboardInsider>
<JournalActionsBar <JournalActionsBar
onSubmitFilter={handleFilterSubmit} onSubmitFilter={handleFilterSubmit}
onPrintClick={handlePrintClick} onPrintClick={handlePrintClick}
onExportClick={handleExportClick} /> onExportClick={handleExportClick}
/>
<DashboardPageContent> <DashboardPageContent>
<div class="financial-statement financial-statement--journal"> <div class="financial-statement financial-statement--journal">
<JournalHeader <JournalHeader
pageFilter={filter} pageFilter={filter}
onSubmitFilter={handleFilterSubmit} /> onSubmitFilter={handleFilterSubmit}
/>
<div class="financial-statement__table"> <div class="financial-statement__table">
<JournalTable <JournalTable
companyName={organizationSettings.name} companyName={organizationSettings.name}
journalQuery={filter} journalQuery={filter}
onFetchData={handleFetchData} /> onFetchData={handleFetchData}
/>
</div> </div>
</div> </div>
</DashboardPageContent> </DashboardPageContent>
</DashboardInsider> </DashboardInsider>
) );
} }
export default compose( export default compose(
withDashboard, withDashboard,
withJournalActions, withJournalActions,
SettingsConnect, SettingsConnect,
)(Journal); )(Journal);

View File

@@ -1,20 +1,17 @@
import React, { useCallback, useMemo } from 'react'; import React, { useCallback, useMemo } from 'react';
import {connect} from 'react-redux'; import { connect } from 'react-redux';
import moment from 'moment'; import moment from 'moment';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import FinancialSheet from 'components/FinancialSheet'; import FinancialSheet from 'components/FinancialSheet';
import DataTable from 'components/DataTable'; import DataTable from 'components/DataTable';
import {compose, defaultExpanderReducer} from 'utils'; import { compose, defaultExpanderReducer } from 'utils';
import Money from 'components/Money'; import Money from 'components/Money';
import { import { getFinancialSheetIndexByQuery } from 'store/financialStatement/financialStatements.selectors';
getFinancialSheetIndexByQuery,
} from 'store/financialStatement/financialStatements.selectors';
import withJournal from './withJournal'; import withJournal from './withJournal';
function JournalSheetTable({ function JournalSheetTable({
// #withJournal // #withJournal
journalSheetTableRows, journalSheetTableRows,
@@ -28,61 +25,80 @@ function JournalSheetTable({
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const rowTypeFilter = (rowType, value, types) => { const rowTypeFilter = (rowType, value, types) => {
return (types.indexOf(rowType) === -1) ? '' : value; return types.indexOf(rowType) === -1 ? '' : value;
}; };
const exceptRowTypes = (rowType, value, types) => { const exceptRowTypes = (rowType, value, types) => {
return (types.indexOf(rowType) !== -1) ? '' : value; return types.indexOf(rowType) !== -1 ? '' : value;
}; };
const columns = useMemo(() => [ const columns = useMemo(
{ () => [
Header: formatMessage({id:'date'}), {
accessor: r => rowTypeFilter(r.rowType, moment(r.date).format('YYYY/MM/DD'), ['first_entry']), Header: formatMessage({ id: 'date' }),
className: 'date', accessor: (r) =>
width: 85, rowTypeFilter(r.rowType, moment(r.date).format('YYYY/MM/DD'), [
}, 'first_entry',
{ ]),
Header: formatMessage({id:'transaction_type'}), className: 'date',
accessor: r => rowTypeFilter(r.rowType, r.transaction_type, ['first_entry']), width: 85,
className: "transaction_type", },
width: 145, {
}, Header: formatMessage({ id: 'transaction_type' }),
{ accessor: (r) =>
Header: formatMessage({id:'num'}), rowTypeFilter(r.rowType, r.transaction_type, ['first_entry']),
accessor: r => rowTypeFilter(r.rowType, r.reference_id, ['first_entry']), className: 'transaction_type',
className: 'reference_id', width: 145,
width: 70, },
}, {
{ Header: formatMessage({ id: 'num' }),
Header: formatMessage({id:'description'}), accessor: (r) =>
accessor: 'note', rowTypeFilter(r.rowType, r.reference_id, ['first_entry']),
}, className: 'reference_id',
{ width: 70,
Header: formatMessage({id:'acc_code'}), },
accessor: 'account.code', {
width: 120, Header: formatMessage({ id: 'description' }),
className: 'account_code', accessor: 'note',
}, },
{ {
Header: formatMessage({id:'account'}), Header: formatMessage({ id: 'acc_code' }),
accessor: 'account.name', accessor: 'account.code',
}, width: 120,
{ className: 'account_code',
Header: formatMessage({id:'credit'}), },
accessor: r => exceptRowTypes( {
r.rowType, (<Money amount={r.credit} currency={'USD'} />), ['space_entry']), Header: formatMessage({ id: 'account' }),
}, accessor: 'account.name',
{ },
Header: formatMessage({id:'debit'}), {
accessor: r => exceptRowTypes( Header: formatMessage({ id: 'credit' }),
r.rowType, (<Money amount={r.debit} currency={'USD'} />), ['space_entry']), accessor: (r) =>
}, exceptRowTypes(
], [formatMessage]); r.rowType,
<Money amount={r.credit} currency={'USD'} />,
['space_entry'],
),
},
{
Header: formatMessage({ id: 'debit' }),
accessor: (r) =>
exceptRowTypes(
r.rowType,
<Money amount={r.debit} currency={'USD'} />,
['space_entry'],
),
},
],
[formatMessage],
);
const handleFetchData = useCallback((...args) => { const handleFetchData = useCallback(
onFetchData && onFetchData(...args) (...args) => {
}, [onFetchData]); onFetchData && onFetchData(...args);
},
[onFetchData],
);
// Default expanded rows of general journal table. // Default expanded rows of general journal table.
const expandedRows = useMemo(() => defaultExpanderReducer([], 1), []); const expandedRows = useMemo(() => defaultExpanderReducer([], 1), []);
@@ -90,41 +106,45 @@ function JournalSheetTable({
return ( return (
<FinancialSheet <FinancialSheet
companyName={companyName} companyName={companyName}
sheetType={'Journal Sheet'} sheetType={formatMessage({ id: 'journal_sheet' })}
fromDate={journalSheetQuery.from_date} fromDate={journalSheetQuery.from_date}
toDate={journalSheetQuery.to_date} toDate={journalSheetQuery.to_date}
name="journal" name="journal"
loading={journalSheetLoading}> loading={journalSheetLoading}
>
<DataTable <DataTable
className="bigcapital-datatable--financial-report" className="bigcapital-datatable--financial-report"
columns={columns} columns={columns}
data={journalSheetTableRows} data={journalSheetTableRows}
onFetchData={handleFetchData} onFetchData={handleFetchData}
noResults={"This report does not contain any data between date period."} noResults={formatMessage({
expanded={expandedRows} /> id: 'this_report_does_not_contain_any_data_between_date_period',
})}
expanded={expandedRows}
/>
</FinancialSheet> </FinancialSheet>
); );
} }
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
const { journalQuery } = props; const { journalQuery } = props;
return { return {
journalIndex: getFinancialSheetIndexByQuery( journalIndex: getFinancialSheetIndexByQuery(
state.financialStatements.journal.sheets, state.financialStatements.journal.sheets,
journalQuery, journalQuery,
) ),
}; };
} };
const withJournalTable = connect(mapStateToProps); const withJournalTable = connect(mapStateToProps);
export default compose( export default compose(
withJournalTable, withJournalTable,
withJournal(({ journalSheetTableRows, journalSheetLoading, journalSheetQuery }) => ({ withJournal(
journalSheetTableRows, ({ journalSheetTableRows, journalSheetLoading, journalSheetQuery }) => ({
journalSheetLoading, journalSheetTableRows,
journalSheetQuery, journalSheetLoading,
})), journalSheetQuery,
)(JournalSheetTable); }),
),
)(JournalSheetTable);

View File

@@ -34,7 +34,6 @@ function ProfitLossSheet({
from_date: moment().startOf('year').format('YYYY-MM-DD'), from_date: moment().startOf('year').format('YYYY-MM-DD'),
to_date: moment().endOf('year').format('YYYY-MM-DD'), to_date: moment().endOf('year').format('YYYY-MM-DD'),
}); });
const [refetch, setRefetch] = useState(false);
// Change page title of the dashboard. // Change page title of the dashboard.
useEffect(() => { useEffect(() => {
@@ -54,20 +53,13 @@ function ProfitLossSheet({
to_date: moment(filter.to_date).format('YYYY-MM-DD'), to_date: moment(filter.to_date).format('YYYY-MM-DD'),
}; };
setFilter(_filter); setFilter(_filter);
setRefetch(true); fetchHook.refetch({ force: true });
}, []); }, []);
// Handle fetch data of profit/loss sheet table. // Handle fetch data of profit/loss sheet table.
const handleFetchData = useCallback(() => { const handleFetchData = useCallback(() => {
setRefetch(true); fetchHook.refetch({ force: true });
}, [fetchHook]); }, []);
useEffect(() => {
if (refetch) {
fetchHook.refetch({ force: true });
setRefetch(false);
}
}, [fetchHook, refetch]);
return ( return (
<DashboardInsider> <DashboardInsider>

View File

@@ -3,7 +3,7 @@ import { useQuery } from 'react-query';
import moment from 'moment'; import moment from 'moment';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import TrialBalanceSheetHeader from "./TrialBalanceSheetHeader"; import TrialBalanceSheetHeader from './TrialBalanceSheetHeader';
import TrialBalanceSheetTable from './TrialBalanceSheetTable'; import TrialBalanceSheetTable from './TrialBalanceSheetTable';
import TrialBalanceActionsBar from './TrialBalanceActionsBar'; import TrialBalanceActionsBar from './TrialBalanceActionsBar';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
@@ -16,8 +16,6 @@ import withTrialBalanceActions from './withTrialBalanceActions';
import withTrialBalance from './withTrialBalance'; import withTrialBalance from './withTrialBalance';
import withSettings from 'containers/Settings/withSettings'; import withSettings from 'containers/Settings/withSettings';
function TrialBalanceSheet({ function TrialBalanceSheet({
// #withDashboard // #withDashboard
changePageTitle, changePageTitle,
@@ -37,40 +35,36 @@ function TrialBalanceSheet({
basis: 'accural', basis: 'accural',
none_zero: false, none_zero: false,
}); });
const [refetch, setRefetch] = useState(false);
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const fetchHook = useQuery(['trial-balance', filter], const fetchHook = useQuery(
['trial-balance', filter],
(key, query) => fetchTrialBalanceSheet(query), (key, query) => fetchTrialBalanceSheet(query),
{ manual: true }); { manual: true },
);
// handle fetch data of trial balance table. // handle fetch data of trial balance table.
const handleFetchData = useCallback(() => { const handleFetchData = useCallback(() => {
setRefetch(true); fetchHook.refetch({ force: true });
}, [fetchHook]); }, []);
// Change page title of the dashboard. // Change page title of the dashboard.
useEffect(() => { useEffect(() => {
changePageTitle(formatMessage({id:'trial_balance_sheet'})); changePageTitle(formatMessage({ id: 'trial_balance_sheet' }));
}, [changePageTitle,formatMessage]); }, [changePageTitle, formatMessage]);
const handleFilterSubmit = useCallback((filter) => { const handleFilterSubmit = useCallback(
const parsedFilter = { (filter) => {
...filter, const parsedFilter = {
from_date: moment(filter.from_date).format('YYYY-MM-DD'), ...filter,
to_date: moment(filter.to_date).format('YYYY-MM-DD'), from_date: moment(filter.from_date).format('YYYY-MM-DD'),
}; to_date: moment(filter.to_date).format('YYYY-MM-DD'),
setFilter(parsedFilter); };
setRefetch(true); setFilter(parsedFilter);
}, []);
// Refetch sheet effect.
useEffect(() => {
if (refetch) {
fetchHook.refetch({ force: true }); fetchHook.refetch({ force: true });
setRefetch(false); },
} [fetchHook],
}, [fetchHook]); );
return ( return (
<DashboardInsider> <DashboardInsider>
@@ -80,19 +74,21 @@ function TrialBalanceSheet({
<div class="financial-statement"> <div class="financial-statement">
<TrialBalanceSheetHeader <TrialBalanceSheetHeader
pageFilter={filter} pageFilter={filter}
onSubmitFilter={handleFilterSubmit} /> onSubmitFilter={handleFilterSubmit}
/>
<div class="financial-statement__body"> <div class="financial-statement__body">
<TrialBalanceSheetTable <TrialBalanceSheetTable
companyName={organizationSettings.name} companyName={organizationSettings.name}
trialBalanceQuery={filter} trialBalanceQuery={filter}
onFetchData={handleFetchData} onFetchData={handleFetchData}
loading={trialBalanceSheetLoading} /> loading={trialBalanceSheetLoading}
/>
</div> </div>
</div> </div>
</DashboardPageContent> </DashboardPageContent>
</DashboardInsider> </DashboardInsider>
) );
} }
export default compose( export default compose(
@@ -102,4 +98,4 @@ export default compose(
trialBalanceSheetLoading, trialBalanceSheetLoading,
})), })),
withSettings, withSettings,
)(TrialBalanceSheet); )(TrialBalanceSheet);

View File

@@ -1,19 +1,16 @@
import React, {useCallback, useMemo} from 'react'; import React, { useCallback, useMemo } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { useIntl } from 'react-intl'; import { useIntl } from 'react-intl';
import FinancialSheet from 'components/FinancialSheet'; import FinancialSheet from 'components/FinancialSheet';
import DataTable from 'components/DataTable'; import DataTable from 'components/DataTable';
import Money from 'components/Money'; import Money from 'components/Money';
import { import { getFinancialSheetIndexByQuery } from 'store/financialStatement/financialStatements.selectors';
getFinancialSheetIndexByQuery,
} from 'store/financialStatement/financialStatements.selectors';
import withTrialBalance from './withTrialBalance'; import withTrialBalance from './withTrialBalance';
import { compose } from 'utils'; import { compose } from 'utils';
function TrialBalanceSheetTable({ function TrialBalanceSheetTable({
// #withTrialBalanceDetail // #withTrialBalanceDetail
trialBalanceAccounts, trialBalanceAccounts,
@@ -26,40 +23,42 @@ function TrialBalanceSheetTable({
loading, loading,
companyName, companyName,
}) { }) {
const { formatMessage } = useIntl();
const {formatMessage} =useIntl(); const columns = useMemo(
() => [
const columns = useMemo(() => [ {
{ Header: formatMessage({ id: 'account_name' }),
Header: formatMessage({ id:'account_name' }), accessor: 'name',
accessor: 'name', className: 'name',
className: "name", },
}, {
{ Header: formatMessage({ id: 'code' }),
Header: formatMessage({ id:'code' }), accessor: 'code',
accessor: 'code', className: 'code',
className: "code", width: 120,
width: 120, },
}, {
{ Header: formatMessage({ id: 'credit' }),
Header: formatMessage({ id:'credit' }), accessor: (r) => <Money amount={r.credit} currency="USD" />,
accessor: r => (<Money amount={r.credit} currency="USD" />), className: 'credit',
className: 'credit', width: 120,
width: 120, },
}, {
{ Header: formatMessage({ id: 'debit' }),
Header: formatMessage({ id:'debit' }), accessor: (r) => <Money amount={r.debit} currency="USD" />,
accessor: r => (<Money amount={r.debit} currency="USD" />), className: 'debit',
className: 'debit', width: 120,
width: 120, },
}, {
{ Header: formatMessage({ id: 'balance' }),
Header: formatMessage({ id:'balance' }), accessor: (r) => <Money amount={r.balance} currency="USD" />,
accessor: r => (<Money amount={r.balance} currency="USD" />), className: 'balance',
className: 'balance', width: 120,
width: 120, },
} ],
], [formatMessage]); [formatMessage],
);
const handleFetchData = useCallback(() => { const handleFetchData = useCallback(() => {
onFetchData && onFetchData(); onFetchData && onFetchData();
@@ -68,21 +67,22 @@ function TrialBalanceSheetTable({
return ( return (
<FinancialSheet <FinancialSheet
companyName={companyName} companyName={companyName}
sheetType={'Trial Balance Sheet'} sheetType={formatMessage({ id: 'trial_balance_sheet' })}
fromDate={trialBalanceQuery.from_date} fromDate={trialBalanceQuery.from_date}
toDate={trialBalanceQuery.to_date} toDate={trialBalanceQuery.to_date}
name="trial-balance" name="trial-balance"
loading={loading}> loading={loading}
>
<DataTable <DataTable
className="bigcapital-datatable--financial-report" className="bigcapital-datatable--financial-report"
columns={columns} columns={columns}
data={trialBalanceAccounts} data={trialBalanceAccounts}
onFetchData={handleFetchData} onFetchData={handleFetchData}
expandable={true} expandable={true}
expandToggleColumn={1} /> expandToggleColumn={1}
/>
</FinancialSheet> </FinancialSheet>
); );
} }
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
@@ -102,4 +102,4 @@ export default compose(
withTrialBalance(({ trialBalanceAccounts }) => ({ withTrialBalance(({ trialBalanceAccounts }) => ({
trialBalanceAccounts, trialBalanceAccounts,
})), })),
)(TrialBalanceSheetTable); )(TrialBalanceSheetTable);