From cd27864f6df3599bded5300333fb47ab49d3cf19 Mon Sep 17 00:00:00 2001 From: elforjani3 Date: Sun, 25 Jul 2021 01:16:24 +0200 Subject: [PATCH] feat : allocate landed cost. --- .../AllocateLandedCostDialogProvider.js | 31 ++++- .../AllocateLandedCostEntriesTable.js | 49 +++----- .../AllocateLandedCostFloatingActions.js | 1 - .../AllocateLandedCostForm.js | 56 +++++++-- .../AllocateLandedCostFormBody.js | 14 ++- .../AllocateLandedCostFormContent.js | 1 + .../AllocateLandedCostFormFields.js | 109 +++++++++--------- .../Dialogs/AllocateLandedCostDialog/utils.js | 4 + client/src/hooks/query/landedCost.js | 7 +- client/src/lang/en/index.json | 4 +- 10 files changed, 161 insertions(+), 115 deletions(-) create mode 100644 client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js index aec4f85eb..ba4be03fa 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js @@ -1,27 +1,50 @@ import React from 'react'; import { DialogContent } from 'components'; -import { useBill } from 'hooks/query'; +import { useBill, useCreateLandedCost } from 'hooks/query'; -import { pick } from 'lodash'; +import { map, omit, pick } from 'lodash'; +import * as R from 'ramda'; const AllocateLandedCostDialogContext = React.createContext(); /** * Allocate landed cost provider. */ -function AllocateLandedCostDialogProvider({ billId, dialogName, ...props }) { +function AllocateLandedCostDialogProvider({ + billId, + query, + dialogName, + ...props +}) { // Handle fetch bill details. const { isLoading: isBillLoading, data: bill } = useBill(billId, { enabled: !!billId, }); + // Create landed cost mutations. + const { mutateAsync: createLandedCostMutate } = useCreateLandedCost(); + + // const L = [bill].map(({ entries: items }) => ({ + // items, + // })); + // let obj = { oldKey: 1, b: 2, c: 3 }; + // const { oldKey: newKey, ...rest } = obj; + // obj = { newKey, ...rest }; + + // const obj = { ...pick(bill, ['entries']).map((index) => index) }; + + // provider payload. const provider = { - bill: { + items: { ...pick(bill, ['entries']), }, dialogName, + query, + createLandedCostMutate, + billId, }; + return ( diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js index 171d88ce1..4400b0124 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js @@ -1,6 +1,6 @@ import React from 'react'; import intl from 'react-intl-universal'; -import { DataTable, MoneyFieldCell, DataTableEditable } from 'components'; +import { MoneyFieldCell, DataTableEditable } from 'components'; import { compose, updateTableRow } from 'utils'; /** @@ -10,12 +10,13 @@ export default function AllocateLandedCostEntriesTable({ onUpdateData, entries, }) { + // allocate landed cost entries table columns. const columns = React.useMemo( () => [ { Header: intl.get('item'), - accessor: 'item_id', + accessor: 'item.name', disableSortBy: true, width: '150', }, @@ -59,38 +60,14 @@ export default function AllocateLandedCostEntriesTable({ [onUpdateData, entries], ); - const LL = [ - { - item_id: 'ITEM', - quantity: '30000', - rate: '100000', - amount: '400', - }, - { - item_id: 'ITEM', - quantity: '30000', - rate: '100000', - amount: '400', - }, - { - item_id: 'ITEM', - quantity: '30000', - rate: '100000', - amount: '400', - }, - { - item_id: 'ITEM', - quantity: '30000', - rate: '100000', - amount: '400', - }, - { - item_id: 'ITEM', - quantity: '30000', - rate: '100000', - amount: '400', - }, - ]; - - return ; + return ( + + ); } diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js index ddc400903..8f16e5ec2 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js @@ -13,7 +13,6 @@ function AllocateLandedCostFloatingActions({ }) { // Formik context. const { isSubmitting } = useFormikContext(); - const { dialogName } = useAllocateLandedConstDialogContext(); // Handle cancel button click. diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js index 5ccffca48..d3f5ef983 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js @@ -1,24 +1,27 @@ import React from 'react'; import { Formik } from 'formik'; +import { Intent } from '@blueprintjs/core'; +import intl from 'react-intl-universal'; import moment from 'moment'; +import { pick, omit } from 'lodash'; import 'style/pages/AllocateLandedCost/AllocateLandedCostForm.scss'; +import { AppToaster } from 'components'; import { AllocateLandedCostFormSchema } from './AllocateLandedCostForm.schema'; import { useAllocateLandedConstDialogContext } from './AllocateLandedCostDialogProvider'; import AllocateLandedCostFormContent from './AllocateLandedCostFormContent'; import withDialogActions from 'containers/Dialog/withDialogActions'; - import { compose } from 'utils'; const defaultInitialValues = { - transaction_type: 'bills', + transaction_type: 'Bill', transaction_date: moment(new Date()).format('YYYY-MM-DD'), transaction_id: '', transaction_entry_id: '', amount: '', allocation_method: 'quantity', - entries: { + items: { entry_id: '', cost: '', }, @@ -31,26 +34,59 @@ function AllocateLandedCostForm({ // #withDialogActions closeDialog, }) { - const { bill, dialogName } = useAllocateLandedConstDialogContext(); + const { items, dialogName, createLandedCostMutate } = + useAllocateLandedConstDialogContext(); // Initial form values. const initialValues = { ...defaultInitialValues, - ...bill, + ...items, }; - // Handle form submit. - const handleFormSubmit = (values, { setSubmitting }) => {}; + const handleFormSubmit = (values, { setSubmitting }) => { + setSubmitting(false); + closeDialog(dialogName); + + const entries = [values] + .filter((entry) => entry.id && entry.cost) + .map((entry) => ({ + entry_id: entry.id, + ...pick(entry, ['cost']), + })); + + const form = { + ...values, + // items:{entries}, + }; + + // Handle the request success. + const onSuccess = (response) => { + AppToaster.show({ + message: intl.get('the_landed_cost_has_been_created_successfully'), + intent: Intent.SUCCESS, + }); + setSubmitting(false); + }; + + // Handle the request error. + const onError = ({ + response: { + data: { errors }, + }, + }) => { + setSubmitting(false); + }; + createLandedCostMutate(form).then(onSuccess).catch(onError); + }; return ( - - + component={AllocateLandedCostFormContent} + /> ); } diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js index 13029efd5..a0df6980a 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js @@ -13,12 +13,14 @@ export default function AllocateLandedCostFormBody() { field: { value }, meta: { error, touched }, }) => ( - { - setFieldValue('entries', newEntries); - }} - /> + <> + { + setFieldValue('entries', newEntries); + }} + /> + )} diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormContent.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormContent.js index c06d05a67..e1f5f08c0 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormContent.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormContent.js @@ -2,6 +2,7 @@ import React from 'react'; import { Form } from 'formik'; import AllocateLandedCostFormFields from './AllocateLandedCostFormFields'; import AllocateLandedCostFloatingActions from './AllocateLandedCostFloatingActions'; + /** * Allocate landed cost form content. */ diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js index a1639ca96..ea7b76a2f 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js @@ -1,34 +1,39 @@ import React from 'react'; -import { FastField, ErrorMessage } from 'formik'; +import { FastField, Field, ErrorMessage, useFormikContext } from 'formik'; import { Classes, FormGroup, RadioGroup, Radio, InputGroup, - Position, } from '@blueprintjs/core'; -import { DateInput } from '@blueprintjs/datetime'; import classNames from 'classnames'; import { FormattedMessage as T } from 'components'; import intl from 'react-intl-universal'; -import { - inputIntent, - momentFormatter, - tansformDateValue, - handleDateChange, - handleStringChange, -} from 'utils'; +import { inputIntent, handleStringChange } from 'utils'; import { FieldRequiredHint, ListSelect } from 'components'; import { CLASSES } from 'common/classes'; import allocateLandedCostType from 'common/allocateLandedCostType'; -import AccountsSuggestField from 'components/AccountsSuggestField'; +import { useLandedCostTransaction } from 'hooks/query'; + import AllocateLandedCostFormBody from './AllocateLandedCostFormBody'; +import { getEntriesByTransactionId } from './utils'; /** * Allocate landed cost form fields. */ export default function AllocateLandedCostFormFields() { + const { values } = useFormikContext(); + + const { + data: { transactions }, + } = useLandedCostTransaction(values.transaction_type); + + const transactionEntry = getEntriesByTransactionId( + transactions, + values.transaction_id, + ); + return (
{/*------------Transaction type -----------*/} @@ -61,69 +66,64 @@ export default function AllocateLandedCostFormFields() { )} - {/*------------Transaction date -----------*/} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - // labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} - minimal={true} - className={classNames(CLASSES.FILL, 'form-group--transaction_date')} - inline={true} - > - { - form.setFieldValue('transaction_date', formattedDate); - })} - value={tansformDateValue(value)} - popoverProps={{ - position: Position.BOTTOM, - minimal: true, - }} - /> - - )} - {/*------------ Transaction -----------*/} - - {({ form, field, meta: { error, touched } }) => ( + + {({ form, field: { value }, meta: { error, touched } }) => ( } // labelInfo={} intent={inputIntent({ error, touched })} helperText={} - className={'form-group--transaction_id'} + className={classNames(CLASSES.FILL, 'form-group--transaction_id')} inline={true} > - - form.setFieldValue('transaction_id', id) - } - inputProps={{ - placeholder: intl.get('select_transaction'), + { + form.setFieldValue('transaction_id', id); }} + filterable={false} + selectedItem={value} + selectedItemProp={'id'} + textProp={'name'} + labelProp={'id'} + defaultText={intl.get('select_transaction')} + popoverProps={{ minimal: true }} /> )} - + + {/*------------ Transaction line -----------*/} - - {({ form, field, meta: { error, touched } }) => ( + + {({ form, field: { value }, meta: { error, touched } }) => ( } intent={inputIntent({ error, touched })} helperText={} - className={'form-group--transaction_entry_id'} + className={classNames( + CLASSES.FILL, + 'form-group--transaction_entry_id', + )} inline={true} > - + { + form.setFieldValue('transaction_entry_id', id); + }} + filterable={false} + selectedItem={value} + selectedItemProp={'id'} + textProp={'name'} + labelProp={'id'} + defaultText={intl.get('select_transaction')} + popoverProps={{ minimal: true }} + /> )} - + + {/*------------ Amount -----------*/} {({ form, field, meta: { error, touched } }) => ( @@ -138,6 +138,7 @@ export default function AllocateLandedCostFormFields() { )} + {/*------------ Allocation method -----------*/} {({ form, field: { value }, meta: { touched, error } }) => ( @@ -158,7 +159,7 @@ export default function AllocateLandedCostFormFields() { inline={true} > } value="quantity" /> - } value="valuation" /> + } value="value" /> )} diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js new file mode 100644 index 000000000..b906a6ba0 --- /dev/null +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js @@ -0,0 +1,4 @@ +export function getEntriesByTransactionId(transactions, id) { + const transaction = transactions.find((trans) => trans.id === id); + return transaction ? transaction.entries : []; +} diff --git a/client/src/hooks/query/landedCost.js b/client/src/hooks/query/landedCost.js index 860835f4c..f9bb28497 100644 --- a/client/src/hooks/query/landedCost.js +++ b/client/src/hooks/query/landedCost.js @@ -63,8 +63,11 @@ export function useLandedCostTransaction(query, props) { params: { transaction_type: query }, }, { - select: (res) => res.data.transactions, - defaultData: [], + select: (res) => res.data, + + defaultData: { + transactions: [], + }, ...props, }, ); diff --git a/client/src/lang/en/index.json b/client/src/lang/en/index.json index 6ad074587..8e4e8053e 100644 --- a/client/src/lang/en/index.json +++ b/client/src/lang/en/index.json @@ -1138,6 +1138,6 @@ "located_landed_cost":"Located Landed Cost", "delete_transaction":"Delete transaction", "cannot_delete_bill_that_has_associated_landed_cost_transactions":"Cannot delete bill that has associated landed cost transactions.", - "couldn_t_delete_expense_transaction_has_associated_located_landed_cost_transaction":"Couldn't delete expense transaction has associated located landed cost transaction" - + "couldn_t_delete_expense_transaction_has_associated_located_landed_cost_transaction":"Couldn't delete expense transaction has associated located landed cost transaction", + "the_landed_cost_has_been_created_successfully":"The landed cost has been created successfully" } \ No newline at end of file