This commit is contained in:
elforjani3
2021-01-21 15:19:46 +02:00
62 changed files with 1598 additions and 794 deletions

View File

@@ -2,6 +2,8 @@ import React from 'react';
import { Switch, Route } from 'react-router';
import { useQuery } from 'react-query';
import 'style/pages/Dashboard/Dashboard.scss';
import DashboardLoadingIndicator from './DashboardLoadingIndicator';
import Sidebar from 'components/Sidebar/Sidebar';
@@ -15,8 +17,6 @@ import withSettingsActions from 'containers/Settings/withSettingsActions';
import { compose } from 'utils';
import 'style/pages/Dashboard/Dashboard.scss';
/**
* Dashboard page.
*/

View File

@@ -191,7 +191,7 @@ export default function DataTable({
// Renders table cell.
const RenderCell = useCallback(
({ row, cell, index }) => (
({ row, cell, column, index }) => (
<ConditionalWrapper
condition={expandToggleColumn === index && expandable}
wrapper={(children) => (
@@ -199,6 +199,7 @@ export default function DataTable({
style={{
'padding-left': `${row.depth * expandColumnSpace}rem`,
}}
className={'expend-padding'}
>
{children}
</div>
@@ -224,7 +225,14 @@ export default function DataTable({
/>
</span>
</If>
{cell.render('Cell')}
<ConditionalWrapper
condition={cell.column.textOverview}
wrapper={(children) => (
<span class="text-overview">{ children }</span>
)}>
{cell.render('Cell')}
</ConditionalWrapper>
</ConditionalWrapper>
),
[expandable, expandToggleColumn, expandColumnSpace],
@@ -276,7 +284,13 @@ export default function DataTable({
return (
<div
{...cell.getCellProps({
className: classnames(cell.column.className || '', 'td'),
className: classnames(
cell.column.className,
'td',
{
'is-text-overview': cell.column.textOverview,
}
),
})}
onContextMenu={handleRowContextMenu(cell, row)}
>

View File

@@ -0,0 +1,5 @@
import React from 'react';
export function CellTextSpan({ cell: { value } }) {
return (<span class="cell-text">{ value }</span>)
}

View File

@@ -3,9 +3,10 @@ import moment from 'moment';
import classnames from 'classnames';
import { FormattedMessage as T, useIntl } from 'react-intl';
import 'style/pages/FinancialStatements/FinancialSheet.scss';
import { If, LoadingIndicator, MODIFIER } from 'components';
import 'style/pages/FinancialStatements/FinancialSheet.scss';
export default function FinancialSheet({
companyName,
@@ -20,7 +21,8 @@ export default function FinancialSheet({
className,
basis,
minimal = false,
fullWidth = false
fullWidth = false,
currentDate = true,
}) {
const { formatMessage } = useIntl();
const format = 'DD MMMM YYYY';
@@ -84,11 +86,19 @@ export default function FinancialSheet({
<div class="financial-sheet__table">{children}</div>
<div class="financial-sheet__accounting-basis">{accountingBasis}</div>
{basisLabel && (
<div class="financial-sheet__basis">
<T id={'accounting_basis'} /> {basisLabel}
</div>
)}
<div class="financial-sheet__footer">
<If condition={basisLabel}>
<span class="financial-sheet__basis">
<T id={'accounting_basis'} /> {basisLabel}
</span>
</If>
<If condition={currentDate}>
<span class="financial-sheet__current-date">
{moment().format('YYYY MMM DD HH:MM')}
</span>
</If>
</div>
</div>
</div>
);

View File

@@ -27,8 +27,6 @@ import withAccounts from 'containers/Accounts/withAccounts';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withCurrentView from 'containers/Views/withCurrentView';
import { accountNameAccessor } from './utils';
function AccountsDataTable({
// #withDashboardActions
accountsTable,
@@ -136,7 +134,7 @@ function AccountsDataTable({
{
id: 'name',
Header: formatMessage({ id: 'account_name' }),
accessor: accountNameAccessor,
accessor: 'name',
className: 'account_name',
width: 220,
},
@@ -145,7 +143,7 @@ function AccountsDataTable({
Header: formatMessage({ id: 'code' }),
accessor: 'code',
className: 'code',
width: 125,
width: 70,
},
{
id: 'type',
@@ -160,13 +158,13 @@ function AccountsDataTable({
Cell: NormalCell,
accessor: 'type.normal',
className: 'normal',
width: 115,
width: 65,
},
{
id: 'currency',
Header: formatMessage({ id: 'currency' }),
accessor: (row) => 'USD',
width: 100,
width: 75,
},
{
id: 'balance',

View File

@@ -38,6 +38,7 @@ function ReceivableAgingSummaryTable({
className: 'customer_name',
sticky: 'left',
width: 240,
textOverview: true,
},
{
Header: <T id={'current'} />,

View File

@@ -4,33 +4,12 @@ import classNames from 'classnames';
import FinancialSheet from 'components/FinancialSheet';
import DataTable from 'components/DataTable';
import { CellTextSpan } from 'components/Datatable/Cells';
import withBalanceSheetDetail from './withBalanceSheetDetail';
import { compose, defaultExpanderReducer, getColumnWidth } from 'utils';
// Total cell.
function TotalCell({ cell }) {
const row = cell.row.original;
if (row.total) {
return row.total.formatted_amount;
}
return '';
}
// Total period cell.
const TotalPeriodCell = (index) => ({ cell }) => {
const { original } = cell.row;
if (original.total_periods && original.total_periods[index]) {
const amount = original.total_periods[index].formatted_amount;
return amount;
}
return '';
};
/**
* Balance sheet table.
*/
@@ -52,14 +31,15 @@ function BalanceSheetTable({
Header: formatMessage({ id: 'account_name' }),
accessor: (row) => (row.code ? `${row.name} - ${row.code}` : row.name),
className: 'account_name',
textOverview: true,
width: 240,
},
...(balanceSheetQuery.display_columns_type === 'total'
? [
{
Header: formatMessage({ id: 'total' }),
accessor: 'balance.formatted_amount',
Cell: TotalCell,
accessor: 'total.formatted_amount',
Cell: CellTextSpan,
className: 'total',
width: 140,
},
@@ -69,8 +49,8 @@ function BalanceSheetTable({
? balanceSheetColumns.map((column, index) => ({
id: `date_period_${index}`,
Header: column,
accessor: `total_periods[${index}]`,
Cell: TotalPeriodCell(index),
Cell: CellTextSpan,
accessor: `total_periods[${index}].formatted_amount`,
className: classNames('total-period', `total-periods-${index}`),
width: getColumnWidth(
balanceSheetTableRows,
@@ -93,7 +73,7 @@ function BalanceSheetTable({
const { original } = row;
const rowTypes = Array.isArray(original.row_types)
? original.row_types
: [];
: [original.row_types];
return {
...rowTypes.reduce((acc, rowType) => {

View File

@@ -14,6 +14,8 @@ import { CLASSES } from 'common/classes';
import { Col, Row, ListSelect, MODIFIER } from 'components';
import { filterAccountsOptions } from './common';
export default function FinancialAccountsFilter({ ...restProps }) {
const SUBMENU_POPOVER_MODIFIERS = {
flip: { boundariesElement: 'viewport', padding: 20 },

View File

@@ -49,6 +49,7 @@ function GeneralLedger({
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
basis: 'accural',
accountsFilter: 'with-transactions',
});
// Change page title of the dashboard.

View File

@@ -1,16 +1,21 @@
import React from 'react';
import { FormGroup, Classes } from '@blueprintjs/core';
import {
FormGroup,
Classes,
} from '@blueprintjs/core';
import { FormattedMessage as T } from 'react-intl';
import classNames from 'classnames';
import { compose } from 'redux';
import { AccountsMultiSelect, Row, Col } from 'components';
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
import RadiosAccountingBasis from '../RadiosAccountingBasis';
import FinancialAccountsFilter from '../FinancialAccountsFilter';
import withAccounts from 'containers/Accounts/withAccounts';
import { compose } from 'redux';
import { filterAccountsOptions } from './common';
/**
* General ledger (GL) - Header - General panel.
@@ -22,7 +27,10 @@ function GeneralLedgerHeaderGeneralPane({
return (
<div>
<FinancialStatementDateRange />
<FinancialAccountsFilter
items={filterAccountsOptions}
initialSelectedItem={'all-accounts'}
/>
<Row>
<Col xs={4}>
<FormGroup

View File

@@ -8,6 +8,7 @@ import DataTable from 'components/DataTable';
import Money from 'components/Money';
import withGeneralLedger from './withGeneralLedger';
import { getForceWidth, getColumnWidth } from 'utils';
const ROW_TYPE = {
CLOSING_BALANCE: 'closing_balance',
@@ -25,91 +26,89 @@ function GeneralLedgerTable({
}) {
const { formatMessage } = useIntl();
// Account name column accessor.
const accountNameAccessor = (row) => {
switch (row.rowType) {
case ROW_TYPE.OPENING_BALANCE:
return 'Opening Balance';
case ROW_TYPE.CLOSING_BALANCE:
return 'Closing Balance';
default:
return row.name;
}
};
// Date accessor.
const dateAccessor = (row) => {
const TYPES = [
ROW_TYPE.OPENING_BALANCE,
ROW_TYPE.CLOSING_BALANCE,
ROW_TYPE.TRANSACTION,
];
return TYPES.indexOf(row.rowType) !== -1
? moment(row.date).format('DD MMM YYYY')
: '';
};
// Amount cell
const amountCell = useCallback(({ cell }) => {
const transaction = cell.row.original;
if (transaction.rowType === ROW_TYPE.ACCOUNT) {
return !cell.row.isExpanded ? (
<Money amount={transaction.closing.amount} currency={'USD'} />
) : (
''
);
}
return <Money amount={transaction.amount} currency={'USD'} />;
}, []);
const columns = useMemo(
() => [
{
Header: formatMessage({ id: 'account_name' }),
accessor: accountNameAccessor,
className: 'name',
width: 225,
Header: formatMessage({ id: 'date' }),
accessor: (row) => {
if (row.rowType === 'ACCOUNT_ROW') {
return (
<span
className={'force-width'}
style={{ minWidth: getForceWidth(row.date) }}
>
{row.date}
</span>
);
}
return row.date;
},
className: 'date',
width: 120,
},
{
Header: formatMessage({ id: 'date' }),
accessor: dateAccessor,
className: 'date',
width: 115,
Header: formatMessage({ id: 'account_name' }),
accessor: 'name',
className: 'name',
textOverview: true,
// width: 200,
},
{
Header: formatMessage({ id: 'transaction_type' }),
accessor: 'referenceType',
accessor: 'reference_type_formatted',
className: 'transaction_type',
width: 145,
width: 125 ,
},
{
Header: formatMessage({ id: 'trans_num' }),
Header: formatMessage({ id: 'transaction_number' }),
accessor: 'reference_id',
className: 'transaction_number',
width: 110,
width: 100,
},
{
Header: formatMessage({ id: 'description' }),
accessor: 'note',
className: 'description',
width: 145,
// width: 145,
},
{
Header: formatMessage({ id: 'credit' }),
accessor: 'formatted_credit',
className: 'credit',
width: getColumnWidth(generalLedgerTableRows, 'formatted_credit', {
minWidth: 100,
magicSpacing: 10,
}),
},
{
Header: formatMessage({ id: 'debit' }),
accessor: 'formatted_debit',
className: 'debit',
width: getColumnWidth(generalLedgerTableRows, 'formatted_debit', {
minWidth: 100,
magicSpacing: 10,
}),
},
{
Header: formatMessage({ id: 'amount' }),
Cell: amountCell,
accessor: 'formatted_amount',
className: 'amount',
width: 150,
width: getColumnWidth(generalLedgerTableRows, 'formatted_amount', {
minWidth: 100,
magicSpacing: 10,
}),
},
{
Header: formatMessage({ id: 'balance' }),
Cell: amountCell,
className: 'balance',
width: 150,
Header: formatMessage({ id: 'running_balance' }),
accessor: 'formatted_running_balance',
className: 'running_balance',
width: getColumnWidth(generalLedgerTableRows, 'formatted_running_balance', {
minWidth: 100,
magicSpacing: 10,
}),
},
],
[],
[formatMessage, generalLedgerTableRows],
);
// Default expanded rows of general ledger table.
@@ -140,7 +139,7 @@ function GeneralLedgerTable({
rowClassNames={rowClassNames}
expanded={expandedRows}
virtualizedRows={true}
fixedItemSize={37}
fixedItemSize={30}
fixedSizeHeight={1000}
expandable={true}
expandToggleColumn={1}

View File

@@ -0,0 +1,16 @@
import { formatMessage } from 'services/intl';
export const filterAccountsOptions = [
{
key: 'all-accounts',
name: formatMessage({ id: 'all_accounts' }),
hint: formatMessage({ id: 'all_accounts_including_with_zero_balance' }),
},
{
key: 'with-transactions',
name: formatMessage({ id: 'accounts_with_transactions' }),
hint: formatMessage({
id: 'include_accounts_once_has_transactions_on_given_date_period',
}),
},
];

View File

@@ -8,7 +8,7 @@ import Money from 'components/Money';
import withJournal from './withJournal';
import { compose, defaultExpanderReducer } from 'utils';
import { compose, defaultExpanderReducer, getForceWidth } from 'utils';
function JournalSheetTable({
// #withJournal
@@ -22,70 +22,52 @@ function JournalSheetTable({
}) {
const { formatMessage } = useIntl();
const rowTypeFilter = (rowType, value, types) => {
return types.indexOf(rowType) === -1 ? '' : value;
};
const exceptRowTypes = (rowType, value, types) => {
return types.indexOf(rowType) !== -1 ? '' : value;
};
const columns = useMemo(
() => [
{
Header: formatMessage({ id: 'date' }),
accessor: (r) =>
rowTypeFilter(r.rowType, moment(r.date).format('YYYY MMM DD'), [
'first_entry',
]),
accessor: row => row.date ? moment(row.date).format('YYYY MMM DD') : '',
className: 'date',
width: 85,
width: 100,
},
{
Header: formatMessage({ id: 'transaction_type' }),
accessor: (r) =>
rowTypeFilter(r.rowType, r.transaction_type, ['first_entry']),
accessor: 'reference_type_formatted',
className: 'reference_type_formatted',
width: 145,
width: 120,
},
{
Header: formatMessage({ id: 'num' }),
accessor: (r) =>
rowTypeFilter(r.rowType, r.reference_id, ['first_entry']),
accessor: 'reference_id',
className: 'reference_id',
width: 70,
},
{
Header: formatMessage({ id: 'description' }),
accessor: 'note',
className: 'note'
},
{
Header: formatMessage({ id: 'acc_code' }),
accessor: 'account.code',
accessor: 'account_code',
width: 95,
className: 'account_code',
},
{
Header: formatMessage({ id: 'account' }),
accessor: 'account.name',
accessor: 'account_name',
className: 'account_name',
textOverview: true,
},
{
Header: formatMessage({ id: 'credit' }),
accessor: (r) =>
exceptRowTypes(
r.rowType,
<Money amount={r.credit} currency={'USD'} />,
['space_entry'],
),
accessor: 'formatted_credit',
className: 'credit'
},
{
Header: formatMessage({ id: 'debit' }),
accessor: (r) =>
exceptRowTypes(
r.rowType,
<Money amount={r.debit} currency={'USD'} />,
['space_entry'],
),
accessor: 'formatted_debit',
className: 'debit'
},
],
[formatMessage],
@@ -101,6 +83,20 @@ function JournalSheetTable({
// Default expanded rows of general journal table.
const expandedRows = useMemo(() => defaultExpanderReducer([], 1), []);
const rowClassNames = useCallback((row) => {
const { original } = row;
const rowTypes = Array.isArray(original.rowType)
? original.rowType
: [original.rowType];
return {
...rowTypes.reduce((acc, rowType) => {
acc[`row_type--${rowType}`] = rowType;
return acc;
}, {}),
};
}, []);
return (
<FinancialSheet
companyName={companyName}
@@ -111,11 +107,12 @@ function JournalSheetTable({
loading={journalSheetLoading}
// minimal={true}
fullWidth={true}
>
>
<DataTable
className="bigcapital-datatable--financial-report"
columns={columns}
data={journalSheetTableRows}
rowClassNames={rowClassNames}
onFetchData={handleFetchData}
noResults={formatMessage({
id: 'this_report_does_not_contain_any_data_between_date_period',

View File

@@ -3,7 +3,7 @@ import { FormattedMessage as T, useIntl } from 'react-intl';
import FinancialSheet from 'components/FinancialSheet';
import DataTable from 'components/DataTable';
import Money from 'components/Money';
import { CellTextSpan } from 'components/Datatable/Cells';
import { compose, defaultExpanderReducer, getColumnWidth } from 'utils';
import withProfitLossDetail from './withProfitLoss';
@@ -26,12 +26,14 @@ function ProfitLossSheetTable({
Header: formatMessage({ id: 'account' }),
accessor: (row) => (row.code ? `${row.name} - ${row.code}` : row.name),
className: 'name',
textOverview: true,
width: 240,
},
...(profitLossQuery.display_columns_type === 'total'
? [
{
Header: formatMessage({ id: 'total' }),
Cell: CellTextSpan,
accessor: 'total.formatted_amount',
className: 'total',
width: 140,
@@ -42,6 +44,7 @@ function ProfitLossSheetTable({
? profitLossColumns.map((column, index) => ({
id: `date_period_${index}`,
Header: column,
Cell: CellTextSpan,
accessor: `total_periods[${index}].formatted_amount`,
width: getColumnWidth(
profitLossTableRows,

View File

@@ -3,7 +3,7 @@ import { useIntl } from 'react-intl';
import FinancialSheet from 'components/FinancialSheet';
import DataTable from 'components/DataTable';
import Money from 'components/Money';
import { CellTextSpan } from 'components/Datatable/Cells';
import withTrialBalance from './withTrialBalance';
@@ -28,9 +28,11 @@ function TrialBalanceSheetTable({
accessor: (row) => (row.code ? `${row.name} - ${row.code}` : row.name),
className: 'name',
width: 160,
textOverview: true,
},
{
Header: formatMessage({ id: 'credit' }),
Cell: CellTextSpan,
accessor: 'formatted_credit',
className: 'credit',
width: getColumnWidth(trialBalanceTableRows, `credit`, {
@@ -39,11 +41,13 @@ function TrialBalanceSheetTable({
},
{
Header: formatMessage({ id: 'debit' }),
Cell: CellTextSpan,
accessor: 'formatted_debit',
width: getColumnWidth(trialBalanceTableRows, `debit`, { minWidth: 95 }),
},
{
Header: formatMessage({ id: 'balance' }),
Cell: CellTextSpan,
accessor: 'formatted_balance',
className: 'balance',
width: getColumnWidth(trialBalanceTableRows, `balance`, {
@@ -56,7 +60,7 @@ function TrialBalanceSheetTable({
const rowClassNames = (row) => {
const { original } = row;
const rowTypes = Array.isArray(original.rowTypes) ? original.rowTypes : [];
const rowTypes = Array.isArray(original.rowType) ? original.rowType : [original.rowType];
return {
...rowTypes.reduce((acc, rowType) => {

View File

@@ -1,4 +1,4 @@
import { mapKeys, omit, snakeCase } from 'lodash';
import { omit } from 'lodash';
import { transformToCamelCase, flatObject } from 'utils';
import { formatMessage } from 'services/intl';

View File

@@ -974,4 +974,6 @@ export default {
specific_customers: 'Specific Customers',
all_customers: 'All Customers',
selected_customers: '{count} Selected Customers',
transaction_number: 'Transaction #',
running_balance: 'Running balance'
};

View File

@@ -1,14 +1,8 @@
import { omit } from 'lodash';
import { omit, chain } from 'lodash';
import moment from 'moment';
export const mapBalanceSheetToTableRows = (accounts) => {
return accounts.map((account) => {
const PRIMARY_SECTIONS = ['assets', 'liability', 'equity'];
const rowTypes = [
'total_row',
...(PRIMARY_SECTIONS.indexOf(account.section_type) !== -1
? ['total_assets']
: []),
];
return {
...account,
children: mapBalanceSheetToTableRows([
@@ -31,51 +25,79 @@ export const mapBalanceSheetToTableRows = (accounts) => {
};
export const journalToTableRowsMapper = (journal) => {
return journal.reduce((rows, journal) => {
journal.entries.forEach((entry, index) => {
rows.push({
...entry,
rowType: index === 0 ? 'first_entry' : 'entry',
});
});
rows.push({
credit: journal.credit,
debit: journal.debit,
rowType: 'entries_total',
});
rows.push({
rowType: 'space_entry',
});
return rows;
}, []);
const TYPES = {
ENTRY: 'ENTRY',
TOTAL_ENTRIES: 'TOTAL_ENTRIES',
EMPTY_ROW: 'EMPTY_ROW',
};
const entriesMapper = (transaction) => {
return transaction.entries.map((entry, index) => ({
...(index === 0
? {
date: transaction.date,
reference_type: transaction.reference_type,
reference_id: transaction.reference_id,
reference_type_formatted: transaction.reference_type_formatted,
}
: {}),
rowType: TYPES.ENTRY,
...entry,
}));
};
return chain(journal)
.map((transaction) => {
const entries = entriesMapper(transaction);
return [
...entries,
{
rowType: TYPES.TOTAL_ENTRIES,
currency_code: transaction.currency_code,
credit: transaction.credit,
debit: transaction.debit,
formatted_credit: transaction.formatted_credit,
formatted_debit: transaction.formatted_debit,
},
{
rowType: TYPES.EMPTY_ROW,
},
];
})
.flatten()
.value();
};
export const generalLedgerToTableRows = (accounts) => {
return accounts.reduce((tableRows, account) => {
const children = [];
children.push({
...account.opening,
rowType: 'opening_balance',
});
account.transactions.map((transaction) => {
children.push({
...transaction,
...omit(account, ['transactions']),
rowType: 'transaction',
});
});
children.push({
...account.closing,
rowType: 'closing_balance',
});
tableRows.push({
...omit(account, ['transactions']),
children,
rowType: 'account_name',
});
return tableRows;
}, []);
return chain(accounts)
.map((account) => {
return {
name: '',
code: account.code,
rowType: 'ACCOUNT_ROW',
date: account.name,
children: [
{
...account.opening_balance,
name: 'Opening balance',
rowType: 'OPENING_BALANCE',
},
...account.transactions.map((transaction) => ({
...transaction,
name: account.name,
code: account.code,
date: moment(transaction.date).format('DD MMM YYYY'),
})),
{
...account.closing_balance,
name: 'Closing balance',
rowType: 'CLOSING_BALANCE',
},
],
};
})
.value();
};
export const ARAgingSummaryTableRowsMapper = (sheet, total) => {
@@ -109,25 +131,32 @@ export const ARAgingSummaryTableRowsMapper = (sheet, total) => {
current: sheet.total.current.formatted_amount,
...mapAging(sheet.total.aging),
total: sheet.total.total.formatted_amount,
}
];
};
export const mapTrialBalanceSheetToRows = (sheet) => {
return [
...sheet.accounts,
{
name: 'Total',
rowTypes: ['total'],
...sheet.total,
},
];
};
export const profitLossToTableRowsMapper = (profitLoss) => {
export const mapTrialBalanceSheetToRows = (sheet) => {
const results = [];
return [
{
if (sheet.accounts) {
sheet.accounts.forEach((account) => {
results.push(account);
});
}
if (sheet.total) {
results.push({
rowType: 'total',
...sheet.total,
});
}
return results;
};
export const profitLossToTableRowsMapper = (profitLoss) => {
const results = [];
if (profitLoss.income) {
results.push({
name: 'Income',
total: profitLoss.income.total,
children: [
@@ -140,8 +169,10 @@ export const profitLossToTableRowsMapper = (profitLoss) => {
},
],
total_periods: profitLoss.income.total_periods,
},
{
});
}
if (profitLoss.cost_of_sales) {
results.push({
name: 'Cost of sales',
total: profitLoss.cost_of_sales.total,
children: [
@@ -153,15 +184,19 @@ export const profitLossToTableRowsMapper = (profitLoss) => {
rowTypes: ['cogs_total', 'section_total', 'total'],
},
],
total_periods: profitLoss.cost_of_sales.total_periods
},
{
total_periods: profitLoss.cost_of_sales.total_periods,
});
}
if (profitLoss.gross_profit) {
results.push({
name: 'Gross profit',
total: profitLoss.gross_profit.total,
total_periods: profitLoss.gross_profit.total_periods,
rowTypes: ['gross_total', 'section_total', 'total'],
},
{
})
}
if (profitLoss.expenses) {
results.push({
name: 'Expenses',
total: profitLoss.expenses.total,
children: [
@@ -174,14 +209,34 @@ export const profitLossToTableRowsMapper = (profitLoss) => {
},
],
total_periods: profitLoss.expenses.total_periods,
},
{
})
}
if (profitLoss.operating_profit) {
results.push({
name: 'Net Operating income',
total: profitLoss.operating_profit.total,
total_periods: profitLoss.income.total_periods,
rowTypes: ['net_operating_total', 'section_total', 'total'],
},
{
})
}
if (profitLoss.other_income) {
results.push({
name: 'Other Income',
total: profitLoss.other_income.total,
total_periods: profitLoss.other_income.total_periods,
children: [
...profitLoss.other_income.accounts,
{
name: 'Total other income',
total: profitLoss.other_income.total,
total_periods: profitLoss.other_income.total_periods,
rowTypes: ['expenses_total', 'section_total', 'total'],
},
],
});
}
if (profitLoss.other_expenses) {
results.push({
name: 'Other expenses',
total: profitLoss.other_expenses.total,
total_periods: profitLoss.other_expenses.total_periods,
@@ -194,12 +249,15 @@ export const profitLossToTableRowsMapper = (profitLoss) => {
rowTypes: ['expenses_total', 'section_total', 'total'],
},
],
},
{
});
}
if (profitLoss.net_income) {
results.push({
name: 'Net Income',
total: profitLoss.net_income.total,
total_periods: profitLoss.net_income.total_periods,
rowTypes: ['net_income_total', 'section_total', 'total'],
},
];
};
})
};
return results;
};

View File

@@ -27,6 +27,12 @@
color: #58667b;
font-weight: 500;
border-bottom: 1px solid rgb(224, 224, 224);
> div{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.sort-icon {
width: 0;
@@ -141,10 +147,23 @@
.placeholder {
color: #a0a0a0;
}
.text-overview{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.bp3-form-group {
width: 100%;
}
&.is-text-overview {
.expend-padding{
display: flex;
width: 100%;
}
}
}
.tr:hover .td {
background: #f3f7fc;

View File

@@ -60,12 +60,17 @@
display: none;
}
}
&__basis {
&__footer {
color: #888;
text-align: center;
margin-top: auto;
padding-top: 18px;
font-size: 13px;
> span + span{
padding-left: 10px;
}
}
.dashboard__loading-indicator {
margin: auto;

View File

@@ -13,20 +13,22 @@
}
}
.tbody{
.tr .td{
border-bottom: 0;
padding-top: 0.4rem;
padding-bottom: 0.4rem;
}
.tr:not(:first-child) .td{
border-top: 1px solid transparent;
}
.tr.row-type--total{
font-weight: 500;
.tr:not(.no-results) {
.td{
border-top: 1px solid #333;
border-bottom: 3px double #333;
border-bottom: 0;
padding-top: 0.4rem;
padding-bottom: 0.4rem;
}
&.row-type--total{
font-weight: 500;
.td{
border-top: 1px solid #333;
border-bottom: 3px double #333;
}
}
&:not(:first-child) .td{
border-top: 1px solid transparent;
}
}
}

View File

@@ -36,7 +36,7 @@
.tr.is-expanded{
.td.total,
.td.total-period{
> span{
> span.cell-text{
display: none;
}
}

View File

@@ -3,9 +3,17 @@
&--financial-report{
.table {
.tbody{
.tr.no-results {
.td{
border-bottom: 1px solid #DDD;
}
}
}
.thead{
.tr .th{
background: transparent;
background-color: #fff;
border-top: 1px solid #666;
border-bottom: 1px solid #666;

View File

@@ -2,25 +2,64 @@
.financial-sheet{
&--general-ledger{
.financial-sheet__table{
.tbody,
.thead{
.tr .td,
.tr .th{
&.credit,
&.debit,
&.running_balance,
&.amount{
justify-content: flex-end;
}
}
}
.tbody{
.tr .td{
padding-top: 0.2rem;
padding-bottom: 0.2rem;
border-top-color: transparent;
border-bottom-color: transparent;
&.date{
> div{
display: flex;
}
span.force-width{
position: relative;
}
}
}
.tr:not(.no-results) .td{
border-left: 1px solid #ececec;
}
.tr.row-type{
&--opening_balance,
&--closing_balance{
&--ACCOUNT_ROW{
.td{
border-top: 1px solid #333;
&.date{
font-weight: 500;
}
&.name{
border-left-color: transparent;
}
}
.name,
.amount,
.balance{
&:not(:first-child).is-expanded .td{
border-top: 1px solid #DDD;
}
}
&--OPENING_BALANCE,
&--CLOSING_BALANCE{
.amount{
font-weight: 500;
}
}
&--closing_balance .td{
border-bottom-color: #666;
}
&--account_name .td.name{
font-weight: 500;
&--CLOSING_BALANCE{
.name{
font-weight: 500;
}
}
}
}

View File

@@ -3,19 +3,39 @@
&--journal{
.financial-sheet__table{
.tr .td.credit,
.tr .th.credit,
.tr .td.debit,
.tr .th.debit{
justify-content: flex-end;
}
.tbody{
.tr:not(.no-results) .td{
padding: 0.4rem;
padding: 0.3rem 0.4rem;
color: #000;
border-bottom-color: transparent;
min-height: 32px;
min-height: 28px;
border-left: 1px solid #ececec;
&:first-of-type{
border-left: 0;
}
&.account_name,
&.reference_type_formatted{
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
}
.tr:not(.no-results):last-child{
.td{
border-bottom: 1px solid #dbdbdb;
}
}
.tr.row_type--TOTAL_ENTRIES{
font-weight: 600;
}
}
}
}

View File

@@ -389,6 +389,16 @@ export const getColumnWidth = (
return result;
};
export const getForceWidth = (
text,
magicSpacing = 14,
) => {
const textLength = text.length;
const result = textLength * magicSpacing
return result;
}
export const toSafeNumber = (number) => {
return _.toNumber(_.defaultTo(number, 0));
};