mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat: Financial statements enhancement.
This commit is contained in:
@@ -121,6 +121,17 @@ function ExpenseDataTable({
|
||||
[handleEditExpense, handleDeleteExpense, handlePublishExpense],
|
||||
);
|
||||
|
||||
const expenseAccountAccessor = (expense) => {
|
||||
if (expense.categories.length === 1) {
|
||||
return expense.categories[0].expense_account.name;
|
||||
} else if (expense.categories.length > 1) {
|
||||
const mutliCategories = expense.categories.map(category =>
|
||||
(<div>- {category.expense_account.name} ${ category.amount }</div>)
|
||||
);
|
||||
return <Tooltip content={mutliCategories}>{ '- Multi Categories -' }</Tooltip>;
|
||||
}
|
||||
}
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -155,11 +166,10 @@ function ExpenseDataTable({
|
||||
{
|
||||
id: 'expense_account_id',
|
||||
Header: formatMessage({ id: 'expense_account' }),
|
||||
accessor:'expense_account_id',
|
||||
accessor: expenseAccountAccessor,
|
||||
width: 150,
|
||||
className: 'expense_account',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'publish',
|
||||
Header: formatMessage({ id: 'publish' }),
|
||||
|
||||
@@ -12,10 +12,11 @@ import { Intent, FormGroup, TextArea } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { pick } from 'lodash';
|
||||
import { useQuery } from 'react-query';
|
||||
import { Col, Row } from 'react-grid-system';
|
||||
|
||||
import ExpenseFormHeader from './ExpenseFormHeader';
|
||||
import ExpenseTable from './ExpenseTable';
|
||||
import ExpenseFooter from './ExpenseFooter';
|
||||
import ExpenseFloatingFooter from './ExpenseFooter';
|
||||
|
||||
import withExpensesActions from 'containers/Expenses/withExpensesActions';
|
||||
import withExpneseDetail from 'containers/Expenses/withExpenseDetail';
|
||||
@@ -76,11 +77,11 @@ function ExpenseForm({
|
||||
useEffect(() => {
|
||||
if (expenseDetail && expenseDetail.id) {
|
||||
changePageTitle(formatMessage({ id: 'edit_expense' }));
|
||||
changePageSubtitle(`No. ${expenseDetail.payment_account_id}`);
|
||||
// changePageSubtitle(`No. ${expenseDetail.payment_account_id}`);
|
||||
} else {
|
||||
changePageTitle(formatMessage({ id: 'new_expense' }));
|
||||
}
|
||||
// @todo not functions just states.
|
||||
// @todo not functions just states.
|
||||
}, [changePageTitle, changePageSubtitle, expenseDetail, formatMessage]);
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
@@ -137,7 +138,6 @@ function ExpenseForm({
|
||||
reference_no: '',
|
||||
currency_code: '',
|
||||
categories: [
|
||||
// @todo @mohamed index
|
||||
defaultCategory,
|
||||
defaultCategory,
|
||||
defaultCategory,
|
||||
@@ -154,7 +154,8 @@ function ExpenseForm({
|
||||
...pick(expenseDetail, Object.keys(defaultInitialValues)),
|
||||
categories: expenseDetail.categories.map((category) => ({
|
||||
...pick(category, Object.keys(defaultCategory)),
|
||||
})),
|
||||
}),
|
||||
),
|
||||
}
|
||||
: {
|
||||
...defaultInitialValues,
|
||||
@@ -257,7 +258,7 @@ function ExpenseForm({
|
||||
},
|
||||
});
|
||||
|
||||
console.log(formik.errors);
|
||||
console.log(formik.values, 'VALUES');
|
||||
|
||||
const handleSubmitClick = useCallback(
|
||||
(payload) => {
|
||||
@@ -298,29 +299,32 @@ function ExpenseForm({
|
||||
defaultRow={defaultCategory}
|
||||
/>
|
||||
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
{...formik.getFieldProps('description')}
|
||||
/>
|
||||
</FormGroup>
|
||||
<div class="expense-form-footer">
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
{...formik.getFieldProps('description')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<ExpenseFooter
|
||||
<Dragzone
|
||||
initialFiles={initialAttachmentFiles}
|
||||
onDrop={handleDropFiles}
|
||||
onDeleteFile={handleDeleteFile}
|
||||
hint={'Attachments: Maxiumum size: 20MB'}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<ExpenseFloatingFooter
|
||||
formik={formik}
|
||||
onSubmitClick={handleSubmitClick}
|
||||
onCancelClick={handleCancelClick}
|
||||
/>
|
||||
</form>
|
||||
<Dragzone
|
||||
initialFiles={initialAttachmentFiles}
|
||||
onDrop={handleDropFiles}
|
||||
onDeleteFile={handleDeleteFile}
|
||||
hint={'Attachments: Maxiumum size: 20MB'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ function ExpenseFormHeader({
|
||||
return (
|
||||
<div className={'dashboard__insider--expense-form__header'}>
|
||||
<Row>
|
||||
<Col sm={3.5}>
|
||||
<Col width={300}>
|
||||
<FormGroup
|
||||
label={<T id={'beneficiary'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
@@ -141,7 +141,8 @@ function ExpenseFormHeader({
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<Col sm={3}>
|
||||
|
||||
<Col width={400}>
|
||||
<FormGroup
|
||||
label={<T id={'payment_account'} />}
|
||||
className={classNames(
|
||||
@@ -177,8 +178,9 @@ function ExpenseFormHeader({
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<Col sm={3.5}>
|
||||
<Col width={300}>
|
||||
<FormGroup
|
||||
label={<T id={'payment_date'} />}
|
||||
labelInfo={infoIcon}
|
||||
@@ -189,17 +191,17 @@ function ExpenseFormHeader({
|
||||
helperText={
|
||||
<ErrorMessage name="payment_date" {...{ errors, touched }} />
|
||||
}
|
||||
minimal={true}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
defaultValue={new Date()}
|
||||
onChange={handleDateChange}
|
||||
popoverProps={{ position: Position.BOTTOM }}
|
||||
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<Col sm={2}>
|
||||
|
||||
<Col width={200}>
|
||||
<FormGroup
|
||||
label={<T id={'currency'} />}
|
||||
className={classNames(
|
||||
@@ -223,23 +225,25 @@ function ExpenseFormHeader({
|
||||
onItemSelect={onItemsSelect('currency_code')}
|
||||
selectedItem={values.currency_code}
|
||||
selectedItemProp={'currency_code'}
|
||||
defaultText={<T id={'select_currency_code'} />}
|
||||
defaultText={<T id={'select_currency'} />}
|
||||
labelProp={'currency_code'}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col sm={3}>
|
||||
<Col width={200}>
|
||||
<FormGroup
|
||||
label={<T id={'ref_no'} />}
|
||||
className={'form-group--ref_no'}
|
||||
className={classNames(
|
||||
'form-group--ref_no',
|
||||
Classes.FILL,
|
||||
)}
|
||||
intent={
|
||||
errors.reference_no && touched.reference_no && Intent.DANGER
|
||||
}
|
||||
helperText={
|
||||
<ErrorMessage name="reference_no" {...{ errors, touched }} />
|
||||
}
|
||||
minimal={true}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { useState, useMemo, useEffect, useCallback } from 'react';
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
import { Button, Intent, Position, Tooltip } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
|
||||
import DataTable from 'components/DataTable';
|
||||
import Icon from 'components/Icon';
|
||||
import { Hint } from 'components';
|
||||
import { compose, formattedAmount } from 'utils';
|
||||
import {
|
||||
AccountsListFieldCell,
|
||||
@@ -88,14 +89,16 @@ function ExpenseTable({
|
||||
payload.removeRow(index);
|
||||
};
|
||||
return (
|
||||
<Button
|
||||
icon={<Icon icon="times-circle" iconSize={14} />}
|
||||
iconSize={14}
|
||||
className="ml2"
|
||||
minimal={true}
|
||||
intent={Intent.DANGER}
|
||||
onClick={onClickRemoveRole}
|
||||
/>
|
||||
<Tooltip content={<T id={'remove_the_line'} />} position={Position.LEFT}>
|
||||
<Button
|
||||
icon={<Icon icon="times-circle" iconSize={14} />}
|
||||
iconSize={14}
|
||||
className="ml2"
|
||||
minimal={true}
|
||||
intent={Intent.DANGER}
|
||||
onClick={onClickRemoveRole}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -144,8 +147,7 @@ function ExpenseTable({
|
||||
disableSortBy: true,
|
||||
},
|
||||
{
|
||||
// @todo Add hint component after the header label.
|
||||
Header: formatMessage({ id: 'expense_category' }),
|
||||
Header: (<>{ formatMessage({ id: 'expense_category' }) }<Hint /></>),
|
||||
id: 'expense_account_id',
|
||||
accessor: 'expense_account_id',
|
||||
Cell: TotalExpenseCellRenderer(AccountsListFieldCell),
|
||||
@@ -161,6 +163,7 @@ function ExpenseTable({
|
||||
disableSortBy: true,
|
||||
disableResizing: true,
|
||||
width: 150,
|
||||
className: 'amount',
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'description' }),
|
||||
@@ -195,7 +198,6 @@ function ExpenseTable({
|
||||
[rows],
|
||||
);
|
||||
|
||||
|
||||
return (
|
||||
<div className={'dashboard__insider--expense-form__table'}>
|
||||
<DataTable
|
||||
@@ -235,5 +237,4 @@ export default compose(
|
||||
withAccounts(({ accounts }) => ({
|
||||
accounts,
|
||||
})),
|
||||
|
||||
)(ExpenseTable);
|
||||
|
||||
@@ -12,6 +12,7 @@ import ExpenseDataTable from 'containers/Expenses/ExpenseDataTable';
|
||||
import ExpenseActionsBar from 'containers/Expenses/ExpenseActionsBar';
|
||||
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withExpenses from 'containers/Expenses/withExpenses';
|
||||
import withExpensesActions from 'containers/Expenses/withExpensesActions';
|
||||
import withViewsActions from 'containers/Views/withViewsActions';
|
||||
|
||||
@@ -24,6 +25,9 @@ function ExpensesList({
|
||||
// #withViewsActions
|
||||
requestFetchResourceViews,
|
||||
|
||||
// #withExpenses
|
||||
expensesTableQuery,
|
||||
|
||||
//#withExpensesActions
|
||||
requestFetchExpensesTable,
|
||||
requestDeleteExpense,
|
||||
@@ -44,8 +48,9 @@ function ExpensesList({
|
||||
return requestFetchResourceViews('expenses');
|
||||
});
|
||||
|
||||
const fetchExpenses = useQuery('expenses-table', () =>
|
||||
requestFetchExpensesTable(),
|
||||
const fetchExpenses = useQuery(
|
||||
['expenses-table', expensesTableQuery],
|
||||
() => requestFetchExpensesTable(),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -53,7 +58,6 @@ function ExpensesList({
|
||||
}, [changePageTitle, formatMessage]);
|
||||
|
||||
// Handle delete expense click.
|
||||
|
||||
const handleDeleteExpense = useCallback(
|
||||
(expnese) => {
|
||||
setDeleteExpense(expnese);
|
||||
@@ -108,8 +112,6 @@ function ExpensesList({
|
||||
.catch((error) => {
|
||||
setBulkDelete(false);
|
||||
});
|
||||
|
||||
// @todo
|
||||
}, [requestDeleteBulkExpenses, bulkDelete, formatMessage, selectedRowsCount]);
|
||||
|
||||
// Handle cancel bulk delete alert.
|
||||
@@ -149,6 +151,7 @@ function ExpensesList({
|
||||
message: formatMessage({ id: 'the_expense_id_has_been_published' }),
|
||||
});
|
||||
});
|
||||
fetchExpenses.refetch();
|
||||
},
|
||||
[requestPublishExpense, formatMessage],
|
||||
);
|
||||
@@ -163,7 +166,7 @@ function ExpensesList({
|
||||
|
||||
return (
|
||||
<DashboardInsider
|
||||
loading={fetchViews.isFetching || fetchExpenses.isFetching}
|
||||
loading={fetchViews.isFetching}
|
||||
name={'expenses'}
|
||||
>
|
||||
<ExpenseActionsBar
|
||||
@@ -232,5 +235,6 @@ function ExpensesList({
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withExpensesActions,
|
||||
withExpenses(({ expensesTableQuery }) => ({ expensesTableQuery })),
|
||||
withViewsActions,
|
||||
)(ExpensesList);
|
||||
|
||||
Reference in New Issue
Block a user