mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 14:50:32 +00:00
WIP financial statements.
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.10.0",
|
"@typescript-eslint/eslint-plugin": "^2.10.0",
|
||||||
"@typescript-eslint/parser": "^2.10.0",
|
"@typescript-eslint/parser": "^2.10.0",
|
||||||
|
"accounting": "^0.4.1",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
"babel-eslint": "10.0.3",
|
"babel-eslint": "10.0.3",
|
||||||
"babel-jest": "^24.9.0",
|
"babel-jest": "^24.9.0",
|
||||||
@@ -45,6 +46,7 @@
|
|||||||
"jest-environment-jsdom-fourteen": "1.0.1",
|
"jest-environment-jsdom-fourteen": "1.0.1",
|
||||||
"jest-resolve": "24.9.0",
|
"jest-resolve": "24.9.0",
|
||||||
"jest-watch-typeahead": "0.4.2",
|
"jest-watch-typeahead": "0.4.2",
|
||||||
|
"js-money": "^0.6.3",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"mini-css-extract-plugin": "0.9.0",
|
"mini-css-extract-plugin": "0.9.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
|
|||||||
@@ -131,7 +131,8 @@ function AccountsDataTable({
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
data={accounts}
|
data={accounts}
|
||||||
onFetchData={handleDatatableFetchData}
|
onFetchData={handleDatatableFetchData}
|
||||||
manualSortBy={true} />
|
manualSortBy={true}
|
||||||
|
selectionColumn={true} />
|
||||||
</LoadingIndicator>
|
</LoadingIndicator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import {
|
|||||||
import {Checkbox} from '@blueprintjs/core';
|
import {Checkbox} from '@blueprintjs/core';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
// import { FixedSizeList } from 'react-window'
|
|
||||||
|
|
||||||
const IndeterminateCheckbox = React.forwardRef(
|
const IndeterminateCheckbox = React.forwardRef(
|
||||||
({ indeterminate, ...rest }, ref) => {
|
({ indeterminate, ...rest }, ref) => {
|
||||||
@@ -23,9 +22,7 @@ const IndeterminateCheckbox = React.forwardRef(
|
|||||||
resolvedRef.current.indeterminate = indeterminate
|
resolvedRef.current.indeterminate = indeterminate
|
||||||
}, [resolvedRef, indeterminate])
|
}, [resolvedRef, indeterminate])
|
||||||
|
|
||||||
return (
|
return (<Checkbox ref={resolvedRef} {...rest} />);
|
||||||
<Checkbox ref={resolvedRef} {...rest} />
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -35,7 +32,9 @@ export default function DataTable({
|
|||||||
loading,
|
loading,
|
||||||
onFetchData,
|
onFetchData,
|
||||||
onSelectedRowsChange,
|
onSelectedRowsChange,
|
||||||
manualSortBy = 'false'
|
manualSortBy = 'false',
|
||||||
|
selectionColumn = false,
|
||||||
|
className
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
getTableProps,
|
getTableProps,
|
||||||
@@ -51,8 +50,8 @@ export default function DataTable({
|
|||||||
nextPage,
|
nextPage,
|
||||||
previousPage,
|
previousPage,
|
||||||
setPageSize,
|
setPageSize,
|
||||||
|
|
||||||
selectedFlatRows,
|
selectedFlatRows,
|
||||||
|
|
||||||
// Get the state from the instance
|
// Get the state from the instance
|
||||||
state: { pageIndex, pageSize, sortBy, selectedRowIds },
|
state: { pageIndex, pageSize, sortBy, selectedRowIds },
|
||||||
} = useTable(
|
} = useTable(
|
||||||
@@ -77,7 +76,7 @@ export default function DataTable({
|
|||||||
hooks => {
|
hooks => {
|
||||||
hooks.visibleColumns.push(columns => [
|
hooks.visibleColumns.push(columns => [
|
||||||
// Let's make a column for selection
|
// Let's make a column for selection
|
||||||
{
|
...(selectionColumn) ? [{
|
||||||
id: 'selection',
|
id: 'selection',
|
||||||
disableResizing: true,
|
disableResizing: true,
|
||||||
minWidth: 35,
|
minWidth: 35,
|
||||||
@@ -97,23 +96,19 @@ export default function DataTable({
|
|||||||
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
|
<IndeterminateCheckbox {...row.getToggleRowSelectedProps()} />
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
}] : [],
|
||||||
...columns,
|
...columns,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Debounce our onFetchData call for 100ms
|
|
||||||
const onFetchDataDebounced = useAsyncDebounce(onFetchData, 100);
|
|
||||||
const onSelectRowsDebounced = useAsyncDebounce(onSelectedRowsChange, 250);
|
|
||||||
|
|
||||||
// When these table states change, fetch new data!
|
// When these table states change, fetch new data!
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onFetchDataDebounced({ pageIndex, pageSize, sortBy })
|
onFetchData && onFetchData({ pageIndex, pageSize, sortBy })
|
||||||
}, []);
|
}, [pageIndex, pageSize, sortBy]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'bigcapital-datatable'}>
|
<div className={classnames('bigcapital-datatable', className)}>
|
||||||
<div {...getTableProps()} className="table">
|
<div {...getTableProps()} className="table">
|
||||||
<div className="thead">
|
<div className="thead">
|
||||||
{headerGroups.map(headerGroup => (
|
{headerGroups.map(headerGroup => (
|
||||||
@@ -157,8 +152,7 @@ export default function DataTable({
|
|||||||
className: classnames(cell.column.className || '', 'td'),
|
className: classnames(cell.column.className || '', 'td'),
|
||||||
})}>{ cell.render('Cell') }</div>
|
})}>{ cell.render('Cell') }</div>
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>)
|
||||||
)
|
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,26 +1,35 @@
|
|||||||
import React, { Children } from 'react';
|
import React, { Children } from 'react';
|
||||||
|
import moment from 'moment';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import LoadingIndicator from 'components/LoadingIndicator';
|
||||||
|
|
||||||
export default function FinancialSheet({
|
export default function FinancialSheet({
|
||||||
companyTitle,
|
companyTitle,
|
||||||
sheetType,
|
sheetType,
|
||||||
date,
|
date,
|
||||||
children,
|
children,
|
||||||
accountingBasis
|
accountingBasis,
|
||||||
|
name,
|
||||||
|
loading,
|
||||||
}) {
|
}) {
|
||||||
|
const formattedDate = moment(date).format('DD MMMM YYYY')
|
||||||
|
const nameModifer = name ? `financial-sheet--${name}` : '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="financial-sheet">
|
<div className={classnames('financial-sheet', nameModifer)}>
|
||||||
<h1 class="financial-sheet__title">{ companyTitle }</h1>
|
<LoadingIndicator loading={loading}>
|
||||||
<h6 class="financial-sheet__sheet-type">{ sheetType }</h6>
|
<h1 class="financial-sheet__title">{ companyTitle }</h1>
|
||||||
<span class="financial-sheet__date">{ date }</span>
|
<h6 class="financial-sheet__sheet-type">{ sheetType }</h6>
|
||||||
|
<div class="financial-sheet__date">As of { formattedDate }</div>
|
||||||
|
|
||||||
<div class="financial-sheet__table">
|
<div class="financial-sheet__table">
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="financial-sheet__accounting-basis">
|
<div class="financial-sheet__accounting-basis">
|
||||||
{ accountingBasis }
|
{ accountingBasis }
|
||||||
</div>
|
</div>
|
||||||
|
</LoadingIndicator>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -4,9 +4,10 @@ import { Spinner } from '@blueprintjs/core';
|
|||||||
export default function LoadingIndicator({
|
export default function LoadingIndicator({
|
||||||
loading,
|
loading,
|
||||||
spinnerSize = 40,
|
spinnerSize = 40,
|
||||||
children
|
children,
|
||||||
|
mount = true,
|
||||||
}) {
|
}) {
|
||||||
const [rendered, setRendered] = useState(false);
|
const [rendered, setRendered] = useState(mount);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!loading) { setRendered(true); }
|
if (!loading) { setRendered(true); }
|
||||||
|
|||||||
16
client/src/components/Money.js
Normal file
16
client/src/components/Money.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Currency from 'js-money/lib/currency';
|
||||||
|
import accounting from 'accounting';
|
||||||
|
|
||||||
|
function formattedAmount(cents, currency) {
|
||||||
|
const { symbol, decimal_digits: precision } = Currency[currency];
|
||||||
|
const amount = cents / Math.pow(10, precision);
|
||||||
|
|
||||||
|
return accounting.formatMoney(amount, { symbol, precision });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Money({ amount, currency }) {
|
||||||
|
return (
|
||||||
|
<span>{ formattedAmount(amount, currency) }</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,12 +6,15 @@ import {
|
|||||||
getTrialBalanceSheetIndex,
|
getTrialBalanceSheetIndex,
|
||||||
getTrialBalanceAccounts,
|
getTrialBalanceAccounts,
|
||||||
getTrialBalanceQuery,
|
getTrialBalanceQuery,
|
||||||
|
getFinancialSheetIndexByQuery,
|
||||||
} from 'store/financialStatement/financialStatements.selectors';
|
} from 'store/financialStatement/financialStatements.selectors';
|
||||||
|
|
||||||
export const mapStateToProps = (state, props) => ({
|
export const mapStateToProps = (state, props) => ({
|
||||||
getTrialBalanceSheetIndex: (query) => getTrialBalanceSheetIndex(state.financialStatements.trialBalanceSheets, query),
|
getTrialBalanceSheetIndex: (query) => getFinancialSheetIndexByQuery(state.financialStatements.trialBalance.sheets, query),
|
||||||
getTrialBalanceAccounts: (sheetIndex) => getTrialBalanceAccounts(state.financialStatements.trialBalanceSheets, sheetIndex),
|
getTrialBalanceAccounts: (sheetIndex) => getTrialBalanceAccounts(state.financialStatements.trialBalance.sheets, sheetIndex),
|
||||||
getTrialBalanceQuery: (sheetIndex) => getTrialBalanceQuery(state.financialStatements.trialBalanceSheets, sheetIndex),
|
getTrialBalanceQuery: (sheetIndex) => getTrialBalanceQuery(state.financialStatements.trialBalance.sheets, sheetIndex),
|
||||||
|
|
||||||
|
trialBalanceSheetLoading: state.financialStatements.trialBalance.loading,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const mapDispatchToProps = (dispatch) => ({
|
export const mapDispatchToProps = (dispatch) => ({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {useEffect, useMemo, useState} from 'react';
|
import React, {useEffect, useMemo, useCallback, useState} from 'react';
|
||||||
import DashboardConnect from 'connectors/Dashboard.connector';
|
import DashboardConnect from 'connectors/Dashboard.connector';
|
||||||
import {compose} from 'utils';
|
import {compose} from 'utils';
|
||||||
import useAsync from 'hooks/async';
|
import useAsync from 'hooks/async';
|
||||||
@@ -30,39 +30,41 @@ function BalanceSheet({
|
|||||||
|
|
||||||
const fetchHook = useAsync(async () => {
|
const fetchHook = useAsync(async () => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
fetchBalanceSheet(filter),
|
fetchBalanceSheet({
|
||||||
|
...filter,
|
||||||
|
display_columns_type: 'total',
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
setReload(false);
|
setReload(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
// Handle fetch the data of balance sheet.
|
||||||
if (!reload) { return; }
|
const handleFetchData = useCallback(() => { fetchHook.execute(); }, [fetchHook]);
|
||||||
fetchHook.execute();
|
|
||||||
}, [reload]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
changePageTitle('Balance Sheet');
|
changePageTitle('Balance Sheet');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Retrieve balance sheet index by the given filter query.
|
// Retrieve balance sheet index by the given filter query.
|
||||||
const balanceSheetIndex = useMemo(() => {
|
const balanceSheetIndex = useMemo(() =>
|
||||||
return getBalanceSheetIndexByQuery(filter);
|
getBalanceSheetIndexByQuery(filter),
|
||||||
}, [filter, balanceSheets]);
|
[filter, getBalanceSheetIndexByQuery]);
|
||||||
|
|
||||||
// Retreive balance sheet by the given sheet index.
|
// Retreive balance sheet by the given sheet index.
|
||||||
const balanceSheet = useMemo(() => {
|
const balanceSheet = useMemo(() =>
|
||||||
return getBalanceSheetByIndex(balanceSheetIndex);
|
getBalanceSheetByIndex(balanceSheetIndex),
|
||||||
}, [balanceSheetIndex, balanceSheets]);
|
[balanceSheetIndex, getBalanceSheetByIndex]);
|
||||||
|
|
||||||
// Handle re-fetch balance sheet after filter change.
|
// Handle re-fetch balance sheet after filter change.
|
||||||
const handleFilterSubmit = (filter) => {
|
const handleFilterSubmit = useCallback((filter) => {
|
||||||
setFilter({
|
setFilter({
|
||||||
...filter,
|
...filter,
|
||||||
from_date: moment(filter.from_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'),
|
to_date: moment(filter.to_date).format('YYYY-MM-DD'),
|
||||||
});
|
});
|
||||||
setReload(true);
|
setReload(true);
|
||||||
};
|
}, [setFilter]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="financial-statement">
|
<div class="financial-statement">
|
||||||
<BalanceSheetHeader
|
<BalanceSheetHeader
|
||||||
@@ -73,7 +75,9 @@ function BalanceSheet({
|
|||||||
<LoadingIndicator loading={fetchHook.pending}>
|
<LoadingIndicator loading={fetchHook.pending}>
|
||||||
<BalanceSheetTable
|
<BalanceSheetTable
|
||||||
balanceSheet={balanceSheet}
|
balanceSheet={balanceSheet}
|
||||||
balanceSheetIndex={balanceSheetIndex} />
|
balanceSheetIndex={balanceSheetIndex}
|
||||||
|
onFetchData={handleFetchData}
|
||||||
|
asDate={new Date()} />
|
||||||
</LoadingIndicator>
|
</LoadingIndicator>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
HTMLSelect,
|
HTMLSelect,
|
||||||
Intent,
|
Intent,
|
||||||
Popover,
|
Popover,
|
||||||
|
Classes,
|
||||||
} from "@blueprintjs/core";
|
} from "@blueprintjs/core";
|
||||||
import {Select} from '@blueprintjs/select';
|
import {Select} from '@blueprintjs/select';
|
||||||
import {DateInput} from '@blueprintjs/datetime';
|
import {DateInput} from '@blueprintjs/datetime';
|
||||||
@@ -21,6 +22,7 @@ import {
|
|||||||
parseDateRangeQuery,
|
parseDateRangeQuery,
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import Icon from 'components/Icon';
|
||||||
|
|
||||||
export default function BalanceSheetHeader({
|
export default function BalanceSheetHeader({
|
||||||
onSubmitFilter,
|
onSubmitFilter,
|
||||||
@@ -111,12 +113,16 @@ export default function BalanceSheetHeader({
|
|||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const infoIcon = useMemo(() => (<Icon icon="info-circle" iconSize={12} />), []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FinancialStatementHeader>
|
<FinancialStatementHeader>
|
||||||
<Row>
|
<Row>
|
||||||
<Col sm={3}>
|
<Col sm={3}>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={intl.formatMessage({'id': 'report_date_range'})}
|
label={intl.formatMessage({'id': 'report_date_range'})}
|
||||||
|
labelInfo={infoIcon}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
fill={true}>
|
fill={true}>
|
||||||
|
|
||||||
@@ -131,6 +137,7 @@ export default function BalanceSheetHeader({
|
|||||||
<Col sm={3}>
|
<Col sm={3}>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={intl.formatMessage({'id': 'from_date'})}
|
label={intl.formatMessage({'id': 'from_date'})}
|
||||||
|
labelInfo={infoIcon}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
fill={true}>
|
fill={true}>
|
||||||
|
|
||||||
@@ -146,6 +153,7 @@ export default function BalanceSheetHeader({
|
|||||||
<Col sm={3}>
|
<Col sm={3}>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={intl.formatMessage({'id': 'to_date'})}
|
label={intl.formatMessage({'id': 'to_date'})}
|
||||||
|
labelInfo={infoIcon}
|
||||||
minimal={true}
|
minimal={true}
|
||||||
fill={true}>
|
fill={true}>
|
||||||
|
|
||||||
@@ -163,7 +171,8 @@ export default function BalanceSheetHeader({
|
|||||||
<Col sm={3}>
|
<Col sm={3}>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={'Display report columns'}
|
label={'Display report columns'}
|
||||||
className="{'form-group-display-columns-by'}"
|
labelInfo={infoIcon}
|
||||||
|
className="form-group-display-columns-by form-group--select-list bp3-fill"
|
||||||
inline={false}>
|
inline={false}>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
@@ -184,6 +193,7 @@ export default function BalanceSheetHeader({
|
|||||||
<Col sm={3}>
|
<Col sm={3}>
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={'Show non-zero or active only'}
|
label={'Show non-zero or active only'}
|
||||||
|
className="form-group--select-list bp3-fill"
|
||||||
inline={false}>
|
inline={false}>
|
||||||
|
|
||||||
<Popover
|
<Popover
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import React, {useMemo, useState, useEffect} from 'react';
|
import React, {useMemo, useState, useCallback, useEffect} from 'react';
|
||||||
import FinancialSheet from 'components/FinancialSheet';
|
import FinancialSheet from 'components/FinancialSheet';
|
||||||
import DataTable from 'components/DataTable';
|
import DataTable from 'components/DataTable';
|
||||||
import FinancialStatementConnect from 'connectors/FinancialStatements.connector';
|
import FinancialStatementConnect from 'connectors/FinancialStatements.connector';
|
||||||
import {compose} from 'utils';
|
import {compose} from 'utils';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import Money from 'components/Money';
|
||||||
|
|
||||||
function BalanceSheetTable({
|
function BalanceSheetTable({
|
||||||
balanceSheet,
|
balanceSheet,
|
||||||
@@ -14,25 +15,32 @@ function BalanceSheetTable({
|
|||||||
getBalanceSheetLiabilitiesAccounts,
|
getBalanceSheetLiabilitiesAccounts,
|
||||||
|
|
||||||
getBalanceSheetQuery,
|
getBalanceSheetQuery,
|
||||||
}) {
|
|
||||||
const balanceSheetColumns = useMemo(() => {
|
|
||||||
return getBalanceSheetColumns(balanceSheetIndex);
|
|
||||||
}, [getBalanceSheetColumns]);
|
|
||||||
|
|
||||||
const balanceSheetQuery = useMemo(() => {
|
onFetchData,
|
||||||
return getBalanceSheetQuery(balanceSheetIndex);
|
asDate,
|
||||||
}, [getBalanceSheetQuery])
|
}) {
|
||||||
|
const balanceSheetColumns = useMemo(() =>
|
||||||
|
getBalanceSheetColumns(balanceSheetIndex),
|
||||||
|
[getBalanceSheetColumns, balanceSheetIndex]);
|
||||||
|
|
||||||
|
const balanceSheetQuery = useMemo(() =>
|
||||||
|
getBalanceSheetQuery(balanceSheetIndex),
|
||||||
|
[getBalanceSheetQuery, balanceSheetIndex])
|
||||||
|
|
||||||
const columns = useMemo(() => [
|
const columns = useMemo(() => [
|
||||||
{
|
{
|
||||||
// Build our expander column
|
// Build our expander column
|
||||||
id: 'expander', // Make sure it has an ID
|
id: 'expander', // Make sure it has an ID
|
||||||
|
className: 'expander',
|
||||||
Header: ({
|
Header: ({
|
||||||
getToggleAllRowsExpandedProps,
|
getToggleAllRowsExpandedProps,
|
||||||
isAllRowsExpanded
|
isAllRowsExpanded
|
||||||
}) => (
|
}) => (
|
||||||
<span {...getToggleAllRowsExpandedProps()}>
|
<span {...getToggleAllRowsExpandedProps()} className="toggle">
|
||||||
{isAllRowsExpanded ? '👇' : '👉'}
|
{isAllRowsExpanded ?
|
||||||
|
(<span class="arrow-down" />) :
|
||||||
|
(<span class="arrow-right" />)
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
Cell: ({ row }) =>
|
Cell: ({ row }) =>
|
||||||
@@ -47,30 +55,41 @@ function BalanceSheetTable({
|
|||||||
// of the row
|
// of the row
|
||||||
paddingLeft: `${row.depth * 2}rem`,
|
paddingLeft: `${row.depth * 2}rem`,
|
||||||
},
|
},
|
||||||
|
className: 'toggle',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{row.isExpanded ? '👇' : '👉'}
|
{row.isExpanded ?
|
||||||
|
(<span class="arrow-down" />) :
|
||||||
|
(<span class="arrow-right" />)
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
) : null,
|
) : null,
|
||||||
|
width: 20,
|
||||||
|
disableResizing: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Account Name',
|
Header: 'Account Name',
|
||||||
accessor: 'name',
|
accessor: 'name',
|
||||||
className: "actions",
|
className: "account_name",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Code',
|
Header: 'Code',
|
||||||
accessor: 'code',
|
accessor: 'code',
|
||||||
className: "note",
|
className: "code",
|
||||||
},
|
},
|
||||||
...(balanceSheetQuery &&
|
...(balanceSheetQuery &&
|
||||||
balanceSheetQuery.display_columns_by === 'total') ? [
|
balanceSheetQuery.display_columns_by === 'total') ? [
|
||||||
{
|
{
|
||||||
Header: 'Total',
|
Header: 'Total',
|
||||||
accessor: 'balance.formatted_amount',
|
accessor: 'balance.formatted_amount',
|
||||||
|
Cell: ({ cell }) => {
|
||||||
|
const row = cell.row.original;
|
||||||
|
if (!row.balance) { return ''; }
|
||||||
|
return (<Money amount={row.balance.formatted_amount} currency={'USD'} />);
|
||||||
|
},
|
||||||
className: "credit",
|
className: "credit",
|
||||||
}
|
}
|
||||||
]: (balanceSheetColumns.map((column, index) => ({
|
] : (balanceSheetColumns.map((column, index) => ({
|
||||||
Header: column,
|
Header: column,
|
||||||
accessor: (row) => {
|
accessor: (row) => {
|
||||||
if (row.periods_balance && row.periods_balance[index]) {
|
if (row.periods_balance && row.periods_balance[index]) {
|
||||||
@@ -87,33 +106,32 @@ function BalanceSheetTable({
|
|||||||
setData([
|
setData([
|
||||||
{
|
{
|
||||||
name: 'Assets',
|
name: 'Assets',
|
||||||
code: '',
|
children: getBalanceSheetAssetsAccounts(balanceSheetIndex),
|
||||||
children: [
|
|
||||||
...getBalanceSheetAssetsAccounts(balanceSheetIndex),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Liabilies & Equity',
|
name: 'Liabilies & Equity',
|
||||||
code: '',
|
children: getBalanceSheetLiabilitiesAccounts(balanceSheetIndex),
|
||||||
children: [
|
|
||||||
...getBalanceSheetLiabilitiesAccounts(balanceSheetIndex),
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
|
const handleFetchData = useCallback(() => {
|
||||||
|
onFetchData && onFetchData();
|
||||||
|
}, [onFetchData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FinancialSheet
|
<FinancialSheet
|
||||||
companyTitle={'Facebook, Incopration'}
|
companyTitle={'Facebook, Incopration'}
|
||||||
sheetType={'Balance Sheet'}
|
sheetType={'Balance Sheet'}
|
||||||
date={''}>
|
date={asDate}>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
|
className="bigcapital-datatable--financial-report"
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={data} />
|
data={data}
|
||||||
|
onFetchData={handleFetchData} />
|
||||||
</FinancialSheet>
|
</FinancialSheet>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import React, { useEffect, useState, useMemo } from 'react';
|
import React, { useEffect, useCallback, useState, useMemo } from 'react';
|
||||||
import TrialBalanceSheetHeader from "./TrialBalanceSheetHeader";
|
import TrialBalanceSheetHeader from "./TrialBalanceSheetHeader";
|
||||||
import LoadingIndicator from 'components/LoadingIndicator';
|
import LoadingIndicator from 'components/LoadingIndicator';
|
||||||
import TrialBalanceSheetTable from './TrialBalanceSheetTable';
|
import TrialBalanceSheetTable from './TrialBalanceSheetTable';
|
||||||
import { useAsync } from 'react-use';
|
import useAsync from 'hooks/async';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import {compose} from 'utils';
|
import {compose} from 'utils';
|
||||||
import TrialBalanceSheetConnect from 'connectors/TrialBalanceSheet.connect';
|
import TrialBalanceSheetConnect from 'connectors/TrialBalanceSheet.connect';
|
||||||
@@ -13,44 +13,48 @@ function TrialBalanceSheet({
|
|||||||
fetchTrialBalanceSheet,
|
fetchTrialBalanceSheet,
|
||||||
getTrialBalanceSheetIndex,
|
getTrialBalanceSheetIndex,
|
||||||
getTrialBalanceAccounts,
|
getTrialBalanceAccounts,
|
||||||
|
trialBalanceSheetLoading,
|
||||||
}) {
|
}) {
|
||||||
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: 'cash',
|
basis: 'accural',
|
||||||
none_zero: false,
|
none_zero: false,
|
||||||
});
|
});
|
||||||
const [reload, setReload] = useState(false);
|
|
||||||
|
|
||||||
const fetchHook = useAsync(async () => {
|
const fetchHook = useAsync((query = filter) => {
|
||||||
await Promise.all([
|
return Promise.all([
|
||||||
fetchTrialBalanceSheet(),
|
fetchTrialBalanceSheet(query),
|
||||||
]);
|
]);
|
||||||
});
|
}, false);
|
||||||
|
|
||||||
|
// handle fetch data of trial balance table.
|
||||||
|
const handleFetchData = useCallback(() => { fetchHook.execute() }, [fetchHook]);
|
||||||
|
|
||||||
// Retrieve balance sheet index by the given filter query.
|
// Retrieve balance sheet index by the given filter query.
|
||||||
const trialBalanceSheetIndex = useMemo(() => {
|
const trialBalanceSheetIndex = useMemo(() =>
|
||||||
return getTrialBalanceSheetIndex(filter);
|
getTrialBalanceSheetIndex(filter),
|
||||||
}, [getTrialBalanceSheetIndex, filter]);
|
[getTrialBalanceSheetIndex, filter]);
|
||||||
|
|
||||||
// Retrieve balance sheet accounts bu the given sheet index.
|
// Retrieve balance sheet accounts bu the given sheet index.
|
||||||
const trialBalanceAccounts = useMemo(() => {
|
const trialBalanceAccounts = useMemo(() =>
|
||||||
return getTrialBalanceAccounts(trialBalanceSheetIndex);
|
getTrialBalanceAccounts(trialBalanceSheetIndex),
|
||||||
}, [trialBalanceSheetIndex]);
|
[getTrialBalanceAccounts, trialBalanceSheetIndex]);
|
||||||
|
|
||||||
// Change page title of the dashboard.
|
// Change page title of the dashboard.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
changePageTitle('Trial Balance Sheet');
|
changePageTitle('Trial Balance Sheet');
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleFilterSubmit = (filter) => {
|
const handleFilterSubmit = useCallback((filter) => {
|
||||||
setFilter({
|
const parsedFilter = {
|
||||||
...filter,
|
...filter,
|
||||||
from_date: moment(filter.from_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'),
|
to_date: moment(filter.to_date).format('YYYY-MM-DD'),
|
||||||
});
|
};
|
||||||
setReload(true);
|
setFilter(parsedFilter);
|
||||||
};
|
fetchHook.execute(parsedFilter);
|
||||||
|
}, [setFilter, fetchHook]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="financial-statement">
|
<div class="financial-statement">
|
||||||
@@ -59,11 +63,11 @@ function TrialBalanceSheet({
|
|||||||
onSubmitFilter={handleFilterSubmit} />
|
onSubmitFilter={handleFilterSubmit} />
|
||||||
|
|
||||||
<div class="financial-statement__body">
|
<div class="financial-statement__body">
|
||||||
<LoadingIndicator loading={fetchHook.pending}>
|
<TrialBalanceSheetTable
|
||||||
<TrialBalanceSheetTable
|
trialBalanceSheetAccounts={trialBalanceAccounts}
|
||||||
trialBalanceSheetAccounts={trialBalanceAccounts}
|
trialBalanceSheetIndex={trialBalanceSheetIndex}
|
||||||
trialBalanceSheetIndex={trialBalanceSheetIndex} />
|
onFetchData={handleFetchData}
|
||||||
</LoadingIndicator>
|
loading={trialBalanceSheetLoading} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {useState} from 'react';
|
import React, {useState, useCallback} from 'react';
|
||||||
import FinancialStatementHeader from 'containers/Dashboard/FinancialStatements/FinancialStatementHeader';
|
import FinancialStatementHeader from 'containers/Dashboard/FinancialStatements/FinancialStatementHeader';
|
||||||
import {Row, Col} from 'react-grid-system';
|
import {Row, Col} from 'react-grid-system';
|
||||||
import {
|
import {
|
||||||
@@ -48,7 +48,7 @@ export default function TrialBalanceSheetHeader({
|
|||||||
setFilterByKey(name, date);
|
setFilterByKey(name, date);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmitClick = () => { onSubmitFilter(filter); };
|
const handleSubmitClick = useCallback(() => { onSubmitFilter(filter); }, [filter]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FinancialStatementHeader>
|
<FinancialStatementHeader>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import React, {useEffect, useState, useMemo} from 'react';
|
import React, {useEffect, useState, useCallback, useMemo} from 'react';
|
||||||
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';
|
||||||
|
|
||||||
export default function TrialBalanceSheetTable({
|
export default function TrialBalanceSheetTable({
|
||||||
trialBalanceSheetAccounts,
|
trialBalanceSheetAccounts,
|
||||||
trialBalanceSheetIndex,
|
trialBalanceSheetIndex,
|
||||||
|
onFetchData,
|
||||||
|
loading,
|
||||||
}) {
|
}) {
|
||||||
const [data, setData] = useState([]);
|
const [data, setData] = useState([]);
|
||||||
|
|
||||||
@@ -13,12 +15,16 @@ export default function TrialBalanceSheetTable({
|
|||||||
{
|
{
|
||||||
// Build our expander column
|
// Build our expander column
|
||||||
id: 'expander', // Make sure it has an ID
|
id: 'expander', // Make sure it has an ID
|
||||||
|
className: 'expander',
|
||||||
Header: ({
|
Header: ({
|
||||||
getToggleAllRowsExpandedProps,
|
getToggleAllRowsExpandedProps,
|
||||||
isAllRowsExpanded
|
isAllRowsExpanded
|
||||||
}) => (
|
}) => (
|
||||||
<span {...getToggleAllRowsExpandedProps()}>
|
<span {...getToggleAllRowsExpandedProps()} className="toggle">
|
||||||
{isAllRowsExpanded ? '👇' : '👉'}
|
{isAllRowsExpanded ?
|
||||||
|
(<span class="arrow-down" />) :
|
||||||
|
(<span class="arrow-right" />)
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
),
|
),
|
||||||
Cell: ({ row }) =>
|
Cell: ({ row }) =>
|
||||||
@@ -33,48 +39,66 @@ export default function TrialBalanceSheetTable({
|
|||||||
// of the row
|
// of the row
|
||||||
paddingLeft: `${row.depth * 2}rem`,
|
paddingLeft: `${row.depth * 2}rem`,
|
||||||
},
|
},
|
||||||
|
className: 'toggle',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{row.isExpanded ? '👇' : '👉'}
|
{row.isExpanded ?
|
||||||
|
(<span class="arrow-down" />) :
|
||||||
|
(<span class="arrow-right" />)
|
||||||
|
}
|
||||||
</span>
|
</span>
|
||||||
) : null,
|
) : null,
|
||||||
|
width: 20,
|
||||||
|
disableResizing: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Account Name',
|
Header: 'Account Name',
|
||||||
accessor: 'name',
|
accessor: 'name',
|
||||||
className: "actions",
|
className: "name",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Code',
|
Header: 'Code',
|
||||||
accessor: 'code',
|
accessor: 'code',
|
||||||
className: "note",
|
className: "code",
|
||||||
|
width: 120,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Credit',
|
Header: 'Credit',
|
||||||
accessor: 'credit',
|
accessor: r => (<Money amount={r.credit} currency="USD" />),
|
||||||
className: 'credit',
|
className: 'credit',
|
||||||
|
width: 120,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'debit',
|
Header: 'Debit',
|
||||||
accessor: 'debit',
|
accessor: r => (<Money amount={r.debit} currency="USD" />),
|
||||||
className: 'debit',
|
className: 'debit',
|
||||||
|
width: 120,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Header: 'Balance',
|
Header: 'Balance',
|
||||||
accessor: 'balance',
|
accessor: r => (<Money amount={r.balance} currency="USD" />),
|
||||||
className: 'balance',
|
className: 'balance',
|
||||||
|
width: 120,
|
||||||
}
|
}
|
||||||
], []);
|
], []);
|
||||||
|
|
||||||
|
const handleFetchData = useCallback(() => {
|
||||||
|
onFetchData && onFetchData();
|
||||||
|
}, [onFetchData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FinancialSheet
|
<FinancialSheet
|
||||||
companyTitle={'Facebook, Incopration'}
|
companyTitle={'Facebook, Incopration'}
|
||||||
sheetType={'Trial Balance Sheet'}
|
sheetType={'Trial Balance Sheet'}
|
||||||
date={''}>
|
date={new Date()}
|
||||||
|
name="trial-balance"
|
||||||
|
loading={loading}>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
|
className="bigcapital-datatable--financial-report"
|
||||||
columns={columns}
|
columns={columns}
|
||||||
data={trialBalanceSheetAccounts} />
|
data={trialBalanceSheetAccounts}
|
||||||
|
onFetchData={handleFetchData} />
|
||||||
</FinancialSheet>
|
</FinancialSheet>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -9,12 +9,12 @@ const useAsync = (asyncFunction, immediate = true) => {
|
|||||||
// handles setting state for pending, value, and error.
|
// handles setting state for pending, value, and error.
|
||||||
// useCallback ensures the below useEffect is not called
|
// useCallback ensures the below useEffect is not called
|
||||||
// on every render, but only if asyncFunction changes.
|
// on every render, but only if asyncFunction changes.
|
||||||
const execute = useCallback(() => {
|
const execute = useCallback((...args) => {
|
||||||
setPending(true);
|
setPending(true);
|
||||||
setValue(null);
|
setValue(null);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
return asyncFunction()
|
return asyncFunction(...args)
|
||||||
.then(response => setValue(response))
|
.then(response => setValue(response))
|
||||||
.catch(error => setError(error))
|
.catch(error => setError(error))
|
||||||
.finally(() => setPending(false));
|
.finally(() => setPending(false));
|
||||||
|
|||||||
@@ -86,5 +86,9 @@ export default {
|
|||||||
"sort-down": {
|
"sort-down": {
|
||||||
path: ['M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z'],
|
path: ['M41 288h238c21.4 0 32.1 25.9 17 41L177 448c-9.4 9.4-24.6 9.4-33.9 0L24 329c-15.1-15.1-4.4-41 17-41z'],
|
||||||
viewBox: '0 0 320 512'
|
viewBox: '0 0 320 512'
|
||||||
|
},
|
||||||
|
"info-circle": {
|
||||||
|
path: ['M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z'],
|
||||||
|
viewBox: '0 0 512 512'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,11 +28,19 @@ export const fetchBalanceSheet = ({ query }) => {
|
|||||||
|
|
||||||
export const fetchTrialBalanceSheet = ({ query }) => {
|
export const fetchTrialBalanceSheet = ({ query }) => {
|
||||||
return (dispatch) => new Promise((resolve, reject) => {
|
return (dispatch) => new Promise((resolve, reject) => {
|
||||||
|
dispatch({
|
||||||
|
type: t.TRIAL_BALANCE_SHEET_LOADING,
|
||||||
|
loading: true,
|
||||||
|
});
|
||||||
ApiService.get('/financial_statements/trial_balance_sheet', { params: query }).then((response) => {
|
ApiService.get('/financial_statements/trial_balance_sheet', { params: query }).then((response) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: t.TRAIL_BALANCE_STATEMENT_SET,
|
type: t.TRAIL_BALANCE_STATEMENT_SET,
|
||||||
data: response.data,
|
data: response.data,
|
||||||
});
|
});
|
||||||
|
dispatch({
|
||||||
|
type: t.TRIAL_BALANCE_SHEET_LOADING,
|
||||||
|
loading: false,
|
||||||
|
});
|
||||||
resolve(response.data);
|
resolve(response.data);
|
||||||
}).catch((error) => { reject(error); })
|
}).catch((error) => { reject(error); })
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import { createReducer } from '@reduxjs/toolkit';
|
|||||||
import t from 'store/types';
|
import t from 'store/types';
|
||||||
import {
|
import {
|
||||||
getBalanceSheetIndexByQuery,
|
getBalanceSheetIndexByQuery,
|
||||||
getTrialBalanceSheetIndex,
|
|
||||||
getFinancialSheetIndexByQuery,
|
getFinancialSheetIndexByQuery,
|
||||||
|
// getFinancialSheetIndexByQuery,
|
||||||
} from './financialStatements.selectors';
|
} from './financialStatements.selectors';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
balanceSheets: [],
|
balanceSheets: [],
|
||||||
trialBalanceSheets: [],
|
trialBalance: {
|
||||||
|
sheets: [],
|
||||||
|
loading: false,
|
||||||
|
},
|
||||||
generalLedger: [],
|
generalLedger: [],
|
||||||
journalSheets: [],
|
journalSheets: [],
|
||||||
};
|
};
|
||||||
@@ -30,19 +33,22 @@ export default createReducer(initialState, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
[t.TRAIL_BALANCE_STATEMENT_SET]: (state, action) => {
|
[t.TRAIL_BALANCE_STATEMENT_SET]: (state, action) => {
|
||||||
const index = getTrialBalanceSheetIndex(state.trialBalanceSheets, action.query);
|
const index = getFinancialSheetIndexByQuery(state.trialBalance.sheets, action.query);
|
||||||
|
|
||||||
const trailBalanceSheet = {
|
const trailBalanceSheet = {
|
||||||
accounts: action.data.accounts,
|
accounts: action.data.accounts,
|
||||||
query: action.data.query,
|
query: action.data.query,
|
||||||
};
|
};
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
state.trialBalanceSheets[index] = trailBalanceSheet;
|
state.trialBalance.sheets[index] = trailBalanceSheet;
|
||||||
} else {
|
} else {
|
||||||
state.trailBalanceSheet.push(trailBalanceSheet);
|
state.trialBalance.sheets.push(trailBalanceSheet);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[t.TRIAL_BALANCE_SHEET_LOADING]: (state, action) => {
|
||||||
|
state.trialBalance.loading = !!action.loading;
|
||||||
|
},
|
||||||
|
|
||||||
[t.JOURNAL_SHEET_SET]: (state, action) => {
|
[t.JOURNAL_SHEET_SET]: (state, action) => {
|
||||||
const index = getFinancialSheetIndexByQuery(state.journalSheets, action.query);
|
const index = getFinancialSheetIndexByQuery(state.journalSheets, action.query);
|
||||||
console.log(index, 'INDEX');
|
console.log(index, 'INDEX');
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ export default {
|
|||||||
GENERAL_LEDGER_STATEMENT_SET: 'GENERAL_LEDGER_STATEMENT_SET',
|
GENERAL_LEDGER_STATEMENT_SET: 'GENERAL_LEDGER_STATEMENT_SET',
|
||||||
BALANCE_SHEET_STATEMENT_SET: 'BALANCE_SHEET_STATEMENT_SET',
|
BALANCE_SHEET_STATEMENT_SET: 'BALANCE_SHEET_STATEMENT_SET',
|
||||||
TRAIL_BALANCE_STATEMENT_SET: 'TRAIL_BALANCE_STATEMENT_SET',
|
TRAIL_BALANCE_STATEMENT_SET: 'TRAIL_BALANCE_STATEMENT_SET',
|
||||||
|
TRIAL_BALANCE_SHEET_LOADING: 'TRIAL_BALANCE_SHEET_LOADING',
|
||||||
JOURNAL_SHEET_SET: 'JOURNAL_SHEET_SET',
|
JOURNAL_SHEET_SET: 'JOURNAL_SHEET_SET',
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ $pt-font-family: Noto Sans, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
|
|||||||
// Objects
|
// Objects
|
||||||
@import "objects/form";
|
@import "objects/form";
|
||||||
@import "objects/typography";
|
@import "objects/typography";
|
||||||
|
@import "objects/buttons";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
@import "components/data-table";
|
@import "components/data-table";
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
|
|
||||||
.bigcapital-datatable{
|
.bigcapital-datatable{
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
// max-width: 100%;
|
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
|
|
||||||
@@ -18,8 +16,6 @@
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
.th{
|
.th{
|
||||||
|
|
||||||
|
|
||||||
padding: 1rem 1.5rem;
|
padding: 1rem 1.5rem;
|
||||||
background: #F8FAFA;
|
background: #F8FAFA;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -78,7 +74,7 @@
|
|||||||
.inner-resizer{
|
.inner-resizer{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
background: #ececec;
|
border-left: 1px solid #ececec;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +100,58 @@
|
|||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tr .th.expander,
|
||||||
|
.tr .td.expander{
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.toggle{
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
padding: 14px 8px;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-right{
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: 5px solid transparent;
|
||||||
|
border-bottom: 5px solid transparent;
|
||||||
|
border-left: 8px solid #acacac;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-down{
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: 5px solid transparent;
|
||||||
|
border-right: 5px solid transparent;
|
||||||
|
border-top: 8px solid #acacac;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .td,
|
||||||
|
+ .th{
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&--financial-report{
|
||||||
|
|
||||||
|
.thead{
|
||||||
|
.tr .th{
|
||||||
|
background: transparent;
|
||||||
|
border-top: 1px solid #666;
|
||||||
|
border-bottom: 1px solid #666;
|
||||||
|
|
||||||
|
padding: 10px 1.5rem;
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
58
client/src/style/objects/buttons.scss
Normal file
58
client/src/style/objects/buttons.scss
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
|
||||||
|
|
||||||
|
.form-group--select-list{
|
||||||
|
|
||||||
|
.bp3-button{
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
|
||||||
|
&,
|
||||||
|
&:hover{
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 0 0;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group--select-list.bp3-fill{
|
||||||
|
|
||||||
|
.bp3-popover-wrapper{
|
||||||
|
&,
|
||||||
|
.bp3-popover-target{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-button{
|
||||||
|
width: 100%;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group--select-list{
|
||||||
|
|
||||||
|
.bp3-popover-open{
|
||||||
|
|
||||||
|
.bp3-button{
|
||||||
|
border-color: #80bdff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-button{
|
||||||
|
min-width: 32px;
|
||||||
|
min-height: 32px;
|
||||||
|
|
||||||
|
&.bp3-intent-primary,
|
||||||
|
&.bp3-intent-success,
|
||||||
|
&.bp3-intent-danger,
|
||||||
|
&.bp3-intent-warning{
|
||||||
|
|
||||||
|
&,
|
||||||
|
&:hover{
|
||||||
|
box-shadow: 0 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,15 +17,22 @@ label{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.#{$ns}-input{
|
.#{$ns}-input{
|
||||||
box-shadow: 0 0 0 0 rgba(19, 124, 189, 0),
|
box-shadow: 0 0 0;
|
||||||
0 0 0 0 rgba(19, 124, 189, 0),
|
border: 1px solid #ced4da;
|
||||||
inset 0 0 0 1px rgba(16, 22, 26, 0.1),
|
border-radius: 0;
|
||||||
inset 0 1px 1px rgba(16, 22, 26, 0.15);
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
color: #333;
|
||||||
|
|
||||||
|
&:focus,
|
||||||
|
&.bp3-active{
|
||||||
|
box-shadow: 0 0 0 .2rem rgba(0,123,255,.25);
|
||||||
|
border-color: #80bdff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.#{$ns}-form-group{
|
.#{$ns}-form-group{
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
&.#{$ns}-intent-danger{
|
&.#{$ns}-intent-danger{
|
||||||
select{
|
select{
|
||||||
@@ -36,4 +43,51 @@ label{
|
|||||||
inset 0 1px 1px rgba(16, 22, 26, 0.2);
|
inset 0 1px 1px rgba(16, 22, 26, 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.#{$ns}-label{
|
||||||
|
margin-bottom: 6px;
|
||||||
|
|
||||||
|
.#{$ns}-icon-info-circle{
|
||||||
|
margin-left: 3px;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
color: #A1B2C5;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.#{$ns}-button:not([class*=".#{$ns}-intent-"]) {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.#{$ns}-html-select select,
|
||||||
|
.#{$ns}-select select{
|
||||||
|
background-image: none;
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
&,
|
||||||
|
&:hover{
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 0 0;
|
||||||
|
border: 1px solid #ced4da;
|
||||||
|
}
|
||||||
|
&:focus{
|
||||||
|
box-shadow: 0 0 0 .2rem rgba(0,123,255,.25);
|
||||||
|
border-color: #80bdff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-datepicker-caption select{
|
||||||
|
|
||||||
|
&,
|
||||||
|
&:hover{
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group--select-list{
|
||||||
|
|
||||||
|
.#{$ns}-icon-caret-down{
|
||||||
|
color: #8D8D8D;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
body{
|
||||||
|
color: #212529;
|
||||||
|
}
|
||||||
|
|
||||||
.#{$ns}-heading{
|
.#{$ns}-heading{
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,14 @@
|
|||||||
.financial-statement{
|
.financial-statement{
|
||||||
|
|
||||||
&__header{
|
&__header{
|
||||||
padding: 30px;
|
padding: 25px 26px 25px;
|
||||||
background: #FDFDFD;
|
background: #FDFDFD;
|
||||||
|
|
||||||
|
.bp3-form-group .bp3-label{
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__body{
|
&__body{
|
||||||
@@ -21,28 +27,44 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin-top: 40px;
|
padding-top: 30px;
|
||||||
|
margin-top: 35px;
|
||||||
|
|
||||||
&__title{
|
&__title{
|
||||||
|
margin: 0;
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
color: #222;
|
color: #222;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__sheet-type{
|
&__sheet-type{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__date{
|
&__date{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: #888;
|
||||||
|
margin-top: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__table{
|
&__table{
|
||||||
|
margin-top: 24px;
|
||||||
|
|
||||||
|
.tbody{
|
||||||
|
.code.td{
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__accounting-basis{
|
&__accounting-basis{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--trial-balance{
|
||||||
|
min-width: 720px;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -74,7 +74,7 @@ factory.define('manual_journal', 'manual_journals', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory.define('item_category', 'items_categories', () => ({
|
factory.define('item_category', 'items_categories', () => ({
|
||||||
label: faker.name.firstName(),
|
name: faker.name.firstName(),
|
||||||
description: faker.lorem.text(),
|
description: faker.lorem.text(),
|
||||||
parent_category_id: null,
|
parent_category_id: null,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -414,10 +414,10 @@ export default {
|
|||||||
query('basis').optional(),
|
query('basis').optional(),
|
||||||
query('from_date').optional().isISO8601(),
|
query('from_date').optional().isISO8601(),
|
||||||
query('to_date').optional().isISO8601(),
|
query('to_date').optional().isISO8601(),
|
||||||
query('number_format.no_cents').optional().isBoolean(),
|
query('number_format.no_cents').optional().isBoolean().toBoolean(),
|
||||||
query('number_format.1000_divide').optional().isBoolean(),
|
query('number_format.1000_divide').optional().isBoolean().toBoolean(),
|
||||||
query('basis').optional(),
|
query('basis').optional(),
|
||||||
query('none_zero').optional(),
|
query('none_zero').optional().isBoolean().toBoolean(),
|
||||||
],
|
],
|
||||||
async handler(req, res) {
|
async handler(req, res) {
|
||||||
const validationErrors = validationResult(req);
|
const validationErrors = validationResult(req);
|
||||||
@@ -462,6 +462,7 @@ export default {
|
|||||||
const trial = journalEntries.getTrialBalance(account.id);
|
const trial = journalEntries.getTrialBalance(account.id);
|
||||||
return {
|
return {
|
||||||
account_id: account.id,
|
account_id: account.id,
|
||||||
|
name: account.name,
|
||||||
code: account.code,
|
code: account.code,
|
||||||
accountNormal: account.type.normal,
|
accountNormal: account.type.normal,
|
||||||
credit: balanceFormatter(trial.credit),
|
credit: balanceFormatter(trial.credit),
|
||||||
@@ -471,7 +472,7 @@ export default {
|
|||||||
});
|
});
|
||||||
return res.status(200).send({
|
return res.status(200).send({
|
||||||
query: { ...filter },
|
query: { ...filter },
|
||||||
items: [...items],
|
accounts: [...items],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user