mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 06:40:31 +00:00
feat: notify by SMS.
This commit is contained in:
36
src/components/MoreMenutItems.js
Normal file
36
src/components/MoreMenutItems.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Popover,
|
||||||
|
PopoverInteractionKind,
|
||||||
|
Position,
|
||||||
|
MenuItem,
|
||||||
|
Menu,
|
||||||
|
} from '@blueprintjs/core';
|
||||||
|
|
||||||
|
import { Icon, FormattedMessage as T } from 'components';
|
||||||
|
|
||||||
|
function MoreMenuItems({ payload: { onNotifyViaSMS } }) {
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
minimal={true}
|
||||||
|
content={
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
onClick={onNotifyViaSMS}
|
||||||
|
text={<T id={'notify_via_sms.dialog.notify_via_sms'} />}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
interactionKind={PopoverInteractionKind.CLICK}
|
||||||
|
position={Position.BOTTOM_LEFT}
|
||||||
|
modifiers={{
|
||||||
|
offset: { offset: '0, 4' },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button icon={<Icon icon="more-vert" iconSize={16} />} minimal={true} />
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MoreMenuItems;
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
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 }) => (
|
|
||||||
<MenuItem text={item.name} label={item.label} onClick={handleClick} />
|
|
||||||
);
|
|
||||||
const handleMenuSelect = (type) => {
|
|
||||||
onItemSelect && onItemSelect(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
items={items}
|
|
||||||
itemRenderer={itemsRenderer}
|
|
||||||
onItemSelect={handleMenuSelect}
|
|
||||||
popoverProps={{
|
|
||||||
minimal: true,
|
|
||||||
position: Position.BOTTOM_LEFT,
|
|
||||||
interactionKind: PopoverInteractionKind.CLICK,
|
|
||||||
modifiers: {
|
|
||||||
offset: { offset: '0, 4' },
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
filterable={false}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
text={text}
|
|
||||||
icon={<Icon icon={'more-vert'} iconSize={16} />}
|
|
||||||
minimal={true}
|
|
||||||
{...buttonProps}
|
|
||||||
/>
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default MoreVertMenutItems;
|
|
||||||
@@ -61,7 +61,7 @@ import Card from './Card';
|
|||||||
import AvaterCell from './AvaterCell';
|
import AvaterCell from './AvaterCell';
|
||||||
|
|
||||||
import { ItemsMultiSelect } from './Items';
|
import { ItemsMultiSelect } from './Items';
|
||||||
import MoreVertMenutItems from './MoreVertMenutItems';
|
import MoreMenuItems from './MoreMenutItems';
|
||||||
|
|
||||||
export * from './Menu';
|
export * from './Menu';
|
||||||
export * from './AdvancedFilter/AdvancedFilterDropdown';
|
export * from './AdvancedFilter/AdvancedFilterDropdown';
|
||||||
@@ -83,7 +83,7 @@ export * from './MultiSelectTaggable';
|
|||||||
export * from './Utils/FormatNumber';
|
export * from './Utils/FormatNumber';
|
||||||
export * from './Utils/FormatDate';
|
export * from './Utils/FormatDate';
|
||||||
export * from './BankAccounts';
|
export * from './BankAccounts';
|
||||||
export * from './IntersectionObserver'
|
export * from './IntersectionObserver';
|
||||||
export * from './Datatable/CellForceWidth';
|
export * from './Datatable/CellForceWidth';
|
||||||
export * from './Button';
|
export * from './Button';
|
||||||
export * from './IntersectionObserver';
|
export * from './IntersectionObserver';
|
||||||
@@ -158,5 +158,5 @@ export {
|
|||||||
ItemsMultiSelect,
|
ItemsMultiSelect,
|
||||||
Card,
|
Card,
|
||||||
AvaterCell,
|
AvaterCell,
|
||||||
MoreVertMenutItems,
|
MoreMenuItems
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import '../../../style/pages/NotifyConactViaSMS/NotifyConactViaSMSDialog.scss';
|
import 'style/pages/NotifyConactViaSMS/NotifyConactViaSMSDialog.scss';
|
||||||
import { NotifyContactViaSMSFormProvider } from './NotifyContactViaSMSFormProvider';
|
import { NotifyContactViaSMSFormProvider } from './NotifyContactViaSMSFormProvider';
|
||||||
import NotifyContactViaSMSForm from './NotifyContactViaSMSForm';
|
import NotifyContactViaSMSForm from './NotifyContactViaSMSForm';
|
||||||
|
|
||||||
@@ -10,9 +10,13 @@ import NotifyContactViaSMSForm from './NotifyContactViaSMSForm';
|
|||||||
export default function NotifyContactViaSMSContent({
|
export default function NotifyContactViaSMSContent({
|
||||||
// #ownProps
|
// #ownProps
|
||||||
dialogName,
|
dialogName,
|
||||||
|
invoice,
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<NotifyContactViaSMSFormProvider dialogName={dialogName}>
|
<NotifyContactViaSMSFormProvider
|
||||||
|
invoiceId={invoice}
|
||||||
|
dialogName={dialogName}
|
||||||
|
>
|
||||||
<NotifyContactViaSMSForm />
|
<NotifyContactViaSMSForm />
|
||||||
</NotifyContactViaSMSFormProvider>
|
</NotifyContactViaSMSFormProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,27 +13,54 @@ import withDialogActions from 'containers/Dialog/withDialogActions';
|
|||||||
|
|
||||||
import { useNotifyContactViaSMSContext } from './NotifyContactViaSMSFormProvider';
|
import { useNotifyContactViaSMSContext } from './NotifyContactViaSMSFormProvider';
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { transformToForm, compose } from 'utils';
|
||||||
|
|
||||||
const defaultInitialValues = {
|
const defaultInitialValues = {
|
||||||
name: '',
|
customer_name: '',
|
||||||
phone: '',
|
customer_personal_phone: '',
|
||||||
note: '',
|
sms_message: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
function NotifyContactViaSMSForm({
|
function NotifyContactViaSMSForm({
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
closeDialog,
|
closeDialog,
|
||||||
}) {
|
}) {
|
||||||
const { dialogName } = useNotifyContactViaSMSContext();
|
const {
|
||||||
|
invoiceId,
|
||||||
|
invoiceSMSDetail,
|
||||||
|
dialogName,
|
||||||
|
createNotifyInvoiceBySMSMutate,
|
||||||
|
} = useNotifyContactViaSMSContext();
|
||||||
|
|
||||||
// Initial form values
|
// Initial form values
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
...defaultInitialValues,
|
...defaultInitialValues,
|
||||||
|
...transformToForm(invoiceSMSDetail, defaultInitialValues),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handles the form submit.
|
// Handles the form submit.
|
||||||
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {};
|
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
|
||||||
|
// Handle request response success.
|
||||||
|
const onSuccess = (response) => {
|
||||||
|
AppToaster.show({
|
||||||
|
message: intl.get('notify_via_sms.dialog.success_message'),
|
||||||
|
intent: Intent.SUCCESS,
|
||||||
|
});
|
||||||
|
closeDialog(dialogName);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle request response errors.
|
||||||
|
const onError = ({
|
||||||
|
response: {
|
||||||
|
data: { errors },
|
||||||
|
},
|
||||||
|
}) => {
|
||||||
|
setSubmitting(false);
|
||||||
|
};
|
||||||
|
createNotifyInvoiceBySMSMutate([invoiceId, values])
|
||||||
|
.then(onSuccess)
|
||||||
|
.catch(onError);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Formik
|
<Formik
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import intl from 'react-intl-universal';
|
|||||||
import { DATATYPES_LENGTH } from 'common/dataTypes';
|
import { DATATYPES_LENGTH } from 'common/dataTypes';
|
||||||
|
|
||||||
const Schema = Yup.object().shape({
|
const Schema = Yup.object().shape({
|
||||||
customer_id: Yup.string().required(),
|
customer_name: Yup.string().required(),
|
||||||
phone: Yup.number().required(),
|
customer_personal_phone: Yup.number().required(),
|
||||||
note: Yup.string().required().trim().max(DATATYPES_LENGTH.TEXT),
|
sms_message: Yup.string().required().trim().max(DATATYPES_LENGTH.TEXT),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const CreateNotifyContactViaSMSFormSchema = Schema;
|
export const CreateNotifyContactViaSMSFormSchema = Schema;
|
||||||
|
|||||||
@@ -24,48 +24,60 @@ function NotifyContactViaSMSFormFields() {
|
|||||||
return (
|
return (
|
||||||
<div className={Classes.DIALOG_BODY}>
|
<div className={Classes.DIALOG_BODY}>
|
||||||
{/* ----------- Send Notification to ----------- */}
|
{/* ----------- Send Notification to ----------- */}
|
||||||
<FastField name={'customer_id'}>
|
<FastField name={'customer_name'}>
|
||||||
{({ form, field, meta: { error, touched } }) => (
|
{({ form, field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'notify_via_sms.dialog.send_notification_to'} />}
|
label={<T id={'notify_via_sms.dialog.send_notification_to'} />}
|
||||||
className={classNames('form-group--customer-name', CLASSES.FILL)}
|
className={classNames('form-group--customer-name', CLASSES.FILL)}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name={'customer_id'} />}
|
helperText={<ErrorMessage name={'customer_name'} />}
|
||||||
>
|
>
|
||||||
<InputGroup intent={inputIntent({ error, touched })} {...field} />
|
<InputGroup
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
disabled={true}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
|
|
||||||
{/* ----------- Phone number ----------- */}
|
{/* ----------- Phone number ----------- */}
|
||||||
<FastField name={'phone'}>
|
<FastField name={'customer_personal_phone'}>
|
||||||
{({ form, field, meta: { error, touched } }) => (
|
{({ form, field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'phone_number'} />}
|
label={<T id={'phone_number'} />}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name="phone" />}
|
helperText={<ErrorMessage name="customer_personal_phone" />}
|
||||||
className={classNames('form-group--phone', CLASSES.FILL)}
|
className={classNames(
|
||||||
|
'form-group--customer_personal_phone',
|
||||||
|
CLASSES.FILL,
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<InputGroup intent={inputIntent({ error, touched })} {...field} />
|
<InputGroup
|
||||||
|
intent={inputIntent({ error, touched })}
|
||||||
|
disabled={true}
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
|
|
||||||
{/* ----------- Message Text ----------- */}
|
{/* ----------- Message Text ----------- */}
|
||||||
<FastField name={'note'}>
|
<FastField name={'sms_message'}>
|
||||||
{({ field, meta: { error, touched } }) => (
|
{({ field, meta: { error, touched } }) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'notify_via_sms.dialog.message_text'} />}
|
label={<T id={'notify_via_sms.dialog.message_text'} />}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
className={'form-group--note'}
|
className={'form-group--sms_message'}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
helperText={<ErrorMessage name={'note'} />}
|
helperText={<ErrorMessage name={'sms_message'} />}
|
||||||
>
|
>
|
||||||
<TextArea
|
<TextArea
|
||||||
growVertically={true}
|
growVertically={true}
|
||||||
large={true}
|
large={true}
|
||||||
|
disabled={true}
|
||||||
intent={inputIntent({ error, touched })}
|
intent={inputIntent({ error, touched })}
|
||||||
{...field}
|
{...field}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,27 +1,41 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DialogContent } from 'components';
|
import { DialogContent } from 'components';
|
||||||
import { useCustomers } from 'hooks/query';
|
import {
|
||||||
|
useInvoice,
|
||||||
|
useCreateNotifyInvoiceBySMS,
|
||||||
|
useInvocieSMSDetails,
|
||||||
|
} from 'hooks/query';
|
||||||
|
|
||||||
const NotifyContactViaSMSContext = React.createContext();
|
const NotifyContactViaSMSContext = React.createContext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify contact via SMS provider.
|
* Notify contact via SMS provider.
|
||||||
*/
|
*/
|
||||||
function NotifyContactViaSMSFormProvider({ dialogName, ...props }) {
|
function NotifyContactViaSMSFormProvider({ invoiceId, dialogName, ...props }) {
|
||||||
// Fetches customers list.
|
// Handle fetch invoice data.
|
||||||
const {
|
const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(invoiceId, {
|
||||||
data: { customers },
|
enabled: !!invoiceId,
|
||||||
isLoading: isCustomersLoading,
|
});
|
||||||
} = useCustomers();
|
|
||||||
|
const { data: invoiceSMSDetail, isLoading: isInvoiceSMSDetailLoading } =
|
||||||
|
useInvocieSMSDetails(invoiceId, {
|
||||||
|
enabled: !!invoiceId,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create notfiy invoice by sms mutations.
|
||||||
|
const { mutateAsync: createNotifyInvoiceBySMSMutate } =
|
||||||
|
useCreateNotifyInvoiceBySMS();
|
||||||
|
|
||||||
// State provider.
|
// State provider.
|
||||||
const provider = {
|
const provider = {
|
||||||
|
invoiceId,
|
||||||
|
invoiceSMSDetail,
|
||||||
dialogName,
|
dialogName,
|
||||||
customers,
|
createNotifyInvoiceBySMSMutate,
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DialogContent isLoading={isCustomersLoading}>
|
<DialogContent isLoading={isInvoiceLoading || isInvoiceSMSDetailLoading}>
|
||||||
<NotifyContactViaSMSContext.Provider value={provider} {...props} />
|
<NotifyContactViaSMSContext.Provider value={provider} {...props} />
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,18 +12,25 @@ const NotifyContactViaSMSDialogContent = React.lazy(() =>
|
|||||||
/**
|
/**
|
||||||
* Notify contact via SMS.
|
* Notify contact via SMS.
|
||||||
*/
|
*/
|
||||||
function NotifyContactViaSMSDialog({ dialogName, payload, isOpen }) {
|
function NotifyContactViaSMSDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { invoiceId },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
name={dialogName}
|
name={dialogName}
|
||||||
title={'Notify via SMS'}
|
title={<T id={'notify_via_sms.dialog.notify_via_sms'} />}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
canEscapeJeyClose={true}
|
canEscapeJeyClose={true}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
className={'dialog--notify-vis-sms'}
|
className={'dialog--notify-vis-sms'}
|
||||||
>
|
>
|
||||||
<DialogSuspense>
|
<DialogSuspense>
|
||||||
<NotifyContactViaSMSDialogContent dialogName={dialogName} />
|
<NotifyContactViaSMSDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
invoice={invoiceId}
|
||||||
|
/>
|
||||||
</DialogSuspense>
|
</DialogSuspense>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,28 +6,17 @@ import {
|
|||||||
NavbarGroup,
|
NavbarGroup,
|
||||||
Classes,
|
Classes,
|
||||||
NavbarDivider,
|
NavbarDivider,
|
||||||
Popover,
|
|
||||||
PopoverInteractionKind,
|
|
||||||
Position,
|
|
||||||
Intent,
|
Intent,
|
||||||
MenuItem,
|
|
||||||
Menu,
|
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||||
|
|
||||||
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
|
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
|
||||||
import { moreVertOptions } from '../../../common/moreVertOptions';
|
|
||||||
|
|
||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||||
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||||
|
|
||||||
import {
|
import { If, Icon, FormattedMessage as T } from 'components';
|
||||||
If,
|
|
||||||
Icon,
|
|
||||||
FormattedMessage as T,
|
|
||||||
// MoreVertMenutItems,
|
|
||||||
} from 'components';
|
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
@@ -78,7 +67,7 @@ function InvoiceDetailActionsBar({
|
|||||||
};
|
};
|
||||||
// Handle notify via SMS.
|
// Handle notify via SMS.
|
||||||
const handleNotifyViaSMS = () => {
|
const handleNotifyViaSMS = () => {
|
||||||
openDialog('notify-via-sms', {});
|
openDialog('notify-via-sms', { invoiceId });
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle cancele write-off invoice.
|
// Handle cancele write-off invoice.
|
||||||
@@ -120,7 +109,6 @@ function InvoiceDetailActionsBar({
|
|||||||
/>
|
/>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
<BadDebtMenuItem
|
<BadDebtMenuItem
|
||||||
invoice={invoice}
|
|
||||||
payload={{
|
payload={{
|
||||||
onBadDebt: handleBadDebtInvoice,
|
onBadDebt: handleBadDebtInvoice,
|
||||||
onCancelBadDebt: handleCancelBadDebtInvoice,
|
onCancelBadDebt: handleCancelBadDebtInvoice,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { Icon, FormattedMessage as T, Choose } from 'components';
|
import { Icon, FormattedMessage as T, Choose } from 'components';
|
||||||
import { FormatNumberCell } from '../../../components';
|
import { FormatNumberCell } from '../../../components';
|
||||||
|
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve invoice readonly details table columns.
|
* Retrieve invoice readonly details table columns.
|
||||||
@@ -59,9 +60,10 @@ export const useInvoiceReadonlyEntriesColumns = () =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const BadDebtMenuItem = ({
|
export const BadDebtMenuItem = ({
|
||||||
invoice,
|
|
||||||
payload: { onCancelBadDebt, onBadDebt, onNotifyViaSMS },
|
payload: { onCancelBadDebt, onBadDebt, onNotifyViaSMS },
|
||||||
}) => {
|
}) => {
|
||||||
|
const { invoice } = useInvoiceDetailDrawerContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover
|
<Popover
|
||||||
minimal={true}
|
minimal={true}
|
||||||
|
|||||||
@@ -189,3 +189,38 @@ export function useRefreshEstimates() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useCreateNotifyEstimateBySMS(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
(id) => apiRequest.post(`sales/estimates/${id}/notify-by-sms`),
|
||||||
|
{
|
||||||
|
onSuccess: (res, id) => {
|
||||||
|
// Common invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
|
||||||
|
// Invalidate sale estimate.
|
||||||
|
queryClient.invalidateQueries([t.NOTIFY_SALE_ESTIMATE_BY_SMS, id]);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useEstimateSMS(estimateId, props, requestProps) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.SALE_ESTIMATE_SMS, estimateId],
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
url: `sales/estimates/${estimateId}/sms-details`,
|
||||||
|
...requestProps,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: (res) => res.data,
|
||||||
|
defaultData: {},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -219,14 +219,52 @@ export function useCancelBadDebt(props) {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
return useMutation((id) => apiRequest.post(`sales/invoices/${id}/writeoff/cancel`), {
|
return useMutation(
|
||||||
onSuccess: (res, id) => {
|
(id) => apiRequest.post(`sales/invoices/${id}/writeoff/cancel`),
|
||||||
// Invalidate
|
{
|
||||||
queryClient.invalidateQueries([t.CANCEL_BAD_DEBT, id]);
|
onSuccess: (res, id) => {
|
||||||
|
// Invalidate
|
||||||
|
queryClient.invalidateQueries([t.CANCEL_BAD_DEBT, id]);
|
||||||
|
|
||||||
// Common invalidate queries.
|
// Common invalidate queries.
|
||||||
commonInvalidateQueries(queryClient);
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
},
|
},
|
||||||
...props,
|
);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
export function useCreateNotifyInvoiceBySMS(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
(id) => apiRequest.post(`sales/invoices/${id}/notify-by-sms`),
|
||||||
|
{
|
||||||
|
onSuccess: (res, id) => {
|
||||||
|
// Invalidate
|
||||||
|
queryClient.invalidateQueries([t.NOTIFY_SALE_INVOICE_BY_SMS, id]);
|
||||||
|
|
||||||
|
// Common invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useInvocieSMSDetails(invoiceId, props, requestProps) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.SALE_INVOICE_SMS, invoiceId],
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
url: `sales/invoices/${invoiceId}/sms-details`,
|
||||||
|
...requestProps,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: (res) => res.data.data,
|
||||||
|
defaultData: {},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,3 +174,34 @@ export function useRefreshPaymentReceive() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useCreateNotifyPaymentReceiveBySMS(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
(id) => apiRequest.post(`sales/payment_receives/${id}/notify-by-sms`),
|
||||||
|
{
|
||||||
|
onSuccess: (res, id) => {
|
||||||
|
// Invalidate
|
||||||
|
queryClient.invalidateQueries([t.NOTIFY_PAYMENT_RECEIVE_BY_SMS, id]);
|
||||||
|
|
||||||
|
// Common invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function usePaymentReceiveSMS(id, props, requestProps) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.PAYMENT_RECEIVE_SMS, id],
|
||||||
|
{ method: 'get', url: `sales/payment_receives/${id}/sms-details`, ...requestProps },
|
||||||
|
{
|
||||||
|
select: (res) => res.data,
|
||||||
|
defaultData: {},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -163,3 +163,32 @@ export function useRefreshReceipts() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useCreateNotifyReceiptBySMS(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
return useMutation(
|
||||||
|
(id) => apiRequest.post(`sales/receipts/${id}/notify-by-sms`),
|
||||||
|
{
|
||||||
|
onSuccess: (res, id) => {
|
||||||
|
queryClient.invalidateQueries([t.NOTIFY_SALE_RECEIPT_BY_SMS, id]);
|
||||||
|
|
||||||
|
// Invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useReceiptSMS(receiptId, props, requestProps) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.SALE_RECEIPT_SMS, receiptId],
|
||||||
|
{ method: 'get', url: `sales/receipts/${receiptId}/sms-details`, ...requestProps },
|
||||||
|
{
|
||||||
|
select: (res) => res.data,
|
||||||
|
defaultData: {},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -123,3 +123,18 @@ export function useSettingCashFlow(props) {
|
|||||||
props,
|
props,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve SMS settings.
|
||||||
|
*/
|
||||||
|
export function useSettingSMSNotifications(props) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.SETTING_SMS_NOTIFICATIONS],
|
||||||
|
{ method: 'get', url: `settings/sms-notifications` },
|
||||||
|
{
|
||||||
|
select: (res) => res.data.notifications,
|
||||||
|
defaultData: [],
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -51,11 +51,15 @@ const ITEMS = {
|
|||||||
const SALE_ESTIMATES = {
|
const SALE_ESTIMATES = {
|
||||||
SALE_ESTIMATES: 'SALE_ESTIMATES',
|
SALE_ESTIMATES: 'SALE_ESTIMATES',
|
||||||
SALE_ESTIMATE: 'SALE_ESTIMATE',
|
SALE_ESTIMATE: 'SALE_ESTIMATE',
|
||||||
|
SALE_ESTIMATE_SMS: 'SALE_ESTIMATE_SMS',
|
||||||
|
NOTIFY_SALE_ESTIMATE_BY_SMS: 'NOTIFY_SALE_ESTIMATE_BY_SMS',
|
||||||
};
|
};
|
||||||
|
|
||||||
const SALE_RECEIPTS = {
|
const SALE_RECEIPTS = {
|
||||||
SALE_RECEIPTS: 'SALE_RECEIPTS',
|
SALE_RECEIPTS: 'SALE_RECEIPTS',
|
||||||
SALE_RECEIPT: 'SALE_RECEIPT',
|
SALE_RECEIPT: 'SALE_RECEIPT',
|
||||||
|
SALE_RECEIPT_SMS: 'SALE_RECEIPT_SMS',
|
||||||
|
NOTIFY_SALE_RECEIPT_BY_SMS: 'NOTIFY_SALE_RECEIPT_BY_SMS',
|
||||||
};
|
};
|
||||||
|
|
||||||
const INVENTORY_ADJUSTMENTS = {
|
const INVENTORY_ADJUSTMENTS = {
|
||||||
@@ -79,12 +83,16 @@ const PAYMENT_RECEIVES = {
|
|||||||
PAYMENT_RECEIVE: 'PAYMENT_RECEIVE',
|
PAYMENT_RECEIVE: 'PAYMENT_RECEIVE',
|
||||||
PAYMENT_RECEIVE_NEW_ENTRIES: 'PAYMENT_RECEIVE_NEW_ENTRIES',
|
PAYMENT_RECEIVE_NEW_ENTRIES: 'PAYMENT_RECEIVE_NEW_ENTRIES',
|
||||||
PAYMENT_RECEIVE_EDIT_PAGE: 'PAYMENT_RECEIVE_EDIT_PAGE',
|
PAYMENT_RECEIVE_EDIT_PAGE: 'PAYMENT_RECEIVE_EDIT_PAGE',
|
||||||
|
PAYMENT_RECEIVE_SMS: 'PAYMENT_RECEIVE_SMS',
|
||||||
|
NOTIFY_PAYMENT_RECEIVE_BY_SMS: 'NOTIFY_PAYMENT_RECEIVE_BY_SMS',
|
||||||
};
|
};
|
||||||
|
|
||||||
const SALE_INVOICES = {
|
const SALE_INVOICES = {
|
||||||
SALE_INVOICES: 'SALE_INVOICES',
|
SALE_INVOICES: 'SALE_INVOICES',
|
||||||
SALE_INVOICE: 'SALE_INVOICE',
|
SALE_INVOICE: 'SALE_INVOICE',
|
||||||
SALE_INVOICES_DUE: 'SALE_INVOICES_DUE',
|
SALE_INVOICES_DUE: 'SALE_INVOICES_DUE',
|
||||||
|
SALE_INVOICE_SMS: 'SALE_INVOICE_SMS',
|
||||||
|
NOTIFY_SALE_INVOICE_BY_SMS: 'NOTIFY_SALE_INVOICE_BY_SMS',
|
||||||
BAD_DEBT: 'BAD_DEBT',
|
BAD_DEBT: 'BAD_DEBT',
|
||||||
CANCEL_BAD_DEBT: 'CANCEL_BAD_DEBT',
|
CANCEL_BAD_DEBT: 'CANCEL_BAD_DEBT',
|
||||||
};
|
};
|
||||||
@@ -103,6 +111,7 @@ const SETTING = {
|
|||||||
SETTING_MANUAL_JOURNALS: 'SETTING_MANUAL_JOURNALS',
|
SETTING_MANUAL_JOURNALS: 'SETTING_MANUAL_JOURNALS',
|
||||||
SETTING_ITEMS: 'SETTING_ITEMS',
|
SETTING_ITEMS: 'SETTING_ITEMS',
|
||||||
SETTING_CASHFLOW: 'SETTING_CASHFLOW',
|
SETTING_CASHFLOW: 'SETTING_CASHFLOW',
|
||||||
|
SETTING_SMS_NOTIFICATIONS: 'SETTING_SMS_NOTIFICATIONS',
|
||||||
};
|
};
|
||||||
|
|
||||||
const ORGANIZATIONS = {
|
const ORGANIZATIONS = {
|
||||||
|
|||||||
Reference in New Issue
Block a user