| @@ -1767,6 +1767,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO | |||||
| const byLotId = new Map<number, any>(); | const byLotId = new Map<number, any>(); | ||||
| const byLotNo = new Map<string, any[]>(); | const byLotNo = new Map<string, any[]>(); | ||||
| const byStockInLineId = new Map<number, any[]>(); | const byStockInLineId = new Map<number, any[]>(); | ||||
| // Cache active lots separately to avoid filtering on every scan | // Cache active lots separately to avoid filtering on every scan | ||||
| const activeLotsByItemId = new Map<number, any[]>(); | const activeLotsByItemId = new Map<number, any[]>(); | ||||
| const rejectedStatuses = new Set(['rejected']); | const rejectedStatuses = new Set(['rejected']); | ||||
| @@ -1838,6 +1839,7 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO | |||||
| const processOutsideQrCode = useCallback(async (latestQr: string, qrScanCountAtInvoke?: number) => { | const processOutsideQrCode = useCallback(async (latestQr: string, qrScanCountAtInvoke?: number) => { | ||||
| const totalStartTime = performance.now(); | const totalStartTime = performance.now(); | ||||
| console.log(` [PROCESS OUTSIDE QR START] QR: ${latestQr.substring(0, 50)}...`); | console.log(` [PROCESS OUTSIDE QR START] QR: ${latestQr.substring(0, 50)}...`); | ||||
| console.log(` Start time: ${new Date().toISOString()}`); | console.log(` Start time: ${new Date().toISOString()}`); | ||||
| @@ -1855,6 +1857,9 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO | |||||
| qrData = JSON.parse(latestQr); | qrData = JSON.parse(latestQr); | ||||
| parseTime = performance.now() - parseStartTime; | parseTime = performance.now() - parseStartTime; | ||||
| console.log(` [PERF] JSON parse time: ${parseTime.toFixed(2)}ms`); | console.log(` [PERF] JSON parse time: ${parseTime.toFixed(2)}ms`); | ||||
| console.log("[QR DEBUG] qrData:", qrData); | |||||
| console.log("[QR DEBUG] typeof itemId:", typeof qrData?.itemId, "value:", qrData?.itemId); | |||||
| console.log("[QR DEBUG] typeof stockInLineId:", typeof qrData?.stockInLineId, "value:", qrData?.stockInLineId); | |||||
| } catch { | } catch { | ||||
| console.log("QR content is not JSON; skipping lotNo direct submit to avoid false matches."); | console.log("QR content is not JSON; skipping lotNo direct submit to avoid false matches."); | ||||
| startTransition(() => { | startTransition(() => { | ||||
| @@ -1875,11 +1880,32 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO | |||||
| return; | return; | ||||
| } | } | ||||
| const validationTime = performance.now() - validationStartTime; | const validationTime = performance.now() - validationStartTime; | ||||
| console.log(` [PERF] Validation time: ${validationTime.toFixed(2)}ms`); | |||||
| console.log("[QR DEBUG] raw latestQr:", latestQr); | |||||
| console.log("[QR DEBUG] qrData:", qrData); | |||||
| console.log("[QR DEBUG] typeof qrData.itemId:", typeof qrData?.itemId, "value:", qrData?.itemId); | |||||
| console.log("[QR DEBUG] typeof qrData.stockInLineId:", typeof qrData?.stockInLineId, "value:", qrData?.stockInLineId); | |||||
| const scannedItemId = qrData.itemId; | const scannedItemId = qrData.itemId; | ||||
| const scannedStockInLineId = qrData.stockInLineId; | const scannedStockInLineId = qrData.stockInLineId; | ||||
| console.log("[QR DEBUG] combinedLotData.length:", combinedLotData?.length); | |||||
| const directBySil = (combinedLotData || []).find( | |||||
| (l: any) => String(l?.stockInLineId) === String(scannedStockInLineId) | |||||
| ); | |||||
| console.log("[QR DEBUG] direct match by stockInLineId:", directBySil); | |||||
| const sample0: any = combinedLotData?.[0]; | |||||
| if (sample0) { | |||||
| console.log("[QR DEBUG] combinedLotData[0] id fields:", { | |||||
| itemId: sample0.itemId, | |||||
| stockInLineId: sample0.stockInLineId, | |||||
| tItemId: typeof sample0.itemId, | |||||
| tStockInLineId: typeof sample0.stockInLineId, | |||||
| lotNo: sample0.lotNo, | |||||
| lotId: sample0.lotId, | |||||
| }); | |||||
| } else { | |||||
| console.log("[QR DEBUG] combinedLotData[0] is empty/undefined"); | |||||
| } | |||||
| // ✅ Check if this combination was already processed | // ✅ Check if this combination was already processed | ||||
| const duplicateCheckStartTime = performance.now(); | const duplicateCheckStartTime = performance.now(); | ||||
| const itemProcessedSet = processedQrCombinations.get(scannedItemId); | const itemProcessedSet = processedQrCombinations.get(scannedItemId); | ||||
| @@ -1894,8 +1920,14 @@ const fetchAllCombinedLotData = useCallback(async (userId?: number, pickOrderIdO | |||||
| // ✅ OPTIMIZATION: Use cached active lots directly (no filtering needed) | // ✅ OPTIMIZATION: Use cached active lots directly (no filtering needed) | ||||
| const lookupStartTime = performance.now(); | const lookupStartTime = performance.now(); | ||||
| const activeSuggestedLots = indexes.activeLotsByItemId.get(scannedItemId) || []; | const activeSuggestedLots = indexes.activeLotsByItemId.get(scannedItemId) || []; | ||||
| console.log("[QR DEBUG] byItemId.has(num):", indexes.byItemId.has(Number(scannedItemId))); | |||||
| //console.log("[QR DEBUG] byItemId.has(str):", indexes.byItemId.has(String(scannedItemId))); | |||||
| console.log("[QR DEBUG] byStockInLineId.has(num):", indexes.byStockInLineId.has(Number(scannedStockInLineId))); | |||||
| //console.log("[QR DEBUG] byStockInLineId.has(str):", indexes.byStockInLineId.has(String(scannedStockInLineId))); | |||||
| // ✅ Also get all lots for this item (not just active ones) to allow lot switching even when all lots are rejected | // ✅ Also get all lots for this item (not just active ones) to allow lot switching even when all lots are rejected | ||||
| const allLotsForItem = indexes.byItemId.get(scannedItemId) || []; | const allLotsForItem = indexes.byItemId.get(scannedItemId) || []; | ||||
| const lookupTime = performance.now() - lookupStartTime; | const lookupTime = performance.now() - lookupStartTime; | ||||
| console.log(` [PERF] Index lookup time: ${lookupTime.toFixed(2)}ms, found ${activeSuggestedLots.length} active lots, ${allLotsForItem.length} total lots`); | console.log(` [PERF] Index lookup time: ${lookupTime.toFixed(2)}ms, found ${activeSuggestedLots.length} active lots, ${allLotsForItem.length} total lots`); | ||||