diff --git a/client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js b/client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js
new file mode 100644
index 000000000..3aba617c8
--- /dev/null
+++ b/client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js
@@ -0,0 +1,89 @@
+import React, { useCallback, useState } from 'react';
+import {
+ FormattedMessage as T,
+ FormattedHTMLMessage,
+ useIntl,
+} from 'react-intl';
+import { Intent, Alert } from '@blueprintjs/core';
+import { queryCache } from 'react-query';
+import { AppToaster } from 'components';
+
+import { handleDeleteErrors } from 'containers/Sales/Invoice/components';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+import withInvoiceActions from 'containers/Sales/Invoice/withInvoiceActions';
+
+import { compose } from 'utils';
+
+/**
+ * Invoice delete alert.
+ */
+function InvoiceDeleteAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { invoiceId },
+
+ // #withInvoiceActions
+ requestDeleteInvoice,
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { formatMessage } = useIntl();
+ const [isLoading, setLoading] = useState(false);
+
+ // handle cancel delete invoice alert.
+ const handleCancelDeleteAlert = () => {
+ closeAlert(name);
+ };
+
+ // handleConfirm delete invoice
+ const handleConfirmInvoiceDelete = useCallback(() => {
+ setLoading(true);
+ requestDeleteInvoice(invoiceId)
+ .then(() => {
+ AppToaster.show({
+ message: formatMessage({
+ id: 'the_invoice_has_been_deleted_successfully',
+ }),
+ intent: Intent.SUCCESS,
+ });
+ queryCache.invalidateQueries('invoices-table');
+ })
+ .catch((errors) => {
+ handleDeleteErrors(errors);
+ })
+ .finally(() => {
+ closeAlert(name);
+ setLoading(false);
+ });
+ }, [invoiceId, requestDeleteInvoice, formatMessage]);
+
+ return (
+ }
+ confirmButtonText={}
+ icon="trash"
+ intent={Intent.DANGER}
+ isOpen={isOpen}
+ onCancel={handleCancelDeleteAlert}
+ onConfirm={handleConfirmInvoiceDelete}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+ withInvoiceActions,
+)(InvoiceDeleteAlert);
diff --git a/client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js b/client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js
new file mode 100644
index 000000000..d8f3f8263
--- /dev/null
+++ b/client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js
@@ -0,0 +1,78 @@
+import React, { useCallback, useState } from 'react';
+import { FormattedMessage as T, useIntl } from 'react-intl';
+import { Intent, Alert } from '@blueprintjs/core';
+import { queryCache } from 'react-query';
+import { AppToaster } from 'components';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+import withInvoiceActions from 'containers/Sales/Invoice/withInvoiceActions';
+
+import { compose } from 'utils';
+
+/**
+ * Invoice alert.
+ */
+function InvoiceDeliverAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { invoiceId },
+
+ // #withInvoiceActions
+ requestDeliverInvoice,
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ const { formatMessage } = useIntl();
+ const [isLoading, setLoading] = useState(false);
+
+ // handle cancel delete deliver alert.
+ const handleCancelDeleteAlert = () => {
+ closeAlert(name);
+ };
+
+ // Handle confirm invoice deliver.
+ const handleConfirmInvoiceDeliver = useCallback(() => {
+ setLoading(true);
+ requestDeliverInvoice(invoiceId)
+ .then(() => {
+ AppToaster.show({
+ message: formatMessage({
+ id: 'the_invoice_has_been_delivered_successfully',
+ }),
+ intent: Intent.SUCCESS,
+ });
+ queryCache.invalidateQueries('invoices-table');
+ })
+ .catch((error) => {})
+ .finally(() => {
+ closeAlert(name);
+ setLoading(false);
+ });
+ }, [invoiceId, requestDeliverInvoice, formatMessage]);
+
+ return (
+ }
+ confirmButtonText={}
+ intent={Intent.WARNING}
+ isOpen={isOpen}
+ onCancel={handleCancelDeleteAlert}
+ onConfirm={handleConfirmInvoiceDeliver}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+ withInvoiceActions,
+)(InvoiceDeliverAlert);
diff --git a/client/src/containers/Sales/Invoice/InvoicesAlerts.js b/client/src/containers/Sales/Invoice/InvoicesAlerts.js
new file mode 100644
index 000000000..024b4a819
--- /dev/null
+++ b/client/src/containers/Sales/Invoice/InvoicesAlerts.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import InvoiceDeleteAlert from 'containers/Alerts/Invoices/InvoiceDeleteAlert';
+import InvoiceDeliverAlert from 'containers/Alerts/Invoices/InvoiceDeliverAlert';
+
+/**
+ * Invoices alert.
+ */
+export default function ItemsAlerts() {
+ return (
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Sales/Invoice/InvoicesList.js b/client/src/containers/Sales/Invoice/InvoicesList.js
index cede77ee2..d20dee75f 100644
--- a/client/src/containers/Sales/Invoice/InvoicesList.js
+++ b/client/src/containers/Sales/Invoice/InvoicesList.js
@@ -1,25 +1,24 @@
import React, { useEffect, useCallback, useMemo, useState } from 'react';
import { Route, Switch, useHistory } from 'react-router-dom';
-import { useQuery, queryCache } from 'react-query';
-import { Alert, Intent } from '@blueprintjs/core';
+import { useQuery} from 'react-query';
import 'style/pages/SaleInvoice/List.scss';
-import AppToaster from 'components/AppToaster';
-import { FormattedMessage as T, useIntl } from 'react-intl'
-;
+import { FormattedMessage as T, useIntl } from 'react-intl';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import InvoicesDataTable from './InvoicesDataTable';
import InvoiceActionsBar from './InvoiceActionsBar';
import InvoiceViewTabs from './InvoiceViewTabs';
+import InvoicesAlerts from './InvoicesAlerts';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withResourceActions from 'containers/Resources/withResourcesActions';
import withInvoices from './withInvoices';
-import withInvoiceActions from './withInvoiceActions';
+import withInvoiceActions from 'containers/Sales/Invoice/withInvoiceActions';
import withViewsActions from 'containers/Views/withViewsActions';
+import withAlertsActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
@@ -38,17 +37,17 @@ function InvoicesList({
invoicesTableQuery,
invoicesViews,
+ // #withAlertsActions.
+ openAlert,
+
//#withInvoiceActions
requestFetchInvoiceTable,
- requestDeleteInvoice,
- requestDeliverInvoice,
+
addInvoiceTableQueries,
}) {
const history = useHistory();
const { formatMessage } = useIntl();
- const [deleteInvoice, setDeleteInvoice] = useState(false);
- const [deliverInvoice, setDeliverInvoice] = useState(false);
- const [selectedRows, setSelectedRows] = useState([]);
+ const [selectedRows, setSelectedRows] = useState([]);
useEffect(() => {
changePageTitle(formatMessage({ id: 'invoices_list' }));
@@ -68,89 +67,27 @@ function InvoicesList({
['invoices-table', invoicesTableQuery],
(key, query) => requestFetchInvoiceTable({ ...query }),
);
- //handle dalete Invoice
+ //handle delete Invoice
const handleDeleteInvoice = useCallback(
- (invoice) => {
- setDeleteInvoice(invoice);
+ ({ id }) => {
+ openAlert('invoice-delete', { invoiceId: id });
},
- [setDeleteInvoice],
+ [openAlert],
);
- // handle cancel Invoice
- const handleCancelInvoiceDelete = useCallback(() => {
- setDeleteInvoice(false);
- }, [setDeleteInvoice]);
-
- const handleDeleteErrors = (errors) => {
- if (
- errors.find(
- (error) => error.type === 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES',
- )
- ) {
- AppToaster.show({
- message: formatMessage({
- id: 'the_invoice_cannot_be_deleted',
- }),
- intent: Intent.DANGER,
- });
- }
- };
-
- // handleConfirm delete invoice
- const handleConfirmInvoiceDelete = useCallback(() => {
- requestDeleteInvoice(deleteInvoice.id)
- .then(() => {
- setDeleteInvoice(false);
- AppToaster.show({
- message: formatMessage({
- id: 'the_invoice_has_been_deleted_successfully',
- }),
- intent: Intent.SUCCESS,
- });
- })
- .catch((errors) => {
- handleDeleteErrors(errors);
- setDeleteInvoice(false);
- });
- }, [deleteInvoice, requestDeleteInvoice, formatMessage]);
-
// Handle cancel/confirm invoice deliver.
- const handleDeliverInvoice = useCallback((invoice) => {
- setDeliverInvoice(invoice);
- }, []);
+ const handleDeliverInvoice = useCallback(
+ ({id}) => {
+ openAlert('invoice-deliver', { invoiceId: id });
+ },
+ [openAlert],
+ );
- // Handle cancel deliver invoice alert.
- const handleCancelDeliverInvoice = useCallback(() => {
- setDeliverInvoice(false);
- }, []);
-
- // Handle confirm invoiec deliver.
- const handleConfirmInvoiceDeliver = useCallback(() => {
- requestDeliverInvoice(deliverInvoice.id)
- .then(() => {
- setDeliverInvoice(false);
- AppToaster.show({
- message: formatMessage({
- id: 'the_invoice_has_been_delivered_successfully',
- }),
- intent: Intent.SUCCESS,
- });
- queryCache.invalidateQueries('invoices-table');
- })
- .catch((error) => {
- // setDeliverInvoice(false);
- });
- }, [deliverInvoice, requestDeliverInvoice, formatMessage]);
const handleEditInvoice = useCallback((invoice) => {
history.push(`/invoices/${invoice.id}/edit`);
});
- // Calculates the selected rows count.
- const selectedRowsCount = useMemo(() => Object.values(selectedRows).length, [
- selectedRows,
- ]);
-
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, []);
@@ -167,7 +104,6 @@ function InvoicesList({
name={'sales-invoices-list'}
>
@@ -187,31 +123,7 @@ function InvoicesList({
- }
- confirmButtonText={}
- icon={'trash'}
- intent={Intent.DANGER}
- isOpen={deleteInvoice}
- onCancel={handleCancelInvoiceDelete}
- onConfirm={handleConfirmInvoiceDelete}
- >
-
-
-
-
- }
- confirmButtonText={}
- intent={Intent.WARNING}
- isOpen={deliverInvoice}
- onCancel={handleCancelDeliverInvoice}
- onConfirm={handleConfirmInvoiceDeliver}
- >
-
-
-
-
+
);
@@ -225,4 +137,5 @@ export default compose(
withInvoices(({ invoicesTableQuery }) => ({
invoicesTableQuery,
})),
+ withAlertsActions,
)(InvoicesList);
diff --git a/client/src/containers/Sales/Invoice/components.js b/client/src/containers/Sales/Invoice/components.js
index ade11fa9e..e4f31a5e4 100644
--- a/client/src/containers/Sales/Invoice/components.js
+++ b/client/src/containers/Sales/Invoice/components.js
@@ -2,6 +2,8 @@ import React from 'react';
import { Intent, Tag, ProgressBar } from '@blueprintjs/core';
import { Choose, If, Icon } from 'components';
import { FormattedMessage as T, useIntl } from 'react-intl';
+import { AppToaster } from 'components';
+import { formatMessage } from 'services/intl';
const calculateStatus = (paymentAmount, balanceAmount) =>
paymentAmount / balanceAmount;
@@ -60,3 +62,18 @@ export const statusAccessor = (row) => {
);
};
+
+export const handleDeleteErrors = (errors) => {
+ if (
+ errors.find(
+ (error) => error.type === 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES',
+ )
+ ) {
+ AppToaster.show({
+ message: formatMessage({
+ id: 'the_invoice_cannot_be_deleted',
+ }),
+ intent: Intent.DANGER,
+ });
+ }
+};