| @@ -20,6 +20,7 @@ import { | |||
| Modal, | |||
| Chip, | |||
| } from "@mui/material"; | |||
| import dayjs from 'dayjs'; | |||
| import TestQrCodeProvider from '../QrCodeScannerProvider/TestQrCodeProvider'; | |||
| import { fetchLotDetail } from "@/app/api/inventory/actions"; | |||
| import { useCallback, useEffect, useState, useRef, useMemo } from "react"; | |||
| @@ -34,7 +35,7 @@ import { | |||
| fetchFGPickOrders, // ✅ Add this import | |||
| FGPickOrderResponse, | |||
| stockReponse, | |||
| PickExecutionIssueData, | |||
| checkPickOrderCompletion, | |||
| fetchAllPickOrderLotsHierarchical, | |||
| PickOrderCompletionResponse, | |||
| @@ -1466,6 +1467,7 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe | |||
| stopScan(); | |||
| resetScan(); | |||
| }, [stopScan, resetScan]); | |||
| // ... existing code around line 1469 ... | |||
| const handlelotnull = useCallback(async (lot: any) => { | |||
| // ✅ 优先使用 stockouts 中的 id,如果没有则使用 stockOutLineId | |||
| const stockOutLineId = lot.stockOutLineId; | |||
| @@ -1475,13 +1477,57 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe | |||
| return; | |||
| } | |||
| await updateStockOutLineStatus({ | |||
| id: stockOutLineId, // ✅ 现在这个值应该来自 stockouts 数组的 id | |||
| status: 'completed', | |||
| qty: 0 | |||
| }); | |||
| await fetchAllCombinedLotData(); | |||
| }, [fetchAllCombinedLotData]); | |||
| try { | |||
| // ✅ Step 1: Update stock out line status | |||
| await updateStockOutLineStatus({ | |||
| id: stockOutLineId, | |||
| status: 'completed', | |||
| qty: 0 | |||
| }); | |||
| // ✅ Step 2: Create pick execution issue for no-lot case | |||
| // Get pick order ID from fgPickOrders or use 0 if not available | |||
| const pickOrderId = lot.pickOrderId || fgPickOrders[0]?.pickOrderId || 0; | |||
| const pickOrderCode = lot.pickOrderCode || fgPickOrders[0]?.pickOrderCode || lot.pickOrderConsoCode || ''; | |||
| const issueData: PickExecutionIssueData = { | |||
| type: "Do", // Delivery Order type | |||
| pickOrderId: pickOrderId, | |||
| pickOrderCode: pickOrderCode, | |||
| pickOrderCreateDate: dayjs().format('YYYY-MM-DD'), // ✅ Use dayjs format | |||
| pickExecutionDate: dayjs().format('YYYY-MM-DD'), | |||
| pickOrderLineId: lot.pickOrderLineId, | |||
| itemId: lot.itemId, | |||
| itemCode: lot.itemCode || '', | |||
| itemDescription: lot.itemName || '', | |||
| lotId: null, // ✅ No lot available | |||
| lotNo: null, // ✅ No lot number | |||
| storeLocation: lot.location || '', | |||
| requiredQty: lot.requiredQty || lot.pickOrderLineRequiredQty || 0, | |||
| actualPickQty: 0, // ✅ No items picked (no lot available) | |||
| missQty: lot.requiredQty || lot.pickOrderLineRequiredQty || 0, // ✅ All quantity is missing | |||
| badItemQty: 0, | |||
| issueRemark: `No lot available for this item. Handled via handlelotnull.`, | |||
| pickerName: session?.user?.name || '', | |||
| }; | |||
| const result = await recordPickExecutionIssue(issueData); | |||
| console.log("✅ Pick execution issue created for no-lot item:", result); | |||
| if (result && result.code === "SUCCESS") { | |||
| console.log("✅ No-lot item handled and issue recorded successfully"); | |||
| } else { | |||
| console.error("❌ Failed to record pick execution issue:", result); | |||
| } | |||
| // ✅ Step 3: Refresh data | |||
| await fetchAllCombinedLotData(); | |||
| } catch (error) { | |||
| console.error("❌ Error in handlelotnull:", error); | |||
| } | |||
| }, [fetchAllCombinedLotData, session, currentUserId, fgPickOrders]); | |||
| // ... existing code ... | |||
| const handleSubmitAllScanned = useCallback(async () => { | |||
| const scannedLots = combinedLotData.filter(lot => { | |||
| // ✅ 如果是 noLot 情况,检查状态是否为 pending 或 partially_complete | |||
| @@ -1516,6 +1562,30 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe | |||
| qty: 0 | |||
| }); | |||
| console.log(`✅ No-lot item completed: ${lot.itemName || lot.itemCode}`); | |||
| const pickOrderId = lot.pickOrderId || fgPickOrders[0]?.pickOrderId || 0; | |||
| const pickOrderCode = lot.pickOrderCode || fgPickOrders[0]?.pickOrderCode || lot.pickOrderConsoCode || ''; | |||
| const issueData: PickExecutionIssueData = { | |||
| type: "Do", // Delivery Order type | |||
| pickOrderId: pickOrderId, | |||
| pickOrderCode: pickOrderCode, | |||
| pickOrderCreateDate: dayjs().format('YYYY-MM-DD'), // ✅ Use dayjs format | |||
| pickExecutionDate: dayjs().format('YYYY-MM-DD'), | |||
| pickOrderLineId: lot.pickOrderLineId, | |||
| itemId: lot.itemId, | |||
| itemCode: lot.itemCode || '', | |||
| itemDescription: lot.itemName || '', | |||
| lotId: null, // ✅ No lot available | |||
| lotNo: null, // ✅ No lot number | |||
| storeLocation: lot.location || '', | |||
| requiredQty: lot.requiredQty || lot.pickOrderLineRequiredQty || 0, | |||
| actualPickQty: 0, // ✅ No items picked (no lot available) | |||
| missQty: lot.requiredQty || lot.pickOrderLineRequiredQty || 0, | |||
| badItemQty: 0, | |||
| issueRemark: `No lot available for this item. Handled via handlelotnull.`, | |||
| pickerName: session?.user?.name || '', | |||
| }; | |||
| const result = await recordPickExecutionIssue(issueData); | |||
| return { success: true, lotNo: lot.lotNo || 'No Lot', isNoLot: true }; | |||
| } | |||
| @@ -1888,7 +1958,7 @@ paginatedData.map((lot, index) => { | |||
| }} | |||
| /> | |||
| </Box> | |||
| ) : isIssueLot&&lot.stockOutLineStatus?.toLowerCase() == 'partially_completed' ? ( | |||
| ) : isIssueLot&&lot.stockOutLineStatus?.toLowerCase() == 'partially_completed'||lot.stockOutLineStatus?.toLowerCase() == 'completed' ? ( | |||
| <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}> | |||
| <Checkbox | |||
| checked={true} | |||
| @@ -1913,6 +1983,9 @@ paginatedData.map((lot, index) => { | |||
| variant="outlined" | |||
| size="small" | |||
| onClick={() => handlelotnull(lot)} | |||
| disabled={ | |||
| lot.stockOutLineStatus === 'completed' | |||
| } | |||
| sx={{ | |||
| fontSize: '0.7rem', | |||
| py: 0.5, | |||