fix(preferences): currencies preferences.

This commit is contained in:
a.bouhuolia
2021-03-24 13:09:56 +02:00
parent 542110fdf3
commit ac5e88f558
16 changed files with 346 additions and 285 deletions

View File

@@ -2,7 +2,9 @@ import React from 'react';
import { Classes, FormGroup, InputGroup } from '@blueprintjs/core';
import { FastField } from 'formik';
import { FormattedMessage as T } from 'react-intl';
import classNames from 'classnames';
import { CLASSES } from 'common/classes';
import { useCurrencyFormContext } from './CurrencyFormProvider';
import { ErrorMessage, FieldRequiredHint, ListSelect } from 'components';
@@ -25,7 +27,7 @@ export default function CurrencyFormFields() {
field: { value },
meta: { error, touched },
}) => (
<FormGroup label={'Currency code'}>
<FormGroup label={'Currency code'} className={classNames(CLASSES.FILL, 'form-group--type')}>
<ListSelect
items={currenciesOptions}
selectedItemProp={'currency_code'}
@@ -38,6 +40,7 @@ export default function CurrencyFormFields() {
setFieldValue('currency_sign', currency.symbol);
}}
disabled={isEditMode}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}

View File

@@ -30,7 +30,7 @@ function CurrencyFormDialog({
isOpen={isOpen}
autoFocus={true}
canEscapeKeyClose={true}
style={{ width: '450px' }}
style={{ width: '400px' }}
>
<DialogSuspense>
<CurrencyFormDialogContent

View File

@@ -11,11 +11,13 @@ import {
import { useHistory } from 'react-router-dom';
import { AccountsSelectList, FieldRequiredHint } from 'components';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { ACCOUNT_PARENT_TYPE } from 'common/accountTypes';
import { handleStringChange, inputIntent } from 'utils';
import { useAccountantFormContext } from './AccountantFormProvider';
/**
* Accountant form.
*/
export default function AccountantForm() {
const history = useHistory();

View File

@@ -1,9 +1,8 @@
import React, { useEffect } from 'react';
import classNames from 'classnames';
import { Formik } from 'formik';
import { pick } from 'lodash';
import { Intent } from '@blueprintjs/core';
import { CLASSES } from 'common/classes';
import { AppToaster } from 'components';
import { useIntl } from 'react-intl';
@@ -50,6 +49,7 @@ function AccountantFormPage({
const handleFormSubmit = (values, { setSubmitting }) => {
const options = transformToOptions(values);
setSubmitting(true);
const onSuccess = () => {
AppToaster.show({
@@ -68,21 +68,12 @@ function AccountantFormPage({
};
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}
onSubmit={handleFormSubmit}
component={AccountantForm}
/>
</div>
</div>
<Formik
initialValues={initialValues}
validationSchema={AccountantSchema}
onSubmit={handleFormSubmit}
component={AccountantForm}
/>
);
}

View File

@@ -1,6 +1,8 @@
import React from 'react';
import { LoadingIndicator } from 'components';
import classNames from 'classnames';
import { CLASSES } from 'common/classes';
import { useAccounts, useSaveSettings, useSettings } from 'hooks/query';
import PreferencesPageLoader from '../PreferencesPageLoader';
const AccountantFormContext = React.createContext();
@@ -24,10 +26,23 @@ function AccountantFormProvider({ ...props }) {
saveSettingMutate,
};
const isLoading = isSettingsLoading || isAccountsLoading;
return (
<LoadingIndicator loading={isSettingsLoading || isAccountsLoading}>
<AccountantFormContext.Provider value={provider} {...props} />
</LoadingIndicator>
<div
className={classNames(
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT,
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_ACCOUNTANT,
)}
>
<div className={classNames(CLASSES.CARD)}>
{isLoading ? (
<PreferencesPageLoader />
) : (
<AccountantFormContext.Provider value={provider} {...props} />
)}
</div>
</div>
);
}

View File

@@ -36,220 +36,224 @@ export default function PreferencesGeneralForm({}) {
return (
<Form>
<FastField name={'name'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'organization_name'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
intent={inputIntent({ error, touched })}
className={'form-group--org-name'}
helperText={'Shown on sales forms and purchase orders.'}
>
<InputGroup medium={'true'} {...field} />
</FormGroup>
)}
</FastField>
<FastField name={'name'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'organization_name'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
intent={inputIntent({ error, touched })}
className={'form-group--org-name'}
helperText={'Shown on sales forms and purchase orders.'}
>
<InputGroup medium={'true'} {...field} />
</FormGroup>
)}
</FastField>
<FastField name={'financial_date_start'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'financial_starting_date'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
intent={inputIntent({ error, touched })}
className={classNames('form-group--select-list', CLASSES.FILL)}
helperText={'For reporting, you can specify any month as the start of your financial year (also called your financial reporting year or accounting year).'}
>
<DateInput
{...momentFormatter('MMMM Do YYYY')}
value={tansformDateValue(value)}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('financial_date_start', formattedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'industry'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'organization_industry'} />}
inline={true}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="industry" />}
className={'form-group--org-industry'}
>
<InputGroup medium={'true'} {...field} />
</FormGroup>
)}
</FastField>
<FastField name={'location'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'business_location'} />}
className={classNames(
'form-group--business-location',
CLASSES.FILL,
)}
inline={true}
helperText={<ErrorMessage name="location" />}
intent={inputIntent({ error, touched })}
>
<ListSelect
items={countriesOptions}
onItemSelect={({ value }) => {
form.setFieldValue('location', value);
}}
selectedItem={value}
selectedItemProp={'value'}
defaultText={<T id={'select_business_location'} />}
textProp={'name'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'base_currency'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'base_currency'} />}
labelInfo={<FieldRequiredHint />}
className={classNames('form-group--base-currency', CLASSES.FILL)}
inline={true}
intent={inputIntent({ error, touched })}
helperText={"You can't change the base currency as there are transactions recorded in your organization."}
>
<ListSelect
items={currencies}
onItemSelect={(currency) => {
form.setFieldValue('base_currency', currency.code);
}}
selectedItem={value}
selectedItemProp={'code'}
defaultText={<T id={'select_base_currency'} />}
textProp={'name'}
labelProp={'code'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'fiscal_year'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'fiscal_year'} />}
labelInfo={<FieldRequiredHint />}
className={classNames('form-group--fiscal-year', CLASSES.FILL)}
inline={true}
helperText={<ErrorMessage name="fiscal_year" />}
intent={inputIntent({ error, touched })}
>
<ListSelect
items={fiscalYearOptions}
onItemSelect={({ value }) =>
form.setFieldValue('fiscal_year', value)
<FastField name={'financial_date_start'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'financial_starting_date'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
intent={inputIntent({ error, touched })}
className={classNames('form-group--select-list', CLASSES.FILL)}
helperText={
'For reporting, you can specify any month as the start of your financial year (also called your financial reporting year or accounting year).'
}
selectedItem={value}
selectedItemProp={'value'}
defaultText={<T id={'select_fiscal_year'} />}
textProp={'name'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
>
<DateInput
{...momentFormatter('MMMM Do YYYY')}
value={tansformDateValue(value)}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('financial_date_start', formattedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'language'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'language'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
className={classNames('form-group--language', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="language" />}
>
<ListSelect
items={languages}
selectedItemProp={'value'}
textProp={'name'}
defaultText={<T id={'select_language'} />}
selectedItem={value}
onItemSelect={(item) =>
form.setFieldValue('language', item.value)
<FastField name={'industry'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'organization_industry'} />}
inline={true}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="industry" />}
className={'form-group--org-industry'}
>
<InputGroup medium={'true'} {...field} />
</FormGroup>
)}
</FastField>
<FastField name={'location'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'business_location'} />}
className={classNames(
'form-group--business-location',
CLASSES.FILL,
)}
inline={true}
helperText={<ErrorMessage name="location" />}
intent={inputIntent({ error, touched })}
>
<ListSelect
items={countriesOptions}
onItemSelect={({ value }) => {
form.setFieldValue('location', value);
}}
selectedItem={value}
selectedItemProp={'value'}
defaultText={<T id={'select_business_location'} />}
textProp={'name'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'base_currency'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'base_currency'} />}
labelInfo={<FieldRequiredHint />}
className={classNames('form-group--base-currency', CLASSES.FILL)}
inline={true}
intent={inputIntent({ error, touched })}
helperText={
"You can't change the base currency as there are transactions recorded in your organization."
}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
>
<ListSelect
items={currencies}
onItemSelect={(currency) => {
form.setFieldValue('base_currency', currency.code);
}}
selectedItem={value}
selectedItemProp={'code'}
defaultText={<T id={'select_base_currency'} />}
textProp={'name'}
labelProp={'code'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'time_zone'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'time_zone'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
className={classNames(
'form-group--time-zone',
CLASSES.FORM_GROUP_LIST_SELECT,
CLASSES.FILL,
)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="time_zone" />}
>
<TimezonePicker
value={value}
onChange={(timezone) => {
form.setFieldValue('time_zone', timezone);
}}
valueDisplayFormat="composite"
placeholder={<T id={'select_time_zone'} />}
/>
</FormGroup>
)}
</FastField>
<FastField name={'fiscal_year'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'fiscal_year'} />}
labelInfo={<FieldRequiredHint />}
className={classNames('form-group--fiscal-year', CLASSES.FILL)}
inline={true}
helperText={<ErrorMessage name="fiscal_year" />}
intent={inputIntent({ error, touched })}
>
<ListSelect
items={fiscalYearOptions}
onItemSelect={({ value }) =>
form.setFieldValue('fiscal_year', value)
}
selectedItem={value}
selectedItemProp={'value'}
defaultText={<T id={'select_fiscal_year'} />}
textProp={'name'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'date_format'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'date_format'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
className={classNames('form-group--date-format', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="date_format" />}
>
<ListSelect
items={dateFormatsOptions}
onItemSelect={(dateFormat) => {
form.setFieldValue('date_format', dateFormat.value);
}}
selectedItem={value}
selectedItemProp={'value'}
defaultText={<T id={'select_date_format'} />}
textProp={'name'}
labelProp={'label'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<FastField name={'language'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'language'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
className={classNames('form-group--language', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="language" />}
>
<ListSelect
items={languages}
selectedItemProp={'value'}
textProp={'name'}
defaultText={<T id={'select_language'} />}
selectedItem={value}
onItemSelect={(item) =>
form.setFieldValue('language', item.value)
}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<div className={'card__footer'}>
<Button intent={Intent.PRIMARY} type="submit">
<T id={'save'} />
</Button>
<Button onClick={handleCloseClick}>
<T id={'close'} />
</Button>
</div>
</Form>
<FastField name={'time_zone'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'time_zone'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
className={classNames(
'form-group--time-zone',
CLASSES.FORM_GROUP_LIST_SELECT,
CLASSES.FILL,
)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="time_zone" />}
>
<TimezonePicker
value={value}
onChange={(timezone) => {
form.setFieldValue('time_zone', timezone);
}}
valueDisplayFormat="composite"
placeholder={<T id={'select_time_zone'} />}
/>
</FormGroup>
)}
</FastField>
<FastField name={'date_format'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'date_format'} />}
labelInfo={<FieldRequiredHint />}
inline={true}
className={classNames('form-group--date-format', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="date_format" />}
>
<ListSelect
items={dateFormatsOptions}
onItemSelect={(dateFormat) => {
form.setFieldValue('date_format', dateFormat.value);
}}
selectedItem={value}
selectedItemProp={'value'}
defaultText={<T id={'select_date_format'} />}
textProp={'name'}
labelProp={'label'}
popoverProps={{ minimal: true }}
/>
</FormGroup>
)}
</FastField>
<div className={'card__footer'}>
<Button intent={Intent.PRIMARY} type="submit">
<T id={'save'} />
</Button>
<Button onClick={handleCloseClick}>
<T id={'close'} />
</Button>
</div>
</Form>
);
}

View File

@@ -2,9 +2,7 @@ import React, { useEffect } from 'react';
import { Formik } from 'formik';
import { mapKeys, snakeCase } from 'lodash';
import { Intent } from '@blueprintjs/core';
import classNames from 'classnames';
import { useIntl } from 'react-intl';
import { CLASSES } from 'common/classes';
import { AppToaster } from 'components';
import GeneralForm from './GeneralForm';
@@ -46,6 +44,7 @@ function GeneralFormPage({
const options = optionsMapToArray(values).map((option) => {
return { key: option.key, ...option, group: 'organization' };
});
// Handle request success.
const onSuccess = (response) => {
AppToaster.show({
message: 'The general preferences has been saved.',
@@ -54,6 +53,7 @@ function GeneralFormPage({
setSubmitting(false);
resetForm();
};
// Handle request error.
const onError = (errors) => {
setSubmitting(false);
};
@@ -61,21 +61,12 @@ function GeneralFormPage({
};
return (
<div
className={classNames(
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT,
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_GENERAL,
)}
>
<div className={classNames(CLASSES.CARD)}>
<Formik
initialValues={initialValues}
validationSchema={PreferencesGeneralSchema}
onSubmit={handleFormSubmit}
component={GeneralForm}
/>
</div>
</div>
<Formik
initialValues={initialValues}
validationSchema={PreferencesGeneralSchema}
onSubmit={handleFormSubmit}
component={GeneralForm}
/>
);
}

View File

@@ -1,6 +1,8 @@
import React, { createContext } from 'react';
import { LoadingIndicator } from 'components';
import classNames from 'classnames';
import { CLASSES } from 'common/classes';
import { useSaveSettings, useSettings } from 'hooks/query';
import PreferencesPageLoader from '../PreferencesPageLoader';
const GeneralFormContext = createContext();
@@ -8,8 +10,8 @@ const GeneralFormContext = createContext();
* General form provider.
*/
function GeneralFormProvider({ ...props }) {
//Fetches Organization Settings.
const { isFetching: isSettingsLoading } = useSettings();
// Fetches Organization Settings.
const { isLoading: isSettingsLoading } = useSettings();
// Save Organization Settings.
const { mutateAsync: saveSettingMutate } = useSaveSettings();
@@ -20,10 +22,23 @@ function GeneralFormProvider({ ...props }) {
saveSettingMutate,
};
const loading = isSettingsLoading;
return (
<LoadingIndicator loading={isSettingsLoading} spinnerSize={28}>
<GeneralFormContext.Provider value={provider} {...props} />
</LoadingIndicator>
<div
className={classNames(
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT,
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_GENERAL,
)}
>
<div className={classNames(CLASSES.CARD)}>
{loading ? (
<PreferencesPageLoader />
) : (
<GeneralFormContext.Provider value={provider} {...props} />
)}
</div>
</div>
);
}

View File

@@ -1,9 +1,9 @@
import * as Yup from 'yup';
const Schema = Yup.object().shape({
sell_account: Yup.number().nullable().required(),
cost_account: Yup.number().nullable().required(),
inventory_account: Yup.number().nullable().required(),
sell_account: Yup.number().nullable(),
cost_account: Yup.number().nullable(),
inventory_account: Yup.number().nullable(),
});
export const ItemPreferencesSchema = Schema;

View File

@@ -1,8 +1,6 @@
import React, { useEffect } from 'react';
import { Formik } from 'formik';
import { Intent } from '@blueprintjs/core';
import classNames from 'classnames';
import { CLASSES } from 'common/classes';
import { AppToaster } from 'components';
import { useIntl } from 'react-intl';
import { ItemPreferencesSchema } from './Item.schema';
@@ -19,24 +17,28 @@ import 'style/pages/Preferences/Accounting.scss';
function ItemFormPage({
// #withSettings
itemsSettings,
//# withDashboardActions
// #withDashboardActions
changePreferencesPageTitle,
}) {
const { formatMessage } = useIntl();
const { saveSettingMutate } = useItemFormContext();
const initialValues = {
sell_account: '',
cost_account: '',
inventory_account: '',
...transformGeneralSettings(itemsSettings),
};
useEffect(() => {
changePreferencesPageTitle(formatMessage({ id: 'items' }));
}, [changePreferencesPageTitle]);
}, [formatMessage, changePreferencesPageTitle]);
// Handle form submit.
const handleFormSubmit = (values, { setSubmitting, setErrors }) => {
const options = optionsMapToArray(values).map((option) => {
return { key: option.key, ...option, group: 'items' };
});
const options = optionsMapToArray(values)
.map((option) => ({ ...option, group: 'items' }));
const onSuccess = () => {
AppToaster.show({
@@ -55,21 +57,12 @@ function ItemFormPage({
};
return (
<div
className={classNames(
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT,
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_ACCOUNTANT,
)}
>
<div className={classNames(CLASSES.CARD)}>
<Formik
initialValues={initialValues}
validationSchema={ItemPreferencesSchema}
onSubmit={handleFormSubmit}
component={ItemForm}
/>
</div>
</div>
<Formik
initialValues={initialValues}
validationSchema={ItemPreferencesSchema}
onSubmit={handleFormSubmit}
component={ItemForm}
/>
);
}

View File

@@ -1,7 +1,9 @@
import React, { useContext, createContext } from 'react';
import { LoadingIndicator } from 'components';
import classNames from 'classnames';
import { CLASSES } from 'common/classes';
import { useAccounts, useSaveSettings } from 'hooks/query';
import PreferencesPageLoader from '../PreferencesPageLoader';
const ItemFormContext = createContext();
@@ -22,10 +24,23 @@ function ItemFormProvider({ ...props }) {
saveSettingMutate,
};
const isLoading = isAccountsLoading;
return (
<LoadingIndicator loading={isAccountsLoading}>
<ItemFormContext.Provider value={provider} {...props} />
</LoadingIndicator>
<div
className={classNames(
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT,
CLASSES.PREFERENCES_PAGE_INSIDE_CONTENT_ACCOUNTANT,
)}
>
<div className={classNames(CLASSES.CARD)}>
{isLoading ? (
<PreferencesPageLoader />
) : (
<ItemFormContext.Provider value={provider} {...props} />
)}
</div>
</div>
);
}

View File

@@ -0,0 +1,23 @@
import React from 'react';
import ContentLoader from 'react-content-loader';
export default function PreferencesPageLoader(props) {
return (
<ContentLoader
speed={2}
width={400}
height={250}
viewBox="0 0 400 250"
backgroundColor="#f3f3f3"
foregroundColor="#e6e6e6"
{...props}
>
<rect x="0" y="82" rx="2" ry="2" width="200" height="20" />
<rect x="0" y="112" rx="2" ry="2" width="385" height="30" />
<rect x="0" y="0" rx="2" ry="2" width="200" height="20" />
<rect x="-1" y="30" rx="2" ry="2" width="385" height="30" />
<rect x="0" y="164" rx="2" ry="2" width="200" height="20" />
<rect x="0" y="194" rx="2" ry="2" width="385" height="30" />
</ContentLoader>
);
}

View File

@@ -1,5 +1,7 @@
.dialog--currency-form {
.bp3-dialog-body {
margin-bottom: 30px;
.bp3-form-group.bp3-inline {
.bp3-label {
min-width: 140px;

View File

@@ -41,7 +41,7 @@ export default class SettingsController extends BaseController {
return [
body('options').isArray({ min: 1 }),
body('options.*.key').exists().trim().isLength({ min: 1 }),
body('options.*.value').exists().trim().isLength({ min: 1 }),
body('options.*.value').exists().trim(),
body('options.*.group').exists().trim().isLength({ min: 1 }),
];
}

View File

@@ -5,6 +5,12 @@ exports.up = (knex) => {
const tenancyService = Container.get(TenancyService);
const settings = tenancyService.settings(knex.userParams.tenantId);
// Orgnization settings.
settings.set({ group: 'organization', key: 'accounting_basis', value: 'accural' });
// Accounts settings.
settings.set({ group: 'accounts', key: 'account_code_unique', value: true });
// Manual journals settings.
settings.set({ group: 'manual_journals', key: 'next_number', value: '00001' });
settings.set({ group: 'manual_journals', key: 'auto_increment', value: true });

View File

@@ -261,6 +261,7 @@ export default class CurrenciesService implements ICurrenciesService {
await Currency.query().insert({
currency_code: currencyMeta.code,
currency_name: currencyMeta.name,
currency_sign: currencyMeta.symbol,
});
}
}