mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
Merge branch 'develop' into fix-spelling-a-char
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
FeatureCan,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { useMakeJournalFormContext } from './MakeJournalProvider';
|
||||
|
||||
@@ -51,18 +52,9 @@ function MakeJournalFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={MakeJournalBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
function MakeJournalBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('make_journal.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
|
||||
import OwnerContributionFormFields from './OwnerContribution/OwnerContributionFormFields';
|
||||
import OtherIncomeFormFields from './OtherIncome/OtherIncomeFormFields';
|
||||
import TransferFromAccountFormFields from './TransferFromAccount/TransferFromAccountFormFields';
|
||||
import { MoneyInFieldsProvider } from './MoneyInFieldsProvider';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param param0
|
||||
* @returns
|
||||
* Money-in dialog content.
|
||||
* Switches between fields based on the given transaction type.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export default function MoneyInContentFields({ accountType }) {
|
||||
const handleTransactionType = () => {
|
||||
switch (accountType) {
|
||||
export default function MoneyInContentFields() {
|
||||
const { values } = useFormikContext();
|
||||
|
||||
const transactionFields = useMemo(() => {
|
||||
switch (values.transaction_type) {
|
||||
case 'owner_contribution':
|
||||
return <OwnerContributionFormFields />;
|
||||
|
||||
@@ -24,6 +28,10 @@ export default function MoneyInContentFields({ accountType }) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
return <React.Fragment>{handleTransactionType()}</React.Fragment>;
|
||||
}, [values.transaction_type]);
|
||||
|
||||
// Cannot continue if transaction type or account is not selected.
|
||||
if (!values.transaction_type || !values.cashflow_account_id) return null;
|
||||
|
||||
return <MoneyInFieldsProvider>{transactionFields}</MoneyInFieldsProvider>;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import { MoneyInDialogProvider } from './MoneyInDialogProvider';
|
||||
import MoneyInForm from './MoneyInForm';
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { DialogContent } from '@/components';
|
||||
import { Features } from '@/constants';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
useCreateCashflowTransaction,
|
||||
useAccount,
|
||||
useAccounts,
|
||||
useBranches,
|
||||
useCashflowAccounts,
|
||||
@@ -18,22 +17,21 @@ const MoneyInDialogContent = React.createContext();
|
||||
* Money in dialog provider.
|
||||
*/
|
||||
function MoneyInDialogProvider({
|
||||
accountId,
|
||||
accountId: defaultAccountId,
|
||||
accountType,
|
||||
dialogName,
|
||||
...props
|
||||
}) {
|
||||
// Holds the selected account id of the dialog.
|
||||
const [accountId, setAccountId] = useState<number | null>(defaultAccountId);
|
||||
|
||||
// Detarmines whether the feature is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
const isBranchFeatureCan = featureCan(Features.Branches);
|
||||
|
||||
// Fetches accounts list.
|
||||
const { isLoading: isAccountsLoading, data: accounts } = useAccounts();
|
||||
|
||||
// Fetches the specific account details.
|
||||
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, {
|
||||
enabled: !!accountId,
|
||||
});
|
||||
|
||||
// Fetches the branches list.
|
||||
const {
|
||||
data: branches,
|
||||
@@ -41,10 +39,11 @@ function MoneyInDialogProvider({
|
||||
isSuccess: isBranchesSuccess,
|
||||
} = useBranches({}, { enabled: isBranchFeatureCan });
|
||||
|
||||
// Fetch cash flow list .
|
||||
// Fetch cash flow list.
|
||||
const { data: cashflowAccounts, isLoading: isCashFlowAccountsLoading } =
|
||||
useCashflowAccounts({}, { keepPreviousData: true });
|
||||
|
||||
// Mutation create cashflow transaction.
|
||||
const { mutateAsync: createCashflowTransactionMutate } =
|
||||
useCreateCashflowTransaction();
|
||||
|
||||
@@ -57,9 +56,12 @@ function MoneyInDialogProvider({
|
||||
// Provider data.
|
||||
const provider = {
|
||||
accounts,
|
||||
account,
|
||||
branches,
|
||||
|
||||
accountId,
|
||||
defaultAccountId,
|
||||
setAccountId,
|
||||
|
||||
accountType,
|
||||
isAccountsLoading,
|
||||
isBranchesSuccess,
|
||||
@@ -77,8 +79,7 @@ function MoneyInDialogProvider({
|
||||
isAccountsLoading ||
|
||||
isCashFlowAccountsLoading ||
|
||||
isBranchesLoading ||
|
||||
isSettingsLoading ||
|
||||
isAccountLoading;
|
||||
isSettingsLoading;
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isLoading}>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { ExchangeRateMutedField } from '@/components';
|
||||
import { useForeignAccount } from './utils';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { useMoneyInFieldsContext } from './MoneyInFieldsProvider';
|
||||
|
||||
export function MoneyInExchangeRateField() {
|
||||
const { account } = useMoneyInFieldsContext();
|
||||
const { values } = useFormikContext();
|
||||
|
||||
const isForeigAccount = useForeignAccount();
|
||||
|
||||
if (!isForeigAccount) return null;
|
||||
|
||||
return (
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values.currency_code}
|
||||
toCurrency={account.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { DialogContent } from '@/components';
|
||||
import { useAccount } from '@/hooks/query';
|
||||
import { useMoneyInDailogContext } from './MoneyInDialogProvider';
|
||||
|
||||
const MoneyInFieldsContext = React.createContext();
|
||||
|
||||
/**
|
||||
* Money in dialog provider.
|
||||
*/
|
||||
function MoneyInFieldsProvider({ ...props }) {
|
||||
const { accountId } = useMoneyInDailogContext();
|
||||
|
||||
// Fetches the specific account details.
|
||||
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, {
|
||||
enabled: !!accountId,
|
||||
});
|
||||
// Provider data.
|
||||
const provider = {
|
||||
account,
|
||||
};
|
||||
const isLoading = isAccountLoading;
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isLoading}>
|
||||
<MoneyInFieldsContext.Provider value={provider} {...props} />
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
||||
|
||||
const useMoneyInFieldsContext = () => React.useContext(MoneyInFieldsContext);
|
||||
|
||||
export { MoneyInFieldsProvider, useMoneyInFieldsContext };
|
||||
@@ -53,7 +53,6 @@ function MoneyInForm({
|
||||
accountId,
|
||||
accountType,
|
||||
createCashflowTransactionMutate,
|
||||
submitPayload,
|
||||
} = useMoneyInDailogContext();
|
||||
|
||||
// transaction number.
|
||||
@@ -61,7 +60,6 @@ function MoneyInForm({
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
|
||||
// Initial form values.
|
||||
const initialValues = {
|
||||
...defaultInitialValues,
|
||||
@@ -95,15 +93,13 @@ function MoneyInForm({
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Formik
|
||||
validationSchema={CreateMoneyInFormSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<MoneyInFormContent />
|
||||
</Formik>
|
||||
</div>
|
||||
<Formik
|
||||
validationSchema={CreateMoneyInFormSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<MoneyInFormContent />
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,17 +12,13 @@ import { useMoneyInDailogContext } from './MoneyInDialogProvider';
|
||||
* Money in form fields.
|
||||
*/
|
||||
function MoneyInFormFields() {
|
||||
const { values } = useFormikContext();
|
||||
|
||||
// Money in dialog context.
|
||||
const { accountId } = useMoneyInDailogContext();
|
||||
const { defaultAccountId } = useMoneyInDailogContext();
|
||||
|
||||
return (
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<If condition={!accountId}>
|
||||
<TransactionTypeFields />
|
||||
</If>
|
||||
<MoneyInContentFields accountType={values.transaction_type} />
|
||||
{!defaultAccountId && <TransactionTypeFields />}
|
||||
<MoneyInContentFields />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field, ErrorMessage, useFormikContext } from 'formik';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import {
|
||||
Classes,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
TextArea,
|
||||
Position,
|
||||
ControlGroup,
|
||||
@@ -18,14 +17,15 @@ import {
|
||||
FieldRequiredHint,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
ExchangeRateMutedField,
|
||||
FInputGroup,
|
||||
FFormGroup,
|
||||
FTextArea,
|
||||
FMoneyInputGroup,
|
||||
} from '@/components';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { useAutofocus } from '@/hooks';
|
||||
import { CLASSES, ACCOUNT_TYPE, Features } from '@/constants';
|
||||
|
||||
import {
|
||||
@@ -36,22 +36,18 @@ import {
|
||||
} from '@/utils';
|
||||
|
||||
import { useMoneyInDailogContext } from '../MoneyInDialogProvider';
|
||||
import {
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../utils';
|
||||
import { useSetPrimaryBranchToForm, BranchRowDivider } from '../utils';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
import { useMoneyInFieldsContext } from '../MoneyInFieldsProvider';
|
||||
import { MoneyInExchangeRateField } from '../MoneyInExchangeRateField';
|
||||
|
||||
/**
|
||||
* Other income form fields.
|
||||
*/
|
||||
export default function OtherIncomeFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyInDailogContext();
|
||||
const { values } = useFormikContext();
|
||||
const amountFieldRef = useAutofocus();
|
||||
const isForeigAccount = useForeignAccount();
|
||||
const { accounts, branches } = useMoneyInDailogContext();
|
||||
const { account } = useMoneyInFieldsContext();
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
@@ -61,17 +57,14 @@ export default function OtherIncomeFormFields() {
|
||||
<FeatureCan feature={Features.Branches}>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<FormGroup
|
||||
label={<T id={'branch'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<FFormGroup name={'amount'} label={<T id={'branch'} />}>
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<BranchRowDivider />
|
||||
@@ -106,53 +99,32 @@ export default function OtherIncomeFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
<FastField name={'amount'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
|
||||
{/*------------ Amount -----------*/}
|
||||
<Row>
|
||||
<Col xs={10}>
|
||||
<FFormGroup
|
||||
name={'amount'}
|
||||
label={<T id={'amount'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="amount" />}
|
||||
className={'form-group--amount'}
|
||||
>
|
||||
<ControlGroup>
|
||||
<InputPrependText text={account.currency_code} />
|
||||
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
minimal={true}
|
||||
onChange={(amount) => {
|
||||
setFieldValue('amount', amount);
|
||||
}}
|
||||
inputRef={(ref) => (amountFieldRef.current = ref)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
/>
|
||||
<FMoneyInputGroup name={'amount'} minimal={true} />
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ Exchange rate -----------*/}
|
||||
<MoneyInExchangeRateField />
|
||||
|
||||
<If condition={isForeigAccount}>
|
||||
{/*------------ exchange rate -----------*/}
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values.currency_code}
|
||||
toCurrency={account.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
</If>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ other income account -----------*/}
|
||||
@@ -182,43 +154,24 @@ export default function OtherIncomeFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
className={'form-group--reference-no'}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup label={<T id={'reference_no'} />} name={'reference_no'}>
|
||||
<FInputGroup name={'reference_no'} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
{/*------------ Description -----------*/}
|
||||
<FFormGroup name={'description'} label={<T id={'description'} />}>
|
||||
<FTextArea
|
||||
name={'description'}
|
||||
growVertically={true}
|
||||
large={true}
|
||||
fill={true}
|
||||
/>
|
||||
</FFormGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,32 +1,24 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field, ErrorMessage, useFormikContext } from 'formik';
|
||||
import {
|
||||
Classes,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
TextArea,
|
||||
Position,
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { FormGroup, Position, ControlGroup } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
AccountsSuggestField,
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
ExchangeRateMutedField,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
FeatureCan,
|
||||
FFormGroup,
|
||||
FMoneyInputGroup,
|
||||
FTextArea,
|
||||
FInputGroup,
|
||||
} from '@/components';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { useAutofocus } from '@/hooks';
|
||||
import { ACCOUNT_TYPE, CLASSES, Features } from '@/constants';
|
||||
import {
|
||||
inputIntent,
|
||||
@@ -37,10 +29,11 @@ import {
|
||||
import { useMoneyInDailogContext } from '../MoneyInDialogProvider';
|
||||
import {
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../../MoneyInDialog/utils';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
import { useMoneyInFieldsContext } from '../MoneyInFieldsProvider';
|
||||
import { MoneyInExchangeRateField } from '../MoneyInExchangeRateField';
|
||||
|
||||
/**
|
||||
/**
|
||||
@@ -48,13 +41,8 @@ import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
*/
|
||||
export default function OwnerContributionFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyInDailogContext();
|
||||
|
||||
const { values } = useFormikContext();
|
||||
|
||||
const amountFieldRef = useAutofocus();
|
||||
|
||||
const isForeigAccount = useForeignAccount();
|
||||
const { accounts, branches } = useMoneyInDailogContext();
|
||||
const { account } = useMoneyInFieldsContext();
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
@@ -64,21 +52,19 @@ export default function OwnerContributionFormFields() {
|
||||
<FeatureCan feature={Features.Branches}>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<FormGroup
|
||||
label={<T id={'branch'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<FFormGroup name={'branch_id'} label={<T id={'branch'} />}>
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<BranchRowDivider />
|
||||
</FeatureCan>
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ Date -----------*/}
|
||||
@@ -113,47 +99,26 @@ export default function OwnerContributionFormFields() {
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
<Field name={'amount'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
|
||||
{/*------------ Amount -----------*/}
|
||||
<Row>
|
||||
<Col xs={10}>
|
||||
<FFormGroup
|
||||
name={'amount'}
|
||||
label={<T id={'amount'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="amount" />}
|
||||
className={'form-group--amount'}
|
||||
>
|
||||
<ControlGroup>
|
||||
<InputPrependText text={account?.currency_code} />
|
||||
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
minimal={true}
|
||||
onChange={(amount) => {
|
||||
setFieldValue('amount', amount);
|
||||
}}
|
||||
inputRef={(ref) => (amountFieldRef.current = ref)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
/>
|
||||
<InputPrependText text={account?.currency_code || '--'} />
|
||||
<FMoneyInputGroup name={'amount'} minimal={true} />
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<If condition={isForeigAccount}>
|
||||
{/*------------ exchange rate -----------*/}
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values.currency_code}
|
||||
toCurrency={account.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
</If>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ Exchange rate -----------*/}
|
||||
<MoneyInExchangeRateField />
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ equity account -----------*/}
|
||||
@@ -181,43 +146,24 @@ export default function OwnerContributionFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
className={'form-group--reference-no'}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup name={'reference_no'} label={<T id={'reference_no'} />}>
|
||||
<FInputGroup name={'reference_no'} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
{/*------------ Description -----------*/}
|
||||
<FFormGroup name={'description'} label={<T id={'description'} />}>
|
||||
<FTextArea
|
||||
name={'description'}
|
||||
growVertically={true}
|
||||
large={true}
|
||||
fill={true}
|
||||
/>
|
||||
</FFormGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
ListSelect,
|
||||
Col,
|
||||
Row,
|
||||
FFormGroup,
|
||||
FSelect,
|
||||
} from '@/components';
|
||||
import { inputIntent } from '@/utils';
|
||||
import { CLASSES, getAddMoneyInOptions } from '@/constants';
|
||||
@@ -21,7 +23,7 @@ import { useMoneyInDailogContext } from './MoneyInDialogProvider';
|
||||
*/
|
||||
export default function TransactionTypeFields() {
|
||||
// Money in dialog context.
|
||||
const { cashflowAccounts } = useMoneyInDailogContext();
|
||||
const { cashflowAccounts, setAccountId } = useMoneyInDailogContext();
|
||||
|
||||
// Retrieves the add money in button options.
|
||||
const addMoneyInOptions = useMemo(() => getAddMoneyInOptions(), []);
|
||||
@@ -29,6 +31,23 @@ export default function TransactionTypeFields() {
|
||||
return (
|
||||
<div className="trasnaction-type-fileds">
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction type -----------*/}
|
||||
<FFormGroup
|
||||
name={'transaction_type'}
|
||||
label={<T id={'transaction_type'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
>
|
||||
<FSelect
|
||||
name={'transaction_type'}
|
||||
items={addMoneyInOptions}
|
||||
popoverProps={{ minimal: true }}
|
||||
valueAccessor={'value'}
|
||||
textAccessor={'name'}
|
||||
/>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Current account -----------*/}
|
||||
<FastField name={'cashflow_account_id'}>
|
||||
@@ -46,9 +65,10 @@ export default function TransactionTypeFields() {
|
||||
>
|
||||
<AccountsSuggestField
|
||||
accounts={cashflowAccounts}
|
||||
onAccountSelected={({ id }) =>
|
||||
form.setFieldValue('cashflow_account_id', id)
|
||||
}
|
||||
onAccountSelected={({ id }) => {
|
||||
form.setFieldValue('cashflow_account_id', id);
|
||||
setAccountId(id);
|
||||
}}
|
||||
inputProps={{
|
||||
intent: inputIntent({ error, touched }),
|
||||
}}
|
||||
@@ -56,39 +76,6 @@ export default function TransactionTypeFields() {
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ Transaction type -----------*/}
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
<Field name={'transaction_type'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_type'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
helperText={<ErrorMessage name="transaction_type" />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
className={classNames(
|
||||
CLASSES.FILL,
|
||||
'form-group--transaction_type',
|
||||
)}
|
||||
>
|
||||
<ListSelect
|
||||
items={addMoneyInOptions}
|
||||
onItemSelect={(type) => {
|
||||
setFieldValue('transaction_type', type.value);
|
||||
}}
|
||||
filterable={false}
|
||||
selectedItem={value}
|
||||
selectedItemProp={'value'}
|
||||
textProp={'name'}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,33 +1,27 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field, ErrorMessage, useFormikContext } from 'formik';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import {
|
||||
Classes,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
TextArea,
|
||||
Position,
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { FormGroup, Position, ControlGroup } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
AccountsSuggestField,
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
ExchangeRateMutedField,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
FMoneyInputGroup,
|
||||
FInputGroup,
|
||||
FFormGroup,
|
||||
FTextArea,
|
||||
} from '@/components';
|
||||
import { useAutofocus } from '@/hooks';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
import { MoneyInExchangeRateField } from '../MoneyInExchangeRateField';
|
||||
import { CLASSES, ACCOUNT_TYPE, Features } from '@/constants';
|
||||
|
||||
import {
|
||||
inputIntent,
|
||||
momentFormatter,
|
||||
@@ -35,25 +29,19 @@ import {
|
||||
handleDateChange,
|
||||
} from '@/utils';
|
||||
import { useMoneyInDailogContext } from '../MoneyInDialogProvider';
|
||||
import { useMoneyInFieldsContext } from '../MoneyInFieldsProvider';
|
||||
import {
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../../MoneyInDialog/utils';
|
||||
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
|
||||
/**
|
||||
* Transfer from account form fields.
|
||||
*/
|
||||
export default function TransferFromAccountFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyInDailogContext();
|
||||
|
||||
const isForeigAccount = useForeignAccount();
|
||||
const amountFieldRef = useAutofocus();
|
||||
|
||||
const { values } = useFormikContext();
|
||||
const { accounts, branches } = useMoneyInDailogContext();
|
||||
const { account } = useMoneyInFieldsContext();
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
@@ -63,17 +51,14 @@ export default function TransferFromAccountFormFields() {
|
||||
<FeatureCan feature={Features.Branches}>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<FormGroup
|
||||
label={<T id={'branch'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<FFormGroup label={<T id={'branch'} />} name={'branch_id'}>
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<BranchRowDivider />
|
||||
@@ -112,50 +97,27 @@ export default function TransferFromAccountFormFields() {
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
<FastField name={'amount'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
{/*------------ Amount -----------*/}
|
||||
<Row>
|
||||
<Col xs={10}>
|
||||
<FormGroup
|
||||
label={<T id={'amount'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="amount" />}
|
||||
className={'form-group--amount'}
|
||||
>
|
||||
<ControlGroup>
|
||||
<InputPrependText text={account.currency_code} />
|
||||
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
minimal={true}
|
||||
onChange={(amount) => {
|
||||
setFieldValue('amount', amount);
|
||||
}}
|
||||
inputRef={(ref) => (amountFieldRef.current = ref)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
/>
|
||||
<InputPrependText text={account.currency_code || '--'} />
|
||||
<FMoneyInputGroup name={'amount'} minimal={true} />
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<If condition={isForeigAccount}>
|
||||
{/*------------ exchange rate -----------*/}
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values.currency_code}
|
||||
toCurrency={account.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
</If>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ Exchange rate -----------*/}
|
||||
<MoneyInExchangeRateField />
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ transfer from account -----------*/}
|
||||
{/*------------ Transfer from account -----------*/}
|
||||
<FastField name={'credit_account_id'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
@@ -185,43 +147,24 @@ export default function TransferFromAccountFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
className={'form-group--reference-no'}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup name={'reference_no'} label={<T id={'reference_no'} />}>
|
||||
<FInputGroup name={'reference_no'} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
{/*------------ Description -----------*/}
|
||||
<FormGroup name={'description'} label={<T id={'description'} />}>
|
||||
<FTextArea
|
||||
name={'description'}
|
||||
growVertically={true}
|
||||
large={true}
|
||||
fill={true}
|
||||
/>
|
||||
</FormGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Dialog, DialogSuspense } from '@/components';
|
||||
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||
|
||||
import { compose } from '@/utils';
|
||||
|
||||
const MoneyInDialogContent = React.lazy(() => import('./MoneyInDialogContent'));
|
||||
|
||||
@@ -6,6 +6,7 @@ import { transactionNumber } from '@/utils';
|
||||
import { isEqual, isNull, first } from 'lodash';
|
||||
|
||||
import { useMoneyInDailogContext } from './MoneyInDialogProvider';
|
||||
import { useMoneyInFieldsContext } from './MoneyInFieldsProvider';
|
||||
|
||||
export const useObserveTransactionNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
@@ -33,7 +34,7 @@ export const useSetPrimaryBranchToForm = () => {
|
||||
|
||||
export const useForeignAccount = () => {
|
||||
const { values } = useFormikContext();
|
||||
const { account } = useMoneyInDailogContext();
|
||||
const { account } = useMoneyInFieldsContext();
|
||||
|
||||
return (
|
||||
!isEqual(account.currency_code, values.currency_code) &&
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
|
||||
import OtherExpnseFormFields from './OtherExpense/OtherExpnseFormFields';
|
||||
import OwnerDrawingsFormFields from './OwnerDrawings/OwnerDrawingsFormFields';
|
||||
import TransferToAccountFormFields from './TransferToAccount/TransferToAccountFormFields';
|
||||
import { MoneyOutFieldsProvider } from './MoneyOutFieldsProvider';
|
||||
|
||||
function MoneyOutContentFields({ accountType }) {
|
||||
const handleTransactionType = () => {
|
||||
switch (accountType) {
|
||||
/**
|
||||
* Money out content fields.
|
||||
* Switches between form fields based on the given transaction type.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
function MoneyOutContentFields() {
|
||||
const { values } = useFormikContext();
|
||||
|
||||
const transactionType = useMemo(() => {
|
||||
switch (values.transaction_type) {
|
||||
case 'OwnerDrawing':
|
||||
return <OwnerDrawingsFormFields />;
|
||||
|
||||
@@ -19,8 +28,12 @@ function MoneyOutContentFields({ accountType }) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
return <React.Fragment>{handleTransactionType()}</React.Fragment>;
|
||||
}, [values.transaction_type]);
|
||||
|
||||
// Cannot continue if transaction type or account is not selected.
|
||||
if (!values.transaction_type || !values.cashflow_account_id) return null;
|
||||
|
||||
return <MoneyOutFieldsProvider>{transactionType}</MoneyOutFieldsProvider>;
|
||||
}
|
||||
|
||||
export default MoneyOutContentFields;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { DialogContent } from '@/components';
|
||||
import { Features } from '@/constants';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
useAccounts,
|
||||
useAccount,
|
||||
useBranches,
|
||||
useCreateCashflowTransaction,
|
||||
useCashflowAccounts,
|
||||
@@ -17,7 +16,15 @@ const MoneyInDialogContent = React.createContext();
|
||||
/**
|
||||
* Money out dialog provider.
|
||||
*/
|
||||
function MoneyOutProvider({ accountId, accountType, dialogName, ...props }) {
|
||||
function MoneyOutProvider({
|
||||
accountId: defaultAccountId,
|
||||
accountType,
|
||||
dialogName,
|
||||
...props
|
||||
}) {
|
||||
// Holds the selected account id of the dialog.
|
||||
const [accountId, setAccountId] = useState<number | null>(defaultAccountId);
|
||||
|
||||
// Features guard.
|
||||
const { featureCan } = useFeatureCan();
|
||||
const isBranchFeatureCan = featureCan(Features.Branches);
|
||||
@@ -25,11 +32,6 @@ function MoneyOutProvider({ accountId, accountType, dialogName, ...props }) {
|
||||
// Fetches accounts list.
|
||||
const { isLoading: isAccountsLoading, data: accounts } = useAccounts();
|
||||
|
||||
// Fetches the specific account details.
|
||||
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, {
|
||||
enabled: !!accountId,
|
||||
});
|
||||
|
||||
// Fetches the branches list.
|
||||
const {
|
||||
data: branches,
|
||||
@@ -41,6 +43,7 @@ function MoneyOutProvider({ accountId, accountType, dialogName, ...props }) {
|
||||
const { data: cashflowAccounts, isLoading: isCashFlowAccountsLoading } =
|
||||
useCashflowAccounts({}, { keepPreviousData: true });
|
||||
|
||||
// Mutation to create a new cashflow account.
|
||||
const { mutateAsync: createCashflowTransactionMutate } =
|
||||
useCreateCashflowTransaction();
|
||||
|
||||
@@ -52,9 +55,11 @@ function MoneyOutProvider({ accountId, accountType, dialogName, ...props }) {
|
||||
|
||||
// Provider data.
|
||||
const provider = {
|
||||
accounts,
|
||||
account,
|
||||
accountId,
|
||||
setAccountId,
|
||||
defaultAccountId,
|
||||
|
||||
accounts,
|
||||
accountType,
|
||||
branches,
|
||||
isAccountsLoading,
|
||||
@@ -73,8 +78,7 @@ function MoneyOutProvider({ accountId, accountType, dialogName, ...props }) {
|
||||
isAccountsLoading ||
|
||||
isCashFlowAccountsLoading ||
|
||||
isBranchesLoading ||
|
||||
isSettingsLoading ||
|
||||
isAccountLoading;
|
||||
isSettingsLoading;
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isLoading}>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { useForeignAccount } from './utils';
|
||||
import { ExchangeRateMutedField } from '@/components';
|
||||
import { useMoneyOutFieldsContext } from './MoneyOutFieldsProvider';
|
||||
|
||||
/**
|
||||
* Money-out exchange rate field.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function MoneyOutExchangeRateField() {
|
||||
const { values } = useFormikContext();
|
||||
|
||||
const { account } = useMoneyOutFieldsContext();
|
||||
const isForeigAccount = useForeignAccount();
|
||||
|
||||
// Cannot continue if the account is not foreign account.
|
||||
if (!isForeigAccount) return null;
|
||||
|
||||
return (
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values?.currency_code}
|
||||
toCurrency={account?.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { DialogContent } from '@/components';
|
||||
import { useAccount } from '@/hooks/query';
|
||||
import { useMoneyOutDialogContext } from './MoneyOutDialogProvider';
|
||||
|
||||
const MoneyOutFieldsContext = React.createContext();
|
||||
|
||||
/**
|
||||
* Money out fields dialog provider.
|
||||
*/
|
||||
function MoneyOutFieldsProvider({ ...props }) {
|
||||
const { accountId } = useMoneyOutDialogContext();
|
||||
|
||||
// Fetches the specific account details.
|
||||
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, {
|
||||
enabled: !!accountId,
|
||||
});
|
||||
// Provider data.
|
||||
const provider = {
|
||||
account,
|
||||
};
|
||||
const isLoading = isAccountLoading;
|
||||
|
||||
return (
|
||||
<DialogContent isLoading={isLoading}>
|
||||
<MoneyOutFieldsContext.Provider value={provider} {...props} />
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
||||
|
||||
const useMoneyOutFieldsContext = () => React.useContext(MoneyOutFieldsContext);
|
||||
|
||||
export { MoneyOutFieldsProvider, useMoneyOutFieldsContext };
|
||||
@@ -24,18 +24,16 @@ function MoneyOutFloatingActions({
|
||||
useMoneyOutDialogContext();
|
||||
|
||||
// handle submit as draft button click.
|
||||
const handleSubmitDraftBtnClick = (event) => {
|
||||
const handleSubmitDraftBtnClick = () => {
|
||||
setSubmitPayload({ publish: false });
|
||||
submitForm();
|
||||
};
|
||||
|
||||
// Handle submit button click.
|
||||
const handleSubmittBtnClick = (event) => {
|
||||
const handleSubmittBtnClick = () => {
|
||||
setSubmitPayload({ publish: true });
|
||||
};
|
||||
|
||||
// Handle close button click.
|
||||
const handleCloseBtnClick = (event) => {
|
||||
const handleCloseBtnClick = () => {
|
||||
closeDialog(dialogName);
|
||||
};
|
||||
|
||||
@@ -49,7 +47,7 @@ function MoneyOutFloatingActions({
|
||||
>
|
||||
<T id={'close'} />
|
||||
</Button>
|
||||
|
||||
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
disabled={isSubmitting}
|
||||
|
||||
@@ -92,15 +92,13 @@ function MoneyOutForm({
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<Formik
|
||||
validationSchema={CreateMoneyOutSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<MoneyOutFormContent />
|
||||
</Formik>
|
||||
</div>
|
||||
<Formik
|
||||
validationSchema={CreateMoneyOutSchema}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleFormSubmit}
|
||||
>
|
||||
<MoneyOutFormContent />
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ export default function MoneyOutFormDialog() {
|
||||
setFieldValue('transaction_number', incrementNumber || '');
|
||||
setFieldValue('transaction_number_manually', manually);
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<TransactionNumberDialog
|
||||
|
||||
@@ -1,28 +1,18 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
|
||||
import { If } from '@/components';
|
||||
|
||||
import MoneyOutContentFields from './MoneyOutContentFields';
|
||||
import TransactionTypeFields from './TransactionTypeFields';
|
||||
import { useMoneyOutDialogContext } from './MoneyOutDialogProvider';
|
||||
|
||||
/**
|
||||
* Money out form fields.
|
||||
*/
|
||||
function MoneyOutFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accountId } = useMoneyOutDialogContext();
|
||||
|
||||
const { values } = useFormikContext();
|
||||
return (
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<If condition={!accountId}>
|
||||
<TransactionTypeFields />
|
||||
</If>
|
||||
<MoneyOutContentFields accountType={values.transaction_type} />
|
||||
<TransactionTypeFields />
|
||||
<MoneyOutContentFields />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,33 +1,25 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field, ErrorMessage, useFormikContext } from 'formik';
|
||||
import {
|
||||
Classes,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
TextArea,
|
||||
Position,
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { FormGroup, Position, ControlGroup } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
AccountsSuggestField,
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
ExchangeRateMutedField,
|
||||
FTextArea,
|
||||
FFormGroup,
|
||||
FInputGroup,
|
||||
FMoneyInputGroup,
|
||||
} from '@/components';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { useAutofocus } from '@/hooks';
|
||||
import { Features, ACCOUNT_TYPE } from '@/constants';
|
||||
|
||||
import {
|
||||
inputIntent,
|
||||
momentFormatter,
|
||||
@@ -36,25 +28,18 @@ import {
|
||||
} from '@/utils';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { useMoneyOutDialogContext } from '../MoneyOutDialogProvider';
|
||||
import {
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../utils';
|
||||
|
||||
import { useSetPrimaryBranchToForm, BranchRowDivider } from '../utils';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
import { MoneyOutExchangeRateField } from '../MoneyOutExchangeRateField';
|
||||
import { useMoneyOutFieldsContext } from '../MoneyOutFieldsProvider';
|
||||
|
||||
/**
|
||||
* Other expense form fields.
|
||||
*/
|
||||
export default function OtherExpnseFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyOutDialogContext();
|
||||
|
||||
const isForeigAccount = useForeignAccount();
|
||||
const { values } = useFormikContext();
|
||||
|
||||
const amountFieldRef = useAutofocus();
|
||||
const { accounts, branches } = useMoneyOutDialogContext();
|
||||
const { account } = useMoneyOutFieldsContext();
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
@@ -64,21 +49,19 @@ export default function OtherExpnseFormFields() {
|
||||
<FeatureCan feature={Features.Branches}>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<FormGroup
|
||||
label={<T id={'branch'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<FFormGroup name={'branch_id'} label={<T id={'branch'} />}>
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<BranchRowDivider />
|
||||
</FeatureCan>
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ Date -----------*/}
|
||||
@@ -113,47 +96,27 @@ export default function OtherExpnseFormFields() {
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ amount -----------*/}
|
||||
<FastField name={'amount'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
|
||||
<Row>
|
||||
<Col xs={10}>
|
||||
<FFormGroup
|
||||
name={'amount'}
|
||||
label={<T id={'amount'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="amount" />}
|
||||
className={'form-group--amount'}
|
||||
>
|
||||
<ControlGroup>
|
||||
<InputPrependText text={account.currency_code} />
|
||||
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
minimal={true}
|
||||
onChange={(amount) => {
|
||||
setFieldValue('amount', amount);
|
||||
}}
|
||||
inputRef={(ref) => (amountFieldRef.current = ref)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
/>
|
||||
<FMoneyInputGroup name={'amount'} minimal={true} />
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<If condition={isForeigAccount}>
|
||||
{/*------------ exchange rate -----------*/}
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values.currency_code}
|
||||
toCurrency={account.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
</If>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ Exchange rate -----------*/}
|
||||
<MoneyOutExchangeRateField />
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ other expense account -----------*/}
|
||||
@@ -183,44 +146,24 @@ export default function OtherExpnseFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
className={'form-group--reference-no'}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup name={'reference_no'} label={<T id={'reference_no'} />}>
|
||||
<FInputGroup name={'reference_no'} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup name={'description'} label={<T id={'description'} />}>
|
||||
<FTextArea
|
||||
name={'description'}
|
||||
growVertically={true}
|
||||
large={true}
|
||||
fill={true}
|
||||
/>
|
||||
</FFormGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field, ErrorMessage, useFormikContext } from 'formik';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import {
|
||||
Classes,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
TextArea,
|
||||
Position,
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { FormGroup, Position, ControlGroup } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
AccountsSuggestField,
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
If,
|
||||
Col,
|
||||
Row,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
ExchangeRateMutedField,
|
||||
FFormGroup,
|
||||
FTextArea,
|
||||
FInputGroup,
|
||||
FMoneyInputGroup,
|
||||
} from '@/components';
|
||||
import { useAutofocus } from '@/hooks';
|
||||
import { CLASSES, Features, ACCOUNT_TYPE } from '@/constants';
|
||||
import {
|
||||
inputIntent,
|
||||
@@ -36,21 +29,19 @@ import {
|
||||
import { useMoneyOutDialogContext } from '../MoneyOutDialogProvider';
|
||||
import {
|
||||
useSetPrimaryBranchToForm,
|
||||
useForeignAccount,
|
||||
BranchRowDivider,
|
||||
} from '../../MoneyOutDialog/utils';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
import { useMoneyOutFieldsContext } from '../MoneyOutFieldsProvider';
|
||||
import { MoneyOutExchangeRateField } from '../MoneyOutExchangeRateField';
|
||||
|
||||
/**
|
||||
* Owner drawings form fields.
|
||||
*/
|
||||
export default function OwnerDrawingsFormFields() {
|
||||
// Money out dialog context.
|
||||
const { accounts, account, branches } = useMoneyOutDialogContext();
|
||||
const { values } = useFormikContext();
|
||||
const isForeigAccount = useForeignAccount();
|
||||
|
||||
const amountFieldRef = useAutofocus();
|
||||
const { accounts, branches } = useMoneyOutDialogContext();
|
||||
const { account } = useMoneyOutFieldsContext();
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
@@ -60,21 +51,19 @@ export default function OwnerDrawingsFormFields() {
|
||||
<FeatureCan feature={Features.Branches}>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<FormGroup
|
||||
label={<T id={'branch'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<FFormGroup label={<T id={'branch'} />} name={'branch_id'}>
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<BranchRowDivider />
|
||||
</FeatureCan>
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ Date -----------*/}
|
||||
@@ -109,48 +98,27 @@ export default function OwnerDrawingsFormFields() {
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
<Field name={'amount'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
|
||||
{/*------------ Amount -----------*/}
|
||||
|
||||
<Row>
|
||||
<Col xs={10}>
|
||||
<FormGroup
|
||||
name={'amount'}
|
||||
label={<T id={'amount'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="amount" />}
|
||||
className={'form-group--amount'}
|
||||
>
|
||||
<ControlGroup>
|
||||
<InputPrependText text={account.currency_code} />
|
||||
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
minimal={true}
|
||||
onChange={(amount) => {
|
||||
setFieldValue('amount', amount);
|
||||
}}
|
||||
inputRef={(ref) => (amountFieldRef.current = ref)}
|
||||
intent={inputIntent({ error, touched })}
|
||||
/>
|
||||
<FMoneyInputGroup name={'amount'} minimal={true} />
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ Exchange rate -----------*/}
|
||||
<MoneyOutExchangeRateField />
|
||||
|
||||
<If condition={isForeigAccount}>
|
||||
{/*------------ exchange rate -----------*/}
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values?.currency_code}
|
||||
toCurrency={account?.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
</If>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ equitty account -----------*/}
|
||||
@@ -177,44 +145,24 @@ export default function OwnerDrawingsFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
className={'form-group--reference-no'}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup name={'reference_no'} label={<T id={'reference_no'} />}>
|
||||
<FInputGroup name={'reference_no'} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup name={'description'} label={<T id={'description'} />}>
|
||||
<FTextArea
|
||||
name={'description'}
|
||||
growVertically={true}
|
||||
large={true}
|
||||
fill={true}
|
||||
/>
|
||||
</FFormGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import React, { useMemo } from 'react';
|
||||
import { FastField, Field, ErrorMessage } from 'formik';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { FormGroup } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
AccountsSuggestField,
|
||||
FieldRequiredHint,
|
||||
ListSelect,
|
||||
Col,
|
||||
Row,
|
||||
FSelect,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
|
||||
import { inputIntent } from '@/utils';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { getAddMoneyOutOptions } from '@/constants/cashflowOptions';
|
||||
|
||||
import { useMoneyOutDialogContext } from './MoneyOutDialogProvider';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
|
||||
/**
|
||||
* Transaction type fields.
|
||||
@@ -27,9 +26,32 @@ function TransactionTypeFields() {
|
||||
|
||||
const addMoneyOutOptions = useMemo(() => getAddMoneyOutOptions(), []);
|
||||
|
||||
// Money in dialog context.
|
||||
const { defaultAccountId, setAccountId } = useMoneyOutDialogContext();
|
||||
|
||||
// Cannot continue if the default account id is defined.
|
||||
if (defaultAccountId) return null;
|
||||
|
||||
return (
|
||||
<div className="trasnaction-type-fileds">
|
||||
<Row>
|
||||
{/*------------ Transaction type -----------*/}
|
||||
<Col xs={5}>
|
||||
<FFormGroup
|
||||
name={'transaction_type'}
|
||||
label={<T id={'transaction_type'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
>
|
||||
<FSelect
|
||||
name={'transaction_type'}
|
||||
items={addMoneyOutOptions}
|
||||
popoverProps={{ minimal: true }}
|
||||
valueAccessor={'value'}
|
||||
textAccessor={'name'}
|
||||
/>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Current account -----------*/}
|
||||
<FastField name={'cashflow_account_id'}>
|
||||
@@ -47,9 +69,10 @@ function TransactionTypeFields() {
|
||||
>
|
||||
<AccountsSuggestField
|
||||
accounts={cashflowAccounts}
|
||||
onAccountSelected={({ id }) =>
|
||||
form.setFieldValue('cashflow_account_id', id)
|
||||
}
|
||||
onAccountSelected={({ id }) => {
|
||||
form.setFieldValue('cashflow_account_id', id);
|
||||
setAccountId(id);
|
||||
}}
|
||||
inputProps={{
|
||||
intent: inputIntent({ error, touched }),
|
||||
}}
|
||||
@@ -57,39 +80,6 @@ function TransactionTypeFields() {
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
{/*------------ Transaction type -----------*/}
|
||||
</Col>
|
||||
<Col xs={5}>
|
||||
<Field name={'transaction_type'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'transaction_type'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
helperText={<ErrorMessage name="transaction_type" />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
className={classNames(
|
||||
CLASSES.FILL,
|
||||
'form-group--transaction_type',
|
||||
)}
|
||||
>
|
||||
<ListSelect
|
||||
items={addMoneyOutOptions}
|
||||
onItemSelect={(type) => {
|
||||
setFieldValue('transaction_type', type.value);
|
||||
}}
|
||||
filterable={false}
|
||||
selectedItem={value}
|
||||
selectedItemProp={'value'}
|
||||
textProp={'name'}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,65 +1,46 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field, ErrorMessage, useFormikContext } from 'formik';
|
||||
import {
|
||||
Classes,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
TextArea,
|
||||
Position,
|
||||
ControlGroup,
|
||||
} from '@blueprintjs/core';
|
||||
import { FastField, ErrorMessage } from 'formik';
|
||||
import { FormGroup, Position, ControlGroup } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
AccountsSuggestField,
|
||||
InputPrependText,
|
||||
MoneyInputGroup,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
Col,
|
||||
Row,
|
||||
If,
|
||||
InputPrependButton,
|
||||
FeatureCan,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
ExchangeRateMutedField,
|
||||
FFormGroup,
|
||||
FTextArea,
|
||||
FMoneyInputGroup,
|
||||
FInputGroup,
|
||||
} from '@/components';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { useAutofocus } from '@/hooks';
|
||||
import { ACCOUNT_TYPE } from '@/constants/accountTypes';
|
||||
|
||||
import {
|
||||
inputIntent,
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
handleDateChange,
|
||||
compose,
|
||||
} from '@/utils';
|
||||
import { Features } from '@/constants';
|
||||
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 { useSetPrimaryBranchToForm, BranchRowDivider } from '../utils';
|
||||
import { MoneyInOutTransactionNoField } from '../../_components';
|
||||
import { MoneyOutExchangeRateField } from '../MoneyOutExchangeRateField';
|
||||
import { useMoneyOutFieldsContext } from '../MoneyOutFieldsProvider';
|
||||
|
||||
/**
|
||||
* Transfer to account form fields.
|
||||
*/
|
||||
export default function TransferToAccountFormFields() {
|
||||
// Money in dialog context.
|
||||
const { accounts, account, branches } = useMoneyOutDialogContext();
|
||||
const { values } = useFormikContext();
|
||||
const isForeigAccount = useForeignAccount();
|
||||
|
||||
const accountRef = useAutofocus();
|
||||
const { accounts, branches } = useMoneyOutDialogContext();
|
||||
const { account } = useMoneyOutFieldsContext();
|
||||
|
||||
// Sets the primary branch to form.
|
||||
useSetPrimaryBranchToForm();
|
||||
@@ -69,21 +50,19 @@ export default function TransferToAccountFormFields() {
|
||||
<FeatureCan feature={Features.Branches}>
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<FormGroup
|
||||
label={<T id={'branch'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<FFormGroup label={<T id={'branch'} />} name={'branch_id'}>
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
<BranchRowDivider />
|
||||
</FeatureCan>
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ Date -----------*/}
|
||||
@@ -113,52 +92,32 @@ export default function TransferToAccountFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Transaction number -----------*/}
|
||||
<MoneyInOutTransactionNoField />
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ amount -----------*/}
|
||||
<FastField name={'amount'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
|
||||
{/*------------ Amount -----------*/}
|
||||
<Row>
|
||||
<Col xs={10}>
|
||||
<FFormGroup
|
||||
name={'amount'}
|
||||
label={<T id={'amount'} />}
|
||||
labelInfo={<FieldRequiredHint />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="amount" />}
|
||||
className={'form-group--amount'}
|
||||
>
|
||||
<ControlGroup>
|
||||
<InputPrependText text={account.currency_code} />
|
||||
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
minimal={true}
|
||||
onChange={(amount) => {
|
||||
setFieldValue('amount', amount);
|
||||
}}
|
||||
inputRef={accountRef}
|
||||
intent={inputIntent({ error, touched })}
|
||||
/>
|
||||
<FMoneyInputGroup name={'amount'} minimal={true} />
|
||||
</ControlGroup>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<If condition={isForeigAccount}>
|
||||
{/*------------ exchange rate -----------*/}
|
||||
<ExchangeRateMutedField
|
||||
name={'exchange_rate'}
|
||||
fromCurrency={values?.currency_code}
|
||||
toCurrency={account?.currency_code}
|
||||
formGroupProps={{ label: '', inline: false }}
|
||||
date={values.date}
|
||||
exchangeRate={values.exchange_rate}
|
||||
/>
|
||||
</If>
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{/*------------ Exchange rate -----------*/}
|
||||
<MoneyOutExchangeRateField />
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
{/*------------ transfer from account -----------*/}
|
||||
@@ -191,43 +150,24 @@ export default function TransferToAccountFormFields() {
|
||||
)}
|
||||
</FastField>
|
||||
</Col>
|
||||
|
||||
<Col xs={5}>
|
||||
{/*------------ Reference -----------*/}
|
||||
<FastField name={'reference_no'}>
|
||||
{({ form, field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'reference_no'} />}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name="reference_no" />}
|
||||
className={'form-group--reference-no'}
|
||||
>
|
||||
<InputGroup
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup name={'reference_no'} label={<T id={'reference_no'} />}>
|
||||
<FInputGroup name={'reference_no'} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
{/*------------ description -----------*/}
|
||||
<FastField name={'description'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'description'} />}
|
||||
className={'form-group--description'}
|
||||
intent={inputIntent({ error, touched })}
|
||||
helperText={<ErrorMessage name={'description'} />}
|
||||
>
|
||||
<TextArea
|
||||
growVertically={true}
|
||||
large={true}
|
||||
intent={inputIntent({ error, touched })}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
|
||||
{/*------------ Description -----------*/}
|
||||
<FFormGroup name={'description'} label={<T id={'description'} />}>
|
||||
<FTextArea
|
||||
name={'description'}
|
||||
growVertically={true}
|
||||
large={true}
|
||||
fill={true}
|
||||
/>
|
||||
</FFormGroup>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { transactionNumber } from '@/utils';
|
||||
import { first, isEqual, isNull } from 'lodash';
|
||||
|
||||
import { useMoneyOutDialogContext } from './MoneyOutDialogProvider';
|
||||
import { useMoneyOutFieldsContext } from './MoneyOutFieldsProvider';
|
||||
|
||||
export const useObserveTransactionNoSettings = (prefix, nextNumber) => {
|
||||
const { setFieldValue } = useFormikContext();
|
||||
@@ -33,7 +34,7 @@ export const useSetPrimaryBranchToForm = () => {
|
||||
|
||||
export const useForeignAccount = () => {
|
||||
const { values } = useFormikContext();
|
||||
const { account } = useMoneyOutDialogContext();
|
||||
const { account } = useMoneyOutFieldsContext();
|
||||
|
||||
return (
|
||||
!isEqual(account.currency_code, values.currency_code) &&
|
||||
|
||||
@@ -38,11 +38,11 @@ export const MoneyInOutSyncIncrementSettingsToForm = R.compose(
|
||||
// Do not update if the invoice auto-increment is disabled.
|
||||
if (!transactionAutoIncrement) return null;
|
||||
|
||||
const transactionNumber = transactionNumber(
|
||||
const newTransactionNumber = transactionNumber(
|
||||
transactionNumberPrefix,
|
||||
transactionNextNumber,
|
||||
);
|
||||
setFieldValue('transaction_number', transactionNumber);
|
||||
setFieldValue('transaction_number', newTransactionNumber);
|
||||
}, [setFieldValue, transactionNumberPrefix, transactionNextNumber]);
|
||||
|
||||
return null;
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
InputPrependText,
|
||||
CurrencySelectList,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
FeatureCan,
|
||||
Row,
|
||||
Col,
|
||||
@@ -78,12 +77,10 @@ export default function CustomerFinancialPanel() {
|
||||
label={<T id={'customer.label.opening_branch'} />}
|
||||
name={'opening_balance_branch_id'}
|
||||
inline={true}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<BranchSelect
|
||||
name={'opening_balance_branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FFormGroup>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import { Card } from '@/components';
|
||||
import { Card, CommercialDocBox } from '@/components';
|
||||
|
||||
import CashflowTransactionDrawerActionBar from './CashflowTransactionDrawerActionBar';
|
||||
import CashflowTransactionDrawerHeader from './CashflowTransactionDrawerHeader';
|
||||
import CashflowTransactionDrawerTable from './CashflowTransactionDrawerTable';
|
||||
import CashflowTransactionDrawerFooter from './CashflowTransactionDrawerFooter';
|
||||
import CashflowTransactionDrawerTableFooter from './CashflowTransactionDrawerTableFooter';
|
||||
import { CashflowTransactionDrawerFooter } from './CashflowTransactionDrawerFooter';
|
||||
/**
|
||||
* Cashflow transaction view details.
|
||||
*/
|
||||
@@ -16,11 +17,12 @@ export default function CashflowTransactionDrawerDetails() {
|
||||
<CashflowTransactionDrawerActionBar />
|
||||
|
||||
<div className="cashflow-drawer__content">
|
||||
<Card>
|
||||
<CommercialDocBox>
|
||||
<CashflowTransactionDrawerHeader />
|
||||
<CashflowTransactionDrawerTable />
|
||||
<CashflowTransactionDrawerTableFooter />
|
||||
<CashflowTransactionDrawerFooter />
|
||||
</Card>
|
||||
</CommercialDocBox>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,35 +1,18 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { CommercialDocFooter, DetailsMenu, DetailItem, T } from '@/components';
|
||||
import { useCashflowTransactionDrawerContext } from './CashflowTransactionDrawerProvider';
|
||||
import { T, FormatNumber } from '@/components';
|
||||
|
||||
export default function CashflowTransactionDrawerFooter() {
|
||||
const {
|
||||
cashflowTransaction: { formatted_amount },
|
||||
} = useCashflowTransactionDrawerContext();
|
||||
export function CashflowTransactionDrawerFooter() {
|
||||
const { cashflowTransaction } = useCashflowTransactionDrawerContext();
|
||||
|
||||
return (
|
||||
<div className="cashflow-drawer__content-footer">
|
||||
<div class="total-lines">
|
||||
<div class="total-lines__line total-lines__line--subtotal">
|
||||
<div class="title">
|
||||
<T id={'manual_journal.details.subtotal'} />
|
||||
</div>
|
||||
<div class="debit">
|
||||
<FormatNumber value={formatted_amount} />
|
||||
</div>
|
||||
<div class="credit">
|
||||
<FormatNumber value={formatted_amount} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="total-lines__line total-lines__line--total">
|
||||
<div class="title">
|
||||
<T id={'manual_journal.details.total'} />
|
||||
</div>
|
||||
<div class="debit">{formatted_amount}</div>
|
||||
<div class="credit">{formatted_amount}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CommercialDocFooter>
|
||||
<DetailsMenu direction={'horizantal'} minLabelSize={'180px'}>
|
||||
<DetailItem label={<T id={'cash_flow.drawer.label.statement'} />}>
|
||||
{cashflowTransaction.description}
|
||||
</DetailItem>
|
||||
</DetailsMenu>
|
||||
</CommercialDocFooter>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { useCashflowTransactionDrawerContext } from './CashflowTransactionDrawerProvider';
|
||||
import { T, FormatNumber } from '@/components';
|
||||
|
||||
export default function CashflowTransactionDrawerTableFooter() {
|
||||
const {
|
||||
cashflowTransaction: { formatted_amount },
|
||||
} = useCashflowTransactionDrawerContext();
|
||||
|
||||
return (
|
||||
<div className="cashflow-drawer__content-footer">
|
||||
<div class="total-lines">
|
||||
<div class="total-lines__line total-lines__line--subtotal">
|
||||
<div class="title">
|
||||
<T id={'manual_journal.details.subtotal'} />
|
||||
</div>
|
||||
<div class="debit">
|
||||
<FormatNumber value={formatted_amount} />
|
||||
</div>
|
||||
<div class="credit">
|
||||
<FormatNumber value={formatted_amount} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="total-lines__line total-lines__line--total">
|
||||
<div class="title">
|
||||
<T id={'manual_journal.details.total'} />
|
||||
</div>
|
||||
<div class="debit">{formatted_amount}</div>
|
||||
<div class="credit">{formatted_amount}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import {
|
||||
CommercialDocFooter,
|
||||
T,
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Button, Alignment, NavbarGroup, Classes } from '@blueprintjs/core';
|
||||
import { Alignment, NavbarGroup, Classes } from '@blueprintjs/core';
|
||||
import { useSetPrimaryBranchToForm } from './utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { Features } from '@/constants';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { useExpenseFormContext } from './ExpenseFormPageProvider';
|
||||
|
||||
@@ -51,19 +50,9 @@ function ExpenseFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={ExpenseBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function ExpenseBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('expense.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// @ts-nocheck
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { getDefaultAPAgingSummaryQuery } from './common';
|
||||
import { useAPAgingSummaryQuery } from './common';
|
||||
import { FinancialStatement, DashboardPageContent } from '@/components';
|
||||
|
||||
import APAgingSummaryHeader from './APAgingSummaryHeader';
|
||||
@@ -26,25 +26,22 @@ function APAgingSummary({
|
||||
// #withAPAgingSummaryActions
|
||||
toggleAPAgingSummaryFilterDrawer: toggleDisplayFilterDrawer,
|
||||
}) {
|
||||
const [filter, setFilter] = useState({
|
||||
...getDefaultAPAgingSummaryQuery(),
|
||||
});
|
||||
const { query, setLocationQuery } = useAPAgingSummaryQuery();
|
||||
|
||||
// Handle filter submit.
|
||||
const handleFilterSubmit = useCallback((filter) => {
|
||||
const _filter = {
|
||||
...filter,
|
||||
asDate: moment(filter.asDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(_filter);
|
||||
}, []);
|
||||
|
||||
const handleFilterSubmit = useCallback(
|
||||
(filter) => {
|
||||
const _filter = {
|
||||
...filter,
|
||||
asDate: moment(filter.asDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setLocationQuery(_filter);
|
||||
},
|
||||
[setLocationQuery],
|
||||
);
|
||||
// Handle number format submit.
|
||||
const handleNumberFormatSubmit = (numberFormat) => {
|
||||
setFilter({
|
||||
...filter,
|
||||
numberFormat,
|
||||
});
|
||||
setLocationQuery({ ...filter, numberFormat });
|
||||
};
|
||||
// Hide the report filter drawer once the page unmount.
|
||||
useEffect(
|
||||
@@ -55,9 +52,9 @@ function APAgingSummary({
|
||||
);
|
||||
|
||||
return (
|
||||
<APAgingSummaryProvider filter={filter}>
|
||||
<APAgingSummaryProvider filter={query}>
|
||||
<APAgingSummaryActionsBar
|
||||
numberFormat={filter.numberFormat}
|
||||
numberFormat={query.numberFormat}
|
||||
onNumberFormatSubmit={handleNumberFormatSubmit}
|
||||
/>
|
||||
<APAgingSummarySheetLoadingBar />
|
||||
@@ -65,7 +62,7 @@ function APAgingSummary({
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement name={'AP-aging-summary'}>
|
||||
<APAgingSummaryHeader
|
||||
pageFilter={filter}
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit}
|
||||
/>
|
||||
<APAgingSummaryBody organizationName={organizationName} />
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import styled from 'styled-components';
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
import { Formik, Form } from 'formik';
|
||||
@@ -17,6 +15,10 @@ import withAPAgingSummaryActions from './withAPAgingSummaryActions';
|
||||
import { transformToForm, compose } from '@/utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { Features } from '@/constants';
|
||||
import {
|
||||
getAPAgingSummaryQuerySchema,
|
||||
getDefaultAPAgingSummaryQuery,
|
||||
} from './common';
|
||||
|
||||
/**
|
||||
* AP Aging Summary Report - Drawer Header.
|
||||
@@ -33,39 +35,22 @@ function APAgingSummaryHeader({
|
||||
isFilterDrawerOpen,
|
||||
}) {
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
agingDaysBefore: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingBeforeDays'),
|
||||
agingPeriods: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingPeriods'),
|
||||
});
|
||||
const validationSchema = getAPAgingSummaryQuerySchema();
|
||||
|
||||
// Initial values.
|
||||
const defaultValues = {
|
||||
asDate: moment(pageFilter.asDate).toDate(),
|
||||
agingDaysBefore: 30,
|
||||
agingPeriods: 3,
|
||||
vendorsIds: [],
|
||||
branchesIds: [],
|
||||
filterByOption: 'without-zero-balance',
|
||||
};
|
||||
// Formik initial values.
|
||||
const initialValues = transformToForm({ ...pageFilter }, defaultValues);
|
||||
const defaultValues = getDefaultAPAgingSummaryQuery();
|
||||
|
||||
// Formik initial values.
|
||||
const initialValues = transformToForm(
|
||||
{ ...defaultValues, ...pageFilter },
|
||||
defaultValues,
|
||||
);
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
onSubmitFilter(values);
|
||||
toggleFilterDrawerDisplay(false);
|
||||
setSubmitting(false);
|
||||
};
|
||||
|
||||
// Handle cancel button click.
|
||||
const handleCancelClick = () => {
|
||||
toggleFilterDrawerDisplay(false);
|
||||
@@ -74,9 +59,8 @@ function APAgingSummaryHeader({
|
||||
const handleDrawerClose = () => {
|
||||
toggleFilterDrawerDisplay(false);
|
||||
};
|
||||
// Detarmines the feature whether is enabled.
|
||||
// Detarmines whether the feature is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
|
||||
const isBranchesFeatureCan = featureCan(Features.Branches);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field } from 'formik';
|
||||
import { FastField } from 'formik';
|
||||
import { Intent, FormGroup, InputGroup, Position } from '@blueprintjs/core';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import {
|
||||
Intent,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
Position,
|
||||
Classes,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
ContactsMultiSelect,
|
||||
Row,
|
||||
Col,
|
||||
FieldHint,
|
||||
FFormGroup,
|
||||
VendorsMultiSelect,
|
||||
} from '@/components';
|
||||
import { useAPAgingSummaryGeneralContext } from './APAgingSummaryGeneralProvider';
|
||||
import FinancialStatementsFilter from '../FinancialStatementsFilter';
|
||||
@@ -104,22 +98,9 @@ export default function APAgingSummaryHeaderGeneralContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<Field name={'vendorsIds'}>
|
||||
{({ form: { setFieldValue }, field: { value } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'specific_vendors'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
items={vendors}
|
||||
onItemSelect={(vendors) => {
|
||||
const vendorsIds = vendors.map((customer) => customer.id);
|
||||
setFieldValue('vendorsIds', vendorsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup label={<T id={'specific_vendors'} />} name={'vendorsIds'}>
|
||||
<VendorsMultiSelect name={'vendorsIds'} items={vendors} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,80 @@
|
||||
// @ts-nocheck
|
||||
import moment from 'moment';
|
||||
import { transformToCamelCase, flatObject } from '@/utils';
|
||||
import * as Yup from 'yup';
|
||||
import { transformToCamelCase, flatObject, transformToForm } from '@/utils';
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { useMemo } from 'react';
|
||||
import { castArray } from 'lodash';
|
||||
|
||||
export const transformFilterFormToQuery = (form) => {
|
||||
return flatObject(transformToCamelCase(form));
|
||||
};
|
||||
|
||||
/**
|
||||
* The default query of AP aging summary.
|
||||
* @returns
|
||||
*/
|
||||
export const getDefaultAPAgingSummaryQuery = () => {
|
||||
return {
|
||||
asDate: moment().endOf('day').format('YYYY-MM-DD'),
|
||||
agingDaysBefore: 30,
|
||||
agingPeriods: 3,
|
||||
filterByOption: 'without-zero-balance',
|
||||
vendorsIds: [],
|
||||
branchesIds: [],
|
||||
filterByOption: 'without-zero-balance',
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the query validation schema.
|
||||
* @returns {Yup}
|
||||
*/
|
||||
export const getAPAgingSummaryQuerySchema = () => {
|
||||
return Yup.object({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
agingDaysBefore: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingBeforeDays'),
|
||||
agingPeriods: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingPeriods'),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the AP aging summary query state.
|
||||
* @param locationQuery
|
||||
* @returns
|
||||
*/
|
||||
const parseAPAgingSummaryQuery = (locationQuery) => {
|
||||
const defaultQuery = getDefaultAPAgingSummaryQuery();
|
||||
|
||||
const transformed = {
|
||||
...defaultQuery,
|
||||
...transformToForm(locationQuery, defaultQuery),
|
||||
};
|
||||
return {
|
||||
...transformed,
|
||||
vendorsIds: castArray(transformed.vendorsIds),
|
||||
branchesIds: castArray(transformed.branchesIds),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* AP aging summary query state.
|
||||
*/
|
||||
export const useAPAgingSummaryQuery = () => {
|
||||
// Retrieves location query.
|
||||
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||
|
||||
// Merges the default filter query with location URL query.
|
||||
const query = useMemo(
|
||||
() => parseAPAgingSummaryQuery(locationQuery),
|
||||
[locationQuery],
|
||||
);
|
||||
return { query, locationQuery, setLocationQuery };
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
|
||||
import ARAgingSummaryHeader from './ARAgingSummaryHeader';
|
||||
import ARAgingSummaryActionsBar from './ARAgingSummaryActionsBar';
|
||||
|
||||
@@ -13,7 +12,7 @@ import { ARAgingSummaryBody } from './ARAgingSummaryBody';
|
||||
|
||||
import withARAgingSummaryActions from './withARAgingSummaryActions';
|
||||
|
||||
import { getDefaultARAgingSummaryQuery } from './common';
|
||||
import { useARAgingSummaryQuery } from './common';
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
@@ -23,9 +22,7 @@ function ReceivableAgingSummarySheet({
|
||||
// #withARAgingSummaryActions
|
||||
toggleARAgingSummaryFilterDrawer: toggleDisplayFilterDrawer,
|
||||
}) {
|
||||
const [filter, setFilter] = useState({
|
||||
...getDefaultARAgingSummaryQuery(),
|
||||
});
|
||||
const { query, setLocationQuery } = useARAgingSummaryQuery();
|
||||
|
||||
// Handle filter submit.
|
||||
const handleFilterSubmit = useCallback((filter) => {
|
||||
@@ -33,25 +30,23 @@ function ReceivableAgingSummarySheet({
|
||||
...filter,
|
||||
asDate: moment(filter.asDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(_filter);
|
||||
}, []);
|
||||
setLocationQuery(_filter);
|
||||
}, [setLocationQuery]);
|
||||
|
||||
// Handle number format submit.
|
||||
const handleNumberFormatSubmit = (numberFormat) => {
|
||||
setFilter({ ...filter, numberFormat });
|
||||
setLocationQuery({ ...query, numberFormat });
|
||||
};
|
||||
// Hide the filter drawer once the page unmount.
|
||||
useEffect(
|
||||
() => () => {
|
||||
toggleDisplayFilterDrawer(false);
|
||||
},
|
||||
() => () => toggleDisplayFilterDrawer(false),
|
||||
[toggleDisplayFilterDrawer],
|
||||
);
|
||||
|
||||
return (
|
||||
<ARAgingSummaryProvider filter={filter}>
|
||||
<ARAgingSummaryProvider filter={query}>
|
||||
<ARAgingSummaryActionsBar
|
||||
numberFormat={filter.numberFormat}
|
||||
numberFormat={query.numberFormat}
|
||||
onNumberFormatSubmit={handleNumberFormatSubmit}
|
||||
/>
|
||||
<ARAgingSummarySheetLoadingBar />
|
||||
@@ -59,7 +54,7 @@ function ReceivableAgingSummarySheet({
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement>
|
||||
<ARAgingSummaryHeader
|
||||
pageFilter={filter}
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit}
|
||||
/>
|
||||
<ARAgingSummaryBody />
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
@@ -17,6 +16,10 @@ import withARAgingSummaryActions from './withARAgingSummaryActions';
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { Features } from '@/constants';
|
||||
import {
|
||||
getARAgingSummaryQuerySchema,
|
||||
getDefaultARAgingSummaryQuery,
|
||||
} from './common';
|
||||
|
||||
/**
|
||||
* AR Aging Summary Report - Drawer Header.
|
||||
@@ -33,32 +36,15 @@ function ARAgingSummaryHeader({
|
||||
isFilterDrawerOpen,
|
||||
}) {
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
agingDaysBefore: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingDaysBefore'),
|
||||
agingPeriods: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingPeriods'),
|
||||
});
|
||||
const validationSchema = getARAgingSummaryQuerySchema();
|
||||
|
||||
// Initial values.
|
||||
const defaultValues = {
|
||||
asDate: moment().toDate(),
|
||||
agingDaysBefore: 30,
|
||||
agingPeriods: 3,
|
||||
customersIds: [],
|
||||
branchesIds: [],
|
||||
filterByOption: 'without-zero-balance',
|
||||
};
|
||||
const defaultValues = getDefaultARAgingSummaryQuery();
|
||||
|
||||
// Initial values.
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
...defaultValues,
|
||||
...pageFilter,
|
||||
asDate: moment(pageFilter.asDate).toDate(),
|
||||
},
|
||||
@@ -80,7 +66,6 @@ function ARAgingSummaryHeader({
|
||||
};
|
||||
// Detarmines the feature whether is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
|
||||
const isBranchesFeatureCan = featureCan(Features.Branches);
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,22 +2,16 @@
|
||||
import React from 'react';
|
||||
import { FastField, Field } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import {
|
||||
Intent,
|
||||
FormGroup,
|
||||
InputGroup,
|
||||
Position,
|
||||
Classes,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Intent, FormGroup, InputGroup, Position } from '@blueprintjs/core';
|
||||
import FinancialStatementsFilter from '../FinancialStatementsFilter';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
ContactsMultiSelect,
|
||||
Row,
|
||||
Col,
|
||||
FieldHint,
|
||||
FInputGroup,
|
||||
FFormGroup,
|
||||
CustomersMultiSelect,
|
||||
} from '@/components';
|
||||
import { momentFormatter } from '@/utils';
|
||||
import { useARAgingSummaryGeneralContext } from './ARAgingSummaryGeneralProvider';
|
||||
@@ -81,22 +75,13 @@ export default function ARAgingSummaryHeaderGeneralContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<FastField name={'agingPeriods'}>
|
||||
{({ field, meta: { error, touched } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'aging_periods'} />}
|
||||
labelInfo={<FieldHint />}
|
||||
className={'form-group--aging-periods'}
|
||||
intent={error && Intent.DANGER}
|
||||
>
|
||||
<InputGroup
|
||||
medium={true}
|
||||
intent={error && Intent.DANGER}
|
||||
{...field}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</FastField>
|
||||
<FFormGroup
|
||||
name={'agingPeriods'}
|
||||
label={<T id={'aging_periods'} />}
|
||||
labelInfo={<FieldHint />}
|
||||
>
|
||||
<FInputGroup name={'agingPeriods'} medium={true} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -111,24 +96,12 @@ export default function ARAgingSummaryHeaderGeneralContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<Field name="customersIds">
|
||||
{({ form: { setFieldValue }, field: { value } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'specific_customers'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
items={customers}
|
||||
onItemSelect={(customers) => {
|
||||
const customersIds = customers.map(
|
||||
(customer) => customer.id,
|
||||
);
|
||||
setFieldValue('customersIds', customersIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup
|
||||
name="customersIds"
|
||||
label={<T id={'specific_customers'} />}
|
||||
>
|
||||
<CustomersMultiSelect name="customersIds" items={customers} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import moment from 'moment';
|
||||
import { transformToCamelCase, flatObject } from '@/utils';
|
||||
import * as Yup from 'yup';
|
||||
import { transformToCamelCase, flatObject, transformToForm } from '@/utils';
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { useMemo } from 'react';
|
||||
import { castArray } from 'lodash';
|
||||
|
||||
export const transfromFilterFormToQuery = (form) => {
|
||||
return flatObject(transformToCamelCase(form));
|
||||
@@ -14,8 +18,57 @@ export const getDefaultARAgingSummaryQuery = () => {
|
||||
asDate: moment().endOf('day').format('YYYY-MM-DD'),
|
||||
agingDaysBefore: 30,
|
||||
agingPeriods: 3,
|
||||
customersIds: [],
|
||||
filterByOption: 'without-zero-balance',
|
||||
customersIds: [],
|
||||
branchesIds: [],
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the AR aging summary query schema.
|
||||
* @returns {Yup}
|
||||
*/
|
||||
export const getARAgingSummaryQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
agingDaysBefore: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingDaysBefore'),
|
||||
agingPeriods: Yup.number()
|
||||
.required()
|
||||
.integer()
|
||||
.positive()
|
||||
.label('agingPeriods'),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the AR aging summary state.
|
||||
*/
|
||||
const parseARAgingSummaryQuery = (locationQuery) => {
|
||||
const defaultQuery = getDefaultARAgingSummaryQuery();
|
||||
const transformed = {
|
||||
...defaultQuery,
|
||||
...transformToForm(locationQuery, defaultQuery),
|
||||
};
|
||||
return {
|
||||
...transformed,
|
||||
branchesIds: castArray(transformed.branchesIds),
|
||||
customersIds: castArray(transformed.customersIds),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* AR aging summary query state.
|
||||
*/
|
||||
export const useARAgingSummaryQuery = () => {
|
||||
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||
|
||||
const query = useMemo(
|
||||
() => parseARAgingSummaryQuery(locationQuery),
|
||||
[locationQuery],
|
||||
);
|
||||
return { query, locationQuery, setLocationQuery };
|
||||
};
|
||||
|
||||
@@ -68,7 +68,6 @@ function BalanceSheetHeader({
|
||||
};
|
||||
// Detarmines the given feature whether is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
|
||||
const isBranchesFeatureCan = featureCan(Features.Branches);
|
||||
|
||||
return (
|
||||
|
||||
@@ -21,19 +21,21 @@ export function BalanceSheetAlerts() {
|
||||
refetchBalanceSheet();
|
||||
};
|
||||
// Can't display any error if the report is loading.
|
||||
if (isLoading) return null;
|
||||
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
// Can't continue if the cost compute job is not running.
|
||||
if (!balanceSheet.meta.is_cost_compute_running) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<If condition={balanceSheet.meta.is_cost_compute_running}>
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />{' '}
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'report.compute_running.refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
</If>
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />{' '}
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'report.compute_running.refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
import { dynamicColumns } from './dynamicColumns';
|
||||
import { useCashFlowStatementContext } from './CashFlowStatementProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
|
||||
/**
|
||||
* Retrieve cash flow statement columns.
|
||||
@@ -27,6 +28,7 @@ export const useCashFlowStatementColumns = () => {
|
||||
*/
|
||||
export function CashFlowStatementLoadingBar() {
|
||||
const { isCashFlowFetching } = useCashFlowStatementContext();
|
||||
|
||||
return (
|
||||
<If condition={isCashFlowFetching}>
|
||||
<FinancialLoadingBar />
|
||||
@@ -45,20 +47,21 @@ export function CashFlowStatementAlerts() {
|
||||
const handleRecalcReport = () => {
|
||||
refetchCashFlow();
|
||||
};
|
||||
|
||||
// Can't display any error if the report is loading
|
||||
if (isCashFlowLoading) {
|
||||
return null;
|
||||
}
|
||||
// Can't continue if the cost compute is not running.
|
||||
if (!cashFlowStatement.meta.is_cost_compute_running) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<If condition={cashFlowStatement.meta.is_cost_compute_running}>
|
||||
<div className="alert-compute-running">
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import moment from 'moment';
|
||||
import * as R from 'ramda';
|
||||
|
||||
@@ -10,11 +10,10 @@ import CustomersBalanceSummaryHeader from './CustomersBalanceSummaryHeader';
|
||||
|
||||
import { CustomerBalanceSummaryBody } from './CustomerBalanceSummaryBody';
|
||||
import { CustomersBalanceSummaryProvider } from './CustomersBalanceSummaryProvider';
|
||||
import { getDefaultCustomersBalanceQuery } from './utils';
|
||||
import { useCustomerBalanceSummaryQuery } from './utils';
|
||||
import { CustomersBalanceLoadingBar } from './components';
|
||||
import withCustomersBalanceSummaryActions from './withCustomersBalanceSummaryActions';
|
||||
|
||||
|
||||
/**
|
||||
* Customers Balance summary.
|
||||
*/
|
||||
@@ -22,36 +21,33 @@ function CustomersBalanceSummary({
|
||||
// #withCustomersBalanceSummaryActions
|
||||
toggleCustomerBalanceFilterDrawer,
|
||||
}) {
|
||||
const [filter, setFilter] = useState({
|
||||
...getDefaultCustomersBalanceQuery(),
|
||||
});
|
||||
const { query, setLocationQuery } = useCustomerBalanceSummaryQuery();
|
||||
|
||||
// Handle re-fetch customers balance summary after filter change.
|
||||
const handleFilterSubmit = (filter) => {
|
||||
const _filter = {
|
||||
...filter,
|
||||
asDate: moment(filter.asDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter({ ..._filter });
|
||||
setLocationQuery({ ..._filter });
|
||||
};
|
||||
// Handle number format.
|
||||
const handleNumberFormat = (values) => {
|
||||
setFilter({
|
||||
setLocationQuery({
|
||||
...filter,
|
||||
numberFormat: values,
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
toggleCustomerBalanceFilterDrawer(false);
|
||||
},
|
||||
() => () => toggleCustomerBalanceFilterDrawer(false),
|
||||
[toggleCustomerBalanceFilterDrawer],
|
||||
);
|
||||
|
||||
return (
|
||||
<CustomersBalanceSummaryProvider filter={filter}>
|
||||
<CustomersBalanceSummaryProvider filter={query}>
|
||||
<CustomersBalanceSummaryActionsBar
|
||||
numberFormat={filter?.numberFormat}
|
||||
numberFormat={query?.numberFormat}
|
||||
onNumberFormatSubmit={handleNumberFormat}
|
||||
/>
|
||||
<CustomersBalanceLoadingBar />
|
||||
@@ -59,7 +55,7 @@ function CustomersBalanceSummary({
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement>
|
||||
<CustomersBalanceSummaryHeader
|
||||
pageFilter={filter}
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit}
|
||||
/>
|
||||
<CustomerBalanceSummaryBody />
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FastField, Field } from 'formik';
|
||||
import { FastField } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { Classes, FormGroup, Position, Checkbox } from '@blueprintjs/core';
|
||||
import { FormGroup, Position, Checkbox } from '@blueprintjs/core';
|
||||
import {
|
||||
ContactsMultiSelect,
|
||||
FormattedMessage as T,
|
||||
Row,
|
||||
Col,
|
||||
FieldHint,
|
||||
CustomersMultiSelect,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
@@ -86,26 +85,12 @@ export default function CustomersBalanceSummaryGeneralPanelContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<Field name={'customersIds'}>
|
||||
{({
|
||||
form: { setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'specific_customers'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
items={customers}
|
||||
onItemSelect={(contacts) => {
|
||||
const customersIds = contacts.map((contact) => contact.id);
|
||||
setFieldValue('customersIds', customersIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup
|
||||
name={'customersIds'}
|
||||
label={<T id={'specific_customers'} />}
|
||||
>
|
||||
<CustomersMultiSelect name={'customersIds'} items={customers} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import styled from 'styled-components';
|
||||
import moment from 'moment';
|
||||
import { Formik, Form } from 'formik';
|
||||
@@ -13,6 +13,7 @@ import withCustomersBalanceSummaryActions from './withCustomersBalanceSummaryAct
|
||||
import CustomersBalanceSummaryGeneralPanel from './CustomersBalanceSummaryGeneralPanel';
|
||||
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import { getCustomersBalanceQuerySchema } from './utils';
|
||||
|
||||
/**
|
||||
* Customers balance summary.
|
||||
@@ -29,9 +30,8 @@ function CustomersBalanceSummaryHeader({
|
||||
toggleCustomerBalanceFilterDrawer,
|
||||
}) {
|
||||
// validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
});
|
||||
const validationSchema = getCustomersBalanceQuerySchema();
|
||||
|
||||
// Default form values.
|
||||
const defaultValues = {
|
||||
...pageFilter,
|
||||
|
||||
@@ -1,9 +1,58 @@
|
||||
// @ts-nocheck
|
||||
import { useMemo } from 'react';
|
||||
import { castArray } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { getDefaultARAgingSummaryQuery } from '../ARAgingSummary/common';
|
||||
import { transformToForm } from '@/utils';
|
||||
|
||||
/**
|
||||
* Default query of customers balance summary.
|
||||
*/
|
||||
export const getDefaultCustomersBalanceQuery = () => {
|
||||
return {
|
||||
asDate: moment().endOf('day').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
customersIds: [],
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the customers balance query schema.
|
||||
* @returns {Yup}
|
||||
*/
|
||||
export const getCustomersBalanceQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the customer balance summary query.
|
||||
*/
|
||||
const parseCustomersBalanceSummaryQuery = (locationQuery) => {
|
||||
const defaultQuery = getDefaultARAgingSummaryQuery();
|
||||
|
||||
const transformed = {
|
||||
...defaultQuery,
|
||||
...transformToForm(locationQuery, defaultQuery),
|
||||
};
|
||||
return {
|
||||
...transformed,
|
||||
customersIds: castArray(transformed.customersIds),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Getter/setter query state of customers balance summary.
|
||||
*/
|
||||
export const useCustomerBalanceSummaryQuery = () => {
|
||||
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||
|
||||
const query = useMemo(
|
||||
() => parseCustomersBalanceSummaryQuery(locationQuery),
|
||||
[locationQuery],
|
||||
);
|
||||
return { query, locationQuery, setLocationQuery };
|
||||
};
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import intl from 'react-intl-universal';
|
||||
import moment from 'moment';
|
||||
import styled from 'styled-components';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
@@ -15,6 +13,10 @@ import withCustomersTransactions from './withCustomersTransactions';
|
||||
import withCustomersTransactionsActions from './withCustomersTransactionsActions';
|
||||
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import {
|
||||
getCustomersTransactionsDefaultQuery,
|
||||
getCustomersTransactionsQuerySchema,
|
||||
} from './_utils';
|
||||
|
||||
/**
|
||||
* Customers transactions header.
|
||||
@@ -31,12 +33,8 @@ function CustomersTransactionsHeader({
|
||||
toggleCustomersTransactionsFilterDrawer: toggleFilterDrawer,
|
||||
}) {
|
||||
// Default form values.
|
||||
const defaultValues = {
|
||||
...pageFilter,
|
||||
fromDate: moment().toDate(),
|
||||
toDate: moment().toDate(),
|
||||
customersIds: [],
|
||||
};
|
||||
const defaultValues = getCustomersTransactionsDefaultQuery();
|
||||
|
||||
// Initial form values.
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
@@ -49,13 +47,7 @@ function CustomersTransactionsHeader({
|
||||
);
|
||||
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('toDate')),
|
||||
});
|
||||
const validationSchema = getCustomersTransactionsQuerySchema();
|
||||
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Field } from 'formik';
|
||||
import { Classes, FormGroup } from '@blueprintjs/core';
|
||||
import FinancialStatementDateRange from '../FinancialStatementDateRange';
|
||||
import FinancialStatementsFilter from '../FinancialStatementsFilter';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
ContactsMultiSelect,
|
||||
FormattedMessage as T,
|
||||
CustomersMultiSelect,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
import { filterCustomersOptions } from '../constants';
|
||||
|
||||
@@ -51,24 +49,12 @@ function CustomersTransactionsHeaderGeneralPanelContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'customersIds'}>
|
||||
{({ form: { setFieldValue }, field: { value } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'specific_customers'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
items={customers}
|
||||
onItemSelect={(customers) => {
|
||||
const customersIds = customers.map(
|
||||
(customer) => customer.id,
|
||||
);
|
||||
setFieldValue('customersIds', customersIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup
|
||||
label={<T id={'specific_customers'} />}
|
||||
name={'customersIds'}
|
||||
>
|
||||
<CustomersMultiSelect name={'customersIds'} items={customers} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import * as Yup from 'yup';
|
||||
import intl from 'react-intl-universal';
|
||||
import moment from 'moment';
|
||||
|
||||
export const getCustomersTransactionsQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('toDate')),
|
||||
});
|
||||
};
|
||||
|
||||
export const getCustomersTransactionsDefaultQuery = () => ({
|
||||
fromDate: moment().toDate(),
|
||||
toDate: moment().toDate(),
|
||||
customersIds: [],
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import GeneralLedgerHeader from './GeneralLedgerHeader';
|
||||
@@ -41,10 +41,8 @@ function GeneralLedger({
|
||||
);
|
||||
|
||||
// Hide the filter drawer once the page unmount.
|
||||
React.useEffect(
|
||||
() => () => {
|
||||
toggleGeneralLedgerFilterDrawer(false);
|
||||
},
|
||||
useEffect(
|
||||
() => () => toggleGeneralLedgerFilterDrawer(false),
|
||||
[toggleGeneralLedgerFilterDrawer],
|
||||
);
|
||||
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import styled from 'styled-components';
|
||||
import * as Yup from 'yup';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
import { getDefaultGeneralLedgerQuery } from './common';
|
||||
import {
|
||||
getDefaultGeneralLedgerQuery,
|
||||
getGeneralLedgerQuerySchema,
|
||||
} from './common';
|
||||
import { compose, transformToForm, saveInvoke } from '@/utils';
|
||||
|
||||
import FinancialStatementHeader from '../FinancialStatementHeader';
|
||||
@@ -39,6 +41,7 @@ function GeneralLedgerHeader({
|
||||
// Initial values.
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
...defaultValues,
|
||||
...pageFilter,
|
||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||
toDate: moment(pageFilter.toDate).toDate(),
|
||||
@@ -46,11 +49,8 @@ function GeneralLedgerHeader({
|
||||
defaultValues,
|
||||
);
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
dateRange: Yup.string().optional(),
|
||||
fromDate: Yup.date().required(),
|
||||
toDate: Yup.date().min(Yup.ref('fromDate')).required(),
|
||||
});
|
||||
const validationSchema = getGeneralLedgerQuerySchema();
|
||||
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
saveInvoke(onSubmitFilter, values);
|
||||
@@ -68,6 +68,7 @@ function GeneralLedgerHeader({
|
||||
// Detarmines the feature whether is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
|
||||
// Detarmine if the feature is enabled.
|
||||
const isBranchesFeatureCan = featureCan(Features.Branches);
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import { castArray } from 'lodash';
|
||||
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
@@ -26,15 +27,25 @@ export const filterAccountsOptions = [
|
||||
/**
|
||||
* Retrieves the default general ledger query.
|
||||
*/
|
||||
export const getDefaultGeneralLedgerQuery = () => {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
basis: 'accrual',
|
||||
filterByOption: 'with-transactions',
|
||||
branchesIds: [],
|
||||
accountsIds: [],
|
||||
};
|
||||
export const getDefaultGeneralLedgerQuery = () => ({
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
basis: 'accrual',
|
||||
filterByOption: 'with-transactions',
|
||||
branchesIds: [],
|
||||
accountsIds: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* Retrieves the validation schema of general ledger.
|
||||
* @returns {Yup}
|
||||
*/
|
||||
export const getGeneralLedgerQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
dateRange: Yup.string().optional(),
|
||||
fromDate: Yup.date().required(),
|
||||
toDate: Yup.date().min(Yup.ref('fromDate')).required(),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getColumnWidth } from '@/utils';
|
||||
import { useGeneralLedgerContext } from './GeneralLedgerProvider';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
import { Align } from '@/constants';
|
||||
|
||||
/**
|
||||
@@ -116,17 +117,18 @@ export function GeneralLedgerSheetAlerts() {
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can't continue if the cost compute job is not running.
|
||||
if (!generalLedger.meta.is_cost_compute_running) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<If condition={generalLedger.meta.is_cost_compute_running}>
|
||||
<div class="alert-compute-running">
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import moment from 'moment';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
@@ -16,7 +15,10 @@ import InventoryItemDetailsHeaderDimensionsPanel from './InventoryItemDetailsHea
|
||||
import withInventoryItemDetails from './withInventoryItemDetails';
|
||||
import withInventoryItemDetailsActions from './withInventoryItemDetailsActions';
|
||||
|
||||
import { getInventoryItemDetailsDefaultQuery } from './utils2';
|
||||
import {
|
||||
getInventoryItemDetailsDefaultQuery,
|
||||
getInventoryItemDetailsQuerySchema,
|
||||
} from './utils2';
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { Features } from '@/constants';
|
||||
@@ -28,6 +30,7 @@ function InventoryItemDetailsHeader({
|
||||
// #ownProps
|
||||
onSubmitFilter,
|
||||
pageFilter,
|
||||
|
||||
// #withInventoryItemDetails
|
||||
isFilterDrawerOpen,
|
||||
|
||||
@@ -40,30 +43,29 @@ function InventoryItemDetailsHeader({
|
||||
// Filter form initial values.
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
...defaultValues,
|
||||
...pageFilter,
|
||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||
toDate: moment(pageFilter.toDate).toDate(),
|
||||
},
|
||||
defaultValues,
|
||||
);
|
||||
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('toDate')),
|
||||
});
|
||||
const validationSchema = getInventoryItemDetailsQuerySchema();
|
||||
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
onSubmitFilter(values);
|
||||
toggleFilterDrawer(false);
|
||||
setSubmitting(false);
|
||||
};
|
||||
|
||||
// Handle drawer close action.
|
||||
const handleDrawerClose = () => {
|
||||
toggleFilterDrawer(false);
|
||||
};
|
||||
|
||||
// Detarmines the given feature whether is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||
import { Field } from 'formik';
|
||||
import {
|
||||
ItemsMultiSelect,
|
||||
Row,
|
||||
Col,
|
||||
FormattedMessage as T,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
import classNames from 'classnames';
|
||||
import FinancialStatementDateRange from '../FinancialStatementDateRange';
|
||||
|
||||
import {
|
||||
@@ -39,26 +37,9 @@ function InventoryItemDetailsHeaderGeneralPanelContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'itemsIds'}>
|
||||
{({
|
||||
form: { setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup label={<T id={'Specific items'} />} name={'itemsIds'}>
|
||||
<ItemsMultiSelect name={'itemsIds'} items={items} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Icon, If, FormattedMessage as T } from '@/components';
|
||||
import { dynamicColumns } from './utils';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
|
||||
/**
|
||||
* Retrieve inventory item details columns.
|
||||
@@ -53,17 +54,19 @@ export function InventoryItemDetailsAlerts() {
|
||||
if (isInventoryItemDetailsLoading) {
|
||||
return null;
|
||||
}
|
||||
// Can't continue if the cost compute job is running.
|
||||
if (!inventoryItemDetails.meta.is_cost_compute_running) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<If condition={inventoryItemDetails.meta.is_cost_compute_running}>
|
||||
<div className="alert-compute-running">
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { castArray } from 'lodash';
|
||||
import * as Yup from 'yup';
|
||||
import intl from 'react-intl-universal';
|
||||
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { transformToForm } from '@/utils';
|
||||
@@ -9,13 +11,26 @@ import { transformToForm } from '@/utils';
|
||||
/**
|
||||
* Retrieves inventory item details default query.
|
||||
*/
|
||||
export const getInventoryItemDetailsDefaultQuery = () => {
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
warehousesIds: [],
|
||||
branchesIds: [],
|
||||
};
|
||||
export const getInventoryItemDetailsDefaultQuery = () => ({
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
itemsIds: [],
|
||||
warehousesIds: [],
|
||||
branchesIds: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* Retrieves inventory item details query schema.
|
||||
* @returns {Yup}
|
||||
*/
|
||||
export const getInventoryItemDetailsQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('toDate')),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -32,7 +47,8 @@ const parseInventoryItemDetailsQuery = (locationQuery) => {
|
||||
return {
|
||||
...transformed,
|
||||
|
||||
// Ensures the branches/warehouses ids is always array.
|
||||
// Ensure the branches, warehouses and items ids is always array.
|
||||
itemsIds: castArray(transformed.itemsIds),
|
||||
branchesIds: castArray(transformed.branchesIds),
|
||||
warehousesIds: castArray(transformed.warehousesIds),
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import moment from 'moment';
|
||||
import styled from 'styled-components';
|
||||
import { Formik, Form } from 'formik';
|
||||
@@ -17,6 +16,10 @@ import withInventoryValuationActions from './withInventoryValuationActions';
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { Features } from '@/constants';
|
||||
import {
|
||||
getInventoryValuationQuery,
|
||||
getInventoryValuationQuerySchema,
|
||||
} from './utils';
|
||||
|
||||
/**
|
||||
* inventory valuation header.
|
||||
@@ -33,25 +36,17 @@ function InventoryValuationHeader({
|
||||
toggleInventoryValuationFilterDrawer,
|
||||
}) {
|
||||
// Form validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
});
|
||||
const validationSchema = getInventoryValuationQuerySchema();
|
||||
const defaultQuery = getInventoryValuationQuery();
|
||||
|
||||
// Default values.
|
||||
const defaultValues = {
|
||||
...pageFilter,
|
||||
asDate: moment().toDate(),
|
||||
itemsIds: [],
|
||||
warehousesIds: [],
|
||||
};
|
||||
// Initial values.
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
...defaultValues,
|
||||
...defaultQuery,
|
||||
...pageFilter,
|
||||
asDate: moment(pageFilter.asDate).toDate(),
|
||||
},
|
||||
defaultValues,
|
||||
defaultQuery,
|
||||
);
|
||||
|
||||
// Handle the form of header submit.
|
||||
@@ -71,6 +66,7 @@ function InventoryValuationHeader({
|
||||
// Detarmines the given feature whether is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
|
||||
// Detarmine if these feature are enabled.
|
||||
const isBranchesFeatureCan = featureCan(Features.Branches);
|
||||
const isWarehousesFeatureCan = featureCan(Features.Warehouses);
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
import React from 'react';
|
||||
import { FastField, Field } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FormGroup, Position, Classes } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup, Position } from '@blueprintjs/core';
|
||||
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
@@ -11,9 +10,9 @@ import {
|
||||
Row,
|
||||
Col,
|
||||
FieldHint,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
import { filterInventoryValuationOptions } from '../constants';
|
||||
|
||||
import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
@@ -83,22 +82,9 @@ function InventoryValuationHeaderGeneralPanelContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'itemsIds'}>
|
||||
{({ form: { setFieldValue } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup name={'itemsIds'} label={<T id={'Specific items'} />}>
|
||||
<ItemsMultiSelect name={'itemsIds'} items={items} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -2,25 +2,33 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { castArray } from 'lodash';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { transformToForm } from '@/utils';
|
||||
|
||||
/**
|
||||
* Retrieves the inventory valuation sheet default query.
|
||||
* Retrieves the validation schema of inventory valuation query.
|
||||
*/
|
||||
export const getInventoryValuationQuery = () => {
|
||||
return {
|
||||
asDate: moment().endOf('day').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
|
||||
branchesIds: [],
|
||||
warehousesIds: [],
|
||||
};
|
||||
export const getInventoryValuationQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses inventory valiation location query to report query.
|
||||
* Retrieves the inventory valuation sheet default query.
|
||||
*/
|
||||
export const getInventoryValuationQuery = () => ({
|
||||
asDate: moment().endOf('day').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
itemsIds: [],
|
||||
branchesIds: [],
|
||||
warehousesIds: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* Parses inventory valuation location query to report query.
|
||||
*/
|
||||
const parseInventoryValuationQuery = (locationQuery) => {
|
||||
const defaultQuery = getInventoryValuationQuery();
|
||||
@@ -33,6 +41,7 @@ const parseInventoryValuationQuery = (locationQuery) => {
|
||||
...transformed,
|
||||
|
||||
// Ensures the branches/warehouses ids is always array.
|
||||
itemsIds: castArray(transformed.itemsIds),
|
||||
branchesIds: castArray(transformed.branchesIds),
|
||||
warehousesIds: castArray(transformed.warehousesIds),
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Button } from '@blueprintjs/core';
|
||||
import { Icon, If, FormattedMessage as T } from '@/components';
|
||||
import { useJournalSheetContext } from './JournalProvider';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
|
||||
import { Align } from '@/constants';
|
||||
|
||||
@@ -99,17 +100,18 @@ export function JournalSheetAlerts() {
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can't continue if the cost compute job is running.
|
||||
if (!journalSheet.meta.is_cost_compute_running) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<If condition={journalSheet.meta.is_cost_compute_running}>
|
||||
<div class="alert-compute-running">
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import withProfitLossActions from './withProfitLossActions';
|
||||
|
||||
import { useProfitLossSheetQuery } from './utils';
|
||||
import { ProfitLossSheetProvider } from './ProfitLossProvider';
|
||||
import { ProfitLossSheetLoadingBar } from './components';
|
||||
import { ProfitLossSheetAlerts, ProfitLossSheetLoadingBar } from './components';
|
||||
import { ProfitLossBody } from './ProfitLossBody';
|
||||
|
||||
/**
|
||||
@@ -58,7 +58,7 @@ function ProfitLossSheet({
|
||||
onNumberFormatSubmit={handleNumberFormatSubmit}
|
||||
/>
|
||||
<ProfitLossSheetLoadingBar />
|
||||
{/* <ProfitLossSheetAlerts /> */}
|
||||
<ProfitLossSheetAlerts />
|
||||
|
||||
<DashboardPageContent>
|
||||
<ProfitLossSheetHeader
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Button } from '@blueprintjs/core';
|
||||
import { Icon, If, FormattedMessage as T } from '@/components';
|
||||
|
||||
import { useProfitLossSheetContext } from './ProfitLossProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
/**
|
||||
@@ -34,17 +35,18 @@ export function ProfitLossSheetAlerts() {
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can't continue if the cost compute job is not running.
|
||||
if (!profitLossSheet.meta.is_cost_compute_running) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<If condition={profitLossSheet.meta.is_cost_compute_running}>
|
||||
<div class="alert-compute-running">
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import PurchasesByItemsActionsBar from './PurchasesByItemsActionsBar';
|
||||
@@ -9,7 +9,7 @@ import { FinancialStatement, DashboardPageContent } from '@/components';
|
||||
import { PurchasesByItemsLoadingBar } from './components';
|
||||
import { PurchasesByItemsProvider } from './PurchasesByItemsProvider';
|
||||
import { PurchasesByItemsBody } from './PurchasesByItemsBody';
|
||||
import { getDefaultPurchasesByItemsQuery } from './utils';
|
||||
import { usePurchasesByItemsQuery } from './utils';
|
||||
import { compose } from '@/utils';
|
||||
|
||||
import withPurchasesByItemsActions from './withPurchasesByItemsActions';
|
||||
@@ -21,9 +21,7 @@ function PurchasesByItems({
|
||||
// #withPurchasesByItemsActions
|
||||
togglePurchasesByItemsFilterDrawer,
|
||||
}) {
|
||||
const [filter, setFilter] = useState({
|
||||
...getDefaultPurchasesByItemsQuery(),
|
||||
});
|
||||
const { query, setLocationQuery } = usePurchasesByItemsQuery();
|
||||
|
||||
// Handle filter form submit.
|
||||
const handleFilterSubmit = useCallback(
|
||||
@@ -33,11 +31,10 @@ function PurchasesByItems({
|
||||
fromDate: moment(filter.fromDate).format('YYYY-MM-DD'),
|
||||
toDate: moment(filter.toDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(parsedFilter);
|
||||
setLocationQuery(parsedFilter);
|
||||
},
|
||||
[setFilter],
|
||||
[setLocationQuery],
|
||||
);
|
||||
|
||||
// Handle number format form submit.
|
||||
const handleNumberFormatSubmit = (numberFormat) => {
|
||||
setFilter({
|
||||
@@ -45,7 +42,6 @@ function PurchasesByItems({
|
||||
numberFormat,
|
||||
});
|
||||
};
|
||||
|
||||
// Hide the filter drawer once the page unmount.
|
||||
useEffect(
|
||||
() => () => {
|
||||
@@ -55,9 +51,9 @@ function PurchasesByItems({
|
||||
);
|
||||
|
||||
return (
|
||||
<PurchasesByItemsProvider query={filter}>
|
||||
<PurchasesByItemsProvider query={query}>
|
||||
<PurchasesByItemsActionsBar
|
||||
numberFormat={filter.numberFormat}
|
||||
numberFormat={query.numberFormat}
|
||||
onNumberFormatSubmit={handleNumberFormatSubmit}
|
||||
/>
|
||||
<PurchasesByItemsLoadingBar />
|
||||
@@ -65,7 +61,7 @@ function PurchasesByItems({
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement>
|
||||
<PurchasesByItemsHeader
|
||||
pageFilter={filter}
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit}
|
||||
/>
|
||||
<PurchasesByItemsBody />
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||
import { Field } from 'formik';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
FormattedMessage as T,
|
||||
ItemsMultiSelect,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
import classNames from 'classnames';
|
||||
import FinancialStatementDateRange from '../FinancialStatementDateRange';
|
||||
import FinancialStatementsFilter from '../FinancialStatementsFilter';
|
||||
import { filterItemsOptions } from '../constants';
|
||||
@@ -51,22 +49,9 @@ function PurchasesByItemsGeneralPanelContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'itemsIds'}>
|
||||
{({ form: { setFieldValue } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup name={'itemsIds'} label={<T id={'Specific items'} />}>
|
||||
<ItemsMultiSelect name={'itemsIds'} items={items} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import moment from 'moment';
|
||||
import intl from 'react-intl-universal';
|
||||
import styled from 'styled-components';
|
||||
import styled from 'styled-components';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
|
||||
import FinancialStatementHeader from '@/containers/FinancialStatements/FinancialStatementHeader';
|
||||
import PurchasesByItemsGeneralPanel from './PurchasesByItemsGeneralPanel';
|
||||
|
||||
@@ -16,6 +13,10 @@ import withPurchasesByItems from './withPurchasesByItems';
|
||||
import withPurchasesByItemsActions from './withPurchasesByItemsActions';
|
||||
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import {
|
||||
getDefaultPurchasesByItemsQuery,
|
||||
getPurchasesByItemsQuerySchema,
|
||||
} from './utils';
|
||||
|
||||
/**
|
||||
* Purchases by items header.
|
||||
@@ -32,38 +33,26 @@ function PurchasesByItemsHeader({
|
||||
togglePurchasesByItemsFilterDrawer,
|
||||
}) {
|
||||
// Form validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('from_date')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('to_date')),
|
||||
});
|
||||
// Default form values.
|
||||
const defaultValues = {
|
||||
...pageFilter,
|
||||
fromDate: moment().toDate(),
|
||||
toDate: moment().toDate(),
|
||||
itemsIds: [],
|
||||
};
|
||||
const validationSchema = getPurchasesByItemsQuerySchema();
|
||||
|
||||
const defaultQuery = getDefaultPurchasesByItemsQuery();
|
||||
|
||||
// Initial form values.
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
...defaultValues,
|
||||
...defaultQuery,
|
||||
...pageFilter,
|
||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||
toDate: moment(pageFilter.toDate).toDate(),
|
||||
},
|
||||
defaultValues,
|
||||
defaultQuery,
|
||||
);
|
||||
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
onSubmitFilter(values);
|
||||
setSubmitting(false);
|
||||
togglePurchasesByItemsFilterDrawer(false);
|
||||
};
|
||||
|
||||
// Handle drawer close & cancel action.
|
||||
const handleDrawerClose = () => {
|
||||
togglePurchasesByItemsFilterDrawer(false);
|
||||
|
||||
@@ -1,11 +1,62 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import intl from 'react-intl-universal';
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { transformToForm } from '@/utils';
|
||||
import { castArray } from 'lodash';
|
||||
|
||||
/**
|
||||
* Retrieves the purchases by items query.
|
||||
*/
|
||||
export const getDefaultPurchasesByItemsQuery = () => ({
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
itemsIds: [],
|
||||
});
|
||||
|
||||
export const getDefaultPurchasesByItemsQuery = () => {
|
||||
/**
|
||||
* Retrieves the purchases by items query validation schema.
|
||||
* @returns {Yup}
|
||||
*/
|
||||
export const getPurchasesByItemsQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('from_date')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('to_date')),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the purchases by items query.
|
||||
*/
|
||||
const parsePurchasesByItemsQuery = (locationQuery) => {
|
||||
const defaultQuery = getDefaultPurchasesByItemsQuery();
|
||||
|
||||
const transformed = {
|
||||
...defaultQuery,
|
||||
...transformToForm(locationQuery, defaultQuery),
|
||||
};
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
}
|
||||
}
|
||||
...transformed,
|
||||
itemsIds: castArray(transformed.itemsIds),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Purchases by items query state.
|
||||
*/
|
||||
export const usePurchasesByItemsQuery = () => {
|
||||
// Retrieves location query.
|
||||
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||
|
||||
const query = React.useMemo(
|
||||
() => parsePurchasesByItemsQuery(locationQuery),
|
||||
[locationQuery],
|
||||
);
|
||||
return { query, locationQuery, setLocationQuery };
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React, { useEffect, useState, useCallback } from 'react';
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import moment from 'moment';
|
||||
|
||||
import { SalesByItemsBody } from './SalesByItemsBody';
|
||||
@@ -11,7 +11,7 @@ import SalesByItemsHeader from './SalesByItemsHeader';
|
||||
|
||||
import withSalesByItemsActions from './withSalesByItemsActions';
|
||||
|
||||
import { getDefaultSalesByItemsQuery } from './utils';
|
||||
import { useSalesByItemsQuery } from './utils';
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
@@ -21,9 +21,7 @@ function SalesByItems({
|
||||
// #withSellsByItemsActions
|
||||
toggleSalesByItemsFilterDrawer,
|
||||
}) {
|
||||
const [filter, setFilter] = useState({
|
||||
...getDefaultSalesByItemsQuery(),
|
||||
});
|
||||
const { query, setLocationQuery } = useSalesByItemsQuery();
|
||||
|
||||
// Handle filter form submit.
|
||||
const handleFilterSubmit = useCallback(
|
||||
@@ -33,30 +31,28 @@ function SalesByItems({
|
||||
fromDate: moment(filter.fromDate).format('YYYY-MM-DD'),
|
||||
toDate: moment(filter.toDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(parsedFilter);
|
||||
setLocationQuery(parsedFilter);
|
||||
},
|
||||
[setFilter],
|
||||
[setLocationQuery],
|
||||
);
|
||||
|
||||
// Handle number format form submit.
|
||||
const handleNumberFormatSubmit = (numberFormat) => {
|
||||
setFilter({
|
||||
setLocationQuery({
|
||||
...filter,
|
||||
numberFormat,
|
||||
});
|
||||
};
|
||||
// Hide the filter drawer once the page unmount.
|
||||
useEffect(
|
||||
() => () => {
|
||||
toggleSalesByItemsFilterDrawer(false);
|
||||
},
|
||||
() => () => toggleSalesByItemsFilterDrawer(false),
|
||||
[toggleSalesByItemsFilterDrawer],
|
||||
);
|
||||
|
||||
return (
|
||||
<SalesByItemProvider query={filter}>
|
||||
<SalesByItemProvider query={query}>
|
||||
<SalesByItemsActionsBar
|
||||
numberFormat={filter.numberFormat}
|
||||
numberFormat={query.numberFormat}
|
||||
onNumberFormatSubmit={handleNumberFormatSubmit}
|
||||
/>
|
||||
<SalesByItemsLoadingBar />
|
||||
@@ -64,7 +60,7 @@ function SalesByItems({
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement>
|
||||
<SalesByItemsHeader
|
||||
pageFilter={filter}
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit}
|
||||
/>
|
||||
<SalesByItemsBody />
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import moment from 'moment';
|
||||
import intl from 'react-intl-universal';
|
||||
import styled from 'styled-components';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
@@ -14,7 +12,11 @@ import SalesByItemsHeaderGeneralPanel from './SalesByItemsHeaderGeneralPanel';
|
||||
import withSalesByItems from './withSalesByItems';
|
||||
import withSalesByItemsActions from './withSalesByItemsActions';
|
||||
|
||||
import { compose } from '@/utils';
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import {
|
||||
getDefaultSalesByItemsQuery,
|
||||
getSalesByItemsQueryShema,
|
||||
} from './utils';
|
||||
|
||||
/**
|
||||
* Sales by items header.
|
||||
@@ -31,21 +33,22 @@ function SalesByItemsHeader({
|
||||
toggleSalesByItemsFilterDrawer,
|
||||
}) {
|
||||
// Form validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('from_date')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('to_date')),
|
||||
});
|
||||
const validationSchema = getSalesByItemsQueryShema();
|
||||
|
||||
const defaultQuery = getDefaultSalesByItemsQuery();
|
||||
|
||||
// Initial values.
|
||||
const initialValues = {
|
||||
...pageFilter,
|
||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||
toDate: moment(pageFilter.toDate).toDate(),
|
||||
};
|
||||
const initialValues = transformToForm(
|
||||
{
|
||||
...defaultQuery,
|
||||
...pageFilter,
|
||||
fromDate: moment(pageFilter.fromDate).toDate(),
|
||||
toDate: moment(pageFilter.toDate).toDate(),
|
||||
},
|
||||
defaultQuery,
|
||||
);
|
||||
|
||||
// Handle the form submitting.
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
onSubmitFilter(values);
|
||||
setSubmitting(false);
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||
import { Field } from 'formik';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { filterItemsOptions } from '../constants';
|
||||
import { Row, Col, ItemsMultiSelect, FormattedMessage as T } from '@/components';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
ItemsMultiSelect,
|
||||
FormattedMessage as T,
|
||||
FFormGroup,
|
||||
} from '@/components';
|
||||
import FinancialStatementDateRange from '../FinancialStatementDateRange';
|
||||
import FinancialStatementsFilter from '../FinancialStatementsFilter';
|
||||
import { filterItemsOptions } from '../constants';
|
||||
import {
|
||||
SalesByItemGeneralPanelProvider,
|
||||
useSalesByItemsGeneralPanelContext,
|
||||
@@ -46,22 +48,9 @@ function SalesByItemsHeaderGeneralPanelContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'itemsIds'}>
|
||||
{({ form: { setFieldValue }, field: { value } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup label={<T id={'Specific items'} />} name={'itemsIds'}>
|
||||
<ItemsMultiSelect name={'itemsIds'} items={items} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,63 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import * as Yup from 'yup';
|
||||
import intl from 'react-intl-universal';
|
||||
import { castArray } from 'lodash';
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { transformToForm } from '@/utils';
|
||||
|
||||
export const getDefaultSalesByItemsQuery = () => {
|
||||
/**
|
||||
* Retrieves the validation schema.
|
||||
* @returns {Yup}
|
||||
*/
|
||||
export const getSalesByItemsQueryShema = () => {
|
||||
return Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('from_date')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('to_date')),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the default query.
|
||||
*/
|
||||
export const getDefaultSalesByItemsQuery = () => ({
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
itemsIds: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* Parses sales by items query of browser location.
|
||||
*/
|
||||
const parseSalesByItemsQuery = (locationQuery) => {
|
||||
const defaultQuery = getDefaultSalesByItemsQuery();
|
||||
|
||||
const transformed = {
|
||||
...defaultQuery,
|
||||
...transformToForm(locationQuery, defaultQuery),
|
||||
};
|
||||
return {
|
||||
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
|
||||
toDate: moment().endOf('year').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
...transformed,
|
||||
itemsIds: castArray(transformed.itemsIds),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Sales by items query state.
|
||||
*/
|
||||
export const useSalesByItemsQuery = () => {
|
||||
// Retrieves location query.
|
||||
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||
|
||||
// Merges the default filter query with location URL query.
|
||||
const query = React.useMemo(
|
||||
() => parseSalesByItemsQuery(locationQuery),
|
||||
[locationQuery],
|
||||
);
|
||||
return { query, locationQuery, setLocationQuery };
|
||||
};
|
||||
|
||||
@@ -8,9 +8,9 @@ import { getColumnWidth } from '@/utils';
|
||||
import { CellTextSpan } from '@/components/Datatable/Cells';
|
||||
import { If, Icon, FormattedMessage as T } from '@/components';
|
||||
import { useTrialBalanceSheetContext } from './TrialBalanceProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the credit column.
|
||||
*/
|
||||
@@ -114,17 +114,19 @@ export function TrialBalanceSheetAlerts() {
|
||||
if (isLoading) {
|
||||
return null;
|
||||
}
|
||||
// Can't continue if the cost compute job is not running.
|
||||
if (!meta.is_cost_compute_running) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<If condition={meta.is_cost_compute_running}>
|
||||
<div class="alert-compute-running">
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
<FinancialComputeAlert>
|
||||
<Icon icon="info-block" iconSize={12} />
|
||||
<T id={'just_a_moment_we_re_calculating_your_cost_transactions'} />
|
||||
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</div>
|
||||
</If>
|
||||
<Button onClick={handleRecalcReport} minimal={true} small={true}>
|
||||
<T id={'refresh'} />
|
||||
</Button>
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { VendorBalanceSummaryBody } from './VendorsBalanceSummaryBody';
|
||||
|
||||
import withVendorsBalanceSummaryActions from './withVendorsBalanceSummaryActions';
|
||||
|
||||
import { getDefaultVendorsBalanceQuery } from './utils';
|
||||
import { useVendorsBalanceSummaryQuery } from './utils';
|
||||
import { compose } from '@/utils';
|
||||
|
||||
/**
|
||||
@@ -23,9 +23,7 @@ function VendorsBalanceSummary({
|
||||
// #withVendorsBalanceSummaryActions
|
||||
toggleVendorSummaryFilterDrawer,
|
||||
}) {
|
||||
const [filter, setFilter] = useState({
|
||||
...getDefaultVendorsBalanceQuery(),
|
||||
});
|
||||
const { query, setLocationQuery } = useVendorsBalanceSummaryQuery();
|
||||
|
||||
// Handle refetch vendors balance summary.
|
||||
const handleFilterSubmit = (filter) => {
|
||||
@@ -33,28 +31,26 @@ function VendorsBalanceSummary({
|
||||
...filter,
|
||||
asDate: moment(filter.asDate).format('YYYY-MM-DD'),
|
||||
};
|
||||
setFilter(_filter);
|
||||
setLocationQuery(_filter);
|
||||
};
|
||||
|
||||
// Handle number format submit.
|
||||
const handleNumberFormatSubmit = (format) => {
|
||||
setFilter({
|
||||
setLocationQuery({
|
||||
...filter,
|
||||
numberFormat: format,
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
toggleVendorSummaryFilterDrawer(false);
|
||||
},
|
||||
() => () => toggleVendorSummaryFilterDrawer(false),
|
||||
[toggleVendorSummaryFilterDrawer],
|
||||
);
|
||||
|
||||
return (
|
||||
<VendorsBalanceSummaryProvider filter={filter}>
|
||||
<VendorsBalanceSummaryProvider filter={query}>
|
||||
<VendorsBalanceSummaryActionsBar
|
||||
numberFormat={filter?.numberFormat}
|
||||
numberFormat={query?.numberFormat}
|
||||
onNumberFormatSubmit={handleNumberFormatSubmit}
|
||||
/>
|
||||
<VendorsSummarySheetLoadingBar />
|
||||
@@ -62,7 +58,7 @@ function VendorsBalanceSummary({
|
||||
<DashboardPageContent>
|
||||
<FinancialStatement>
|
||||
<VendorsBalanceSummaryHeader
|
||||
pageFilter={filter}
|
||||
pageFilter={query}
|
||||
onSubmitFilter={handleFilterSubmit}
|
||||
/>
|
||||
<VendorBalanceSummaryBody />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import moment from 'moment';
|
||||
import styled from 'styled-components';
|
||||
import { Formik, Form } from 'formik';
|
||||
@@ -13,6 +13,7 @@ import FinancialStatementHeader from '../FinancialStatementHeader';
|
||||
import VendorsBalanceSummaryHeaderGeneral from './VendorsBalanceSummaryHeaderGeneral';
|
||||
import withVendorsBalanceSummary from './withVendorsBalanceSummary';
|
||||
import withVendorsBalanceSummaryActions from './withVendorsBalanceSummaryActions';
|
||||
import { getVendorsBalanceQuerySchema } from './utils';
|
||||
|
||||
/**
|
||||
* Vendors balance summary drawer header.
|
||||
@@ -28,10 +29,8 @@ function VendorsBalanceSummaryHeader({
|
||||
//#withVendorsBalanceSummaryActions
|
||||
toggleVendorSummaryFilterDrawer,
|
||||
}) {
|
||||
// validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
});
|
||||
// Validation schema.
|
||||
const validationSchema = getVendorsBalanceQuerySchema();
|
||||
|
||||
// filter form initial values.
|
||||
const defaultValues = {
|
||||
@@ -80,6 +79,7 @@ function VendorsBalanceSummaryHeader({
|
||||
panel={<VendorsBalanceSummaryHeaderGeneral />}
|
||||
/>
|
||||
</Tabs>
|
||||
|
||||
<div className={'financial-header-drawer__footer'}>
|
||||
<Button className={'mr1'} intent={Intent.PRIMARY} type={'submit'}>
|
||||
<T id={'calculate_report'} />
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Field, FastField } from 'formik';
|
||||
import { FastField } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup, Position, Classes, Checkbox } from '@blueprintjs/core';
|
||||
import { FormGroup, Position, Checkbox } from '@blueprintjs/core';
|
||||
|
||||
import {
|
||||
ContactsMultiSelect,
|
||||
Row,
|
||||
Col,
|
||||
FieldHint,
|
||||
FormattedMessage as T,
|
||||
FFormGroup,
|
||||
VendorsMultiSelect,
|
||||
} from '@/components';
|
||||
import { filterVendorsOptions } from '../constants';
|
||||
|
||||
import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
@@ -87,22 +86,9 @@ export default function VendorsBalanceSummaryHeaderGeneralContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<Field name={'vendorsIds'}>
|
||||
{({ form: { setFieldValue } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'specific_vendors'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
items={vendors}
|
||||
onItemSelect={(contacts) => {
|
||||
const vendorsIds = contacts.map((contact) => contact.id);
|
||||
setFieldValue('vendorsIds', vendorsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup label={<T id={'specific_vendors'} />} name={'vendorsIds'}>
|
||||
<VendorsMultiSelect name={'vendorsIds'} items={vendors} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,44 @@
|
||||
// @ts-nocheck
|
||||
import moment from 'moment';
|
||||
import { useMemo } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { castArray } from 'lodash';
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { transformToForm } from '@/utils';
|
||||
|
||||
export const getDefaultVendorsBalanceQuery = () => {
|
||||
return {
|
||||
asDate: moment().endOf('day').format('YYYY-MM-DD'),
|
||||
filterByOption: 'with-transactions',
|
||||
vendorsIds: [],
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const getVendorsBalanceQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
asDate: Yup.date().required().label('asDate'),
|
||||
});
|
||||
};
|
||||
|
||||
export const parseVendorsBalanceSummaryQuery = (locationQuery) => {
|
||||
const defaultQuery = getDefaultVendorsBalanceQuery();
|
||||
|
||||
const transformed = {
|
||||
...defaultQuery,
|
||||
...transformToForm(locationQuery, defaultQuery),
|
||||
};
|
||||
return {
|
||||
...transformed,
|
||||
vendorsIds: castArray(transformed.vendorsIds),
|
||||
};
|
||||
};
|
||||
|
||||
export const useVendorsBalanceSummaryQuery = () => {
|
||||
const [locationQuery, setLocationQuery] = useAppQueryString();
|
||||
|
||||
const query = useMemo(
|
||||
() => parseVendorsBalanceSummaryQuery(locationQuery),
|
||||
[locationQuery],
|
||||
);
|
||||
return { query, locationQuery, setLocationQuery };
|
||||
};
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
import moment from 'moment';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Tabs, Tab, Button, Intent } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T } from '@/components';
|
||||
@@ -14,11 +13,14 @@ import withVendorsTransaction from './withVendorsTransaction';
|
||||
import withVendorsTransactionsActions from './withVendorsTransactionsActions';
|
||||
|
||||
import { compose, transformToForm } from '@/utils';
|
||||
import {
|
||||
getVendorTransactionsQuerySchema,
|
||||
getVendorsTransactionsDefaultQuery,
|
||||
} from './_utils';
|
||||
|
||||
/**
|
||||
* Vendors transactions header.
|
||||
*/
|
||||
|
||||
function VendorsTransactionsHeader({
|
||||
// #ownProps
|
||||
onSubmitFilter,
|
||||
@@ -31,12 +33,7 @@ function VendorsTransactionsHeader({
|
||||
toggleVendorsTransactionsFilterDrawer: toggleFilterDrawer,
|
||||
}) {
|
||||
// Default form values.
|
||||
const defaultValues = {
|
||||
...pageFilter,
|
||||
fromDate: moment().toDate(),
|
||||
toDate: moment().toDate(),
|
||||
vendorsIds: [],
|
||||
};
|
||||
const defaultValues = getVendorsTransactionsDefaultQuery();
|
||||
|
||||
// Initial form values.
|
||||
const initialValues = transformToForm(
|
||||
@@ -48,15 +45,8 @@ function VendorsTransactionsHeader({
|
||||
},
|
||||
defaultValues,
|
||||
);
|
||||
|
||||
// Validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('toDate')),
|
||||
});
|
||||
const validationSchema = getVendorTransactionsQuerySchema();
|
||||
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, { setSubmitting }) => {
|
||||
@@ -64,7 +54,6 @@ function VendorsTransactionsHeader({
|
||||
toggleFilterDrawer(false);
|
||||
setSubmitting(false);
|
||||
};
|
||||
|
||||
// Handle drawer close action.
|
||||
const handleDrawerClose = () => {
|
||||
toggleFilterDrawer(false);
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Field } from 'formik';
|
||||
import { Classes, FormGroup } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import FinancialStatementDateRange from '../FinancialStatementDateRange';
|
||||
import FinancialStatementsFilter from '../FinancialStatementsFilter';
|
||||
@@ -10,8 +7,9 @@ import FinancialStatementsFilter from '../FinancialStatementsFilter';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
ContactsMultiSelect,
|
||||
FormattedMessage as T,
|
||||
FFormGroup,
|
||||
VendorsMultiSelect,
|
||||
} from '@/components';
|
||||
import { filterVendorsOptions } from '../constants';
|
||||
|
||||
@@ -53,22 +51,9 @@ function VendorsTransactionsHeaderGeneralPanelContent() {
|
||||
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'vendorsIds'}>
|
||||
{({ form: { setFieldValue }, field: { value } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'specific_vendors'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
items={vendors}
|
||||
onItemSelect={(vendors) => {
|
||||
const vendorsIds = vendors.map((customer) => customer.id);
|
||||
setFieldValue('vendorsIds', vendorsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
<FFormGroup label={<T id={'specific_vendors'} />} name={'vendorsIds'}>
|
||||
<VendorsMultiSelect name={'vendorsIds'} items={vendors} />
|
||||
</FFormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import * as Yup from 'yup';
|
||||
import intl from 'react-intl-universal';
|
||||
import moment from 'moment';
|
||||
|
||||
/**
|
||||
* The validation schema of vendors transactions.
|
||||
*/
|
||||
export const getVendorTransactionsQuerySchema = () => {
|
||||
return Yup.object().shape({
|
||||
fromDate: Yup.date().required().label(intl.get('fromDate')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
.label(intl.get('toDate')),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the default query of vendors transactions.
|
||||
*/
|
||||
export const getVendorsTransactionsDefaultQuery = () => ({
|
||||
fromDate: moment().toDate(),
|
||||
toDate: moment().toDate(),
|
||||
vendorsIds: [],
|
||||
});
|
||||
@@ -9,6 +9,7 @@ import { compose } from '@/utils';
|
||||
|
||||
let toastKeySessionExpired;
|
||||
let toastKeySomethingWrong;
|
||||
let toastTooManyRequests;
|
||||
|
||||
function GlobalErrors({
|
||||
// #withGlobalErrors
|
||||
@@ -41,6 +42,18 @@ function GlobalErrors({
|
||||
toastKeySomethingWrong,
|
||||
);
|
||||
}
|
||||
if (globalErrors.too_many_requests) {
|
||||
toastTooManyRequests = AppToaster.show(
|
||||
{
|
||||
message: intl.get('global_error.too_many_requests'),
|
||||
intent: Intent.DANGER,
|
||||
onDismiss: () => {
|
||||
globalErrorsSet({ too_many_requests: false });
|
||||
},
|
||||
},
|
||||
toastTooManyRequests,
|
||||
);
|
||||
}
|
||||
if (globalErrors.access_denied) {
|
||||
toastKeySomethingWrong = AppToaster.show(
|
||||
{
|
||||
|
||||
@@ -82,7 +82,6 @@ function BillForm({
|
||||
isNewMode
|
||||
? 'the_bill_has_been_created_successfully'
|
||||
: 'the_bill_has_been_edited_successfully',
|
||||
{ number: values.bill_number },
|
||||
),
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import {
|
||||
Alignment,
|
||||
NavbarGroup,
|
||||
NavbarDivider,
|
||||
Button,
|
||||
Classes,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
@@ -14,12 +12,13 @@ import {
|
||||
} from './utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
WarehouseSelect,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormWarehouseSelectButton,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { useBillFormContext } from './BillFormProvider';
|
||||
import { Features } from '@/constants';
|
||||
@@ -70,8 +69,9 @@ function BillFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={BillBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -86,30 +86,9 @@ function BillFormSelectWarehouse() {
|
||||
<WarehouseSelect
|
||||
name={'warehouse_id'}
|
||||
warehouses={warehouses}
|
||||
input={BillWarehouseSelectButton}
|
||||
input={FormWarehouseSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function BillWarehouseSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('bill.warehouse_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function BillBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('bill.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,6 @@ function VendorCreditNoteFormHeaderFields({
|
||||
name={'exchange_rate'}
|
||||
formGroupProps={{ label: ' ', inline: true }}
|
||||
/>
|
||||
|
||||
{/* ------- Vendor Credit date ------- */}
|
||||
<FastField name={'vendor_credit_date'}>
|
||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import {
|
||||
Alignment,
|
||||
NavbarGroup,
|
||||
@@ -20,6 +19,8 @@ import {
|
||||
WarehouseSelect,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormWarehouseSelectButton,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { useVendorCreditNoteFormContext } from './VendorCreditNoteFormProvider';
|
||||
import { Features } from '@/constants';
|
||||
@@ -70,8 +71,9 @@ function VendorCreditNoteFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={VendorCreditNoteBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -86,30 +88,9 @@ function VendorCreditFormSelectWarehouse() {
|
||||
<WarehouseSelect
|
||||
name={'warehouse_id'}
|
||||
warehouses={warehouses}
|
||||
input={VendorCreditNoteWarehouseSelectButton}
|
||||
input={FormWarehouseSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function VendorCreditNoteWarehouseSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('vendor_credit.warehouse_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function VendorCreditNoteBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('vendor_credit.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,12 +13,14 @@ export function PaymentMadeFormFooterLeft() {
|
||||
<React.Fragment>
|
||||
{/* --------- Internal Note--------- */}
|
||||
<InternalNoteFormGroup
|
||||
name={'internal_note'}
|
||||
name={'statement'}
|
||||
label={<T id={'payment_made.form.internal_note.label'} />}
|
||||
fastField={true}
|
||||
>
|
||||
<FEditableText
|
||||
name={'internal_note'}
|
||||
name={'statement'}
|
||||
placeholder={intl.get('payment_made.form.internal_note.placeholder')}
|
||||
fastField={true}
|
||||
/>
|
||||
</InternalNoteFormGroup>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Alignment, NavbarGroup, Button, Classes } from '@blueprintjs/core';
|
||||
import { Alignment, NavbarGroup, Classes } from '@blueprintjs/core';
|
||||
import { useSetPrimaryBranchToForm } from './utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { usePaymentMadeFormContext } from './PaymentMadeFormProvider';
|
||||
import { Features } from '@/constants';
|
||||
@@ -50,19 +49,9 @@ function PaymentMadeFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={PaymentMadeBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function PaymentMadeBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('payment_made.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
|
||||
import {
|
||||
Alignment,
|
||||
NavbarGroup,
|
||||
NavbarDivider,
|
||||
Button,
|
||||
Classes,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
@@ -15,12 +14,13 @@ import {
|
||||
import { Features } from '@/constants';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
WarehouseSelect,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormWarehouseSelectButton,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { useCreditNoteFormContext } from './CreditNoteFormProvider';
|
||||
|
||||
@@ -70,8 +70,9 @@ function CreditNoteFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={CreditNoteBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -86,30 +87,9 @@ function CreditFormSelectWarehouse() {
|
||||
<WarehouseSelect
|
||||
name={'warehouse_id'}
|
||||
warehouses={warehouses}
|
||||
input={CreditNoteWarehouseSelectButton}
|
||||
input={FormWarehouseSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function CreditNoteWarehouseSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('credit_note.warehouse_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function CreditNoteBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('credit_note.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import {
|
||||
Alignment,
|
||||
NavbarGroup,
|
||||
NavbarDivider,
|
||||
Button,
|
||||
Classes,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
@@ -15,12 +13,13 @@ import {
|
||||
import { Features } from '@/constants';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
WarehouseSelect,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormWarehouseSelectButton,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { useEstimateFormContext } from './EstimateFormProvider';
|
||||
|
||||
@@ -70,8 +69,9 @@ function EstimateFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={EstimateBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -86,30 +86,9 @@ function EstimateFormSelectWarehouse() {
|
||||
<WarehouseSelect
|
||||
name={'warehouse_id'}
|
||||
warehouses={warehouses}
|
||||
input={EstimateWarehouseSelectButton}
|
||||
input={FormWarehouseSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function EstimateWarehouseSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('estimate.warehouse_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function EstimateBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('estimate.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
Alignment,
|
||||
NavbarGroup,
|
||||
NavbarDivider,
|
||||
Button,
|
||||
Classes,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
@@ -18,11 +16,12 @@ import { Features } from '@/constants';
|
||||
import { useInvoiceFormContext } from './InvoiceFormProvider';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
WarehouseSelect,
|
||||
FormTopbar,
|
||||
FormWarehouseSelectButton,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
|
||||
/**
|
||||
@@ -70,8 +69,9 @@ function InvoiceFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={InvoiceBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -86,30 +86,9 @@ function InvoiceFormSelectWarehouse() {
|
||||
<WarehouseSelect
|
||||
name={'warehouse_id'}
|
||||
warehouses={warehouses}
|
||||
input={InvoiceWarehouseSelectButton}
|
||||
input={FormWarehouseSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function InvoiceWarehouseSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('invoice.warehouse_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function InvoiceBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('invoice.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,25 +7,18 @@ import { FFormGroup, FEditableText, FormattedMessage as T } from '@/components';
|
||||
export function PaymentReceiveFormFootetLeft() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{/* --------- Statement--------- */}
|
||||
<PaymentMsgFormGroup
|
||||
name={'message'}
|
||||
label={<T id={'payment_receive_form.message.label'} />}
|
||||
>
|
||||
<FEditableText
|
||||
name={'message'}
|
||||
placeholder={intl.get('payment_receive_form.message.placeholder')}
|
||||
/>
|
||||
</PaymentMsgFormGroup>
|
||||
|
||||
{/* --------- Internal Note--------- */}
|
||||
<TermsConditsFormGroup
|
||||
name={'internal_note'}
|
||||
name={'statement'}
|
||||
label={<T id={'payment_receive_form.label.note'} />}
|
||||
fastField={true}
|
||||
>
|
||||
<FEditableText
|
||||
name={'internal_note'}
|
||||
placeholder={intl.get('payment_receive_form.internal_note.placeholder')}
|
||||
name={'statement'}
|
||||
placeholder={intl.get(
|
||||
'payment_receive_form.internal_note.placeholder',
|
||||
)}
|
||||
fastField={true}
|
||||
/>
|
||||
</TermsConditsFormGroup>
|
||||
</React.Fragment>
|
||||
@@ -43,17 +36,3 @@ const TermsConditsFormGroup = styled(FFormGroup)`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const PaymentMsgFormGroup = styled(FFormGroup)`
|
||||
&.bp3-form-group {
|
||||
margin-bottom: 40px;
|
||||
|
||||
.bp3-label {
|
||||
font-size: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.bp3-form-content {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Alignment, NavbarGroup, Button, Classes } from '@blueprintjs/core';
|
||||
import { Alignment, NavbarGroup, Classes } from '@blueprintjs/core';
|
||||
import { useSetPrimaryBranchToForm } from './utils';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormBranchSelectButton,
|
||||
} from '@/components';
|
||||
import { usePaymentReceiveFormContext } from './PaymentReceiveFormProvider';
|
||||
import { Features } from '@/constants';
|
||||
|
||||
/**
|
||||
* Payment receive from top bar.
|
||||
* @returns
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export default function PaymentReceiveFormTopBar() {
|
||||
// Features guard.
|
||||
@@ -29,7 +28,6 @@ export default function PaymentReceiveFormTopBar() {
|
||||
if (!featureCan(Features.Branches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<FormTopbar>
|
||||
<NavbarGroup align={Alignment.LEFT}>
|
||||
@@ -41,6 +39,10 @@ export default function PaymentReceiveFormTopBar() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Branch select of payment receive form.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
function PaymentReceiveFormSelectBranch() {
|
||||
// payment receive form context.
|
||||
const { branches, isBranchesLoading } = usePaymentReceiveFormContext();
|
||||
@@ -51,19 +53,9 @@ function PaymentReceiveFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={PaymentReceiveBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function PaymentReceiveBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('payment_receive.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
Alignment,
|
||||
NavbarGroup,
|
||||
NavbarDivider,
|
||||
Button,
|
||||
Classes,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
@@ -18,12 +15,13 @@ import { Features } from '@/constants';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { useReceiptFormContext } from './ReceiptFormProvider';
|
||||
import {
|
||||
Icon,
|
||||
BranchSelect,
|
||||
FeatureCan,
|
||||
WarehouseSelect,
|
||||
FormTopbar,
|
||||
DetailsBarSkeletonBase,
|
||||
FormBranchSelectButton,
|
||||
FormWarehouseSelectButton,
|
||||
} from '@/components';
|
||||
|
||||
/**
|
||||
@@ -76,8 +74,9 @@ function ReceiptFormSelectBranch() {
|
||||
<BranchSelect
|
||||
name={'branch_id'}
|
||||
branches={branches}
|
||||
input={ReceiptBranchSelectButton}
|
||||
input={FormBranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -96,30 +95,9 @@ function ReceiptFormSelectWarehouse() {
|
||||
<WarehouseSelect
|
||||
name={'warehouse_id'}
|
||||
warehouses={warehouses}
|
||||
input={ReceiptWarehouseSelectButton}
|
||||
input={FormWarehouseSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function ReceiptBranchSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('receipt.branch_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'branch-16'} iconSize={16} />}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
function ReceiptWarehouseSelectButton({ label }) {
|
||||
return (
|
||||
<Button
|
||||
text={intl.get('receipt.warehouse_button.label', { label })}
|
||||
minimal={true}
|
||||
small={true}
|
||||
icon={<Icon icon={'warehouse-16'} iconSize={16} />}
|
||||
fill={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
InputPrependText,
|
||||
CurrencySelectList,
|
||||
BranchSelect,
|
||||
BranchSelectButton,
|
||||
FeatureCan,
|
||||
Row,
|
||||
Col,
|
||||
@@ -75,12 +74,10 @@ export default function VendorFinanicalPanelTab() {
|
||||
label={<T id={'vendor.label.opening_branch'} />}
|
||||
name={'opening_balance_branch_id'}
|
||||
inline={true}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<BranchSelect
|
||||
name={'opening_balance_branch_id'}
|
||||
branches={branches}
|
||||
input={BranchSelectButton}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FFormGroup>
|
||||
|
||||
Reference in New Issue
Block a user