|
- "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 {
- fetchJobOrderPickOrdersrecords,
- fetchJobOrderPickOrderLotDetailsForPick,
- 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";
- import {
- buildPrintPickRecordRequest,
- promptAllFloorsPlasticBoxCartonQty,
- promptPlasticBoxCartonQty,
- type PickRecordFloor,
- } from "./pickRecordHelpers";
- import dayjs from "dayjs";
- interface Props {
- filterArgs: Record<string, any>;
- printerCombo: PrinterCombo[];
- selectedPrinter?: PrinterCombo | null;
- printQty?: number;
- initialPickOrderCode?: string;
- initialTargetDate?: string;
- /** When true (Item Tracing `openDetail=1`), auto-open matching pick-order detail. */
- openDetail?: boolean;
- }
-
- // 修改:已完成的 Job Order Pick Order 接口
- interface CompletedJobOrderPickOrder {
- id: number;
- pickOrderId: number;
- pickOrderCode: string;
- pickOrderConsoCode: string;
- pickOrderTargetDate: string;
- pickOrderStatus: string;
- // Backend可能返回 [yyyy, MM, dd, HH, mm, ss] 或字符串,前端统一在 helper 里转成 YYYY-MM-DD
- completedDate: any;
- jobOrderId: number;
- jobOrderCode: string;
- jobOrderName: string;
- reqQty: number;
- uom: string;
- planStart: any;
- planEnd: any;
- secondScanCompleted: boolean;
- totalItems: number;
- completedItems: number;
- }
-
- // 新增:Lot 详情接口
- interface LotDetail {
- lotId: number | null;
- lotNo: string | null;
- expiryDate: string | null;
- location: string | null;
- availableQty: number | null;
- requiredQty: number | null;
- actualPickQty: number | null;
- processingStatus: string;
- lotAvailability: string;
- pickOrderId: number;
- pickOrderCode: string;
- pickOrderConsoCode: string;
- pickOrderLineId: number;
- stockOutLineId: number | null;
- stockOutLineStatus: string;
- routerIndex: number | null;
- routerArea: string | null;
- routerRoute: string | null;
- uomShortDesc: string | null;
- secondQrScanStatus: string;
- itemId: number;
- itemCode: string;
- itemName: string;
- uomCode: string;
- uomDesc: string;
- match_status: string | null;
- }
-
- const CompleteJobOrderRecord: React.FC<Props> = ({
- filterArgs,
- printerCombo,
- selectedPrinter: selectedPrinterProp,
- printQty: printQtyProp,
- initialPickOrderCode,
- initialTargetDate,
- openDetail = false,
- }) => {
- 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<CompletedJobOrderPickOrder[]>([]);
- const [completedJobOrderPickOrdersLoading, setCompletedJobOrderPickOrdersLoading] = useState(false);
-
- // 修改:详情视图状态
- const [selectedJobOrderPickOrder, setSelectedJobOrderPickOrder] = useState<CompletedJobOrderPickOrder | null>(null);
- const [showDetailView, setShowDetailView] = useState(false);
- const [detailLotData, setDetailLotData] = useState<LotDetail[]>([]);
- const [detailLotDataLoading, setDetailLotDataLoading] = useState(false);
-
- // 修改:搜索状态
- const [searchQuery, setSearchQuery] = useState<Record<string, any>>(() => {
- const raw = initialTargetDate?.trim() || "";
- const match = raw.match(/(\d{4}-\d{2}-\d{2})/);
- return {
- completedDate: match?.[1] || dayjs().format("YYYY-MM-DD"),
- ...(initialPickOrderCode?.trim()
- ? { pickOrderCode: initialPickOrderCode.trim() }
- : {}),
- };
- });
- const [filteredJobOrderPickOrders, setFilteredJobOrderPickOrders] = useState<CompletedJobOrderPickOrder[]>([]);
-
- // Use props with fallback
- const selectedPrinter = selectedPrinterProp ?? (printerCombo && printerCombo.length > 0 ? printerCombo[0] : null);
- const printQty = printQtyProp ?? 1;
- const pickRecordPrintInFlightRef = useRef(false);
- const initialDetailOpenedRef = useRef(false);
-
- // 修改:分页状态
- 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 fetchJobOrderPickOrdersData = useCallback(
- async (forDate?: string, forStatus?: string) => {
- if (!currentUserId) return;
-
- setCompletedJobOrderPickOrdersLoading(true);
- try {
- const dateParam =
- forDate !== undefined
- ? forDate
- : searchQuery.completedDate
- ? String(searchQuery.completedDate)
- : dayjs().format("YYYY-MM-DD");
-
- const statusParam =
- forStatus !== undefined
- ? forStatus
- : searchQuery.pickOrderStatus
- ? String(searchQuery.pickOrderStatus)
- : null;
-
- const data = await fetchJobOrderPickOrdersrecords(
- dateParam?.trim() ? dateParam.trim() : null,
- statusParam?.trim() ? statusParam.trim() : null,
- );
-
- const safeData = Array.isArray(data) ? data : [];
- setCompletedJobOrderPickOrders(safeData);
- setFilteredJobOrderPickOrders(safeData);
- } finally {
- setCompletedJobOrderPickOrdersLoading(false);
- }
- },
- [currentUserId, searchQuery.completedDate, searchQuery.pickOrderStatus],
- );
- // 新增:获取 lot 详情数据(使用新的API)
- const fetchLotDetailsData = useCallback(async (pickOrderId: number) => {
- setDetailLotDataLoading(true);
- try {
- console.log("🔍 Fetching lot details for completed pick order:", pickOrderId);
-
- const lotDetails = await fetchJobOrderPickOrderLotDetailsForPick(pickOrderId);
-
- setDetailLotData(Array.isArray(lotDetails) ? lotDetails : []);
- console.log(" Fetched lot details:", lotDetails);
- } catch (error) {
- console.error("❌ Error fetching lot details:", error);
- setDetailLotData([]);
- } finally {
- setDetailLotDataLoading(false);
- }
- }, []);
-
- // 修改:初始化时获取数据
- useEffect(() => {
- if (!currentUserId) return;
- const d = searchQuery?.completedDate;
- const s = searchQuery?.pickOrderStatus;
-
- const dateStr = d != null && String(d).trim() !== "" ? String(d).trim() : "";
- const statusStr = s != null && String(s).trim() !== "" ? String(s).trim() : "";
-
- void fetchJobOrderPickOrdersData(dateStr || undefined, statusStr || undefined);
- }, [currentUserId, searchQuery?.completedDate, searchQuery?.pickOrderStatus, fetchJobOrderPickOrdersData]);
-
- // 修改:搜索功能(只更新 query;实际过滤交给 useEffect + date filter 统一处理)
- const handleSearch = useCallback((query: Record<string, any>) => {
- setSearchQuery({ ...query });
- }, []);
- const formatDateTime = (value: any) => {
- if (!value) return "-";
-
- // 后端发来的是 [yyyy, MM, dd, HH, mm, ss]
- if (Array.isArray(value)) {
- const [year, month, day, hour = 0, minute = 0, second = 0] = value;
- return new Date(year, month - 1, day, hour, minute, second).toLocaleString();
- }
-
- // 如果以后改成字符串/ISO,也兼容
- const d = new Date(value);
- return isNaN(d.getTime()) ? "-" : d.toLocaleString();
- };
- const toDateYMD = (value: any): string | null => {
- if (!value) return null;
-
- // Backend 常见格式:[yyyy, MM, dd, HH, mm, ss]
- if (Array.isArray(value)) {
- const [year, month, day] = value;
- if (!year || !month || !day) return null;
- return dayjs(new Date(Number(year), Number(month) - 1, Number(day))).format("YYYY-MM-DD");
- }
-
- // 兼容 ISO 字符串 / Date
- if (typeof value === "string") {
- const d = dayjs(value);
- return d.isValid() ? d.format("YYYY-MM-DD") : null;
- }
-
- if (value instanceof Date) {
- return dayjs(value).format("YYYY-MM-DD");
- }
-
- return null;
- };
-
- useEffect(() => {
- const query = searchQuery || {};
- const dateFilter = query.completedDate ? String(query.completedDate) : "";
-
- const filtered = (Array.isArray(completedJobOrderPickOrders) ? completedJobOrderPickOrders : []).filter((pickOrder) => {
- const pickOrderDateYMD = toDateYMD((pickOrder as any).completedDate ?? (pickOrder as any).planEnd);
- const dateMatch = !dateFilter || pickOrderDateYMD === dateFilter;
-
- const pickOrderCodeMatch =
- !query.pickOrderCode ||
- pickOrder.pickOrderCode?.toLowerCase().includes(String(query.pickOrderCode).toLowerCase());
- const jobOrderCodeMatch =
- !query.jobOrderCode ||
- pickOrder.jobOrderCode?.toLowerCase().includes(String(query.jobOrderCode).toLowerCase());
- const jobOrderNameMatch =
- !query.jobOrderName ||
- pickOrder.jobOrderName?.toLowerCase().includes(String(query.jobOrderName).toLowerCase());
-
- return dateMatch && pickOrderCodeMatch && jobOrderCodeMatch && jobOrderNameMatch;
- });
-
- setFilteredJobOrderPickOrders(filtered);
- }, [completedJobOrderPickOrders, searchQuery]);
-
- // 修改:重置搜索
- const handleSearchReset = useCallback(() => {
- setSearchQuery({});
- }, []);
-
- // 修改:分页功能
- const handlePageChange = useCallback((event: unknown, newPage: number) => {
- setPaginationController(prev => ({
- ...prev,
- pageNum: newPage,
- }));
- }, []);
-
- const handlePageSizeChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
- 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<any>[] = [
- {
- label: t("Target Date"),
- paramName: "completedDate",
- type: "date",
- },
- {
- label: t("Pick Order Code"),
- paramName: "pickOrderCode",
- type: "text",
- },
- {
- label: t("Job Order Code"),
- paramName: "jobOrderCode",
- type: "text",
- },
- {
- label: t("Pick Order Status"),
- paramName: "pickOrderStatus",
- type: "select-labelled",
- options: [
- { label: t("Released"), value: "RELEASED" },
- { label: t("Completed"), value: "COMPLETED" },
- ], // 依你后端实际枚举
- },
- {
- 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]);
-
- useEffect(() => {
- if (!openDetail) return;
- if (initialDetailOpenedRef.current || completedJobOrderPickOrdersLoading) return;
- const code = initialPickOrderCode?.trim();
- if (!code) return;
- const match = completedJobOrderPickOrders.find(
- (row) =>
- row.pickOrderCode?.trim() === code ||
- row.pickOrderConsoCode?.trim() === code,
- );
- if (!match) return;
- initialDetailOpenedRef.current = true;
- void handleDetailClick(match);
- }, [
- openDetail,
- completedJobOrderPickOrders,
- completedJobOrderPickOrdersLoading,
- initialPickOrderCode,
- handleDetailClick,
- ]);
-
- // 修改:返回列表视图
- const handleBackToList = useCallback(() => {
- setShowDetailView(false);
- setSelectedJobOrderPickOrder(null);
- setDetailLotData([]);
-
- // 返回列表时禁用打印按钮
- window.dispatchEvent(new CustomEvent('pickOrderCompletionStatus', {
- detail: {
- allLotsCompleted: false,
- tabIndex: 3
- }
- }));
- }, []);
-
- const handlePickRecord = useCallback(async (
- jobOrderPickOrder: CompletedJobOrderPickOrder,
- floor: PickRecordFloor,
- ) => {
- if (pickRecordPrintInFlightRef.current) return;
- 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;
- let printRequest;
- if (floor === "ALL") {
- const allFloorsQty = await promptAllFloorsPlasticBoxCartonQty(t, pickOrderId);
- if (allFloorsQty === null) {
- return;
- }
- printRequest = buildPrintPickRecordRequest({
- pickOrderId,
- printerId: selectedPrinter.id,
- printQty,
- floor,
- allFloorsQty,
- });
- } else {
- const plasticBoxCartonQty = await promptPlasticBoxCartonQty(t);
- if (plasticBoxCartonQty === null) {
- return;
- }
- printRequest = buildPrintPickRecordRequest({
- pickOrderId,
- printerId: selectedPrinter.id,
- printQty,
- floor,
- plasticBoxCartonQty,
- });
- }
-
- pickRecordPrintInFlightRef.current = true;
-
- const response = await PrintPickRecord(printRequest);
-
- if (response.success) {
- Swal.fire({
- position: "bottom-end",
- icon: "success",
- text: t("Printed Successfully."),
- showConfirmButton: false,
- timer: 1500
- });
- } else {
- 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
- });
- } finally {
- pickRecordPrintInFlightRef.current = false;
- }
- }, [t, selectedPrinter, printQty]);
- // 修改:如果显示详情视图,渲染 Job Order 详情和 Lot 信息
- if (showDetailView && selectedJobOrderPickOrder) {
- return (
- <FormProvider {...formProps}>
- <Box>
- {/* 返回按钮和标题 */}
- <Box sx={{ mb: 2, display: 'flex', alignItems: 'center', gap: 2 }}>
- <Button variant="outlined" onClick={handleBackToList}>
- {t("Back to List")}
- </Button>
- <Typography variant="h6">
- {t("Job Order Pick Order Details")}: {selectedJobOrderPickOrder.pickOrderCode}
- </Typography>
- </Box>
-
- {/* Job Order 信息卡片 */}
- <Card sx={{ mb: 2 }}>
- <CardContent>
- <Stack direction="row" spacing={4} useFlexGap flexWrap="wrap">
- <Typography variant="subtitle1">
- <strong>{t("Pick Order Code")}:</strong> {selectedJobOrderPickOrder.pickOrderCode}
- </Typography>
- <Typography variant="subtitle1">
- <strong>{t("Job Order Code")}:</strong> {selectedJobOrderPickOrder.jobOrderCode}
- </Typography>
- <Typography variant="subtitle1">
- <strong>{t("Job Order Item Name")}:</strong> {selectedJobOrderPickOrder.jobOrderName}
- </Typography>
- <Typography variant="subtitle1">
- <strong>{t("Target Date")}:</strong> {selectedJobOrderPickOrder.pickOrderTargetDate}
- </Typography>
- </Stack>
-
- <Stack direction="row" spacing={4} useFlexGap flexWrap="wrap" sx={{ mt: 2 }}>
- <Typography variant="subtitle1">
- <strong>{t("Required Qty")}:</strong> {selectedJobOrderPickOrder.reqQty} {selectedJobOrderPickOrder.uom}
- </Typography>
- </Stack>
- </CardContent>
- </Card>
-
- {/* 修改:Lot 详情表格 - 添加复选框列 */}
- <Card>
- <CardContent>
- <Typography variant="h6" gutterBottom>
- {t("Lot Details")}
- </Typography>
-
- {detailLotDataLoading ? (
- <Box sx={{ display: 'flex', justifyContent: 'center', p: 2 }}>
- <CircularProgress />
- </Box>
- ) : (
- <TableContainer component={Paper}>
- <Table>
- <TableHead>
- <TableRow>
- <TableCell>{t("Index")}</TableCell>
- <TableCell>{t("Route")}</TableCell>
- <TableCell>{t("Item Code")}</TableCell>
- <TableCell>{t("Item Name")}</TableCell>
- <TableCell>{t("Lot No")}</TableCell>
-
- <TableCell align="right">{t("Required Qty")}</TableCell>
- <TableCell align="right">{t("Actual Pick Qty")}</TableCell>
- <TableCell align="center">{t("Processing Status")}</TableCell>
- <TableCell align="center">{t("Second Scan Status")}</TableCell>
- </TableRow>
- </TableHead>
- <TableBody>
- {detailLotData.length === 0 ? (
- <TableRow>
- <TableCell colSpan={10} align="center">
- <Typography variant="body2" color="text.secondary">
- {t("No lot details available")}
- </Typography>
- </TableCell>
- </TableRow>
- ) : (
- detailLotData.map((lot, index) => (
- <TableRow key={lot.stockOutLineId ?? lot.lotId ?? index}>
- <TableCell>
- <Typography variant="body2" fontWeight="bold">
- {index + 1}
- </Typography>
- </TableCell>
- <TableCell>
- <Typography variant="body2">
- {lot.routerRoute || '-'}
- </Typography>
- </TableCell>
- <TableCell>{lot.itemCode}</TableCell>
- <TableCell>{lot.itemName}</TableCell>
- <TableCell>{lot.lotNo || '-'}</TableCell>
-
- <TableCell align="right">
- {lot.requiredQty?.toLocaleString() || 0} ({lot.uomShortDesc || ''})
- </TableCell>
- <TableCell align="right">
- {lot.actualPickQty?.toLocaleString() || 0} ({lot.uomShortDesc || ''})
- </TableCell>
- {/* 修改:Processing Status 使用复选框 */}
- <TableCell align="center">
- <Box sx={{
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- width: '100%',
- height: '100%'
- }}>
- <Checkbox
- checked={lot.processingStatus === 'completed'}
- disabled={true}
- readOnly={true}
- size="large"
- sx={{
- color: lot.processingStatus === 'completed' ? 'success.main' : 'grey.400',
- '&.Mui-checked': {
- color: 'success.main',
- },
- transform: 'scale(1.3)',
- '& .MuiSvgIcon-root': {
- fontSize: '1.5rem',
- }
- }}
- />
- </Box>
- </TableCell>
- {/* 修改:Second Scan Status 使用复选框 */}
- <TableCell align="center">
- <Box sx={{
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- width: '100%',
- height: '100%'
- }}>
- <Checkbox
- checked={lot.match_status === 'completed'}
- disabled={true}
- readOnly={true}
- size="large"
- sx={{
- color: lot.match_status === 'completed' ? 'success.main' : 'grey.400',
- '&.Mui-checked': {
- color: 'success.main',
- },
- transform: 'scale(1.3)',
- '& .MuiSvgIcon-root': {
- fontSize: '1.5rem',
- }
- }}
- />
- </Box>
- </TableCell>
- </TableRow>
- ))
- )}
- </TableBody>
- </Table>
- </TableContainer>
- )}
- </CardContent>
- </Card>
- </Box>
- </FormProvider>
- );
- }
-
- // 修改:默认列表视图
- return (
- <FormProvider {...formProps}>
- <Box>
- {/* 搜索框 */}
- <Box sx={{ mb: 2 }}>
- <SearchBox
- criteria={searchCriteria}
- onSearch={handleSearch}
- onReset={handleSearchReset}
- />
- </Box>
-
- {/* 加载状态 */}
- {completedJobOrderPickOrdersLoading ? (
- <Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}>
- <CircularProgress />
- </Box>
- ) : (
- <Box>
- {/* 结果统计 */}
- <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
- {t("Total")}: {filteredJobOrderPickOrders.length} {t("completed Job Order pick orders with matching")}
- </Typography>
-
- {/* 列表 */}
- {filteredJobOrderPickOrders.length === 0 ? (
- <Box sx={{ p: 3, textAlign: 'center' }}>
- <Typography variant="body2" color="text.secondary">
- {t("No completed Job Order pick orders with matching found")}
- </Typography>
- </Box>
- ) : (
- <Stack spacing={2}>
- {paginatedData.map((jobOrderPickOrder) => {
- const normalizedStatus = String(jobOrderPickOrder.pickOrderStatus ?? "").toLowerCase();
- return (
- <Card key={jobOrderPickOrder.id}>
- <CardContent>
- <Stack direction="row" justifyContent="space-between" alignItems="center">
- <Box>
- <Typography variant="h6">
- {jobOrderPickOrder.jobOrderCode}
- </Typography>
- <Typography variant="body2" color="text.secondary">
- {jobOrderPickOrder.jobOrderName} - {jobOrderPickOrder.pickOrderCode}
- </Typography>
- <Typography variant="body2" color="text.secondary">
- {t("Completed")}: {formatDateTime(jobOrderPickOrder.planEnd)}
- </Typography>
- <Typography variant="body2" color="text.secondary">
- {t("Target Date")}: {jobOrderPickOrder.pickOrderTargetDate}
- </Typography>
- </Box>
-
- <Box>
- <Chip
-
- label={t(jobOrderPickOrder.pickOrderStatus)}
- color={normalizedStatus === "completed" ? "success" : "default"}
- size="small"
- sx={{ mb: 1 }}
- />
- <Typography variant="body2" color="text.secondary">
- {jobOrderPickOrder.completedItems}/{jobOrderPickOrder.totalItems} {t("items completed")}
- </Typography>
-
-
- </Box>
- </Stack>
- </CardContent>
- <CardActions sx={{ alignItems: "center", gap: 1, flexWrap: "wrap" }}>
- <Button
- variant="outlined"
- onClick={() => handleDetailClick(jobOrderPickOrder)}
- >
- {t("View Details")}
- </Button>
- <Button
- variant="contained"
- color="primary"
- onClick={() => handlePickRecord(jobOrderPickOrder, "ALL")}
- >
- 打印全部樓層板頭紙
- </Button>
- <Button
- variant="contained"
- color="primary"
- onClick={() => handlePickRecord(jobOrderPickOrder, "2F")}
- >
- {t("Print Pick Record")} 2F
- </Button>
- <Button
- variant="contained"
- color="primary"
- onClick={() => handlePickRecord(jobOrderPickOrder, "3F")}
- >
- {t("Print Pick Record")} 3F
- </Button>
- <Button
- variant="contained"
- color="primary"
- onClick={() => handlePickRecord(jobOrderPickOrder, "4F")}
- >
- {t("Print Pick Record")} 4F
- </Button>
- </CardActions>
- </Card>
- );
- })}
-
- </Stack>
- )}
-
- {/* 分页 */}
- {filteredJobOrderPickOrders.length > 0 && (
- <TablePagination
- component="div"
- count={filteredJobOrderPickOrders.length}
- page={paginationController.pageNum}
- rowsPerPage={paginationController.pageSize}
- onPageChange={handlePageChange}
- onRowsPerPageChange={handlePageSizeChange}
- rowsPerPageOptions={[5, 10, 25, 50]}
- labelRowsPerPage={t("Rows per page")}
- />
- )}
- </Box>
- )}
- </Box>
- </FormProvider>
- );
- };
-
- export default CompleteJobOrderRecord;
|