From 77d987ef1f23e63a3bca894d7985bf24aecccddc Mon Sep 17 00:00:00 2001 From: "a.bouhuolia" Date: Sun, 25 Jul 2021 12:58:33 +0200 Subject: [PATCH] WIP: allocate landed cost. --- .../AllocateLandedCostDialogContent.js | 4 +- .../AllocateLandedCostDialogProvider.js | 18 +---- .../AllocateLandedCostEntriesTable.js | 3 +- .../AllocateLandedCostFloatingActions.js | 6 +- .../AllocateLandedCostForm.js | 50 +++++++------- .../AllocateLandedCostForm.schema.js | 2 +- .../AllocateLandedCostFormBody.js | 16 ++--- .../AllocateLandedCostFormFields.js | 68 ++++++++++--------- .../Dialogs/AllocateLandedCostDialog/index.js | 2 +- .../Dialogs/AllocateLandedCostDialog/utils.js | 3 + client/src/hooks/query/landedCost.js | 3 +- client/src/lang/en/index.js | 3 +- .../AllocateLandedCostForm.scss | 22 +++++- 13 files changed, 108 insertions(+), 92 deletions(-) diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogContent.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogContent.js index 1f574d9fa..75ddad1c5 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogContent.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogContent.js @@ -8,10 +8,10 @@ import AllocateLandedCostForm from './AllocateLandedCostForm'; export default function AllocateLandedCostDialogContent({ // #ownProps dialogName, - bill, + billId, }) { return ( - + ); diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js index ba4be03fa..780ea0621 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.js @@ -2,9 +2,6 @@ import React from 'react'; import { DialogContent } from 'components'; import { useBill, useCreateLandedCost } from 'hooks/query'; -import { map, omit, pick } from 'lodash'; -import * as R from 'ramda'; - const AllocateLandedCostDialogContext = React.createContext(); /** @@ -24,21 +21,10 @@ function AllocateLandedCostDialogProvider({ // 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 = { - items: { - ...pick(bill, ['entries']), - }, + isBillLoading, + bill, dialogName, query, createLandedCostMutate, diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js index 4400b0124..cb0b41aaa 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostEntriesTable.js @@ -10,8 +10,7 @@ export default function AllocateLandedCostEntriesTable({ onUpdateData, entries, }) { - - // allocate landed cost entries table columns. + // Allocate landed cost entries table columns. const columns = React.useMemo( () => [ { diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js index 8f16e5ec2..2b4cded08 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.js @@ -23,14 +23,14 @@ function AllocateLandedCostFloatingActions({ return (
- diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js index d3f5ef983..3dccf250d 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.js @@ -3,7 +3,6 @@ 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'; @@ -12,8 +11,9 @@ import { AllocateLandedCostFormSchema } from './AllocateLandedCostForm.schema'; import { useAllocateLandedConstDialogContext } from './AllocateLandedCostDialogProvider'; import AllocateLandedCostFormContent from './AllocateLandedCostFormContent'; import withDialogActions from 'containers/Dialog/withDialogActions'; -import { compose } from 'utils'; +import { compose, transformToForm } from 'utils'; +// Default form initial values. const defaultInitialValues = { transaction_type: 'Bill', transaction_date: moment(new Date()).format('YYYY-MM-DD'), @@ -21,10 +21,12 @@ const defaultInitialValues = { transaction_entry_id: '', amount: '', allocation_method: 'quantity', - items: { - entry_id: '', - cost: '', - }, + items: [ + { + entry_id: '', + cost: '', + }, + ], }; /** @@ -34,32 +36,36 @@ function AllocateLandedCostForm({ // #withDialogActions closeDialog, }) { - const { items, dialogName, createLandedCostMutate } = + const { dialogName, bill, billId, createLandedCostMutate } = useAllocateLandedConstDialogContext(); // Initial form values. const initialValues = { ...defaultInitialValues, - ...items, + items: bill.entries.map((entry) => ({ + ...entry, + entry_id: entry.id, + cost: '', + })), }; // Handle form submit. 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']), - })); + // Filters the entries has no cost. + const entries = values.items + .filter((entry) => entry.entry_id && entry.cost) + .map((entry) => transformToForm(entry, defaultInitialValues.items[0])); + if (entries.length <= 0) { + AppToaster.show({ message: 'Something wrong!', intent: Intent.DANGER }); + return; + } const form = { ...values, - // items:{entries}, + items: entries, }; - // Handle the request success. const onSuccess = (response) => { AppToaster.show({ @@ -67,17 +73,15 @@ function AllocateLandedCostForm({ intent: Intent.SUCCESS, }); setSubmitting(false); + closeDialog(dialogName); }; // Handle the request error. - const onError = ({ - response: { - data: { errors }, - }, - }) => { + const onError = () => { setSubmitting(false); + AppToaster.show({ message: 'Something went wrong!', intent: Intent.DANGER }); }; - createLandedCostMutate(form).then(onSuccess).catch(onError); + createLandedCostMutate([billId, form]).then(onSuccess).catch(onError); }; return ( diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.schema.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.schema.js index 176514808..0751bd67f 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.schema.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostForm.schema.js @@ -8,7 +8,7 @@ const Schema = Yup.object().shape({ transaction_entry_id: Yup.string().label(intl.get('transaction_line')), amount: Yup.number().label(intl.get('amount')), allocation_method: Yup.string().trim(), - entries: Yup.array().of( + items: Yup.array().of( Yup.object().shape({ entry_id: Yup.number().nullable(), cost: Yup.number().nullable(), diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js index a0df6980a..2e57fa57e 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormBody.js @@ -7,20 +7,18 @@ import AllocateLandedCostEntriesTable from './AllocateLandedCostEntriesTable'; export default function AllocateLandedCostFormBody() { return (
- + {({ form: { setFieldValue, values }, field: { value }, meta: { error, touched }, }) => ( - <> - { - setFieldValue('entries', newEntries); - }} - /> - + { + setFieldValue('items', newEntries); + }} + /> )}
diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js index ea7b76a2f..bb30785ce 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.js @@ -8,7 +8,7 @@ import { InputGroup, } from '@blueprintjs/core'; import classNames from 'classnames'; -import { FormattedMessage as T } from 'components'; +import { FormattedMessage as T, If } from 'components'; import intl from 'react-intl-universal'; import { inputIntent, handleStringChange } from 'utils'; import { FieldRequiredHint, ListSelect } from 'components'; @@ -29,10 +29,11 @@ export default function AllocateLandedCostFormFields() { data: { transactions }, } = useLandedCostTransaction(values.transaction_type); - const transactionEntry = getEntriesByTransactionId( + // Retrieve entries of the given transaction id. + const transactionEntries = React.useMemo(() => getEntriesByTransactionId( transactions, values.transaction_id, - ); + ), [transactions, values.transaction_id]); return (
@@ -71,7 +72,7 @@ export default function AllocateLandedCostFormFields() { {({ form, field: { value }, meta: { error, touched } }) => ( } - // labelInfo={} + labelInfo={} intent={inputIntent({ error, touched })} helperText={} className={classNames(CLASSES.FILL, 'form-group--transaction_id')} @@ -95,34 +96,37 @@ export default function AllocateLandedCostFormFields() { {/*------------ Transaction line -----------*/} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - intent={inputIntent({ error, touched })} - helperText={} - 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 }} - /> - - )} - + 0}> + + {({ form, field: { value }, meta: { error, touched } }) => ( + } + intent={inputIntent({ error, touched })} + helperText={} + className={classNames( + CLASSES.FILL, + 'form-group--transaction_entry_id', + )} + inline={true} + > + { + form.setFieldValue('amount', amount) + 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 -----------*/} diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/index.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/index.js index 5798a5aba..de65ae01b 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/index.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/index.js @@ -25,7 +25,7 @@ function AllocateLandedCostDialog({ > diff --git a/client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js b/client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js index b906a6ba0..fed205e5b 100644 --- a/client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js +++ b/client/src/containers/Dialogs/AllocateLandedCostDialog/utils.js @@ -1,3 +1,6 @@ +/** + * Retrieve transaction entries of the given transaction id. + */ 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 f9bb28497..6249a6061 100644 --- a/client/src/hooks/query/landedCost.js +++ b/client/src/hooks/query/landedCost.js @@ -21,7 +21,8 @@ export function useCreateLandedCost(props) { const apiRequest = useApiRequest(); return useMutation( - (id) => apiRequest.post(`purchases/landed-cost/bills/${id}/allocate`), + ([id, values]) => + apiRequest.post(`purchases/landed-cost/bills/${id}/allocate`, values), { onSuccess: (res, id) => { // Common invalidate queries. diff --git a/client/src/lang/en/index.js b/client/src/lang/en/index.js index 8de51d797..897136ef1 100644 --- a/client/src/lang/en/index.js +++ b/client/src/lang/en/index.js @@ -1067,6 +1067,7 @@ export default { cash_flow_statement: 'Cash Flow Statement', statement_of_cash_flow: 'Statement of Cash Flow ', inventory_item_details: 'Inventory Item Details', - congratulations: 'Congratulations' + congratulations: 'Congratulations', + "all_items" }; diff --git a/client/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss b/client/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss index fe15f6d73..1040746e2 100644 --- a/client/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss +++ b/client/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss @@ -3,9 +3,12 @@ width: 700px; .bp3-dialog-body { + .bp3-form-group{ + margin-bottom: 18px; + } .bp3-form-group.bp3-inline { .bp3-label { - min-width: 140px; + min-width: 150px; } .bp3-form-content { width: 300px; @@ -17,6 +20,10 @@ } } + .bp3-dialog-footer{ + padding-top: 10px; + } + .bigcapital-datatable { .table { // max-height: 300px; @@ -37,6 +44,19 @@ margin-left: -1px; border-left: 1px solid #ececec; } + + .bp3-form-group{ + margin-bottom: 0; + + &:not(.bp3-intent-danger) .bp3-input{ + border: 1px solid #d0dfe2; + + &:focus{ + box-shadow: 0 0 0 1px #116cd0; + border-color: #116cd0; + } + } + } } } }