diff --git a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.js b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.js index 5246f894c..5fb142ac5 100644 --- a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.js +++ b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.js @@ -27,6 +27,8 @@ const defaultInitialValues = { reference_no: '', quantity_on_hand: '', publish: '', + branch_id: '', + warehouse_id: '', }; /** @@ -36,13 +38,8 @@ function InventoryAdjustmentForm({ // #withDialogActions closeDialog, }) { - const { - dialogName, - item, - itemId, - submitPayload, - createInventoryAdjMutate, - } = useInventoryAdjContext(); + const { dialogName, item, itemId, submitPayload, createInventoryAdjMutate } = + useInventoryAdjContext(); // Initial form values. const initialValues = { @@ -63,7 +60,9 @@ function InventoryAdjustmentForm({ closeDialog(dialogName); AppToaster.show({ - message: intl.get('the_adjustment_transaction_has_been_created_successfully'), + message: intl.get( + 'the_adjustment_transaction_has_been_created_successfully', + ), intent: Intent.SUCCESS, }); }) diff --git a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.schema.js b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.schema.js index 0926f5645..0a8810a75 100644 --- a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.schema.js +++ b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentForm.schema.js @@ -23,6 +23,8 @@ const Schema = Yup.object().shape({ reference_no: Yup.string(), new_quantity: Yup.number().required(), publish: Yup.boolean(), + branch_id: Yup.string(), + warehouse_id: Yup.string(), }); export const CreateInventoryAdjustmentFormSchema = Schema; diff --git a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormDialogFields.js b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormDialogFields.js index 9f6f2ca80..27e79cde2 100644 --- a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormDialogFields.js +++ b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormDialogFields.js @@ -1,4 +1,5 @@ import React from 'react'; +import styled from 'styled-components'; import { FastField, ErrorMessage, Field } from 'formik'; import { Classes, @@ -12,7 +13,17 @@ import { FormattedMessage as T } from 'components'; import intl from 'react-intl-universal'; import { DateInput } from '@blueprintjs/datetime'; import { useAutofocus } from 'hooks'; -import { ListSelect, FieldRequiredHint, Col, Row } from 'components'; +import { + ListSelect, + FieldRequiredHint, + Col, + Row, + FeatureCan, + BranchSelect, + WarehouseSelect, + BranchSelectButton, + WarehouseSelectButton, +} from 'components'; import { inputIntent, momentFormatter, @@ -21,26 +32,76 @@ import { toSafeNumber, } from 'utils'; import { CLASSES } from 'common/classes'; +import { Features } from 'common'; import adjustmentType from 'common/adjustmentType'; import AccountsSuggestField from 'components/AccountsSuggestField'; import { useInventoryAdjContext } from './InventoryAdjustmentFormProvider'; -import { diffQuantity } from './utils'; +import { + diffQuantity, + useSetPrimaryBranchToForm, + useSetPrimaryWarehouseToForm, +} from './utils'; +import { useFeatureCan } from 'hooks/state'; import InventoryAdjustmentQuantityFields from './InventoryAdjustmentQuantityFields'; /** * Inventory adjustment form dialogs fields. */ export default function InventoryAdjustmentFormDialogFields() { + // Features guard. + const { featureCan } = useFeatureCan(); + const dateFieldRef = useAutofocus(); // Inventory adjustment dialog context. - const { accounts } = useInventoryAdjContext(); + const { accounts, branches, warehouses } = useInventoryAdjContext(); - // Intl context. + // Sets the primary warehouse to form. + useSetPrimaryWarehouseToForm(); + + // Sets the primary branch to form. + useSetPrimaryBranchToForm(); return (
+ + + + } + className={classNames('form-group--select-list', Classes.FILL)} + > + + + + + + + } + className={classNames('form-group--select-list', Classes.FILL)} + > + + + + + + + {featureCan(Features.Warehouses) && featureCan(Features.Branches) && ( + + )} + {/*------------ Date -----------*/} @@ -173,3 +234,9 @@ export default function InventoryAdjustmentFormDialogFields() {
); } + +export const FeatureRowDivider = styled.div` + height: 2px; + background: #e9e9e9; + margin-bottom: 15px; +`; diff --git a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormProvider.js b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormProvider.js index 5e8c1ab1f..e61559f9e 100644 --- a/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormProvider.js +++ b/src/containers/Dialogs/InventoryAdjustmentFormDialog/InventoryAdjustmentFormProvider.js @@ -1,8 +1,12 @@ import React, { useState, createContext } from 'react'; import { DialogContent } from 'components'; +import { Features } from 'common'; +import { useFeatureCan } from 'hooks/state'; import { useItem, useAccounts, + useBranches, + useWarehouses, useCreateInventoryAdjustment, } from 'hooks/query'; @@ -12,29 +16,59 @@ const InventoryAdjustmentContext = createContext(); * Inventory adjustment dialog provider. */ function InventoryAdjustmentFormProvider({ itemId, dialogName, ...props }) { + // Features guard. + const { featureCan } = useFeatureCan(); + const isWarehouseFeatureCan = featureCan(Features.Warehouses); + const isBranchFeatureCan = featureCan(Features.Branches); + // Fetches accounts list. const { isFetching: isAccountsLoading, data: accounts } = useAccounts(); // Fetches the item details. const { isFetching: isItemLoading, data: item } = useItem(itemId); + // Fetch warehouses list. const { - mutateAsync: createInventoryAdjMutate, - } = useCreateInventoryAdjustment(); + data: warehouses, + isLoading: isWarehouesLoading, + isSuccess: isWarehousesSuccess, + } = useWarehouses({}, { enabled: isWarehouseFeatureCan }); + + // Fetches the branches list. + const { + data: branches, + isLoading: isBranchesLoading, + isSuccess: isBranchesSuccess, + } = useBranches({}, { enabled: isBranchFeatureCan }); + + const { mutateAsync: createInventoryAdjMutate } = + useCreateInventoryAdjustment(); // Submit payload. const [submitPayload, setSubmitPayload] = useState({}); + // Determines whether the warehouse and branches are loading. + const isFeatureLoading = isWarehouesLoading || isBranchesLoading; + // State provider. const provider = { - itemId, - isAccountsLoading, - accounts, - isItemLoading, item, - submitPayload, + itemId, + branches, + warehouses, + accounts, + dialogName, - + submitPayload, + + isBranchesSuccess, + isWarehousesSuccess, + isAccountsLoading, + isItemLoading, + isFeatureLoading, + isWarehouesLoading, + isBranchesLoading, + createInventoryAdjMutate, setSubmitPayload, }; @@ -46,6 +80,7 @@ function InventoryAdjustmentFormProvider({ itemId, dialogName, ...props }) { ); } -const useInventoryAdjContext = () => React.useContext(InventoryAdjustmentContext); +const useInventoryAdjContext = () => + React.useContext(InventoryAdjustmentContext); export { InventoryAdjustmentFormProvider, useInventoryAdjContext }; diff --git a/src/containers/Dialogs/InventoryAdjustmentFormDialog/utils.js b/src/containers/Dialogs/InventoryAdjustmentFormDialog/utils.js index 6492300d8..d6b659376 100644 --- a/src/containers/Dialogs/InventoryAdjustmentFormDialog/utils.js +++ b/src/containers/Dialogs/InventoryAdjustmentFormDialog/utils.js @@ -1,3 +1,7 @@ +import React from 'react'; +import { useFormikContext } from 'formik'; +import { useInventoryAdjContext } from './InventoryAdjustmentFormProvider'; +import { first } from 'lodash'; export const decrementQuantity = (newQuantity, quantityOnHand) => { return quantityOnHand - newQuantity; @@ -12,3 +16,34 @@ export const diffQuantity = (newQuantity, quantityOnHand, type) => { ? decrementQuantity(newQuantity, quantityOnHand) : incrementQuantity(newQuantity, quantityOnHand); }; + +export const useSetPrimaryWarehouseToForm = () => { + const { setFieldValue } = useFormikContext(); + const { warehouses, isWarehousesSuccess } = useInventoryAdjContext(); + + React.useEffect(() => { + if (isWarehousesSuccess) { + const primaryWarehouse = + warehouses.find((b) => b.primary) || first(warehouses); + + if (primaryWarehouse) { + setFieldValue('warehouse_id', primaryWarehouse.id); + } + } + }, [isWarehousesSuccess, setFieldValue, warehouses]); +}; + +export const useSetPrimaryBranchToForm = () => { + const { setFieldValue } = useFormikContext(); + const { branches, isBranchesSuccess } = useInventoryAdjContext(); + + React.useEffect(() => { + if (isBranchesSuccess) { + const primaryBranch = branches.find((b) => b.primary) || first(branches); + + if (primaryBranch) { + setFieldValue('branch_id', primaryBranch.id); + } + } + }, [isBranchesSuccess, setFieldValue, branches]); +}; diff --git a/src/lang/en/index.json b/src/lang/en/index.json index 2a568d6ea..603e82507 100644 --- a/src/lang/en/index.json +++ b/src/lang/en/index.json @@ -1844,6 +1844,7 @@ "branches.column.code": "Code", "select_branch": "Select branch", "branch": "Branch", + "warehouse":"Warehouse", "branch.dialog.label_new_branch": "New Branch", "branch.dialog.label_edit_branch": "New Branch", "branch.dialog.label.branch_name": "Branch Name", diff --git a/src/style/pages/PaymentReceive/QuickPaymentReceiveDialog.scss b/src/style/pages/PaymentReceive/QuickPaymentReceiveDialog.scss index 4c8ef838a..ad208a3a9 100644 --- a/src/style/pages/PaymentReceive/QuickPaymentReceiveDialog.scss +++ b/src/style/pages/PaymentReceive/QuickPaymentReceiveDialog.scss @@ -1,8 +1,6 @@ .dialog--quick-payment-receive { - .bp3-dialog-body { - line-height: 14px; .bp3-form-group { - margin-bottom: 13px; + margin-bottom: 15px; label.bp3-label { margin-bottom: 3px; @@ -25,5 +23,4 @@ .bp3-dialog-footer { padding-top: 10px; - } }