From b3af37400721a4f775c9d78a8df59f3c925cb1dd Mon Sep 17 00:00:00 2001 From: "a.bouhuolia" Date: Tue, 3 Aug 2021 22:43:05 +0200 Subject: [PATCH] fix: Ensure entries has atleast one empty line in expense and make journal form. --- .../MakeJournal/MakeJournalEntriesForm.js | 4 +-- .../Accounting/MakeJournal/utils.js | 28 ++++++++++++------- .../Expenses/ExpenseForm/ExpenseForm.js | 9 ++++-- .../ExpenseForm/ExpenseFormEntriesTable.js | 1 + .../Expenses/ExpenseForm/ExpenseFormPage.js | 3 +- .../containers/Expenses/ExpenseForm/utils.js | 27 +++++++++++------- client/src/utils.js | 13 ++++++++- 7 files changed, 58 insertions(+), 27 deletions(-) diff --git a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js index 9b99ebe64..09e9a2c17 100644 --- a/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js +++ b/client/src/containers/Accounting/MakeJournal/MakeJournalEntriesForm.js @@ -2,6 +2,7 @@ import React, { useMemo } from 'react'; import { Formik, Form } from 'formik'; import { Intent } from '@blueprintjs/core'; import intl from 'react-intl-universal'; +import * as R from 'ramda'; import { defaultTo, isEmpty, omit } from 'lodash'; import classNames from 'classnames'; import { useHistory } from 'react-router-dom'; @@ -68,7 +69,6 @@ function MakeJournalEntriesForm({ journal_number: defaultTo(journalNumber, ''), }), currency_code: baseCurrency, - entries: orderingLinesIndexes(defaultManualJournal.entries), }), }), [manualJournal, baseCurrency, journalNumber], @@ -109,7 +109,7 @@ function MakeJournalEntriesForm({ ...(values.journal_number_manually && { journal_number: values.journal_number, }), - entries, + entries: R.compose(orderingLinesIndexes)(entries), publish: submitPayload.publish, }; diff --git a/client/src/containers/Accounting/MakeJournal/utils.js b/client/src/containers/Accounting/MakeJournal/utils.js index 143224e41..2c39d14eb 100644 --- a/client/src/containers/Accounting/MakeJournal/utils.js +++ b/client/src/containers/Accounting/MakeJournal/utils.js @@ -2,12 +2,14 @@ import React from 'react'; import { Intent } from '@blueprintjs/core'; import { sumBy, setWith, toSafeInteger, get } from 'lodash'; import moment from 'moment'; +import * as R from 'ramda'; import { transactionNumber, updateTableRow, repeatValue, transformToForm, defaultFastFieldShouldUpdate, + ensureEntriesHasEmptyLine } from 'utils'; import { AppToaster } from 'components'; import intl from 'react-intl-universal'; @@ -27,7 +29,6 @@ const ERROR = { export const MIN_LINES_NUMBER = 4; export const defaultEntry = { - index: 0, account_id: '', credit: '', debit: '', @@ -48,17 +49,24 @@ export const defaultManualJournal = { // Transform to edit form. 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 { ...transformToForm(manualJournal, defaultManualJournal), - entries: [ - ...manualJournal.entries.map((entry) => ({ - ...transformToForm(entry, defaultManualJournal.entries[0]), - })), - ...repeatValue( - defaultEntry, - Math.max(MIN_LINES_NUMBER - manualJournal.entries.length, 0), - ), - ], + entries, }; } diff --git a/client/src/containers/Expenses/ExpenseForm/ExpenseForm.js b/client/src/containers/Expenses/ExpenseForm/ExpenseForm.js index a75fd5dd6..a8e2479b0 100644 --- a/client/src/containers/Expenses/ExpenseForm/ExpenseForm.js +++ b/client/src/containers/Expenses/ExpenseForm/ExpenseForm.js @@ -6,6 +6,7 @@ import { Formik, Form } from 'formik'; import classNames from 'classnames'; import { useHistory } from 'react-router-dom'; import { CLASSES } from 'common/classes'; +import * as R from 'ramda'; import ExpenseFormHeader from './ExpenseFormHeader'; import ExpenseFormBody from './ExpenseFormBody'; @@ -59,7 +60,6 @@ function ExpenseForm({ ...defaultExpense, currency_code: baseCurrency, payment_account_id: defaultTo(preferredPaymentAccount, ''), - categories: orderingLinesIndexes(defaultExpense.categories), }), }), [expense, baseCurrency, preferredPaymentAccount], @@ -77,15 +77,18 @@ function ExpenseForm({ }); return; } + // Filter expense entries that has no amount or expense account. const categories = values.categories.filter( (category) => - category.amount && category.index && category.expense_account_id, + category.amount && category.expense_account_id, ); const form = { ...values, publish: submitPayload.publish, - categories, + categories: R.compose( + orderingLinesIndexes, + )(categories), }; // Handle request success. const handleSuccess = (response) => { diff --git a/client/src/containers/Expenses/ExpenseForm/ExpenseFormEntriesTable.js b/client/src/containers/Expenses/ExpenseForm/ExpenseFormEntriesTable.js index 79ee363be..90ec018af 100644 --- a/client/src/containers/Expenses/ExpenseForm/ExpenseFormEntriesTable.js +++ b/client/src/containers/Expenses/ExpenseForm/ExpenseFormEntriesTable.js @@ -10,6 +10,7 @@ import { updateMinEntriesLines, updateAutoAddNewLine, updateRemoveLineByIndex, + orderingLinesIndexes, } from 'utils'; /** diff --git a/client/src/containers/Expenses/ExpenseForm/ExpenseFormPage.js b/client/src/containers/Expenses/ExpenseForm/ExpenseFormPage.js index e2ab04fc8..51453b61b 100644 --- a/client/src/containers/Expenses/ExpenseForm/ExpenseFormPage.js +++ b/client/src/containers/Expenses/ExpenseForm/ExpenseFormPage.js @@ -11,9 +11,10 @@ import { ExpenseFormPageProvider } from './ExpenseFormPageProvider'; */ export default function ExpenseFormPage() { const { id } = useParams(); + const expenseId = parseInt(id, 10); return ( - + ); diff --git a/client/src/containers/Expenses/ExpenseForm/utils.js b/client/src/containers/Expenses/ExpenseForm/utils.js index c926f9865..27ec5bd3a 100644 --- a/client/src/containers/Expenses/ExpenseForm/utils.js +++ b/client/src/containers/Expenses/ExpenseForm/utils.js @@ -1,10 +1,12 @@ import { AppToaster } from 'components'; import moment from 'moment'; import intl from 'react-intl-universal'; +import * as R from 'ramda'; import { defaultFastFieldShouldUpdate, transformToForm, repeatValue, + ensureEntriesHasEmptyLine } from 'utils'; const ERROR = { @@ -27,7 +29,6 @@ export const transformErrors = (errors, { setErrors }) => { export const MIN_LINES_NUMBER = 4; export const defaultExpenseEntry = { - index: 0, amount: '', expense_account_id: '', description: '', @@ -53,17 +54,23 @@ export const transformToEditForm = ( defaultExpense, 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 { ...transformToForm(expense, defaultExpense), - categories: [ - ...expense.categories.map((category) => ({ - ...transformToForm(category, defaultExpense.categories[0]), - })), - ...repeatValue( - expense, - Math.max(linesNumber - expense.categories.length, 0), - ), - ], + categories, }; }; diff --git a/client/src/utils.js b/client/src/utils.js index 32dadaaec..e424f126a 100644 --- a/client/src/utils.js +++ b/client/src/utils.js @@ -1,5 +1,6 @@ import moment from 'moment'; -import _, { castArray } from 'lodash'; +import _ from 'lodash'; +import * as R from 'ramda'; import Currencies from 'js-money/lib/currency'; import { Intent } from '@blueprintjs/core'; @@ -670,3 +671,13 @@ export const defaultFastFieldShouldUpdate = (props, prevProps) => { props.formik.isSubmitting !== prevProps.formik.isSubmitting ); }; + + +export const ensureEntriesHasEmptyLine = R.curry( + (minLinesNumber, defaultEntry, entries) => { + if (entries.length >= minLinesNumber) { + return [...entries, defaultEntry]; + } + return entries; + }, +); \ No newline at end of file