This commit is contained in:
a.bouhuolia
2021-03-18 14:23:53 +02:00
9 changed files with 215 additions and 137 deletions

View File

@@ -1,61 +1,14 @@
import React, { useEffect } from 'react'; import React from 'react';
import classNames from 'classnames'; import AccountantFormPage from './AccountantFormPage';
import { Formik } from 'formik'; import { AccountantFormProvider } from './AccountantFormProvider';
import { useQuery } from 'react-query';
import { CLASSES } from 'common/classes';
import { LoadingIndicator } from 'components';
import AccountantForm from './AccountantForm';
import { AccountantSchema } from './Accountant.schema';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withSettings from 'containers/Settings/withSettings';
import withSettingsActions from 'containers/Settings/withSettingsActions';
import withAccountsActions from 'containers/Accounts/withAccountsActions';
import { compose } from 'utils';
import 'style/pages/Preferences/Accounting.scss';
// Accountant preferences.
function AccountantPreferences({
changePreferencesPageTitle,
// #withAccountsActions
requestFetchAccounts,
}) {
const initialValues = {};
useEffect(() => {
changePreferencesPageTitle('Accountant');
}, [changePreferencesPageTitle]);
const fetchAccounts = useQuery('accounts-list', (key) =>
requestFetchAccounts(),
);
/**
* Accountant preferences.
*/
export default function AccountantPreferences() {
return ( return (
<div <AccountantFormProvider>
className={classNames( <AccountantFormPage />
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT, </AccountantFormProvider>
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_ACCOUNTANT,
)}
>
<div className={classNames(CLASSES.CARD)}>
<LoadingIndicator loading={fetchAccounts.isFetching} spinnerSize={28}>
<Formik
initialValues={initialValues}
validationSchema={AccountantSchema}
component={AccountantForm}
/>
</LoadingIndicator>
</div>
</div>
); );
} }
export default compose(
withSettings(({ organizationSettings }) => ({ organizationSettings })),
withSettingsActions,
withDashboardActions,
withAccountsActions,
)(AccountantPreferences);

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Form } from 'formik'; import { Form, FastField, Field } from 'formik';
import { import {
FormGroup, FormGroup,
RadioGroup, RadioGroup,
@@ -10,25 +10,35 @@ import {
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { AccountsSelectList } from 'components'; import { AccountsSelectList } from 'components';
import { import { FieldRequiredHint } from 'components';
FieldRequiredHint, import { FormattedMessage as T, useIntl } from 'react-intl';
} from 'components'; // import { } from 'common/accountTypes';
import { FormattedMessage as T } from 'react-intl'; import { handleStringChange, saveInvoke } from 'utils';
import { compose } from 'utils';
import withAccounts from 'containers/Accounts/withAccounts';
function AccountantForm({ import { useAccountantFormContext } from './AccountantFormProvider';
// #withAccounts
accountsList,
}) {
export default function AccountantForm() {
const history = useHistory(); const history = useHistory();
const { formatMessage } = useIntl();
const handleCloseClick = () => { const handleCloseClick = () => {
history.go(-1); history.go(-1);
}; };
const { accounts } = useAccountantFormContext();
return ( return (
<Form> <Form>
<FormGroup label={<strong>Accounts</strong>}> {/* ----------- accounts ----------- */}
<FormGroup
label={
<strong>
<T id={'accounts'} />
</strong>
}
>
<Checkbox <Checkbox
label={'Make account code required when create a new accounts.'} label={'Make account code required when create a new accounts.'}
/> />
@@ -36,58 +46,93 @@ function AccountantForm({
label={'Should account code be unique when create a new account.'} label={'Should account code be unique when create a new account.'}
/> />
</FormGroup> </FormGroup>
{/* ----------- accounting basis ----------- */}
<FastField name={'accounting_basis'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
labelInfo={<FieldRequiredHint />}
label={
<strong>
<T id={'accounting_basis_'} />
</strong>
}
>
<RadioGroup inline={true}>
<Radio label={formatMessage({ id: 'Cash' })} value="cash" />
<Radio label={formatMessage({ id: 'accrual' })} value="accrual" />
</RadioGroup>
</FormGroup>
)}
</FastField>
{/* ----------- deposit customer account ----------- */}
<FastField name={'deposit_customer_account'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={
<strong>
<T id={'deposit_customer_account'} />
</strong>
}
helperText={
'Select a preferred account to deposit into it after customer make payment.'
}
labelInfo={<FieldRequiredHint />}
>
<AccountsSelectList
accounts={accounts}
// onAccountSelected
defaultSelectText={<T id={'select_payment_account'} />}
// filterByTypes={['current_asset']}
/>
</FormGroup>
)}
</FastField>
<FormGroup {/* ----------- withdrawal customer account ----------- */}
labelInfo={<FieldRequiredHint />} <FastField name={'withdrawal_customer_account'}>
label={<strong>Accounting Basis</strong>}> {({ form, field: { value }, meta: { error, touched } }) => (
<RadioGroup inline={true}> <FormGroup
<Radio label="Cash" value="cash" /> label={
<Radio label="Accural" value="accural" /> <strong>
</RadioGroup> <T id={'withdrawal_customer_account'} />
</FormGroup> </strong>
}
<FormGroup helperText={
label={<strong>Deposit customer account</strong>} 'Select a preferred account to deposit into it after customer make payment.'
helperText={ }
'Select a preferred account to deposit into it after customer make payment.' labelInfo={<FieldRequiredHint />}
} >
labelInfo={<FieldRequiredHint />} <AccountsSelectList
> accounts={accounts}
<AccountsSelectList defaultSelectText={<T id={'select_payment_account'} />}
accounts={accountsList} // filterByTypes={['current_asset']}
defaultSelectText={<T id={'select_payment_account'} />} />
filterByTypes={['current_asset']} </FormGroup>
/> )}
</FormGroup> </FastField>
<FormGroup
label={<strong>Withdrawal customer account</strong>}
helperText={
'Select a preferred account to deposit into it after customer make payment.'
}
labelInfo={<FieldRequiredHint />}
>
<AccountsSelectList
accounts={accountsList}
defaultSelectText={<T id={'select_payment_account'} />}
filterByTypes={['current_asset']}
/>
</FormGroup>
<FormGroup
label={<strong>Vendor advance deposit</strong>}
helperText={
'Select a preferred account to deposit into it vendor advanced deposits.'
}
labelInfo={<FieldRequiredHint />}
>
<AccountsSelectList
accounts={accountsList}
defaultSelectText={<T id={'select_payment_account'} />}
filterByTypes={['current_asset', 'other_current_asset']}
/>
</FormGroup>
{/* ----------- withdrawal customer account ----------- */}
<FastField name={'vendor_advance_deposit'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={
<strong>
<T id={'vendor_advance_deposit'} />
</strong>
}
helperText={
'Select a preferred account to deposit into it vendor advanced deposits.'
}
labelInfo={<FieldRequiredHint />}
>
<AccountsSelectList
accounts={accounts}
defaultSelectText={<T id={'select_payment_account'} />}
// filterByTypes={['current_asset', 'other_current_asset']}
/>
</FormGroup>
)}
</FastField>
<div className={'card__footer'}> <div className={'card__footer'}>
<Button intent={Intent.PRIMARY} type="submit"> <Button intent={Intent.PRIMARY} type="submit">
<T id={'save'} /> <T id={'save'} />
@@ -99,7 +144,3 @@ function AccountantForm({
</Form> </Form>
); );
} }
export default compose(
withAccounts(({ accountsList }) => ({ accountsList })),
)(AccountantForm);

View File

@@ -0,0 +1,44 @@
import React, { useEffect } from 'react';
import classNames from 'classnames';
import { Formik } from 'formik';
import { CLASSES } from 'common/classes';
import AccountantForm from './AccountantForm';
import { AccountantSchema } from './Accountant.schema';
import { useAccountantFormContext } from './AccountantFormProvider';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import { compose } from 'utils';
import 'style/pages/Preferences/Accounting.scss';
// Accountant preferences.
function AccountantFormPage({ changePreferencesPageTitle }) {
const { saveSettingMutate } = useAccountantFormContext();
const initialValues = {};
useEffect(() => {
changePreferencesPageTitle('Accountant');
}, [changePreferencesPageTitle]);
return (
<div
className={classNames(
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT,
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_ACCOUNTANT,
)}
>
<div className={classNames(CLASSES.CARD)}>
<Formik
initialValues={initialValues}
validationSchema={AccountantSchema}
component={AccountantForm}
/>
</div>
</div>
);
}
export default compose(withDashboardActions)(AccountantFormPage);

View File

@@ -0,0 +1,35 @@
import React from 'react';
import { LoadingIndicator } from 'components';
import { useAccounts, useSaveSettings, useSettings } from 'hooks/query';
const AccountantFormContext = React.createContext();
/**
* Accountant data provider.
*/
function AccountantFormProvider({ ...props }) {
// Fetches the accounts list.
const { isFetching: isAccountsLoading, data: accounts } = useAccounts();
//Fetches Organization Settings.
const { isFetching: isSettingsLoading } = useSettings();
// Save Organization Settings.
const { mutateAsync: saveSettingMutate } = useSaveSettings();
// Provider state.
const provider = {
accounts,
isAccountsLoading,
saveSettingMutate,
};
return (
<LoadingIndicator loading={isSettingsLoading || isAccountsLoading}>
<AccountantFormContext.Provider value={provider} {...props} />
</LoadingIndicator>
);
}
const useAccountantFormContext = () => React.useContext(AccountantFormContext);
export { AccountantFormProvider, useAccountantFormContext };

View File

@@ -43,7 +43,7 @@ export function ActionsMenu({
onClick={safeCallback(onOpen, original)} onClick={safeCallback(onOpen, original)}
/> />
</If> </If>
<If condition={!original.is_fully_paid}> <If condition={original.is_open && !original.is_fully_paid}>
<MenuItem <MenuItem
icon={<Icon icon="quick-payment-16" iconSize={16} />} icon={<Icon icon="quick-payment-16" iconSize={16} />}
text={formatMessage({ id: 'add_payment' })} text={formatMessage({ id: 'add_payment' })}

View File

@@ -9,6 +9,7 @@ export const ERRORS = {
export const defaultPaymentMadeEntry = { export const defaultPaymentMadeEntry = {
bill_id: '', bill_id: '',
payment_amount: '', payment_amount: '',
currency_code:'',
id: null, id: null,
due_amount: null, due_amount: null,
}; };

View File

@@ -1,7 +1,7 @@
const ACCOUNTS = { const ACCOUNTS = {
ACCOUNT: 'ACCOUNT', ACCOUNT: 'ACCOUNT',
ACCOUNTS: 'ACCOUNTS', ACCOUNTS: 'ACCOUNTS',
ACCOUNTS_TYPES: 'ACCOUNTS_TYPES' ACCOUNTS_TYPES: 'ACCOUNTS_TYPES',
}; };
const FINANCIAL_REPORTS = { const FINANCIAL_REPORTS = {
@@ -18,7 +18,7 @@ const FINANCIAL_REPORTS = {
const BILLS = { const BILLS = {
BILLS: 'BILLS', BILLS: 'BILLS',
BILL: 'BILL', BILL: 'BILL',
BILLS_DUE: 'BILLS_DUE' BILLS_DUE: 'BILLS_DUE',
}; };
const VENDORS = { const VENDORS = {
@@ -45,7 +45,7 @@ const SALE_ESTIMATES = {
const SALE_RECEIPTS = { const SALE_RECEIPTS = {
SALE_RECEIPTS: 'SALE_RECEIPTS', SALE_RECEIPTS: 'SALE_RECEIPTS',
SALE_RECEIPT: 'SALE_RECEIPT', SALE_RECEIPT: 'SALE_RECEIPT',
} };
const INVENTORY_ADJUSTMENTS = { const INVENTORY_ADJUSTMENTS = {
INVENTORY_ADJUSTMENTS: 'INVENTORY_ADJUSTMENTS', INVENTORY_ADJUSTMENTS: 'INVENTORY_ADJUSTMENTS',
@@ -77,7 +77,7 @@ const SALE_INVOICES = {
const USERS = { const USERS = {
USERS: 'USERS', USERS: 'USERS',
USER: 'USER' USER: 'USER',
}; };
const SETTING = { const SETTING = {
@@ -91,7 +91,7 @@ const SETTING = {
const ORGANIZATIONS = { const ORGANIZATIONS = {
ORGANIZATIONS: 'ORGANIZATIONS', ORGANIZATIONS: 'ORGANIZATIONS',
ORGANIZATION_CURRENT: 'ORGANIZATION_CURRENT' ORGANIZATION_CURRENT: 'ORGANIZATION_CURRENT',
}; };
export default { export default {
@@ -111,4 +111,4 @@ export default {
...USERS, ...USERS,
...SETTING, ...SETTING,
...ORGANIZATIONS, ...ORGANIZATIONS,
} };

View File

@@ -1011,4 +1011,8 @@ export default {
quick_made_payment: 'Quick Made Payment', quick_made_payment: 'Quick Made Payment',
the_payment_amount_bigger_than_invoice_due_amount: the_payment_amount_bigger_than_invoice_due_amount:
'The payment amount bigger than invoice due amount.', 'The payment amount bigger than invoice due amount.',
accounting_basis_: 'Accounting Basis',
deposit_customer_account: 'Deposit customer account',
withdrawal_customer_account: 'Withdrawal customer account',
vendor_advance_deposit: 'Vendor advance deposit',
}; };

View File

@@ -1,8 +1,8 @@
import General from 'containers/Preferences/General/General'; import General from 'containers/Preferences/General/General';
import Users from 'containers/Preferences/Users/Users'; import Users from 'containers/Preferences/Users/Users';
// import Accountant from 'containers/Preferences/Accountant/Accountant'; import Accountant from 'containers/Preferences/Accountant/Accountant';
import Accounts from 'containers/Preferences/Accounts/Accounts'; import Accounts from 'containers/Preferences/Accounts/Accounts';
import Currencies from 'containers/Preferences/Currencies/Currencies' import Currencies from 'containers/Preferences/Currencies/Currencies';
const BASE_URL = '/preferences'; const BASE_URL = '/preferences';
@@ -22,9 +22,9 @@ export default [
component: Currencies, component: Currencies,
exact: true, exact: true,
}, },
// { {
// path: `${BASE_URL}/accountant`, path: `${BASE_URL}/accountant`,
// component: Accountant, component: Accountant,
// exact: true, exact: true,
// }, },
]; ];