feat(InventoryItemDetail): Location query.

This commit is contained in:
a.bouhuolia
2022-03-23 21:28:13 +02:00
parent 8fc11b3237
commit 73cb0ec32e
6 changed files with 105 additions and 46 deletions

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect } from 'react';
import moment from 'moment'; import moment from 'moment';
import { FinancialStatement } from 'components'; import { FinancialStatement } from 'components';
@@ -8,30 +8,25 @@ import InventoryItemDetailsActionsBar from './InventoryItemDetailsActionsBar';
import InventoryItemDetailsHeader from './InventoryItemDetailsHeader'; import InventoryItemDetailsHeader from './InventoryItemDetailsHeader';
import withInventoryItemDetailsActions from './withInventoryItemDetailsActions'; import withInventoryItemDetailsActions from './withInventoryItemDetailsActions';
import withCurrentOrganization from '../../../containers/Organization/withCurrentOrganization';
import { InventoryItemDetailsProvider } from './InventoryItemDetailsProvider'; import { InventoryItemDetailsProvider } from './InventoryItemDetailsProvider';
import { import {
InventoryItemDetailsLoadingBar, InventoryItemDetailsLoadingBar,
InventoryItemDetailsAlerts, InventoryItemDetailsAlerts,
} from './components'; } from './components';
import { compose } from 'utils';
import { InventoryItemDetailsBody } from './InventoryItemDetailsBody'; import { InventoryItemDetailsBody } from './InventoryItemDetailsBody';
import { useInventoryValuationQuery } from './utils2';
import { compose } from 'utils';
/** /**
* inventory item details. * inventory item details.
*/ */
function InventoryItemDetails({ function InventoryItemDetails({
// #withSettings
organizationName,
//#withInventoryItemDetailsActions //#withInventoryItemDetailsActions
toggleInventoryItemDetailsFilterDrawer: toggleFilterDrawer, toggleInventoryItemDetailsFilterDrawer: toggleFilterDrawer,
}) { }) {
const [filter, setFilter] = useState({ const { query, setLocationQuery } = useInventoryValuationQuery();
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
});
// Handle filter submit. // Handle filter submit.
const handleFilterSubmit = (filter) => { const handleFilterSubmit = (filter) => {
const _filter = { const _filter = {
@@ -39,23 +34,22 @@ function InventoryItemDetails({
fromDate: moment(filter.fromDate).format('YYYY-MM-DD'), fromDate: moment(filter.fromDate).format('YYYY-MM-DD'),
toDate: moment(filter.toDate).format('YYYY-MM-DD'), toDate: moment(filter.toDate).format('YYYY-MM-DD'),
}; };
setFilter({ ..._filter }); setLocationQuery({ ..._filter });
}; };
// Handle number format submit. // Handle number format submit.
const handleNumberFormatSubmit = (values) => { const handleNumberFormatSubmit = (values) => {
setFilter({ setLocationQuery({
...filter, ...query,
numberFormat: values, numberFormat: values,
}); });
}; };
// Close the report header once the browser leave the page.
useEffect(() => () => toggleFilterDrawer(false), [toggleFilterDrawer]); useEffect(() => () => toggleFilterDrawer(false), [toggleFilterDrawer]);
return ( return (
<InventoryItemDetailsProvider filter={filter}> <InventoryItemDetailsProvider query={query}>
<InventoryItemDetailsActionsBar <InventoryItemDetailsActionsBar
numberFormat={filter.numberFormat} numberFormat={query.numberFormat}
onNumberFormatSubmit={handleNumberFormatSubmit} onNumberFormatSubmit={handleNumberFormatSubmit}
/> />
<InventoryItemDetailsLoadingBar /> <InventoryItemDetailsLoadingBar />
@@ -64,7 +58,7 @@ function InventoryItemDetails({
<DashboardPageContent> <DashboardPageContent>
<FinancialStatement> <FinancialStatement>
<InventoryItemDetailsHeader <InventoryItemDetailsHeader
pageFilter={filter} pageFilter={query}
onSubmitFilter={handleFilterSubmit} onSubmitFilter={handleFilterSubmit}
/> />
<InventoryItemDetailsBody /> <InventoryItemDetailsBody />
@@ -74,9 +68,4 @@ function InventoryItemDetails({
); );
} }
export default compose( export default compose(withInventoryItemDetailsActions)(InventoryItemDetails);
withCurrentOrganization(({ organization }) => ({
organizationName: organization.name,
})),
withInventoryItemDetailsActions,
)(InventoryItemDetails);

View File

@@ -15,6 +15,7 @@ import InventoryItemDetailsHeaderDimensionsPanel from './InventoryItemDetailsHea
import withInventoryItemDetails from './withInventoryItemDetails'; import withInventoryItemDetails from './withInventoryItemDetails';
import withInventoryItemDetailsActions from './withInventoryItemDetailsActions'; import withInventoryItemDetailsActions from './withInventoryItemDetailsActions';
import { getInventoryItemDetailsDefaultQuery } from './utils2';
import { compose, transformToForm } from 'utils'; import { compose, transformToForm } from 'utils';
/** /**
@@ -31,12 +32,7 @@ function InventoryItemDetailsHeader({
toggleInventoryItemDetailsFilterDrawer: toggleFilterDrawer, toggleInventoryItemDetailsFilterDrawer: toggleFilterDrawer,
}) { }) {
// Default form values. // Default form values.
const defaultValues = { const defaultValues = getInventoryItemDetailsDefaultQuery();
fromDate: moment().toDate(),
toDate: moment().toDate(),
itemsIds: [],
warehousesIds: [],
};
// Filter form initial values. // Filter form initial values.
const initialValues = transformToForm( const initialValues = transformToForm(
@@ -44,11 +40,9 @@ function InventoryItemDetailsHeader({
...pageFilter, ...pageFilter,
fromDate: moment(pageFilter.fromDate).toDate(), fromDate: moment(pageFilter.fromDate).toDate(),
toDate: moment(pageFilter.toDate).toDate(), toDate: moment(pageFilter.toDate).toDate(),
warehousesIds: [],
}, },
defaultValues, defaultValues,
); );
// Validation schema. // Validation schema.
const validationSchema = Yup.object().shape({ const validationSchema = Yup.object().shape({
fromDate: Yup.date().required().label(intl.get('fromDate')), fromDate: Yup.date().required().label(intl.get('fromDate')),

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import intl from 'react-intl-universal'; import intl from 'react-intl-universal';
import { FormGroup, Classes } from '@blueprintjs/core'; import { FormGroup, Classes } from '@blueprintjs/core';
import { WarehouseMultiSelect, Row, Col } from 'components'; import { BranchMultiSelect, WarehouseMultiSelect, Row, Col } from 'components';
import { import {
InventoryItemDetailsHeaderDimensionsProvider, InventoryItemDetailsHeaderDimensionsProvider,
useInventoryItemDetailsHeaderDimensionsPanelContext, useInventoryItemDetailsHeaderDimensionsPanelContext,
@@ -24,11 +24,19 @@ export default function InventoryItemDetailsHeaderDimensionsPanel() {
* @returns * @returns
*/ */
function InventoryItemDetailsHeaderDimensionsPanelContent() { function InventoryItemDetailsHeaderDimensionsPanelContent() {
const { warehouses } = useInventoryItemDetailsHeaderDimensionsPanelContext(); const { warehouses, branches } =
useInventoryItemDetailsHeaderDimensionsPanelContext();
return ( return (
<Row> <Row>
<Col xs={4}> <Col xs={4}>
<FormGroup
label={intl.get('branches_multi_select.label')}
className={Classes.FILL}
>
<BranchMultiSelect name={'branchesIds'} branches={branches} />
</FormGroup>
<FormGroup <FormGroup
label={intl.get('warehouses_multi_select.label')} label={intl.get('warehouses_multi_select.label')}
className={Classes.FILL} className={Classes.FILL}

View File

@@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import { Features } from 'common'; import { useWarehouses, useBranches } from 'hooks/query';
import { useWarehouses } from 'hooks/query';
import { useFeatureCan } from 'hooks/state'; import { useFeatureCan } from 'hooks/state';
import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton'; import { FinancialHeaderLoadingSkeleton } from '../FinancialHeaderLoadingSkeleton';
import { Features } from 'common';
const InventoryItemDetailsHeaderDimensionsPanelContext = React.createContext(); const InventoryItemDetailsHeaderDimensionsPanelContext = React.createContext();
@@ -11,25 +11,36 @@ const InventoryItemDetailsHeaderDimensionsPanelContext = React.createContext();
* Inventory Item details header provider. * Inventory Item details header provider.
* @returns * @returns
*/ */
function InventoryItemDetailsHeaderDimensionsProvider({ query, ...props }) { function InventoryItemDetailsHeaderDimensionsProvider({ ...props }) {
// Features guard. // Features guard.
const { featureCan } = useFeatureCan(); const { featureCan } = useFeatureCan();
// Detarmines whether the warehouses feature is accessiable.
const isWarehouseFeatureCan = featureCan(Features.Warehouses); const isWarehouseFeatureCan = featureCan(Features.Warehouses);
// Fetch warehouses list. // Detarmines whether the branches feature is accessiable.
const isBranchesFeatureCan = featureCan(Features.Branches);
// Fetches the warehouses list.
const { data: warehouses, isLoading: isWarehouesLoading } = useWarehouses( const { data: warehouses, isLoading: isWarehouesLoading } = useWarehouses(
query, null,
{ enabled: isWarehouseFeatureCan }, { enabled: isWarehouseFeatureCan },
); );
// Fetches the branches list.
const { data: branches, isLoading: isBranchesLoading } = useBranches(null, {
enabled: isBranchesFeatureCan,
});
// Provider // Provider
const provider = { const provider = {
warehouses, warehouses,
branches,
isWarehouesLoading, isWarehouesLoading,
isBranchesLoading,
}; };
return isWarehouesLoading ? ( return isWarehouesLoading || isBranchesLoading ? (
<FinancialHeaderLoadingSkeleton /> <FinancialHeaderLoadingSkeleton />
) : ( ) : (
<InventoryItemDetailsHeaderDimensionsPanelContext.Provider <InventoryItemDetailsHeaderDimensionsPanelContext.Provider

View File

@@ -8,10 +8,10 @@ const InventoryItemDetailsContext = React.createContext();
/** /**
* Inventory item details provider. * Inventory item details provider.
*/ */
function InventoryItemDetailsProvider({ filter, ...props }) { function InventoryItemDetailsProvider({ query, ...props }) {
const query = React.useMemo( const requestQuery = React.useMemo(
() => transformFilterFormToQuery(filter), () => transformFilterFormToQuery(query),
[filter], [query],
); );
// Fetching inventory item details report based on the givne query. // Fetching inventory item details report based on the givne query.
@@ -20,7 +20,7 @@ function InventoryItemDetailsProvider({ filter, ...props }) {
isFetching: isInventoryItemDetailsFetching, isFetching: isInventoryItemDetailsFetching,
isLoading: isInventoryItemDetailsLoading, isLoading: isInventoryItemDetailsLoading,
refetch: inventoryItemDetailsRefetch, refetch: inventoryItemDetailsRefetch,
} = useInventoryItemDetailsReport(query, { keepPreviousData: true }); } = useInventoryItemDetailsReport(requestQuery, { keepPreviousData: true });
const provider = { const provider = {
inventoryItemDetails, inventoryItemDetails,
@@ -29,7 +29,6 @@ function InventoryItemDetailsProvider({ filter, ...props }) {
inventoryItemDetailsRefetch, inventoryItemDetailsRefetch,
query, query,
filter,
}; };
return ( return (

View File

@@ -0,0 +1,58 @@
import React from 'react';
import { castArray } from 'lodash';
import moment from 'moment';
import { useAppQueryString } from 'hooks';
import { transformToForm } from 'utils';
/**
* Retrieves inventory item details default query.
*/
export const getInventoryItemDetailsDefaultQuery = () => {
return {
fromDate: moment().startOf('year').format('YYYY-MM-DD'),
toDate: moment().endOf('year').format('YYYY-MM-DD'),
warehousesIds: [],
branchesIds: [],
};
};
/**
* Parses inventory item details browser location query.
*/
const parseInventoryItemDetailsQuery = (locationQuery) => {
const defaultQuery = getInventoryItemDetailsDefaultQuery();
const transformed = {
...defaultQuery,
...transformToForm(locationQuery, defaultQuery),
};
return {
...transformed,
// Ensures the branches/warehouses ids is always array.
branchesIds: castArray(transformed.branchesIds),
warehousesIds: castArray(transformed.warehousesIds),
};
};
/**
* State setter/getter of inventory valuation browser location query.
*/
export const useInventoryValuationQuery = () => {
// Retrieves location query.
const [locationQuery, setLocationQuery] = useAppQueryString();
// Merges the default filter query with location URL query.
const query = React.useMemo(
() => parseInventoryItemDetailsQuery(locationQuery),
[locationQuery],
);
return {
query,
locationQuery,
setLocationQuery,
};
};