mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-22 07:40:32 +00:00
fix: Ensure entries has atleast one empty line in expense and make journal form.
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
|
|||||||
import { Formik, Form } from 'formik';
|
import { Formik, Form } from 'formik';
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
|
import * as R from 'ramda';
|
||||||
import { defaultTo, isEmpty, omit } from 'lodash';
|
import { defaultTo, isEmpty, omit } from 'lodash';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
@@ -68,7 +69,6 @@ function MakeJournalEntriesForm({
|
|||||||
journal_number: defaultTo(journalNumber, ''),
|
journal_number: defaultTo(journalNumber, ''),
|
||||||
}),
|
}),
|
||||||
currency_code: baseCurrency,
|
currency_code: baseCurrency,
|
||||||
entries: orderingLinesIndexes(defaultManualJournal.entries),
|
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
[manualJournal, baseCurrency, journalNumber],
|
[manualJournal, baseCurrency, journalNumber],
|
||||||
@@ -109,7 +109,7 @@ function MakeJournalEntriesForm({
|
|||||||
...(values.journal_number_manually && {
|
...(values.journal_number_manually && {
|
||||||
journal_number: values.journal_number,
|
journal_number: values.journal_number,
|
||||||
}),
|
}),
|
||||||
entries,
|
entries: R.compose(orderingLinesIndexes)(entries),
|
||||||
publish: submitPayload.publish,
|
publish: submitPayload.publish,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ import React from 'react';
|
|||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import { sumBy, setWith, toSafeInteger, get } from 'lodash';
|
import { sumBy, setWith, toSafeInteger, get } from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import * as R from 'ramda';
|
||||||
import {
|
import {
|
||||||
transactionNumber,
|
transactionNumber,
|
||||||
updateTableRow,
|
updateTableRow,
|
||||||
repeatValue,
|
repeatValue,
|
||||||
transformToForm,
|
transformToForm,
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
|
ensureEntriesHasEmptyLine
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
import { AppToaster } from 'components';
|
import { AppToaster } from 'components';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
@@ -27,7 +29,6 @@ const ERROR = {
|
|||||||
export const MIN_LINES_NUMBER = 4;
|
export const MIN_LINES_NUMBER = 4;
|
||||||
|
|
||||||
export const defaultEntry = {
|
export const defaultEntry = {
|
||||||
index: 0,
|
|
||||||
account_id: '',
|
account_id: '',
|
||||||
credit: '',
|
credit: '',
|
||||||
debit: '',
|
debit: '',
|
||||||
@@ -48,17 +49,24 @@ export const defaultManualJournal = {
|
|||||||
|
|
||||||
// Transform to edit form.
|
// Transform to edit form.
|
||||||
export function transformToEditForm(manualJournal) {
|
export function transformToEditForm(manualJournal) {
|
||||||
|
const defaultEntry = defaultManualJournal.entries[0];
|
||||||
|
const initialEntries = [
|
||||||
|
...manualJournal.entries.map((entry) => ({
|
||||||
|
...transformToForm(entry, defaultEntry),
|
||||||
|
})),
|
||||||
|
...repeatValue(
|
||||||
|
defaultEntry,
|
||||||
|
Math.max(MIN_LINES_NUMBER - manualJournal.entries.length, 0),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
const entries = R.compose(
|
||||||
|
ensureEntriesHasEmptyLine(MIN_LINES_NUMBER, defaultEntry),
|
||||||
|
)(initialEntries);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...transformToForm(manualJournal, defaultManualJournal),
|
...transformToForm(manualJournal, defaultManualJournal),
|
||||||
entries: [
|
entries,
|
||||||
...manualJournal.entries.map((entry) => ({
|
|
||||||
...transformToForm(entry, defaultManualJournal.entries[0]),
|
|
||||||
})),
|
|
||||||
...repeatValue(
|
|
||||||
defaultEntry,
|
|
||||||
Math.max(MIN_LINES_NUMBER - manualJournal.entries.length, 0),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { Formik, Form } from 'formik';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { CLASSES } from 'common/classes';
|
import { CLASSES } from 'common/classes';
|
||||||
|
import * as R from 'ramda';
|
||||||
|
|
||||||
import ExpenseFormHeader from './ExpenseFormHeader';
|
import ExpenseFormHeader from './ExpenseFormHeader';
|
||||||
import ExpenseFormBody from './ExpenseFormBody';
|
import ExpenseFormBody from './ExpenseFormBody';
|
||||||
@@ -59,7 +60,6 @@ function ExpenseForm({
|
|||||||
...defaultExpense,
|
...defaultExpense,
|
||||||
currency_code: baseCurrency,
|
currency_code: baseCurrency,
|
||||||
payment_account_id: defaultTo(preferredPaymentAccount, ''),
|
payment_account_id: defaultTo(preferredPaymentAccount, ''),
|
||||||
categories: orderingLinesIndexes(defaultExpense.categories),
|
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
[expense, baseCurrency, preferredPaymentAccount],
|
[expense, baseCurrency, preferredPaymentAccount],
|
||||||
@@ -77,15 +77,18 @@ function ExpenseForm({
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Filter expense entries that has no amount or expense account.
|
||||||
const categories = values.categories.filter(
|
const categories = values.categories.filter(
|
||||||
(category) =>
|
(category) =>
|
||||||
category.amount && category.index && category.expense_account_id,
|
category.amount && category.expense_account_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
const form = {
|
const form = {
|
||||||
...values,
|
...values,
|
||||||
publish: submitPayload.publish,
|
publish: submitPayload.publish,
|
||||||
categories,
|
categories: R.compose(
|
||||||
|
orderingLinesIndexes,
|
||||||
|
)(categories),
|
||||||
};
|
};
|
||||||
// Handle request success.
|
// Handle request success.
|
||||||
const handleSuccess = (response) => {
|
const handleSuccess = (response) => {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
updateMinEntriesLines,
|
updateMinEntriesLines,
|
||||||
updateAutoAddNewLine,
|
updateAutoAddNewLine,
|
||||||
updateRemoveLineByIndex,
|
updateRemoveLineByIndex,
|
||||||
|
orderingLinesIndexes,
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ import { ExpenseFormPageProvider } from './ExpenseFormPageProvider';
|
|||||||
*/
|
*/
|
||||||
export default function ExpenseFormPage() {
|
export default function ExpenseFormPage() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
|
const expenseId = parseInt(id, 10);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ExpenseFormPageProvider expenseId={id}>
|
<ExpenseFormPageProvider expenseId={expenseId}>
|
||||||
<ExpenseForm />
|
<ExpenseForm />
|
||||||
</ExpenseFormPageProvider>
|
</ExpenseFormPageProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { AppToaster } from 'components';
|
import { AppToaster } from 'components';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
|
import * as R from 'ramda';
|
||||||
import {
|
import {
|
||||||
defaultFastFieldShouldUpdate,
|
defaultFastFieldShouldUpdate,
|
||||||
transformToForm,
|
transformToForm,
|
||||||
repeatValue,
|
repeatValue,
|
||||||
|
ensureEntriesHasEmptyLine
|
||||||
} from 'utils';
|
} from 'utils';
|
||||||
|
|
||||||
const ERROR = {
|
const ERROR = {
|
||||||
@@ -27,7 +29,6 @@ export const transformErrors = (errors, { setErrors }) => {
|
|||||||
export const MIN_LINES_NUMBER = 4;
|
export const MIN_LINES_NUMBER = 4;
|
||||||
|
|
||||||
export const defaultExpenseEntry = {
|
export const defaultExpenseEntry = {
|
||||||
index: 0,
|
|
||||||
amount: '',
|
amount: '',
|
||||||
expense_account_id: '',
|
expense_account_id: '',
|
||||||
description: '',
|
description: '',
|
||||||
@@ -53,17 +54,23 @@ export const transformToEditForm = (
|
|||||||
defaultExpense,
|
defaultExpense,
|
||||||
linesNumber = 4,
|
linesNumber = 4,
|
||||||
) => {
|
) => {
|
||||||
|
const expenseEntry = defaultExpense.categories[0];
|
||||||
|
const initialEntries = [
|
||||||
|
...expense.categories.map((category) => ({
|
||||||
|
...transformToForm(category, expenseEntry),
|
||||||
|
})),
|
||||||
|
...repeatValue(
|
||||||
|
expenseEntry,
|
||||||
|
Math.max(linesNumber - expense.categories.length, 0),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
const categories = R.compose(
|
||||||
|
ensureEntriesHasEmptyLine(MIN_LINES_NUMBER, expenseEntry),
|
||||||
|
)(initialEntries);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...transformToForm(expense, defaultExpense),
|
...transformToForm(expense, defaultExpense),
|
||||||
categories: [
|
categories,
|
||||||
...expense.categories.map((category) => ({
|
|
||||||
...transformToForm(category, defaultExpense.categories[0]),
|
|
||||||
})),
|
|
||||||
...repeatValue(
|
|
||||||
expense,
|
|
||||||
Math.max(linesNumber - expense.categories.length, 0),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import _, { castArray } from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import * as R from 'ramda';
|
||||||
import Currencies from 'js-money/lib/currency';
|
import Currencies from 'js-money/lib/currency';
|
||||||
|
|
||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
@@ -670,3 +671,13 @@ export const defaultFastFieldShouldUpdate = (props, prevProps) => {
|
|||||||
props.formik.isSubmitting !== prevProps.formik.isSubmitting
|
props.formik.isSubmitting !== prevProps.formik.isSubmitting
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const ensureEntriesHasEmptyLine = R.curry(
|
||||||
|
(minLinesNumber, defaultEntry, entries) => {
|
||||||
|
if (entries.length >= minLinesNumber) {
|
||||||
|
return [...entries, defaultEntry];
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
},
|
||||||
|
);
|
||||||
Reference in New Issue
Block a user