feat: bulk transcations delete

This commit is contained in:
Ahmed Bouhuolia
2025-11-03 21:40:24 +02:00
parent 8161439365
commit a0bc9db9a6
107 changed files with 2213 additions and 156 deletions

View File

@@ -12,6 +12,10 @@ const CancelBadDebtAlert = React.lazy(
() => import('@/containers/Alerts/Invoices/CancelBadDebtAlert'),
);
const InvoiceBulkDeleteAlert = React.lazy(
() => import('@/containers/Alerts/Invoices/InvoiceBulkDeleteAlert'),
);
/**
* Invoices alert.
*/
@@ -19,4 +23,5 @@ export default [
{ name: 'invoice-delete', component: InvoiceDeleteAlert },
{ name: 'invoice-deliver', component: InvoiceDeliverAlert },
{ name: 'cancel-bad-debt', component: CancelBadDebtAlert },
{ name: 'invoices-bulk-delete', component: InvoiceBulkDeleteAlert },
];

View File

@@ -34,11 +34,13 @@ import withInvoices from './withInvoices';
import withInvoiceActions from './withInvoiceActions';
import withSettings from '@/containers/Settings/withSettings';
import withSettingsActions from '@/containers/Settings/withSettingsActions';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { compose } from '@/utils';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import { DialogsName } from '@/constants/dialogs';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { DRAWERS } from '@/constants/drawers';
import { isEmpty } from 'lodash';
/**
* Invoices table actions bar.
@@ -49,6 +51,7 @@ function InvoiceActionsBar({
// #withInvoices
invoicesFilterRoles,
invoicesSelectedRows = [],
// #withSettings
invoicesTableSize,
@@ -61,6 +64,9 @@ function InvoiceActionsBar({
// #withDrawerActions
openDrawer,
// #withAlertActions
openAlert,
}) {
const history = useHistory();
@@ -112,6 +118,11 @@ function InvoiceActionsBar({
openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'SaleInvoice' });
};
// Handle bulk invoices delete.
const handleBulkDelete = () => {
openAlert('invoices-bulk-delete', { invoicesIds: invoicesSelectedRows });
};
return (
<DashboardActionsBar>
<NavbarGroup>
@@ -145,12 +156,13 @@ function InvoiceActionsBar({
<NavbarDivider />
<If condition={false}>
<If condition={!isEmpty(invoicesSelectedRows)}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}
text={<T id={'delete'} />}
intent={Intent.DANGER}
onClick={handleBulkDelete}
/>
</If>
<Button
@@ -211,8 +223,10 @@ function InvoiceActionsBar({
export default compose(
withInvoiceActions,
withSettingsActions,
withAlertActions,
withInvoices(({ invoicesTableState }) => ({
invoicesFilterRoles: invoicesTableState.filterRoles,
invoicesSelectedRows: invoicesTableState?.selectedRows || [],
})),
withSettings(({ invoiceSettings }) => ({
invoicesTableSize: invoiceSettings?.tableSize,

View File

@@ -34,6 +34,7 @@ import { DialogsName } from '@/constants/dialogs';
function InvoicesDataTable({
// #withInvoicesActions
setInvoicesTableState,
setInvoicesSelectedRows,
// #withInvoices
invoicesTableState,
@@ -125,6 +126,15 @@ function InvoicesDataTable({
[setInvoicesTableState],
);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
(selectedFlatRows) => {
const selectedIds = selectedFlatRows?.map((row) => row.original.id) || [];
setInvoicesSelectedRows(selectedIds);
},
[setInvoicesSelectedRows],
);
// Display invoice empty status instead of the table.
if (isEmptyStatus) {
return <InvoicesEmptyStatus />;
@@ -141,6 +151,7 @@ function InvoicesDataTable({
onFetchData={handleDataTableFetchData}
manualSortBy={true}
selectionColumn={true}
onSelectedRowsChange={handleSelectedRowsChange}
noInitialFetch={true}
sticky={true}
pagination={true}
@@ -149,6 +160,7 @@ function InvoicesDataTable({
pagesCount={pagination.pagesCount}
autoResetSortBy={false}
autoResetPage={false}
autoResetSelectedRows={false}
TableLoadingRenderer={TableSkeletonRows}
TableHeaderSkeletonRenderer={TableSkeletonHeader}
ContextMenu={ActionsMenu}

View File

@@ -1,12 +1,6 @@
// @ts-nocheck
import React from 'react';
import {
Intent,
Tag,
Menu,
MenuItem,
MenuDivider,
} from '@blueprintjs/core';
import { Intent, Tag, Menu, MenuItem, MenuDivider } from '@blueprintjs/core';
import intl from 'react-intl-universal';
import clsx from 'classnames';
import { CLASSES } from '@/constants/classes';
@@ -30,36 +24,33 @@ export function InvoiceStatus({ invoice }) {
return (
<Choose>
<Choose.When condition={invoice.is_fully_paid && invoice.is_delivered}>
<Tag intent={Intent.SUCCESS} round>
<Tag intent={Intent.SUCCESS} round minimal>
<T id={'paid'} />
</Tag>
</Choose.When>
<Choose.When condition={invoice.is_delivered}>
<Choose>
<Choose.When condition={invoice.is_overdue}>
<Tag intent={Intent.DANGER} round>
{intl.get('overdue_by', { overdue: invoice.overdue_days })}
</Tag>
</Choose.When>
<Choose.Otherwise>
<Tag intent={Intent.WARNING} round>
{intl.get('due_in', { due: invoice.remaining_days })}
</Tag>
</Choose.Otherwise>
</Choose>
<Choose.When condition={invoice.is_delivered && invoice.is_overdue}>
<Tag intent={Intent.DANGER} round minimal>
{intl.get('overdue_by', { overdue: invoice.overdue_days })}
</Tag>
</Choose.When>
<If condition={invoice.is_partially_paid}>
<Tag intent={Intent.PRIMARY} round>
{intl.get('day_partially_paid', {
due: formattedAmount(invoice.due_amount, invoice.currency_code),
})}
</Tag>
</If>
<Choose.When condition={invoice.is_delivered && !invoice.is_overdue}>
<Tag intent={Intent.WARNING} round minimal>
{intl.get('due_in', { due: invoice.remaining_days })}
</Tag>
</Choose.When>
<Choose.When condition={invoice.is_partially_paid}>
<Tag intent={Intent.PRIMARY} round minimal>
{intl.get('day_partially_paid', {
due: formattedAmount(invoice.due_amount, invoice.currency_code),
})}
</Tag>
</Choose.When>
<Choose.Otherwise>
<Tag round>
<Tag round minimal>
<T id={'draft'} />
</Tag>
</Choose.Otherwise>

View File

@@ -2,12 +2,14 @@
import { connect } from 'react-redux';
import {
setInvoicesTableState,
resetInvoicesTableState
resetInvoicesTableState,
setInvoicesSelectedRows,
} from '@/store/Invoice/invoices.actions';
const mapDipatchToProps = (dispatch) => ({
setInvoicesTableState: (queries) => dispatch(setInvoicesTableState(queries)),
resetInvoicesTableState: () => dispatch(resetInvoicesTableState()),
setInvoicesSelectedRows: (selectedRows) => dispatch(setInvoicesSelectedRows(selectedRows)),
});
export default connect(null, mapDipatchToProps);

View File

@@ -13,6 +13,7 @@ export default (mapState) => {
const mapped = {
invoicesTableState: getInvoicesTableState(state, props),
invoicesTableStateChanged: isInvoicesTableStateChanged(state, props),
invoicesSelectedRows: state.invoices?.selectedRows || [],
};
return mapState ? mapState(mapped, state, props) : mapped;
};