From 91b848f158d80f98cbe0f7789fb4443c24521eae Mon Sep 17 00:00:00 2001
From: elforjani13 <39470382+elforjani13@users.noreply.github.com>
Date: Mon, 1 Nov 2021 20:24:01 +0200
Subject: [PATCH 1/3] feat: Bad Debt.
---
src/common/moreVertOptions.js | 12 ++
src/components/DialogsContainer.js | 2 +
src/components/MoreVertMenutItems.js | 46 +++++++
src/components/index.js | 4 +-
.../Alerts/Invoices/BadDebtAlert.js | 65 ++++++++++
.../BadDebtDialog/BadDebtDialogContent.js | 20 +++
.../Dialogs/BadDebtDialog/BadDebtForm.js | 86 +++++++++++++
.../BadDebtDialog/BadDebtForm.schema.js | 17 +++
.../BadDebtDialog/BadDebtFormContent.js | 17 +++
.../BadDebtDialog/BadDebtFormFields.js | 121 ++++++++++++++++++
.../BadDebtFormFloatingActions.js | 48 +++++++
.../BadDebtDialog/BadDebtFormProvider.js | 46 +++++++
src/containers/Dialogs/BadDebtDialog/index.js | 29 +++++
src/containers/Dialogs/BadDebtDialog/utils.js | 17 +++
.../Drawers/BillDrawer/BillDrawerDetails.js | 5 +
.../InvoiceDetailDrawer/BadDebtMenuItem.js | 70 ++++++++++
.../InvoiceDetailDrawer/InvoiceDetail.js | 5 +
.../InvoiceDetailActionsBar.js | 24 +++-
.../Sales/Invoices/InvoicesAlerts.js | 5 +
src/hooks/query/invoices.js | 35 +++++
src/hooks/query/types.js | 5 +-
src/lang/ar/index.json | 13 +-
src/lang/en/index.json | 12 +-
src/static/json/icons.js | 8 +-
src/style/pages/BadDebt/BadDebtDialog.scss | 34 +++++
25 files changed, 734 insertions(+), 12 deletions(-)
create mode 100644 src/common/moreVertOptions.js
create mode 100644 src/components/MoreVertMenutItems.js
create mode 100644 src/containers/Alerts/Invoices/BadDebtAlert.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/BadDebtDialogContent.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/BadDebtForm.schema.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/BadDebtFormContent.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/BadDebtFormFloatingActions.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/BadDebtFormProvider.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/index.js
create mode 100644 src/containers/Dialogs/BadDebtDialog/utils.js
create mode 100644 src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js
create mode 100644 src/style/pages/BadDebt/BadDebtDialog.scss
diff --git a/src/common/moreVertOptions.js b/src/common/moreVertOptions.js
new file mode 100644
index 000000000..62a15a755
--- /dev/null
+++ b/src/common/moreVertOptions.js
@@ -0,0 +1,12 @@
+import intl from 'react-intl-universal';
+
+export const moreVertOptions = [
+ {
+ name: intl.get('badDebt.label'),
+ value: 'bad debt',
+ },
+ {
+ name: intl.get('badDebt.label_cancel_bad_debt'),
+ value: 'cancel bad debt',
+ },
+];
diff --git a/src/components/DialogsContainer.js b/src/components/DialogsContainer.js
index 07c00ca6f..f1e803fff 100644
--- a/src/components/DialogsContainer.js
+++ b/src/components/DialogsContainer.js
@@ -19,6 +19,7 @@ import EstimatePdfPreviewDialog from 'containers/Dialogs/EstimatePdfPreviewDialo
import ReceiptPdfPreviewDialog from '../containers/Dialogs/ReceiptPdfPreviewDialog';
import MoneyInDialog from '../containers/Dialogs/MoneyInDialog';
import MoneyOutDialog from '../containers/Dialogs/MoneyOutDialog';
+import BadDebtDialog from '../containers/Dialogs/BadDebtDialog';
/**
* Dialogs container.
@@ -44,6 +45,7 @@ export default function DialogsContainer() {
+
);
}
diff --git a/src/components/MoreVertMenutItems.js b/src/components/MoreVertMenutItems.js
new file mode 100644
index 000000000..9282f33c1
--- /dev/null
+++ b/src/components/MoreVertMenutItems.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import {
+ Button,
+ PopoverInteractionKind,
+ MenuItem,
+ Position,
+} from '@blueprintjs/core';
+
+import { Select } from '@blueprintjs/select';
+import { Icon } from 'components';
+
+function MoreVertMenutItems({ text, items, onItemSelect, buttonProps }) {
+ // Menu items renderer.
+ const itemsRenderer = (item, { handleClick, modifiers, query }) => (
+
+ );
+ const handleMenuSelect = (type) => {
+ onItemSelect && onItemSelect(type);
+ };
+
+ return (
+
+ );
+}
+
+export default MoreVertMenutItems;
diff --git a/src/components/index.js b/src/components/index.js
index 6d78330e3..36ad2797e 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -61,6 +61,7 @@ import Card from './Card';
import AvaterCell from './AvaterCell';
import { ItemsMultiSelect } from './Items';
+import MoreVertMenutItems from './MoreVertMenutItems';
export * from './Menu';
export * from './AdvancedFilter/AdvancedFilterDropdown';
@@ -82,7 +83,7 @@ export * from './MultiSelectTaggable';
export * from './Utils/FormatNumber';
export * from './Utils/FormatDate';
export * from './BankAccounts';
-export * from './IntersectionObserver'
+export * from './IntersectionObserver';
const Hint = FieldHint;
@@ -154,4 +155,5 @@ export {
ItemsMultiSelect,
Card,
AvaterCell,
+ MoreVertMenutItems,
};
diff --git a/src/containers/Alerts/Invoices/BadDebtAlert.js b/src/containers/Alerts/Invoices/BadDebtAlert.js
new file mode 100644
index 000000000..b3d05c083
--- /dev/null
+++ b/src/containers/Alerts/Invoices/BadDebtAlert.js
@@ -0,0 +1,65 @@
+import React from 'react';
+import { FormattedMessage as T } from 'components';
+import intl from 'react-intl-universal';
+import { Intent, Alert } from '@blueprintjs/core';
+import { AppToaster } from 'components';
+import { useCancelBadDebt } from 'hooks/query';
+
+import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
+import withAlertActions from 'containers/Alert/withAlertActions';
+
+import { compose } from 'utils';
+
+/**
+ * bad debt alert.
+ */
+function BadDebtAlert({
+ name,
+
+ // #withAlertStoreConnect
+ isOpen,
+ payload: { invoiceId },
+
+ // #withAlertActions
+ closeAlert,
+}) {
+ // handle cancel alert.
+ const handleCancel = () => {
+ closeAlert(name);
+ };
+
+ const { mutateAsync: cancelBadDebtMutate, isLoading } = useCancelBadDebt();
+
+ // handleConfirm alert.
+ const handleConfirm = () => {
+ cancelBadDebtMutate(invoiceId)
+ .then(() => {
+ AppToaster.show({
+ message: intl.get('the_invoice_has_been_deleted_successfully'),
+ intent: Intent.SUCCESS,
+ });
+ })
+ .catch(() => {})
+ .finally(() => {
+ closeAlert(name);
+ });
+ };
+
+ return (
+ }
+ confirmButtonText={}
+ intent={Intent.WARNING}
+ isOpen={isOpen}
+ onCancel={handleCancel}
+ onConfirm={handleConfirm}
+ loading={isLoading}
+ >
+
+
+
+
+ );
+}
+
+export default compose(withAlertStoreConnect(), withAlertActions)(BadDebtAlert);
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtDialogContent.js b/src/containers/Dialogs/BadDebtDialog/BadDebtDialogContent.js
new file mode 100644
index 000000000..1e4b205b0
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtDialogContent.js
@@ -0,0 +1,20 @@
+import React from 'react';
+
+import 'style/pages/BadDebt/BadDebtDialog.scss';
+import { BadDebtFormProvider } from './BadDebtFormProvider';
+import BadDebtForm from './BadDebtForm';
+
+/**
+ * Bad debt dialog content.
+ */
+export default function BadDebtDialogContent({
+ // #ownProps
+ dialogName,
+ invoice,
+}) {
+ return (
+
+
+
+ );
+}
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
new file mode 100644
index 000000000..5b579db28
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
@@ -0,0 +1,86 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+
+import { Formik } from 'formik';
+import { Intent } from '@blueprintjs/core';
+import { omit } from 'lodash';
+
+import { AppToaster } from 'components';
+import { CreateBadDebtFormSchema } from './BadDebtForm.schema';
+import { transformErrors } from './utils';
+
+import BadDebtFormContent from './BadDebtFormContent';
+
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
+
+import { useBadDebtContext } from './BadDebtFormProvider';
+
+import { compose } from 'utils';
+
+const defaultInitialValues = {
+ expense_account_id: '',
+ reason: '',
+ amount: '',
+};
+
+function BadDebtForm({
+ // #withDialogActions
+ closeDialog,
+
+ // #withCurrentOrganization
+ organization: { base_currency },
+}) {
+ const { invoice, dialogName, createBadDebtMutate, cancelBadDebtMutate } =
+ useBadDebtContext();
+
+ // Initial form values
+ const initialValues = {
+ ...defaultInitialValues,
+ currency_code: base_currency,
+ amount: invoice.due_amount,
+ };
+
+ // Handles the form submit.
+ const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
+ const form = {
+ ...omit(values, ['currency_code']),
+ };
+
+ // Handle request response success.
+ const onSuccess = (response) => {
+ AppToaster.show({
+ message: intl.get('badDebt_success_message'),
+ intent: Intent.SUCCESS,
+ });
+ closeDialog(dialogName);
+ };
+
+ // Handle request response errors.
+ const onError = ({
+ response: {
+ data: { errors },
+ },
+ }) => {
+ if (errors) {
+ transformErrors(errors, { setErrors });
+ }
+ setSubmitting(false);
+ };
+ createBadDebtMutate([invoice.id, form]).then(onSuccess).catch(onError);
+ };
+
+ return (
+
+ );
+}
+
+export default compose(
+ withDialogActions,
+ withCurrentOrganization(),
+)(BadDebtForm);
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtForm.schema.js b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.schema.js
new file mode 100644
index 000000000..dc3d00f61
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.schema.js
@@ -0,0 +1,17 @@
+import * as Yup from 'yup';
+import intl from 'react-intl-universal';
+import { DATATYPES_LENGTH } from 'common/dataTypes';
+
+const Schema = Yup.object().shape({
+ expense_account_id: Yup.number()
+ .required()
+ .label(intl.get('expense_account_id')),
+ amount: Yup.number().required().label(intl.get('amount')),
+ reason: Yup.string()
+ .required()
+ .min(3)
+ .max(DATATYPES_LENGTH.TEXT)
+ .label(intl.get('reason')),
+});
+
+export const CreateBadDebtFormSchema = Schema;
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtFormContent.js b/src/containers/Dialogs/BadDebtDialog/BadDebtFormContent.js
new file mode 100644
index 000000000..568c04a8c
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtFormContent.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import { Form } from 'formik';
+
+import BadDebtFormFields from './BadDebtFormFields';
+import BadDebtFormFloatingActions from './BadDebtFormFloatingActions';
+
+/**
+ * Bad debt form content.
+ */
+export default function BadDebtFormContent() {
+ return (
+
+ );
+}
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js b/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js
new file mode 100644
index 000000000..2d52b4a3c
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js
@@ -0,0 +1,121 @@
+import React from 'react';
+import { FastField, ErrorMessage } from 'formik';
+import { FormattedMessage as T } from 'components';
+
+import { useAutofocus } from 'hooks';
+import {
+ Classes,
+ FormGroup,
+ TextArea,
+ ControlGroup,
+ Callout,
+ Intent,
+} from '@blueprintjs/core';
+import classNames from 'classnames';
+import { CLASSES } from 'common/classes';
+import { ACCOUNT_TYPE } from 'common/accountTypes';
+import { inputIntent } from 'utils';
+import {
+ AccountsSuggestField,
+ InputPrependText,
+ MoneyInputGroup,
+ FieldRequiredHint,
+} from 'components';
+
+import { useBadDebtContext } from './BadDebtFormProvider';
+
+/**
+ * Bad debt form fields.
+ */
+function BadDebtFormFields() {
+ const amountfieldRef = useAutofocus();
+
+ const { accounts } = useBadDebtContext();
+
+ return (
+
+
+
+
+
+
+
+ {/*------------ Written-off amount -----------*/}
+
+ {({
+ form: { values, setFieldValue },
+ field: { value },
+ meta: { error, touched },
+ }) => (
+ }
+ labelInfo={}
+ className={classNames('form-group--amount', CLASSES.FILL)}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ >
+
+
+
+ {
+ setFieldValue('amount', amount);
+ }}
+ intent={inputIntent({ error, touched })}
+ disabled={amountfieldRef}
+ />
+
+
+ )}
+
+ {/*------------ Expense account -----------*/}
+
+ {({ form, field: { value }, meta: { error, touched } }) => (
+ }
+ className={classNames(
+ 'form-group--expense_account_id',
+ 'form-group--select-list',
+ CLASSES.FILL,
+ )}
+ labelInfo={}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ >
+
+ form.setFieldValue('expense_account_id', id)
+ }
+ filterByTypes={[ACCOUNT_TYPE.EXPENSE]}
+ />
+
+ )}
+
+ {/*------------ reason -----------*/}
+
+ {({ field, meta: { error, touched } }) => (
+ }
+ labelInfo={}
+ className={'form-group--reason'}
+ intent={inputIntent({ error, touched })}
+ helperText={}
+ >
+
+
+ )}
+
+
+ );
+}
+
+export default BadDebtFormFields;
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtFormFloatingActions.js b/src/containers/Dialogs/BadDebtDialog/BadDebtFormFloatingActions.js
new file mode 100644
index 000000000..fe50fda63
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtFormFloatingActions.js
@@ -0,0 +1,48 @@
+import React from 'react';
+import { Intent, Button, Classes } from '@blueprintjs/core';
+import { useFormikContext } from 'formik';
+import { FormattedMessage as T } from 'components';
+
+import { useBadDebtContext } from './BadDebtFormProvider';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import { compose } from 'utils';
+
+
+/**
+ * Bad bebt form floating actions.
+ */
+function BadDebtFormFloatingActions({
+ // #withDialogActions
+ closeDialog,
+}) {
+ // bad debt invoice dialog context.
+ const { dialogName } = useBadDebtContext();
+
+ // Formik context.
+ const { isSubmitting } = useFormikContext();
+
+ // Handle close button click.
+ const handleCancelBtnClick = () => {
+ closeDialog(dialogName);
+ };
+
+ return (
+
+ );
+}
+
+export default compose(withDialogActions)(BadDebtFormFloatingActions);
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtFormProvider.js b/src/containers/Dialogs/BadDebtDialog/BadDebtFormProvider.js
new file mode 100644
index 000000000..acc7f36b8
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtFormProvider.js
@@ -0,0 +1,46 @@
+import React from 'react';
+
+import { DialogContent } from 'components';
+import {
+ useAccounts,
+ useInvoice,
+ useCreateBadDebt,
+ useCancelBadDebt,
+} from 'hooks/query';
+
+const BadDebtContext = React.createContext();
+
+/**
+ * Bad debt provider.
+ */
+function BadDebtFormProvider({ invoiceId, dialogName, ...props }) {
+ // Handle fetch accounts data.
+ const { data: accounts, isLoading: isAccountsLoading } = useAccounts();
+
+ // Handle fetch invoice data.
+ const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(invoiceId, {
+ enabled: !!invoiceId,
+ });
+
+ // Create and cancel bad debt mutations.
+ const { mutateAsync: createBadDebtMutate } = useCreateBadDebt();
+
+ // State provider.
+ const provider = {
+ accounts,
+ invoice,
+ invoiceId,
+ dialogName,
+ createBadDebtMutate,
+ };
+
+ return (
+
+
+
+ );
+}
+
+const useBadDebtContext = () => React.useContext(BadDebtContext);
+
+export { BadDebtFormProvider, useBadDebtContext };
diff --git a/src/containers/Dialogs/BadDebtDialog/index.js b/src/containers/Dialogs/BadDebtDialog/index.js
new file mode 100644
index 000000000..7641bfb03
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/index.js
@@ -0,0 +1,29 @@
+import React from 'react';
+
+import { FormattedMessage as T } from 'components';
+import { Dialog, DialogSuspense } from 'components';
+import withDialogRedux from 'components/DialogReduxConnect';
+import { compose } from 'redux';
+
+const BadDebtDialogContent = React.lazy(() => import('./BadDebtDialogContent'));
+
+/**
+ * Bad debt dialog.
+ */
+function BadDebtDialog({ dialogName, payload: { invoiceId = null }, isOpen }) {
+ return (
+ }
+ isOpen={isOpen}
+ canEscapeJeyClose={true}
+ autoFocus={true}
+ className={'dialog--bad-debt'}
+ >
+
+
+
+
+ );
+}
+export default compose(withDialogRedux())(BadDebtDialog);
diff --git a/src/containers/Dialogs/BadDebtDialog/utils.js b/src/containers/Dialogs/BadDebtDialog/utils.js
new file mode 100644
index 000000000..c2845c87f
--- /dev/null
+++ b/src/containers/Dialogs/BadDebtDialog/utils.js
@@ -0,0 +1,17 @@
+import React from 'react';
+import { Intent } from '@blueprintjs/core';
+
+import { AppToaster } from 'components';
+
+/**
+ * Transformes the response errors types.
+ */
+export const transformErrors = (errors, { setErrors }) => {
+ if (errors.some(({ type }) => type === 'SALE_INVOICE_ALREADY_WRITTEN_OFF')) {
+ AppToaster.show({
+ message: 'SALE_INVOICE_ALREADY_WRITTEN_OFF',
+ // message: intl.get(''),
+ intent: Intent.DANGER,
+ });
+ }
+};
diff --git a/src/containers/Drawers/BillDrawer/BillDrawerDetails.js b/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
index 60df54da1..4b72212da 100644
--- a/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
+++ b/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
@@ -38,6 +38,11 @@ export default function BillDrawerDetails() {
id={'landed_cost'}
panel={}
/>
+
);
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js b/src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js
new file mode 100644
index 000000000..ea86bd2f7
--- /dev/null
+++ b/src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import {
+ Button,
+ NavbarGroup,
+ Classes,
+ NavbarDivider,
+ Popover,
+ PopoverInteractionKind,
+ Position,
+ Intent,
+ MenuItem,
+ Menu,
+} from '@blueprintjs/core';
+import { If, Icon, FormattedMessage as T } from 'components';
+import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
+
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import withAlertsActions from 'containers/Alert/withAlertActions';
+
+import { compose } from 'utils';
+
+function BadDebtMenuItem({
+ // #withDialogActions
+ openDialog,
+
+ // #withAlertsActions
+ openAlert,
+}) {
+ // Invoice detail drawer context.
+ const { invoiceId, invoice } = useInvoiceDetailDrawerContext();
+
+ const handleBadDebtInvoiceDialog = () => {
+ openDialog('invoice-bad-debt', { invoiceId });
+ };
+
+ const handleBadDebtInvoiceAlert = () => {
+ openAlert('bad-debt', { invoiceId });
+ };
+
+ return (
+
+
+ }
+ onClick={handleBadDebtInvoiceAlert}
+ />
+
+
+ }
+ />
+
+ }
+ minimal={true}
+ interactionKind={PopoverInteractionKind.CLICK}
+ position={Position.BOTTOM_LEFT}
+ canOutsideClickClose={false}
+ usePortal={false}
+ modifiers={{
+ offset: { offset: '0, 4' },
+ }}
+ >
+ } minimal={true} />
+
+ );
+}
+export default compose(withDialogActions, withAlertsActions)(BadDebtMenuItem);
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
index e80b8b9bf..6318900b0 100644
--- a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
+++ b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
@@ -30,6 +30,11 @@ export default function InvoiceDetail() {
id={'journal_entries'}
panel={}
/>
+
);
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
index 32e9b709b..dc821f2d3 100644
--- a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
+++ b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
@@ -6,20 +6,33 @@ import {
NavbarGroup,
Classes,
NavbarDivider,
+ Popover,
+ PopoverInteractionKind,
+ Position,
Intent,
+ MenuItem,
+ Menu,
} from '@blueprintjs/core';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
+import { moreVertOptions } from '../../../common/moreVertOptions';
import withDialogActions from 'containers/Dialog/withDialogActions';
import withAlertsActions from 'containers/Alert/withAlertActions';
import withDrawerActions from 'containers/Drawer/withDrawerActions';
-import { If, Icon, FormattedMessage as T } from 'components';
+import {
+ If,
+ Icon,
+ FormattedMessage as T,
+ // MoreVertMenutItems,
+} from 'components';
import { compose } from 'utils';
+import BadDebtMenuItem from './BadDebtMenuItem';
+
/**
* Invoice details action bar.
*/
@@ -58,6 +71,13 @@ function InvoiceDetailActionsBar({
const handleQuickPaymentInvoice = () => {
openDialog('quick-payment-receive', { invoiceId });
};
+ const handleBadDebtInvoiceDialog = () => () => {
+ openDialog('invoice-bad-debt', { invoiceId });
+ };
+
+ const handleBadDebtInvoiceAlert = () => {
+ openAlert('bad-debt', { invoiceId });
+ };
return (
@@ -91,6 +111,8 @@ function InvoiceDetailActionsBar({
intent={Intent.DANGER}
onClick={handleDeleteInvoice}
/>
+
+
);
diff --git a/src/containers/Sales/Invoices/InvoicesAlerts.js b/src/containers/Sales/Invoices/InvoicesAlerts.js
index 7325876da..cae3ac2e5 100644
--- a/src/containers/Sales/Invoices/InvoicesAlerts.js
+++ b/src/containers/Sales/Invoices/InvoicesAlerts.js
@@ -7,10 +7,15 @@ const InvoiceDeliverAlert = React.lazy(() =>
import('../../Alerts/Invoices/InvoiceDeliverAlert'),
);
+const BadDebtAlert = React.lazy(() =>
+ import('../../Alerts/Invoices/BadDebtAlert'),
+);
+
/**
* Invoices alert.
*/
export default [
{ name: 'invoice-delete', component: InvoiceDeleteAlert },
{ name: 'invoice-deliver', component: InvoiceDeliverAlert },
+ { name: 'bad-debt', component: BadDebtAlert },
];
diff --git a/src/hooks/query/invoices.js b/src/hooks/query/invoices.js
index 58580dc83..22ad30b7d 100644
--- a/src/hooks/query/invoices.js
+++ b/src/hooks/query/invoices.js
@@ -194,3 +194,38 @@ export function useRefreshInvoices() {
},
};
}
+
+export function useCreateBadDebt(props) {
+ const queryClient = useQueryClient();
+ const apiRequest = useApiRequest();
+
+ return useMutation(
+ ([id, values]) => apiRequest.post(`sales/invoices/${id}/writeoff`, values),
+ {
+ onSuccess: (res, [id, values]) => {
+ // Invalidate
+ queryClient.invalidateQueries([t.BAD_DEBT, id]);
+
+ // Common invalidate queries.
+ commonInvalidateQueries(queryClient);
+ },
+ ...props,
+ },
+ );
+}
+
+export function useCancelBadDebt(props) {
+ const queryClient = useQueryClient();
+ const apiRequest = useApiRequest();
+
+ return useMutation((id) => apiRequest.post(`sales/invoices/${id}/writeoff/cancel`), {
+ onSuccess: (res, id) => {
+ // Invalidate
+ queryClient.invalidateQueries([t.CANCEL_BAD_DEBT, id]);
+
+ // Common invalidate queries.
+ commonInvalidateQueries(queryClient);
+ },
+ ...props,
+ });
+}
diff --git a/src/hooks/query/types.js b/src/hooks/query/types.js
index 9b3637f27..54952a47c 100644
--- a/src/hooks/query/types.js
+++ b/src/hooks/query/types.js
@@ -85,6 +85,8 @@ const SALE_INVOICES = {
SALE_INVOICES: 'SALE_INVOICES',
SALE_INVOICE: 'SALE_INVOICE',
SALE_INVOICES_DUE: 'SALE_INVOICES_DUE',
+ BAD_DEBT: 'BAD_DEBT',
+ CANCEL_BAD_DEBT: 'CANCEL_BAD_DEBT',
};
const USERS = {
@@ -137,7 +139,8 @@ const CASH_FLOW_ACCOUNTS = {
CASH_FLOW_ACCOUNTS: 'CASH_FLOW_ACCOUNTS',
CASH_FLOW_TRANSACTIONS: 'CASH_FLOW_TRANSACTIONS',
CASH_FLOW_TRANSACTION: 'CASH_FLOW_TRANSACTION',
- CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY: 'CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY'
+ CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY:
+ 'CASHFLOW_ACCOUNT_TRANSACTIONS_INFINITY',
};
export default {
diff --git a/src/lang/ar/index.json b/src/lang/ar/index.json
index f6b14d9c0..6fea45707 100644
--- a/src/lang/ar/index.json
+++ b/src/lang/ar/index.json
@@ -1012,6 +1012,8 @@
"jump_to_the_bills": "انتقل إلي فواتير الشراء.",
"jump_to_the_manual_journals": "انتقل إلي القيود اليدوية.",
"jump_to_the_items": "انتقل إلي المنتجات.",
+ "jump_to_the_add_money_in": "انتقل إلي إيداع إلي الحساب.",
+ "jump_to_the_add_money_out": "انتقل إلي سحب من الحساب.",
"jump_to_the_balance_sheet": "انتقل إلي تقرير الميزانية العمومية.",
"jump_to_the_profit_loss_sheet": "انتقل إلي تقرير قائمة الدخل.",
"jump_to_the_journal_sheet": "انتقل إلي دفتر اليومية العامة.",
@@ -1371,7 +1373,6 @@
"payment_made.empty_status.title": "المنشأة لم تدفع اي اموال إلي الموردين ، إلي حد الأن!.",
"estimate.delete.error.estimate_converted_to_invoice": "لا يمكن حذف عملية عرض اسعار الذي تم تحويلها إلي فاتورة بيع.",
"landed_cost.action.delete.success_message": "The landed cost has been deleted successfully.",
-
"items.option.only_active": "Only active",
"items.option_all_items.hint": "جميع الاصناف ، بما في ذلك تلك الاصناف لديها رصيد صفر.",
"items.option_with_transactions": "الاصناف مع معاملات",
@@ -1379,22 +1380,18 @@
"items.option_without_zero_balance": "الاصناف ذات رصيد صفر",
"items.option_without_zero_balance.hint": "قم بتضمين الاصناف واستبعاد تلك التي لديها رصيد صفري.",
"items.label_filter_items": "تصفية الاصناف",
-
"customers.option_all_customers.hint": "All customers, including that ones have zero-balance.",
"customers.option_without_zero_balance": "Customers without zero-balance",
"customers.option_without_zero_balance.hint": "Include customers and exclude that ones have zero-balance.",
"customers.option_with_transactions": "Customers with transactions",
"customers.option_with_transactions.hint": "Include customers that onces have transactions on the given date period only.",
"customers.label_filter_customers": "Filter customers",
-
-
"vendors.option_all_vendors.hint": "All vendors, including that ones have zero-balance.",
"vendors.label_filter_vendors": "Filter Vendors",
"vendors.option_without_zero_balance": "Vendors without zero-balance",
"vendors.option_without_zero_balance.hint": "Include vendors and exclude that ones have zero-balance.",
"vendors.option_with_transactions": "Vendors with transactions",
"vendors.option_with_transactions.hint": "Include vendors that onces have transactions on the given date period only.",
-
"siebar.cashflow": "التدفق النقدي",
"siebar.cashflow.label_cash_and_bank_accounts": "حسابات نقدية والمصارف ",
"cash_flow.label_account_transcations": "معاملات الحساب",
@@ -1405,7 +1402,6 @@
"cash_flow.label.add_bank_account": "اضافة حساب مصرف",
"cash_flow.label.add_money_in": "إيداع إلي الحساب",
"cash_flow.label.add_money_out": "سحب من الحساب",
-
"cash_flow.owner_contribution": "زيادة رأس المال",
"cash_flow.other_income": "إيراد أخر",
"cash_flow.owner_drawings": "سحب رأس المال",
@@ -1436,5 +1432,8 @@
"cash_flow_money_in": "إيداع",
"cash_flow_money_out": "سحب",
"cash_flow_transaction.switch_item": " {value} معاملة علي حساب",
- "cash_flow_transaction.balance_in_bigcapital": "الرصيد في Bigcapital"
+ "cash_flow_transaction.balance_in_bigcapital": "الرصيد في Bigcapital",
+ "badDebt.label_written_off_amount": "المبلغ المشطوب",
+ "badDebt.label": "الديون المعدومة",
+ "badDebt_the_seller_can_charge_the_amount_of_an_invoice": "يمكن للبائع تحميل مبلغ الفاتورة على حساب مصروفات الديون المعدومة عندما يكون من المؤكد أن الفاتورة لن يتم دفعها."
}
\ No newline at end of file
diff --git a/src/lang/en/index.json b/src/lang/en/index.json
index 968aa8644..61228c973 100644
--- a/src/lang/en/index.json
+++ b/src/lang/en/index.json
@@ -1420,5 +1420,15 @@
"AP_aging_summary.filter_options.label": "Filter vendors",
"item.error.type_cannot_change_with_item_has_transactions": "Cannot change item type to inventory with item has associated transactions.",
"item.error.cannot_change_inventory_account": "Cannot change item inventory account while the item has transactions.",
- "customer.link.customer_details": "Customer details ({amount})"
+ "customer.link.customer_details": "Customer details ({amount})",
+ "badDebt.label_written_off_amount": "Written-off amount",
+ "badDebt.label": "Bad debt",
+ "badDebt.label_cancel_bad_debt": "Cancel bad debt",
+ "badDebt_the_seller_can_charge_the_amount_of_an_invoice": "The seller can charge the amount of an invoice to the bad debt expense account when it is certain that the invoice will not be paid.",
+ "badDebt_success_message":"The given sale invoice has been writte-off successfully.",
+ "are_sure_to_cancel_this_invoice": "Are you sure you want to cancel this invoice?",
+
+ "payment_transactions": "Payment transactions"
+
+
}
\ No newline at end of file
diff --git a/src/static/json/icons.js b/src/static/json/icons.js
index 28516dab0..42a191624 100644
--- a/src/static/json/icons.js
+++ b/src/static/json/icons.js
@@ -502,5 +502,11 @@ export default {
'arrow-upward': {
path: ['M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'],
viewBox: '0 0 24 24',
- }
+ },
+ 'more-vert': {
+ path: [
+ 'M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z',
+ ],
+ viewBox: '0 0 24 24',
+ },
};
diff --git a/src/style/pages/BadDebt/BadDebtDialog.scss b/src/style/pages/BadDebt/BadDebtDialog.scss
new file mode 100644
index 000000000..a83fcc41b
--- /dev/null
+++ b/src/style/pages/BadDebt/BadDebtDialog.scss
@@ -0,0 +1,34 @@
+.dialog--bad-debt {
+ max-width: 400px;
+
+ .bp3-dialog-body {
+ .bp3-form-group {
+ margin-bottom: 15px;
+ margin-top: 15px;
+
+ label.bp3-label {
+ margin-bottom: 3px;
+ font-size: 13px;
+ }
+ }
+
+ .bp3-callout {
+ font-size: 13px;
+ }
+ .form-group {
+ &--reason {
+ .bp3-form-content {
+ textarea {
+ width: 100%;
+ min-width: 100%;
+ font-size: 14px;
+ }
+ }
+ }
+ }
+ }
+
+ .bp3-dialog-footer {
+ padding-top: 10px;
+ }
+}
From cd3105b32020ab5ee774643b5be7c4466e148a8b Mon Sep 17 00:00:00 2001
From: elforjani13 <39470382+elforjani13@users.noreply.github.com>
Date: Tue, 2 Nov 2021 00:23:43 +0200
Subject: [PATCH 2/3] feat: add Bad-debt & cancel bad-bebt.
---
src/components/DialogsContainer.js | 2 +-
...{BadDebtAlert.js => CancelBadDebtAlert.js} | 17 +++--
.../Dialogs/BadDebtDialog/BadDebtForm.js | 2 +-
.../Drawers/BillDrawer/BillDrawerDetails.js | 4 +-
.../InvoiceDetailDrawer/BadDebtMenuItem.js | 70 -------------------
.../InvoiceDetailDrawer/InvoiceDetail.js | 4 +-
.../InvoiceDetailActionsBar.js | 19 +++--
.../Drawers/InvoiceDetailDrawer/utils.js | 41 +++++++++++
.../InventoryItemDetails/utils.js | 2 +-
.../Sales/Invoices/InvoicesAlerts.js | 6 +-
src/hooks/query/invoices.js | 1 +
src/lang/ar/index.json | 8 ++-
src/lang/en/index.json | 10 ++-
13 files changed, 86 insertions(+), 100 deletions(-)
rename src/containers/Alerts/Invoices/{BadDebtAlert.js => CancelBadDebtAlert.js} (77%)
delete mode 100644 src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js
diff --git a/src/components/DialogsContainer.js b/src/components/DialogsContainer.js
index f1e803fff..1a31006dc 100644
--- a/src/components/DialogsContainer.js
+++ b/src/components/DialogsContainer.js
@@ -45,7 +45,7 @@ export default function DialogsContainer() {
-
+
);
}
diff --git a/src/containers/Alerts/Invoices/BadDebtAlert.js b/src/containers/Alerts/Invoices/CancelBadDebtAlert.js
similarity index 77%
rename from src/containers/Alerts/Invoices/BadDebtAlert.js
rename to src/containers/Alerts/Invoices/CancelBadDebtAlert.js
index b3d05c083..6bbe29994 100644
--- a/src/containers/Alerts/Invoices/BadDebtAlert.js
+++ b/src/containers/Alerts/Invoices/CancelBadDebtAlert.js
@@ -11,9 +11,9 @@ import withAlertActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
/**
- * bad debt alert.
+ * Cancel bad debt alert.
*/
-function BadDebtAlert({
+function CancelBadDebtAlert({
name,
// #withAlertStoreConnect
@@ -23,7 +23,7 @@ function BadDebtAlert({
// #withAlertActions
closeAlert,
}) {
- // handle cancel alert.
+ // handle cancel alert.
const handleCancel = () => {
closeAlert(name);
};
@@ -35,7 +35,7 @@ function BadDebtAlert({
cancelBadDebtMutate(invoiceId)
.then(() => {
AppToaster.show({
- message: intl.get('the_invoice_has_been_deleted_successfully'),
+ message: intl.get('badDebt_canceled_write_off_success_message'),
intent: Intent.SUCCESS,
});
})
@@ -48,7 +48,7 @@ function BadDebtAlert({
return (
}
- confirmButtonText={}
+ confirmButtonText={}
intent={Intent.WARNING}
isOpen={isOpen}
onCancel={handleCancel}
@@ -56,10 +56,13 @@ function BadDebtAlert({
loading={isLoading}
>
-
+
);
}
-export default compose(withAlertStoreConnect(), withAlertActions)(BadDebtAlert);
+export default compose(
+ withAlertStoreConnect(),
+ withAlertActions,
+)(CancelBadDebtAlert);
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
index 5b579db28..bd2d7696e 100644
--- a/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
@@ -50,7 +50,7 @@ function BadDebtForm({
// Handle request response success.
const onSuccess = (response) => {
AppToaster.show({
- message: intl.get('badDebt_success_message'),
+ message: intl.get('badDebt_writte_off_success_message'),
intent: Intent.SUCCESS,
});
closeDialog(dialogName);
diff --git a/src/containers/Drawers/BillDrawer/BillDrawerDetails.js b/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
index 4b72212da..8369fb7b8 100644
--- a/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
+++ b/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
@@ -38,11 +38,11 @@ export default function BillDrawerDetails() {
id={'landed_cost'}
panel={}
/>
-
+ /> */}
);
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js b/src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js
deleted file mode 100644
index ea86bd2f7..000000000
--- a/src/containers/Drawers/InvoiceDetailDrawer/BadDebtMenuItem.js
+++ /dev/null
@@ -1,70 +0,0 @@
-import React from 'react';
-import {
- Button,
- NavbarGroup,
- Classes,
- NavbarDivider,
- Popover,
- PopoverInteractionKind,
- Position,
- Intent,
- MenuItem,
- Menu,
-} from '@blueprintjs/core';
-import { If, Icon, FormattedMessage as T } from 'components';
-import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
-
-import withDialogActions from 'containers/Dialog/withDialogActions';
-import withAlertsActions from 'containers/Alert/withAlertActions';
-
-import { compose } from 'utils';
-
-function BadDebtMenuItem({
- // #withDialogActions
- openDialog,
-
- // #withAlertsActions
- openAlert,
-}) {
- // Invoice detail drawer context.
- const { invoiceId, invoice } = useInvoiceDetailDrawerContext();
-
- const handleBadDebtInvoiceDialog = () => {
- openDialog('invoice-bad-debt', { invoiceId });
- };
-
- const handleBadDebtInvoiceAlert = () => {
- openAlert('bad-debt', { invoiceId });
- };
-
- return (
-
-
- }
- onClick={handleBadDebtInvoiceAlert}
- />
-
-
- }
- />
-
- }
- minimal={true}
- interactionKind={PopoverInteractionKind.CLICK}
- position={Position.BOTTOM_LEFT}
- canOutsideClickClose={false}
- usePortal={false}
- modifiers={{
- offset: { offset: '0, 4' },
- }}
- >
- } minimal={true} />
-
- );
-}
-export default compose(withDialogActions, withAlertsActions)(BadDebtMenuItem);
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
index 6318900b0..224e948a0 100644
--- a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
+++ b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
@@ -30,11 +30,11 @@ export default function InvoiceDetail() {
id={'journal_entries'}
panel={}
/>
-
+ /> */}
);
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
index dc821f2d3..b83b8a6ed 100644
--- a/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
+++ b/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
@@ -31,7 +31,7 @@ import {
import { compose } from 'utils';
-import BadDebtMenuItem from './BadDebtMenuItem';
+import { BadDebtMenuItem } from './utils';
/**
* Invoice details action bar.
@@ -71,12 +71,15 @@ function InvoiceDetailActionsBar({
const handleQuickPaymentInvoice = () => {
openDialog('quick-payment-receive', { invoiceId });
};
- const handleBadDebtInvoiceDialog = () => () => {
- openDialog('invoice-bad-debt', { invoiceId });
+
+ // Handle write-off invoice.
+ const handleBadDebtInvoice = () => {
+ openDialog('write-off-bad-debt', { invoiceId });
};
- const handleBadDebtInvoiceAlert = () => {
- openAlert('bad-debt', { invoiceId });
+ // Handle cancele write-off invoice.
+ const handleCancelBadDebtInvoice = () => {
+ openAlert('cancel-bad-debt', { invoiceId });
};
return (
@@ -112,7 +115,11 @@ function InvoiceDetailActionsBar({
onClick={handleDeleteInvoice}
/>
-
+
);
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/utils.js b/src/containers/Drawers/InvoiceDetailDrawer/utils.js
index f2d3ae58e..426d5c4c3 100644
--- a/src/containers/Drawers/InvoiceDetailDrawer/utils.js
+++ b/src/containers/Drawers/InvoiceDetailDrawer/utils.js
@@ -1,5 +1,15 @@
import React from 'react';
import intl from 'react-intl-universal';
+
+import {
+ Button,
+ Popover,
+ PopoverInteractionKind,
+ Position,
+ MenuItem,
+ Menu,
+} from '@blueprintjs/core';
+import { If, Icon, FormattedMessage as T, Choose } from 'components';
import { FormatNumberCell } from '../../../components';
/**
@@ -48,3 +58,34 @@ export const useInvoiceReadonlyEntriesColumns = () =>
],
[],
);
+
+export const BadDebtMenuItem = ({ invoice, onDialog, onAlert }) => {
+ return (
+
+
+
+ } onClick={onDialog} />
+
+
+ }
+ />
+
+
+
+ }
+ position={Position.BOTTOM}
+ >
+ } minimal={true} />
+
+ );
+};
diff --git a/src/containers/FinancialStatements/InventoryItemDetails/utils.js b/src/containers/FinancialStatements/InventoryItemDetails/utils.js
index 35d2e29f1..5824c4d52 100644
--- a/src/containers/FinancialStatements/InventoryItemDetails/utils.js
+++ b/src/containers/FinancialStatements/InventoryItemDetails/utils.js
@@ -9,7 +9,7 @@ const columnsMapper = (data, index, column) => ({
id: column.key,
key: column.key,
Header: column.label,
- Cell: CellForceWidth,
+ // Cell: CellForceWidth,
accessor: `cells[${index}].value`,
forceWidthAccess: `cells[0].value`,
className: column.key,
diff --git a/src/containers/Sales/Invoices/InvoicesAlerts.js b/src/containers/Sales/Invoices/InvoicesAlerts.js
index cae3ac2e5..1b2e017ae 100644
--- a/src/containers/Sales/Invoices/InvoicesAlerts.js
+++ b/src/containers/Sales/Invoices/InvoicesAlerts.js
@@ -7,8 +7,8 @@ const InvoiceDeliverAlert = React.lazy(() =>
import('../../Alerts/Invoices/InvoiceDeliverAlert'),
);
-const BadDebtAlert = React.lazy(() =>
- import('../../Alerts/Invoices/BadDebtAlert'),
+const CancelBadDebtAlert = React.lazy(() =>
+ import('../../Alerts/Invoices/CancelBadDebtAlert'),
);
/**
@@ -17,5 +17,5 @@ const BadDebtAlert = React.lazy(() =>
export default [
{ name: 'invoice-delete', component: InvoiceDeleteAlert },
{ name: 'invoice-deliver', component: InvoiceDeliverAlert },
- { name: 'bad-debt', component: BadDebtAlert },
+ { name: 'cancel-bad-debt', component: CancelBadDebtAlert },
];
diff --git a/src/hooks/query/invoices.js b/src/hooks/query/invoices.js
index 22ad30b7d..67debc80c 100644
--- a/src/hooks/query/invoices.js
+++ b/src/hooks/query/invoices.js
@@ -9,6 +9,7 @@ import t from './types';
const commonInvalidateQueries = (queryClient) => {
// Invalidate invoices.
queryClient.invalidateQueries(t.SALE_INVOICES);
+ queryClient.invalidateQueries(t.SALE_INVOICE);
// Invalidate customers.
queryClient.invalidateQueries(t.CUSTOMERS);
diff --git a/src/lang/ar/index.json b/src/lang/ar/index.json
index 6fea45707..c7fda276f 100644
--- a/src/lang/ar/index.json
+++ b/src/lang/ar/index.json
@@ -1435,5 +1435,11 @@
"cash_flow_transaction.balance_in_bigcapital": "الرصيد في Bigcapital",
"badDebt.label_written_off_amount": "المبلغ المشطوب",
"badDebt.label": "الديون المعدومة",
- "badDebt_the_seller_can_charge_the_amount_of_an_invoice": "يمكن للبائع تحميل مبلغ الفاتورة على حساب مصروفات الديون المعدومة عندما يكون من المؤكد أن الفاتورة لن يتم دفعها."
+ "badDebt.label_cancel_bad_debt": "إلغاء الديون المعدومة",
+ "badDebt_the_seller_can_charge_the_amount_of_an_invoice": "يمكن للبائع تحميل مبلغ الفاتورة على حساب مصروفات الديون المعدومة عندما يكون من المؤكد أن الفاتورة لن يتم دفعها.",
+ "badDebt_writte_off_success_message":"تم شطب فاتورة البيع المقدمة بنجاح.",
+ "badDebt_canceled_write_off_success_message":"تم إلغاء شطب فاتورة البيع المقدمة بنجاح.",
+ "badDebt_are_sure_to_write_off_this_invoice": "هل أنت متأكد أنك تريد شطب هذه الفاتورة؟ "
+
+
}
\ No newline at end of file
diff --git a/src/lang/en/index.json b/src/lang/en/index.json
index 61228c973..cb07a2c6e 100644
--- a/src/lang/en/index.json
+++ b/src/lang/en/index.json
@@ -1425,10 +1425,8 @@
"badDebt.label": "Bad debt",
"badDebt.label_cancel_bad_debt": "Cancel bad debt",
"badDebt_the_seller_can_charge_the_amount_of_an_invoice": "The seller can charge the amount of an invoice to the bad debt expense account when it is certain that the invoice will not be paid.",
- "badDebt_success_message":"The given sale invoice has been writte-off successfully.",
- "are_sure_to_cancel_this_invoice": "Are you sure you want to cancel this invoice?",
-
- "payment_transactions": "Payment transactions"
-
-
+ "badDebt_writte_off_success_message":"The given sale invoice has been writte-off successfully.",
+ "badDebt_canceled_write_off_success_message":"The given sale invoice has been canceled write-off successfully.",
+ "badDebt_are_sure_to_write_off_this_invoice": "Are you sure you want to write off this invoice?"
+
}
\ No newline at end of file
From fd09ea12ff339279105ab9228f47b720e28bd750 Mon Sep 17 00:00:00 2001
From: elforjani13 <39470382+elforjani13@users.noreply.github.com>
Date: Tue, 2 Nov 2021 14:22:55 +0200
Subject: [PATCH 3/3] fix: localization.
---
src/common/moreVertOptions.js | 4 ++--
.../Alerts/Invoices/CancelBadDebtAlert.js | 4 ++--
.../Dialogs/BadDebtDialog/BadDebtForm.js | 2 +-
.../Dialogs/BadDebtDialog/BadDebtFormFields.js | 4 ++--
src/containers/Dialogs/BadDebtDialog/index.js | 2 +-
.../Drawers/InvoiceDetailDrawer/utils.js | 7 +++++--
src/lang/ar/index.json | 14 +++++++-------
src/lang/en/index.json | 16 ++++++++--------
8 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/src/common/moreVertOptions.js b/src/common/moreVertOptions.js
index 62a15a755..d3a2564c8 100644
--- a/src/common/moreVertOptions.js
+++ b/src/common/moreVertOptions.js
@@ -2,11 +2,11 @@ import intl from 'react-intl-universal';
export const moreVertOptions = [
{
- name: intl.get('badDebt.label'),
+ name: intl.get('bad_debt.dialog.bad_debt'),
value: 'bad debt',
},
{
- name: intl.get('badDebt.label_cancel_bad_debt'),
+ name: intl.get('bad_debt.dialog.cancel_bad_debt'),
value: 'cancel bad debt',
},
];
diff --git a/src/containers/Alerts/Invoices/CancelBadDebtAlert.js b/src/containers/Alerts/Invoices/CancelBadDebtAlert.js
index 6bbe29994..2e1a914cd 100644
--- a/src/containers/Alerts/Invoices/CancelBadDebtAlert.js
+++ b/src/containers/Alerts/Invoices/CancelBadDebtAlert.js
@@ -35,7 +35,7 @@ function CancelBadDebtAlert({
cancelBadDebtMutate(invoiceId)
.then(() => {
AppToaster.show({
- message: intl.get('badDebt_canceled_write_off_success_message'),
+ message: intl.get('bad_debt.cancel_alert.success_message'),
intent: Intent.SUCCESS,
});
})
@@ -56,7 +56,7 @@ function CancelBadDebtAlert({
loading={isLoading}
>
-
+
);
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
index bd2d7696e..8e521e6f2 100644
--- a/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtForm.js
@@ -50,7 +50,7 @@ function BadDebtForm({
// Handle request response success.
const onSuccess = (response) => {
AppToaster.show({
- message: intl.get('badDebt_writte_off_success_message'),
+ message: intl.get('bad_debt.dialog.success_message'),
intent: Intent.SUCCESS,
});
closeDialog(dialogName);
diff --git a/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js b/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js
index 2d52b4a3c..a5bc69d07 100644
--- a/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js
+++ b/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.js
@@ -36,7 +36,7 @@ function BadDebtFormFields() {
-
+
@@ -48,7 +48,7 @@ function BadDebtFormFields() {
meta: { error, touched },
}) => (
}
+ label={
}
labelInfo={
}
className={classNames('form-group--amount', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
diff --git a/src/containers/Dialogs/BadDebtDialog/index.js b/src/containers/Dialogs/BadDebtDialog/index.js
index 7641bfb03..016645dcf 100644
--- a/src/containers/Dialogs/BadDebtDialog/index.js
+++ b/src/containers/Dialogs/BadDebtDialog/index.js
@@ -14,7 +14,7 @@ function BadDebtDialog({ dialogName, payload: { invoiceId = null }, isOpen }) {
return (
}
+ title={
}
isOpen={isOpen}
canEscapeJeyClose={true}
autoFocus={true}
diff --git a/src/containers/Drawers/InvoiceDetailDrawer/utils.js b/src/containers/Drawers/InvoiceDetailDrawer/utils.js
index 426d5c4c3..26d219e9d 100644
--- a/src/containers/Drawers/InvoiceDetailDrawer/utils.js
+++ b/src/containers/Drawers/InvoiceDetailDrawer/utils.js
@@ -72,12 +72,15 @@ export const BadDebtMenuItem = ({ invoice, onDialog, onAlert }) => {