re-structure to monorepo.

This commit is contained in:
a.bouhuolia
2023-02-03 01:02:31 +02:00
parent 8242ec64ba
commit 7a0a13f9d5
10400 changed files with 46966 additions and 17223 deletions

View File

@@ -0,0 +1,128 @@
// @ts-nocheck
import React from 'react';
import { useHistory } from 'react-router-dom';
import {
Button,
NavbarGroup,
Classes,
NavbarDivider,
Intent,
} from '@blueprintjs/core';
import { useBillDrawerContext } from './BillDrawerProvider';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import withAlertsActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import {
Can,
If,
Icon,
DrawerActionsBar,
FormattedMessage as T,
} from '@/components';
import {
BillAction,
PaymentMadeAction,
AbilitySubject,
} from '@/constants/abilityOption';
import { BillMenuItem } from './utils';
import { safeCallback, compose } from '@/utils';
function BillDetailActionsBar({
// #withDialogActions
openDialog,
// #withAlertsActions
openAlert,
// #withDrawerActions
closeDrawer,
}) {
const history = useHistory();
const { billId, bill } = useBillDrawerContext();
// Handle edit bill.
const onEditBill = () => {
history.push(`/bills/${billId}/edit`);
closeDrawer('bill-drawer');
};
// Handle convert to vendor credit.
const handleConvertToVendorCredit = () => {
history.push(`/vendor-credits/new?from_bill_id=${billId}`, {
billId: billId,
});
closeDrawer('bill-drawer');
};
// Handle delete bill.
const onDeleteBill = () => {
openAlert('bill-delete', { billId });
};
// Handle quick bill payment .
const handleQuickBillPayment = () => {
openDialog('quick-payment-made', { billId });
};
// Handle allocate landed cost button click.
const handleAllocateCostClick = () => {
openDialog('allocate-landed-cost', { billId });
};
return (
<DrawerActionsBar>
<NavbarGroup>
<Can I={BillAction.Edit} a={AbilitySubject.Bill}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="pen-18" />}
text={<T id={'edit_bill'} />}
onClick={safeCallback(onEditBill)}
/>
<NavbarDivider />
</Can>
<Can I={PaymentMadeAction.Create} a={AbilitySubject.PaymentMade}>
<If condition={bill.is_open && !bill.is_fully_paid}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="arrow-upward" iconSize={16} />}
text={<T id={'add_payment'} />}
onClick={handleQuickBillPayment}
/>
</If>
</Can>
<Can I={BillAction.Delete} a={AbilitySubject.Bill}>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}
text={<T id={'delete'} />}
intent={Intent.DANGER}
onClick={safeCallback(onDeleteBill)}
/>
</Can>
<Can I={BillAction.Edit} a={AbilitySubject.Bill}>
<NavbarDivider />
<BillMenuItem
payload={{
onConvert: handleConvertToVendorCredit,
onAllocateLandedCost: handleAllocateCostClick,
}}
/>
</Can>
</NavbarGroup>
</DrawerActionsBar>
);
}
export default compose(
withDialogActions,
withDrawerActions,
withAlertsActions,
)(BillDetailActionsBar);

View File

@@ -0,0 +1,28 @@
// @ts-nocheck
import React from 'react';
import {
CommercialDocFooter,
T,
If,
DetailsMenu,
DetailItem,
} from '@/components';
import { useBillDrawerContext } from './BillDrawerProvider';
/**
* Bill detail footer.
* @returns {React.JSX}
*/
export default function BillDetailFooter() {
const { bill } = useBillDrawerContext();
return (
<CommercialDocFooter>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<If condition={bill.note}>
<DetailItem label={<T id={'note'} />}>{bill.note}</DetailItem>
</If>
</DetailsMenu>
</CommercialDocFooter>
);
}

View File

@@ -0,0 +1,96 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import { defaultTo } from 'lodash';
import {
FormatDate,
DetailsMenu,
DetailItem,
Row,
Col,
CommercialDocHeader,
CommercialDocTopHeader,
VendorDrawerLink,
ExchangeRateDetailItem,
} from '@/components';
import { useBillDrawerContext } from './BillDrawerProvider';
import { BillDetailsStatus } from './utils';
/**
* Bill detail header.
*/
export default function BillDetailHeader() {
const { bill } = useBillDrawerContext();
return (
<CommercialDocHeader>
<CommercialDocTopHeader>
<DetailsMenu>
<AmountDetailItem label={intl.get('amount')}>
<h3 class="big-number">{bill.formatted_amount}</h3>
</AmountDetailItem>
<StatusDetailItem>
<BillDetailsStatus bill={bill} />
</StatusDetailItem>
</DetailsMenu>
</CommercialDocTopHeader>
<Row>
<Col xs={6}>
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
<DetailItem label={intl.get('bill_date')}>
<FormatDate value={bill.bill_date} />
</DetailItem>
<DetailItem label={intl.get('due_date')}>
<FormatDate value={bill.due_date} />
</DetailItem>
<DetailItem label={intl.get('vendor_name')}>
<VendorDrawerLink vendorId={bill.vendor_id}>
{bill.vendor?.display_name}
</VendorDrawerLink>
</DetailItem>
<DetailItem label={intl.get('bill.details.bill_number')}>
{defaultTo(bill.bill_number, '-')}
</DetailItem>
<ExchangeRateDetailItem
exchangeRate={bill?.exchange_rate}
toCurrency={bill?.currency_code}
/>
</DetailsMenu>
</Col>
<Col xs={6}>
<DetailsMenu
direction={'horizantal'}
minLabelSize={'140px'}
textAlign={'right'}
>
<DetailItem label={intl.get('due_amount')}>
<strong>{bill.formatted_due_amount}</strong>
</DetailItem>
<DetailItem
label={intl.get('reference')}
children={defaultTo(bill.reference_no, '--')}
/>
<DetailItem
label={intl.get('bill.details.created_at')}
children={<FormatDate value={bill.created_at} />}
/>
</DetailsMenu>
</Col>
</Row>
</CommercialDocHeader>
);
}
const StatusDetailItem = styled(DetailItem)`
width: 50%;
text-align: right;
position: relative;
top: -5px;
`;
const AmountDetailItem = styled(DetailItem)`
width: 50%;
`;

View File

@@ -0,0 +1,22 @@
// @ts-nocheck
import React from 'react';
import BillDetailHeader from './BillDetailHeader';
import BillDetailTable from './BillDetailTable';
import BillDetailFooter from './BillDetailFooter';
import { CommercialDocBox } from '@/components';
import { BillDetailTableFooter } from './BillDetailTableFooter';
/**
* Bill detail panel tab.
*/
export default function BillDetailTab() {
return (
<CommercialDocBox>
<BillDetailHeader />
<BillDetailTable />
<BillDetailTableFooter />
<BillDetailFooter />
</CommercialDocBox>
);
}

View File

@@ -0,0 +1,26 @@
// @ts-nocheck
import React from 'react';
import { CommercialDocEntriesTable } from '@/components';
import { useBillDrawerContext } from './BillDrawerProvider';
import { useBillReadonlyEntriesTableColumns } from './utils';
import { TableStyle } from '@/constants';
export default function BillDetailTable() {
const {
bill: { entries },
} = useBillDrawerContext();
// Retrieve bill readonly entries table columns.
const columns = useBillReadonlyEntriesTableColumns();
return (
<CommercialDocEntriesTable
columns={columns}
data={entries}
styleName={TableStyle.Constrant}
/>
);
}

View File

@@ -0,0 +1,52 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import {
TotalLineBorderStyle,
TotalLineTextStyle,
FormatNumber,
T,
TotalLines,
TotalLine,
} from '@/components';
import { useBillDrawerContext } from './BillDrawerProvider';
/**
* Bill read-only details table footer.
*/
export function BillDetailTableFooter() {
const { bill } = useBillDrawerContext();
return (
<BillDetailsFooterRoot>
<BillTotalLines labelColWidth={'180px'} amountColWidth={'180px'}>
<TotalLine
title={<T id={'bill.details.subtotal'} />}
value={<FormatNumber value={bill.amont} />}
borderStyle={TotalLineBorderStyle.SingleDark}
/>
<TotalLine
title={<T id={'bill.details.total'} />}
value={bill.formatted_amount}
borderStyle={TotalLineBorderStyle.DoubleDark}
textStyle={TotalLineTextStyle.Bold}
/>
<TotalLine
title={<T id={'bill.details.payment_amount'} />}
value={bill.formatted_payment_amount}
/>
<TotalLine
title={<T id={'bill.details.due_amount'} />}
value={bill.formatted_due_amount}
/>
</BillTotalLines>
</BillDetailsFooterRoot>
);
}
export const BillDetailsFooterRoot = styled.div``;
export const BillTotalLines = styled(TotalLines)`
margin-left: auto;
`;

View File

@@ -0,0 +1,22 @@
// @ts-nocheck
import React from 'react';
import { DrawerBody } from '@/components';
import { BillDrawerProvider } from './BillDrawerProvider';
import BillDrawerDetails from './BillDrawerDetails';
/**
* Bill drawer content.
*/
export default function BillDrawerContent({
// #ownProp
billId,
}) {
return (
<BillDrawerProvider billId={billId}>
<DrawerBody>
<BillDrawerDetails />
</DrawerBody>
</BillDrawerProvider>
);
}

View File

@@ -0,0 +1,65 @@
// @ts-nocheck
import React from 'react';
import { Tab } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import { DrawerMainTabs } from '@/components';
import { useAbilityContext } from '@/hooks/utils';
import { PaymentMadeAction, AbilitySubject } from '@/constants/abilityOption';
import BillDetailTab from './BillDetailTab';
import LocatedLandedCostTable from './LocatedLandedCostTable';
import BillGLEntriesTable from './BillGLEntriesTable';
import BillPaymentTransactionTable from './BillPaymentTransactions/BillPaymentTransactionTable';
import BillDetailActionsBar from './BillDetailActionsBar';
/**
* Bill details tabs.
*/
function BillDetailsTabs() {
const ability = useAbilityContext();
return (
<DrawerMainTabs
renderActiveTabPanelOnly={true}
defaultSelectedTabId="details"
>
<Tab
title={intl.get('overview')}
id={'details'}
panel={<BillDetailTab />}
/>
<Tab
title={intl.get('journal_entries')}
id={'journal_entries'}
panel={<BillGLEntriesTable />}
/>
{ability.can(PaymentMadeAction.View, AbilitySubject.PaymentMade) && (
<Tab
title={intl.get('payment_transactions')}
id={'payment_transactions'}
panel={<BillPaymentTransactionTable />}
/>
)}
<Tab
title={intl.get('located_landed_cost')}
id={'landed_cost'}
panel={<LocatedLandedCostTable />}
/>
</DrawerMainTabs>
);
}
/**
* Bill view detail.
*/
export default function BillDetails() {
return (
<BillDetailsRoot>
<BillDetailActionsBar />
<BillDetailsTabs />
</BillDetailsRoot>
);
}
export const BillDetailsRoot = styled.div``;

View File

@@ -0,0 +1,60 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import { DrawerHeaderContent, DrawerLoading } from '@/components';
import { useBill, useBillLocatedLandedCost } from '@/hooks/query';
import { useFeatureCan } from '@/hooks/state';
import { Features } from '@/constants';
const BillDrawerContext = React.createContext();
/**
* Bill drawer provider.
*/
function BillDrawerProvider({ billId, ...props }) {
// Features guard.
const { featureCan } = useFeatureCan();
// Handle fetch bill details.
const { isLoading: isBillLoading, data: bill } = useBill(billId, {
enabled: !!billId,
});
// Handle fetch bill located landed cost transaction.
const { isLoading: isLandedCostLoading, data: transactions } =
useBillLocatedLandedCost(billId, {
enabled: !!billId,
});
//provider.
const provider = {
billId,
transactions,
bill,
};
const loading = isLandedCostLoading || isBillLoading;
return (
<DrawerLoading loading={loading}>
<DrawerHeaderContent
name="bill-drawer"
title={intl.get('bill.drawer.title', {
number: bill.bill_number ? `(${bill.bill_number})` : null,
})}
subTitle={
featureCan(Features.Branches)
? intl.get('bill.drawer.subtitle', {
value: bill.branch?.name,
})
: null
}
/>
<BillDrawerContext.Provider value={provider} {...props} />
</DrawerLoading>
);
}
const useBillDrawerContext = () => React.useContext(BillDrawerContext);
export { BillDrawerProvider, useBillDrawerContext };

View File

@@ -0,0 +1,50 @@
// @ts-nocheck
import React from 'react';
import styled from 'styled-components';
import { Card } from '@/components';
import { useTransactionsByReference } from '@/hooks/query';
import { useBillDrawerContext } from './BillDrawerProvider';
import JournalEntriesTable, {
AmountDisplayedBaseCurrencyMessage,
} from '../../JournalEntriesTable/JournalEntriesTable';
/**
* Bill GL entries table.
* @returns {React.JSX}
*/
export default function BillGLEntriesTable() {
const { billId } = useBillDrawerContext();
// Handle fetch transaction by reference.
const {
data: { transactions },
isLoading: isTransactionLoading,
} = useTransactionsByReference(
{
reference_id: billId,
reference_type: 'Bill',
},
{ enabled: !!billId },
);
return (
<BilleGLEntriesRoot>
<AmountDisplayedBaseCurrencyMessage />
<BillGLEntriesDatatable
loading={isTransactionLoading}
transactions={transactions}
/>
</BilleGLEntriesRoot>
);
}
const BilleGLEntriesRoot = styled(Card)``;
const BillGLEntriesDatatable = styled(JournalEntriesTable)`
.table .tbody .tr:last-child .td {
border-bottom: 0;
}
`;

View File

@@ -0,0 +1,77 @@
// @ts-nocheck
import React from 'react';
import { useHistory } from 'react-router-dom';
import { DataTable, Card, TableSkeletonRows } from '@/components';
import { TableStyle } from '@/constants';
import { useBillPaymentTransactionsColumns, ActionsMenu } from './components';
import { useBillDrawerContext } from '../BillDrawerProvider';
import { useBillPaymentTransactions } from '@/hooks/query';
import withAlertsActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { compose } from '@/utils';
/**
* Bill payment transactions datatable.
*/
function BillPaymentTransactionTable({
// #withAlertsActions
openAlert,
// #withDrawerActions
closeDrawer,
}) {
const history = useHistory();
const columns = useBillPaymentTransactionsColumns();
const { billId } = useBillDrawerContext();
// Handle fetch bill payment transaction.
const {
isLoading: isPaymentTransactionsLoading,
isFetching: isPaymentTransactionFetching,
data: paymentTransactions,
} = useBillPaymentTransactions(billId, {
enabled: !!billId,
});
// Handles delete bill payment transactions.
const handleDeleteBillPaymentTransactons = ({ bill_payment_id }) => {
openAlert('payment-made-delete', {
paymentMadeId: bill_payment_id,
});
};
// Handles edit bill payment transactions.
const handleEditBillPaymentTransactions = ({ bill_payment_id }) => {
history.push(`/payment-mades/${bill_payment_id}/edit`);
closeDrawer('bill-drawer');
};
return (
<Card>
<DataTable
columns={columns}
data={paymentTransactions}
loading={isPaymentTransactionsLoading}
headerLoading={isPaymentTransactionsLoading}
progressBarLoading={isPaymentTransactionFetching}
TableLoadingRenderer={TableSkeletonRows}
styleName={TableStyle.Constrant}
ContextMenu={ActionsMenu}
payload={{
onDelete: handleDeleteBillPaymentTransactons,
onEdit: handleEditBillPaymentTransactions,
}}
/>
</Card>
);
}
export default compose(
withAlertsActions,
withDrawerActions,
)(BillPaymentTransactionTable);

View File

@@ -0,0 +1,90 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import clsx from 'classnames';
import { Intent, Menu, MenuItem, MenuDivider } from '@blueprintjs/core';
import { safeCallback } from '@/utils';
import { Can, FormatDateCell, Icon } from '@/components';
import { CLASSES } from '@/constants/classes';
import { PaymentMadeAction, AbilitySubject } from '@/constants/abilityOption';
/**
* Table actions menu.
*/
export function ActionsMenu({
row: { original },
payload: { onEdit, onDelete },
}) {
return (
<Menu>
<Can I={PaymentMadeAction.Edit} a={AbilitySubject.PaymentMade}>
<MenuItem
icon={<Icon icon="pen-18" />}
text={intl.get('invoice_transactions.action.edit_transaction')}
onClick={safeCallback(onEdit, original)}
/>
</Can>
<Can I={PaymentMadeAction.Delete} a={AbilitySubject.PaymentMade}>
<MenuDivider />
<MenuItem
text={intl.get('invoice_transactions.action.delete_transaction')}
intent={Intent.DANGER}
onClick={safeCallback(onDelete, original)}
icon={<Icon icon="trash-16" iconSize={16} />}
/>
</Can>
</Menu>
);
}
/**
* Retrieve bill payment transactions table columns.
*/
export const useBillPaymentTransactionsColumns = () => {
return React.useMemo(
() => [
{
id: 'date',
Header: intl.get('payment_date'),
accessor: 'formatted_payment_date',
Cell: FormatDateCell,
width: 110,
className: 'date',
textOverview: true,
},
{
id: 'payment_account_name',
Header: intl.get('bill_transactions.column.deposit_account'),
accessor: 'payment_account_name',
width: 120,
textOverview: true,
},
{
id: 'amount',
Header: intl.get('amount'),
accessor: 'formatted_payment_amount',
align: 'right',
width: 100,
className: clsx(CLASSES.FONT_BOLD),
textOverview: true,
},
{
id: 'payment_number',
Header: intl.get('payment_no'),
accessor: 'payment_number',
width: 100,
className: 'payment_number',
},
{
id: 'reference',
Header: intl.get('reference_no'),
accessor: 'payment_reference_no',
width: 90,
className: 'payment_reference_no',
clickable: true,
textOverview: true,
},
],
[],
);
};

View File

@@ -0,0 +1,84 @@
// @ts-nocheck
import React from 'react';
import {
DataTable,
TableSkeletonRows,
Card,
FormattedMessage as T,
} from '@/components';
import { useLocatedLandedCostColumns, ActionsMenu } from './components';
import { useBillDrawerContext } from './BillDrawerProvider';
import withAlertsActions from '@/containers/Alert/withAlertActions';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { TableStyle } from '@/constants';
import { compose } from '@/utils';
/**
* Located landed cost table.
*/
function LocatedLandedCostTable({
// #withAlertsActions
openAlert,
// #withDialogActions
openDialog,
// #withDrawerActions
openDrawer,
}) {
// Located landed cost table columns.
const columns = useLocatedLandedCostColumns();
// Bill drawer context.
const { transactions, billId } = useBillDrawerContext();
// Handle the transaction delete action.
const handleDeleteTransaction = ({ id }) => {
openAlert('bill-located-cost-delete', { BillId: id });
};
// Handle from transaction link click.
const handleFromTransactionClick = (original) => {
const { from_transaction_type, from_transaction_id } = original;
switch (from_transaction_type) {
case 'Expense':
openDrawer('expense-drawer', { expenseId: from_transaction_id });
break;
case 'Bill':
default:
openDrawer('bill-drawer', { billId: from_transaction_id });
break;
}
};
return (
<div>
<Card>
<DataTable
columns={columns}
data={transactions}
ContextMenu={ActionsMenu}
TableLoadingRenderer={TableSkeletonRows}
styleName={TableStyle.Constrant}
payload={{
onDelete: handleDeleteTransaction,
onFromTranscationClick: handleFromTransactionClick,
}}
/>
</Card>
</div>
);
}
export default compose(
withAlertsActions,
withDialogActions,
withDrawerActions,
)(LocatedLandedCostTable);

View File

@@ -0,0 +1,103 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import clsx from 'classnames';
import { Intent, MenuItem, Menu } from '@blueprintjs/core';
import { safeCallback } from '@/utils';
import { CLASSES } from '@/constants/classes';
import { Icon } from '@/components';
/**
* Actions menu.
*/
export function ActionsMenu({ row: { original }, payload: { onDelete } }) {
return (
<Menu>
<MenuItem
icon={<Icon icon="trash-16" iconSize={16} />}
text={intl.get('delete_transaction')}
intent={Intent.DANGER}
onClick={safeCallback(onDelete, original)}
/>
</Menu>
);
}
/**
* From transaction table cell.
*/
export function FromTransactionCell({
row: { original },
payload: { onFromTranscationClick },
}) {
// Handle the link click
const handleAnchorClick = () => {
onFromTranscationClick && onFromTranscationClick(original);
};
return (
<a href="#" onClick={handleAnchorClick}>
{original.from_transaction_type} {original.from_transaction_id}
</a>
);
}
/**
* Name accessor.
*/
export const NameAccessor = (row) => {
return (
<span className="name">
<LabelName>{row.name}</LabelName>
<LabelDescription>{row.description}</LabelDescription>
</span>
);
};
/**
* Retrieve bill located landed cost table columns.
*/
export function useLocatedLandedCostColumns() {
return React.useMemo(
() => [
{
Header: intl.get('name'),
accessor: NameAccessor,
width: 150,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'formatted_amount',
width: 100,
align: 'right',
textOverview: true,
className: clsx(CLASSES.FONT_BOLD),
},
{
id: 'from_transaction',
Header: intl.get('From transaction'),
Cell: FromTransactionCell,
width: 100,
textOverview: true,
},
{
Header: intl.get('allocation_method'),
accessor: 'allocation_method_formatted',
width: 100,
textOverview: true,
},
],
[],
);
}
const LabelName = styled.div``;
const LabelDescription = styled.div`
font-size: 12px;
margin-top: 2px;
display: block;
opacity: 0.75;
`;

View File

@@ -0,0 +1,33 @@
// @ts-nocheck
import React from 'react';
import { Drawer, DrawerSuspense } from '@/components';
import withDrawers from '@/containers/Drawer/withDrawers';
import { compose } from '@/utils';
const BillDrawerContent = React.lazy(() => import('./BillDrawerContent'));
/**
* Bill drawer.
*/
function BillDrawer({
name,
// #withDrawer
isOpen,
payload: { billId },
}) {
return (
<Drawer
isOpen={isOpen}
name={name}
style={{ minWidth: '700px', maxWidth: '900px' }}
size={'65%'}
>
<DrawerSuspense>
<BillDrawerContent billId={billId} />
</DrawerSuspense>
</Drawer>
);
}
export default compose(withDrawers())(BillDrawer);

View File

@@ -0,0 +1,161 @@
// @ts-nocheck
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import {
Button,
Popover,
PopoverInteractionKind,
Position,
MenuItem,
Menu,
Intent,
Tag,
} from '@blueprintjs/core';
import {
FormatNumberCell,
TextOverviewTooltipCell,
FormattedMessage as T,
Choose,
Icon,
} from '@/components';
import { getColumnWidth } from '@/utils';
import { useBillDrawerContext } from './BillDrawerProvider';
/**
* Retrieve bill readonly details entries table columns.
*/
export const useBillReadonlyEntriesTableColumns = () => {
const {
bill: { entries },
} = useBillDrawerContext();
return React.useMemo(
() => [
{
Header: intl.get('product_and_service'),
accessor: 'item.name',
Cell: TextOverviewTooltipCell,
width: 150,
className: 'item',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('description'),
accessor: 'description',
Cell: TextOverviewTooltipCell,
className: 'description',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('quantity'),
accessor: 'quantity',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'quantity', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('rate'),
accessor: 'rate',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'rate', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
{
Header: intl.get('amount'),
accessor: 'amount',
Cell: FormatNumberCell,
width: getColumnWidth(entries, 'amount', {
minWidth: 60,
magicSpacing: 5,
}),
align: 'right',
disableSortBy: true,
textOverview: true,
},
],
[],
);
};
/**
* Bill details status.
* @returns {React.JSX}
*/
export function BillDetailsStatus({ bill }) {
return (
<Choose>
<Choose.When condition={bill.is_fully_paid && bill.is_open}>
<StatusTag intent={Intent.SUCCESS} round={true}>
<T id={'paid'} />
</StatusTag>
</Choose.When>
<Choose.When condition={bill.is_open}>
<Choose>
<Choose.When condition={bill.is_overdue}>
<StatusTag intent={Intent.WARNING} round={true}>
<T id={'overdue'} />
</StatusTag>
</Choose.When>
<Choose.Otherwise>
<StatusTag intent={Intent.PRIMARY} round={true}>
<T id={'due'} />
</StatusTag>
</Choose.Otherwise>
</Choose>
</Choose.When>
<Choose.Otherwise>
<StatusTag round={true} minimal={true}>
<T id={'draft'} />
</StatusTag>
</Choose.Otherwise>
</Choose>
);
}
export const BillMenuItem = ({
payload: { onConvert, onAllocateLandedCost },
}) => {
return (
<Popover
minimal={true}
interactionKind={PopoverInteractionKind.CLICK}
position={Position.BOTTOM_LEFT}
modifiers={{
offset: { offset: '0, 4' },
}}
content={
<Menu>
<MenuItem
onClick={onAllocateLandedCost}
text={<T id={'bill.allocate_landed_coast'} />}
/>
<MenuItem
onClick={onConvert}
text={<T id={'bill.convert_to_credit_note'} />}
/>
</Menu>
}
>
<Button icon={<Icon icon="more-vert" iconSize={16} />} minimal={true} />
</Popover>
);
};
const StatusTag = styled(Tag)`
min-width: 65px;
text-align: center;
`;