mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
chrone: sperate client and server to different repos.
This commit is contained in:
167
src/containers/Expenses/ExpenseForm/ExpenseForm.js
Normal file
167
src/containers/Expenses/ExpenseForm/ExpenseForm.js
Normal file
@@ -0,0 +1,167 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
import { defaultTo, sumBy, isEmpty } from 'lodash';
|
||||
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';
|
||||
import ExpenseFloatingFooter from './ExpenseFloatingActions';
|
||||
import ExpenseFormFooter from './ExpenseFormFooter';
|
||||
|
||||
import { useExpenseFormContext } from './ExpenseFormPageProvider';
|
||||
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withMediaActions from 'containers/Media/withMediaActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
import withCurrentOrganization from 'containers/Organization/withCurrentOrganization';
|
||||
|
||||
import AppToaster from 'components/AppToaster';
|
||||
import {
|
||||
CreateExpenseFormSchema,
|
||||
EditExpenseFormSchema,
|
||||
} from './ExpenseForm.schema';
|
||||
import { transformErrors, defaultExpense, transformToEditForm } from './utils';
|
||||
import { compose, orderingLinesIndexes } from 'utils';
|
||||
|
||||
/**
|
||||
* Expense form.
|
||||
*/
|
||||
function ExpenseForm({
|
||||
// #withSettings
|
||||
preferredPaymentAccount,
|
||||
// #withCurrentOrganization
|
||||
organization: { base_currency },
|
||||
}) {
|
||||
// Expense form context.
|
||||
const {
|
||||
editExpenseMutate,
|
||||
createExpenseMutate,
|
||||
expense,
|
||||
expenseId,
|
||||
submitPayload,
|
||||
} = useExpenseFormContext();
|
||||
|
||||
const isNewMode = !expenseId;
|
||||
|
||||
// History context.
|
||||
const history = useHistory();
|
||||
|
||||
// Form initial values.
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
...(!isEmpty(expense)
|
||||
? {
|
||||
...transformToEditForm(expense, defaultExpense),
|
||||
}
|
||||
: {
|
||||
...defaultExpense,
|
||||
currency_code: base_currency,
|
||||
payment_account_id: defaultTo(preferredPaymentAccount, ''),
|
||||
}),
|
||||
}),
|
||||
[expense, base_currency, preferredPaymentAccount],
|
||||
);
|
||||
|
||||
// Handle form submit.
|
||||
const handleSubmit = (values, { setSubmitting, setErrors, resetForm }) => {
|
||||
setSubmitting(true);
|
||||
const totalAmount = sumBy(values.categories, 'amount');
|
||||
|
||||
if (totalAmount <= 0) {
|
||||
AppToaster.show({
|
||||
message: intl.get('amount_cannot_be_zero_or_empty'),
|
||||
intent: Intent.DANGER,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// Filter expense entries that has no amount or expense account.
|
||||
const categories = values.categories.filter(
|
||||
(category) => category.amount && category.expense_account_id,
|
||||
);
|
||||
|
||||
const form = {
|
||||
...values,
|
||||
publish: submitPayload.publish,
|
||||
categories: R.compose(orderingLinesIndexes)(categories),
|
||||
};
|
||||
// Handle request success.
|
||||
const handleSuccess = (response) => {
|
||||
AppToaster.show({
|
||||
message: intl.get(
|
||||
isNewMode
|
||||
? 'the_expense_has_been_created_successfully'
|
||||
: 'the_expense_has_been_edited_successfully',
|
||||
{ number: values.payment_account_id },
|
||||
),
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
setSubmitting(false);
|
||||
|
||||
if (submitPayload.redirect) {
|
||||
history.push('/expenses');
|
||||
}
|
||||
if (submitPayload.resetForm) {
|
||||
resetForm();
|
||||
}
|
||||
};
|
||||
|
||||
// Handle the request error.
|
||||
const handleError = ({
|
||||
response: {
|
||||
data: { errors },
|
||||
},
|
||||
}) => {
|
||||
transformErrors(errors, { setErrors });
|
||||
setSubmitting(false);
|
||||
};
|
||||
if (isNewMode) {
|
||||
createExpenseMutate(form).then(handleSuccess).catch(handleError);
|
||||
} else {
|
||||
editExpenseMutate([expense.id, form])
|
||||
.then(handleSuccess)
|
||||
.catch(handleError);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
CLASSES.PAGE_FORM,
|
||||
CLASSES.PAGE_FORM_STRIP_STYLE,
|
||||
CLASSES.PAGE_FORM_EXPENSE,
|
||||
)}
|
||||
>
|
||||
<Formik
|
||||
validationSchema={
|
||||
isNewMode ? CreateExpenseFormSchema : EditExpenseFormSchema
|
||||
}
|
||||
initialValues={initialValues}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<Form>
|
||||
<ExpenseFormHeader />
|
||||
<ExpenseFormBody />
|
||||
<ExpenseFormFooter />
|
||||
<ExpenseFloatingFooter />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDashboardActions,
|
||||
withMediaActions,
|
||||
withSettings(({ expenseSettings }) => ({
|
||||
preferredPaymentAccount: parseInt(
|
||||
expenseSettings?.preferredPaymentAccount,
|
||||
10,
|
||||
),
|
||||
})),
|
||||
withCurrentOrganization(),
|
||||
)(ExpenseForm);
|
||||
Reference in New Issue
Block a user