"use client"; import { Box, Button, Stack, TextField, Typography, Alert, CircularProgress, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, TablePagination, Modal, Card, CardContent, CardActions, Chip, Accordion, AccordionSummary, AccordionDetails, Checkbox, Autocomplete, } from "@mui/material"; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import { useCallback, useEffect, useState, useRef, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { useRouter } from "next/navigation"; import { fetchCompletedJobOrderPickOrdersrecords, fetchCompletedJobOrderPickOrderLotDetailsForCompletedPick, PrintPickRecord } from "@/app/api/jo/actions"; import { fetchNameList, NameList } from "@/app/api/user/actions"; import { FormProvider, useForm, } from "react-hook-form"; import SearchBox, { Criterion } from "../SearchBox"; import { useSession } from "next-auth/react"; import { SessionWithTokens } from "@/config/authConfig"; import Swal from "sweetalert2"; import { PrinterCombo } from "@/app/api/settings/printer"; interface Props { filterArgs: Record; printerCombo: PrinterCombo[]; } // 修改:已完成的 Job Order Pick Order 接口 interface CompletedJobOrderPickOrder { id: number; pickOrderId: number; pickOrderCode: string; pickOrderConsoCode: string; pickOrderTargetDate: string; pickOrderStatus: string; completedDate: string; jobOrderId: number; jobOrderCode: string; jobOrderName: string; reqQty: number; uom: string; planStart: string; planEnd: string; secondScanCompleted: boolean; totalItems: number; completedItems: number; } // 新增:Lot 详情接口 interface LotDetail { lotId: number; lotNo: string; expiryDate: string; location: string; availableQty: number; requiredQty: number; actualPickQty: number; processingStatus: string; lotAvailability: string; pickOrderId: number; pickOrderCode: string; pickOrderConsoCode: string; pickOrderLineId: number; stockOutLineId: number; stockOutLineStatus: string; routerIndex: number; routerArea: string; routerRoute: string; uomShortDesc: string; secondQrScanStatus: string; itemId: number; itemCode: string; itemName: string; uomCode: string; uomDesc: string; } const CompleteJobOrderRecord: React.FC = ({ filterArgs ,printerCombo}) => { const { t } = useTranslation("jo"); const router = useRouter(); const { data: session } = useSession() as { data: SessionWithTokens | null }; const currentUserId = session?.id ? parseInt(session.id) : undefined; // 修改:已完成 Job Order Pick Orders 状态 const [completedJobOrderPickOrders, setCompletedJobOrderPickOrders] = useState([]); const [completedJobOrderPickOrdersLoading, setCompletedJobOrderPickOrdersLoading] = useState(false); // 修改:详情视图状态 const [selectedJobOrderPickOrder, setSelectedJobOrderPickOrder] = useState(null); const [showDetailView, setShowDetailView] = useState(false); const [detailLotData, setDetailLotData] = useState([]); const [detailLotDataLoading, setDetailLotDataLoading] = useState(false); // 修改:搜索状态 const [searchQuery, setSearchQuery] = useState>({}); const [filteredJobOrderPickOrders, setFilteredJobOrderPickOrders] = useState([]); //const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]); const defaultDemoPrinter: PrinterCombo = { id: 2, value: 2, name: "2fi", label: "2fi", code: "2fi" }; const availablePrinters = useMemo(() => { if (printerCombo.length === 0) { console.log("No printers available, using default demo printer"); return [defaultDemoPrinter]; } return printerCombo; }, [printerCombo]); const [selectedPrinter, setSelectedPrinter] = useState( printerCombo && printerCombo.length > 0 ? printerCombo[0] : null ); const [printQty, setPrintQty] = useState(1); // 修改:分页状态 const [paginationController, setPaginationController] = useState({ pageNum: 0, pageSize: 10, }); const formProps = useForm(); const errors = formProps.formState.errors; // 修改:使用新的 Job Order API 获取已完成的 Job Order Pick Orders(仅完成pick的) const fetchCompletedJobOrderPickOrdersData = useCallback(async () => { if (!currentUserId) return; setCompletedJobOrderPickOrdersLoading(true); try { console.log("🔍 Fetching completed Job Order pick orders (pick completed only)..."); const completedJobOrderPickOrders = await fetchCompletedJobOrderPickOrdersrecords(currentUserId); // Fix: Ensure the data is always an array const safeData = Array.isArray(completedJobOrderPickOrders) ? completedJobOrderPickOrders : []; setCompletedJobOrderPickOrders(safeData); setFilteredJobOrderPickOrders(safeData); console.log(" Fetched completed Job Order pick orders:", safeData); } catch (error) { console.error("❌ Error fetching completed Job Order pick orders:", error); setCompletedJobOrderPickOrders([]); setFilteredJobOrderPickOrders([]); } finally { setCompletedJobOrderPickOrdersLoading(false); } }, [currentUserId]); // 新增:获取 lot 详情数据(使用新的API) const fetchLotDetailsData = useCallback(async (pickOrderId: number) => { setDetailLotDataLoading(true); try { console.log("🔍 Fetching lot details for completed pick order:", pickOrderId); const lotDetails = await fetchCompletedJobOrderPickOrderLotDetailsForCompletedPick(pickOrderId); setDetailLotData(lotDetails); console.log(" Fetched lot details:", lotDetails); } catch (error) { console.error("❌ Error fetching lot details:", error); setDetailLotData([]); } finally { setDetailLotDataLoading(false); } }, []); // 修改:初始化时获取数据 useEffect(() => { if (currentUserId) { fetchCompletedJobOrderPickOrdersData(); } }, [currentUserId, fetchCompletedJobOrderPickOrdersData]); // 修改:搜索功能 const handleSearch = useCallback((query: Record) => { setSearchQuery({ ...query }); console.log("Search query:", query); // Fix: Ensure completedJobOrderPickOrders is an array before filtering if (!Array.isArray(completedJobOrderPickOrders)) { setFilteredJobOrderPickOrders([]); return; } const filtered = completedJobOrderPickOrders.filter((pickOrder) => { const pickOrderCodeMatch = !query.pickOrderCode || pickOrder.pickOrderCode?.toLowerCase().includes((query.pickOrderCode || "").toLowerCase()); const jobOrderCodeMatch = !query.jobOrderCode || pickOrder.jobOrderCode?.toLowerCase().includes((query.jobOrderCode || "").toLowerCase()); const jobOrderNameMatch = !query.jobOrderName || pickOrder.jobOrderName?.toLowerCase().includes((query.jobOrderName || "").toLowerCase()); return pickOrderCodeMatch && jobOrderCodeMatch && jobOrderNameMatch; }); setFilteredJobOrderPickOrders(filtered); console.log("Filtered Job Order pick orders count:", filtered.length); }, [completedJobOrderPickOrders]); // 修改:重置搜索 const handleSearchReset = useCallback(() => { setSearchQuery({}); // Fix: Ensure completedJobOrderPickOrders is an array before setting setFilteredJobOrderPickOrders(Array.isArray(completedJobOrderPickOrders) ? completedJobOrderPickOrders : []); }, [completedJobOrderPickOrders]); // 修改:分页功能 const handlePageChange = useCallback((event: unknown, newPage: number) => { setPaginationController(prev => ({ ...prev, pageNum: newPage, })); }, []); const handlePageSizeChange = useCallback((event: React.ChangeEvent) => { const newPageSize = parseInt(event.target.value, 10); setPaginationController({ pageNum: 0, pageSize: newPageSize, }); }, []); // 修改:分页数据 const paginatedData = useMemo(() => { // Fix: Ensure filteredJobOrderPickOrders is an array before calling slice if (!Array.isArray(filteredJobOrderPickOrders)) { return []; } const startIndex = paginationController.pageNum * paginationController.pageSize; const endIndex = startIndex + paginationController.pageSize; return filteredJobOrderPickOrders.slice(startIndex, endIndex); }, [filteredJobOrderPickOrders, paginationController]); // 修改:搜索条件 const searchCriteria: Criterion[] = [ { label: t("Pick Order Code"), paramName: "pickOrderCode", type: "text", }, { label: t("Job Order Code"), paramName: "jobOrderCode", type: "text", }, { label: t("Job Order Item Name"), paramName: "jobOrderName", type: "text", } ]; // 修改:详情点击处理 const handleDetailClick = useCallback(async (jobOrderPickOrder: CompletedJobOrderPickOrder) => { setSelectedJobOrderPickOrder(jobOrderPickOrder); setShowDetailView(true); // 获取 lot 详情数据(使用新的API) await fetchLotDetailsData(jobOrderPickOrder.pickOrderId); // 触发打印按钮状态更新 - 基于详情数据 const allCompleted = jobOrderPickOrder.secondScanCompleted; // 发送事件,包含标签页信息 window.dispatchEvent(new CustomEvent('pickOrderCompletionStatus', { detail: { allLotsCompleted: allCompleted, tabIndex: 3 // 明确指定这是来自标签页 3 的事件 } })); }, [fetchLotDetailsData]); // 修改:返回列表视图 const handleBackToList = useCallback(() => { setShowDetailView(false); setSelectedJobOrderPickOrder(null); setDetailLotData([]); // 返回列表时禁用打印按钮 window.dispatchEvent(new CustomEvent('pickOrderCompletionStatus', { detail: { allLotsCompleted: false, tabIndex: 3 } })); }, []); const handlePickRecord = useCallback(async (jobOrderPickOrder: CompletedJobOrderPickOrder) => { try { if (!jobOrderPickOrder) { console.error("No selected job order pick order available"); return; } // 检查是否已选择打印机 if (!selectedPrinter) { Swal.fire({ position: "bottom-end", icon: "warning", text: t("Please select a printer first"), showConfirmButton: false, timer: 1500 }); return; } // 检查打印数量是否有效 if (!printQty || printQty < 1) { Swal.fire({ position: "bottom-end", icon: "warning", text: t("Please enter a valid print quantity (at least 1)"), showConfirmButton: false, timer: 1500 }); return; } const pickOrderId = jobOrderPickOrder.pickOrderId; console.log("Pick Order ID:", pickOrderId); // 使用已选择的打印机和数量 const printerId = selectedPrinter.id; const printRequest = { pickOrderId: pickOrderId, printerId: printerId, printQty: printQty }; console.log("Printing Pick Record with request: ", printRequest); const response = await PrintPickRecord(printRequest); console.log("Print Pick Record response: ", response); if (response.success) { Swal.fire({ position: "bottom-end", icon: "success", text: t("Printed Successfully."), showConfirmButton: false, timer: 1500 }); } else { console.error("Print failed: ", response.message); Swal.fire({ position: "bottom-end", icon: "error", text: response.message || t("Print failed"), showConfirmButton: false, timer: 1500 }); } } catch (error) { console.error("error: ", error); Swal.fire({ position: "bottom-end", icon: "error", text: t("An error occurred while printing"), showConfirmButton: false, timer: 1500 }); } }, [t, selectedPrinter, printQty]); // 修改:如果显示详情视图,渲染 Job Order 详情和 Lot 信息 if (showDetailView && selectedJobOrderPickOrder) { return ( {/* 返回按钮和标题 */} {t("Job Order Pick Order Details")}: {selectedJobOrderPickOrder.pickOrderCode} {/* Job Order 信息卡片 */} {t("Pick Order Code")}: {selectedJobOrderPickOrder.pickOrderCode} {t("Job Order Code")}: {selectedJobOrderPickOrder.jobOrderCode} {t("Job Order Item Name")}: {selectedJobOrderPickOrder.jobOrderName} {t("Target Date")}: {selectedJobOrderPickOrder.pickOrderTargetDate} {t("Required Qty")}: {selectedJobOrderPickOrder.reqQty} {selectedJobOrderPickOrder.uom} {/* */} {/* 修改:Lot 详情表格 - 添加复选框列 */} {t("Lot Details")} {detailLotDataLoading ? ( ) : ( {t("Index")} {t("Route")} {t("Item Code")} {t("Item Name")} {t("Lot No")} {t("Location")} {t("Required Qty")} {t("Actual Pick Qty")} {t("Processing Status")} {t("Second Scan Status")} {detailLotData.length === 0 ? ( {t("No lot details available")} ) : ( detailLotData.map((lot, index) => ( {index + 1} {lot.routerRoute || '-'} {lot.itemCode} {lot.itemName} {lot.lotNo} {lot.location} {lot.requiredQty?.toLocaleString() || 0} ({lot.uomShortDesc}) {lot.actualPickQty?.toLocaleString() || 0} ({lot.uomShortDesc}) {/* 修改:Processing Status 使用复选框 */} {/* 修改:Second Scan Status 使用复选框 */} )) )}
)}
); } // 修改:默认列表视图 return ( {/* 搜索框 */} {/* 加载状态 */} {completedJobOrderPickOrdersLoading ? ( ) : ( {/* 结果统计 */} {t("Total")}: {filteredJobOrderPickOrders.length} {t("completed Job Order pick orders with matching")} {t("Select Printer")}: option.name || option.label || option.code || `Printer ${option.id}`} value={selectedPrinter} onChange={(_, newValue) => setSelectedPrinter(newValue)} sx={{ minWidth: 250 }} size="small" renderInput={(params) => } /> {t("Print Quantity")}: { const value = parseInt(e.target.value) || 1; setPrintQty(Math.max(1, value)); }} inputProps={{ min: 1, step: 1 }} sx={{ width: 120 }} size="small" /> {/* 列表 */} {filteredJobOrderPickOrders.length === 0 ? ( {t("No completed Job Order pick orders with matching found")} ) : ( {paginatedData.map((jobOrderPickOrder) => ( {jobOrderPickOrder.jobOrderCode} {jobOrderPickOrder.jobOrderName} - {jobOrderPickOrder.pickOrderCode} {t("Completed")}: {new Date(jobOrderPickOrder.completedDate).toLocaleString()} {t("Target Date")}: {jobOrderPickOrder.pickOrderTargetDate} {jobOrderPickOrder.completedItems}/{jobOrderPickOrder.totalItems} {t("items completed")} ))} )} {/* 分页 */} {filteredJobOrderPickOrders.length > 0 && ( )} )} ); }; export default CompleteJobOrderRecord;