fix: Ensure entries has atleast one empty line in expense and make journal form.

This commit is contained in:
a.bouhuolia
2021-08-03 22:43:05 +02:00
parent 1f3ed79f2a
commit b3af374007
7 changed files with 58 additions and 27 deletions

View File

@@ -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,
}; };

View File

@@ -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),
),
],
}; };
} }

View File

@@ -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) => {

View File

@@ -10,6 +10,7 @@ import {
updateMinEntriesLines, updateMinEntriesLines,
updateAutoAddNewLine, updateAutoAddNewLine,
updateRemoveLineByIndex, updateRemoveLineByIndex,
orderingLinesIndexes,
} from 'utils'; } from 'utils';
/** /**

View File

@@ -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>
); );

View File

@@ -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),
),
],
}; };
}; };

View File

@@ -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;
},
);