From cd6c2ca450f1b6cd63ba69ffc64767d6b68c0ca3 Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Mon, 8 Jun 2026 16:43:30 +0800 Subject: [PATCH] do scan fix --- .../WorkbenchGoodPickExecutionDetail.tsx | 101 ++++-------------- 1 file changed, 20 insertions(+), 81 deletions(-) diff --git a/src/components/DoWorkbench/WorkbenchGoodPickExecutionDetail.tsx b/src/components/DoWorkbench/WorkbenchGoodPickExecutionDetail.tsx index c32cbba..a6dbe2c 100644 --- a/src/components/DoWorkbench/WorkbenchGoodPickExecutionDetail.tsx +++ b/src/components/DoWorkbench/WorkbenchGoodPickExecutionDetail.tsx @@ -70,6 +70,12 @@ import { useSession } from "next-auth/react"; import { SessionWithTokens } from "@/config/authConfig"; import { fetchStockInLineInfo } from "@/app/api/po/actions"; import GoodPickExecutionForm from "@/components/FinishedGoodSearch/GoodPickExecutionForm"; +import { WORKBENCH_TAB_FINISHED_GOOD_RECORD_MINE } from "./workbenchTabConstants"; +import { + inferUnpickableScanAvailability, + translateWorkbenchRejectMessage, + type UnpickableScanAvailability, +} from "@/utils/workbenchPickLotUtils"; import WorkbenchLotLabelPrintModal from "@/components/DoWorkbench/WorkbenchLotLabelPrintModal"; import FGPickOrderCard from "@/components/FinishedGoodSearch/FGPickOrderCard"; import LinearProgressWithLabel from "@/components/common/LinearProgressWithLabel"; @@ -423,20 +429,6 @@ function getWorkbenchSourceLotStatusSummary(lot: any): { type PickOrderT = (key: string, options?: Record) => string; -function translateWorkbenchRejectMessage(raw: string, t: PickOrderT): string { - const msg = raw.trim(); - if (!msg) return msg; - - const expiredMatch = msg.match(/^Lot is expired \(expiry=([^)]+)\)\.?$/i); - if (expiredMatch) { - return t("Lot is expired (expiry={{expiry}})", { - expiry: expiredMatch[1], - }); - } - - return t(msg); -} - function isExpiredWorkbenchReminderMessage(msg: string): boolean { const trimmed = msg.trim(); if (!trimmed) return false; @@ -444,33 +436,6 @@ function isExpiredWorkbenchReminderMessage(msg: string): boolean { return /已過期/.test(trimmed) || /掃描批號已過期/.test(trimmed); } -type UnpickableScanAvailability = "expired" | "status_unavailable"; - -function inferUnpickableScanAvailability( - failMsg: string | null | undefined, -): UnpickableScanAvailability | null { - const m = String(failMsg ?? "").trim().toLowerCase(); - if (!m) return null; - if ( - m.includes("expired") || - m.includes("过期") || - m.includes("已過期") || - /^lot is expired/.test(m) - ) { - return "expired"; - } - if ( - m.includes("unavailable") || - m.includes("not available") || - m.includes("not yet putaway") || - m.includes("不可用") || - m.includes("未上架") - ) { - return "status_unavailable"; - } - return null; -} - function buildUnpickableScanRowPatch( scannedLot: any | null | undefined, availability: UnpickableScanAvailability, @@ -937,7 +902,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO ) { workbenchFinishNavigateDoneRef.current = true; const redirectParams = new URLSearchParams(); - redirectParams.set("tab", "2"); + redirectParams.set("tab", String(WORKBENCH_TAB_FINISHED_GOOD_RECORD_MINE)); redirectParams.set("ticketNo", ticketForRedirect); if (targetDateForRedirect) { redirectParams.set("targetDate", targetDateForRedirect); @@ -1434,7 +1399,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO const event = new CustomEvent('pickOrderCompletionStatus', { detail: { allLotsCompleted, - tabIndex: 2 // DO workbench「Finished Good Record (mine)」分頁索引 + tabIndex: WORKBENCH_TAB_FINISHED_GOOD_RECORD_MINE, } }); window.dispatchEvent(event); @@ -1669,16 +1634,11 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO } }; - /** Stop QR effect re-entry after unpickable modal (expired/unavailable API fail). */ - const markUnpickableScanSessionHandled = ( - itemId: number, - stockOutLineId: number | null | undefined, - ) => { - if (stockOutLineId != null) { - setProcessedQrCombinations((prev) => - markProcessedStockOutLine(prev, itemId, stockOutLineId), - ); - } + /** + * Stop QR effect re-entry after unpickable modal (expired/unavailable API fail). + * Do NOT mark stock-out line as processed — pick was not completed; user may scan another lot. + */ + const markUnpickableScanSessionHandled = () => { recordHandledQrScanCount(qrScanCountAtInvoke); }; @@ -1778,10 +1738,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO `此批次(${scannedLot.lotNo || scannedStockInLineId})已被拒绝,无法使用。请扫描其他批次。` ); }); - markUnpickableScanSessionHandled( - scannedItemId, - scannedLot.stockOutLineId, - ); + markUnpickableScanSessionHandled(); return; } @@ -1796,10 +1753,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO scannedLot, t("This lot is not available, please scan another lot."), ); - markUnpickableScanSessionHandled( - scannedItemId, - scannedLot.stockOutLineId, - ); + markUnpickableScanSessionHandled(); return; } @@ -1814,10 +1768,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO scannedLot, `Lot is expired (expiry=${scannedLot.expiryDate || "-"})`, ); - markUnpickableScanSessionHandled( - scannedItemId, - scannedLot.stockOutLineId, - ); + markUnpickableScanSessionHandled(); return; } } @@ -1929,10 +1880,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO null, failMsg, ); - markUnpickableScanSessionHandled( - scannedItemId, - expectedLot.stockOutLineId, - ); + markUnpickableScanSessionHandled(); return; } if (workbenchMode && expectedLot.stockOutLineId != null) { @@ -2109,10 +2057,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO }, failMsg, ); - markUnpickableScanSessionHandled( - scannedItemId, - expectedLot.stockOutLineId, - ); + markUnpickableScanSessionHandled(); return; } if (workbenchMode && expectedLot.stockOutLineId != null) { @@ -2300,10 +2245,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO exactMatch ) { openUnpickableScanLotLabelModal(exactMatch, exactMatch, failMsg); - markUnpickableScanSessionHandled( - scannedItemId, - exactMatch.stockOutLineId, - ); + markUnpickableScanSessionHandled(); return; } if (workbenchMode && exactMatch.stockOutLineId != null) { @@ -2428,10 +2370,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO }, failMsg, ); - markUnpickableScanSessionHandled( - scannedItemId, - expectedLot.stockOutLineId, - ); + markUnpickableScanSessionHandled(); return; } if (workbenchMode && expectedLot.stockOutLineId != null) {