mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 20:30:33 +00:00
refactoring: invoice, receipt, payment receive, estimate and journal number dialogs.
This commit is contained in:
@@ -5,11 +5,7 @@ import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
|
||||
import ItemCategoryDialog from 'containers/Dialogs/ItemCategoryDialog';
|
||||
import CurrencyFormDialog from 'containers/Dialogs/CurrencyFormDialog';
|
||||
import ExchangeRateFormDialog from 'containers/Dialogs/ExchangeRateFormDialog';
|
||||
import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
|
||||
import PaymentReceiveNumberDialog from 'containers/Dialogs/PaymentReceiveNumberDialog';
|
||||
import EstimateNumberDialog from 'containers/Dialogs/EstimateNumberDialog';
|
||||
import ReceiptNumberDialog from 'containers/Dialogs/ReceiptNumberDialog';
|
||||
import InvoiceNumberDialog from 'containers/Dialogs/InvoiceNumberDialog';
|
||||
|
||||
import InventoryAdjustmentDialog from 'containers/Dialogs/InventoryAdjustmentFormDialog';
|
||||
import PaymentViaVoucherDialog from 'containers/Dialogs/PaymentViaVoucherDialog';
|
||||
|
||||
@@ -20,11 +16,6 @@ export default function DialogsContainer() {
|
||||
return (
|
||||
<div>
|
||||
<AccountDialog dialogName={'account-form'} />
|
||||
<JournalNumberDialog dialogName={'journal-number-form'} />
|
||||
<PaymentReceiveNumberDialog dialogName={'payment-receive-number-form'} />
|
||||
<EstimateNumberDialog dialogName={'estimate-number-form'} />
|
||||
<ReceiptNumberDialog dialogName={'receipt-number-form'} />
|
||||
<InvoiceNumberDialog dialogName={'invoice-number-form'} />
|
||||
<CurrencyFormDialog dialogName={'currency-form'} />
|
||||
<InviteUserDialog dialogName={'invite-user'} />
|
||||
<ExchangeRateFormDialog dialogName={'exchangeRate-form'} />
|
||||
|
||||
@@ -15,6 +15,7 @@ import MakeJournalEntriesHeader from './MakeJournalEntriesHeader';
|
||||
import MakeJournalFormFloatingActions from './MakeJournalFormFloatingActions';
|
||||
import MakeJournalEntriesField from './MakeJournalEntriesField';
|
||||
import MakeJournalFormFooter from './MakeJournalFormFooter';
|
||||
import MakeJournalFormDialogs from './MakeJournalFormDialogs';
|
||||
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
|
||||
@@ -167,6 +168,8 @@ function MakeJournalEntriesForm({
|
||||
<MakeJournalEntriesField />
|
||||
<MakeJournalFormFooter />
|
||||
<MakeJournalFormFloatingActions />
|
||||
|
||||
<MakeJournalFormDialogs />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
|
||||
import { transactionNumber } from 'utils';
|
||||
|
||||
/**
|
||||
* Make journal form dialogs.
|
||||
*/
|
||||
export default function MakeJournalFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the journal number form submit confirm.
|
||||
const handleConfirm = (values) => {
|
||||
setFieldValue(
|
||||
'journal_number',
|
||||
transactionNumber(values.number_prefix, values.next_number),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<JournalNumberDialog
|
||||
dialogName={'journal-number-form'}
|
||||
onConfirm={handleConfirm}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import { useQuery, queryCache } from 'react-query';
|
||||
import { useSaveSettings, useSettingsEstimates } from 'hooks/query';
|
||||
|
||||
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||
|
||||
import { compose, optionsMapToArray } from 'utils';
|
||||
import { compose, optionsMapToArray, saveInvoke } from 'utils';
|
||||
|
||||
/**
|
||||
* Estimate number dialog's content.
|
||||
@@ -18,28 +17,26 @@ function EstimateNumberDialogContent({
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
|
||||
// #withSettingsActions
|
||||
requestFetchOptions,
|
||||
requestSubmitOptions,
|
||||
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
|
||||
// #ownProps
|
||||
onConfirm,
|
||||
}) {
|
||||
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||
const { isLoading: isSettingsLoading } = useSettingsEstimates();
|
||||
const { mutateAsync: saveSettingsMutate } = useSaveSettings();
|
||||
|
||||
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||
const options = optionsMapToArray(values).map((option) => {
|
||||
return { key: option.key, ...option, group: 'sales_estimates' };
|
||||
});
|
||||
requestSubmitOptions({ options })
|
||||
const options = optionsMapToArray(values).map((option) => ({
|
||||
key: option.key,
|
||||
...option,
|
||||
group: 'sales_estimates',
|
||||
}));
|
||||
saveSettingsMutate({ options })
|
||||
.then(() => {
|
||||
setSubmitting(false);
|
||||
closeDialog('estimate-number-form');
|
||||
|
||||
setTimeout(() => {
|
||||
queryCache.invalidateQueries('settings');
|
||||
// setEstimateNumberChanged(true);
|
||||
}, 250);
|
||||
saveInvoke(onConfirm, values);
|
||||
})
|
||||
.catch(() => {
|
||||
setSubmitting(false);
|
||||
@@ -51,7 +48,7 @@ function EstimateNumberDialogContent({
|
||||
}, [closeDialog]);
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={fetchSettings.isFetching}>
|
||||
<DialogContent isLoading={isSettingsLoading}>
|
||||
<ReferenceNumberForm
|
||||
initialNumber={nextNumber}
|
||||
initialPrefix={numberPrefix}
|
||||
@@ -64,7 +61,6 @@ function EstimateNumberDialogContent({
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettingsActions,
|
||||
withSettings(({ estimatesSettings }) => ({
|
||||
nextNumber: estimatesSettings?.nextNumber,
|
||||
numberPrefix: estimatesSettings?.numberPrefix,
|
||||
|
||||
@@ -2,13 +2,18 @@ import React, { lazy } from 'react';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { Dialog, DialogSuspense } from 'components';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import { compose } from 'utils';
|
||||
import { saveInvoke, compose } from 'utils';
|
||||
|
||||
const EstimateNumberDialogContent = lazy(() =>
|
||||
import('./EstimateNumberDialogContent'),
|
||||
);
|
||||
|
||||
function EstimateNumberDialog({ dialogName, paylaod = { id: null }, isOpen }) {
|
||||
function EstimateNumberDialog({
|
||||
dialogName,
|
||||
paylaod = { id: null },
|
||||
isOpen,
|
||||
onConfirm
|
||||
}) {
|
||||
return (
|
||||
<Dialog
|
||||
name={dialogName}
|
||||
@@ -19,7 +24,9 @@ function EstimateNumberDialog({ dialogName, paylaod = { id: null }, isOpen }) {
|
||||
className={'dialog--journal-number-settings'}
|
||||
>
|
||||
<DialogSuspense>
|
||||
<EstimateNumberDialogContent EstimateNumberId={paylaod.id} />
|
||||
<EstimateNumberDialogContent
|
||||
estimateNumberId={paylaod.id}
|
||||
onConfirm={(values) => saveInvoke(onConfirm, values)}/>
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -16,24 +16,30 @@ import { compose, optionsMapToArray } from 'utils';
|
||||
*/
|
||||
|
||||
function InvoiceNumberDialogContent({
|
||||
// #ownProps
|
||||
onConfirm,
|
||||
|
||||
// #withSettings
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
|
||||
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
}) {
|
||||
const { mutateAsync: saveSettings } = useSaveSettings();
|
||||
|
||||
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||
const options = optionsMapToArray(values).map((option) => {
|
||||
return { key: option.key, ...option, group: 'sales_invoices' };
|
||||
});
|
||||
const options = optionsMapToArray(values).map((option) => ({
|
||||
key: option.key,
|
||||
...option,
|
||||
group: 'sales_invoices',
|
||||
}));
|
||||
|
||||
saveSettings({ options })
|
||||
.then(() => {
|
||||
setSubmitting(false);
|
||||
closeDialog('invoice-number-form');
|
||||
onConfirm(values);
|
||||
})
|
||||
.catch(() => {
|
||||
setSubmitting(false);
|
||||
@@ -64,5 +70,4 @@ export default compose(
|
||||
nextNumber: invoiceSettings?.nextNumber,
|
||||
numberPrefix: invoiceSettings?.numberPrefix,
|
||||
})),
|
||||
// withInvoicesActions,
|
||||
)(InvoiceNumberDialogContent);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import { useSettings } from 'hooks/query';
|
||||
import { useSettingsInvoices } from 'hooks/query';
|
||||
|
||||
const InvoiceNumberDialogContext = createContext();
|
||||
|
||||
@@ -8,15 +8,15 @@ const InvoiceNumberDialogContext = createContext();
|
||||
* Invoice number dialog provider.
|
||||
*/
|
||||
function InvoiceNumberDialogProvider({ query, ...props }) {
|
||||
const { isLoading } = useSettings();
|
||||
const { isLoading: isSettingsLoading } = useSettingsInvoices();
|
||||
|
||||
// Provider payload.
|
||||
const provider = {
|
||||
|
||||
isSettingsLoading,
|
||||
};
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isLoading}>
|
||||
<DialogContent isLoading={isSettingsLoading}>
|
||||
<InvoiceNumberDialogContext.Provider value={provider} {...props} />
|
||||
</DialogContent>
|
||||
);
|
||||
|
||||
@@ -2,13 +2,19 @@ import React, { lazy } from 'react';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { Dialog, DialogSuspense } from 'components';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import { compose } from 'utils';
|
||||
import { compose, saveInvoke } from 'utils';
|
||||
|
||||
const InvoiceNumberDialogContent = lazy(() =>
|
||||
import('./InvoiceNumberDialogContent'),
|
||||
);
|
||||
|
||||
function InvoiceNumberDialog({ dialogName, payload = { id: null }, isOpen }) {
|
||||
function InvoiceNumberDialog({
|
||||
dialogName,
|
||||
payload = { id: null },
|
||||
isOpen,
|
||||
onConfirm,
|
||||
}) {
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title={<T id={'invoice_number_settings'} />}
|
||||
@@ -18,7 +24,9 @@ function InvoiceNumberDialog({ dialogName, payload = { id: null }, isOpen }) {
|
||||
isOpen={isOpen}
|
||||
>
|
||||
<DialogSuspense>
|
||||
<InvoiceNumberDialogContent InvoiceNumberId={payload.id} />
|
||||
<InvoiceNumberDialogContent
|
||||
InvoiceNumberId={payload.id}
|
||||
onConfirm={(values) => saveInvoke(onConfirm, values)} />
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import { useQuery, queryCache } from 'react-query';
|
||||
import { useSaveSettings, useSettingsManualJournals } from 'hooks/query';
|
||||
|
||||
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
// import withManualJournalsActions from 'containers/Accounting/withManualJournalsActions';
|
||||
|
||||
import { compose, optionsMapToArray } from 'utils';
|
||||
import { saveInvoke, compose, optionsMapToArray } from 'utils';
|
||||
|
||||
import 'style/pages/ManualJournal/JournalNumberDialog.scss'
|
||||
|
||||
@@ -21,28 +18,25 @@ function JournalNumberDialogContent({
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
|
||||
// #withSettingsActions
|
||||
requestFetchOptions,
|
||||
requestSubmitOptions,
|
||||
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
|
||||
}) {
|
||||
const fetchSettings = useQuery(
|
||||
['settings'],
|
||||
() => requestFetchOptions({}),
|
||||
);
|
||||
// #ownProps
|
||||
onConfirm
|
||||
}) {
|
||||
const { isLoading: isSettingsLoading } = useSettingsManualJournals();
|
||||
const { mutateAsync: saveSettingsMutate } = useSaveSettings();
|
||||
|
||||
// Handle the form submit.
|
||||
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||
const options = optionsMapToArray(values).map((option) => ({
|
||||
key: option.key, ...option, group: 'manual_journals',
|
||||
}));
|
||||
|
||||
requestSubmitOptions({ options }).then(() => {
|
||||
saveSettingsMutate({ options }).then(() => {
|
||||
setSubmitting(false);
|
||||
closeDialog('journal-number-form');
|
||||
|
||||
saveInvoke(onConfirm, values);
|
||||
}).catch(() => {
|
||||
setSubmitting(false);
|
||||
});
|
||||
@@ -53,7 +47,7 @@ function JournalNumberDialogContent({
|
||||
}, [closeDialog]);
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={fetchSettings.isFetching}>
|
||||
<DialogContent isLoading={isSettingsLoading}>
|
||||
<ReferenceNumberForm
|
||||
initialNumber={nextNumber}
|
||||
initialPrefix={numberPrefix}
|
||||
@@ -66,10 +60,8 @@ function JournalNumberDialogContent({
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettingsActions,
|
||||
withSettings(({ manualJournalsSettings }) => ({
|
||||
nextNumber: manualJournalsSettings?.nextNumber,
|
||||
numberPrefix: manualJournalsSettings?.numberPrefix,
|
||||
})),
|
||||
// withManualJournalsActions,
|
||||
)(JournalNumberDialogContent);
|
||||
@@ -2,7 +2,7 @@ import React, { lazy } from 'react';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { Dialog, DialogSuspense } from 'components';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import { compose } from 'utils';
|
||||
import { saveInvoke, compose } from 'utils';
|
||||
|
||||
const JournalNumberDialogContent = lazy(() => import('./JournalNumberDialogContent'));
|
||||
|
||||
@@ -10,7 +10,12 @@ function JournalNumberDialog({
|
||||
dialogName,
|
||||
payload = { id: null },
|
||||
isOpen,
|
||||
onConfirm
|
||||
}) {
|
||||
|
||||
const handleConfirm = (values) => {
|
||||
saveInvoke(onConfirm, values)
|
||||
};
|
||||
return (
|
||||
<Dialog
|
||||
name={dialogName}
|
||||
@@ -23,6 +28,7 @@ function JournalNumberDialog({
|
||||
<DialogSuspense>
|
||||
<JournalNumberDialogContent
|
||||
journalNumberId={payload.id}
|
||||
onConfirm={handleConfirm}
|
||||
/>
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import { useQuery } from 'react-query';
|
||||
import { useSaveSettings, useSettingsPaymentReceives } from 'hooks/query';
|
||||
|
||||
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
// import withPaymentReceivesActions from 'containers/Sales/PaymentReceive/withPaymentReceivesActions';
|
||||
|
||||
import { compose, optionsMapToArray } from 'utils';
|
||||
import { saveInvoke, compose, optionsMapToArray } from 'utils';
|
||||
|
||||
/**
|
||||
* payment receive number dialog's content.
|
||||
@@ -20,31 +19,28 @@ function PaymentNumberDialogContent({
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
|
||||
// #withSettingsActions
|
||||
requestFetchOptions,
|
||||
requestSubmitOptions,
|
||||
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
|
||||
// #withPaymentReceivesActions
|
||||
// setPaymentReceiveNumberChanged,
|
||||
// #ownProps
|
||||
onConfirm,
|
||||
}) {
|
||||
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||
const { isLoading: isSettingsLoading } = useSettingsPaymentReceives();
|
||||
const { mutateAsync: saveSettingsMutate } = useSaveSettings();
|
||||
|
||||
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||
const options = optionsMapToArray(values).map((option) => {
|
||||
return { key: option.key, ...option, group: 'payment_receives' };
|
||||
});
|
||||
const options = optionsMapToArray(values).map((option) => ({
|
||||
key: option.key,
|
||||
...option,
|
||||
group: 'payment_receives',
|
||||
}));
|
||||
|
||||
requestSubmitOptions({ options })
|
||||
saveSettingsMutate({ options })
|
||||
.then(() => {
|
||||
setSubmitting(false);
|
||||
closeDialog('payment-receive-number-form');
|
||||
|
||||
setTimeout(() => {
|
||||
// setPaymentReceiveNumberChanged(true);
|
||||
}, 250);
|
||||
saveInvoke(onConfirm, values);
|
||||
})
|
||||
.catch(() => {
|
||||
setSubmitting(false);
|
||||
@@ -55,9 +51,8 @@ function PaymentNumberDialogContent({
|
||||
closeDialog('payment-receive-number-form');
|
||||
}, [closeDialog]);
|
||||
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={fetchSettings.isFetching}>
|
||||
<DialogContent isLoading={isSettingsLoading}>
|
||||
<ReferenceNumberForm
|
||||
initialNumber={nextNumber}
|
||||
initialPrefix={numberPrefix}
|
||||
@@ -75,5 +70,4 @@ export default compose(
|
||||
nextNumber: paymentReceiveSettings?.nextNumber,
|
||||
numberPrefix: paymentReceiveSettings?.numberPrefix,
|
||||
})),
|
||||
// withPaymentReceivesActions,
|
||||
)(PaymentNumberDialogContent);
|
||||
|
||||
@@ -2,16 +2,20 @@ import React, { lazy } from 'react';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { Dialog, DialogSuspense } from 'components';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import { compose } from 'utils';
|
||||
import { saveInvoke, compose } from 'utils';
|
||||
|
||||
const PaymentReceiveNumbereDialogConetnet = lazy(() =>
|
||||
import('./PaymentReceiveNumberDialogContent'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Payment receive number dialog.
|
||||
*/
|
||||
function PaymentReceiveNumberDialog({
|
||||
dialogName,
|
||||
payload = { id: null },
|
||||
isOpen,
|
||||
onConfirm
|
||||
}) {
|
||||
return (
|
||||
<Dialog
|
||||
@@ -24,6 +28,7 @@ function PaymentReceiveNumberDialog({
|
||||
<DialogSuspense>
|
||||
<PaymentReceiveNumbereDialogConetnet
|
||||
paymentReceiveNumberId={payload.id}
|
||||
onConfirm={(values) => saveInvoke(onConfirm, values)}
|
||||
/>
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
|
||||
@@ -1,49 +1,45 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { DialogContent } from 'components';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import { useSettingsReceipts, useSaveSettings } from 'hooks/query';
|
||||
import ReferenceNumberForm from 'containers/JournalNumber/ReferenceNumberForm';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
import withSettingsActions from 'containers/Settings/withSettingsActions';
|
||||
|
||||
import { compose, optionsMapToArray } from 'utils';
|
||||
import { compose, optionsMapToArray, saveInvoke } from 'utils';
|
||||
|
||||
/**
|
||||
* Receipt number dialog's content.
|
||||
*/
|
||||
|
||||
function ReceiptNumberDialogContent({
|
||||
// #ownProps
|
||||
receiptId,
|
||||
onConfirm,
|
||||
|
||||
// #withSettings
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
|
||||
// #withSettingsActions
|
||||
requestFetchOptions,
|
||||
requestSubmitOptions,
|
||||
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
|
||||
// #withReceiptActions
|
||||
setReceiptNumberChanged,
|
||||
}) {
|
||||
const fetchSettings = useQuery(['settings'], () => requestFetchOptions({}));
|
||||
const { isLoading: isSettingsLoading } = useSettingsReceipts();
|
||||
const { mutateAsync: saveSettingsMutate } = useSaveSettings();
|
||||
|
||||
const handleSubmitForm = (values, { setSubmitting }) => {
|
||||
const options = optionsMapToArray(values).map((option) => {
|
||||
return { key: option.key, ...option, group: 'sales_receipts' };
|
||||
});
|
||||
const options = optionsMapToArray(values).map((option) => ({
|
||||
key: option.key,
|
||||
...option,
|
||||
group: 'sales_receipts',
|
||||
}));
|
||||
|
||||
requestSubmitOptions({ options })
|
||||
saveSettingsMutate({ options })
|
||||
.then(() => {
|
||||
setSubmitting(false);
|
||||
closeDialog('receipt-number-form');
|
||||
|
||||
setTimeout(() => {
|
||||
setReceiptNumberChanged(true);
|
||||
}, 250);
|
||||
saveInvoke(onConfirm, values)
|
||||
})
|
||||
.catch(() => {
|
||||
setSubmitting(false);
|
||||
@@ -55,7 +51,7 @@ function ReceiptNumberDialogContent({
|
||||
}, [closeDialog]);
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={fetchSettings.isFetching}>
|
||||
<DialogContent isLoading={isSettingsLoading}>
|
||||
<ReferenceNumberForm
|
||||
initialNumber={nextNumber}
|
||||
initialPrefix={numberPrefix}
|
||||
@@ -68,7 +64,6 @@ function ReceiptNumberDialogContent({
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettingsActions,
|
||||
withSettings(({ receiptSettings }) => ({
|
||||
nextNumber: receiptSettings?.nextNumber,
|
||||
numberPrefix: receiptSettings?.numberPrefix,
|
||||
|
||||
@@ -2,13 +2,25 @@ import React, { lazy } from 'react';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { Dialog, DialogSuspense } from 'components';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import { compose } from 'utils';
|
||||
import { compose, saveInvoke } from 'utils';
|
||||
|
||||
const ReceiptNumberDialogContent = lazy(() =>
|
||||
import('./ReceiptNumberDialogContent'),
|
||||
);
|
||||
|
||||
function ReceiptNumberDialog({ dialogName, paylaod = { id: null }, isOpen }) {
|
||||
/**
|
||||
* Sale receipt number dialog.
|
||||
*/
|
||||
function ReceiptNumberDialog({
|
||||
dialogName,
|
||||
paylaod = { id: null },
|
||||
isOpen,
|
||||
onConfirm,
|
||||
}) {
|
||||
const handleConfirm = (values) => {
|
||||
saveInvoke(onConfirm, values);
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
name={dialogName}
|
||||
@@ -18,7 +30,10 @@ function ReceiptNumberDialog({ dialogName, paylaod = { id: null }, isOpen }) {
|
||||
isOpen={isOpen}
|
||||
>
|
||||
<DialogSuspense>
|
||||
<ReceiptNumberDialogContent ReceiptNumberId={paylaod.id} />
|
||||
<ReceiptNumberDialogContent
|
||||
receiptId={paylaod.id}
|
||||
onConfirm={handleConfirm}
|
||||
/>
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import { shortcutBox } from 'common/homepageOptions';
|
||||
import { Icon } from 'components';
|
||||
|
||||
function ShortcutBox({ title, iconColor, description }) {
|
||||
return (
|
||||
<div className={'shortcut-box'}>
|
||||
<div className={'shortcut-box__header'}>
|
||||
<span
|
||||
className={'header--icon'}
|
||||
style={{ backgroundColor: `${iconColor}` }}
|
||||
>
|
||||
<Icon icon={'clock'} iconSize={24} />
|
||||
</span>
|
||||
<span>
|
||||
<a href={'#'}>
|
||||
<a href={'#'}>
|
||||
<div className={'shortcut-box__header'}>
|
||||
<span
|
||||
className={'header--icon'}
|
||||
style={{ backgroundColor: `${iconColor}` }}
|
||||
>
|
||||
<Icon icon={'clock'} iconSize={24} />
|
||||
</span>
|
||||
<span>
|
||||
<Icon icon={'arrow-top-right'} iconSize={24} />
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
<div className={'shortcut-box__title'}>{title}</div>
|
||||
<div className={'shortcut-box__description'}>{description}</div>
|
||||
</span>
|
||||
</div>
|
||||
<div className={'shortcut-box__title'}>{title}</div>
|
||||
<div className={'shortcut-box__description'}>{description}</div>
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { ErrorMessage, FastField, useFormikContext } from 'formik';
|
||||
import { ErrorMessage, FastField } from 'formik';
|
||||
import {
|
||||
CategoriesSelectList,
|
||||
Hint,
|
||||
@@ -26,13 +26,11 @@ import { handleStringChange, inputIntent } from 'utils';
|
||||
* Item form primary section.
|
||||
*/
|
||||
export default function ItemFormPrimarySection() {
|
||||
const { itemsCategories } = useItemFormContext();
|
||||
// Item form context.
|
||||
const { isNewMode, item, itemsCategories } = useItemFormContext();
|
||||
|
||||
const nameFieldRef = useRef(null);
|
||||
|
||||
// Formik context.
|
||||
const { values: { type } } = useFormikContext();
|
||||
|
||||
useEffect(() => {
|
||||
// Auto focus item name field once component mount.
|
||||
if (nameFieldRef.current) {
|
||||
@@ -87,7 +85,7 @@ export default function ItemFormPrimarySection() {
|
||||
form.setFieldValue('type', _value);
|
||||
})}
|
||||
selectedValue={value}
|
||||
disabled={type === 'inventory'}
|
||||
disabled={!isNewMode && item.type === 'inventory'}
|
||||
>
|
||||
<Radio label={<T id={'service'} />} value="service" />
|
||||
<Radio label={<T id={'non_inventory'} />} value="non-inventory" />
|
||||
|
||||
@@ -58,9 +58,8 @@ export default function ReferenceNumberForm({
|
||||
tincidunt porta quam,
|
||||
</p>
|
||||
<Row>
|
||||
{/* prefix */}
|
||||
<Col>
|
||||
|
||||
{/* ------------- Prefix ------------- */}
|
||||
<Col xs={6}>
|
||||
<FormGroup
|
||||
label={<T id={'prefix'} />}
|
||||
className={'form-group--'}
|
||||
@@ -75,8 +74,9 @@ export default function ReferenceNumberForm({
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
{/* next_number */}
|
||||
<Col>
|
||||
|
||||
{/* ------------- Next number ------------- */}
|
||||
<Col xs={6}>
|
||||
<FormGroup
|
||||
label={<T id={'next_number'} />}
|
||||
className={'form-group--'}
|
||||
|
||||
@@ -16,6 +16,7 @@ import EstimateFormHeader from './EstimateFormHeader';
|
||||
import EstimateItemsEntriesField from './EstimateItemsEntriesField';
|
||||
import EstimateFloatingActions from './EstimateFloatingActions';
|
||||
import EstimateFormFooter from './EstimateFormFooter';
|
||||
import EstimateFormDialogs from './EstimateFormDialogs';
|
||||
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
|
||||
@@ -158,12 +159,11 @@ function EstimateForm({
|
||||
>
|
||||
<Form>
|
||||
<EstimateFormHeader />
|
||||
|
||||
<div className={classNames(CLASSES.PAGE_FORM_BODY)}>
|
||||
<EstimateItemsEntriesField />
|
||||
</div>
|
||||
<EstimateItemsEntriesField />
|
||||
<EstimateFormFooter />
|
||||
<EstimateFloatingActions />
|
||||
|
||||
<EstimateFormDialogs />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import EstimateNumberDialog from 'containers/Dialogs/EstimateNumberDialog';
|
||||
import { transactionNumber } from 'utils';
|
||||
|
||||
/**
|
||||
* Estimate form dialogs.
|
||||
*/
|
||||
export default function EstimateFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the invoice number form submit confirm.
|
||||
const handleEstimateNumberFormConfirm = (values) => {
|
||||
setFieldValue(
|
||||
'estimate_number',
|
||||
transactionNumber(values.number_prefix, values.next_number),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<EstimateNumberDialog
|
||||
dialogName={'estimate-number-form'}
|
||||
onConfirm={handleEstimateNumberFormConfirm}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -32,7 +32,7 @@ function EstimateFormHeader({
|
||||
}) {
|
||||
const { customers } = useEstimateFormContext();
|
||||
|
||||
const handleEstimateNumberChange = () => {
|
||||
const handleEstimateNumberBtnClick = () => {
|
||||
openDialog('estimate-number-form', {});
|
||||
};
|
||||
|
||||
@@ -135,7 +135,7 @@ function EstimateFormHeader({
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleEstimateNumberChange,
|
||||
onClick: handleEstimateNumberBtnClick,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import React from 'react';
|
||||
import { FastField } from 'formik';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import ItemsEntriesTable from 'containers/Entries/ItemsEntriesTable';
|
||||
import { useEstimateFormContext } from './EstimateFormProvider';
|
||||
|
||||
@@ -10,18 +12,20 @@ export default function EstimateFormItemsEntriesField() {
|
||||
const { items } = useEstimateFormContext();
|
||||
|
||||
return (
|
||||
<FastField name={'entries'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<ItemsEntriesTable
|
||||
entries={value}
|
||||
onUpdateData={(entries) => {
|
||||
form.setFieldValue('entries', entries);
|
||||
}}
|
||||
items={items}
|
||||
errors={error}
|
||||
linesNumber={4}
|
||||
/>
|
||||
)}
|
||||
</FastField>
|
||||
<div className={classNames(CLASSES.PAGE_FORM_BODY)}>
|
||||
<FastField name={'entries'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<ItemsEntriesTable
|
||||
entries={value}
|
||||
onUpdateData={(entries) => {
|
||||
form.setFieldValue('entries', entries);
|
||||
}}
|
||||
items={items}
|
||||
errors={error}
|
||||
linesNumber={4}
|
||||
/>
|
||||
)}
|
||||
</FastField>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import InvoiceFormHeader from './InvoiceFormHeader';
|
||||
import InvoiceItemsEntriesEditorField from './InvoiceItemsEntriesEditorField';
|
||||
import InvoiceFloatingActions from './InvoiceFloatingActions';
|
||||
import InvoiceFormFooter from './InvoiceFormFooter';
|
||||
import InvoiceFormDialogs from './InvoiceFormDialogs';
|
||||
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withMediaActions from 'containers/Media/withMediaActions';
|
||||
@@ -159,6 +160,7 @@ function InvoiceForm({
|
||||
</div>
|
||||
<InvoiceFormFooter />
|
||||
<InvoiceFloatingActions />
|
||||
<InvoiceFormDialogs />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import InvoiceNumberDialog from 'containers/Dialogs/InvoiceNumberDialog';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { transactionNumber } from 'utils';
|
||||
|
||||
/**
|
||||
* Invoice form dialogs.
|
||||
*/
|
||||
export default function InvoiceFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the invoice number form submit confirm.
|
||||
const handleInvoiceNumberFormConfirm = (values) => {
|
||||
setFieldValue(
|
||||
'invoice_no',
|
||||
transactionNumber(values.number_prefix, values.next_number),
|
||||
);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<InvoiceNumberDialog
|
||||
dialogName={'invoice-number-form'}
|
||||
onConfirm={handleInvoiceNumberFormConfirm}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
useCustomers,
|
||||
useCreateInvoice,
|
||||
useEditInvoice,
|
||||
useSettingsInvoices,
|
||||
} from 'hooks/query';
|
||||
|
||||
const InvoiceFormContext = createContext();
|
||||
@@ -14,7 +15,7 @@ const InvoiceFormContext = createContext();
|
||||
* Accounts chart data provider.
|
||||
*/
|
||||
function InvoiceFormProvider({ invoiceId, ...props }) {
|
||||
const { data: invoice, isFetching: isInvoiceLoading } = useInvoice(
|
||||
const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(
|
||||
invoiceId,
|
||||
{
|
||||
enabled: !!invoiceId,
|
||||
@@ -24,21 +25,24 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
|
||||
// Handle fetching the items table based on the given query.
|
||||
const {
|
||||
data: { items },
|
||||
isFetching: isItemsLoading,
|
||||
isLoading: isItemsLoading,
|
||||
} = useItems();
|
||||
|
||||
// Handle fetch customers data table or list
|
||||
const {
|
||||
data: { customers },
|
||||
isFetching: isCustomersLoading,
|
||||
isLoading: isCustomersLoading,
|
||||
} = useCustomers();
|
||||
|
||||
// Handle fetching settings.
|
||||
const { isLoading: isSettingsLoading } = useSettingsInvoices();
|
||||
|
||||
// Create and edit invoice mutations.
|
||||
const { mutateAsync: createInvoiceMutate } = useCreateInvoice();
|
||||
const { mutateAsync: editInvoiceMutate } = useEditInvoice();
|
||||
|
||||
// Form submit payload.
|
||||
const [submitPayload, setSubmitPayload] = useState({});
|
||||
const [submitPayload, setSubmitPayload] = useState();
|
||||
|
||||
// Detarmines whether the form in new mode.
|
||||
const isNewMode = !invoiceId;
|
||||
@@ -53,16 +57,22 @@ function InvoiceFormProvider({ invoiceId, ...props }) {
|
||||
isInvoiceLoading,
|
||||
isItemsLoading,
|
||||
isCustomersLoading,
|
||||
isSettingsLoading,
|
||||
|
||||
createInvoiceMutate,
|
||||
editInvoiceMutate,
|
||||
setSubmitPayload,
|
||||
isNewMode
|
||||
isNewMode,
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardInsider
|
||||
loading={isInvoiceLoading || isItemsLoading || isCustomersLoading}
|
||||
loading={
|
||||
isInvoiceLoading ||
|
||||
isItemsLoading ||
|
||||
isCustomersLoading ||
|
||||
isSettingsLoading
|
||||
}
|
||||
name={'invoice-form'}
|
||||
>
|
||||
<InvoiceFormContext.Provider value={provider} {...props} />
|
||||
|
||||
@@ -12,6 +12,7 @@ import PaymentReceiveFormBody from './PaymentReceiveFormBody';
|
||||
import PaymentReceiveFloatingActions from './PaymentReceiveFloatingActions';
|
||||
import PaymentReceiveFormFooter from './PaymentReceiveFormFooter';
|
||||
import PaymentReceiveFormAlerts from './PaymentReceiveFormAlerts';
|
||||
import PaymentReceiveFormDialogs from './PaymentReceiveFormDialogs';
|
||||
import { PaymentReceiveInnerProvider } from './PaymentReceiveInnerProvider';
|
||||
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
@@ -164,7 +165,9 @@ function PaymentReceiveForm({
|
||||
<PaymentReceiveFormFooter />
|
||||
<PaymentReceiveFloatingActions />
|
||||
|
||||
{/* Alerts & Dialogs */}
|
||||
<PaymentReceiveFormAlerts />
|
||||
<PaymentReceiveFormDialogs />
|
||||
</PaymentReceiveInnerProvider>
|
||||
</Form>
|
||||
</Formik>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import PaymentReceiveNumberDialog from 'containers/Dialogs/PaymentReceiveNumberDialog';
|
||||
import { transactionNumber } from 'utils';
|
||||
|
||||
/**
|
||||
* Payment receive form dialogs.
|
||||
*/
|
||||
export default function PaymentReceiveFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
const handleUpdatePaymentNumber = (values) => {
|
||||
setFieldValue(
|
||||
'payment_receive_no',
|
||||
transactionNumber(values.number_prefix, values.next_number),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<PaymentReceiveNumberDialog
|
||||
dialogName={'payment-receive-number-form'}
|
||||
onConfirm={handleUpdatePaymentNumber}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
Money,
|
||||
} from 'components';
|
||||
import { usePaymentReceiveFormContext } from './PaymentReceiveFormProvider';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
|
||||
import { amountPaymentEntries, fullAmountPaymentEntries } from './utils';
|
||||
@@ -41,7 +41,12 @@ import { toSafeInteger } from 'lodash';
|
||||
/**
|
||||
* Payment receive header fields.
|
||||
*/
|
||||
function PaymentReceiveHeaderFields({ baseCurrency }) {
|
||||
function PaymentReceiveHeaderFields({
|
||||
baseCurrency,
|
||||
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
}) {
|
||||
// Payment receive form context.
|
||||
const { customers, accounts, isNewMode } = usePaymentReceiveFormContext();
|
||||
|
||||
@@ -73,6 +78,12 @@ function PaymentReceiveHeaderFields({ baseCurrency }) {
|
||||
setFieldValue('entries', newEntries);
|
||||
};
|
||||
|
||||
|
||||
// Handle click open payment receive number dialog.
|
||||
const handleClickOpenDialog = () => {
|
||||
openDialog('payment-receive-number-form')
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
{/* ------------- Customer name ------------- */}
|
||||
@@ -185,7 +196,7 @@ function PaymentReceiveHeaderFields({ baseCurrency }) {
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
// onClick: handlePaymentReceiveNumberChange,
|
||||
onClick: handleClickOpenDialog,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
@@ -253,4 +264,5 @@ export default compose(
|
||||
withSettings(({ organizationSettings }) => ({
|
||||
baseCurrency: organizationSettings?.baseCurrency,
|
||||
})),
|
||||
withDialogActions
|
||||
)(PaymentReceiveHeaderFields);
|
||||
|
||||
@@ -21,6 +21,7 @@ import ReceiptFromHeader from './ReceiptFormHeader';
|
||||
import ReceiptItemsEntriesEditor from './ReceiptItemsEntriesEditor';
|
||||
import ReceiptFormFloatingActions from './ReceiptFormFloatingActions';
|
||||
import ReceiptFormFooter from './ReceiptFormFooter';
|
||||
import ReceiptFormDialogs from './ReceiptFormDialogs';
|
||||
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
@@ -170,6 +171,8 @@ function ReceiptForm({
|
||||
<ReceiptItemsEntriesEditor />
|
||||
<ReceiptFormFooter />
|
||||
<ReceiptFormFloatingActions />
|
||||
|
||||
<ReceiptFormDialogs />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import ReceiptNumberDialog from 'containers/Dialogs/ReceiptNumberDialog';
|
||||
import { transactionNumber } from 'utils';
|
||||
|
||||
/**
|
||||
* Receipt form dialogs.
|
||||
*/
|
||||
export default function ReceiptFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the receipt number form submit confirm.
|
||||
const handleReceiptNumberFormConfirm = (values) => {
|
||||
setFieldValue(
|
||||
'receipt_number',
|
||||
transactionNumber(values.number_prefix, values.next_number),
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<ReceiptNumberDialog
|
||||
dialogName={'receipt-number-form'}
|
||||
onConfirm={handleReceiptNumberFormConfirm}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -39,7 +39,7 @@ function ReceiptFormProvider({ receiptId, ...props }) {
|
||||
} = useItems();
|
||||
|
||||
// Fetch receipt settings.
|
||||
const { isFetching: isSettingLoading } = useSettings();
|
||||
const { isLoading: isSettingLoading } = useSettings();
|
||||
|
||||
const { mutateAsync: createReceiptMutate } = useCreateReceipt();
|
||||
const { mutateAsync: editReceiptMutate } = useEditReceipt();
|
||||
|
||||
@@ -11,9 +11,11 @@ export function useCreateBill(props) {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
return useMutation((values) => apiRequest.post('purchases/bills', values), {
|
||||
onSuccess: () => {
|
||||
onSuccess: (res, values) => {
|
||||
queryClient.invalidateQueries('BILLS');
|
||||
queryClient.invalidateQueries('BILL');
|
||||
queryClient.invalidateQueries(['VENDORS']);
|
||||
queryClient.invalidateQueries(['VENDOR', values.vendor_id]);
|
||||
},
|
||||
...props,
|
||||
});
|
||||
@@ -29,9 +31,11 @@ export function useEditBill(props) {
|
||||
return useMutation(
|
||||
([id, values]) => apiRequest.post(`purchases/bills/${id}`, values),
|
||||
{
|
||||
onSuccess: () => {
|
||||
onSuccess: (res, [id, values]) => {
|
||||
queryClient.invalidateQueries('BILLS');
|
||||
queryClient.invalidateQueries('BILL');
|
||||
queryClient.invalidateQueries(['VENDORS']);
|
||||
queryClient.invalidateQueries(['VENDOR', values.vendor_id]);
|
||||
},
|
||||
...props,
|
||||
},
|
||||
@@ -46,9 +50,10 @@ export function useDeleteBill(props) {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
return useMutation((id) => apiRequest.delete(`purchases/bills/${id}`), {
|
||||
onSuccess: () => {
|
||||
onSuccess: (res, id) => {
|
||||
queryClient.invalidateQueries('BILLS');
|
||||
queryClient.invalidateQueries('BILL');
|
||||
queryClient.invalidateQueries(['VENDORS']);
|
||||
},
|
||||
...props,
|
||||
});
|
||||
@@ -122,6 +127,7 @@ export function useOpenBill(props) {
|
||||
{
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('BILLS');
|
||||
queryClient.invalidateQueries(['VENDORS']);
|
||||
},
|
||||
...props,
|
||||
},
|
||||
|
||||
@@ -13,6 +13,7 @@ export function useCreateEstimate(props) {
|
||||
return useMutation((values) => apiRequest.post('sales/estimates', values), {
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries('SALE_ESTIMATES');
|
||||
queryClient.invalidateQueries(['SETTINGS', 'ESTIMATES']);
|
||||
},
|
||||
...props,
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ export const useAuthInviteAccept = (props) => {
|
||||
return useMutation(
|
||||
([values, token]) => apiRequest.post(`invite/accept/${token}`, values),
|
||||
props,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,8 +11,11 @@ export function useCreateInvoice(props) {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
return useMutation((values) => apiRequest.post('sales/invoices', values), {
|
||||
onSuccess: () => {
|
||||
onSuccess: (values) => {
|
||||
queryClient.invalidateQueries('SALE_INVOICES');
|
||||
queryClient.invalidateQueries(['SETTINGS', 'INVOICES']);
|
||||
queryClient.invalidateQueries('CUSTOMERS');
|
||||
queryClient.invalidateQueries(['CUSTOMER', values.customer_id]);
|
||||
},
|
||||
...props,
|
||||
});
|
||||
@@ -28,9 +31,11 @@ export function useEditInvoice(props) {
|
||||
return useMutation(
|
||||
([id, values]) => apiRequest.post(`sales/invoices/${id}`, values),
|
||||
{
|
||||
onSuccess: (res, id) => {
|
||||
onSuccess: (res, [id, values]) => {
|
||||
queryClient.invalidateQueries('SALE_INVOICES');
|
||||
queryClient.invalidateQueries(['SALE_INVOICE', id]);
|
||||
queryClient.invalidateQueries('CUSTOMERS');
|
||||
queryClient.invalidateQueries(['CUSTOMER', values.customer_id]);
|
||||
},
|
||||
...props,
|
||||
},
|
||||
@@ -48,6 +53,7 @@ export function useDeleteInvoice(props) {
|
||||
onSuccess: (res, id) => {
|
||||
queryClient.invalidateQueries('SALE_INVOICES');
|
||||
queryClient.invalidateQueries(['SALE_INVOICE', id]);
|
||||
queryClient.invalidateQueries('CUSTOMERS');
|
||||
},
|
||||
...props,
|
||||
});
|
||||
@@ -97,6 +103,7 @@ export function useDeliverInvoice(props) {
|
||||
onSuccess: (res, id) => {
|
||||
queryClient.invalidateQueries('SALE_INVOICES');
|
||||
queryClient.invalidateQueries(['SALE_INVOICE', id]);
|
||||
queryClient.invalidateQueries('CUSTOMERS');
|
||||
},
|
||||
...props,
|
||||
});
|
||||
|
||||
@@ -3,34 +3,6 @@ import { useDispatch } from 'react-redux';
|
||||
import useApiRequest from '../useRequest';
|
||||
import t from 'store/types';
|
||||
|
||||
/**
|
||||
* Retrieve settings.
|
||||
*/
|
||||
export function useSettings(query, props) {
|
||||
const dispatch = useDispatch();
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
const settings = useQuery(
|
||||
['SETTINGS', query],
|
||||
async () => {
|
||||
const {
|
||||
data: { settings },
|
||||
} = await apiRequest.get('settings', { params: query });
|
||||
|
||||
return settings;
|
||||
},
|
||||
{
|
||||
initialData: [],
|
||||
...props,
|
||||
},
|
||||
);
|
||||
dispatch({
|
||||
type: t.SETTING_SET,
|
||||
options: settings.data,
|
||||
});
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the settings.
|
||||
*/
|
||||
@@ -45,3 +17,90 @@ export function useSaveSettings(props) {
|
||||
...props,
|
||||
});
|
||||
}
|
||||
|
||||
function useSettingsQuery(key, query, props) {
|
||||
const dispatch = useDispatch();
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
return useQuery(
|
||||
key,
|
||||
() => apiRequest.get('settings', { params: query }),
|
||||
{
|
||||
select: (res) => res.data.settings,
|
||||
initialDataUpdatedAt: 0,
|
||||
initialData: {
|
||||
data: {
|
||||
settings: [],
|
||||
},
|
||||
},
|
||||
onSuccess: (settings) => {
|
||||
dispatch({ type: t.SETTING_SET, options: settings });
|
||||
},
|
||||
...props,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the all settings of the organization.
|
||||
*/
|
||||
export function useSettings() {
|
||||
return useSettingsQuery(['SETTINGS', 'ALL'], {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve invoices settings.
|
||||
*/
|
||||
export function useSettingsInvoices(props) {
|
||||
return useSettingsQuery(
|
||||
['SETTINGS', 'INVOICES'],
|
||||
{ group: 'sale_invoices' },
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve invoices settings.
|
||||
*/
|
||||
export function useSettingsEstimates(props) {
|
||||
return useSettingsQuery(
|
||||
['SETTINGS', 'ESTIMATES'],
|
||||
{ group: 'sale_estimates' },
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve payment receives settings.
|
||||
*/
|
||||
export function useSettingsPaymentReceives(props) {
|
||||
return useSettingsQuery(
|
||||
['SETTINGS', 'PAYMENT_RECEIVES'],
|
||||
{ group: 'payment_receives' },
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve sale receipts settings.
|
||||
* @param {*} props
|
||||
*/
|
||||
export function useSettingsReceipts(props) {
|
||||
return useSettingsQuery(
|
||||
['SETTINGS', 'RECEIPTS'],
|
||||
{ group: 'sale_receipts' },
|
||||
props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve sale receipts settings.
|
||||
* @param {*} props
|
||||
*/
|
||||
export function useSettingsManualJournals(props) {
|
||||
return useSettingsQuery(
|
||||
['SETTINGS', 'MANUAL_JOURNALS'],
|
||||
{ group: 'sale_receipts' },
|
||||
props,
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
.homepage {
|
||||
&__container {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
|
||||
margin: 22px 32px;
|
||||
background-color: transparent;
|
||||
align-items: flex-start;
|
||||
|
||||
.shortcut-boxes {
|
||||
flex: 2;
|
||||
@@ -12,23 +13,27 @@
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #d2dce2;
|
||||
border-right: 1px solid #d2dce2;
|
||||
max-width: 800px;
|
||||
|
||||
.shortcut-box {
|
||||
width: 50%;
|
||||
// height: 174px;
|
||||
padding: 16px;
|
||||
border-left: 1px solid #d2dce2;
|
||||
border-top: 1px solid #d2dce2;
|
||||
background-color: transparent;
|
||||
transition: 0.2s;
|
||||
|
||||
a{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 14px;
|
||||
|
||||
span > a {
|
||||
span {
|
||||
color: #d6d6e0;
|
||||
}
|
||||
.header--icon {
|
||||
@@ -62,7 +67,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 32px;
|
||||
width: 100%;
|
||||
max-width: 400px;
|
||||
|
||||
&__title {
|
||||
font-size: 16px;
|
||||
|
||||
@@ -34,7 +34,7 @@ $sidebar-width: 100%;
|
||||
$sidebar-menu-item-color: rgb(255, 255, 255);
|
||||
$sidebar-menu-item-color-active: rgb(255, 255, 255);
|
||||
$sidebar-popover-submenu-bg: rgb(1, 20, 62);
|
||||
$sidebar-menu-label-color: rgba(255, 255, 255, 0.45);
|
||||
$sidebar-menu-label-color: rgba(255, 255, 255, 0.5);
|
||||
$sidebar-submenu-item-color: rgba(255, 255, 255, 0.85);
|
||||
$sidebar-submenu-item-hover-color: rgb(255, 255, 255);
|
||||
$sidebar-logo-opacity: 0.5;
|
||||
|
||||
Reference in New Issue
Block a user