fix: numeric values formating.

This commit is contained in:
a.bouhuolia
2021-09-14 15:28:02 +02:00
parent 40ff1464c8
commit e1a2fa57db
50 changed files with 492 additions and 420 deletions

View File

@@ -88,6 +88,7 @@ const CLASSES = {
...Classes, ...Classes,
CARD: 'card', CARD: 'card',
ALIGN_RIGHT: 'align-right',
}; };
export { export {

View File

@@ -59,6 +59,7 @@ export default function TableCell({ cell, row, index }) {
className: classNames(cell.column.className, 'td', { className: classNames(cell.column.className, 'td', {
'is-text-overview': cell.column.textOverview, 'is-text-overview': cell.column.textOverview,
'clickable': cell.column.clickable, 'clickable': cell.column.clickable,
'align-right': cell.column.align === 'right',
}), }),
onClick: handleCellClick, onClick: handleCellClick,
})} })}

View File

@@ -14,7 +14,9 @@ function TableHeaderCell({ column, index }) {
return ( return (
<div <div
{...column.getHeaderProps({ {...column.getHeaderProps({
className: classNames(column.className || '', 'th'), className: classNames(column.className || '', 'th', {
'align-right': column.align === 'right',
}),
})} })}
> >
<If condition={expandable && index + 1 === expandToggleColumn}> <If condition={expandable && index + 1 === expandToggleColumn}>
@@ -32,7 +34,7 @@ function TableHeaderCell({ column, index }) {
{...column.getSortByToggleProps({ {...column.getSortByToggleProps({
className: classNames('cell-inner', { className: classNames('cell-inner', {
'text-overview': column.textOverview, 'text-overview': column.textOverview,
}) }),
})} })}
> >
{column.render('Header')} {column.render('Header')}

View File

@@ -0,0 +1,10 @@
import React from 'react';
import { formattedAmount } from 'utils';
export function FormatNumber({ value, currency = '', noZero }) {
return formattedAmount(value, currency, { noZero });
}
export function FormatNumberCell({ value, column: { formatNumber } }) {
return <FormatNumber value={value} {...formatNumber} />;
}

View File

@@ -0,0 +1,3 @@
export * from './FormatNumber';

View File

@@ -78,6 +78,8 @@ export * from './Dashboard';
export * from './Drawer'; export * from './Drawer';
export * from './Forms'; export * from './Forms';
export * from './MultiSelectTaggable' export * from './MultiSelectTaggable'
export * from './Utils/FormatNumber';
const Hint = FieldHint; const Hint = FieldHint;
const T = FormattedMessage; const T = FormattedMessage;

View File

@@ -1,12 +1,7 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import moment from 'moment'; import moment from 'moment';
import { import { NoteAccessor, StatusAccessor, DateAccessor } from './components';
NoteAccessor,
StatusAccessor,
DateAccessor,
AmountAccessor,
} from './components';
/** /**
* Retrieve the manual journals columns. * Retrieve the manual journals columns.
@@ -29,6 +24,7 @@ export const useManualJournalsColumns = () => {
className: 'amount', className: 'amount',
width: 115, width: 115,
clickable: true, clickable: true,
align: 'right',
}, },
{ {
id: 'journal_number', id: 'journal_number',

View File

@@ -1,7 +1,10 @@
import React from 'react'; import React from 'react';
import { Intent, Tag } from '@blueprintjs/core'; import { Intent, Tag } from '@blueprintjs/core';
import { If, AppToaster } from 'components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import clsx from 'classnames';
import { CLASSES } from '../../common/classes';
import { If, AppToaster } from 'components';
import { NormalCell, BalanceCell } from './components'; import { NormalCell, BalanceCell } from './components';
import { transformTableStateToQuery, isBlank } from 'utils'; import { transformTableStateToQuery, isBlank } from 'utils';
@@ -99,6 +102,7 @@ export const useAccountsTableColumns = () => {
Cell: BalanceCell, Cell: BalanceCell,
width: 150, width: 150,
clickable: true, clickable: true,
align: 'right',
}, },
], ],
[], [],

View File

@@ -1,18 +1,18 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import { import {
Button,
Popover,
Menu, Menu,
MenuItem, MenuItem,
MenuDivider, MenuDivider,
Position,
Intent, Intent,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { Icon, Money, If } from 'components'; import clsx from 'classnames';
import { safeCallback } from 'utils';
import { firstLettersArgs } from 'utils';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { CLASSES } from '../../../common/classes';
import { Icon, Money, If } from 'components';
import { } from 'utils';
import { safeCallback, firstLettersArgs } from 'utils';
/** /**
* Actions menu. * Actions menu.
*/ */
@@ -134,7 +134,7 @@ export function useCustomersTableColumns() {
id: 'balance', id: 'balance',
Header: intl.get('receivable_balance'), Header: intl.get('receivable_balance'),
accessor: BalanceAccessor, accessor: BalanceAccessor,
className: 'receivable_balance', align: 'right',
width: 100, width: 100,
clickable: true, clickable: true,
}, },

View File

@@ -17,7 +17,6 @@ export default function AccountDrawerDetails() {
<Card className={'card-header'}> <Card className={'card-header'}>
<AccountDrawerHeader /> <AccountDrawerHeader />
</Card> </Card>
<AccountDrawerTable /> <AccountDrawerTable />
</div> </div>
); );

View File

@@ -2,7 +2,6 @@ import intl from 'react-intl-universal';
import React from 'react'; import React from 'react';
import moment from 'moment'; import moment from 'moment';
import { Money } from 'components';
import { isBlank } from 'utils'; import { isBlank } from 'utils';
/** /**
@@ -35,29 +34,40 @@ export const useAccountReadEntriesColumns = () =>
Header: intl.get('transaction_date'), Header: intl.get('transaction_date'),
accessor: ({ date }) => moment(date).format('YYYY MMM DD'), accessor: ({ date }) => moment(date).format('YYYY MMM DD'),
width: 110, width: 110,
textOverview: true,
}, },
{ {
Header: intl.get('transaction_type'), Header: intl.get('transaction_type'),
accessor: 'reference_type_formatted', accessor: 'reference_type_formatted',
width: 100, width: 100,
textOverview: true,
}, },
{ {
Header: intl.get('credit'), Header: intl.get('credit'),
accessor: 'credit', accessor: 'credit',
Cell: DebitCreditTableCell, Cell: DebitCreditTableCell,
width: 80, width: 80,
className: 'credit',
align: 'right',
textOverview: true,
}, },
{ {
Header: intl.get('debit'), Header: intl.get('debit'),
accessor: 'debit', accessor: 'debit',
Cell: DebitCreditTableCell, Cell: DebitCreditTableCell,
width: 80, width: 80,
className: 'debit',
align: 'right',
textOverview: true,
}, },
{ {
Header: intl.get('running_balance'), Header: intl.get('running_balance'),
Cell: RunningBalanceTableCell, Cell: RunningBalanceTableCell,
accessor: 'running_balance', accessor: 'running_balance',
width: 110, width: 110,
className: 'running_balance',
align: 'right',
textOverview: true,
}, },
], ],
[], [],

View File

@@ -1,10 +1,14 @@
import React from 'react'; import React from 'react';
import clsx from 'classnames'; import clsx from 'classnames';
import { T, TotalLines, TotalLine } from 'components'; import { FormatNumber, T, TotalLines, TotalLine } from '../../../components';
import BillDrawerCls from 'style/components/Drawers/BillDrawer.module.scss';
import { useBillDrawerContext } from './BillDrawerProvider'; import { useBillDrawerContext } from './BillDrawerProvider';
import BillDrawerCls from 'style/components/Drawers/BillDrawer.module.scss';
/**
* Bill read-only details footer.
*/
export function BillDetailFooter() { export function BillDetailFooter() {
const { bill } = useBillDrawerContext(); const { bill } = useBillDrawerContext();
@@ -13,17 +17,17 @@ export function BillDetailFooter() {
<TotalLines> <TotalLines>
<TotalLine <TotalLine
title={<T id={'bill.details.subtotal'} />} title={<T id={'bill.details.subtotal'} />}
value={bill.amount} value={<FormatNumber value={bill.amount} />}
className={BillDrawerCls.total_line_subtotal} className={BillDrawerCls.total_line_subtotal}
/> />
<TotalLine <TotalLine
title={<T id={'bill.details.total'} />} title={<T id={'bill.details.total'} />}
value={bill.amount} value={bill.formatted_amount}
className={BillDrawerCls.total_line_total} className={BillDrawerCls.total_line_total}
/> />
<TotalLine <TotalLine
title={<T id={'bill.details.payment_amount'} />} title={<T id={'bill.details.payment_amount'} />}
value={bill.payment_amount} value={bill.formatted_payment_amount}
className={BillDrawerCls.total_line_payment} className={BillDrawerCls.total_line_payment}
/> />
<TotalLine <TotalLine

View File

@@ -1,6 +1,11 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
/**
* Retrieve bill readonly details entries table columns.
*/
export const useBillReadonlyEntriesTableColumns = () => export const useBillReadonlyEntriesTableColumns = () =>
React.useMemo( React.useMemo(
() => [ () => [
@@ -20,22 +25,25 @@ React.useMemo(
{ {
Header: intl.get('quantity'), Header: intl.get('quantity'),
accessor: 'quantity', accessor: 'quantity',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'quantity', align: 'right',
disableSortBy: true disableSortBy: true
}, },
{ {
Header: intl.get('rate'), Header: intl.get('rate'),
accessor: 'rate', accessor: 'rate',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'rate', align: 'right',
disableSortBy: true disableSortBy: true
}, },
{ {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: 'amount', accessor: 'amount',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'amount', align: 'right',
disableSortBy: true disableSortBy: true
}, },
], ],

View File

@@ -2,6 +2,8 @@ import React from 'react';
import clsx from 'classnames'; import clsx from 'classnames';
import { T, TotalLines, TotalLine, If } from 'components'; import { T, TotalLines, TotalLine, If } from 'components';
import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider';
import { FormatNumber } from '../../../components';
import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.scss'; import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.scss';
@@ -9,29 +11,21 @@ import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.
* Estimate details panel footer content. * Estimate details panel footer content.
*/ */
export default function EstimateDetailFooter() { export default function EstimateDetailFooter() {
const { estimate } = useEstimateDetailDrawerContext();
return ( return (
<div className={clsx(EstimateDetailsCls.detail_panel_footer)}> <div className={clsx(EstimateDetailsCls.detail_panel_footer)}>
<TotalLines className={clsx(EstimateDetailsCls.total_lines)}> <TotalLines className={clsx(EstimateDetailsCls.total_lines)}>
<TotalLine <TotalLine
title={<T id={'estimate.details.subtotal'} />} title={<T id={'estimate.details.subtotal'} />}
value={'1000'} value={<FormatNumber value={estimate.amount} />}
className={EstimateDetailsCls.total_line_subtotal} className={EstimateDetailsCls.total_line_subtotal}
/> />
<TotalLine <TotalLine
title={<T id={'estimate.details.total'} />} title={<T id={'estimate.details.total'} />}
value={'1000'} value={estimate.formatted_amount}
className={EstimateDetailsCls.total_line_total} className={EstimateDetailsCls.total_line_total}
/> />
<TotalLine
title={<T id={'estimate.details.payment_made'} />}
value={'1000'}
className={EstimateDetailsCls.total_line_payment}
/>
<TotalLine
title={<T id={'estimate.details.due_amount'} />}
value={'1000'}
className={EstimateDetailsCls.total_line_dueAmount}
/>
</TotalLines> </TotalLines>
<If condition={false}> <If condition={false}>

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
/** /**
* Retrieve table columns of estimate readonly entries details. * Retrieve table columns of estimate readonly entries details.
@@ -22,22 +23,25 @@ export const useEstimateReadonlyEntriesColumns = () =>
{ {
Header: intl.get('quantity'), Header: intl.get('quantity'),
accessor: 'quantity', accessor: 'quantity',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'quantity', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Header: intl.get('rate'), Header: intl.get('rate'),
accessor: 'rate', accessor: 'rate',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'rate', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: 'amount', accessor: 'amount',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'amount', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
], []); ], []);

View File

@@ -2,19 +2,30 @@ import React from 'react';
import { T } from 'components'; import { T } from 'components';
import { useExpenseDrawerContext } from './ExpenseDrawerProvider'; import { useExpenseDrawerContext } from './ExpenseDrawerProvider';
import { FormatNumber } from '../../../components';
/**
* Footer details of expense readonly details.
*/
export default function ExpenseDrawerFooter() { export default function ExpenseDrawerFooter() {
const { expense: { total_amount } } = useExpenseDrawerContext(); const { expense } = useExpenseDrawerContext();
return ( return (
<div className="expense-drawer__content-footer"> <div className="expense-drawer__content-footer">
<div class="total-lines"> <div class="total-lines">
<div class="total-lines__line total-lines__line--subtotal"> <div class="total-lines__line total-lines__line--subtotal">
<div class="title"><T id={'expense.details.subtotal'} /></div> <div class="title">
<div class="amount">{total_amount}</div> <T id={'expense.details.subtotal'} />
</div>
<div class="amount">
{<FormatNumber value={expense.total_amount} />}
</div>
</div> </div>
<div class="total-lines__line total-lines__line--total"> <div class="total-lines__line total-lines__line--total">
<div class="title"><T id={'expense.details.total'} /></div> <div class="title">
<div class="amount">{total_amount}</div> <T id={'expense.details.total'} />
</div>
<div class="amount">{expense.formatted_amount}</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,6 +1,11 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
/**
* Retrieve expense readonly details entries table columns.
*/
export const useExpenseReadEntriesColumns = () => export const useExpenseReadEntriesColumns = () =>
React.useMemo( React.useMemo(
() => [ () => [
@@ -9,18 +14,23 @@ export const useExpenseReadEntriesColumns = () =>
accessor: 'expense_account.name', accessor: 'expense_account.name',
width: 110, width: 110,
disableSortBy: true, disableSortBy: true,
className: 'account',
}, },
{ {
Header: intl.get('description'), Header: intl.get('description'),
accessor: 'description', accessor: 'description',
width: 110, width: 110,
disableSortBy: true, disableSortBy: true,
className: 'description',
}, },
{ {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: 'amount', accessor: 'amount',
Cell: FormatNumberCell,
width: 100, width: 100,
disableSortBy: true, disableSortBy: true,
className: 'amount',
align: 'right',
}, },
], ],
[], [],

View File

@@ -15,21 +15,21 @@ export const useInventoryAdjustmentEntriesColumns = () =>
Header: intl.get('quantity'), Header: intl.get('quantity'),
accessor: 'quantity', accessor: 'quantity',
width: 100, width: 100,
className: 'quantity', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Header: intl.get('cost'), Header: intl.get('cost'),
accessor: 'cost', accessor: 'cost',
width: 100, width: 100,
className: 'cost', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Header: intl.get('value'), Header: intl.get('value'),
accessor: 'value', accessor: 'value',
width: 100, width: 100,
className: 'value', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
], ],

View File

@@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import clsx from 'classnames'; import clsx from 'classnames';
import { T, TotalLines, TotalLine } from 'components'; import { T, TotalLines, FormatNumber, TotalLine } from 'components';
import InvoiceDrawerCls from 'style/components/Drawers/InvoiceDrawer.module.scss'; import InvoiceDrawerCls from 'style/components/Drawers/InvoiceDrawer.module.scss';
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider'; import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
/** /**
* * Invoice details footer.
*/ */
export function InvoiceDetailFooter() { export function InvoiceDetailFooter() {
const { invoice } = useInvoiceDetailDrawerContext(); const { invoice } = useInvoiceDetailDrawerContext();
@@ -16,22 +16,22 @@ export function InvoiceDetailFooter() {
<TotalLines> <TotalLines>
<TotalLine <TotalLine
title={<T id={'invoice.details.subtotal'} />} title={<T id={'invoice.details.subtotal'} />}
value={invoice.balance} value={<FormatNumber value={invoice.balance} />}
className={InvoiceDrawerCls.total_line_subtotal} className={InvoiceDrawerCls.total_line_subtotal}
/> />
<TotalLine <TotalLine
title={<T id={'invoice.details.total'} />} title={<T id={'invoice.details.total'} />}
value={invoice.balance} value={invoice.formatted_amount}
className={InvoiceDrawerCls.total_line_total} className={InvoiceDrawerCls.total_line_total}
/> />
<TotalLine <TotalLine
title={<T id={'invoice.details.payment_amount'} />} title={<T id={'invoice.details.payment_amount'} />}
value={invoice.payment_amount} value={invoice.formatted_payment_amount}
className={InvoiceDrawerCls.total_line_payment} className={InvoiceDrawerCls.total_line_payment}
/> />
<TotalLine <TotalLine
title={<T id={'invoice.details.due_amount'} />} title={<T id={'invoice.details.due_amount'} />}
value={'1000'} value={invoice.formatted_due_amount}
className={InvoiceDrawerCls.total_line_dueAmount} className={InvoiceDrawerCls.total_line_dueAmount}
/> />
</TotalLines> </TotalLines>

View File

@@ -1,6 +1,10 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
/**
* Retrieve invoice readonly details table columns.
*/
export const useInvoiceReadonlyEntriesColumns = () => export const useInvoiceReadonlyEntriesColumns = () =>
React.useMemo( React.useMemo(
() => [ () => [
@@ -20,22 +24,25 @@ export const useInvoiceReadonlyEntriesColumns = () =>
{ {
Header: intl.get('quantity'), Header: intl.get('quantity'),
accessor: 'quantity', accessor: 'quantity',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'quantity', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Header: intl.get('rate'), Header: intl.get('rate'),
accessor: 'rate', accessor: 'rate',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'rate', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
{ {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: 'amount', accessor: 'amount',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'amount', align: 'right',
disableSortBy: true, disableSortBy: true,
}, },
], ],

View File

@@ -1,9 +1,8 @@
import React from 'react'; import React from 'react';
import 'style/components/Drawers/ManualJournalDrawer.scss';
import { DrawerBody } from 'components'; import { DrawerBody } from 'components';
import 'style/components/Drawers/ViewDetails.scss';
import { ManualJournalDrawerProvider } from './ManualJournalDrawerProvider'; import { ManualJournalDrawerProvider } from './ManualJournalDrawerProvider';
import ManualJournalDrawerDetails from './ManualJournalDrawerDetails'; import ManualJournalDrawerDetails from './ManualJournalDrawerDetails';

View File

@@ -1,9 +1,14 @@
import React from 'react'; import React from 'react';
import { useManualJournalDrawerContext } from './ManualJournalDrawerProvider'; import { useManualJournalDrawerContext } from './ManualJournalDrawerProvider';
export default function ManualJournalDrawerFooter({}) { import { FormatNumber } from '../../../components';
/**
* Manual journal readonly details footer.
*/
export default function ManualJournalDrawerFooter() {
const { const {
manualJournal: { amount }, manualJournal: { amount, formatted_amount },
} = useManualJournalDrawerContext(); } = useManualJournalDrawerContext();
return ( return (
@@ -11,17 +16,19 @@ export default function ManualJournalDrawerFooter({}) {
<div class="total-lines"> <div class="total-lines">
<div class="total-lines__line total-lines__line--subtotal"> <div class="total-lines__line total-lines__line--subtotal">
<div class="title">Subtotal</div> <div class="title">Subtotal</div>
<div class="debit">{amount}</div> <div class="debit">
<div class="credit">{amount} </div> <FormatNumber value={amount} />
</div>
<div class="credit">
<FormatNumber value={amount} />
</div>
</div> </div>
<div class="total-lines__line total-lines__line--total"> <div class="total-lines__line total-lines__line--total">
<div class="title">TOTAL</div> <div class="title">TOTAL</div>
<div class="debit">{amount}</div> <div class="debit">{formatted_amount}</div>
<div class="credit">{amount}</div> <div class="credit">{formatted_amount}</div>
</div> </div>
</div> </div>
</div> </div>
); );
} }

View File

@@ -2,7 +2,7 @@ import intl from 'react-intl-universal';
import React from 'react'; import React from 'react';
import { Classes, Tooltip, Position } from '@blueprintjs/core'; import { Classes, Tooltip, Position } from '@blueprintjs/core';
import { If, Icon } from 'components'; import { FormatNumberCell, If, Icon } from '../../../components';
/** /**
* Note column accessor. * Note column accessor.
@@ -33,32 +33,43 @@ export const useManualJournalEntriesColumns = () =>
accessor: 'account.name', accessor: 'account.name',
width: 130, width: 130,
disableSortBy: true, disableSortBy: true,
className: 'account',
}, },
{ {
Header: intl.get('contact'), Header: intl.get('contact'),
accessor: 'contact.display_name', accessor: 'contact.display_name',
width: 130, width: 130,
disableSortBy: true, disableSortBy: true,
className: 'contact',
}, },
{ {
Header: intl.get('note'), Header: intl.get('note'),
accessor: NoteAccessor, accessor: NoteAccessor,
width: 80, width: 80,
disableSortBy: true, disableSortBy: true,
className: 'note',
}, },
{ {
Header: intl.get('credit'), Header: intl.get('credit'),
accessor: 'credit', accessor: 'credit',
Cell: FormatNumberCell,
width: 100, width: 100,
disableResizable: true, disableResizable: true,
disableSortBy: true, disableSortBy: true,
formatNumber: { noZero: true },
className: 'credit',
align: 'right',
}, },
{ {
Header: intl.get('debit'), Header: intl.get('debit'),
accessor: 'debit', accessor: 'debit',
Cell: FormatNumberCell,
width: 100, width: 100,
disableResizable: true, disableResizable: true,
disableSortBy: true, disableSortBy: true,
formatNumber: { noZero: true },
className: 'debit',
align: 'right',
}, },
], ],
[], [],

View File

@@ -3,23 +3,25 @@ import clsx from 'classnames';
import { T, TotalLines, TotalLine } from 'components'; import { T, TotalLines, TotalLine } from 'components';
import PaymentDrawerCls from './PaymentMadeDrawer.module.scss'; import PaymentDrawerCls from './PaymentMadeDrawer.module.scss';
import { usePaymentMadeDetailContext } from './PaymentMadeDetailProvider';
/** /**
* Payment made - Details panel - Footer. * Payment made - Details panel - Footer.
*/ */
export default function PaymentMadeDetailFooter() { export default function PaymentMadeDetailFooter() {
const { paymentMade } = usePaymentMadeDetailContext();
return ( return (
<div className={clsx(PaymentDrawerCls.detail_panel_footer)}> <div className={clsx(PaymentDrawerCls.detail_panel_footer)}>
<TotalLines> <TotalLines>
<TotalLine <TotalLine
title={<T id={'payment_made.details.subtotal'} />} title={<T id={'payment_made.details.subtotal'} />}
value={1000} value={paymentMade.amount}
className={clsx(PaymentDrawerCls.total_line_subtotal)} className={clsx(PaymentDrawerCls.total_line_subtotal)}
/> />
<TotalLine <TotalLine
title={<T id={'payment_made.details.total'} />} title={<T id={'payment_made.details.total'} />}
value={1000} value={paymentMade.formatted_amount}
className={clsx(PaymentDrawerCls.total_line_total)} className={clsx(PaymentDrawerCls.total_line_total)}
/> />
</TotalLines> </TotalLines>

View File

@@ -14,7 +14,7 @@ const PaymentMadeDetailContext = React.createContext();
*/ */
function PaymentMadeDetailProvider({ paymentMadeId, ...props }) { function PaymentMadeDetailProvider({ paymentMadeId, ...props }) {
// Handle fetch specific payment made details. // Handle fetch specific payment made details.
const { data: paymentMade, isFetching: isPaymentMadeLoading } = const { data: paymentMade, isLoading: isPaymentMadeLoading } =
usePaymentMade(paymentMadeId, { usePaymentMade(paymentMadeId, {
enabled: !!paymentMadeId, enabled: !!paymentMadeId,
}); });

View File

@@ -8,7 +8,12 @@ import { usePaymentMadeDetailContext } from './PaymentMadeDetailProvider';
import PaymentDrawerCls from './PaymentMadeDrawer.module.scss'; import PaymentDrawerCls from './PaymentMadeDrawer.module.scss';
/**
* Payment made read-only details table.
*/
export default function PaymentMadeDetailTable() { export default function PaymentMadeDetailTable() {
// Retrieve payment made entries columns.
const columns = usePaymentMadeEntriesColumns(); const columns = usePaymentMadeEntriesColumns();
// Payment made details context. // Payment made details context.

View File

@@ -2,6 +2,8 @@ import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import moment from 'moment'; import moment from 'moment';
import { FormatNumberCell } from '../../../components';
export const usePaymentMadeEntriesColumns = () => export const usePaymentMadeEntriesColumns = () =>
React.useMemo(() => [ React.useMemo(() => [
{ {
@@ -21,20 +23,23 @@ export const usePaymentMadeEntriesColumns = () =>
{ {
Header: intl.get('bill_amount'), Header: intl.get('bill_amount'),
accessor: 'amount', accessor: 'amount',
className: 'amount', Cell: FormatNumberCell,
align: 'right',
}, },
{ {
Header: intl.get('due_amount'), Header: intl.get('due_amount'),
accessor: 'due_amount', accessor: 'due_amount',
Cell: FormatNumberCell,
width: 100, width: 100,
disableSortBy: true, disableSortBy: true,
className: 'due_amount', align: 'right',
}, },
{ {
Header: intl.get('payment_amount'), Header: intl.get('payment_amount'),
accessor: 'payment_amount', accessor: 'payment_amount',
Cell: FormatNumberCell,
width: 100, width: 100,
disableSortBy: true, disableSortBy: true,
className: 'payment_amount', align: 'right',
}, },
], []); ], []);

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import clsx from 'classnames'; import clsx from 'classnames';
import { T, TotalLine, TotalLines } from 'components'; import { FormatNumber, T, TotalLine, TotalLines } from 'components';
import { usePaymentReceiveDetailContext } from './PaymentReceiveDetailProvider'; import { usePaymentReceiveDetailContext } from './PaymentReceiveDetailProvider';
import PaymentDrawerCls from './PaymentReceiveDrawer.module.scss'; import PaymentDrawerCls from './PaymentReceiveDrawer.module.scss';
@@ -17,12 +17,12 @@ export default function PaymentReceiveDetailFooter() {
<TotalLines> <TotalLines>
<TotalLine <TotalLine
title={<T id={'payment_receive.details.subtotal'} />} title={<T id={'payment_receive.details.subtotal'} />}
value={paymentReceive.amount} value={<FormatNumber value={paymentReceive.amount} />}
className={PaymentDrawerCls.total_line_subtotal} className={PaymentDrawerCls.total_line_subtotal}
/> />
<TotalLine <TotalLine
title={<T id={'payment_receive.details.total'} />} title={<T id={'payment_receive.details.total'} />}
value={paymentReceive.amount} value={paymentReceive.formatted_amount}
className={PaymentDrawerCls.total_line_total} className={PaymentDrawerCls.total_line_total}
/> />
</TotalLines> </TotalLines>

View File

@@ -1,6 +1,7 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import moment from 'moment'; import moment from 'moment';
import { FormatNumberCell } from '../../../components';
/** /**
* Retrieve payment entries table columns. * Retrieve payment entries table columns.
@@ -25,19 +26,22 @@ export const usePaymentReceiveEntriesColumns = () =>
{ {
Header: intl.get('invoice_amount'), Header: intl.get('invoice_amount'),
accessor: 'invoice.balance', accessor: 'invoice.balance',
className: 'invoice_amount', Cell: FormatNumberCell,
align: 'right',
}, },
{ {
Header: intl.get('amount_due'), Header: intl.get('amount_due'),
accessor: 'invoice.amount_due', accessor: 'invoice.amount_due',
className: 'amount_due', Cell: FormatNumberCell,
align: 'right',
width: 100, width: 100,
disableSortBy: true, disableSortBy: true,
}, },
{ {
Header: intl.get('payment_amount'), Header: intl.get('payment_amount'),
accessor: 'invoice.payment_amount', accessor: 'invoice.payment_amount',
className: 'payment_amount', Cell: FormatNumberCell,
align: 'right',
width: 100, width: 100,
disableSortBy: true, disableSortBy: true,
}, },

View File

@@ -6,6 +6,11 @@ import { T, TotalLines, TotalLine } from 'components';
import ReceiptDrawerCls from 'style/components/Drawers/ReceiptDrawer.module.scss'; import ReceiptDrawerCls from 'style/components/Drawers/ReceiptDrawer.module.scss';
import { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider'; import { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider';
import { FormatNumber } from '../../../components';
/**
* Receipts read-only details footer.
*/
export function ReceiptDetailFooter() { export function ReceiptDetailFooter() {
const { receipt } = useReceiptDetailDrawerContext(); const { receipt } = useReceiptDetailDrawerContext();
@@ -14,17 +19,17 @@ export function ReceiptDetailFooter() {
<TotalLines> <TotalLines>
<TotalLine <TotalLine
title={<T id={'receipt.details.subtotal'} />} title={<T id={'receipt.details.subtotal'} />}
value={receipt.amount} value={<FormatNumber value={receipt.amount} />}
className={ReceiptDrawerCls.total_line_subtotal} className={ReceiptDrawerCls.total_line_subtotal}
/> />
<TotalLine <TotalLine
title={<T id={'receipt.details.total'} />} title={<T id={'receipt.details.total'} />}
value={receipt.amount} value={receipt.formatted_amount}
className={ReceiptDrawerCls.total_line_total} className={ReceiptDrawerCls.total_line_total}
/> />
<TotalLine <TotalLine
title={<T id={'receipt.details.payment_amount'} />} title={<T id={'receipt.details.payment_amount'} />}
value={receipt.amount} value={receipt.formatted_amount}
className={ReceiptDrawerCls.total_line_payment} className={ReceiptDrawerCls.total_line_payment}
/> />
<TotalLine <TotalLine

View File

@@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormatNumberCell } from '../../../components';
export const useReceiptReadonlyEntriesTableColumns = () => React.useMemo(() => [ export const useReceiptReadonlyEntriesTableColumns = () => React.useMemo(() => [
{ {
@@ -18,22 +19,25 @@ export const useReceiptReadonlyEntriesTableColumns = () => React.useMemo(() => [
{ {
Header: intl.get('quantity'), Header: intl.get('quantity'),
accessor: 'quantity', accessor: 'quantity',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'quantity', align: 'right',
disableSortBy: true disableSortBy: true
}, },
{ {
Header: intl.get('rate'), Header: intl.get('rate'),
accessor: 'rate', accessor: 'rate',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'rate', align: 'right',
disableSortBy: true disableSortBy: true
}, },
{ {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: 'amount', accessor: 'amount',
Cell: FormatNumberCell,
width: 100, width: 100,
className: 'amount', align: 'right',
disableSortBy: true disableSortBy: true
}, },
], []); ], []);

View File

@@ -12,9 +12,9 @@ import {
MenuDivider, MenuDivider,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import moment from 'moment'; import moment from 'moment';
import { FormattedMessage as T } from 'components';
import { Money, Icon, If } from 'components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormattedMessage as T, Money, Icon, If } from 'components';
import { safeCallback } from 'utils'; import { safeCallback } from 'utils';
/** /**
@@ -138,6 +138,7 @@ export function useExpensesTableColumns() {
Header: intl.get('full_amount'), Header: intl.get('full_amount'),
accessor: TotalAmountAccessor, accessor: TotalAmountAccessor,
className: 'amount', className: 'amount',
align: 'right',
width: 150, width: 150,
clickable: true, clickable: true,
}, },

View File

@@ -37,23 +37,17 @@ export const useAPAgingSummaryColumns = () => {
Header: <T id={'current'} />, Header: <T id={'current'} />,
accessor: 'current', accessor: 'current',
className: 'current', className: 'current',
width: getColumnWidth(tableRows, `current`, { width: getColumnWidth(tableRows, `current`, { minWidth: 120 }),
minWidth: 120,
}),
}, },
...agingColumns.map((agingColumn, index) => ({ ...agingColumns.map((agingColumn, index) => ({
Header: agingColumn, Header: agingColumn,
accessor: `aging-${index}`, accessor: `aging-${index}`,
width: getColumnWidth(tableRows, `aging-${index}`, { width: getColumnWidth(tableRows, `aging-${index}`, { minWidth: 120 }),
minWidth: 120,
}),
})), })),
{ {
Header: <T id={'total'} />, Header: <T id={'total'} />,
accessor: 'total', accessor: 'total',
width: getColumnWidth(tableRows, 'total', { width: getColumnWidth(tableRows, 'total', { minWidth: 120 }),
minWidth: 120,
}),
}, },
], ],
[tableRows, agingColumns], [tableRows, agingColumns],

View File

@@ -15,8 +15,6 @@ import { useGeneralLedgerTableColumns } from './components';
* General ledger table. * General ledger table.
*/ */
export default function GeneralLedgerTable({ companyName }) { export default function GeneralLedgerTable({ companyName }) {
// General ledger context. // General ledger context.
const { const {
generalLedger: { tableRows, query }, generalLedger: { tableRows, query },

View File

@@ -12,8 +12,6 @@ import FinancialLoadingBar from '../FinancialLoadingBar';
* Retrieve the general ledger table columns. * Retrieve the general ledger table columns.
*/ */
export function useGeneralLedgerTableColumns() { export function useGeneralLedgerTableColumns() {
// General ledger context. // General ledger context.
const { const {
generalLedger: { tableRows }, generalLedger: { tableRows },
@@ -37,6 +35,7 @@ export function useGeneralLedgerTableColumns() {
return row.date; return row.date;
}, },
className: 'date', className: 'date',
textOverview: true,
width: 120, width: 120,
}, },
{ {
@@ -44,7 +43,6 @@ export function useGeneralLedgerTableColumns() {
accessor: 'name', accessor: 'name',
className: 'name', className: 'name',
textOverview: true, textOverview: true,
// width: 200,
}, },
{ {
Header: intl.get('transaction_type'), Header: intl.get('transaction_type'),
@@ -58,12 +56,13 @@ export function useGeneralLedgerTableColumns() {
accessor: 'reference_id', accessor: 'reference_id',
className: 'transaction_number', className: 'transaction_number',
width: 100, width: 100,
textOverview: true,
}, },
{ {
Header: intl.get('description'), Header: intl.get('description'),
accessor: 'note', accessor: 'note',
className: 'description', className: 'description',
// width: 145, textOverview: true,
}, },
{ {
Header: intl.get('credit'), Header: intl.get('credit'),
@@ -73,6 +72,7 @@ export function useGeneralLedgerTableColumns() {
minWidth: 100, minWidth: 100,
magicSpacing: 10, magicSpacing: 10,
}), }),
textOverview: true,
}, },
{ {
Header: intl.get('debit'), Header: intl.get('debit'),
@@ -82,6 +82,7 @@ export function useGeneralLedgerTableColumns() {
minWidth: 100, minWidth: 100,
magicSpacing: 10, magicSpacing: 10,
}), }),
textOverview: true,
}, },
{ {
Header: intl.get('amount'), Header: intl.get('amount'),
@@ -91,6 +92,7 @@ export function useGeneralLedgerTableColumns() {
minWidth: 100, minWidth: 100,
magicSpacing: 10, magicSpacing: 10,
}), }),
textOverview: true,
}, },
{ {
Header: intl.get('running_balance'), Header: intl.get('running_balance'),
@@ -100,6 +102,7 @@ export function useGeneralLedgerTableColumns() {
minWidth: 100, minWidth: 100,
magicSpacing: 10, magicSpacing: 10,
}), }),
textOverview: true,
}, },
], ],
[tableRows], [tableRows],

View File

@@ -10,9 +10,9 @@ import {
Popover, Popover,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormattedMessage as T } from 'components';
import { isNumber } from 'lodash'; import { isNumber } from 'lodash';
import { Icon, Money, If } from 'components';
import { FormattedMessage as T, Icon, Money, If } from 'components';
import { isBlank, safeCallback } from 'utils'; import { isBlank, safeCallback } from 'utils';
/** /**
@@ -187,7 +187,7 @@ export const useItemsTableColumns = () => {
id: 'sell_price', id: 'sell_price',
Header: intl.get('sell_price'), Header: intl.get('sell_price'),
accessor: 'sell_price_formatted', accessor: 'sell_price_formatted',
className: 'sell-price', align: 'right',
width: 150, width: 150,
clickable: true, clickable: true,
}, },
@@ -195,7 +195,7 @@ export const useItemsTableColumns = () => {
id: 'cost_price', id: 'cost_price',
Header: intl.get('cost_price'), Header: intl.get('cost_price'),
accessor: 'cost_price_formatted', accessor: 'cost_price_formatted',
className: 'cost-price', align: 'right',
width: 150, width: 150,
clickable: true, clickable: true,
}, },
@@ -204,6 +204,7 @@ export const useItemsTableColumns = () => {
Header: intl.get('quantity_on_hand'), Header: intl.get('quantity_on_hand'),
accessor: 'quantity_on_hand', accessor: 'quantity_on_hand',
Cell: QuantityOnHandCell, Cell: QuantityOnHandCell,
align: 'right',
width: 140, width: 140,
clickable: true, clickable: true,
}, },

View File

@@ -11,11 +11,11 @@ import {
ProgressBar, ProgressBar,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormattedMessage as T } from 'components';
import { Icon, If, Choose, Money } from 'components';
import { formattedAmount, safeCallback, isBlank, calculateStatus } from 'utils';
import moment from 'moment'; import moment from 'moment';
import { FormattedMessage as T, Icon, If, Choose, Money } from 'components';
import { formattedAmount, safeCallback, isBlank, calculateStatus } from 'utils';
/** /**
* Actions menu. * Actions menu.
*/ */
@@ -183,6 +183,7 @@ export function useBillsTableColumns() {
accessor: AmountAccessor, accessor: AmountAccessor,
width: 120, width: 120,
className: 'amount', className: 'amount',
align: 'right',
clickable: true, clickable: true,
}, },
{ {

View File

@@ -2,7 +2,7 @@ import React from 'react';
import 'style/pages/PaymentMade/List.scss'; import 'style/pages/PaymentMade/List.scss';
import { DashboardContentTable, DashboardPageContent } from 'components'; import { DashboardPageContent } from 'components';
import PaymentMadeActionsBar from './PaymentMadeActionsBar'; import PaymentMadeActionsBar from './PaymentMadeActionsBar';
import PaymentMadesAlerts from '../PaymentMadesAlerts'; import PaymentMadesAlerts from '../PaymentMadesAlerts';
import PaymentMadesTable from './PaymentMadesTable'; import PaymentMadesTable from './PaymentMadesTable';

View File

@@ -10,6 +10,7 @@ import {
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Icon, Money } from 'components'; import { Icon, Money } from 'components';
import { safeCallback } from 'utils'; import { safeCallback } from 'utils';
@@ -111,6 +112,7 @@ export function usePaymentMadesTableColumns() {
accessor: AmountAccessor, accessor: AmountAccessor,
width: 140, width: 140,
className: 'amount', className: 'amount',
align: 'right',
clickable: true, clickable: true,
}, },
{ {

View File

@@ -9,12 +9,12 @@ import {
MenuDivider, MenuDivider,
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { Money, Choose, Icon, If } from 'components';
import { FormattedMessage as T } from 'components';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { safeCallback } from 'utils';
import moment from 'moment'; import moment from 'moment';
import { FormattedMessage as T, Money, Choose, Icon, If } from 'components';
import { safeCallback } from 'utils';
/** /**
* Status accessor. * Status accessor.
*/ */
@@ -196,7 +196,7 @@ export function useEstiamtesTableColumns() {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: AmountAccessor, accessor: AmountAccessor,
width: 140, width: 140,
className: 'amount', align: 'right',
clickable: true, clickable: true,
}, },
{ {

View File

@@ -11,11 +11,9 @@ import {
Button, Button,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormattedMessage as T } from 'components';
import moment from 'moment'; import moment from 'moment';
import { Choose, If, Icon } from 'components';
import { Money, AppToaster } from 'components'; import { FormattedMessage as T, AppToaster, Choose, If, Icon } from 'components';
import { formattedAmount, safeCallback, calculateStatus } from 'utils'; import { formattedAmount, safeCallback, calculateStatus } from 'utils';
export const statusAccessor = (row) => { export const statusAccessor = (row) => {
@@ -146,17 +144,6 @@ export function ActionsMenu({
); );
} }
function ActionsCell(props) {
return (
<Popover
content={<ActionsMenu {...props} />}
position={Position.RIGHT_BOTTOM}
>
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
</Popover>
);
}
/** /**
* Retrieve invoices table columns. * Retrieve invoices table columns.
*/ */
@@ -196,7 +183,7 @@ export function useInvoicesTableColumns() {
Header: intl.get('balance'), Header: intl.get('balance'),
accessor: 'formatted_amount', accessor: 'formatted_amount',
width: 120, width: 120,
className: 'balance', align: 'right',
clickable: true, clickable: true,
textOverview: true, textOverview: true,
}, },

View File

@@ -10,6 +10,7 @@ import {
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import moment from 'moment'; import moment from 'moment';
import { Money, Icon } from 'components'; import { Money, Icon } from 'components';
import { safeCallback } from 'utils'; import { safeCallback } from 'utils';
@@ -105,7 +106,7 @@ export function usePaymentReceivesColumns() {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: AmountAccessor, accessor: AmountAccessor,
width: 120, width: 120,
className: 'amount', align: 'right',
clickable: true, clickable: true,
textOverview: true, textOverview: true,
}, },

View File

@@ -11,9 +11,10 @@ import {
Tag, Tag,
Button, Button,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import moment from 'moment';
import { safeCallback } from 'utils'; import { safeCallback } from 'utils';
import { Choose, Money, Icon, If } from 'components'; import { Choose, Money, Icon, If } from 'components';
import moment from 'moment';
export function ActionsMenu({ export function ActionsMenu({
payload: { onEdit, onDelete, onClose, onDrawer, onViewDetails, onPrint }, payload: { onEdit, onDelete, onClose, onDrawer, onViewDetails, onPrint },
@@ -136,7 +137,7 @@ export function useReceiptsTableColumns() {
Header: intl.get('amount'), Header: intl.get('amount'),
accessor: (r) => <Money amount={r.amount} currency={r.currency_code} />, accessor: (r) => <Money amount={r.amount} currency={r.currency_code} />,
width: 140, width: 140,
className: 'amount', align: 'right',
clickable: true, clickable: true,
textOverview: true, textOverview: true,
}, },

View File

@@ -9,6 +9,7 @@ import {
Intent, Intent,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { Icon, Money, If } from 'components'; import { Icon, Money, If } from 'components';
import { safeCallback, firstLettersArgs } from 'utils'; import { safeCallback, firstLettersArgs } from 'utils';
@@ -147,7 +148,7 @@ export function useVendorsTableColumns() {
id: 'balance', id: 'balance',
Header: intl.get('receivable_balance'), Header: intl.get('receivable_balance'),
accessor: BalanceAccessor, accessor: BalanceAccessor,
className: 'receivable_balance', align: 'right',
width: 100, width: 100,
clickable: true, clickable: true,
}, },

View File

@@ -256,14 +256,12 @@ html[lang^="ar"] {
} }
} }
} }
} }
.bp3-drawer{ .bp3-drawer{
border-left: 1px solid #00115e; border-left: 1px solid #00115e;
} }
.drawer-portal{ .drawer-portal{
.bp3-overlay-backdrop{ .bp3-overlay-backdrop{
@@ -279,3 +277,8 @@ html[lang^="ar"] {
font-weight: 600; font-weight: 600;
margin-bottom: 0; margin-bottom: 0;
} }
.align-right{
text-align: right;
}

View File

@@ -1,103 +1,107 @@
.expense-drawer { .expense-drawer {
.card { .card {
margin: 15px; margin: 15px;
padding: 25px 15px 35px; padding: 25px 15px 35px;
.amount { .amount {}
}
}
&__content-header {
margin-bottom: 30px;
.detail-item {
flex-grow: 1;
&--amount {
width: 20%;
}
.big-number {
font-size: 28px;
color: #c06361;
margin: 6px 0;
font-weight: 600;
}
} }
&__content-header { .details-menu+.details-menu {
margin-bottom: 30px; margin-top: 14px;
.detail-item {
flex-grow: 1;
&--amount {
width: 20%;
}
.big-number{
font-size: 28px;
color: #c06361;
margin: 6px 0;
font-weight: 600;
}
}
.details-menu + .details-menu{
margin-top: 14px;
}
.details-menu--horizantal{
.detail-item{
&__label{
min-width: 120px;
}
}
}
} }
&__content-footer{ .details-menu--horizantal {
display: flex;
.total-lines{ .detail-item {
margin-left: auto;
} &__label {
} min-width: 120px;
.table {
.thead .th {
background: transparent;
color: #222222;
border-bottom: 1px solid #000000;
border-top: 1px solid #000000;
padding: 0.5rem;
}
.tbody .tr .td {
background: transparent;
padding: 0.5rem 0.5rem;
border-bottom: 0;
}
.tbody .tr:last-child .td {
border-bottom: 1px solid #d2dce2;
} }
}
} }
}
&__content-footer {
display: flex;
.total-lines { .total-lines {
margin-left: auto;
}
}
&__line {
display: flex;
>div {
padding: 7px 8px;
}
.title {
width: 220px;
font-weight: 600;
}
.amount {
font-weight: 600;
width: 260px;
}
&--subtotal {
border-bottom: 1px solid #000;
}
&--total {
border-bottom: 3px double #000;
}
}
.table {
.thead .th {
background: transparent;
color: #222222;
border-bottom: 1px solid #000000;
border-top: 1px solid #000000;
padding: 0.5rem;
} }
.tbody .tr .td {
background: transparent;
padding: 0.5rem 0.5rem;
border-bottom: 0;
}
.tbody .tr:last-child .td {
border-bottom: 1px solid #d2dce2;
}
}
.total-lines {
&__line {
display: flex;
>div {
padding: 7px 8px;
}
.title {
width: 220px;
font-weight: 600;
}
.amount {
font-weight: 600;
width: 260px;
}
&--subtotal,
&--total {
text-align: right;
}
&--subtotal {
border-bottom: 1px solid #000;
}
&--total {
border-bottom: 3px double #000;
}
}
}
} }

View File

@@ -0,0 +1,113 @@
.journal-drawer {
.card {
margin: 15px;
padding: 25px 15px 35px;
}
.card {
.amount {
font-size: 28px;
color: #c06361;
margin: 6px 0;
font-weight: 600;
}
}
.table {
.thead .th {
background: transparent;
color: #222222;
border-bottom: 1px solid #000000;
border-top: 1px solid #000000;
padding: 0.5rem;
}
.tbody .tr .td {
background: transparent;
padding: 0.5rem 0.5rem;
border-bottom: 0;
}
.tbody .tr:last-child .td {
border-bottom: 1px solid #d2dce2;
}
.thead,
.tbody{
.tr .td,
.tr .th{
&.credit,
&.debit{
text-align: right;
}
}
}
}
&__content {
&-header {
margin-bottom: 35px;
.detail-item {
flex-grow: 1;
&--amount {
width: 20%;
}
}
}
&-footer {
display: flex;
.total-lines {
margin-left: auto;
}
}
&-description {
margin-top: 20px;
.title {
color: #727983;
}
}
}
.total-lines {
&__line {
display: flex;
>div {
padding: 7px 8px;
}
.title {
width: 220px;
font-weight: 600;
}
.credit,
.debit {
font-weight: 600;
width: 155px;
}
&--subtotal {
border-bottom: 1px solid #000;
}
&--total {
border-bottom: 3px double #000;
}
&--subtotal,
&--total{
text-align: right;
}
}
}
}

View File

@@ -1,179 +0,0 @@
.journal-drawer{
.card{
margin: 15px;
padding: 25px 15px 35px;
}
.card{
.amount{
font-size: 28px;
color: #c06361;
margin: 6px 0;
font-weight: 600;
}
}
.table{
.thead .th {
background: transparent;
color: #222222;
border-bottom: 1px solid #000000;
border-top: 1px solid #000000;
padding: 0.5rem;
}
.tbody .tr .td {
background: transparent;
padding: 0.5rem 0.5rem;
border-bottom: 0;
}
.tbody .tr:last-child .td{
border-bottom: 1px solid #d2dce2;
}
}
&__content{
&-header{
margin-bottom: 35px;
.detail-item{
flex-grow: 1;
&--amount{
width: 20%;
}
}
}
&-footer{
display: flex;
.total-lines{
margin-left: auto;
}
}
&-description{
margin-top: 20px;
.title{
color: #727983;
}
}
}
.total-lines{
&__line{
display: flex;
> div{
padding: 7px 8px;
}
.title{
width: 220px;
font-weight: 600;
}
.credit,
.debit{
font-weight: 600;
width: 155px;
}
&--subtotal{
border-bottom: 1px solid #000;
}
&--total{
border-bottom: 3px double #000;
}
}
}
}
// .expense-drawer {
// &__content {
// display: flex;
// flex-direction: column;
// border: 1px solid #d2dce2;
// box-shadow: 1px 1px #fbf8f8;
// background-color: #ffffff;
// min-height: 508px;
// &--header {
// display: flex;
// flex-wrap: wrap;
// justify-content: flex-start;
// margin: 15px 0 20px;
// font-size: 14px;
// color: #666666;
// > div {
// flex-grow: 1;
// span {
// display: block;
// color: #666666;
// font-weight: 500;
// margin: 10px 0;
// }
// }
// .info {
// flex: 0 1 25%;
// padding-left: 2%;
// margin: 10px 0;
// }
// .balance {
// font-size: 26px;
// font-weight: 500;
// color: #0f1118;
// }
// }
// &--table {
// flex-grow: 1;
// flex-shrink: 0;
// .desc {
// margin: 20px 0 60px;
// > b {
// color: #2f2f2f;
// }
// }
// }
// &--footer {
// display: flex;
// flex-direction: column;
// align-items: flex-end;
// color: #666666;
// .wrapper > div {
// display: flex;
// border-top: 1px solid #000000;
// border-bottom: 1px solid #000000;
// padding: 0.2rem;
// span,
// p {
// margin: 10px 50px 5px 0px;
// }
// span {
// color: #333333;
// flex-grow: 1;
// font-weight: 500;
// }
// }
// }
// }
// }

View File

@@ -13,16 +13,16 @@ import { isEqual } from 'lodash';
import jsCookie from 'js-cookie'; import jsCookie from 'js-cookie';
export const getCookie = (name, defaultValue) => _.defaultTo(jsCookie.get(name), defaultValue); export const getCookie = (name, defaultValue) =>
_.defaultTo(jsCookie.get(name), defaultValue);
export const setCookie = (name, value, expiry = 365, secure = false) => { export const setCookie = (name, value, expiry = 365, secure = false) => {
jsCookie.set(name, value, { expires: expiry, path: '/', secure }); jsCookie.set(name, value, { expires: expiry, path: '/', secure });
}; };
export const removeCookie = (name) => { export const removeCookie = (name) => {
return jsCookie.remove(name, { path: '/' }); return jsCookie.remove(name, { path: '/' });
} };
export function removeEmptyFromObject(obj) { export function removeEmptyFromObject(obj) {
obj = Object.assign({}, obj); obj = Object.assign({}, obj);
@@ -137,7 +137,7 @@ export const parseDateRangeQuery = (keyword) => {
}, },
this_quarter: { this_quarter: {
range: 'quarter', range: 'quarter',
} },
}; };
if (typeof queries[keyword] === 'undefined') { if (typeof queries[keyword] === 'undefined') {
@@ -168,16 +168,21 @@ export const defaultExpanderReducer = (tableRows, level) => {
return expended; return expended;
}; };
export function formattedAmount(cents, currency, props) { export function formattedAmount(cents, currencyCode = '', props) {
const { symbol, decimal_digits: precision } = Currency[currency]; const currency = Currency[currencyCode];
const parsedCurrency = {
symbol: '',
decimal_digits: 0,
...currency
};
const parsedProps = { const parsedProps = {
noZero: false, noZero: false,
...props, ...props,
}; };
const formatOptions = { const formatOptions = {
symbol, symbol: parsedCurrency.symbol,
precision: 0, precision: parsedCurrency.decimal_digits,
format: { format: {
pos: '%s%v', pos: '%s%v',
neg: '%s-%v', neg: '%s-%v',
@@ -188,6 +193,24 @@ export function formattedAmount(cents, currency, props) {
return accounting.formatMoney(cents, formatOptions); return accounting.formatMoney(cents, formatOptions);
} }
export function formattedNumber(amount, props) {
const parsedProps = {
noZero: false,
...props,
};
const formatOptions = {
symbol: '',
precision: 0,
format: {
pos: '%s%v',
neg: '%s-%v',
zero: parsedProps.noZero ? '' : '%s%v',
},
...props,
};
return accounting.formatMoney(amount, formatOptions);
}
export function formattedExchangeRate(amount, currency) { export function formattedExchangeRate(amount, currency) {
const options = { const options = {
style: 'currency', style: 'currency',
@@ -243,7 +266,6 @@ export const firstLettersArgs = (...args) => {
return letters.join('').toUpperCase(); return letters.join('').toUpperCase();
}; };
export const uniqueMultiProps = (items, props) => { export const uniqueMultiProps = (items, props) => {
return _.uniqBy(items, (item) => { return _.uniqBy(items, (item) => {
return JSON.stringify(_.pick(item, props)); return JSON.stringify(_.pick(item, props));
@@ -780,8 +802,7 @@ export function getFilterableFieldsFromFields(fields) {
export const RESORUCE_TYPE = { export const RESORUCE_TYPE = {
ACCOUNTS: 'account', ACCOUNTS: 'account',
ITEMS: 'items', ITEMS: 'items',
};
}
function escapeRegExpChars(text) { function escapeRegExpChars(text) {
return text.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); return text.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
@@ -816,4 +837,4 @@ export function highlightText(text, query) {
tokens.push(rest); tokens.push(rest);
} }
return tokens; return tokens;
} }

View File

@@ -1,4 +1,4 @@
import { Service } from 'typedi';; import { Service } from 'typedi';
import { Transformer } from 'lib/Transformer/Transformer'; import { Transformer } from 'lib/Transformer/Transformer';
import { formatNumber } from 'utils'; import { formatNumber } from 'utils';
@@ -13,6 +13,7 @@ export default class SaleInvoiceTransformer extends Transformer {
'formattedDueDate', 'formattedDueDate',
'formattedAmount', 'formattedAmount',
'formattedDueAmount', 'formattedDueAmount',
'formattedPaymentAmount',
]; ];
}; };
@@ -50,9 +51,20 @@ export default class SaleInvoiceTransformer extends Transformer {
* @param {ISaleInvoice} invoice * @param {ISaleInvoice} invoice
* @returns {string} * @returns {string}
*/ */
protected formattedDueAmount(invoice) { protected formattedDueAmount = (invoice): string => {
return formatNumber(invoice.dueAmount, { return formatNumber(invoice.dueAmount, {
currencyCode: invoice.currencyCode, currencyCode: invoice.currencyCode,
}); });
} };
/**
* Retrieve formatted payment amount.
* @param {ISaleInvoice} invoice
* @returns {string}
*/
protected formattedPaymentAmount = (invoice): string => {
return formatNumber(invoice.paymentAmount, {
currencyCode: invoice.currencyCode,
});
};
} }