Skip to content

Commit d620fed

Browse files
authored
Merge pull request #2075 from boxwise/cached-products-take-precedence-over-matched-products
Cached products take precedence over matched products
2 parents 2900b80 + 3ec864f commit d620fed

File tree

3 files changed

+42
-24
lines changed

3 files changed

+42
-24
lines changed

front/src/components/BoxReconciliationOverlay/components/BoxReconciliationAccordion.tsx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ import { useState } from "react";
1313
import { BsFillCheckCircleFill } from "react-icons/bs";
1414
import { RiQuestionFill } from "react-icons/ri";
1515
import { ILocationData, IProductWithSizeRangeData } from "./BoxReconciliationView";
16-
import { IMatchProductsFormData, MatchProductsForm } from "./MatchProductsForm";
16+
import { MatchProductsFormData, MatchProductsForm } from "./MatchProductsForm";
1717
import { IReceiveLocationFormData, ReceiveLocationForm } from "./ReceiveLocationForm";
18-
import { useAtom, useSetAtom } from "jotai";
18+
import { useAtom, useAtomValue, useSetAtom } from "jotai";
1919
import {
2020
reconciliationMatchProductAtom,
2121
reconciliationReceiveLocationAtom,
@@ -55,8 +55,17 @@ export function BoxReconcilationAccordion({
5555
onBoxUndelivered,
5656
onBoxDelivered,
5757
}: IBoxReconcilationAccordionProps) {
58+
const [reconciliationMatchProductCache, setReconciliationMatchProductCache] = useAtom(
59+
reconciliationMatchProductAtom,
60+
);
61+
const cachedReconciliationMatchProduct = useAtomValue(reconciliationMatchProductAtom);
62+
/** Matching Source Product ID to look up a matching product in the cache store to prefill the form input. */
63+
const matchingProductSourceId = (shipmentDetail.sourceProduct?.id as `${number}`) || "0";
64+
const isProductIdMatchedInCache = !!cachedReconciliationMatchProduct[matchingProductSourceId];
5865
const isProductAutoMatched = !!shipmentDetail?.autoMatchingTargetProduct;
59-
const [accordionIndex, setAccordionIndex] = useState(isProductAutoMatched ? 1 : 0);
66+
const [accordionIndex, setAccordionIndex] = useState(
67+
isProductIdMatchedInCache ? 0 : isProductAutoMatched ? 1 : 0,
68+
);
6069
const [productManuallyMatched, setProductManuallyMatched] = useState(false);
6170
const [locationSpecified, setLocationSpecified] = useState(false);
6271
const [productFormData, setProductFormData] = useState<IProductFormData>({
@@ -66,9 +75,6 @@ export function BoxReconcilationAccordion({
6675
sizeId: isProductAutoMatched ? parseInt(shipmentDetail.sourceSize?.id ?? "0") : undefined,
6776
numberOfItems: shipmentDetail?.sourceQuantity ?? undefined,
6877
});
69-
const [reconciliationMatchProductCache, setReconciliationMatchProductCache] = useAtom(
70-
reconciliationMatchProductAtom,
71-
);
7278
const setReconciliationReceiveLocationCache = useSetAtom(reconciliationReceiveLocationAtom);
7379
const accordionHeaderColor = isProductAutoMatched || productManuallyMatched ? "#659A7E" : "#000";
7480
const accordionHeaderText = productManuallyMatched
@@ -119,7 +125,7 @@ export function BoxReconcilationAccordion({
119125
shipmentDetail={shipmentDetail}
120126
productAndSizesData={productAndSizesData}
121127
onBoxUndelivered={onBoxUndelivered}
122-
onSubmitMatchProductsForm={(matchedProductsFormData: IMatchProductsFormData) => {
128+
onSubmitMatchProductsForm={(matchedProductsFormData: MatchProductsFormData) => {
123129
setProductManuallyMatched(true);
124130
setAccordionIndex(1);
125131

front/src/components/BoxReconciliationOverlay/components/MatchProductsForm.tsx

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ export const MatchProductsFormDataSchema = z.object({
5757
.nonnegative(),
5858
});
5959

60-
export type IMatchProductsFormData = z.infer<typeof MatchProductsFormDataSchema>;
60+
export type MatchProductsFormData = z.infer<typeof MatchProductsFormDataSchema>;
6161

6262
interface IMatchProductsFormProps {
6363
shipmentDetail: ShipmentDetailWithAutomatchProduct;
6464
productAndSizesData: IProductWithSizeRangeData[];
6565
loading: boolean;
66-
onSubmitMatchProductsForm: (matchedProductsFormData: IMatchProductsFormData) => void;
66+
onSubmitMatchProductsForm: (matchedProductsFormData: MatchProductsFormData) => void;
6767
onBoxUndelivered: (labelIdentifier: string) => void;
6868
}
6969

@@ -81,25 +81,37 @@ export function MatchProductsForm({
8181
const isProductIdMatchedInCache = !!cachedReconciliationMatchProduct[matchingProductSourceId];
8282
/** Object key to match in the store to fetch the input values. */
8383
const cacheId = isProductIdMatchedInCache ? matchingProductSourceId : "0";
84+
const cachedProductLabel = cachedReconciliationMatchProduct[cacheId]?.productId.label;
85+
const cachedProductValue = cachedReconciliationMatchProduct[cacheId]?.productId.value;
86+
const cachedProductSizeIdLabel = cachedReconciliationMatchProduct[cacheId]?.sizeId.label;
87+
const cachedProductSizeIdValue = cachedReconciliationMatchProduct[cacheId]?.sizeId.value;
8488

8589
// Default Values
86-
// Automatched Products take precedence over cached products.
87-
const defaultValues: IMatchProductsFormData = {
90+
// Cached products take precedence over automatched products.
91+
const defaultValues: MatchProductsFormData = {
8892
productId: {
8993
label:
90-
shipmentDetail?.autoMatchingTargetProduct?.name ??
91-
cachedReconciliationMatchProduct[cacheId]?.productId.label,
94+
cachedProductLabel !== "Save Product As..."
95+
? cachedProductLabel
96+
: (shipmentDetail?.autoMatchingTargetProduct?.name ?? "Save Product As..."),
9297
value:
93-
shipmentDetail?.autoMatchingTargetProduct?.id ??
94-
cachedReconciliationMatchProduct[cacheId]?.productId.value,
98+
cachedProductValue !== ""
99+
? cachedProductValue
100+
: (shipmentDetail?.autoMatchingTargetProduct?.id ?? ""),
95101
},
96102
sizeId: {
97-
label: isProductAutoMatched
98-
? (shipmentDetail.sourceSize?.label ?? "")
99-
: cachedReconciliationMatchProduct[cacheId]?.sizeId.label,
100-
value: isProductAutoMatched
101-
? (shipmentDetail.sourceSize?.id ?? "")
102-
: cachedReconciliationMatchProduct[cacheId]?.sizeId.value,
103+
label:
104+
cachedProductSizeIdLabel !== "Save Size As..."
105+
? cachedProductSizeIdLabel
106+
: isProductAutoMatched
107+
? (shipmentDetail.sourceSize?.label ?? "")
108+
: "Save Size As...",
109+
value:
110+
cachedProductSizeIdValue !== ""
111+
? cachedProductSizeIdValue
112+
: isProductAutoMatched
113+
? (shipmentDetail.sourceSize?.id ?? "")
114+
: "",
103115
},
104116
numberOfItems: shipmentDetail?.sourceQuantity ?? 0,
105117
};
@@ -116,7 +128,7 @@ export function MatchProductsForm({
116128
resetField,
117129
register,
118130
formState: { errors, isSubmitting },
119-
} = useForm<IMatchProductsFormData>({
131+
} = useForm<MatchProductsFormData>({
120132
resolver: zodResolver(MatchProductsFormDataSchema),
121133
defaultValues,
122134
});

front/src/stores/globalCacheStore.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { IMatchProductsFormData } from "components/BoxReconciliationOverlay/components/MatchProductsForm";
1+
import { MatchProductsFormData } from "components/BoxReconciliationOverlay/components/MatchProductsForm";
22
import { IReceiveLocationFormData } from "components/BoxReconciliationOverlay/components/ReceiveLocationForm";
33
import { atomWithStorage } from "jotai/utils";
44

55
type ReconciliationMatchProductFields = Record<
66
`${number}`,
7-
Pick<IMatchProductsFormData, "productId" | "sizeId">
7+
Pick<MatchProductsFormData, "productId" | "sizeId">
88
>;
99

1010
/** Persisted atom to cache the value for the Match Product form input in the Box Reconciliation View. */

0 commit comments

Comments
 (0)