| @@ -20,6 +20,7 @@ import { | |||||
| Modal, | Modal, | ||||
| Chip, | Chip, | ||||
| } from "@mui/material"; | } from "@mui/material"; | ||||
| import dayjs from 'dayjs'; | |||||
| import TestQrCodeProvider from '../QrCodeScannerProvider/TestQrCodeProvider'; | import TestQrCodeProvider from '../QrCodeScannerProvider/TestQrCodeProvider'; | ||||
| import { fetchLotDetail } from "@/app/api/inventory/actions"; | import { fetchLotDetail } from "@/app/api/inventory/actions"; | ||||
| import { useCallback, useEffect, useState, useRef, useMemo } from "react"; | import { useCallback, useEffect, useState, useRef, useMemo } from "react"; | ||||
| @@ -34,7 +35,7 @@ import { | |||||
| fetchFGPickOrders, // ✅ Add this import | fetchFGPickOrders, // ✅ Add this import | ||||
| FGPickOrderResponse, | FGPickOrderResponse, | ||||
| stockReponse, | stockReponse, | ||||
| PickExecutionIssueData, | |||||
| checkPickOrderCompletion, | checkPickOrderCompletion, | ||||
| fetchAllPickOrderLotsHierarchical, | fetchAllPickOrderLotsHierarchical, | ||||
| PickOrderCompletionResponse, | PickOrderCompletionResponse, | ||||
| @@ -1466,6 +1467,7 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe | |||||
| stopScan(); | stopScan(); | ||||
| resetScan(); | resetScan(); | ||||
| }, [stopScan, resetScan]); | }, [stopScan, resetScan]); | ||||
| // ... existing code around line 1469 ... | |||||
| const handlelotnull = useCallback(async (lot: any) => { | const handlelotnull = useCallback(async (lot: any) => { | ||||
| // ✅ 优先使用 stockouts 中的 id,如果没有则使用 stockOutLineId | // ✅ 优先使用 stockouts 中的 id,如果没有则使用 stockOutLineId | ||||
| const stockOutLineId = lot.stockOutLineId; | const stockOutLineId = lot.stockOutLineId; | ||||
| @@ -1475,13 +1477,57 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe | |||||
| return; | 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 handleSubmitAllScanned = useCallback(async () => { | ||||
| const scannedLots = combinedLotData.filter(lot => { | const scannedLots = combinedLotData.filter(lot => { | ||||
| // ✅ 如果是 noLot 情况,检查状态是否为 pending 或 partially_complete | // ✅ 如果是 noLot 情况,检查状态是否为 pending 或 partially_complete | ||||
| @@ -1516,6 +1562,30 @@ const handleSubmitPickQtyWithQty = useCallback(async (lot: any, submitQty: numbe | |||||
| qty: 0 | qty: 0 | ||||
| }); | }); | ||||
| console.log(`✅ No-lot item completed: ${lot.itemName || lot.itemCode}`); | 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 }; | return { success: true, lotNo: lot.lotNo || 'No Lot', isNoLot: true }; | ||||
| } | } | ||||
| @@ -1888,7 +1958,7 @@ paginatedData.map((lot, index) => { | |||||
| }} | }} | ||||
| /> | /> | ||||
| </Box> | </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' }}> | <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}> | ||||
| <Checkbox | <Checkbox | ||||
| checked={true} | checked={true} | ||||
| @@ -1913,6 +1983,9 @@ paginatedData.map((lot, index) => { | |||||
| variant="outlined" | variant="outlined" | ||||
| size="small" | size="small" | ||||
| onClick={() => handlelotnull(lot)} | onClick={() => handlelotnull(lot)} | ||||
| disabled={ | |||||
| lot.stockOutLineStatus === 'completed' | |||||
| } | |||||
| sx={{ | sx={{ | ||||
| fontSize: '0.7rem', | fontSize: '0.7rem', | ||||
| py: 0.5, | py: 0.5, | ||||