mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 07:10:33 +00:00
fix: add bank rule categories
This commit is contained in:
@@ -39,3 +39,12 @@ export const TRANSACRIONS_TYPE = [
|
|||||||
'OtherExpense',
|
'OtherExpense',
|
||||||
'TransferToAccount',
|
'TransferToAccount',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const MoneyCategoryPerCreditAccountRootType = {
|
||||||
|
OwnerContribution: ['equity'],
|
||||||
|
OtherIncome: ['income'],
|
||||||
|
OwnerDrawing: ['equity'],
|
||||||
|
OtherExpense: ['expense'],
|
||||||
|
TransferToAccount: ['asset'],
|
||||||
|
TransferFromAccount: ['asset'],
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
import { Form, Formik, FormikHelpers, useFormikContext } from 'formik';
|
import { Form, Formik, FormikHelpers, useFormikContext } from 'formik';
|
||||||
import { Button, Classes, Intent, Radio, Tag } from '@blueprintjs/core';
|
import { Button, Classes, Intent, Radio, Tag } from '@blueprintjs/core';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
@@ -16,11 +17,11 @@ import {
|
|||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { useCreateBankRule, useEditBankRule } from '@/hooks/query/bank-rules';
|
import { useCreateBankRule, useEditBankRule } from '@/hooks/query/bank-rules';
|
||||||
import {
|
import {
|
||||||
AssignTransactionTypeOptions,
|
|
||||||
FieldCondition,
|
FieldCondition,
|
||||||
Fields,
|
Fields,
|
||||||
RuleFormValues,
|
RuleFormValues,
|
||||||
TransactionTypeOptions,
|
TransactionTypeOptions,
|
||||||
|
getAccountRootFromMoneyCategory,
|
||||||
initialValues,
|
initialValues,
|
||||||
} from './_utils';
|
} from './_utils';
|
||||||
import { useRuleFormDialogBoot } from './RuleFormBoot';
|
import { useRuleFormDialogBoot } from './RuleFormBoot';
|
||||||
@@ -31,6 +32,11 @@ import {
|
|||||||
} from '@/utils';
|
} from '@/utils';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import { getAddMoneyInOptions, getAddMoneyOutOptions } from '@/constants';
|
||||||
|
|
||||||
|
// Retrieves the add money in button options.
|
||||||
|
const MoneyInOptions = getAddMoneyInOptions();
|
||||||
|
const MoneyOutOptions = getAddMoneyOutOptions();
|
||||||
|
|
||||||
function RuleFormContentFormRoot({
|
function RuleFormContentFormRoot({
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
@@ -47,7 +53,6 @@ function RuleFormContentFormRoot({
|
|||||||
...initialValues,
|
...initialValues,
|
||||||
...transformToForm(transformToCamelCase(bankRule), initialValues),
|
...transformToForm(transformToCamelCase(bankRule), initialValues),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handles the form submitting.
|
// Handles the form submitting.
|
||||||
const handleSubmit = (
|
const handleSubmit = (
|
||||||
values: RuleFormValues,
|
values: RuleFormValues,
|
||||||
@@ -92,8 +97,9 @@ function RuleFormContentFormRoot({
|
|||||||
label={'Rule Name'}
|
label={'Rule Name'}
|
||||||
labelInfo={<Tag minimal>Required</Tag>}
|
labelInfo={<Tag minimal>Required</Tag>}
|
||||||
style={{ maxWidth: 300 }}
|
style={{ maxWidth: 300 }}
|
||||||
|
fastField
|
||||||
>
|
>
|
||||||
<FInputGroup name={'name'} />
|
<FInputGroup name={'name'} fastField />
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
<FFormGroup
|
<FFormGroup
|
||||||
@@ -101,29 +107,22 @@ function RuleFormContentFormRoot({
|
|||||||
label={'Apply the rule to account'}
|
label={'Apply the rule to account'}
|
||||||
labelInfo={<Tag minimal>Required</Tag>}
|
labelInfo={<Tag minimal>Required</Tag>}
|
||||||
style={{ maxWidth: 350 }}
|
style={{ maxWidth: 350 }}
|
||||||
|
fastField
|
||||||
>
|
>
|
||||||
<AccountsSelect
|
<AccountsSelect
|
||||||
name={'applyIfAccountId'}
|
name={'applyIfAccountId'}
|
||||||
items={accounts}
|
items={accounts}
|
||||||
filterByTypes={['cash', 'bank']}
|
filterByTypes={['cash', 'bank']}
|
||||||
|
fastField
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
<FFormGroup
|
<RuleApplyIfTransactionTypeField />
|
||||||
name={'applyIfTransactionType'}
|
|
||||||
label={'Apply to transactions are'}
|
|
||||||
style={{ maxWidth: 350 }}
|
|
||||||
>
|
|
||||||
<FSelect
|
|
||||||
name={'applyIfTransactionType'}
|
|
||||||
items={TransactionTypeOptions}
|
|
||||||
popoverProps={{ minimal: true, inline: false }}
|
|
||||||
/>
|
|
||||||
</FFormGroup>
|
|
||||||
|
|
||||||
<FFormGroup
|
<FFormGroup
|
||||||
name={'conditionsType'}
|
name={'conditionsType'}
|
||||||
label={'Categorize the transactions when'}
|
label={'Categorize the transactions when'}
|
||||||
|
fastField
|
||||||
>
|
>
|
||||||
<FRadioGroup name={'conditionsType'}>
|
<FRadioGroup name={'conditionsType'}>
|
||||||
<Radio value={'and'} label={'All the following criteria matches'} />
|
<Radio value={'and'} label={'All the following criteria matches'} />
|
||||||
@@ -139,34 +138,16 @@ function RuleFormContentFormRoot({
|
|||||||
Then Assign
|
Then Assign
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<FFormGroup
|
<RuleAssignCategoryField />
|
||||||
name={'assignCategory'}
|
<RuleAssignCategoryAccountField />
|
||||||
label={'Transaction type'}
|
|
||||||
labelInfo={<Tag minimal>Required</Tag>}
|
|
||||||
style={{ maxWidth: 300 }}
|
|
||||||
>
|
|
||||||
<FSelect
|
|
||||||
name={'assignCategory'}
|
|
||||||
items={AssignTransactionTypeOptions}
|
|
||||||
popoverProps={{ minimal: true, inline: false }}
|
|
||||||
/>
|
|
||||||
</FFormGroup>
|
|
||||||
|
|
||||||
<FFormGroup
|
|
||||||
name={'assignAccountId'}
|
|
||||||
label={'Account category'}
|
|
||||||
labelInfo={<Tag minimal>Required</Tag>}
|
|
||||||
style={{ maxWidth: 300 }}
|
|
||||||
>
|
|
||||||
<AccountsSelect name={'assignAccountId'} items={accounts} />
|
|
||||||
</FFormGroup>
|
|
||||||
|
|
||||||
<FFormGroup
|
<FFormGroup
|
||||||
name={'assignRef'}
|
name={'assignRef'}
|
||||||
label={'Reference'}
|
label={'Reference'}
|
||||||
style={{ maxWidth: 300 }}
|
style={{ maxWidth: 300 }}
|
||||||
|
fastField
|
||||||
>
|
>
|
||||||
<FInputGroup name={'assignRef'} />
|
<FInputGroup name={'assignRef'} fastField />
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
<RuleFormActions />
|
<RuleFormActions />
|
||||||
@@ -203,11 +184,13 @@ function RuleFormConditions() {
|
|||||||
name={`conditions[${index}].field`}
|
name={`conditions[${index}].field`}
|
||||||
label={'Field'}
|
label={'Field'}
|
||||||
style={{ marginBottom: 0, flex: '1 0' }}
|
style={{ marginBottom: 0, flex: '1 0' }}
|
||||||
|
fastField
|
||||||
>
|
>
|
||||||
<FSelect
|
<FSelect
|
||||||
name={`conditions[${index}].field`}
|
name={`conditions[${index}].field`}
|
||||||
items={Fields}
|
items={Fields}
|
||||||
popoverProps={{ minimal: true, inline: false }}
|
popoverProps={{ minimal: true, inline: false }}
|
||||||
|
fastField
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
@@ -215,11 +198,13 @@ function RuleFormConditions() {
|
|||||||
name={`conditions[${index}].comparator`}
|
name={`conditions[${index}].comparator`}
|
||||||
label={'Condition'}
|
label={'Condition'}
|
||||||
style={{ marginBottom: 0, flex: '1 0' }}
|
style={{ marginBottom: 0, flex: '1 0' }}
|
||||||
|
fastField
|
||||||
>
|
>
|
||||||
<FSelect
|
<FSelect
|
||||||
name={`conditions[${index}].comparator`}
|
name={`conditions[${index}].comparator`}
|
||||||
items={FieldCondition}
|
items={FieldCondition}
|
||||||
popoverProps={{ minimal: true, inline: false }}
|
popoverProps={{ minimal: true, inline: false }}
|
||||||
|
fastField
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
@@ -227,8 +212,9 @@ function RuleFormConditions() {
|
|||||||
name={`conditions[${index}].value`}
|
name={`conditions[${index}].value`}
|
||||||
label={'Value'}
|
label={'Value'}
|
||||||
style={{ marginBottom: 0, flex: '1 0 ', width: '40%' }}
|
style={{ marginBottom: 0, flex: '1 0 ', width: '40%' }}
|
||||||
|
fastField
|
||||||
>
|
>
|
||||||
<FInputGroup name={`conditions[${index}].value`} />
|
<FInputGroup name={`conditions[${index}].value`} fastField />
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
</Group>
|
</Group>
|
||||||
))}
|
))}
|
||||||
@@ -284,3 +270,104 @@ function RuleFormActionsRoot({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RuleFormActions = R.compose(withDialogActions)(RuleFormActionsRoot);
|
const RuleFormActions = R.compose(withDialogActions)(RuleFormActionsRoot);
|
||||||
|
|
||||||
|
function RuleApplyIfTransactionTypeField() {
|
||||||
|
const { setFieldValue } = useFormikContext<RuleFormValues>();
|
||||||
|
|
||||||
|
const handleItemChange = useCallback(
|
||||||
|
(item: any) => {
|
||||||
|
setFieldValue('applyIfTransactionType', item.value);
|
||||||
|
setFieldValue('assignCategory', '');
|
||||||
|
setFieldValue('assignAccountId', '');
|
||||||
|
},
|
||||||
|
[setFieldValue],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'applyIfTransactionType'}
|
||||||
|
label={'Apply to transactions are'}
|
||||||
|
style={{ maxWidth: 350 }}
|
||||||
|
fastField
|
||||||
|
>
|
||||||
|
<FSelect
|
||||||
|
name={'applyIfTransactionType'}
|
||||||
|
items={TransactionTypeOptions}
|
||||||
|
popoverProps={{ minimal: true, inline: false }}
|
||||||
|
onItemChange={handleItemChange}
|
||||||
|
fastField
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RuleAssignCategoryField() {
|
||||||
|
const { values, setFieldValue } = useFormikContext<RuleFormValues>();
|
||||||
|
|
||||||
|
// Retrieves the transaction types if it is deposit or withdrawal.
|
||||||
|
const transactionTypes = useMemo(
|
||||||
|
() =>
|
||||||
|
values?.applyIfTransactionType === 'deposit'
|
||||||
|
? MoneyInOptions
|
||||||
|
: MoneyOutOptions,
|
||||||
|
[values?.applyIfTransactionType],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Handles the select item change.
|
||||||
|
const handleItemChange = useCallback(
|
||||||
|
(item: any) => {
|
||||||
|
setFieldValue('assignCategory', item.value);
|
||||||
|
setFieldValue('assignAccountId', '');
|
||||||
|
},
|
||||||
|
[setFieldValue],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'assignCategory'}
|
||||||
|
label={'Transaction type'}
|
||||||
|
labelInfo={<Tag minimal>Required</Tag>}
|
||||||
|
style={{ maxWidth: 300 }}
|
||||||
|
fastField
|
||||||
|
>
|
||||||
|
<FSelect
|
||||||
|
name={'assignCategory'}
|
||||||
|
items={transactionTypes}
|
||||||
|
popoverProps={{ minimal: true, inline: false }}
|
||||||
|
valueAccessor={'value'}
|
||||||
|
textAccessor={'name'}
|
||||||
|
onItemChange={handleItemChange}
|
||||||
|
fastField
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function RuleAssignCategoryAccountField() {
|
||||||
|
const { values } = useFormikContext<RuleFormValues>();
|
||||||
|
const { accounts } = useRuleFormDialogBoot();
|
||||||
|
|
||||||
|
const accountRoot = useMemo(
|
||||||
|
() => getAccountRootFromMoneyCategory(values.assignCategory),
|
||||||
|
[values.assignCategory],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'assignAccountId'}
|
||||||
|
label={'Account category'}
|
||||||
|
labelInfo={<Tag minimal>Required</Tag>}
|
||||||
|
style={{ maxWidth: 300 }}
|
||||||
|
fastField
|
||||||
|
shouldUpdateDeps={{ accountRoot }}
|
||||||
|
>
|
||||||
|
<AccountsSelect
|
||||||
|
name={'assignAccountId'}
|
||||||
|
items={accounts}
|
||||||
|
filterByRootTypes={accountRoot}
|
||||||
|
shouldUpdateDeps={{ accountRoot }}
|
||||||
|
fastField
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
|
import { camelCase, get, upperFirst } from 'lodash';
|
||||||
|
import { MoneyCategoryPerCreditAccountRootType } from '@/constants/cashflowOptions';
|
||||||
|
|
||||||
export const initialValues = {
|
export const initialValues = {
|
||||||
name: '',
|
name: '',
|
||||||
order: 0,
|
order: 0,
|
||||||
applyIfAccountId: '',
|
applyIfAccountId: '',
|
||||||
applyIfTransactionType: '',
|
applyIfTransactionType: 'deposit',
|
||||||
conditionsType: 'and',
|
conditionsType: 'and',
|
||||||
conditions: [
|
conditions: [
|
||||||
{
|
{
|
||||||
@@ -47,3 +50,9 @@ export const FieldCondition = [
|
|||||||
export const AssignTransactionTypeOptions = [
|
export const AssignTransactionTypeOptions = [
|
||||||
{ value: 'expense', text: 'Expense' },
|
{ value: 'expense', text: 'Expense' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const getAccountRootFromMoneyCategory = (category: string): string[] => {
|
||||||
|
const _category = upperFirst(camelCase(category));
|
||||||
|
|
||||||
|
return get(MoneyCategoryPerCreditAccountRootType, _category) || [];
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user