Skip to content

Commit

Permalink
refactor: improve management of fetch for product indicators (#828)
Browse files Browse the repository at this point in the history
* RM#87894
  • Loading branch information
lme-axelor authored Dec 5, 2024
1 parent 88864fe commit b8ffcb7
Show file tree
Hide file tree
Showing 12 changed files with 177 additions and 267 deletions.
6 changes: 6 additions & 0 deletions changelogs/unreleased/87894.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"title": "Indicators: move logic to fetch available stock to card components",
"type": "refactor",
"packages": "stock",
"description": "There was a performance problem on the screens requiring the product indicators. To solve this slow performance problem, product indicators are now retrieved from the card component in the background. The old way of working retrieved the indicators for all the products in the list each time they were updated, before displaying them, which is rather cumbersome and shouldn't be used. The functions concerned have been removed. "
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,70 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React, {useCallback, useMemo} from 'react';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {StyleSheet} from 'react-native';
import {ObjectCard, useDigitFormat, useThemeColor} from '@axelor/aos-mobile-ui';
import {useSelector, useTranslator} from '@axelor/aos-mobile-core';
import {getProductStockIndicators} from '../../../../api';

interface AvailableStockIndicatorCardProps {
product: any;
companyId: number;
stockLocation: any;
unit: any;
currentQty: number;
futureQty: number;
reservedQty: number;
availableStock: number;
}

const AvailableStockIndicatorCard = ({
product,
companyId,
stockLocation,
unit,
currentQty,
futureQty,
reservedQty,
availableStock,
}: AvailableStockIndicatorCardProps) => {
const Colors = useThemeColor();
const I18n = useTranslator();
const formatNumber = useDigitFormat();
const isMounted = useRef(true);

const {activeCompany} = useSelector(state => state.user.user);
const {supplychain: supplychainConfig} = useSelector(
state => state.appConfig,
);

const [availableStock, setAvailableStock] = useState(null);

useEffect(() => {
isMounted.current = true;

if (product != null) {
getProductStockIndicators({
productId: product.id,
version: product.$version,
stockLocationId: stockLocation?.id,
companyId: companyId ?? activeCompany?.id,
})
.then((res: any) => {
if (isMounted.current) {
setAvailableStock(res?.data?.object?.availableStock);
}
})
.catch(() => {
if (isMounted.current) {
setAvailableStock(null);
}
});
}

return () => {
isMounted.current = false;
};
}, [activeCompany, companyId, product, stockLocation]);

const borderStyle = useMemo(() => {
const _color =
availableStock == null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,70 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React from 'react';
import React, {useEffect, useRef, useState} from 'react';
import {StyleSheet} from 'react-native';
import {ObjectCard, useThemeColor} from '@axelor/aos-mobile-ui';
import {useMetafileUri, useTranslator} from '@axelor/aos-mobile-core';
import {
useMetafileUri,
useSelector,
useTranslator,
} from '@axelor/aos-mobile-core';
import {getProductStockIndicators} from '../../../../api';

interface ProductCardProps {
style?: any;
productId: number;
productVersion: number;
name: string;
code: string;
picture: any;
availableStock: number | null | undefined;
onPress: () => void;
}

const ProductCard = ({
style,
productId,
productVersion,
name,
code,
picture,
availableStock,
onPress,
}: ProductCardProps) => {
const Colors = useThemeColor();
const I18n = useTranslator();
const formatMetaFile = useMetafileUri();
const isMounted = useRef(true);

const {activeCompany} = useSelector(state => state.user.user);

const [availableStock, setAvailableStock] = useState(null);

useEffect(() => {
isMounted.current = true;

if (productId != null) {
getProductStockIndicators({
productId: productId,
version: productVersion,
companyId: activeCompany?.id,
stockLocationId: null,
})
.then((res: any) => {
if (isMounted.current) {
setAvailableStock(res?.data?.object?.availableStock);
}
})
.catch(() => {
if (isMounted.current) {
setAvailableStock(null);
}
});
}

return () => {
isMounted.current = false;
};
}, [activeCompany?.id, productId, productVersion]);

return (
<ObjectCard
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React, {useCallback} from 'react';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {StyleSheet} from 'react-native';
import {ObjectCard, useDigitFormat, useThemeColor} from '@axelor/aos-mobile-ui';
import {
Expand All @@ -25,6 +25,10 @@ import {
useTypeHelpers,
useTypes,
} from '@axelor/aos-mobile-core';
import {
getProductStockIndicators,
fetchVariantAttributes,
} from '../../../../api';

interface ProductAttribut {
attrName: string;
Expand All @@ -37,19 +41,21 @@ interface ProductVariantCardProps {
style?: any;
name: string;
code: string;
attributesList: {attributes: ProductAttribut[]};
productId: number;
productVersion: number;
availabiltyData: {stockLocationId: number; companyId: number};
picture?: any;
stockAvailability: number;
onPress: () => void;
}

const ProductVariantCard = ({
style,
name,
code,
attributesList,
productId,
productVersion,
availabiltyData,
picture,
stockAvailability,
onPress,
}: ProductVariantCardProps) => {
const Colors = useThemeColor();
Expand All @@ -58,16 +64,69 @@ const ProductVariantCard = ({
const formatNumber = useDigitFormat();
const {ProductVariantValue} = useTypes();
const {getItemTitle} = useTypeHelpers();
const isMounted = useRef(true);

const [attributes, setAttributesList] = useState<
ProductAttribut[] | undefined
>();
const [availableStock, setAvailableStock] = useState(null);

useEffect(() => {
isMounted.current = true;

return () => {
isMounted.current = false;
};
}, []);

useEffect(() => {
if (productId != null) {
fetchVariantAttributes({
productVariantId: productId,
version: productVersion,
})
.then((res: any) => {
if (isMounted.current) {
setAttributesList(res?.data?.object?.attributes);
}
})
.catch(() => {
if (isMounted.current) {
setAttributesList(null);
}
});
}
}, [availabiltyData, productId, productVersion]);

useEffect(() => {
if (productId != null) {
getProductStockIndicators({
productId: productId,
version: productVersion,
...availabiltyData,
})
.then((res: any) => {
if (isMounted.current) {
setAvailableStock(res?.data?.object?.availableStock);
}
})
.catch(() => {
if (isMounted.current) {
setAvailableStock(null);
}
});
}
}, [availabiltyData, productId, productVersion]);

const renderAttrItems = useCallback(() => {
if (!Array.isArray(attributesList?.attributes)) {
if (!Array.isArray(attributes)) {
return null;
}

let items = [];

for (let index = 0; index < attributesList?.attributes.length; index++) {
const attr = attributesList?.attributes[index];
for (let index = 0; index < attributes.length; index++) {
const attr = attributes[index];

if (attr != null) {
items.push({
Expand All @@ -88,7 +147,7 @@ const ProductVariantCard = ({
return items?.length > 0 ? {items} : null;
}, [
ProductVariantValue?.applicationPriceSelect,
attributesList?.attributes,
attributes,
formatNumber,
getItemTitle,
]);
Expand All @@ -115,11 +174,10 @@ const ProductVariantCard = ({
items: [
{
displayText:
stockAvailability > 0
availableStock > 0
? I18n.t('Stock_Available')
: I18n.t('Stock_Unavailable'),
color:
stockAvailability > 0 ? Colors.successColor : Colors.errorColor,
color: availableStock > 0 ? Colors.successColor : Colors.errorColor,
},
],
}}
Expand Down
7 changes: 1 addition & 6 deletions packages/apps/stock/src/features/asyncFunctions-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ export {
export {filterClients, filterSuppliers} from './partnerSlice';
export {
fetchAvailableStockIndicator,
fetchProductDistribution,
fetchProductIndicators,
fetchProductsAvailability,
fetchPurchaseOrderQtyIndicator,
fetchSaleOrderQtyIndicator,
fetchStockQtyIndicator,
Expand All @@ -69,10 +67,7 @@ export {
updateProductLocker,
} from './productSlice';
export {searchProductTrackingNumber} from './productTrackingNumberSlice';
export {
fetchProductsAttributes,
fetchProductVariants,
} from './productVariantSlice';
export {fetchProductVariants} from './productVariantSlice';
export {getRacks} from './racksListSlice';
export {fetchStockCorrectionReasons} from './stockCorrectionReasonSlice';
export {
Expand Down
Loading

0 comments on commit b8ffcb7

Please sign in to comment.