feat(accoutant) : accountant preference.

This commit is contained in:
elforjani3
2021-03-22 17:21:33 +02:00
parent b492224a83
commit 09c295f62c
6 changed files with 213 additions and 46 deletions

View File

@@ -3,8 +3,10 @@ import * as Yup from 'yup';
const Schema = Yup.object().shape({ const Schema = Yup.object().shape({
accounting_basis: Yup.string().required(), accounting_basis: Yup.string().required(),
account_code_required: Yup.boolean(), account_code_required: Yup.boolean(),
customer_deposit_account: Yup.number().nullable(), account_code_unique: Yup.boolean(),
vendor_withdrawal_account: Yup.number().nullable(), deposit_account: Yup.number().nullable(),
withdrawal_account: Yup.number().nullable(),
advance_deposit: Yup.number().nullable(),
}); });
export const AccountantSchema = Schema; export const AccountantSchema = Schema;

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Form, FastField, Field } from 'formik'; import { Form, FastField, useFormikContext } from 'formik';
import { import {
FormGroup, FormGroup,
RadioGroup, RadioGroup,
@@ -9,20 +9,20 @@ import {
Intent, Intent,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { AccountsSelectList } from 'components'; import { AccountsSelectList, FieldRequiredHint } from 'components';
import { FieldRequiredHint } from 'components';
import { FormattedMessage as T, useIntl } from 'react-intl'; import { FormattedMessage as T, useIntl } from 'react-intl';
// import { } from 'common/accountTypes'; import { ACCOUNT_PARENT_TYPE } from 'common/accountTypes';
import { handleStringChange, saveInvoke } from 'utils'; import { handleStringChange, inputIntent } from 'utils';
import { useAccountantFormContext } from './AccountantFormProvider'; import { useAccountantFormContext } from './AccountantFormProvider';
export default function AccountantForm() { export default function AccountantForm() {
const history = useHistory(); const history = useHistory();
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const { isSubmitting } = useFormikContext();
const handleCloseClick = () => { const handleCloseClick = () => {
history.go(-1); history.go(-1);
}; };
@@ -38,26 +38,60 @@ export default function AccountantForm() {
<T id={'accounts'} /> <T id={'accounts'} />
</strong> </strong>
} }
className={'accounts-checkbox'}
> >
<Checkbox {/*------------ account code required -----------*/}
label={'Make account code required when create a new accounts.'} <FastField name={'account_code_required'} type={'checkbox'}>
/> {({ field }) => (
<Checkbox <FormGroup inline={true}>
label={'Should account code be unique when create a new account.'} <Checkbox
/> inline={true}
label={'Make account code required when create a new accounts.'}
name={'account_code_required'}
{...field}
/>
</FormGroup>
)}
</FastField>
{/*------------ account code unique -----------*/}
<FastField name={'account_code_unique'} type={'checkbox'}>
{({ field }) => (
<FormGroup inline={true}>
<Checkbox
inline={true}
label={
'Should account code be unique when create a new account.'
}
name={'account_code_unique'}
{...field}
/>
</FormGroup>
)}
</FastField>
</FormGroup> </FormGroup>
{/* ----------- Accounting basis ----------- */} {/* ----------- Accounting basis ----------- */}
<FastField name={'accounting_basis'}> <FastField name={'accounting_basis'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({
form: { setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup <FormGroup
labelInfo={<FieldRequiredHint />} labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
label={ label={
<strong> <strong>
<T id={'accounting_basis_'} /> <T id={'accounting_basis_'} />
</strong> </strong>
} }
> >
<RadioGroup inline={true}> <RadioGroup
inline={true}
selectedValue={value}
onChange={handleStringChange((_value) => {
setFieldValue('accounting_basis', _value);
})}
>
<Radio label={formatMessage({ id: 'Cash' })} value="cash" /> <Radio label={formatMessage({ id: 'Cash' })} value="cash" />
<Radio label={formatMessage({ id: 'accrual' })} value="accrual" /> <Radio label={formatMessage({ id: 'accrual' })} value="accrual" />
</RadioGroup> </RadioGroup>
@@ -66,8 +100,12 @@ export default function AccountantForm() {
</FastField> </FastField>
{/* ----------- Deposit customer account ----------- */} {/* ----------- Deposit customer account ----------- */}
<FastField name={'deposit_customer_account'}> <FastField name={'deposit_account'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({
form: { values, setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup <FormGroup
label={ label={
<strong> <strong>
@@ -78,20 +116,28 @@ export default function AccountantForm() {
'Select a preferred account to deposit into it after customer make payment.' 'Select a preferred account to deposit into it after customer make payment.'
} }
labelInfo={<FieldRequiredHint />} labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
> >
<AccountsSelectList <AccountsSelectList
accounts={accounts} accounts={accounts}
// onAccountSelected onAccountSelected={({ id }) => {
setFieldValue('deposit_account', id);
}}
selectedAccountId={value}
defaultSelectText={<T id={'select_payment_account'} />} defaultSelectText={<T id={'select_payment_account'} />}
// filterByTypes={['current_asset']} // filterByParentTypes={[ACCOUNT_PARENT_TYPE.CURRENT_ASSET]}
/> />
</FormGroup> </FormGroup>
)} )}
</FastField> </FastField>
{/* ----------- Withdrawal customer account ----------- */} {/* ----------- Withdrawal vendor account ----------- */}
<FastField name={'withdrawal_customer_account'}> <FastField name={'withdrawal_account'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({
form: { values, setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup <FormGroup
label={ label={
<strong> <strong>
@@ -102,19 +148,27 @@ export default function AccountantForm() {
'Select a preferred account to deposit into it after customer make payment.' 'Select a preferred account to deposit into it after customer make payment.'
} }
labelInfo={<FieldRequiredHint />} labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
> >
<AccountsSelectList <AccountsSelectList
accounts={accounts} accounts={accounts}
onAccountSelected={({ id }) => {
setFieldValue('withdrawal_account', id);
}}
selectedAccountId={value}
defaultSelectText={<T id={'select_payment_account'} />} defaultSelectText={<T id={'select_payment_account'} />}
// filterByTypes={['current_asset']}
/> />
</FormGroup> </FormGroup>
)} )}
</FastField> </FastField>
{/* ----------- Withdrawal customer account ----------- */} {/* ----------- Withdrawal customer account ----------- */}
<FastField name={'vendor_advance_deposit'}> <FastField name={'advance_deposit'}>
{({ form, field: { value }, meta: { error, touched } }) => ( {({
form: { values, setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup <FormGroup
label={ label={
<strong> <strong>
@@ -125,17 +179,23 @@ export default function AccountantForm() {
'Select a preferred account to deposit into it vendor advanced deposits.' 'Select a preferred account to deposit into it vendor advanced deposits.'
} }
labelInfo={<FieldRequiredHint />} labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
> >
<AccountsSelectList <AccountsSelectList
accounts={accounts} accounts={accounts}
onAccountSelected={({ id }) => {
setFieldValue('advance_deposit', id);
}}
selectedAccountId={value}
defaultSelectText={<T id={'select_payment_account'} />} defaultSelectText={<T id={'select_payment_account'} />}
// filterByTypes={['current_asset', 'other_current_asset']} // filterByParentTypes={[ACCOUNT_PARENT_TYPE.CURRENT_ASSET]}
/> />
</FormGroup> </FormGroup>
)} )}
</FastField> </FastField>
<div className={'card__footer'}> <div className={'card__footer'}>
<Button intent={Intent.PRIMARY} type="submit"> <Button intent={Intent.PRIMARY} disabled={isSubmitting} type="submit">
<T id={'save'} /> <T id={'save'} />
</Button> </Button>
<Button onClick={handleCloseClick}> <Button onClick={handleCloseClick}>

View File

@@ -1,28 +1,72 @@
import React, { useEffect } from 'react'; import React, { useEffect } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { Formik } from 'formik'; import { Formik } from 'formik';
import { pick } from 'lodash';
import { Intent } from '@blueprintjs/core';
import { CLASSES } from 'common/classes'; import { CLASSES } from 'common/classes';
import { AppToaster } from 'components';
import { useIntl } from 'react-intl';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withSettings from 'containers/Settings/withSettings';
import AccountantForm from './AccountantForm'; import AccountantForm from './AccountantForm';
import { AccountantSchema } from './Accountant.schema'; import { AccountantSchema } from './Accountant.schema';
import { useAccountantFormContext } from './AccountantFormProvider'; import { useAccountantFormContext } from './AccountantFormProvider';
import { transformToOptions } from './utils';
import withDashboardActions from 'containers/Dashboard/withDashboardActions'; import { compose, transformGeneralSettings } from 'utils';
import { compose } from 'utils';
import 'style/pages/Preferences/Accounting.scss'; import 'style/pages/Preferences/Accounting.scss';
// Accountant preferences. // Accountant preferences.
function AccountantFormPage({ changePreferencesPageTitle }) { function AccountantFormPage({
//# withDashboardActions
changePreferencesPageTitle,
// #withSettings
organizationSettings,
paymentReceiveSettings,
accountsSettings,
billPaymentSettings,
}) {
const { formatMessage } = useIntl();
const { saveSettingMutate } = useAccountantFormContext(); const { saveSettingMutate } = useAccountantFormContext();
const initialValues = {}; const accountantSettings = {
...billPaymentSettings,
...accountsSettings,
...pick(organizationSettings, ['accountingBasis']),
...pick(paymentReceiveSettings, ['depositAccount', 'advanceDeposit']),
};
const initialValues = {
...transformGeneralSettings(accountantSettings),
};
useEffect(() => { useEffect(() => {
changePreferencesPageTitle('Accountant'); changePreferencesPageTitle(formatMessage({ id: 'accountant' }));
}, [changePreferencesPageTitle]); }, [changePreferencesPageTitle]);
const handleFormSubmit = (values, { setSubmitting }) => {
const options = transformToOptions(values);
setSubmitting(true);
const onSuccess = () => {
AppToaster.show({
message: formatMessage({
id: 'the_accountant_preferences_has_been_saved',
}),
intent: Intent.SUCCESS,
});
setSubmitting(false);
};
const onError = (errors) => {
setSubmitting(false);
};
saveSettingMutate({ options }).then(onSuccess).catch(onError);
};
return ( return (
<div <div
className={classNames( className={classNames(
@@ -34,6 +78,7 @@ function AccountantFormPage({ changePreferencesPageTitle }) {
<Formik <Formik
initialValues={initialValues} initialValues={initialValues}
validationSchema={AccountantSchema} validationSchema={AccountantSchema}
onSubmit={handleFormSubmit}
component={AccountantForm} component={AccountantForm}
/> />
</div> </div>
@@ -41,4 +86,19 @@ function AccountantFormPage({ changePreferencesPageTitle }) {
); );
} }
export default compose(withDashboardActions)(AccountantFormPage); export default compose(
withSettings(
({
organizationSettings,
paymentReceiveSettings,
accountsSettings,
billPaymentSettings,
}) => ({
organizationSettings,
paymentReceiveSettings,
accountsSettings,
billPaymentSettings,
}),
),
withDashboardActions,
)(AccountantFormPage);

View File

@@ -0,0 +1,37 @@
export const transformToOptions = (option) => {
return [
{
key: 'accounting_basis',
value: option.accounting_basis,
group: 'organization',
},
{
key: 'withdrawal_account',
value: option.withdrawal_account,
group: 'bill_payments',
},
{
key: 'deposit_account',
value: option.deposit_account,
group: 'payment_receives',
},
{
key: 'advance_deposit',
value: option.advance_deposit,
group: 'payment_receives',
},
{
key: 'account_code_required',
value: option.account_code_required,
group: 'accounts',
},
{
key: 'account_code_unique',
value: option.account_code_unique,
group: 'accounts',
},
];
};

View File

@@ -1,4 +1,3 @@
// Accountant. // Accountant.
// --------------------------------- // ---------------------------------
.preferences-page__inside-content--accountant { .preferences-page__inside-content--accountant {
@@ -13,22 +12,20 @@
.bp3-button { .bp3-button {
min-width: 60px; min-width: 60px;
+ .bp3-button{ + .bp3-button {
margin-left: 10px; margin-left: 10px;
} }
} }
} }
} }
.form-group--select-list{ .form-group--select-list {
button {
button{
min-width: 250px; min-width: 250px;
} }
} }
.bp3-form-group { .bp3-form-group {
.bp3-form-helper-text {
.bp3-form-helper-text{
margin-top: 7px; margin-top: 7px;
} }
@@ -36,4 +33,12 @@
margin-bottom: 7px; margin-bottom: 7px;
} }
} }
} .bp3-form-group.accounts-checkbox {
.bp3-form-group.bp3-inline {
margin-bottom: 7px;
}
.bp3-control.bp3-inline {
margin-bottom: 0;
}
}
}

View File

@@ -616,4 +616,7 @@ export const updateTableRow = (rowIndex, columnId, value) => (old) => {
} }
return row; return row;
}); });
}; };
export const transformGeneralSettings = (data) => {
return _.mapKeys(data, (value, key) => _.snakeCase(key));
};