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