From c148e2976a6ab8d042703f88e224319793fc34f1 Mon Sep 17 00:00:00 2001 From: elforjani13 <39470382+elforjani13@users.noreply.github.com> Date: Sun, 17 Oct 2021 18:00:40 +0200 Subject: [PATCH] feat : Cash flow transaction type. --- src/common/cashflowOptions.js | 16 +- .../AccountTransactionsActionsBar.js | 4 +- .../AccountTransactionsProvider.js | 4 +- .../MoneyInDialog/MoneyInDialogForm.js | 10 +- .../OtherIncome/OtherIncomeForm.js | 5 +- .../OtherIncome/OtherIncomeForm.schema.js | 6 +- .../OtherIncome/OtherIncomeFormFields.js | 22 +- .../OwnerContributionForm.js | 5 +- .../OwnerContributionForm.schema.js | 6 +- .../OwnerContributionFormFields.js | 16 +- .../TransferFromAccountForm.js | 92 ++++++++ .../TransferFromAccountForm.schema.js | 22 ++ .../TransferFromAccountFormContent.js | 14 ++ .../TransferFromAccountFormFields.js | 198 ++++++++++++++++++ .../MoneyOutDialog/MoneyOutDialogContent.js | 5 +- .../MoneyOutDialog/MoneyOutDialogForm.js | 24 +++ .../MoneyOutDialog/MoneyOutProvider.js | 12 +- .../OtherExpenseFloatingActions.js | 76 +++++++ .../OtherExpense/OtherExpenseForm.js | 92 ++++++++ .../OtherExpense/OtherExpenseForm.schema.js | 22 ++ .../OtherExpense/OtherExpenseFormContent.js | 17 ++ .../OtherExpense/OtherExpnseFormFields.js | 195 +++++++++++++++++ .../OwnerDrawingsFloatingActions.js | 2 +- .../OwnerDrawings/OwnerDrawingsForm.js | 31 ++- .../OwnerDrawings/OwnerDrawingsForm.schema.js | 5 +- .../OwnerDrawings/OwnerDrawingsFormFields.js | 22 +- .../TransferToAccountFloatingActions.js | 73 +++++++ .../TransferToAccountForm.js | 92 ++++++++ .../TransferToAccountForm.schema.js | 22 ++ .../TransferToAccountFormFields.js | 198 ++++++++++++++++++ .../TransferToAccountFromContent.js | 14 ++ src/lang/en/index.json | 7 +- .../CashFlow/CashflowTransactionForm.scss | 7 +- 33 files changed, 1273 insertions(+), 63 deletions(-) create mode 100644 src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.js create mode 100644 src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.schema.js create mode 100644 src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormContent.js create mode 100644 src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormFields.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/MoneyOutDialogForm.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/OtherExpense/OtherExpenseFloatingActions.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/OtherExpense/OtherExpenseForm.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/OtherExpense/OtherExpenseForm.schema.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/OtherExpense/OtherExpenseFormContent.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/OtherExpense/OtherExpnseFormFields.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/TransferToAccount/TransferToAccountFloatingActions.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/TransferToAccount/TransferToAccountForm.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/TransferToAccount/TransferToAccountForm.schema.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/TransferToAccount/TransferToAccountFormFields.js create mode 100644 src/containers/Dialogs/MoneyOutDialog/TransferToAccount/TransferToAccountFromContent.js diff --git a/src/common/cashflowOptions.js b/src/common/cashflowOptions.js index 86a6a8863..6ff7401f5 100644 --- a/src/common/cashflowOptions.js +++ b/src/common/cashflowOptions.js @@ -3,25 +3,29 @@ import intl from 'react-intl-universal'; export const addMoneyIn = [ { name: intl.get('cash_flow.option_owner_contribution'), - type: 'OWNERS', + type: 'OWNER_CONTRIBUTION', }, { name: intl.get('cash_flow.option_other_income'), - type: 'EQUITY', + type: 'OTHER_INCOME', + }, + { + name: intl.get('cash_flow.option_transfer_form_account'), + type: 'TRANSFER_FROM_ACCOUNT', }, ]; export const addMoneyOut = [ { name: intl.get('cash_flow.option_owner_drawings'), - type: 'OWNERS', + type: 'ONWERS_DRAWING', }, { name: intl.get('cash_flow.option_expenses'), - type: 'EXPENSES', + type: 'OTHER_EXPENSE', }, { - name: intl.get('cash_flow.option_vendor_payment'), - type: '', + name: intl.get('cash_flow.option_transfer_to_account'), + type: 'TRANSFER_TO_ACCOUNT', }, ]; diff --git a/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.js b/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.js index 2aa0206ca..4615a8cf3 100644 --- a/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.js +++ b/src/containers/CashFlow/AccountTransactions/AccountTransactionsActionsBar.js @@ -36,7 +36,7 @@ function AccountTransactionsActionsBar({ const handleMoneyInFormTransaction = (value) => { openDialog('money-in', { account_type: value.type, - account_id: accountId.id, + account_id: accountId, }); }; @@ -44,7 +44,7 @@ function AccountTransactionsActionsBar({ const handlMoneyOutFormTransaction = (value) => { openDialog('money-out', { account_type: value.type, - account_id: accountId.id, + account_id: accountId, }); }; return ( diff --git a/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.js b/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.js index de67a1a60..a7b501d15 100644 --- a/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.js +++ b/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.js @@ -10,7 +10,8 @@ const AccountTransactionsContext = React.createContext(); * Account transctions provider. */ function AccountTransactionsProvider({ query, ...props }) { - const accountId = useParams(); + const { id } = useParams(); + const accountId = parseInt(id, 10); // Fetch cashflow account transactions list const { @@ -21,7 +22,6 @@ function AccountTransactionsProvider({ query, ...props }) { enabled: !!accountId, }); - // Provider payload. const provider = { accountId, diff --git a/src/containers/Dialogs/MoneyInDialog/MoneyInDialogForm.js b/src/containers/Dialogs/MoneyInDialog/MoneyInDialogForm.js index 6becf35d8..6ea90e77a 100644 --- a/src/containers/Dialogs/MoneyInDialog/MoneyInDialogForm.js +++ b/src/containers/Dialogs/MoneyInDialog/MoneyInDialogForm.js @@ -1,20 +1,24 @@ import React from 'react'; import OwnerContributionForm from './OwnerContribution/OwnerContributionForm'; import OtherIncomeForm from './OtherIncome/OtherIncomeForm'; +import TransferFromAccountForm from './TransferFromAccount/TransferFromAccountForm'; export default function MoneyInDialogForm({ accountType }) { // Handle from transaction. const handleFromTransaction = () => { switch (accountType) { - case 'OWNERS': + case 'OWNER_CONTRIBUTION': return ; - case 'EQUITY': + case 'OTHER_INCOME': return ; + + case 'TRANSFER_FROM_ACCOUNT': + return ; default: break; } }; - return
{handleFromTransaction()}
; + return {handleFromTransaction()}; } diff --git a/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.js b/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.js index 8ffcab15a..3f47fc31b 100644 --- a/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.js +++ b/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.js @@ -2,6 +2,7 @@ import React from 'react'; import moment from 'moment'; import { Intent } from '@blueprintjs/core'; import { Formik } from 'formik'; +import { omit } from 'lodash'; import intl from 'react-intl-universal'; import 'style/pages/CashFlow/CashflowTransactionForm.scss'; @@ -50,13 +51,13 @@ function OtherIncomeForm({ const initialValues = { ...defaultInitialValues, currency_code: base_currency, - credit_account_id: accountId, + cashflow_account_id: accountId, }; // Handles the form submit. const handleFormSubmit = (values, { setSubmitting, setErrors }) => { const form = { - ...values, + ...omit(values, ['currency_code']), published: submitPayload.publish, }; setSubmitting(true); diff --git a/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.schema.js b/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.schema.js index f6178739d..300f98511 100644 --- a/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.schema.js +++ b/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeForm.schema.js @@ -6,12 +6,12 @@ const Schema = Yup.object().shape({ date: Yup.date().required().label(intl.get('date')), amount: Yup.number().required().label(intl.get('amount')), transaction_number: Yup.string(), - transaction_type: Yup.string().required().label(intl.get('transaction_type')), + transaction_type: Yup.string().required(), reference_no: Yup.string(), - credit_account_id: Yup.number().required(), - cashflow_account_id: Yup.string() + credit_account_id: Yup.number() .required() .label(intl.get('other_income_account')), + cashflow_account_id: Yup.string().required(), description: Yup.string() .min(3) .max(DATATYPES_LENGTH.TEXT) diff --git a/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeFormFields.js b/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeFormFields.js index a181ccd4a..0a2544b96 100644 --- a/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeFormFields.js +++ b/src/containers/Dialogs/MoneyInDialog/OtherIncome/OtherIncomeFormFields.js @@ -14,10 +14,14 @@ import { AccountsSuggestField, InputPrependText, MoneyInputGroup, + FieldRequiredHint, + Col, + Row, } from 'components'; import { DateInput } from '@blueprintjs/datetime'; import { useAutofocus } from 'hooks'; -import { FieldRequiredHint, Col, Row } from 'components'; +import { ACCOUNT_TYPE } from 'common/accountTypes'; + import { inputIntent, momentFormatter, @@ -28,7 +32,7 @@ import { CLASSES } from 'common/classes'; import { useMoneyInDailogContext } from '../MoneyInDialogProvider'; /** - * Other income form fiedls. + * Other income form fields. */ function OtherIncomeFormFields() { // Money in dialog context. @@ -120,20 +124,24 @@ function OtherIncomeFormFields() { {/*------------ other income account -----------*/} - + {({ form, field, meta: { error, touched } }) => ( } + label={} labelInfo={} intent={inputIntent({ error, touched })} - helperText={} - className={'form-group--cashflow_account_id'} + helperText={} + className={'form-group--credit_account_id'} > - form.setFieldValue('cashflow_account_id', id) + form.setFieldValue('credit_account_id', id) } + filterByTypes={[ + ACCOUNT_TYPE.INCOME, + ACCOUNT_TYPE.OTHER_INCOME, + ]} inputProps={{ intent: inputIntent({ error, touched }), }} diff --git a/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.js b/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.js index 305bce64b..e7ff7bfaf 100644 --- a/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.js +++ b/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.js @@ -2,6 +2,7 @@ import React from 'react'; import moment from 'moment'; import { Intent } from '@blueprintjs/core'; import { Formik } from 'formik'; +import { omit } from 'lodash'; import intl from 'react-intl-universal'; import 'style/pages/CashFlow/CashflowTransactionForm.scss'; @@ -50,13 +51,13 @@ function OwnerContributionForm({ const initialValues = { ...defaultInitialValues, currency_code: base_currency, - credit_account_id: accountId, + cashflow_account_id: accountId, }; // Handles the form submit. const handleFormSubmit = (values, { setSubmitting, setErrors }) => { const form = { - ...values, + ...omit(values, ['currency_code']), published: submitPayload.publish, }; setSubmitting(true); diff --git a/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.schema.js b/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.schema.js index a55931df1..b877c0e26 100644 --- a/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.schema.js +++ b/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionForm.schema.js @@ -6,12 +6,12 @@ const Schema = Yup.object().shape({ date: Yup.date().required().label(intl.get('date')), amount: Yup.number().required().label(intl.get('amount')), transaction_number: Yup.string(), - transaction_type: Yup.string().required().label(intl.get('transaction_type')), + transaction_type: Yup.string().required(), reference_no: Yup.string(), - credit_account_id: Yup.number().required(), - cashflow_account_id: Yup.string() + credit_account_id: Yup.number() .required() .label(intl.get('cash_flow_transaction.label_equity_account')), + cashflow_account_id: Yup.string().required(), description: Yup.string() .min(3) .max(DATATYPES_LENGTH.TEXT) diff --git a/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionFormFields.js b/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionFormFields.js index 1effb9d14..6bcea0830 100644 --- a/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionFormFields.js +++ b/src/containers/Dialogs/MoneyInDialog/OwnerContribution/OwnerContributionFormFields.js @@ -14,10 +14,13 @@ import { AccountsSuggestField, InputPrependText, MoneyInputGroup, + FieldRequiredHint, + Col, + Row, } from 'components'; import { DateInput } from '@blueprintjs/datetime'; import { useAutofocus } from 'hooks'; -import { FieldRequiredHint, Col, Row } from 'components'; +import { ACCOUNT_TYPE } from 'common/accountTypes'; import { inputIntent, momentFormatter, @@ -118,21 +121,22 @@ function OwnerContributionFormFields() { - {/*------------ cash flow account -----------*/} - + {/*------------ equity account -----------*/} + {({ form, field, meta: { error, touched } }) => ( } labelInfo={} intent={inputIntent({ error, touched })} - helperText={} - className={'form-group--cashflow_account_id'} + helperText={} + className={'form-group--credit_account_id'} > - form.setFieldValue('cashflow_account_id', id) + form.setFieldValue('credit_account_id', id) } + filterByTypes={ACCOUNT_TYPE.EQUITY} inputProps={{ intent: inputIntent({ error, touched }), }} diff --git a/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.js b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.js new file mode 100644 index 000000000..17636469a --- /dev/null +++ b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.js @@ -0,0 +1,92 @@ +import React from 'react'; +import moment from 'moment'; +import { Intent } from '@blueprintjs/core'; +import { Formik } from 'formik'; +import { omit } from 'lodash'; +import intl from 'react-intl-universal'; + +import 'style/pages/CashFlow/CashflowTransactionForm.scss'; + +import { AppToaster } from 'components'; +import { CreateTransferFromAccountFormSchema } from './TransferFromAccountForm.schema'; +import TransferFromAccountFormContent from './TransferFromAccountFormContent'; + +import { useMoneyInDailogContext } from '../MoneyInDialogProvider'; + +import withDialogActions from 'containers/Dialog/withDialogActions'; +import withCurrentOrganization from 'containers/Organization/withCurrentOrganization'; + +import { compose } from 'utils'; + +const defaultInitialValues = { + date: moment(new Date()).format('YYYY-MM-DD'), + amount: '', + transaction_number: '', + transaction_type: 'transfer_from_account', + reference_no: '', + cashflow_account_id: '', + credit_account_id: '', + description: '', + published: '', +}; + +/** + * Transfer from account form. + */ +function TransferFromAccountForm({ + // #withDialogActions + closeDialog, + + // #withCurrentOrganization + organization: { base_currency }, +}) { + const { + dialogName, + accountId, + createCashflowTransactionMutate, + submitPayload, + } = useMoneyInDailogContext(); + + // Initial form values. + const initialValues = { + ...defaultInitialValues, + currency_code: base_currency, + cashflow_account_id: accountId, + }; + + // Handles the form submit. + const handleFormSubmit = (values, { setSubmitting, setErrors }) => { + const form = { + ...omit(values, ['currency_code']), + published: submitPayload.publish, + }; + setSubmitting(true); + createCashflowTransactionMutate(form) + .then(() => { + closeDialog(dialogName); + + AppToaster.show({ + message: intl.get('cash_flow_transaction_success_message'), + intent: Intent.SUCCESS, + }); + }) + .finally(() => { + setSubmitting(true); + }); + }; + + return ( + + + + ); +} + +export default compose( + withDialogActions, + withCurrentOrganization(), +)(TransferFromAccountForm); diff --git a/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.schema.js b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.schema.js new file mode 100644 index 000000000..3e1786695 --- /dev/null +++ b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountForm.schema.js @@ -0,0 +1,22 @@ +import * as Yup from 'yup'; +import intl from 'react-intl-universal'; +import { DATATYPES_LENGTH } from 'common/dataTypes'; + +const Schema = Yup.object().shape({ + date: Yup.date().required().label(intl.get('date')), + amount: Yup.number().required().label(intl.get('amount')), + transaction_number: Yup.string(), + transaction_type: Yup.string().required(), + reference_no: Yup.string(), + credit_account_id: Yup.number() + .required() + .label(intl.get('cash_flow_transaction.label_transfer_account')), + cashflow_account_id: Yup.string().required(), + description: Yup.string() + .min(3) + .max(DATATYPES_LENGTH.TEXT) + .label(intl.get('description')), + published: Yup.boolean(), +}); + +export const CreateTransferFromAccountFormSchema = Schema; diff --git a/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormContent.js b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormContent.js new file mode 100644 index 000000000..073a893e2 --- /dev/null +++ b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormContent.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { Form } from 'formik'; + +import TransferFromAccountFormFields from './TransferFromAccountFormFields'; +import MoneyInFloatingActions from '../MoneyInFloatingActions'; + +export default function TransferFromAccountFormContent() { + return ( +
+ + + + ); +} diff --git a/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormFields.js b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormFields.js new file mode 100644 index 000000000..c3d2496c1 --- /dev/null +++ b/src/containers/Dialogs/MoneyInDialog/TransferFromAccount/TransferFromAccountFormFields.js @@ -0,0 +1,198 @@ +import React from 'react'; +import { FastField, ErrorMessage } from 'formik'; +import { + Classes, + FormGroup, + InputGroup, + TextArea, + Position, + ControlGroup, +} from '@blueprintjs/core'; +import classNames from 'classnames'; +import { + FormattedMessage as T, + AccountsSuggestField, + InputPrependText, + MoneyInputGroup, + FieldRequiredHint, + Col, + Row, +} from 'components'; +import { DateInput } from '@blueprintjs/datetime'; +import { useAutofocus } from 'hooks'; +import { ACCOUNT_TYPE } from 'common/accountTypes'; + +import { + inputIntent, + momentFormatter, + tansformDateValue, + handleDateChange, +} from 'utils'; +import { CLASSES } from 'common/classes'; +import { useMoneyInDailogContext } from '../MoneyInDialogProvider'; + +/** + * Transfer from account form fields. + */ +function TransferFromAccountFormFields() { + // Money in dialog context. + const { accounts } = useMoneyInDailogContext(); + + const amountFieldRef = useAutofocus(); + + return ( +
+ + + {/*------------ Date -----------*/} + + {({ form, field: { value }, meta: { error, touched } }) => ( + } + labelInfo={} + intent={inputIntent({ error, touched })} + helperText={} + minimal={true} + className={classNames(CLASSES.FILL, 'form-group--date')} + > + { + form.setFieldValue('date', formattedDate); + })} + value={tansformDateValue(value)} + popoverProps={{ + position: Position.BOTTOM, + minimal: true, + }} + intent={inputIntent({ error, touched })} + /> + + )} + + + + {/*------------ Transaction number -----------*/} + + {({ form, field, meta: { error, touched } }) => ( + } + intent={inputIntent({ error, touched })} + helperText={} + className={'form-group--transaction_number'} + > + + + )} + + + + {/*------------ amount -----------*/} + + {({ + form: { values, setFieldValue }, + field: { value }, + meta: { error, touched }, + }) => ( + } + labelInfo={} + intent={inputIntent({ error, touched })} + helperText={} + className={'form-group--amount'} + > + + + + { + setFieldValue('amount', amount); + }} + inputRef={(ref) => (amountFieldRef.current = ref)} + intent={inputIntent({ error, touched })} + /> + + + )} + + + + + {/*------------ transfer from account -----------*/} + + {({ form, field, meta: { error, touched } }) => ( + + } + labelInfo={} + intent={inputIntent({ error, touched })} + helperText={} + className={'form-group--credit_account_id'} + > + + form.setFieldValue('credit_account_id', id) + } + filterByTypes={[ + ACCOUNT_TYPE.CASH, + ACCOUNT_TYPE.BANK, + ACCOUNT_TYPE.CREDIT_CARD, + ]} + inputProps={{ + intent: inputIntent({ error, touched }), + }} + /> + + )} + + + + {/*------------ Reference -----------*/} + + {({ form, field, meta: { error, touched } }) => ( + } + intent={inputIntent({ error, touched })} + helperText={} + className={'form-group--reference-no'} + > + + + )} + + + + {/*------------ description -----------*/} + + {({ field, meta: { error, touched } }) => ( + } + className={'form-group--description'} + intent={inputIntent({ error, touched })} + helperText={} + > +