From d4ecb82aa429ff5047e7bf2287f468fdf4000ced Mon Sep 17 00:00:00 2001 From: "kelvin.yau" Date: Mon, 20 Oct 2025 17:45:46 +0800 Subject: [PATCH] update --- src/app/api/pickOrder/actions.ts | 3 +- .../GoodPickExecutiondetail.tsx | 1015 +++++++++-------- 2 files changed, 567 insertions(+), 451 deletions(-) diff --git a/src/app/api/pickOrder/actions.ts b/src/app/api/pickOrder/actions.ts index 48417b2..ea0b95e 100644 --- a/src/app/api/pickOrder/actions.ts +++ b/src/app/api/pickOrder/actions.ts @@ -111,8 +111,9 @@ export interface GetPickOrderLineInfo { itemName: string; availableQty: number| null; requiredQty: number; - uomCode: string; + uomShortDesc: string; uomDesc: string; + suggestedList: any[]; pickedQty: number; } diff --git a/src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx b/src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx index 2710883..1d97df1 100644 --- a/src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx +++ b/src/components/FinishedGoodSearch/GoodPickExecutiondetail.tsx @@ -18,6 +18,7 @@ import { Checkbox, TablePagination, Modal, + Chip, } from "@mui/material"; import TestQrCodeProvider from '../QrCodeScannerProvider/TestQrCodeProvider'; import { fetchLotDetail } from "@/app/api/inventory/actions"; @@ -32,16 +33,16 @@ import { recordPickExecutionIssue, fetchFGPickOrders, // ✅ Add this import FGPickOrderResponse, - autoAssignAndReleasePickOrder, - AutoAssignReleaseResponse, + checkPickOrderCompletion, fetchAllPickOrderLotsHierarchical, PickOrderCompletionResponse, checkAndCompletePickOrderByConsoCode, updateSuggestedLotLineId, - confirmLotSubstitution + confirmLotSubstitution, // ✅ 必须添加 + fetchFGPickOrdersByUserId } from "@/app/api/pickOrder/actions"; - +import FGPickOrderInfoCard from "./FGPickOrderInfoCard"; import LotConfirmationModal from "./LotConfirmationModal"; //import { fetchItem } from "@/app/api/settings/item"; import { updateInventoryLotLineStatus, analyzeQrCode } from "@/app/api/inventory/actions"; @@ -75,7 +76,9 @@ const QrCodeModal: React.FC<{ const { t } = useTranslation("pickOrder"); const { values: qrValues, isScanning, startScan, stopScan, resetScan } = useQrCodeScannerContext(); const [manualInput, setManualInput] = useState(''); - + +const [selectedPickOrderId, setSelectedPickOrderId] = useState(null); +const [pickOrderSwitching, setPickOrderSwitching] = useState(false); const [manualInputSubmitted, setManualInputSubmitted] = useState(false); const [manualInputError, setManualInputError] = useState(false); const [isProcessingQr, setIsProcessingQr] = useState(false); @@ -322,7 +325,9 @@ const PickExecution: React.FC = ({ filterArgs }) => { const { t } = useTranslation("pickOrder"); const router = useRouter(); const { data: session } = useSession() as { data: SessionWithTokens | null }; - + const [availablePickOrders, setAvailablePickOrders] = useState([]); +const [selectedPickOrderId, setSelectedPickOrderId] = useState(null); +const [pickOrderSwitching, setPickOrderSwitching] = useState(false); const currentUserId = session?.id ? parseInt(session.id) : undefined; const [allLotsCompleted, setAllLotsCompleted] = useState(false); const [combinedLotData, setCombinedLotData] = useState([]); @@ -369,38 +374,25 @@ const [isConfirmingLot, setIsConfirmingLot] = useState(false); const [lastProcessedQr, setLastProcessedQr] = useState(''); const [isRefreshingData, setIsRefreshingData] = useState(false); const [isSubmittingAll, setIsSubmittingAll] = useState(false); - const fetchFgPickOrdersData = useCallback(async () => { - if (!currentUserId) return; - - setFgPickOrdersLoading(true); - try { - // Get all pick order IDs from combinedLotData - const pickOrderIds = Array.from(new Set(combinedLotData.map(lot => lot.pickOrderId))); + const fetchFgPickOrdersData = useCallback(async () => { + if (!currentUserId) return; - if (pickOrderIds.length === 0) { + setFgPickOrdersLoading(true); + try { + const fgPickOrders = await fetchFGPickOrdersByUserId(currentUserId); + + setFgPickOrders(fgPickOrders); + + // ✅ 移除:不需要再单独调用 fetchDoPickOrderDetail + // all-lots-hierarchical API 已经包含了所有需要的数据 + + } catch (error) { + console.error("❌ Error fetching FG pick orders:", error); setFgPickOrders([]); - return; + } finally { + setFgPickOrdersLoading(false); } - - // Fetch FG pick orders for each pick order ID - const fgPickOrdersPromises = pickOrderIds.map(pickOrderId => - fetchFGPickOrders(pickOrderId) - ); - - const fgPickOrdersResults = await Promise.all(fgPickOrdersPromises); - - // Flatten the results (each fetchFGPickOrders returns an array) - const allFgPickOrders = fgPickOrdersResults.flat(); - - setFgPickOrders(allFgPickOrders); - console.log("✅ Fetched FG pick orders:", allFgPickOrders); - } catch (error) { - console.error("❌ Error fetching FG pick orders:", error); - setFgPickOrders([]); - } finally { - setFgPickOrdersLoading(false); - } - }, [currentUserId, combinedLotData]); + }, [currentUserId]); useEffect(() => { if (combinedLotData.length > 0) { fetchFgPickOrdersData(); @@ -444,12 +436,12 @@ const [isConfirmingLot, setIsConfirmingLot] = useState(false); setAllLotsCompleted(allCompleted); return allCompleted; }, []); - const fetchAllCombinedLotData = useCallback(async (userId?: number) => { + const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdOverride?: number) => { setCombinedDataLoading(true); try { const userIdToUse = userId || currentUserId; - console.log(" fetchAllCombinedLotData called with userId:", userIdToUse); + console.log("🔍 fetchAllCombinedLotData called with userId:", userIdToUse); if (!userIdToUse) { console.warn("⚠️ No userId available, skipping API call"); @@ -459,77 +451,178 @@ const [isConfirmingLot, setIsConfirmingLot] = useState(false); return; } - // ✅ Use the hierarchical endpoint that includes rejected lots + // ✅ 获取新结构的层级数据 const hierarchicalData = await fetchAllPickOrderLotsHierarchical(userIdToUse); - console.log("✅ Hierarchical lot details:", hierarchicalData); + console.log("✅ Hierarchical data (new structure):", hierarchicalData); + + // ✅ 检查数据结构 + if (!hierarchicalData.fgInfo || !hierarchicalData.pickOrders) { + console.warn("⚠️ No FG info or pick orders found"); + setCombinedLotData([]); + setOriginalCombinedData([]); + setAllLotsCompleted(false); + return; + } + + // ✅ 设置 FG info 到 fgPickOrders(用于显示 FG 信息卡片) + const fgOrder: FGPickOrderResponse = { + ticketNo: hierarchicalData.fgInfo.ticketNo, + storeId: hierarchicalData.fgInfo.storeId, + shopCode: hierarchicalData.fgInfo.shopCode, + shopName: hierarchicalData.fgInfo.shopName, + truckLanceCode: hierarchicalData.fgInfo.truckLanceCode, + DepartureTime: hierarchicalData.fgInfo.departureTime, + shopAddress: "", + + // ✅ 从第一个 pick order 获取兼容字段 + pickOrderId: hierarchicalData.pickOrders[0]?.pickOrderId || 0, + pickOrderCode: hierarchicalData.pickOrders[0]?.pickOrderCode || "", + pickOrderConsoCode: hierarchicalData.pickOrders[0]?.consoCode || "", + pickOrderTargetDate: hierarchicalData.pickOrders[0]?.targetDate || "", + pickOrderStatus: hierarchicalData.pickOrders[0]?.status || "", + deliveryOrderId: hierarchicalData.pickOrders[0]?.doOrderId || 0, + deliveryNo: hierarchicalData.pickOrders[0]?.deliveryOrderCode || "", + deliveryDate: "", + shopId: 0, + shopPoNo: "", + numberOfCartons: 0, + qrCodeData: hierarchicalData.fgInfo.doPickOrderId, + + // ✅ 新增:多个 pick orders 信息 + // numberOfPickOrders: hierarchicalData.pickOrders.length, + // pickOrderIds: hierarchicalData.pickOrders.map((po: any) => po.pickOrderId), + //pickOrderCodes: hierarchicalData.pickOrders.map((po: any) => po.pickOrderCode).join(", "), + // deliveryOrderIds: hierarchicalData.pickOrders.map((po: any) => po.doOrderId), + //deliveryNos: hierarchicalData.pickOrders.map((po: any) => po.deliveryOrderCode).join(", ") + }; + + setFgPickOrders([fgOrder]); + setAvailablePickOrders(hierarchicalData.pickOrders); + // ✅ 构建 doPickOrderDetail(用于 switcher) + + + // ✅ 确定要显示的 pick order + const targetPickOrderId = pickOrderIdOverride || selectedPickOrderId || hierarchicalData.pickOrders[0]?.pickOrderId; + + // ✅ 找到对应的 pick order 数据 + const targetPickOrder = hierarchicalData.pickOrders.find((po: any) => + po.pickOrderId === targetPickOrderId + ); + + if (!targetPickOrder) { + console.warn("⚠️ Target pick order not found:", targetPickOrderId); + setCombinedLotData([]); + setOriginalCombinedData([]); + setAllLotsCompleted(false); + return; + } + + console.log("🎯 Displaying pick order:", targetPickOrder.pickOrderCode); - // ✅ Transform hierarchical data to flat structure for the table + // ✅ 将层级数据转换为平铺格式(用于表格显示) const flatLotData: any[] = []; - if (hierarchicalData.pickOrder && hierarchicalData.pickOrderLines) { - hierarchicalData.pickOrderLines.forEach((line: any) => { - if (line.lots && line.lots.length > 0) { - line.lots.forEach((lot: any) => { - flatLotData.push({ - // Pick order info - pickOrderId: hierarchicalData.pickOrder.id, - pickOrderCode: hierarchicalData.pickOrder.code, - pickOrderConsoCode: hierarchicalData.pickOrder.consoCode, - pickOrderTargetDate: hierarchicalData.pickOrder.targetDate, - pickOrderType: hierarchicalData.pickOrder.type, - pickOrderStatus: hierarchicalData.pickOrder.status, - pickOrderAssignTo: hierarchicalData.pickOrder.assignTo, - - // Pick order line info - pickOrderLineId: line.id, - pickOrderLineRequiredQty: line.requiredQty, - pickOrderLineStatus: line.status, - - // Item info - itemId: line.item.id, - itemCode: line.item.code, - itemName: line.item.name, - uomCode: line.item.uomCode, - uomDesc: line.item.uomDesc, - - // Lot info - lotId: lot.id, - lotNo: lot.lotNo, - expiryDate: lot.expiryDate, - location: lot.location, - stockUnit: lot.stockUnit, - availableQty: lot.availableQty, - requiredQty: lot.requiredQty, - actualPickQty: lot.actualPickQty, - inQty: lot.inQty, - outQty: lot.outQty, - holdQty: lot.holdQty, - lotStatus: lot.lotStatus, - lotAvailability: lot.lotAvailability, - processingStatus: lot.processingStatus, - suggestedPickLotId: lot.suggestedPickLotId, - stockOutLineId: lot.stockOutLineId, - stockOutLineStatus: lot.stockOutLineStatus, - stockOutLineQty: lot.stockOutLineQty, - - // Router info - routerId: lot.router?.id, - routerIndex: lot.router?.index, - routerRoute: lot.router?.route, - routerArea: lot.router?.area, - uomShortDesc: lot.router?.uomId - }); + targetPickOrder.pickOrderLines.forEach((line: any) => { + if (line.lots && line.lots.length > 0) { + // ✅ 有 lots 的情况 + line.lots.forEach((lot: any) => { + flatLotData.push({ + pickOrderId: targetPickOrder.pickOrderId, + pickOrderCode: targetPickOrder.pickOrderCode, + pickOrderConsoCode: targetPickOrder.consoCode, + pickOrderTargetDate: targetPickOrder.targetDate, + pickOrderStatus: targetPickOrder.status, + + pickOrderLineId: line.id, + pickOrderLineRequiredQty: line.requiredQty, + pickOrderLineStatus: line.status, + + itemId: line.item.id, + itemCode: line.item.code, + itemName: line.item.name, + //uomCode: line.item.uomCode, + uomDesc: line.item.uomDesc, + uomShortDesc: line.item.uomShortDesc, + lotId: lot.id, + lotNo: lot.lotNo, + expiryDate: lot.expiryDate, + location: lot.location, + stockUnit: lot.stockUnit, + availableQty: lot.availableQty, + requiredQty: lot.requiredQty, + actualPickQty: lot.actualPickQty, + inQty: lot.inQty, + outQty: lot.outQty, + holdQty: lot.holdQty, + lotStatus: lot.lotStatus, + lotAvailability: lot.lotAvailability, + processingStatus: lot.processingStatus, + suggestedPickLotId: lot.suggestedPickLotId, + stockOutLineId: lot.stockOutLineId, + stockOutLineStatus: lot.stockOutLineStatus, + stockOutLineQty: lot.stockOutLineQty, + + routerId: lot.router?.id, + routerIndex: lot.router?.index, + routerRoute: lot.router?.route, + routerArea: lot.router?.area, }); - } - }); - } + }); + } else { + // ✅ 没有 lots 的情况(null stock)- 也要显示 + flatLotData.push({ + pickOrderId: targetPickOrder.pickOrderId, + pickOrderCode: targetPickOrder.pickOrderCode, + pickOrderConsoCode: targetPickOrder.consoCode, + pickOrderTargetDate: targetPickOrder.targetDate, + pickOrderStatus: targetPickOrder.status, + + pickOrderLineId: line.id, + pickOrderLineRequiredQty: line.requiredQty, + pickOrderLineStatus: line.status, + + itemId: line.item.id, + itemCode: line.item.code, + itemName: line.item.name, + //uomCode: line.item.uomCode, + uomDesc: line.item.uomDesc, + + // ✅ Null stock 字段 + lotId: null, + lotNo: null, + expiryDate: null, + location: null, + stockUnit: line.item.uomDesc, + availableQty: 0, + requiredQty: line.requiredQty, + actualPickQty: 0, + inQty: 0, + outQty: 0, + holdQty: 0, + lotStatus: 'unavailable', + lotAvailability: 'insufficient_stock', + processingStatus: 'pending', + suggestedPickLotId: null, + stockOutLineId: null, + stockOutLineStatus: null, + stockOutLineQty: 0, + + routerId: null, + routerIndex: 999999, // ✅ 放到最后 + routerRoute: null, + routerArea: null, + uomShortDesc: line.item.uomShortDesc + }); + } + }); console.log("✅ Transformed flat lot data:", flatLotData); + console.log("🔍 Total items (including null stock):", flatLotData.length); + setCombinedLotData(flatLotData); setOriginalCombinedData(flatLotData); - - // ✅ Check completion status checkAllLotsCompleted(flatLotData); + } catch (error) { console.error("❌ Error fetching combined lot data:", error); setCombinedLotData([]); @@ -538,8 +631,7 @@ const [isConfirmingLot, setIsConfirmingLot] = useState(false); } finally { setCombinedDataLoading(false); } - }, [currentUserId, checkAllLotsCompleted]); - + }, [currentUserId, selectedPickOrderId, checkAllLotsCompleted]); // ✅ Add effect to check completion when lot data changes useEffect(() => { if (combinedLotData.length > 0) { @@ -1357,7 +1449,22 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe setQrScanSuccess(false); startScan(); }, [startScan]); - + const handlePickOrderSwitch = useCallback(async (pickOrderId: number) => { + if (pickOrderSwitching) return; + + setPickOrderSwitching(true); + try { + console.log("🔍 Switching to pick order:", pickOrderId); + setSelectedPickOrderId(pickOrderId); + + // ✅ 强制刷新数据,确保显示正确的 pick order 数据 + await fetchAllCombinedLotData(currentUserId, pickOrderId); + } catch (error) { + console.error("Error switching pick order:", error); + } finally { + setPickOrderSwitching(false); + } + }, [pickOrderSwitching, currentUserId, fetchAllCombinedLotData]); const handleStopScan = useCallback(() => { console.log("⏹️ Stopping manual QR scan..."); setIsManualScanning(false); @@ -1488,370 +1595,378 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe }, [t]); return ( ( - lot.lotAvailability !== 'rejected' && - lot.stockOutLineStatus !== 'rejected' && - lot.stockOutLineStatus !== 'completed' - )} - > - + lotData={combinedLotData} + onScanLot={handleQrCodeSubmit} + filterActive={(lot) => ( + lot.lotAvailability !== 'rejected' && + lot.stockOutLineStatus !== 'rejected' && + lot.stockOutLineStatus !== 'completed' + )} + > + + + {/* DO Header */} + {fgPickOrdersLoading ? ( + + + + ) : ( + fgPickOrders.length > 0 && ( + + + {/* 基本信息 */} + + + {t("Shop Name")}: {fgPickOrders[0].shopName || '-'} + + + {t("Store ID")}: {fgPickOrders[0].storeId || '-'} + + + {t("Ticket No.")}: {fgPickOrders[0].ticketNo || '-'} + + + {t("Departure Time")}: {fgPickOrders[0].DepartureTime || '-'} + + + + + + ) + )} + + {/* ✅ FG Info Card */} - - - - {/* DO Header */} - {fgPickOrdersLoading ? ( - - - - ) : ( - fgPickOrders.length > 0 && ( - - - - {t("Shop Name")}: {fgPickOrders[0].shopName || '-'} - - - {t("Pick Order Code")}:{fgPickOrders[0].pickOrderCode || '-'} - - - {t("Store ID")}: {fgPickOrders[0].storeId || '-'} - - - {t("Ticket No.")}: {fgPickOrders[0].ticketNo || '-'} - - - {t("Departure Time")}: {fgPickOrders[0].DepartureTime || '-'} - - - - - ) - )} - - - {/* Combined Lot Table */} - - - - {t("All Pick Order Lots")} - - - - {!isManualScanning ? ( + {/* ✅ Pick Order Switcher - 放在 FG Info 下面,QR 按钮上面 */} + {availablePickOrders.length > 1 && ( + + + {t("Select Pick Order:")} + + + {availablePickOrders.map((po: any) => ( + handlePickOrderSwitch(po.pickOrderId)} + color={selectedPickOrderId === po.pickOrderId ? "primary" : "default"} + variant={selectedPickOrderId === po.pickOrderId ? "filled" : "outlined"} + sx={{ + cursor: 'pointer', + '&:hover': { backgroundColor: 'primary.light', color: 'white' } + }} + /> + ))} + + +)} + + {/* ✅ 保留:Combined Lot Table - 包含所有 QR 扫描功能 */} + + + + {t("All Pick Order Lots")} + + + + {!isManualScanning ? ( + + ) : ( + + )} + + {/* ✅ 保留:Submit All Scanned Button */} - ) : ( - - )} - - {/* ✅ ADD THIS: Submit All Scanned Button */} - - + - - - {qrScanError && !qrScanSuccess && ( - - {t("QR code does not match any item in current orders.")} - - )} - {qrScanSuccess && ( - - {t("QR code verified.")} - - )} - - - - - - {t("Index")} - {t("Route")} - {t("Item Code")} - {t("Item Name")} - {t("Lot#")} - {/* {t("Target Date")} */} - {/* {t("Lot Location")} */} - {t("Lot Required Pick Qty")} - {/* {t("Original Available Qty")} */} - {t("Scan Result")} - {t("Submit Required Pick Qty")} - {/* {t("Remaining Available Qty")} */} - - {/* {t("Action")} */} - - - - {paginatedData.length === 0 ? ( + + {qrScanError && !qrScanSuccess && ( + + {t("QR code does not match any item in current orders.")} + + )} + {qrScanSuccess && ( + + {t("QR code verified.")} + + )} + + +
+ - - - {t("No data available")} - - + {t("Index")} + {t("Route")} + {t("Item Code")} + {t("Item Name")} + {t("Lot#")} + {t("Lot Required Pick Qty")} + {t("Scan Result")} + {t("Submit Required Pick Qty")} - ) : ( - paginatedData.map((lot, index) => ( - - - - {index + 1} - - - - - {lot.routerRoute || '-'} + + + {paginatedData.length === 0 ? ( + + + + {t("No data available")} - {lot.itemCode} - {lot.itemName+'('+lot.stockUnit+')'} - - - - {lot.lotNo} - - - - {/* {lot.pickOrderTargetDate} */} - {/* {lot.location} */} - {/* {calculateRemainingRequiredQty(lot).toLocaleString()} */} - - {(() => { - const inQty = lot.inQty || 0; - const requiredQty = lot.requiredQty || 0; - const actualPickQty = lot.actualPickQty || 0; - const outQty = lot.outQty || 0; - const result = requiredQty; - return result.toLocaleString()+'('+lot.uomShortDesc+')'; - })()} - - - - {lot.stockOutLineStatus?.toLowerCase() !== 'pending' ? ( - - - - ) : null} - - - - - - - - - - - - - - )) - )} - -
-
- {/* ✅ Status Messages Display - Move here, outside the table */} - {/* -{paginatedData.length > 0 && ( - - {paginatedData.map((lot, index) => ( - - - {t("Lot")} {lot.lotNo}: {getStatusMessage(lot)} + + ) : ( +// 在第 1797-1938 行之间,将整个 map 函数修改为: +paginatedData.map((lot, index) => { + // ✅ 检查是否是 issue lot + const isIssueLot = lot.stockOutLineStatus === 'rejected' || !lot.lotNo; + + return ( + + + + {index + 1} - - ))} - -)} -*/} - - `${from}-${to} of ${count !== -1 ? count : `more than ${to}`}` - } - /> + + + + {lot.routerRoute || '-'} + + + {lot.itemCode} + {lot.itemName + '(' + lot.stockUnit + ')'} + + + + {lot.lotNo || t('⚠️ No Stock Available')} + -
- - {/* ✅ QR Code Modal */} - { - setQrModalOpen(false); - setSelectedLotForQr(null); - stopScan(); - resetScan(); - }} - lot={selectedLotForQr} - combinedLotData={combinedLotData} // ✅ Add this prop - onQrCodeSubmit={handleQrCodeSubmitFromModal} - /> - {/* ✅ Lot Confirmation Modal */} - {lotConfirmationOpen && expectedLotData && scannedLotData && ( - { - setLotConfirmationOpen(false); - setExpectedLotData(null); - setScannedLotData(null); - }} - onConfirm={handleLotConfirmation} - expectedLot={expectedLotData} - scannedLot={scannedLotData} - isLoading={isConfirmingLot} - /> - )} - {/* ✅ Good Pick Execution Form Modal */} - {pickExecutionFormOpen && selectedLotForExecutionForm && ( - + + {(() => { + const requiredQty = lot.requiredQty || 0; + return requiredQty.toLocaleString() + '(' + lot.uomShortDesc + ')'; + })()} + + + + {/* ✅ Issue lot 不显示扫描状态 */} + {!isIssueLot && lot.stockOutLineStatus?.toLowerCase() !== 'pending' ? ( + + + + ) : isIssueLot ? ( + null + ) : null} + + + + + {isIssueLot ? ( + // ✅ Issue lot 只显示 Issue 按钮 + + ) : ( + // ✅ Normal lot 显示两个按钮 + + + + + + )} + + + + ); +}) + )} + + + + + + `${from}-${to} of ${count !== -1 ? count : `more than ${to}`}` + } + /> +
+
+ + {/* ✅ 保留:QR Code Modal */} + { - setPickExecutionFormOpen(false); - setSelectedLotForExecutionForm(null); - }} - onSubmit={handlePickExecutionFormSubmit} - selectedLot={selectedLotForExecutionForm} - selectedPickOrderLine={{ - id: selectedLotForExecutionForm.pickOrderLineId, - itemId: selectedLotForExecutionForm.itemId, - itemCode: selectedLotForExecutionForm.itemCode, - itemName: selectedLotForExecutionForm.itemName, - pickOrderCode: selectedLotForExecutionForm.pickOrderCode, - // ✅ Add missing required properties from GetPickOrderLineInfo interface - availableQty: selectedLotForExecutionForm.availableQty || 0, - requiredQty: selectedLotForExecutionForm.requiredQty || 0, - uomCode: selectedLotForExecutionForm.uomCode || '', - uomDesc: selectedLotForExecutionForm.uomDesc || '', - pickedQty: selectedLotForExecutionForm.actualPickQty || 0, // ✅ Use pickedQty instead of actualPickQty - suggestedList: [] // ✅ Add required suggestedList property + setQrModalOpen(false); + setSelectedLotForQr(null); + stopScan(); + resetScan(); }} - pickOrderId={selectedLotForExecutionForm.pickOrderId} - pickOrderCreateDate={new Date()} + lot={selectedLotForQr} + combinedLotData={combinedLotData} + onQrCodeSubmit={handleQrCodeSubmitFromModal} /> - )} -
+ + {/* ✅ 保留:Lot Confirmation Modal */} + {lotConfirmationOpen && expectedLotData && scannedLotData && ( + { + setLotConfirmationOpen(false); + setExpectedLotData(null); + setScannedLotData(null); + }} + onConfirm={handleLotConfirmation} + expectedLot={expectedLotData} + scannedLot={scannedLotData} + isLoading={isConfirmingLot} + /> + )} + + {/* ✅ 保留:Good Pick Execution Form Modal */} + {pickExecutionFormOpen && selectedLotForExecutionForm && ( + { + setPickExecutionFormOpen(false); + setSelectedLotForExecutionForm(null); + }} + onSubmit={handlePickExecutionFormSubmit} + selectedLot={selectedLotForExecutionForm} + selectedPickOrderLine={{ + id: selectedLotForExecutionForm.pickOrderLineId, + itemId: selectedLotForExecutionForm.itemId, + itemCode: selectedLotForExecutionForm.itemCode, + itemName: selectedLotForExecutionForm.itemName, + pickOrderCode: selectedLotForExecutionForm.pickOrderCode, + availableQty: selectedLotForExecutionForm.availableQty || 0, + requiredQty: selectedLotForExecutionForm.requiredQty || 0, + // uomCode: selectedLotForExecutionForm.uomCode || '', + uomDesc: selectedLotForExecutionForm.uomDesc || '', + pickedQty: selectedLotForExecutionForm.actualPickQty || 0, + uomShortDesc: selectedLotForExecutionForm.uomShortDesc || '', + suggestedList: [] + }} + pickOrderId={selectedLotForExecutionForm.pickOrderId} + pickOrderCreateDate={new Date()} + /> + )} +
); };