mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
Merge pull request #121 from bigcapitalhq/BIG-429-clean-up-the-auto-increment-of-transactions
fix: the auto-increment of transactions.
This commit is contained in:
@@ -17,8 +17,8 @@ import AllocateLandedCostDialog from '@/containers/Dialogs/AllocateLandedCostDia
|
||||
import InvoicePdfPreviewDialog from '@/containers/Dialogs/InvoicePdfPreviewDialog';
|
||||
import EstimatePdfPreviewDialog from '@/containers/Dialogs/EstimatePdfPreviewDialog';
|
||||
import ReceiptPdfPreviewDialog from '@/containers/Dialogs/ReceiptPdfPreviewDialog';
|
||||
import MoneyInDialog from '@/containers/Dialogs/MoneyInDialog';
|
||||
import MoneyOutDialog from '@/containers/Dialogs/MoneyOutDialog';
|
||||
import MoneyInDialog from '@/containers/CashFlow/MoneyInDialog';
|
||||
import MoneyOutDialog from '@/containers/CashFlow/MoneyOutDialog';
|
||||
import BadDebtDialog from '@/containers/Dialogs/BadDebtDialog';
|
||||
import NotifyInvoiceViaSMSDialog from '@/containers/Dialogs/NotifyInvoiceViaSMSDialog';
|
||||
import NotifyReceiptViaSMSDialog from '@/containers/Dialogs/NotifyReceiptViaSMSDialog';
|
||||
|
||||
@@ -46,4 +46,5 @@ export enum DialogsName {
|
||||
EstimateExpenseForm = 'estimate-expense-form',
|
||||
ProjectInvoicingForm = 'project-invoicing-form',
|
||||
ProjectBillableEntriesForm = 'project-billable-entries',
|
||||
InvoiceNumberSettings = 'InvoiceNumberSettings'
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Formik, Form } from 'formik';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
import * as R from 'ramda';
|
||||
import { defaultTo, isEmpty, omit } from 'lodash';
|
||||
import { isEmpty, omit } from 'lodash';
|
||||
import classNames from 'classnames';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
transformToEditForm,
|
||||
defaultManualJournal,
|
||||
} from './utils';
|
||||
import { JournalSyncIncrementSettingsToForm } from './components';
|
||||
|
||||
/**
|
||||
* Journal entries form.
|
||||
@@ -40,6 +41,7 @@ function MakeJournalEntriesForm({
|
||||
journalNextNumber,
|
||||
journalNumberPrefix,
|
||||
journalAutoIncrement,
|
||||
|
||||
// #withCurrentOrganization
|
||||
organization: { base_currency },
|
||||
}) {
|
||||
@@ -69,6 +71,8 @@ function MakeJournalEntriesForm({
|
||||
}
|
||||
: {
|
||||
...defaultManualJournal,
|
||||
// If the auto-increment mode is enabled, take the next journal
|
||||
// number from the settings.
|
||||
...(journalAutoIncrement && {
|
||||
journal_number: journalNumber,
|
||||
}),
|
||||
@@ -116,7 +120,6 @@ function MakeJournalEntriesForm({
|
||||
entries: R.compose(orderingLinesIndexes)(entries),
|
||||
publish: submitPayload.publish,
|
||||
};
|
||||
|
||||
// Handle the request error.
|
||||
const handleError = ({
|
||||
response: {
|
||||
@@ -126,7 +129,6 @@ function MakeJournalEntriesForm({
|
||||
transformErrors(errors, { setErrors });
|
||||
setSubmitting(false);
|
||||
};
|
||||
|
||||
// Handle the request success.
|
||||
const handleSuccess = (errors) => {
|
||||
AppToaster.show({
|
||||
@@ -147,7 +149,6 @@ function MakeJournalEntriesForm({
|
||||
resetForm();
|
||||
}
|
||||
};
|
||||
|
||||
if (isNewMode) {
|
||||
createJournalMutate(form).then(handleSuccess).catch(handleError);
|
||||
} else {
|
||||
@@ -179,6 +180,9 @@ function MakeJournalEntriesForm({
|
||||
|
||||
{/* --------- Dialogs --------- */}
|
||||
<MakeJournalFormDialogs />
|
||||
|
||||
{/* --------- Effects --------- */}
|
||||
<JournalSyncIncrementSettingsToForm />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,19 @@ import { PageFormBigNumber, FormattedMessage as T } from '@/components';
|
||||
import MakeJournalEntriesHeaderFields from './MakeJournalEntriesHeaderFields';
|
||||
|
||||
export default function MakeJournalEntriesHeader() {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<MakeJournalEntriesHeaderFields />
|
||||
<MakeJournalHeaderBigNumber />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Big total number of make journal header.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
function MakeJournalHeaderBigNumber() {
|
||||
const {
|
||||
values: { entries, currency_code },
|
||||
} = useFormikContext();
|
||||
@@ -17,14 +30,10 @@ export default function MakeJournalEntriesHeader() {
|
||||
const total = Math.max(totalCredit, totalDebit);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<MakeJournalEntriesHeaderFields />
|
||||
|
||||
<PageFormBigNumber
|
||||
label={<T id={'amount'} />}
|
||||
amount={total}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
</div>
|
||||
<PageFormBigNumber
|
||||
label={<T id={'amount'} />}
|
||||
amount={total}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,14 +6,14 @@ import {
|
||||
Position,
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import * as R from 'ramda';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import {
|
||||
momentFormatter,
|
||||
compose,
|
||||
inputIntent,
|
||||
handleDateChange,
|
||||
tansformDateValue,
|
||||
@@ -25,54 +25,101 @@ import {
|
||||
Icon,
|
||||
InputPrependButton,
|
||||
CurrencySelectList,
|
||||
FormattedMessage as T
|
||||
FormattedMessage as T,
|
||||
FInputGroup,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
import { useMakeJournalFormContext } from './MakeJournalProvider';
|
||||
import { JournalExchangeRateInputField } from './components';
|
||||
import { currenciesFieldShouldUpdate } from './utils';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import {
|
||||
currenciesFieldShouldUpdate,
|
||||
useObserveJournalNoSettings,
|
||||
} from './utils';
|
||||
|
||||
/**
|
||||
* Journal number field of make journal form.
|
||||
*/
|
||||
const MakeJournalTransactionNoField = R.compose(
|
||||
withDialogActions,
|
||||
withSettings(({ manualJournalsSettings }) => ({
|
||||
journalAutoIncrement: manualJournalsSettings?.autoIncrement,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
// #withDialog
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
journalAutoIncrement,
|
||||
}) => {
|
||||
const { setFieldValue, values } = useFormikContext();
|
||||
|
||||
const handleJournalNumberChange = () => {
|
||||
openDialog('journal-number-form');
|
||||
};
|
||||
const handleJournalNoBlur = (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (values.journal_number !== newValue && journalAutoIncrement) {
|
||||
openDialog('journal-number-form', {
|
||||
initialFormValues: {
|
||||
onceManualNumber: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
if (!journalAutoIncrement) {
|
||||
setFieldValue('journal_number', newValue);
|
||||
setFieldValue('journal_number_manually', newValue);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FFormGroup
|
||||
name={'journal_number'}
|
||||
label={<T id={'journal_no'} />}
|
||||
labelInfo={
|
||||
<>
|
||||
<FieldRequiredHint />
|
||||
<FieldHint />
|
||||
</>
|
||||
}
|
||||
fill={true}
|
||||
inline={true}
|
||||
fastField={true}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<FInputGroup
|
||||
name={'journal_number'}
|
||||
fill={true}
|
||||
asyncControl={true}
|
||||
onBlur={handleJournalNoBlur}
|
||||
fastField={true}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleJournalNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: <T id={'setting_your_auto_generated_journal_number'} />,
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FFormGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Make journal entries header.
|
||||
*/
|
||||
function MakeJournalEntriesHeader({
|
||||
// #ownProps
|
||||
onJournalNumberChanged,
|
||||
|
||||
// #withDialog
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
journalAutoIncrement,
|
||||
journalNextNumber,
|
||||
journalNumberPrefix,
|
||||
}) {
|
||||
export default function MakeJournalEntriesHeader({}) {
|
||||
const { currencies } = useMakeJournalFormContext();
|
||||
|
||||
// Handle journal number change.
|
||||
const handleJournalNumberChange = () => {
|
||||
openDialog('journal-number-form');
|
||||
};
|
||||
|
||||
// Handle journal number blur.
|
||||
const handleJournalNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && journalAutoIncrement) {
|
||||
openDialog('journal-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
useObserveJournalNoSettings(journalNumberPrefix, journalNextNumber);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
{/*------------ Posting date -----------*/}
|
||||
@@ -106,46 +153,7 @@ function MakeJournalEntriesHeader({
|
||||
</FastField>
|
||||
|
||||
{/*------------ Journal number -----------*/}
|
||||
<FastField name={'journal_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'journal_no'} />}
|
||||
labelInfo={
|
||||
<>
|
||||
<FieldRequiredHint />
|
||||
<FieldHint />
|
||||
</>
|
||||
}
|
||||
className={'form-group--journal-number'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="journal_number" />}
|
||||
fill={true}
|
||||
inline={true}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
fill={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleJournalNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleJournalNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T id={'setting_your_auto_generated_journal_number'} />
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<MakeJournalTransactionNoField />
|
||||
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference'}>
|
||||
@@ -219,12 +227,3 @@ function MakeJournalEntriesHeader({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ manualJournalsSettings }) => ({
|
||||
journalAutoIncrement: manualJournalsSettings?.autoIncrement,
|
||||
journalNextNumber: manualJournalsSettings?.nextNumber,
|
||||
journalNumberPrefix: manualJournalsSettings?.numberPrefix,
|
||||
})),
|
||||
)(MakeJournalEntriesHeader);
|
||||
|
||||
@@ -10,17 +10,21 @@ export default function MakeJournalFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the journal number form submit confirm.
|
||||
const handleConfirm = ({ manually, incrementNumber }) => {
|
||||
setFieldValue('journal_number', incrementNumber || '');
|
||||
setFieldValue('journal_number_manually', manually);
|
||||
const handleConfirm = (settings) => {
|
||||
// Set the invoice transaction no. that cames from dialog to the form.
|
||||
// the `journal_number` will be empty except the increment mode is not auto.
|
||||
setFieldValue('journal_number', settings.transactionNumber);
|
||||
setFieldValue('journal_number_manually', '');
|
||||
|
||||
if (settings.incrementMode !== 'auto') {
|
||||
setFieldValue('journal_number_manually', settings.transactionNumber);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<JournalNumberDialog
|
||||
dialogName={'journal-number-form'}
|
||||
onConfirm={handleConfirm}
|
||||
/>
|
||||
</>
|
||||
<JournalNumberDialog
|
||||
dialogName={'journal-number-form'}
|
||||
onConfirm={handleConfirm}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Menu, MenuItem, Position, Button } from '@blueprintjs/core';
|
||||
import { Popover2 } from '@blueprintjs/popover2';
|
||||
import { useFormikContext } from 'formik';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import {
|
||||
ExchangeRateInputGroup,
|
||||
@@ -24,6 +25,9 @@ import { CellType, Features, Align } from '@/constants';
|
||||
|
||||
import { useCurrentOrganization, useFeatureCan } from '@/hooks/state';
|
||||
import { useJournalIsForeign } from './utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import { transactionNumber } from '@/utils';
|
||||
import { useUpdateEffect } from '@/hooks';
|
||||
|
||||
/**
|
||||
* Contact header cell.
|
||||
@@ -199,3 +203,37 @@ export function JournalExchangeRateInputField({ ...props }) {
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs journal auto-increment settings to form.
|
||||
* @return {React.ReactNode}
|
||||
*/
|
||||
export const JournalSyncIncrementSettingsToForm = R.compose(
|
||||
withSettings(({ manualJournalsSettings }) => ({
|
||||
journalAutoIncrement: manualJournalsSettings?.autoIncrement,
|
||||
journalNextNumber: manualJournalsSettings?.nextNumber,
|
||||
journalNumberPrefix: manualJournalsSettings?.numberPrefix,
|
||||
})),
|
||||
)(({ journalAutoIncrement, journalNextNumber, journalNumberPrefix }) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
useUpdateEffect(() => {
|
||||
// Do not update if the journal auto-increment mode is disabled.
|
||||
if (!journalAutoIncrement) return null;
|
||||
|
||||
setFieldValue(
|
||||
'journal_number',
|
||||
transactionNumber(journalNumberPrefix, journalNextNumber),
|
||||
);
|
||||
}, [
|
||||
setFieldValue,
|
||||
journalNumberPrefix,
|
||||
journalNextNumber,
|
||||
journalAutoIncrement,
|
||||
]);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
JournalSyncIncrementSettingsToForm.displayName =
|
||||
'JournalSyncIncrementSettingsToForm';
|
||||
|
||||
@@ -6,7 +6,6 @@ import intl from 'react-intl-universal';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { sumBy, setWith, toSafeInteger, get, first } from 'lodash';
|
||||
import {
|
||||
transactionNumber,
|
||||
updateTableCell,
|
||||
repeatValue,
|
||||
transformToForm,
|
||||
@@ -46,7 +45,7 @@ export const defaultEntry = {
|
||||
|
||||
export const defaultManualJournal = {
|
||||
journal_number: '',
|
||||
journal_number_manually: false,
|
||||
journal_number_manually: '',
|
||||
journal_type: 'Journal',
|
||||
date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
description: '',
|
||||
@@ -174,15 +173,6 @@ export const transformErrors = (resErrors, { setErrors, errors }) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const useObserveJournalNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
const journalNo = transactionNumber(prefix, nextNumber);
|
||||
setFieldValue('journal_number', journalNo);
|
||||
}, [setFieldValue, prefix, nextNumber]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detarmines entries fast field should update.
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import OwnerContributionFormFields from './OwnerContribution/OwnerContributionFormFields';
|
||||
import OtherIncomeFormFields from './OtherIncome/OtherIncomeFormFields';
|
||||
import TransferFromAccountFormFields from './TransferFromAccount/TransferFromAccountFormFields';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param param0
|
||||
* @returns
|
||||
*/
|
||||
export default function MoneyInContentFields({ accountType }) {
|
||||
const handleTransactionType = () => {
|
||||
switch (accountType) {
|
||||
@@ -19,6 +25,5 @@ export default function MoneyInContentFields({ accountType }) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return <React.Fragment>{handleTransactionType()}</React.Fragment>;
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { Form } from 'formik';
|
||||
import MoneyInFormFields from './MoneyInFormFields';
|
||||
import MoneyInFormDialog from './MoneyInFormDialog';
|
||||
import MoneyInFloatingActions from './MoneyInFloatingActions';
|
||||
import { MoneyInOutSyncIncrementSettingsToForm } from '../_components';
|
||||
|
||||
/**
|
||||
* Money In form content.
|
||||
@@ -15,6 +16,7 @@ export default function MoneyInFormContent() {
|
||||
<MoneyInFormFields />
|
||||
<MoneyInFormDialog />
|
||||
<MoneyInFloatingActions />
|
||||
<MoneyInOutSyncIncrementSettingsToForm />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
@@ -11,12 +11,9 @@ export default function MoneyInFormDialog() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the transaction number form submit confirm.
|
||||
const handleTransactionNumberFormConfirm = ({
|
||||
incrementNumber,
|
||||
manually,
|
||||
}) => {
|
||||
setFieldValue('transaction_number', incrementNumber || '');
|
||||
setFieldValue('transaction_number_manually', manually);
|
||||
const handleTransactionNumberFormConfirm = (settings) => {
|
||||
setFieldValue('transaction_number', settings.transactionNumber);
|
||||
setFieldValue('transaction_number_manually', settings.transactionNumber);
|
||||
};
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -16,14 +16,12 @@ import {
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
InputPrependButton,
|
||||
ExchangeRateMutedField,
|
||||
} from '@/components';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
@@ -35,65 +33,26 @@ import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
handleDateChange,
|
||||
compose,
|
||||
} from '@/utils';
|
||||
|
||||
import { useMoneyInDailogContext } from '../MoneyInDialogProvider';
|
||||
import {
|
||||
useObserveTransactionNoSettings,
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
|
||||
/**
|
||||
* Other income form fields.
|
||||
*/
|
||||
function OtherIncomeFormFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
}) {
|
||||
export default function OtherIncomeFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyInDailogContext();
|
||||
|
||||
const { values } = useFormikContext();
|
||||
|
||||
const amountFieldRef = useAutofocus();
|
||||
|
||||
const isForeigAccount = useForeignAccount();
|
||||
|
||||
// Handle tranaction number changing.
|
||||
const handleTransactionNumberChange = () => {
|
||||
openDialog('transaction-number-form');
|
||||
};
|
||||
|
||||
// Handle transaction no. field blur.
|
||||
const handleTransactionNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && transactionAutoIncrement) {
|
||||
openDialog('transaction-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Syncs transaction number settings with form.
|
||||
useObserveTransactionNoSettings(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
|
||||
@@ -149,42 +108,7 @@ function OtherIncomeFormFields({
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<Field name={'transaction_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_number'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="transaction_number" />}
|
||||
className={'form-group--transaction_number'}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleTransactionNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleTransactionNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={
|
||||
'cash_flow.setting_your_auto_generated_transaction_number'
|
||||
}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
@@ -298,12 +222,3 @@ function OtherIncomeFormFields({
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(OtherIncomeFormFields);
|
||||
@@ -17,11 +17,9 @@ import {
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
InputPrependButton,
|
||||
ExchangeRateMutedField,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
@@ -35,31 +33,20 @@ import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
handleDateChange,
|
||||
compose,
|
||||
} from '@/utils';
|
||||
import { useMoneyInDailogContext } from '../MoneyInDialogProvider';
|
||||
import {
|
||||
useObserveTransactionNoSettings,
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../../MoneyInDialog/utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
|
||||
/**
|
||||
/**
|
||||
* Owner contribution form fields.
|
||||
*/
|
||||
function OwnerContributionFormFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
}) {
|
||||
export default function OwnerContributionFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyInDailogContext();
|
||||
|
||||
@@ -69,31 +56,6 @@ function OwnerContributionFormFields({
|
||||
|
||||
const isForeigAccount = useForeignAccount();
|
||||
|
||||
// Handle tranaction number changing.
|
||||
const handleTransactionNumberChange = () => {
|
||||
openDialog('transaction-number-form');
|
||||
};
|
||||
|
||||
// Handle transaction no. field blur.
|
||||
const handleTransactionNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && transactionAutoIncrement) {
|
||||
openDialog('transaction-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Syncs transaction number settings with form.
|
||||
useObserveTransactionNoSettings(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
|
||||
@@ -148,42 +110,7 @@ function OwnerContributionFormFields({
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<Field name={'transaction_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_number'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="transaction_number" />}
|
||||
className={'form-group--transaction_number'}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleTransactionNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleTransactionNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={
|
||||
'cash_flow.setting_your_auto_generated_transaction_number'
|
||||
}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
@@ -294,12 +221,3 @@ function OwnerContributionFormFields({
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(OwnerContributionFormFields);
|
||||
@@ -17,11 +17,9 @@ import {
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
InputPrependButton,
|
||||
ExchangeRateMutedField,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
@@ -35,30 +33,20 @@ import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
handleDateChange,
|
||||
compose,
|
||||
} from '@/utils';
|
||||
import { useMoneyInDailogContext } from '../MoneyInDialogProvider';
|
||||
import {
|
||||
useObserveTransactionNoSettings,
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../../MoneyInDialog/utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
|
||||
/**
|
||||
* Transfer from account form fields.
|
||||
*/
|
||||
function TransferFromAccountFormFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
}) {
|
||||
export default function TransferFromAccountFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyInDailogContext();
|
||||
|
||||
@@ -67,33 +55,9 @@ function TransferFromAccountFormFields({
|
||||
|
||||
const { values } = useFormikContext();
|
||||
|
||||
// Handle tranaction number changing.
|
||||
const handleTransactionNumberChange = () => {
|
||||
openDialog('transaction-number-form');
|
||||
};
|
||||
|
||||
// Handle transaction no. field blur.
|
||||
const handleTransactionNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && transactionAutoIncrement) {
|
||||
openDialog('transaction-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
|
||||
// Syncs transaction number settings with form.
|
||||
useObserveTransactionNoSettings(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
return (
|
||||
<React.Fragment>
|
||||
<FeatureCan feature={Features.Branches}>
|
||||
@@ -145,42 +109,7 @@ function TransferFromAccountFormFields({
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<Field name={'transaction_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_number'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="transaction_number" />}
|
||||
className={'form-group--transaction_number'}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleTransactionNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleTransactionNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={
|
||||
'cash_flow.setting_your_auto_generated_transaction_number'
|
||||
}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
@@ -296,12 +225,3 @@ function TransferFromAccountFormFields({
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(TransferFromAccountFormFields);
|
||||
@@ -20,7 +20,6 @@ function MoneyOutContentFields({ accountType }) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return <React.Fragment>{handleTransactionType()}</React.Fragment>;
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ import React from 'react';
|
||||
import { Form } from 'formik';
|
||||
|
||||
import MoneyOutFormFields from './MoneyOutFormFields';
|
||||
import MoneyOutFormDialog from './MoneyOutFormDialog'
|
||||
import MoneyOutFormDialog from './MoneyOutFormDialog';
|
||||
import MoneyOutFloatingActions from './MoneyOutFloatingActions';
|
||||
import { MoneyInOutSyncIncrementSettingsToForm } from '../_components';
|
||||
|
||||
/**
|
||||
* Money out form content.
|
||||
*/
|
||||
@@ -12,8 +14,9 @@ export default function MoneyOutFormContent() {
|
||||
return (
|
||||
<Form>
|
||||
<MoneyOutFormFields />
|
||||
<MoneyOutFormDialog/>
|
||||
<MoneyOutFormDialog />
|
||||
<MoneyOutFloatingActions />
|
||||
<MoneyInOutSyncIncrementSettingsToForm />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
@@ -16,11 +16,9 @@ import {
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
InputPrependButton,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
@@ -35,31 +33,21 @@ import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
handleDateChange,
|
||||
compose,
|
||||
} from '@/utils';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { useMoneyOutDialogContext } from '../MoneyOutDialogProvider';
|
||||
import {
|
||||
useObserveTransactionNoSettings,
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
|
||||
/**
|
||||
* Other expense form fields.
|
||||
*/
|
||||
function OtherExpnseFormFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
}) {
|
||||
export default function OtherExpnseFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyOutDialogContext();
|
||||
|
||||
@@ -68,31 +56,6 @@ function OtherExpnseFormFields({
|
||||
|
||||
const amountFieldRef = useAutofocus();
|
||||
|
||||
// Handle tranaction number changing.
|
||||
const handleTransactionNumberChange = () => {
|
||||
openDialog('transaction-number-form');
|
||||
};
|
||||
|
||||
// Handle transaction no. field blur.
|
||||
const handleTransactionNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && transactionAutoIncrement) {
|
||||
openDialog('transaction-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Syncs transaction number settings with form.
|
||||
useObserveTransactionNoSettings(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
|
||||
@@ -147,42 +110,7 @@ function OtherExpnseFormFields({
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<Field name={'transaction_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_number'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="transaction_number" />}
|
||||
className={'form-group--transaction_number'}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleTransactionNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleTransactionNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={
|
||||
'cash_flow.setting_your_auto_generated_transaction_number'
|
||||
}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
@@ -296,12 +224,3 @@ function OtherExpnseFormFields({
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(OtherExpnseFormFields);
|
||||
@@ -17,8 +17,6 @@ import {
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
InputPrependButton,
|
||||
Icon,
|
||||
If,
|
||||
Col,
|
||||
Row,
|
||||
@@ -34,30 +32,19 @@ import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
handleDateChange,
|
||||
compose,
|
||||
} from '@/utils';
|
||||
import { useMoneyOutDialogContext } from '../MoneyOutDialogProvider';
|
||||
import {
|
||||
useObserveTransactionNoSettings,
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../../MoneyOutDialog/utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
|
||||
/**
|
||||
* Owner drawings form fields.
|
||||
*/
|
||||
function OwnerDrawingsFormFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
}) {
|
||||
export default function OwnerDrawingsFormFields() {
|
||||
// Money out dialog context.
|
||||
const { accounts, account, branches } = useMoneyOutDialogContext();
|
||||
const { values } = useFormikContext();
|
||||
@@ -65,31 +52,6 @@ function OwnerDrawingsFormFields({
|
||||
|
||||
const amountFieldRef = useAutofocus();
|
||||
|
||||
// Handle tranaction number changing.
|
||||
const handleTransactionNumberChange = () => {
|
||||
openDialog('transaction-number-form');
|
||||
};
|
||||
|
||||
// Handle transaction no. field blur.
|
||||
const handleTransactionNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && transactionAutoIncrement) {
|
||||
openDialog('transaction-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Syncs transaction number settings with form.
|
||||
useObserveTransactionNoSettings(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
|
||||
@@ -144,42 +106,7 @@ function OwnerDrawingsFormFields({
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<Field name={'transaction_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_number'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="transaction_number" />}
|
||||
className={'form-group--transaction_number'}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleTransactionNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleTransactionNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={
|
||||
'cash_flow.setting_your_auto_generated_transaction_number'
|
||||
}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
@@ -291,12 +218,3 @@ function OwnerDrawingsFormFields({
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(OwnerDrawingsFormFields);
|
||||
@@ -48,19 +48,12 @@ import {
|
||||
} from '../utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
|
||||
/**
|
||||
* Transfer to account form fields.
|
||||
*/
|
||||
function TransferToAccountFormFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
}) {
|
||||
export default function TransferToAccountFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyOutDialogContext();
|
||||
const { values } = useFormikContext();
|
||||
@@ -68,31 +61,6 @@ function TransferToAccountFormFields({
|
||||
|
||||
const accountRef = useAutofocus();
|
||||
|
||||
// Handle tranaction number changing.
|
||||
const handleTransactionNumberChange = () => {
|
||||
openDialog('transaction-number-form');
|
||||
};
|
||||
|
||||
// Handle transaction no. field blur.
|
||||
const handleTransactionNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && transactionAutoIncrement) {
|
||||
openDialog('transaction-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Syncs transaction number settings with form.
|
||||
useObserveTransactionNoSettings(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
|
||||
@@ -147,42 +115,7 @@ function TransferToAccountFormFields({
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<Field name={'transaction_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_number'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="transaction_number" />}
|
||||
className={'form-group--transaction_number'}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleTransactionNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleTransactionNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={
|
||||
'cash_flow.setting_your_auto_generated_transaction_number'
|
||||
}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
@@ -298,11 +231,3 @@ function TransferToAccountFormFields({
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(TransferToAccountFormFields);
|
||||
127
packages/webapp/src/containers/CashFlow/_components.tsx
Normal file
127
packages/webapp/src/containers/CashFlow/_components.tsx
Normal file
@@ -0,0 +1,127 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { InputGroup, Position, ControlGroup } from '@blueprintjs/core';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import {
|
||||
FFormGroup,
|
||||
Icon,
|
||||
InputPrependButton,
|
||||
FormattedMessage as T,
|
||||
} from '@/components';
|
||||
import { useUpdateEffect } from '@/hooks';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
|
||||
/**
|
||||
* Syncs cashflow auto-increment settings to the form once update.
|
||||
*/
|
||||
export const MoneyInOutSyncIncrementSettingsToForm = R.compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
transactionNextNumber,
|
||||
transactionNumberPrefix,
|
||||
}) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
useUpdateEffect(() => {
|
||||
// Do not update if the invoice auto-increment is disabled.
|
||||
if (!transactionAutoIncrement) return null;
|
||||
|
||||
const transactionNumber = transactionNumber(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
setFieldValue('transaction_number', transactionNumber);
|
||||
}, [setFieldValue, transactionNumberPrefix, transactionNextNumber]);
|
||||
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Money In/Out transaction number field.
|
||||
*/
|
||||
export const MoneyInOutTransactionNoField = R.compose(
|
||||
withDialogActions,
|
||||
withSettings(({ cashflowSetting }) => ({
|
||||
transactionAutoIncrement: cashflowSetting?.autoIncrement,
|
||||
transactionNextNumber: cashflowSetting?.nextNumber,
|
||||
transactionNumberPrefix: cashflowSetting?.numberPrefix,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
transactionAutoIncrement,
|
||||
}) => {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
|
||||
// Handle tranaction number changing.
|
||||
const handleTransactionNumberChange = () => {
|
||||
openDialog('transaction-number-form');
|
||||
};
|
||||
// Handle transaction no. field blur.
|
||||
const handleTransactionNoBlur = (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (values.transaction_number !== newValue && transactionAutoIncrement) {
|
||||
openDialog('transaction-number-form', {
|
||||
initialFormValues: {
|
||||
onceManualNumber: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
if (!transactionAutoIncrement) {
|
||||
setFieldValue('transaction_number', values.transaction_number);
|
||||
setFieldValue('transaction_number_manually', values.transaction_number);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FFormGroup
|
||||
name={'transaction_number'}
|
||||
label={<T id={'transaction_number'} />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={values.transaction_number}
|
||||
asyncControl={true}
|
||||
onBlur={handleTransactionNoBlur}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleTransactionNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={
|
||||
'cash_flow.setting_your_auto_generated_transaction_number'
|
||||
}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FFormGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -7,8 +7,10 @@ export const mapStateToProps = (state, props) => {
|
||||
};
|
||||
|
||||
export const mapDispatchToProps = (dispatch) => ({
|
||||
openDialog: (name, payload) => dispatch({ type: t.OPEN_DIALOG, name, payload }),
|
||||
closeDialog: (name, payload) => dispatch({ type: t.CLOSE_DIALOG, name, payload }),
|
||||
openDialog: (name, payload) =>
|
||||
dispatch({ type: t.OPEN_DIALOG, name, payload }),
|
||||
closeDialog: (name, payload) =>
|
||||
dispatch({ type: t.CLOSE_DIALOG, name, payload }),
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps);
|
||||
export default connect(null, mapDispatchToProps);
|
||||
|
||||
@@ -65,7 +65,6 @@ function CreditNoteNumberDialogContent({
|
||||
const handleChange = (values) => {
|
||||
setReferenceFormValues(values);
|
||||
};
|
||||
|
||||
// Description.
|
||||
const description =
|
||||
referenceFormValues?.incrementMode === 'auto'
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
transformFormToSettings,
|
||||
transformSettingsToForm,
|
||||
} from '@/containers/JournalNumber/utils';
|
||||
import { DialogsName } from '@/constants/dialogs';
|
||||
|
||||
/**
|
||||
* invoice number dialog's content.
|
||||
@@ -39,7 +40,7 @@ function InvoiceNumberDialogContent({
|
||||
// Handle the form success.
|
||||
const handleSuccess = () => {
|
||||
setSubmitting(false);
|
||||
closeDialog('invoice-number-form');
|
||||
closeDialog(DialogsName.InvoiceNumberSettings);
|
||||
onConfirm(values);
|
||||
};
|
||||
// Handle the form errors.
|
||||
@@ -56,10 +57,9 @@ function InvoiceNumberDialogContent({
|
||||
// Save the settings.
|
||||
saveSettings({ options }).then(handleSuccess).catch(handleErrors);
|
||||
};
|
||||
|
||||
// Handle the dialog close.
|
||||
const handleClose = () => {
|
||||
closeDialog('invoice-number-form');
|
||||
closeDialog(DialogsName.InvoiceNumberSettings);
|
||||
};
|
||||
// Handle form change.
|
||||
const handleChange = (values) => {
|
||||
@@ -71,17 +71,19 @@ function InvoiceNumberDialogContent({
|
||||
? intl.get('invoice.auto_increment.auto')
|
||||
: intl.get('invoice.auto_increment.manually');
|
||||
|
||||
const initialFormValues = {
|
||||
...transformSettingsToForm({
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
autoIncrement,
|
||||
}),
|
||||
...initialValues,
|
||||
};
|
||||
|
||||
return (
|
||||
<InvoiceNumberDialogProvider>
|
||||
<ReferenceNumberForm
|
||||
initialValues={{
|
||||
...transformSettingsToForm({
|
||||
nextNumber,
|
||||
numberPrefix,
|
||||
autoIncrement,
|
||||
}),
|
||||
...initialValues,
|
||||
}}
|
||||
initialValues={initialFormValues}
|
||||
description={description}
|
||||
onSubmit={handleSubmitForm}
|
||||
onClose={handleClose}
|
||||
|
||||
@@ -2,49 +2,49 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
import { Intent, Button, Classes } from '@blueprintjs/core';
|
||||
|
||||
import '@/style/pages/ReferenceNumber/ReferenceNumber.scss';
|
||||
|
||||
import { FormObserver } from '@/components';
|
||||
import { FormattedMessage as T, FormObserver } from '@/components';
|
||||
import ReferenceNumberFormContent from './ReferenceNumberFormContent';
|
||||
import { transformValuesToForm } from './utils';
|
||||
import { saveInvoke } from '@/utils';
|
||||
import { saveInvoke, transformToForm } from '@/utils';
|
||||
|
||||
const initialFormValues = {
|
||||
incrementMode: 'auto',
|
||||
numberPrefix: '',
|
||||
nextNumber: '',
|
||||
onceManualNumber: '',
|
||||
};
|
||||
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
incrementMode: Yup.string(),
|
||||
numberPrefix: Yup.string(),
|
||||
nextNumber: Yup.number(),
|
||||
onceManualNumber: Yup.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Reference number form.
|
||||
*/
|
||||
export default function ReferenceNumberForm({
|
||||
onSubmit,
|
||||
onClose,
|
||||
initialValues,
|
||||
description,
|
||||
onSubmit,
|
||||
onClose,
|
||||
onChange,
|
||||
}) {
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
incrementMode: Yup.string(),
|
||||
numberPrefix: Yup.string(),
|
||||
nextNumber: Yup.number(),
|
||||
manualTransactionNo: Yup.string(),
|
||||
});
|
||||
// Initial values.
|
||||
const formInitialValues = useMemo(
|
||||
() => ({
|
||||
...initialValues,
|
||||
incrementMode:
|
||||
initialValues.incrementMode === 'auto' &&
|
||||
initialValues.manualTransactionNo
|
||||
? 'manual-transaction'
|
||||
: initialValues.incrementMode,
|
||||
}),
|
||||
[initialValues],
|
||||
);
|
||||
const formInitialValues = {
|
||||
...initialFormValues,
|
||||
...transformToForm(initialValues, initialFormValues),
|
||||
};
|
||||
// Handle the form submit.
|
||||
const handleSubmit = (values, methods) => {
|
||||
const parsed = transformValuesToForm(values);
|
||||
saveInvoke(onSubmit, { ...parsed, ...values }, methods);
|
||||
saveInvoke(onSubmit, { ...values, ...parsed }, methods);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, useFormikContext } from 'formik';
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
import { FormGroup, InputGroup, Radio } from '@blueprintjs/core';
|
||||
import { If, Row, Col, ErrorMessage } from '@/components';
|
||||
|
||||
import { FormattedMessage as T, Row, Col, ErrorMessage } from '@/components';
|
||||
import { inputIntent } from '@/utils';
|
||||
|
||||
/**
|
||||
* Reference number form content.
|
||||
*/
|
||||
export default function ReferenceNumberFormContent() {
|
||||
const { values } = useFormikContext();
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* ------------- Auto increment mode ------------- */}
|
||||
@@ -27,54 +25,13 @@ export default function ReferenceNumberFormContent() {
|
||||
/>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
<If condition={values.incrementMode === 'auto'}>
|
||||
<Row>
|
||||
{/* ------------- Prefix ------------- */}
|
||||
<Col xs={4}>
|
||||
<FastField name={'numberPrefix'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'prefix'} />}
|
||||
className={'form-group--'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'numberPrefix'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
{/* ------------- Next number ------------- */}
|
||||
<Col xs={6}>
|
||||
<FastField name={'nextNumber'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'next_number'} />}
|
||||
className={'form-group--next-number'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'nextNumber'} />}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
</Row>
|
||||
</If>
|
||||
<ReferenceNumberAutoIncrement />
|
||||
|
||||
{/* ------------- Manual increment mode ------------- */}
|
||||
<FastField name={'incrementMode'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<Radio
|
||||
label={<T id={'auto_increment.field.manual_this_transaction'} />}
|
||||
label={<T id={'auto_increment.field.manually'} />}
|
||||
value="manual"
|
||||
onChange={() => {
|
||||
form.setFieldValue('incrementMode', 'manual');
|
||||
@@ -85,20 +42,70 @@ export default function ReferenceNumberFormContent() {
|
||||
</FastField>
|
||||
|
||||
{/* ------------- Transaction manual increment mode ------------- */}
|
||||
<If condition={values.manualTransactionNo}>
|
||||
<FastField name={'incrementMode'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<Radio
|
||||
label={<T id={'auto_increment.field.manually'} />}
|
||||
value="manual"
|
||||
onChange={() => {
|
||||
form.setFieldValue('incrementMode', 'manual-transaction');
|
||||
}}
|
||||
checked={field.value === 'manual-transaction'}
|
||||
/>
|
||||
)}
|
||||
</FastField>
|
||||
</If>
|
||||
<ReferenceNumberManualOnce />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function ReferenceNumberAutoIncrement() {
|
||||
const { values } = useFormikContext();
|
||||
if (!values.incrementMode === 'auto') return null;
|
||||
|
||||
return (
|
||||
<Row>
|
||||
{/* ------------- Prefix ------------- */}
|
||||
<Col xs={4}>
|
||||
<FastField name={'numberPrefix'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'prefix'} />}
|
||||
className={'form-group--'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'numberPrefix'} />}
|
||||
>
|
||||
<InputGroup intent={inputIntent({ error, touched })} {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
{/* ------------- Next number ------------- */}
|
||||
<Col xs={6}>
|
||||
<FastField name={'nextNumber'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'next_number'} />}
|
||||
className={'form-group--next-number'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'nextNumber'} />}
|
||||
>
|
||||
<InputGroup intent={inputIntent({ error, touched })} {...field} />
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
function ReferenceNumberManualOnce() {
|
||||
const { values } = useFormikContext();
|
||||
|
||||
// Do not show the field if the one manual transaction number is not presented.
|
||||
if (!values.onceManualNumber) return null;
|
||||
|
||||
return (
|
||||
<FastField name={'incrementMode'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<Radio
|
||||
label={<T id={'auto_increment.field.manual_this_transaction'} />}
|
||||
value="manual"
|
||||
onChange={() => {
|
||||
form.setFieldValue('incrementMode', 'manual-transaction');
|
||||
}}
|
||||
checked={field.value === 'manual-transaction'}
|
||||
/>
|
||||
)}
|
||||
</FastField>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
transfromToSnakeCase,
|
||||
transactionNumber,
|
||||
} from '@/utils';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
export const defaultInvoiceNoSettings = {
|
||||
nextNumber: '',
|
||||
@@ -13,8 +14,8 @@ export const defaultInvoiceNoSettings = {
|
||||
};
|
||||
|
||||
export const transformSettingsToForm = (settings) => ({
|
||||
...settings,
|
||||
incrementMode: settings.autoIncrement === 'true' ? 'auto' : 'manual',
|
||||
...omit(settings, ['autoIncrement']),
|
||||
incrementMode: settings.autoIncrement ? 'auto' : 'manual',
|
||||
});
|
||||
|
||||
export const transformFormToSettings = (values, group) => {
|
||||
@@ -25,13 +26,21 @@ export const transformFormToSettings = (values, group) => {
|
||||
return optionsMapToArray(options).map((option) => ({ ...option, group }));
|
||||
};
|
||||
|
||||
/**
|
||||
* Transaction number returns auto-increment if the increment mode is auto or
|
||||
* returns empty string if the increment mode is manually or returns the entered
|
||||
* manual text if the increment mode is manual once just in this transaction.
|
||||
*/
|
||||
export const transformValuesToForm = (values) => {
|
||||
const incrementNumber =
|
||||
const autoIncrementNumber = transactionNumber(
|
||||
values.numberPrefix,
|
||||
values.nextNumber,
|
||||
);
|
||||
const _transactionNumber =
|
||||
values.incrementMode === 'auto'
|
||||
? transactionNumber(values.numberPrefix, values.nextNumber)
|
||||
: values.manualTransactionNo;
|
||||
|
||||
const manually = values.incrementMode === 'auto' ? false : true;
|
||||
|
||||
return { incrementNumber, manually };
|
||||
? autoIncrementNumber
|
||||
: values.incrementMode === 'manual-transaction'
|
||||
? values.onceManualNumber
|
||||
: '';
|
||||
return { transactionNumber: _transactionNumber };
|
||||
};
|
||||
|
||||
@@ -13,6 +13,15 @@ import BillFormHeaderFields from './BillFormHeaderFields';
|
||||
* Fill form header.
|
||||
*/
|
||||
function BillFormHeader() {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<BillFormHeaderFields />
|
||||
<BillFormBigTotal />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function BillFormBigTotal() {
|
||||
const {
|
||||
values: { currency_code, entries },
|
||||
} = useFormikContext();
|
||||
@@ -21,14 +30,12 @@ function BillFormHeader() {
|
||||
const totalDueAmount = useMemo(() => sumBy(entries, 'amount'), [entries]);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<BillFormHeaderFields />
|
||||
<PageFormBigNumber
|
||||
label={intl.get('due_amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
</div>
|
||||
<PageFormBigNumber
|
||||
label={intl.get('due_amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default BillFormHeader;
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';
|
||||
import { CreditNoteSyncIncrementSettingsToForm } from './components';
|
||||
|
||||
/**
|
||||
* Credit note form.
|
||||
@@ -105,7 +106,7 @@ function CreditNoteForm({
|
||||
open: submitPayload.open,
|
||||
};
|
||||
// Handle the request success.
|
||||
const onSuccess = (response) => {
|
||||
const onSuccess = () => {
|
||||
AppToaster.show({
|
||||
message: intl.get(
|
||||
isNewMode
|
||||
@@ -161,7 +162,12 @@ function CreditNoteForm({
|
||||
<CreditNoteItemsEntriesEditorField />
|
||||
<CreditNoteFormFooter />
|
||||
<CreditNoteFloatingActions />
|
||||
|
||||
{/*-------- Dialogs --------*/}
|
||||
<CreditNoteFormDialogs />
|
||||
|
||||
{/*-------- Effects --------*/}
|
||||
<CreditNoteSyncIncrementSettingsToForm />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import CreditNoteNumberDialog from '@/containers/Dialogs/CreditNoteNumberDialog';
|
||||
import { useFormikContext } from 'formik';
|
||||
import CreditNoteNumberDialog from '@/containers/Dialogs/CreditNoteNumberDialog';
|
||||
|
||||
/**
|
||||
* Credit note form dialogs.
|
||||
*/
|
||||
export default function CreditNoteFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the credit number form submit confirm.
|
||||
const handleCreditNumberFormConfirm = ({ incrementNumber, manually }) => {
|
||||
setFieldValue('credit_note_number', incrementNumber || '');
|
||||
setFieldValue('credit_note_no_manually', manually);
|
||||
const handleCreditNumberFormConfirm = (settings) => {
|
||||
// Set the credit note transaction no. that cames from dialog to the form.
|
||||
// the `credit_note_number` will be empty except the increment mode is not auto.
|
||||
setFieldValue('credit_note_number', settings.transactionNumber);
|
||||
setFieldValue('credit_note_number_manually', '');
|
||||
|
||||
if (settings.incrementMode !== 'auto') {
|
||||
setFieldValue('credit_note_number_manually', settings.transactionNumber);
|
||||
}
|
||||
};
|
||||
|
||||
const { setFieldValue } = useFormikContext();
|
||||
return (
|
||||
<React.Fragment>
|
||||
<CreditNoteNumberDialog
|
||||
dialogName={'credit-number-form'}
|
||||
onConfirm={handleCreditNumberFormConfirm}
|
||||
/>
|
||||
</React.Fragment>
|
||||
<CreditNoteNumberDialog
|
||||
dialogName={'credit-number-form'}
|
||||
onConfirm={handleCreditNumberFormConfirm}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,19 @@ import { PageFormBigNumber } from '@/components';
|
||||
* Credit note header.
|
||||
*/
|
||||
function CreditNoteFormHeader() {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<CreditNoteFormHeaderFields />
|
||||
<CreditNoteFormBigNumber />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Big total number of credit note form header.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
function CreditNoteFormBigNumber() {
|
||||
const {
|
||||
values: { entries, currency_code },
|
||||
} = useFormikContext();
|
||||
@@ -21,14 +34,11 @@ function CreditNoteFormHeader() {
|
||||
const totalAmount = React.useMemo(() => getEntriesTotal(entries), [entries]);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<CreditNoteFormHeaderFields />
|
||||
<PageFormBigNumber
|
||||
label={intl.get('credit_note.label_amount_to_credit')}
|
||||
amount={totalAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
</div>
|
||||
<PageFormBigNumber
|
||||
label={intl.get('credit_note.label_amount_to_credit')}
|
||||
amount={totalAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as R from 'ramda';
|
||||
import classNames from 'classnames';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
@@ -9,7 +10,8 @@ import {
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FastField, Field, ErrorMessage } from 'formik';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import {
|
||||
CustomerSelectField,
|
||||
@@ -18,11 +20,10 @@ import {
|
||||
Icon,
|
||||
FormattedMessage as T,
|
||||
CustomerDrawerLink,
|
||||
FFormGroup,
|
||||
FInputGroup,
|
||||
} from '@/components';
|
||||
import {
|
||||
customerNameFieldShouldUpdate,
|
||||
useObserveCreditNoSettings,
|
||||
} from './utils';
|
||||
import { customerNameFieldShouldUpdate } from './utils';
|
||||
|
||||
import { useCreditNoteFormContext } from './CreditNoteFormProvider';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
@@ -30,49 +31,99 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { CreditNoteExchangeRateInputField } from './components';
|
||||
import {
|
||||
momentFormatter,
|
||||
compose,
|
||||
tansformDateValue,
|
||||
inputIntent,
|
||||
handleDateChange,
|
||||
} from '@/utils';
|
||||
|
||||
/**
|
||||
* Credit note transaction number field.
|
||||
*/
|
||||
const CreditNoteTransactionNoField = R.compose(
|
||||
withDialogActions,
|
||||
withSettings(({ creditNoteSettings }) => ({
|
||||
creditAutoIncrement: creditNoteSettings?.autoIncrement,
|
||||
creditNextNumber: creditNoteSettings?.nextNumber,
|
||||
creditNumberPrefix: creditNoteSettings?.numberPrefix,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
creditAutoIncrement,
|
||||
}) => {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
|
||||
// Handle credit number changing.
|
||||
const handleCreditNumberChange = () => {
|
||||
openDialog('credit-number-form');
|
||||
};
|
||||
// Handle credit note no. field blur.
|
||||
const handleCreditNoBlur = (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
// Show the confirmation dialog if the value has changed and auto-increment
|
||||
// mode is enabled.
|
||||
if (values.credit_note_no !== newValue && creditAutoIncrement) {
|
||||
openDialog('credit-number-form', {
|
||||
initialFormValues: {
|
||||
onceManualNumber: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
// Setting the credit note number to the form will be manually in case
|
||||
// auto-increment is disable.
|
||||
if (!creditAutoIncrement) {
|
||||
setFieldValue('credit_note_number', newValue);
|
||||
setFieldValue('credit_note_number_manually', newValue);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FFormGroup
|
||||
name={'credit_note_number'}
|
||||
label={<T id={'credit_note.label_credit_note'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
inline={true}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<FInputGroup
|
||||
name={'credit_note_number'}
|
||||
minimal={true}
|
||||
value={values.credit_note_number}
|
||||
asyncControl={true}
|
||||
onBlur={handleCreditNoBlur}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleCreditNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T id={'setting_your_auto_generated_credit_note_number'} />
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FFormGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Credit note form header fields.
|
||||
*/
|
||||
function CreditNoteFormHeaderFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
creditAutoIncrement,
|
||||
creditNumberPrefix,
|
||||
creditNextNumber,
|
||||
}) {
|
||||
export default function CreditNoteFormHeaderFields({}) {
|
||||
// Credit note form context.
|
||||
const { customers } = useCreditNoteFormContext();
|
||||
|
||||
// Handle credit number changing.
|
||||
const handleCreditNumberChange = () => {
|
||||
openDialog('credit-number-form');
|
||||
};
|
||||
|
||||
// Handle credit no. field blur.
|
||||
const handleCreditNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && creditAutoIncrement) {
|
||||
openDialog('credit-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Syncs credit number settings with form.
|
||||
useObserveCreditNoSettings(creditNumberPrefix, creditNextNumber);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
{/* ----------- Customer name ----------- */}
|
||||
@@ -119,7 +170,6 @@ function CreditNoteFormHeaderFields({
|
||||
name={'exchange_rate'}
|
||||
formGroupProps={{ label: ' ', inline: true }}
|
||||
/>
|
||||
|
||||
{/* ----------- Credit note date ----------- */}
|
||||
<FastField name={'credit_note_date'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
@@ -146,43 +196,8 @@ function CreditNoteFormHeaderFields({
|
||||
)}
|
||||
</FastField>
|
||||
{/* ----------- Credit note # ----------- */}
|
||||
<Field name={'credit_note_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'credit_note.label_credit_note'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
inline={true}
|
||||
className={classNames(
|
||||
'form-group--credit_note_number',
|
||||
CLASSES.FILL,
|
||||
)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="credit_note_number" />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleCreditNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleCreditNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T id={'setting_your_auto_generated_credit_note_number'} />
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<CreditNoteTransactionNoField />
|
||||
|
||||
{/* ----------- Reference ----------- */}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
@@ -200,14 +215,6 @@ function CreditNoteFormHeaderFields({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ creditNoteSettings }) => ({
|
||||
creditAutoIncrement: creditNoteSettings?.autoIncrement,
|
||||
creditNextNumber: creditNoteSettings?.nextNumber,
|
||||
creditNumberPrefix: creditNoteSettings?.numberPrefix,
|
||||
})),
|
||||
)(CreditNoteFormHeaderFields);
|
||||
|
||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||
font-size: 11px;
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import * as R from 'ramda';
|
||||
import { ExchangeRateInputGroup } from '@/components';
|
||||
import { useCurrentOrganization } from '@/hooks/state';
|
||||
import { useCreditNoteIsForeignCustomer } from './utils';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import { transactionNumber } from '@/utils';
|
||||
|
||||
/**
|
||||
* credit exchange rate input field.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function CreditNoteExchangeRateInputField({ ...props }) {
|
||||
export function CreditNoteExchangeRateInputField({ ...props }) {
|
||||
const currentOrganization = useCurrentOrganization();
|
||||
const { values } = useFormikContext();
|
||||
|
||||
@@ -27,4 +29,30 @@ import { useCreditNoteIsForeignCustomer } from './utils';
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs credit note auto-increment settings to form.
|
||||
* @return {React.ReactNode}
|
||||
*/
|
||||
export const CreditNoteSyncIncrementSettingsToForm = R.compose(
|
||||
withSettings(({ creditNoteSettings }) => ({
|
||||
creditAutoIncrement: creditNoteSettings?.autoIncrement,
|
||||
creditNextNumber: creditNoteSettings?.nextNumber,
|
||||
creditNumberPrefix: creditNoteSettings?.numberPrefix,
|
||||
})),
|
||||
)(({ creditAutoIncrement, creditNextNumber, creditNumberPrefix }) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
useEffect(() => {
|
||||
// Do not update if the credit note auto-increment mode is disabled.
|
||||
if (!creditAutoIncrement) return;
|
||||
|
||||
setFieldValue(
|
||||
'credit_note_number',
|
||||
transactionNumber(creditNumberPrefix, creditNextNumber),
|
||||
);
|
||||
}, [setFieldValue, creditNumberPrefix, creditNextNumber]);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -40,7 +40,8 @@ export const defaultCreditNote = {
|
||||
customer_id: '',
|
||||
credit_note_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
credit_note_number: '',
|
||||
credit_note_no_manually: false,
|
||||
// Holds the credit note number that entered manually only.
|
||||
credit_note_number_manually: false,
|
||||
open: '',
|
||||
reference_no: '',
|
||||
note: '',
|
||||
@@ -130,18 +131,6 @@ export const entriesFieldShouldUpdate = (newProps, oldProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Syncs invoice no. settings with form.
|
||||
*/
|
||||
export const useObserveCreditNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
const creditNo = transactionNumber(prefix, nextNumber);
|
||||
setFieldValue('credit_note_number', creditNo);
|
||||
}, [setFieldValue, prefix, nextNumber]);
|
||||
};
|
||||
|
||||
export const useSetPrimaryBranchToForm = () => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
const { branches, isBranchesSuccess } = useCreditNoteFormContext();
|
||||
|
||||
@@ -19,6 +19,7 @@ import EstimateFloatingActions from './EstimateFloatingActions';
|
||||
import EstimateFormFooter from './EstimateFormFooter';
|
||||
import EstimateFormDialogs from './EstimateFormDialogs';
|
||||
import EstimtaeFormTopBar from './EstimtaeFormTopBar';
|
||||
import { EstimateIncrementSyncSettingsToForm } from './components';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';
|
||||
@@ -31,6 +32,7 @@ import {
|
||||
defaultEstimate,
|
||||
transfromsFormValuesToRequest,
|
||||
handleErrors,
|
||||
resetFormState,
|
||||
} from './utils';
|
||||
|
||||
/**
|
||||
@@ -40,7 +42,7 @@ function EstimateForm({
|
||||
// #withSettings
|
||||
estimateNextNumber,
|
||||
estimateNumberPrefix,
|
||||
estimateIncrementMode,
|
||||
estimateAutoIncrementMode,
|
||||
|
||||
// #withCurrentOrganization
|
||||
organization: { base_currency },
|
||||
@@ -66,14 +68,16 @@ function EstimateForm({
|
||||
? { ...transformToEditForm(estimate) }
|
||||
: {
|
||||
...defaultEstimate,
|
||||
...(estimateIncrementMode && {
|
||||
// If the auto-increment mode is enabled, take the next estimate
|
||||
// number from the settings.
|
||||
...(estimateAutoIncrementMode && {
|
||||
estimate_number: estimateNumber,
|
||||
}),
|
||||
entries: orderingLinesIndexes(defaultEstimate.entries),
|
||||
currency_code: base_currency,
|
||||
}),
|
||||
}),
|
||||
[estimate, estimateNumber, estimateIncrementMode, base_currency],
|
||||
[estimate, estimateNumber, estimateAutoIncrementMode, base_currency],
|
||||
);
|
||||
|
||||
// Handles form submit.
|
||||
@@ -118,7 +122,7 @@ function EstimateForm({
|
||||
history.push('/estimates');
|
||||
}
|
||||
if (submitPayload.resetForm) {
|
||||
resetForm();
|
||||
resetFormState({ resetForm, initialValues, values });
|
||||
}
|
||||
};
|
||||
// Handle the request error.
|
||||
@@ -161,7 +165,11 @@ function EstimateForm({
|
||||
<EstimateFormFooter />
|
||||
<EstimateFloatingActions />
|
||||
|
||||
{/*------- Dialogs -------*/}
|
||||
<EstimateFormDialogs />
|
||||
|
||||
{/*------- Effects -------*/}
|
||||
<EstimateIncrementSyncSettingsToForm />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
@@ -172,7 +180,7 @@ export default compose(
|
||||
withSettings(({ estimatesSettings }) => ({
|
||||
estimateNextNumber: estimatesSettings?.nextNumber,
|
||||
estimateNumberPrefix: estimatesSettings?.numberPrefix,
|
||||
estimateIncrementMode: estimatesSettings?.autoIncrement,
|
||||
estimateAutoIncrementMode: estimatesSettings?.autoIncrement,
|
||||
})),
|
||||
withCurrentOrganization(),
|
||||
)(EstimateForm);
|
||||
|
||||
@@ -9,10 +9,14 @@ import EstimateNumberDialog from '@/containers/Dialogs/EstimateNumberDialog';
|
||||
export default function EstimateFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the invoice number form submit confirm.
|
||||
const handleEstimateNumberFormConfirm = ({ incrementNumber, manually }) => {
|
||||
setFieldValue('estimate_number', incrementNumber || '');
|
||||
setFieldValue('estimate_number_manually', manually);
|
||||
// Update the form once the estimate number form submit confirm.
|
||||
const handleEstimateNumberFormConfirm = (settings) => {
|
||||
setFieldValue('estimate_number', settings.transactionNumber);
|
||||
setFieldValue('estimate_number_manually', '');
|
||||
|
||||
if (settings.incrementMode !== 'auto') {
|
||||
setFieldValue('estimate_number_manually', settings.transactionNumber);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -12,6 +12,19 @@ import { PageFormBigNumber } from '@/components';
|
||||
|
||||
// Estimate form top header.
|
||||
function EstimateFormHeader() {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<EstimateFormHeaderFields />
|
||||
<EstimateFormBigTotal />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Big total of estimate form header.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
function EstimateFormBigTotal() {
|
||||
const {
|
||||
values: { entries, currency_code },
|
||||
} = useFormikContext();
|
||||
@@ -20,15 +33,11 @@ function EstimateFormHeader() {
|
||||
const totalDueAmount = useMemo(() => getEntriesTotal(entries), [entries]);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<EstimateFormHeaderFields />
|
||||
|
||||
<PageFormBigNumber
|
||||
label={intl.get('amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
</div>
|
||||
<PageFormBigNumber
|
||||
label={intl.get('amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as R from 'ramda';
|
||||
import styled from 'styled-components';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
@@ -10,12 +11,21 @@ import {
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FeatureCan, FFormGroup, FormattedMessage as T } from '@/components';
|
||||
import { FastField, Field, ErrorMessage } from 'formik';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
|
||||
import {
|
||||
FeatureCan,
|
||||
FFormGroup,
|
||||
FInputGroup,
|
||||
FormattedMessage as T,
|
||||
CustomerSelectField,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
InputPrependButton,
|
||||
CustomerDrawerLink,
|
||||
} from '@/components';
|
||||
import {
|
||||
momentFormatter,
|
||||
compose,
|
||||
tansformDateValue,
|
||||
inputIntent,
|
||||
handleDateChange,
|
||||
@@ -23,57 +33,99 @@ import {
|
||||
import { customersFieldShouldUpdate } from './utils';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { Features } from '@/constants';
|
||||
import {
|
||||
CustomerSelectField,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
InputPrependButton,
|
||||
CustomerDrawerLink,
|
||||
} from '@/components';
|
||||
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
|
||||
import { ProjectsSelect } from '@/containers/Projects/components';
|
||||
import {
|
||||
EstimateExchangeRateInputField,
|
||||
EstimateProjectSelectButton,
|
||||
} from './components';
|
||||
|
||||
import { useObserveEstimateNoSettings } from './utils';
|
||||
import { useEstimateFormContext } from './EstimateFormProvider';
|
||||
|
||||
/**
|
||||
* Estimate number field of estimate form.
|
||||
*/
|
||||
const EstimateFormEstimateNumberField = R.compose(
|
||||
withDialogActions,
|
||||
withSettings(({ estimatesSettings }) => ({
|
||||
estimateNextNumber: estimatesSettings?.nextNumber,
|
||||
estimateNumberPrefix: estimatesSettings?.numberPrefix,
|
||||
estimateAutoIncrement: estimatesSettings?.autoIncrement,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
estimateAutoIncrement,
|
||||
}) => {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
|
||||
const handleEstimateNumberBtnClick = () => {
|
||||
openDialog('estimate-number-form', {});
|
||||
};
|
||||
// Handle estimate no. field blur.
|
||||
const handleEstimateNoBlur = (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
// Show the confirmation dialog if the value has changed and auto-increment
|
||||
// mode is enabled.
|
||||
if (values.estimate_number !== newValue && estimateAutoIncrement) {
|
||||
openDialog('estimate-number-form', {
|
||||
initialFormValues: {
|
||||
onceManualNumber: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
// Setting the estimate number to the form will be manually in case
|
||||
// auto-increment is disable.
|
||||
if (!estimateAutoIncrement) {
|
||||
setFieldValue('estimate_number', newValue);
|
||||
setFieldValue('estimate_number_manually', newValue);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FFormGroup
|
||||
name={'estimate_number'}
|
||||
label={<T id={'estimate'} />}
|
||||
inline={true}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<FInputGroup
|
||||
name={'estimate_number'}
|
||||
minimal={true}
|
||||
asyncControl={true}
|
||||
onBlur={handleEstimateNoBlur}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleEstimateNumberBtnClick,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: <T id={'setting_your_auto_generated_estimate_number'} />,
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FFormGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Estimate form header.
|
||||
*/
|
||||
function EstimateFormHeader({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
estimateAutoIncrement,
|
||||
estimateNumberPrefix,
|
||||
estimateNextNumber,
|
||||
}) {
|
||||
export default function EstimateFormHeader() {
|
||||
const { customers, projects } = useEstimateFormContext();
|
||||
|
||||
const handleEstimateNumberBtnClick = () => {
|
||||
openDialog('estimate-number-form', {});
|
||||
};
|
||||
const handleEstimateNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && estimateAutoIncrement) {
|
||||
openDialog('estimate-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
// Syncs estimate number settings with the form.
|
||||
useObserveEstimateNoSettings(estimateNumberPrefix, estimateNextNumber);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
{/* ----------- Customer name ----------- */}
|
||||
@@ -113,13 +165,12 @@ function EstimateFormHeader({
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
{/* ----------- Exchange rate ----------- */}
|
||||
{/* ----------- Exchange Rate ----------- */}
|
||||
<EstimateExchangeRateInputField
|
||||
name={'exchange_rate'}
|
||||
formGroupProps={{ label: ' ', inline: true }}
|
||||
/>
|
||||
|
||||
{/* ----------- Estimate date ----------- */}
|
||||
{/* ----------- Estimate Date ----------- */}
|
||||
<FastField name={'estimate_date'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
@@ -176,40 +227,7 @@ function EstimateFormHeader({
|
||||
</FastField>
|
||||
|
||||
{/* ----------- Estimate number ----------- */}
|
||||
<Field name={'estimate_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'estimate'} />}
|
||||
inline={true}
|
||||
className={('form-group--estimate-number', CLASSES.FILL)}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="estimate_number" />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleEstimateNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleEstimateNumberBtnClick,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T id={'setting_your_auto_generated_estimate_number'} />
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<EstimateFormEstimateNumberField />
|
||||
|
||||
{/* ----------- Reference ----------- */}
|
||||
<FastField name={'reference'}>
|
||||
@@ -246,15 +264,6 @@ function EstimateFormHeader({
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ estimatesSettings }) => ({
|
||||
estimateNextNumber: estimatesSettings?.nextNumber,
|
||||
estimateNumberPrefix: estimatesSettings?.numberPrefix,
|
||||
estimateAutoIncrement: estimatesSettings?.autoIncrement,
|
||||
})),
|
||||
)(EstimateFormHeader);
|
||||
|
||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||
font-size: 11px;
|
||||
margin-top: 6px;
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import * as R from 'ramda';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { ExchangeRateInputGroup } from '@/components';
|
||||
import { useCurrentOrganization } from '@/hooks/state';
|
||||
import { useEstimateIsForeignCustomer } from './utils';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import { transactionNumber } from '@/utils';
|
||||
import { useUpdateEffect } from '@/hooks';
|
||||
|
||||
/**
|
||||
* Estimate exchange rate input field.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function EstimateExchangeRateInputField({ ...props }) {
|
||||
export function EstimateExchangeRateInputField({ ...props }) {
|
||||
const currentOrganization = useCurrentOrganization();
|
||||
const { values } = useFormikContext();
|
||||
|
||||
@@ -35,6 +38,37 @@ import { useEstimateIsForeignCustomer } from './utils';
|
||||
* Estimate project select.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function EstimateProjectSelectButton({ label }) {
|
||||
export function EstimateProjectSelectButton({ label }) {
|
||||
return <Button text={label ?? intl.get('select_project')} />;
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs the estimate auto-increment settings to estimate form.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
export const EstimateIncrementSyncSettingsToForm = R.compose(
|
||||
withSettings(({ estimatesSettings }) => ({
|
||||
estimateNextNumber: estimatesSettings?.nextNumber,
|
||||
estimateNumberPrefix: estimatesSettings?.numberPrefix,
|
||||
estimateAutoIncrement: estimatesSettings?.autoIncrement,
|
||||
})),
|
||||
)(({ estimateNextNumber, estimateNumberPrefix, estimateAutoIncrement }) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
useUpdateEffect(() => {
|
||||
// Do not update if the estimate auto-increment mode is disabled.
|
||||
if (!estimateAutoIncrement) return null;
|
||||
|
||||
setFieldValue(
|
||||
'estimate_number',
|
||||
transactionNumber(estimateNumberPrefix, estimateNextNumber),
|
||||
);
|
||||
}, [
|
||||
setFieldValue,
|
||||
estimateNumberPrefix,
|
||||
estimateNextNumber,
|
||||
estimateAutoIncrement,
|
||||
]);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -7,7 +7,6 @@ import { useFormikContext } from 'formik';
|
||||
import { omit, first } from 'lodash';
|
||||
import {
|
||||
defaultFastFieldShouldUpdate,
|
||||
transactionNumber,
|
||||
repeatValue,
|
||||
transformToForm,
|
||||
formattedAmount,
|
||||
@@ -37,6 +36,8 @@ export const defaultEstimate = {
|
||||
estimate_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
expiration_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
estimate_number: '',
|
||||
// Holds the estimate number that entered manually only.
|
||||
estimate_number_manually: '',
|
||||
delivered: '',
|
||||
reference: '',
|
||||
note: '',
|
||||
@@ -74,18 +75,6 @@ export const transformToEditForm = (estimate) => {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Syncs estimate number of the settings with the context form.
|
||||
*/
|
||||
export const useObserveEstimateNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
const estimateNo = transactionNumber(prefix, nextNumber);
|
||||
setFieldValue('estimate_number', estimateNo);
|
||||
}, [setFieldValue, prefix, nextNumber]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detarmines customers fast field when update.
|
||||
*/
|
||||
@@ -154,6 +143,8 @@ export const transfromsFormValuesToRequest = (values) => {
|
||||
);
|
||||
return {
|
||||
...omit(values, ['estimate_number_manually', 'estimate_number']),
|
||||
// The `estimate_number_manually` will be presented just if the auto-increment
|
||||
// is disable, always both attributes hold the same value in manual mode.
|
||||
...(values.estimate_number_manually && {
|
||||
estimate_number: values.estimate_number,
|
||||
}),
|
||||
@@ -235,3 +226,17 @@ export const useEstimateIsForeignCustomer = () => {
|
||||
);
|
||||
return isForeignCustomer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the form values.
|
||||
*/
|
||||
export const resetFormState = ({ initialValues, values, resetForm }) => {
|
||||
resetForm({
|
||||
values: {
|
||||
// Reset the all values except the warehouse and brand id.
|
||||
...initialValues,
|
||||
warehouse_id: values.warehouse_id,
|
||||
brand_id: values.brand_id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -31,7 +31,9 @@ import {
|
||||
defaultInvoice,
|
||||
transformErrors,
|
||||
transformValueToRequest,
|
||||
resetFormState,
|
||||
} from './utils';
|
||||
import { InvoiceNoSyncSettingsToForm } from './components';
|
||||
|
||||
/**
|
||||
* Invoice form.
|
||||
@@ -40,7 +42,7 @@ function InvoiceForm({
|
||||
// #withSettings
|
||||
invoiceNextNumber,
|
||||
invoiceNumberPrefix,
|
||||
invoiceIncrementMode,
|
||||
invoiceAutoIncrementMode,
|
||||
|
||||
// #withCurrentOrganization
|
||||
organization: { base_currency },
|
||||
@@ -64,23 +66,21 @@ function InvoiceForm({
|
||||
invoiceNextNumber,
|
||||
);
|
||||
// Form initial values.
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
...(!isEmpty(invoice)
|
||||
? { ...transformToEditForm(invoice) }
|
||||
: {
|
||||
...defaultInvoice,
|
||||
...(invoiceIncrementMode && {
|
||||
invoice_no: invoiceNumber,
|
||||
}),
|
||||
entries: orderingLinesIndexes(defaultInvoice.entries),
|
||||
currency_code: base_currency,
|
||||
...newInvoice,
|
||||
const initialValues = {
|
||||
...(!isEmpty(invoice)
|
||||
? { ...transformToEditForm(invoice) }
|
||||
: {
|
||||
...defaultInvoice,
|
||||
// If the auto-increment mode is enabled, take the next invoice
|
||||
// number from the settings.
|
||||
...(invoiceAutoIncrementMode && {
|
||||
invoice_no: invoiceNumber,
|
||||
}),
|
||||
}),
|
||||
[invoice, newInvoice, invoiceNumber, invoiceIncrementMode, base_currency],
|
||||
);
|
||||
|
||||
entries: orderingLinesIndexes(defaultInvoice.entries),
|
||||
currency_code: base_currency,
|
||||
...newInvoice,
|
||||
}),
|
||||
};
|
||||
// Handles form submit.
|
||||
const handleSubmit = (values, { setSubmitting, setErrors, resetForm }) => {
|
||||
setSubmitting(true);
|
||||
@@ -105,7 +105,6 @@ function InvoiceForm({
|
||||
delivered: submitPayload.deliver,
|
||||
from_estimate_id: estimateId,
|
||||
};
|
||||
|
||||
// Handle the request success.
|
||||
const onSuccess = () => {
|
||||
AppToaster.show({
|
||||
@@ -123,10 +122,9 @@ function InvoiceForm({
|
||||
history.push('/invoices');
|
||||
}
|
||||
if (submitPayload.resetForm) {
|
||||
resetForm();
|
||||
resetFormState({ resetForm, initialValues, values });
|
||||
}
|
||||
};
|
||||
|
||||
// Handle the request error.
|
||||
const onError = ({
|
||||
response: {
|
||||
@@ -144,7 +142,6 @@ function InvoiceForm({
|
||||
createInvoiceMutate(form).then(onSuccess).catch(onError);
|
||||
}
|
||||
};
|
||||
|
||||
// Create invoice form schema.
|
||||
const CreateInvoiceFormSchema = getCreateInvoiceFormSchema();
|
||||
|
||||
@@ -172,7 +169,12 @@ function InvoiceForm({
|
||||
<InvoiceItemsEntriesEditorField />
|
||||
<InvoiceFormFooter />
|
||||
<InvoiceFloatingActions />
|
||||
|
||||
{/*---------- Dialogs ----------*/}
|
||||
<InvoiceFormDialogs />
|
||||
|
||||
{/*---------- Effects ----------*/}
|
||||
<InvoiceNoSyncSettingsToForm />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
@@ -184,7 +186,7 @@ export default compose(
|
||||
withSettings(({ invoiceSettings }) => ({
|
||||
invoiceNextNumber: invoiceSettings?.nextNumber,
|
||||
invoiceNumberPrefix: invoiceSettings?.numberPrefix,
|
||||
invoiceIncrementMode: invoiceSettings?.autoIncrement,
|
||||
invoiceAutoIncrementMode: invoiceSettings?.autoIncrement,
|
||||
})),
|
||||
withCurrentOrganization(),
|
||||
)(InvoiceForm);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import InvoiceNumberDialog from '@/containers/Dialogs/InvoiceNumberDialog';
|
||||
import { useFormikContext } from 'formik';
|
||||
import InvoiceNumberDialog from '@/containers/Dialogs/InvoiceNumberDialog';
|
||||
import { DialogsName } from '@/constants/dialogs';
|
||||
|
||||
/**
|
||||
* Invoice form dialogs.
|
||||
@@ -10,17 +11,21 @@ export default function InvoiceFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the invoice number form submit confirm.
|
||||
const handleInvoiceNumberFormConfirm = ({ incrementNumber, manually }) => {
|
||||
setFieldValue('invoice_no', incrementNumber || '');
|
||||
setFieldValue('invoice_no_manually', manually);
|
||||
const handleInvoiceNumberFormConfirm = (settings) => {
|
||||
// Set the invoice transaction no. that cames from dialog to the form.
|
||||
// the `invoice_no_manually` will be empty except the increment mode is not auto.
|
||||
setFieldValue('invoice_no', settings.transactionNumber);
|
||||
setFieldValue('invoice_no_manually', '');
|
||||
|
||||
if (settings.incrementMode !== 'auto') {
|
||||
setFieldValue('invoice_no_manually', settings.transactionNumber);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<InvoiceNumberDialog
|
||||
dialogName={'invoice-number-form'}
|
||||
onConfirm={handleInvoiceNumberFormConfirm}
|
||||
/>
|
||||
</>
|
||||
<InvoiceNumberDialog
|
||||
dialogName={DialogsName.InvoiceNumberSettings}
|
||||
onConfirm={handleInvoiceNumberFormConfirm}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,19 @@ import { useInvoiceTotal } from './utils';
|
||||
* Invoice form header section.
|
||||
*/
|
||||
function InvoiceFormHeader() {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<InvoiceFormHeaderFields />
|
||||
<InvoiceFormBigTotal />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Big total of invoice form header.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
function InvoiceFormBigTotal() {
|
||||
const {
|
||||
values: { currency_code },
|
||||
} = useFormikContext();
|
||||
@@ -22,14 +35,11 @@ function InvoiceFormHeader() {
|
||||
const totalDueAmount = useInvoiceTotal();
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<InvoiceFormHeaderFields />
|
||||
<PageFormBigNumber
|
||||
label={intl.get('due_amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
</div>
|
||||
<PageFormBigNumber
|
||||
label={intl.get('due_amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
);
|
||||
}
|
||||
export default InvoiceFormHeader;
|
||||
|
||||
@@ -10,7 +10,8 @@ import {
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FastField, Field, ErrorMessage, useFormikContext } from 'formik';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import {
|
||||
FFormGroup,
|
||||
@@ -23,14 +24,16 @@ import {
|
||||
Icon,
|
||||
InputPrependButton,
|
||||
FeatureCan,
|
||||
FInputGroup,
|
||||
} from '@/components';
|
||||
import { momentFormatter, compose, tansformDateValue } from '@/utils';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { inputIntent, handleDateChange } from '@/utils';
|
||||
import {
|
||||
useObserveInvoiceNoSettings,
|
||||
customerNameFieldShouldUpdate,
|
||||
} from './utils';
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
inputIntent,
|
||||
handleDateChange,
|
||||
} from '@/utils';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { customerNameFieldShouldUpdate } from './utils';
|
||||
|
||||
import { useInvoiceFormContext } from './InvoiceFormProvider';
|
||||
import {
|
||||
@@ -42,48 +45,98 @@ import {
|
||||
ProjectBillableEntriesLink,
|
||||
} from '@/containers/Projects/components';
|
||||
import { Features } from '@/constants';
|
||||
import { DialogsName } from '@/constants/dialogs';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
|
||||
/**
|
||||
* Invoice number field of invoice form.
|
||||
*/
|
||||
const InvoiceFormInvoiceNumberField = R.compose(
|
||||
withDialogActions,
|
||||
withSettings(({ invoiceSettings }) => ({
|
||||
invoiceAutoIncrement: invoiceSettings?.autoIncrement,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
invoiceAutoIncrement,
|
||||
}) => {
|
||||
// Formik context.
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
|
||||
// Handle invoice number changing.
|
||||
const handleInvoiceNumberChange = () => {
|
||||
openDialog(DialogsName.InvoiceNumberSettings);
|
||||
};
|
||||
// Handle invoice no. field blur.
|
||||
const handleInvoiceNoBlur = (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
// Show the confirmation dialog if the value has changed and auto-increment
|
||||
// mode is enabled.
|
||||
if (values.invoice_no !== newValue && invoiceAutoIncrement) {
|
||||
openDialog(DialogsName.InvoiceNumberSettings, {
|
||||
initialFormValues: {
|
||||
onceManualNumber: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
// Setting the invoice number to the form will be manually in case
|
||||
// auto-increment is disable.
|
||||
if (!invoiceAutoIncrement) {
|
||||
setFieldValue('invoice_no', newValue);
|
||||
setFieldValue('invoice_no_manually', newValue);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FFormGroup
|
||||
name={'invoice_no'}
|
||||
label={<T id={'invoice_no'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
inline={true}
|
||||
fastField={true}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<FInputGroup
|
||||
name={'invoice_no'}
|
||||
minimal={true}
|
||||
asyncControl={true}
|
||||
onBlur={handleInvoiceNoBlur}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleInvoiceNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: <T id={'setting_your_auto_generated_invoice_number'} />,
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FFormGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
InvoiceFormInvoiceNumberField.displayName = 'InvoiceFormInvoiceNumberField';
|
||||
|
||||
/**
|
||||
* Invoice form header fields.
|
||||
*/
|
||||
function InvoiceFormHeaderFields({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
invoiceAutoIncrement,
|
||||
invoiceNumberPrefix,
|
||||
invoiceNextNumber,
|
||||
}) {
|
||||
export default function InvoiceFormHeaderFields() {
|
||||
// Invoice form context.
|
||||
const { customers, projects } = useInvoiceFormContext();
|
||||
|
||||
// Formik context.
|
||||
const { values } = useFormikContext();
|
||||
|
||||
// Handle invoice number changing.
|
||||
const handleInvoiceNumberChange = () => {
|
||||
openDialog('invoice-number-form');
|
||||
};
|
||||
// Handle invoice no. field blur.
|
||||
const handleInvoiceNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && invoiceAutoIncrement) {
|
||||
openDialog('invoice-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
// Syncs invoice number settings with form.
|
||||
useObserveInvoiceNoSettings(invoiceNumberPrefix, invoiceNextNumber);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
{/* ----------- Customer name ----------- */}
|
||||
@@ -189,40 +242,7 @@ function InvoiceFormHeaderFields({
|
||||
</Row>
|
||||
|
||||
{/* ----------- Invoice number ----------- */}
|
||||
<Field name={'invoice_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'invoice_no'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
inline={true}
|
||||
className={classNames('form-group--invoice-no', CLASSES.FILL)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="invoice_no" />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleInvoiceNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleInvoiceNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T id={'setting_your_auto_generated_invoice_number'} />
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<InvoiceFormInvoiceNumberField />
|
||||
|
||||
{/* ----------- Reference ----------- */}
|
||||
<FastField name={'reference_no'}>
|
||||
@@ -264,15 +284,6 @@ function InvoiceFormHeaderFields({
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ invoiceSettings }) => ({
|
||||
invoiceAutoIncrement: invoiceSettings?.autoIncrement,
|
||||
invoiceNextNumber: invoiceSettings?.nextNumber,
|
||||
invoiceNumberPrefix: invoiceSettings?.numberPrefix,
|
||||
})),
|
||||
)(InvoiceFormHeaderFields);
|
||||
|
||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||
font-size: 11px;
|
||||
margin-top: 6px;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import * as R from 'ramda';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { ExchangeRateInputGroup } from '@/components';
|
||||
import { useCurrentOrganization } from '@/hooks/state';
|
||||
import { useInvoiceIsForeignCustomer } from './utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import { useUpdateEffect } from '@/hooks';
|
||||
import { transactionNumber } from '@/utils';
|
||||
|
||||
/**
|
||||
* Invoice exchange rate input field.
|
||||
@@ -37,3 +41,28 @@ export function InvoiceExchangeRateInputField({ ...props }) {
|
||||
export function InvoiceProjectSelectButton({ label }) {
|
||||
return <Button text={label ?? intl.get('select_project')} />;
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs invoice auto-increment settings to invoice form once update.
|
||||
*/
|
||||
export const InvoiceNoSyncSettingsToForm = R.compose(
|
||||
withSettings(({ invoiceSettings }) => ({
|
||||
invoiceAutoIncrement: invoiceSettings?.autoIncrement,
|
||||
invoiceNextNumber: invoiceSettings?.nextNumber,
|
||||
invoiceNumberPrefix: invoiceSettings?.numberPrefix,
|
||||
})),
|
||||
)(({ invoiceAutoIncrement, invoiceNextNumber, invoiceNumberPrefix }) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
useUpdateEffect(() => {
|
||||
// Do not update if the invoice auto-increment mode is disabled.
|
||||
if (!invoiceAutoIncrement) return null;
|
||||
|
||||
setFieldValue(
|
||||
'invoice_no',
|
||||
transactionNumber(invoiceNumberPrefix, invoiceNextNumber),
|
||||
);
|
||||
}, [setFieldValue, invoiceNumberPrefix, invoiceNextNumber]);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -43,7 +43,8 @@ export const defaultInvoice = {
|
||||
due_date: moment().format('YYYY-MM-DD'),
|
||||
delivered: '',
|
||||
invoice_no: '',
|
||||
invoice_no_manually: false,
|
||||
// Holds the invoice number that entered manually only.
|
||||
invoice_no_manually: '',
|
||||
reference_no: '',
|
||||
invoice_message: '',
|
||||
terms_conditions: '',
|
||||
@@ -108,18 +109,6 @@ export const transformErrors = (errors, { setErrors }) => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Syncs invoice no. settings with form.
|
||||
*/
|
||||
export const useObserveInvoiceNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
const invoiceNo = transactionNumber(prefix, nextNumber);
|
||||
setFieldValue('invoice_no', invoiceNo);
|
||||
}, [setFieldValue, prefix, nextNumber]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detarmines customer name field when should update.
|
||||
*/
|
||||
@@ -166,6 +155,8 @@ export function transformValueToRequest(values) {
|
||||
);
|
||||
return {
|
||||
...omit(values, ['invoice_no', 'invoice_no_manually']),
|
||||
// The `invoice_no_manually` will be presented just if the auto-increment
|
||||
// is disable, always both attributes hold the same value in manual mode.
|
||||
...(values.invoice_no_manually && {
|
||||
invoice_no: values.invoice_no,
|
||||
}),
|
||||
@@ -279,3 +270,14 @@ export const useInvoiceIsForeignCustomer = () => {
|
||||
);
|
||||
return isForeignCustomer;
|
||||
};
|
||||
|
||||
export const resetFormState = ({ initialValues, values, resetForm }) => {
|
||||
resetForm({
|
||||
values: {
|
||||
// Reset the all values except the warehouse and brand id.
|
||||
...initialValues,
|
||||
warehouse_id: values.warehouse_id,
|
||||
brand_id: values.brand_id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// @ts-nocheck
|
||||
import React, { useMemo } from 'react';
|
||||
import { sumBy, isEmpty, defaultTo } from 'lodash';
|
||||
import intl from 'react-intl-universal';
|
||||
import classNames from 'classnames';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { omit, sumBy, pick, isEmpty, defaultTo } from 'lodash';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
|
||||
import '@/style/pages/PaymentReceive/PageForm.scss';
|
||||
|
||||
@@ -35,7 +35,9 @@ import {
|
||||
transformToEditForm,
|
||||
transformFormToRequest,
|
||||
transformErrors,
|
||||
resetFormState,
|
||||
} from './utils';
|
||||
import { PaymentReceiveSyncIncrementSettingsToForm } from './components';
|
||||
|
||||
/**
|
||||
* Payment Receive form.
|
||||
@@ -68,7 +70,6 @@ function PaymentReceiveForm({
|
||||
paymentReceiveNumberPrefix,
|
||||
paymentReceiveNextNumber,
|
||||
);
|
||||
|
||||
// Form initial values.
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
@@ -76,10 +77,12 @@ function PaymentReceiveForm({
|
||||
? transformToEditForm(paymentReceiveEditPage, paymentEntriesEditPage)
|
||||
: {
|
||||
...defaultPaymentReceive,
|
||||
// If the auto-increment mode is enabled, take the next payment
|
||||
// number from the settings.
|
||||
...(paymentReceiveAutoIncrement && {
|
||||
payment_receive_no: nextPaymentNumber,
|
||||
deposit_account_id: defaultTo(preferredDepositAccount, ''),
|
||||
}),
|
||||
deposit_account_id: defaultTo(preferredDepositAccount, ''),
|
||||
currency_code: base_currency,
|
||||
}),
|
||||
}),
|
||||
@@ -113,7 +116,8 @@ function PaymentReceiveForm({
|
||||
const form = transformFormToRequest(values);
|
||||
|
||||
// Handle request response success.
|
||||
const onSaved = (response) => {
|
||||
const onSaved = () => {
|
||||
setSubmitting(false);
|
||||
AppToaster.show({
|
||||
message: intl.get(
|
||||
paymentReceiveId
|
||||
@@ -122,13 +126,12 @@ function PaymentReceiveForm({
|
||||
),
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
setSubmitting(false);
|
||||
|
||||
if (submitPayload.redirect) {
|
||||
history.push('/payment-receives');
|
||||
}
|
||||
if (submitPayload.resetForm) {
|
||||
resetForm();
|
||||
resetFormState({ resetForm, initialValues, values });
|
||||
}
|
||||
};
|
||||
// Handle request response errors.
|
||||
@@ -176,6 +179,9 @@ function PaymentReceiveForm({
|
||||
<PaymentReceiveFormFooter />
|
||||
<PaymentReceiveFloatingActions />
|
||||
|
||||
{/* ------- Effects ------- */}
|
||||
<PaymentReceiveSyncIncrementSettingsToForm />
|
||||
|
||||
{/* ------- Alerts & Dialogs ------- */}
|
||||
<PaymentReceiveFormAlerts />
|
||||
<PaymentReceiveFormDialogs />
|
||||
|
||||
@@ -9,17 +9,21 @@ import PaymentReceiveNumberDialog from '@/containers/Dialogs/PaymentReceiveNumbe
|
||||
export default function PaymentReceiveFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
const handleUpdatePaymentNumber = ({ incrementNumber, manually }) => {
|
||||
setFieldValue('payment_receive_no', incrementNumber);
|
||||
setFieldValue('payment_receive_no_manually', manually)
|
||||
const handleUpdatePaymentNumber = (settings) => {
|
||||
// Set the payment transaction no. that cames from dialog to the form.
|
||||
// the `payment_receive_no_manually` will be empty except the increment mode is not auto.
|
||||
setFieldValue('payment_receive_no', settings.transactionNumber);
|
||||
setFieldValue('payment_receive_no_manually', '');
|
||||
|
||||
if (settings.incrementMode !== 'auto') {
|
||||
setFieldValue('payment_receive_no_manually', settings.transactionNumber);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<PaymentReceiveNumberDialog
|
||||
dialogName={'payment-receive-number-form'}
|
||||
onConfirm={handleUpdatePaymentNumber}
|
||||
/>
|
||||
</>
|
||||
<PaymentReceiveNumberDialog
|
||||
dialogName={'payment-receive-number-form'}
|
||||
onConfirm={handleUpdatePaymentNumber}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,21 @@ import PaymentReceiveHeaderFields from './PaymentReceiveHeaderFields';
|
||||
* Payment receive form header.
|
||||
*/
|
||||
function PaymentReceiveFormHeader() {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_PRIMARY)}>
|
||||
<PaymentReceiveHeaderFields />
|
||||
<PaymentReceiveFormBigTotal />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Big total amount of payment receive form.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
function PaymentReceiveFormBigTotal() {
|
||||
// Formik form context.
|
||||
const {
|
||||
values: { currency_code, entries },
|
||||
@@ -25,20 +40,14 @@ function PaymentReceiveFormHeader() {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_PRIMARY)}>
|
||||
<PaymentReceiveHeaderFields />
|
||||
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_BIG_NUMBERS)}>
|
||||
<div class="big-amount">
|
||||
<span class="big-amount__label">
|
||||
<T id={'amount_received'} />
|
||||
</span>
|
||||
<h1 class="big-amount__number">
|
||||
<Money amount={paymentFullAmount} currency={currency_code} />
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_BIG_NUMBERS)}>
|
||||
<div class="big-amount">
|
||||
<span class="big-amount__label">
|
||||
<T id={'amount_received'} />
|
||||
</span>
|
||||
<h1 class="big-amount__number">
|
||||
<Money amount={paymentFullAmount} currency={currency_code} />
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -12,13 +12,13 @@ import {
|
||||
} from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { toSafeInteger } from 'lodash';
|
||||
import { FeatureCan, FormattedMessage as T } from '@/components';
|
||||
import { FastField, Field, useFormikContext, ErrorMessage } from 'formik';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import { FInputGroup, FeatureCan, FormattedMessage as T } from '@/components';
|
||||
import { useAutofocus } from '@/hooks';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import {
|
||||
compose,
|
||||
safeSumBy,
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
@@ -48,10 +48,8 @@ import {
|
||||
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withCurrentOrganization from '@/containers/Organization/withCurrentOrganization';
|
||||
|
||||
import {
|
||||
useObservePaymentNoSettings,
|
||||
amountPaymentEntries,
|
||||
fullAmountPaymentEntries,
|
||||
customersFieldShouldUpdate,
|
||||
@@ -59,21 +57,91 @@ import {
|
||||
} from './utils';
|
||||
import { Features } from '@/constants';
|
||||
|
||||
/**
|
||||
* Payment receive number field.
|
||||
*/
|
||||
const PaymentReceivePaymentNoField = R.compose(
|
||||
withSettings(({ paymentReceiveSettings }) => ({
|
||||
paymentReceiveAutoIncrement: paymentReceiveSettings?.autoIncrement,
|
||||
})),
|
||||
withDialogActions,
|
||||
)(
|
||||
({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
paymentReceiveAutoIncrement,
|
||||
}) => {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
|
||||
// Handle click open payment receive number dialog.
|
||||
const handleClickOpenDialog = () => {
|
||||
openDialog('payment-receive-number-form');
|
||||
};
|
||||
// Handle payment number field blur.
|
||||
const handlePaymentNoBlur = (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
// Show the confirmation dialog if the value has changed and auto-increment
|
||||
// mode is enabled.
|
||||
if (
|
||||
values.payment_receive_no !== newValue &&
|
||||
paymentReceiveAutoIncrement
|
||||
) {
|
||||
openDialog('payment-receive-number-form', {
|
||||
initialFormValues: {
|
||||
onceManualNumber: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
// Setting the payment number to the form will be manually in case
|
||||
// auto-increment is disable.
|
||||
if (!paymentReceiveAutoIncrement) {
|
||||
setFieldValue('payment_receive_no', newValue);
|
||||
setFieldValue('payment_receive_no_manually', newValue);
|
||||
}
|
||||
};
|
||||
return (
|
||||
<FFormGroup
|
||||
name={'payment_receive_no'}
|
||||
label={<T id={'payment_receive_no'} />}
|
||||
inline={true}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<FInputGroup
|
||||
name={'payment_receive_no'}
|
||||
minimal={true}
|
||||
value={values.payment_receive_no}
|
||||
asyncControl={true}
|
||||
onBlur={handlePaymentNoBlur}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleClickOpenDialog,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T id={'setting_your_auto_generated_payment_receive_number'} />
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FFormGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Payment receive header fields.
|
||||
*/
|
||||
function PaymentReceiveHeaderFields({
|
||||
// #withCurrentOrganization
|
||||
organization: { base_currency },
|
||||
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
paymentReceiveAutoIncrement,
|
||||
paymentReceiveNumberPrefix,
|
||||
paymentReceiveNextNumber,
|
||||
}) {
|
||||
export default function PaymentReceiveHeaderFields() {
|
||||
// Payment receive form context.
|
||||
const { customers, accounts, projects, isNewMode } =
|
||||
usePaymentReceiveFormContext();
|
||||
@@ -104,30 +172,6 @@ function PaymentReceiveHeaderFields({
|
||||
const newEntries = amountPaymentEntries(toSafeInteger(value), entries);
|
||||
setFieldValue('entries', newEntries);
|
||||
};
|
||||
// Handle click open payment receive number dialog.
|
||||
const handleClickOpenDialog = () => {
|
||||
openDialog('payment-receive-number-form');
|
||||
};
|
||||
|
||||
// Handle payment number field blur.
|
||||
const handlePaymentNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && paymentReceiveAutoIncrement) {
|
||||
openDialog('payment-receive-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Syncs payment receive number from settings to the form.
|
||||
useObservePaymentNoSettings(
|
||||
paymentReceiveNumberPrefix,
|
||||
paymentReceiveNextNumber,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
@@ -246,43 +290,7 @@ function PaymentReceiveHeaderFields({
|
||||
</Field>
|
||||
|
||||
{/* ------------ Payment receive no. ------------ */}
|
||||
<FastField name={'payment_receive_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'payment_receive_no'} />}
|
||||
inline={true}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
className={('form-group--payment_receive_no', CLASSES.FILL)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="payment_receive_no" />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handlePaymentNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleClickOpenDialog,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={'setting_your_auto_generated_payment_receive_number'}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<PaymentReceivePaymentNoField />
|
||||
|
||||
{/* ------------ Deposit account ------------ */}
|
||||
<FFormGroup
|
||||
@@ -349,16 +357,6 @@ function PaymentReceiveHeaderFields({
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSettings(({ paymentReceiveSettings }) => ({
|
||||
paymentReceiveNextNumber: paymentReceiveSettings?.nextNumber,
|
||||
paymentReceiveNumberPrefix: paymentReceiveSettings?.numberPrefix,
|
||||
paymentReceiveAutoIncrement: paymentReceiveSettings?.autoIncrement,
|
||||
})),
|
||||
withDialogActions,
|
||||
withCurrentOrganization(),
|
||||
)(PaymentReceiveHeaderFields);
|
||||
|
||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||
font-size: 11px;
|
||||
margin-top: 6px;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useEffect, useLayoutEffect } from 'react';
|
||||
import moment from 'moment';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import { useFormikContext } from 'formik';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import { Money, ExchangeRateInputGroup, MoneyFieldCell } from '@/components';
|
||||
|
||||
import { useCurrentOrganization } from '@/hooks/state';
|
||||
import { useEstimateIsForeignCustomer } from './utils';
|
||||
import { transactionNumber } from '@/utils';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
|
||||
/**
|
||||
* Invoice date cell.
|
||||
@@ -109,6 +112,41 @@ export function PaymentReceiveExchangeRateInputField({ ...props }) {
|
||||
* payment receive project select.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function PaymentReceiveProjectSelectButton({ label }) {
|
||||
export function PaymentReceiveProjectSelectButton({ label }) {
|
||||
return <Button text={label ?? intl.get('select_project')} />;
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs the auto-increment settings to payment receive form.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
export const PaymentReceiveSyncIncrementSettingsToForm = R.compose(
|
||||
withSettings(({ paymentReceiveSettings }) => ({
|
||||
paymentReceiveNextNumber: paymentReceiveSettings?.nextNumber,
|
||||
paymentReceiveNumberPrefix: paymentReceiveSettings?.numberPrefix,
|
||||
paymentReceiveAutoIncrement: paymentReceiveSettings?.autoIncrement,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
paymentReceiveNextNumber,
|
||||
paymentReceiveNumberPrefix,
|
||||
paymentReceiveAutoIncrement,
|
||||
}) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!paymentReceiveAutoIncrement) return;
|
||||
|
||||
setFieldValue(
|
||||
'payment_receive_no',
|
||||
transactionNumber(paymentReceiveNumberPrefix, paymentReceiveNextNumber),
|
||||
);
|
||||
}, [
|
||||
setFieldValue,
|
||||
paymentReceiveNumberPrefix,
|
||||
paymentReceiveNextNumber,
|
||||
paymentReceiveAutoIncrement,
|
||||
]);
|
||||
return null;
|
||||
},
|
||||
);
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
} from '@/utils';
|
||||
import { useCurrentOrganization } from '@/hooks/state';
|
||||
|
||||
|
||||
// Default payment receive entry.
|
||||
export const defaultPaymentReceiveEntry = {
|
||||
index: '',
|
||||
@@ -37,8 +36,10 @@ export const defaultPaymentReceive = {
|
||||
payment_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
reference_no: '',
|
||||
payment_receive_no: '',
|
||||
// Holds the payment number that entered manually only.
|
||||
payment_receive_no_manually: '',
|
||||
statement: '',
|
||||
full_amount: '',
|
||||
full_amount: '',
|
||||
currency_code: '',
|
||||
branch_id: '',
|
||||
exchange_rate: 1,
|
||||
@@ -123,18 +124,6 @@ export const fullAmountPaymentEntries = (entries) => {
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Syncs payment receive number settings with form.
|
||||
*/
|
||||
export const useObservePaymentNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
const invoiceNo = transactionNumber(prefix, nextNumber);
|
||||
setFieldValue('payment_receive_no', invoiceNo);
|
||||
}, [setFieldValue, prefix, nextNumber]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detarmines the customers fast-field should update.
|
||||
*/
|
||||
@@ -168,6 +157,8 @@ export const transformFormToRequest = (form) => {
|
||||
|
||||
return {
|
||||
...omit(form, ['payment_receive_no_manually', 'payment_receive_no']),
|
||||
// The `payment_receive_no_manually` will be presented just if the auto-increment
|
||||
// is disable, always both attributes hold the same value in manual mode.
|
||||
...(form.payment_receive_no_manually && {
|
||||
payment_receive_no: form.payment_receive_no,
|
||||
}),
|
||||
@@ -264,3 +255,13 @@ export const useEstimateIsForeignCustomer = () => {
|
||||
);
|
||||
return isForeignCustomer;
|
||||
};
|
||||
|
||||
export const resetFormState = ({ initialValues, values, resetForm }) => {
|
||||
resetForm({
|
||||
values: {
|
||||
// Reset the all values except the brand id.
|
||||
...initialValues,
|
||||
brand_id: values.brand_id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -33,7 +33,9 @@ import {
|
||||
defaultReceipt,
|
||||
handleErrors,
|
||||
transformFormValuesToRequest,
|
||||
resetFormState,
|
||||
} from './utils';
|
||||
import { ReceiptSyncIncrementSettingsToForm } from './components';
|
||||
|
||||
/**
|
||||
* Receipt form.
|
||||
@@ -121,7 +123,7 @@ function ReceiptForm({
|
||||
history.push('/receipts');
|
||||
}
|
||||
if (submitPayload.resetForm) {
|
||||
resetForm();
|
||||
resetFormState();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -165,7 +167,11 @@ function ReceiptForm({
|
||||
<ReceiptFormFooter />
|
||||
<ReceiptFormFloatingActions />
|
||||
|
||||
{/*---------- Dialogs ---------*/}
|
||||
<ReceiptFormDialogs />
|
||||
|
||||
{/*---------- Effects ---------*/}
|
||||
<ReceiptSyncIncrementSettingsToForm />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
|
||||
@@ -10,9 +10,15 @@ export default function ReceiptFormDialogs() {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
// Update the form once the receipt number form submit confirm.
|
||||
const handleReceiptNumberFormConfirm = ({ incrementNumber, manually }) => {
|
||||
setFieldValue('receipt_number', incrementNumber || '');
|
||||
setFieldValue('receipt_number_manually', manually);
|
||||
const handleReceiptNumberFormConfirm = (settings) => {
|
||||
// Set the receipt transaction no. that cames from dialog to the form.
|
||||
// the `receipt_no_manually` will be empty except the increment mode is not auto.
|
||||
setFieldValue('receipt_number', settings.transactionNumber);
|
||||
setFieldValue('receipt_number_manually', '');
|
||||
|
||||
if (settings.incrementMode !== 'auto') {
|
||||
setFieldValue('receipt_number_manually', settings.transactionNumber);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -17,6 +17,21 @@ function ReceiptFormHeader({
|
||||
// #ownProps
|
||||
onReceiptNumberChanged,
|
||||
}) {
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<ReceiptFormHeaderFields
|
||||
onReceiptNumberChanged={onReceiptNumberChanged}
|
||||
/>
|
||||
<ReceiptFormHeaderBigTotal />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The big total amount of receipt form.
|
||||
* @returns {React.ReactNode}
|
||||
*/
|
||||
function ReceiptFormHeaderBigTotal() {
|
||||
const {
|
||||
values: { currency_code, entries },
|
||||
} = useFormikContext();
|
||||
@@ -25,16 +40,11 @@ function ReceiptFormHeader({
|
||||
const totalDueAmount = useMemo(() => getEntriesTotal(entries), [entries]);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER)}>
|
||||
<ReceiptFormHeaderFields
|
||||
onReceiptNumberChanged={onReceiptNumberChanged}
|
||||
/>
|
||||
<PageFormBigNumber
|
||||
label={intl.get('due_amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
</div>
|
||||
<PageFormBigNumber
|
||||
label={intl.get('due_amount')}
|
||||
amount={totalDueAmount}
|
||||
currencyCode={currency_code}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,12 @@ import {
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { ACCOUNT_TYPE } from '@/constants/accountTypes';
|
||||
import { Features } from '@/constants';
|
||||
import {
|
||||
FFormGroup,
|
||||
AccountsSelect,
|
||||
@@ -23,64 +26,112 @@ import {
|
||||
CustomerDrawerLink,
|
||||
FormattedMessage as T,
|
||||
FeatureCan,
|
||||
FInputGroup,
|
||||
} from '@/components';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { ACCOUNT_TYPE } from '@/constants/accountTypes';
|
||||
import { ProjectsSelect } from '@/containers/Projects/components';
|
||||
import {
|
||||
momentFormatter,
|
||||
compose,
|
||||
tansformDateValue,
|
||||
handleDateChange,
|
||||
inputIntent,
|
||||
} from '@/utils';
|
||||
import { useReceiptFormContext } from './ReceiptFormProvider';
|
||||
import {
|
||||
accountsFieldShouldUpdate,
|
||||
customersFieldShouldUpdate,
|
||||
useObserveReceiptNoSettings,
|
||||
} from './utils';
|
||||
import { accountsFieldShouldUpdate, customersFieldShouldUpdate } from './utils';
|
||||
import {
|
||||
ReceiptExchangeRateInputField,
|
||||
ReceiptProjectSelectButton,
|
||||
} from './components';
|
||||
import { Features } from '@/constants';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
|
||||
/**
|
||||
* Receipt number field of receipt form.
|
||||
*/
|
||||
const ReceiptFormReceiptNumberField = R.compose(
|
||||
withDialogActions,
|
||||
withSettings(({ receiptSettings }) => ({
|
||||
receiptAutoIncrement: receiptSettings?.autoIncrement,
|
||||
})),
|
||||
)(
|
||||
({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
receiptAutoIncrement,
|
||||
}) => {
|
||||
const { values, setFieldValue } = useFormikContext();
|
||||
|
||||
const handleReceiptNumberChange = () => {
|
||||
openDialog('receipt-number-form', {});
|
||||
};
|
||||
|
||||
const handleReceiptNoBlur = (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
// Show the confirmation dialog if the value has changed and auto-increment
|
||||
// mode is enabled.
|
||||
if (values.receipt_number !== newValue && receiptAutoIncrement) {
|
||||
openDialog('receipt-number-form', {
|
||||
initialFormValues: {
|
||||
onceManualNumber: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
// Setting the receipt number to the form will be manually in case
|
||||
// auto-increment is disable.
|
||||
if (!receiptAutoIncrement) {
|
||||
setFieldValue('receipt_number', newValue);
|
||||
setFieldValue('receipt_number_manually', newValue);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FFormGroup
|
||||
name={'receipt_number'}
|
||||
label={<T id={'receipt'} />}
|
||||
inline={true}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<FInputGroup
|
||||
name={'receipt_number'}
|
||||
minimal={true}
|
||||
value={values.receipt_number}
|
||||
asyncControl={true}
|
||||
onBlur={handleReceiptNoBlur}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleReceiptNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T id={'setting_your_auto_generated_payment_receive_number'} />
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
inputProps={{
|
||||
leftIcon: <Icon icon={'date-range'} />,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FFormGroup>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* Receipt form header fields.
|
||||
*/
|
||||
function ReceiptFormHeader({
|
||||
//#withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withSettings
|
||||
receiptAutoIncrement,
|
||||
receiptNextNumber,
|
||||
receiptNumberPrefix,
|
||||
}) {
|
||||
export default function ReceiptFormHeader() {
|
||||
const { accounts, customers, projects } = useReceiptFormContext();
|
||||
|
||||
const handleReceiptNumberChange = useCallback(() => {
|
||||
openDialog('receipt-number-form', {});
|
||||
}, [openDialog]);
|
||||
|
||||
const handleReceiptNoBlur = (form, field) => (event) => {
|
||||
const newValue = event.target.value;
|
||||
|
||||
if (field.value !== newValue && receiptAutoIncrement) {
|
||||
openDialog('receipt-number-form', {
|
||||
initialFormValues: {
|
||||
manualTransactionNo: newValue,
|
||||
incrementMode: 'manual-transaction',
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Synsc receipt number settings with the form.
|
||||
useObserveReceiptNoSettings(receiptNumberPrefix, receiptNextNumber);
|
||||
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||
{/* ----------- Customer name ----------- */}
|
||||
@@ -176,45 +227,7 @@ function ReceiptFormHeader({
|
||||
</FastField>
|
||||
|
||||
{/* ----------- Receipt number ----------- */}
|
||||
<FastField name={'receipt_number'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'receipt'} />}
|
||||
inline={true}
|
||||
className={('form-group--receipt_number', CLASSES.FILL)}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="receipt_number" />}
|
||||
>
|
||||
<ControlGroup fill={true}>
|
||||
<InputGroup
|
||||
minimal={true}
|
||||
value={field.value}
|
||||
asyncControl={true}
|
||||
onBlur={handleReceiptNoBlur(form, field)}
|
||||
/>
|
||||
<InputPrependButton
|
||||
buttonProps={{
|
||||
onClick: handleReceiptNumberChange,
|
||||
icon: <Icon icon={'settings-18'} />,
|
||||
}}
|
||||
tooltip={true}
|
||||
tooltipProps={{
|
||||
content: (
|
||||
<T
|
||||
id={'setting_your_auto_generated_payment_receive_number'}
|
||||
/>
|
||||
),
|
||||
position: Position.BOTTOM_LEFT,
|
||||
}}
|
||||
inputProps={{
|
||||
leftIcon: <Icon icon={'date-range'} />,
|
||||
}}
|
||||
/>
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<ReceiptFormReceiptNumberField />
|
||||
|
||||
{/* ----------- Reference ----------- */}
|
||||
<FastField name={'reference_no'}>
|
||||
@@ -251,15 +264,6 @@ function ReceiptFormHeader({
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withSettings(({ receiptSettings }) => ({
|
||||
receiptAutoIncrement: receiptSettings?.autoIncrement,
|
||||
receiptNextNumber: receiptSettings?.nextNumber,
|
||||
receiptNumberPrefix: receiptSettings?.numberPrefix,
|
||||
})),
|
||||
)(ReceiptFormHeader);
|
||||
|
||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||
font-size: 11px;
|
||||
margin-top: 6px;
|
||||
|
||||
@@ -3,9 +3,14 @@ import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import { useFormikContext } from 'formik';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import { ExchangeRateInputGroup } from '@/components';
|
||||
import { useCurrentOrganization } from '@/hooks/state';
|
||||
import { useReceiptIsForeignCustomer } from './utils';
|
||||
import { useUpdateEffect } from '@/hooks';
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import { transactionNumber } from '@/utils';
|
||||
|
||||
/**
|
||||
* Receipt exchange rate input field.
|
||||
@@ -37,3 +42,34 @@ export function ReceiptExchangeRateInputField({ ...props }) {
|
||||
export function ReceiptProjectSelectButton({ label }) {
|
||||
return <Button text={label ?? intl.get('select_project')} />;
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs receipt auto-increment settings to form.
|
||||
* @return {React.ReactNode}
|
||||
*/
|
||||
export const ReceiptSyncIncrementSettingsToForm = R.compose(
|
||||
withSettings(({ receiptSettings }) => ({
|
||||
receiptAutoIncrement: receiptSettings?.autoIncrement,
|
||||
receiptNextNumber: receiptSettings?.nextNumber,
|
||||
receiptNumberPrefix: receiptSettings?.numberPrefix,
|
||||
})),
|
||||
)(({ receiptAutoIncrement, receiptNextNumber, receiptNumberPrefix }) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
useUpdateEffect(() => {
|
||||
// Do not update if the receipt auto-increment mode is disabled.
|
||||
if (!receiptAutoIncrement) return;
|
||||
|
||||
setFieldValue(
|
||||
'receipt_number',
|
||||
transactionNumber(receiptNumberPrefix, receiptNextNumber),
|
||||
);
|
||||
}, [
|
||||
setFieldValue,
|
||||
receiptNumberPrefix,
|
||||
receiptAutoIncrement,
|
||||
receiptNextNumber,
|
||||
]);
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -36,6 +36,8 @@ export const defaultReceipt = {
|
||||
customer_id: '',
|
||||
deposit_account_id: '',
|
||||
receipt_number: '',
|
||||
// Holds the receipt number that entered manually only.
|
||||
receipt_number_manually: '',
|
||||
receipt_date: moment(new Date()).format('YYYY-MM-DD'),
|
||||
reference_no: '',
|
||||
receipt_message: '',
|
||||
@@ -77,15 +79,6 @@ export const transformToEditForm = (receipt) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const useObserveReceiptNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
|
||||
React.useEffect(() => {
|
||||
const receiptNo = transactionNumber(prefix, nextNumber);
|
||||
setFieldValue('receipt_number', receiptNo);
|
||||
}, [setFieldValue, prefix, nextNumber]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detarmines entries fast field should update.
|
||||
*/
|
||||
@@ -248,3 +241,14 @@ export const useReceiptIsForeignCustomer = () => {
|
||||
);
|
||||
return isForeignCustomer;
|
||||
};
|
||||
|
||||
export const resetFormState = ({ initialValues, values, resetForm }) => {
|
||||
resetForm({
|
||||
values: {
|
||||
// Reset the all values except the warehouse and brand id.
|
||||
...initialValues,
|
||||
warehouse_id: values.warehouse_id,
|
||||
brand_id: values.brand_id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -21,6 +21,9 @@ const commonInvalidateQueries = (client) => {
|
||||
client.invalidateQueries(t.ACCOUNTS);
|
||||
client.invalidateQueries(t.ACCOUNT);
|
||||
|
||||
// Invalidate settings.
|
||||
client.invalidateQueries([t.SETTING, t.SETTING_MANUAL_JOURNALS]);
|
||||
|
||||
// Invalidate financial reports.
|
||||
client.invalidateQueries(t.FINANCIAL_REPORT);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useRequestQuery } from '../useQueryRequest';
|
||||
import useApiRequest from '../useRequest';
|
||||
import { useSetSettings } from '@/hooks/state';
|
||||
import t from './types';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
/**
|
||||
* Saves the settings.
|
||||
@@ -23,18 +24,23 @@ export function useSaveSettings(props) {
|
||||
function useSettingsQuery(key, query, props) {
|
||||
const setSettings = useSetSettings();
|
||||
|
||||
return useRequestQuery(
|
||||
const settingsQuery = useRequestQuery(
|
||||
key,
|
||||
{ method: 'get', url: 'settings', params: query },
|
||||
{
|
||||
select: (res) => res.data.settings,
|
||||
defaultData: [],
|
||||
onSuccess: (settings) => {
|
||||
setSettings(settings);
|
||||
},
|
||||
...props,
|
||||
},
|
||||
);
|
||||
useEffect(() => {
|
||||
// Sync to Redux state if the reqeust success and is not fetching.
|
||||
if (!settingsQuery.isFetching && settingsQuery.isSuccess) {
|
||||
setSettings(settingsQuery.data);
|
||||
}
|
||||
}, [settingsQuery.isFetching, settingsQuery.isSuccess, settingsQuery.data]);
|
||||
|
||||
return settingsQuery;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1376,7 +1376,7 @@
|
||||
"receipt.auto_increment.manually": "Your receipt numbers are set on manual mode. Are you sure chaning this settings?",
|
||||
"payment_receive.auto_increment.auto": "Your payment numbers are set on auto-increment mode. Are you sure changing this setting?",
|
||||
"payment_receive.auto_increment.manually": "Your payment numbers are set on manual mode. Are you sure chaning this settings?",
|
||||
"auto_increment.field.manually": "I will enter them manually each time",
|
||||
"auto_increment.field.manually": "I will enter them manually each time.",
|
||||
"auto_increment.field.manual_this_transaction": "Manual entering for this transaction.",
|
||||
"auto_increment.field.auto": "Auto-incrementing number.",
|
||||
"date_formats": {
|
||||
|
||||
Reference in New Issue
Block a user