瀏覽代碼

update

master
CANCERYS\kw093 2 月之前
父節點
當前提交
a443a00f3b
共有 4 個文件被更改,包括 345 次插入511 次删除
  1. +101
    -0
      src/components/FinishedGoodSearch/FGPickOrderInfoCard.tsx
  2. +151
    -206
      src/components/FinishedGoodSearch/FinishedGoodSearch.tsx
  3. +34
    -260
      src/components/FinishedGoodSearch/GoodPickExecution.tsx
  4. +59
    -45
      src/components/FinishedGoodSearch/GoodPickExecutionRecord.tsx

+ 101
- 0
src/components/FinishedGoodSearch/FGPickOrderInfoCard.tsx 查看文件

@@ -0,0 +1,101 @@
"use client";

import { Box, Card, CardContent, Grid, TextField, Stack } from "@mui/material";
import { useTranslation } from "react-i18next";
import { FGPickOrderResponse } from "@/app/api/pickOrder/actions";

interface Props {
fgOrder: FGPickOrderResponse;
}

const FGPickOrderInfoCard: React.FC<Props> = ({ fgOrder }) => {
const { t } = useTranslation("pickOrder");

return (
<Card sx={{ display: "block", mb: 2 }}>
<CardContent component={Stack} spacing={2}>
<Box>
<Grid container spacing={2} columns={{ xs: 6, sm: 12 }}>
<Grid item xs={6}>
<TextField
value={fgOrder.pickOrderCode || ""}
label={t("Pick Order Code")}
fullWidth
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
value={fgOrder.deliveryNo || ""}
label={t("Delivery No")}
fullWidth
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
value={fgOrder.shopName || ""}
label={t("Shop Name")}
fullWidth
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
value={fgOrder.ticketNo || ""}
label={t("Ticket No")}
fullWidth
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
value={fgOrder.storeId || ""}
label={t("Store")}
fullWidth
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
value={fgOrder.truckLanceCode || ""}
label={t("Truck Lane Code")}
fullWidth
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
value={fgOrder.DepartureTime || ""}
label={t("Departure Time")}
fullWidth
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
value={fgOrder.shopAddress || ""}
label={t("Shop Address")}
fullWidth
disabled={true}
multiline
rows={2}
/>
</Grid>
</Grid>
</Box>
</CardContent>
</Card>
);
};

export default FGPickOrderInfoCard;

+ 151
- 206
src/components/FinishedGoodSearch/FinishedGoodSearch.tsx 查看文件

@@ -63,8 +63,8 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => {
const [tabIndex, setTabIndex] = useState(0);
const [totalCount, setTotalCount] = useState<number>();
const [isAssigning, setIsAssigning] = useState(false);
const [summary2F, setSummary2F] = useState<StoreLaneSummary | null>(null);
const [summary4F, setSummary4F] = useState<StoreLaneSummary | null>(null);
// const [summary2F, setSummary2F] = useState<StoreLaneSummary | null>(null);
// const [summary4F, setSummary4F] = useState<StoreLaneSummary | null>(null);
const [isLoadingSummary, setIsLoadingSummary] = useState(false);
const [hideCompletedUntilNext, setHideCompletedUntilNext] = useState<boolean>(
typeof window !== 'undefined' && localStorage.getItem('hideCompletedUntilNext') === 'true'
@@ -83,6 +83,7 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => {
setReleasedOrderCount(0);
}
}, []);
/*
const loadSummaries = useCallback(async () => {
setIsLoadingSummary(true);
try {
@@ -104,6 +105,7 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => {
// 每30秒刷新一次

}, [loadSummaries]);
*/
const handleDraft = useCallback(async () =>{
try{
if (fgPickOrdersData.length === 0) {
@@ -446,11 +448,11 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => {
const onAssigned = () => {
localStorage.removeItem('hideCompletedUntilNext');
setHideCompletedUntilNext(false);
loadSummaries();
// loadSummaries();
};
window.addEventListener('pickOrderAssigned', onAssigned);
return () => window.removeEventListener('pickOrderAssigned', onAssigned);
}, [loadSummaries]);
}, []);
// ... existing code ...

useEffect(() => {
@@ -479,7 +481,7 @@ const PickOrderSearch: React.FC<Props> = ({ pickOrders }) => {
console.log("Reset print buttons for Pick Execution Record tab");
}
}, [tabIndex]);
/*
// ... existing code ...
const handleAssignByLane = useCallback(async (
storeId: string,
@@ -533,7 +535,7 @@ const handleAssignByLane = useCallback(async (
}
}, [currentUserId, t, loadSummaries]);
// ✅ Manual assignment handler - uses the action function
*/
const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>(
(_e, newValue) => {
setTabIndex(newValue);
@@ -731,216 +733,159 @@ const handleAssignByLane = useCallback(async (

return (
<Box sx={{
height: '100vh', // Full viewport height
// Full viewport height
overflow: 'auto' // Single scrollbar for the whole page
}}>
{/* Header section */}
<Box sx={{ p: 2, borderBottom: '1px solid #e0e0e0' }}>
<Stack rowGap={2}>
<Grid container alignItems="center">
<Grid item xs={8}>
<Box mb={2}>
<Typography variant="h4" marginInlineEnd={2}>
{t("Finished Good Order")}
</Typography>
</Box>
</Grid>

{/* Last 2 buttons aligned right */}
<Grid item xs={12}>
<Grid container alignItems="flex-start" spacing={1}>
{/* 2/F 楼层面板 */}
<Grid item>
<Box
sx={{
border: '1px solid #e0e0e0',
borderRadius: 1,
p: 1,
minWidth: 320,
mr: 1,
backgroundColor: '#fafafa'
<Box sx={{
p: 1,
borderBottom: '1px solid #e0e0e0',
minHeight: 'auto' // 确保最小高度自适应
}}>
<Grid container alignItems="center" spacing={1}>
<Grid item xs={8}>
<Typography
variant="h5"
sx={{
lineHeight: 1.4, // 调整行高
m: 0,
fontWeight: 500
}}
>
<Typography variant="subtitle2" sx={{ mb: 0.5, fontWeight: 600, textAlign: 'center' }}>
2/F
</Typography>
{isLoadingSummary ? (
<Typography variant="caption">Loading...</Typography>
) : (
<Stack spacing={0.5}>
{summary2F?.rows.map((row, rowIdx) => (
<Box
key={rowIdx}
sx={{
border: '1px solid #e0e0e0',
borderRadius: 0.5,
p: 0.5,
backgroundColor: '#fff'
}}
>
<Typography
variant="caption"
sx={{
display: 'block',
mb: 0.5,
fontWeight: 500,
textAlign: 'center',
fontSize: '0.7rem'
}}
>
{row.truckDepartureTime}
</Typography>
<Stack direction="row" spacing={0.25} alignItems="center" justifyContent="center">
{row.lanes.map((lane, laneIdx) => (
<Button
key={laneIdx}
variant="outlined"
size="small"
disabled={lane.unassigned === 0 || isAssigning}
onClick={() => handleAssignByLane("2/F", row.truckDepartureTime, lane.truckLanceCode)}
sx={{
minWidth: 80,
fontSize: '0.7rem',
py: 0.25,
px: 0.5,
borderWidth: 1,
borderColor: '#ccc',
'&:hover': {
borderColor: '#999',
backgroundColor: '#f5f5f5'
}
}}
>
{`${lane.truckLanceCode} (${lane.unassigned}/${lane.total})`}
</Button>
))}
</Stack>
</Box>
))}
</Stack>
)}
</Box>
{t("Finished Good Order")}
</Typography>
</Grid>

{/* 4/F 楼层面板 */}
<Grid item>
<Box
sx={{
border: '1px solid #e0e0e0',
borderRadius: 1,
p: 1,
minWidth: 320,
backgroundColor: '#fafafa'
}}
>
<Typography variant="subtitle2" sx={{ mb: 0.5, fontWeight: 600, textAlign: 'center' }}>
4/F
</Typography>
{isLoadingSummary ? (
<Typography variant="caption">Loading...</Typography>
) : (
<Stack spacing={0.5}>
{summary4F?.rows.map((row, rowIdx) => (
<Box
key={rowIdx}
sx={{
border: '1px solid #e0e0e0',
borderRadius: 0.5,
p: 0.5,
backgroundColor: '#fff'
}}
>
<Typography
variant="caption"
sx={{
display: 'block',
mb: 0.5,
fontWeight: 500,
textAlign: 'center',
fontSize: '0.7rem'
}}
>
{row.truckDepartureTime}
</Typography>
<Stack direction="row" spacing={0.25} alignItems="center" justifyContent="center">
{row.lanes.map((lane, laneIdx) => (
<Button
key={laneIdx}
variant="outlined"
size="small"
disabled={lane.unassigned === 0 || isAssigning}
onClick={() => handleAssignByLane("4/F", row.truckDepartureTime, lane.truckLanceCode)}
sx={{
minWidth: 80,
fontSize: '0.7rem',
py: 0.25,
px: 0.5,
borderWidth: 1,
borderColor: '#ccc',
'&:hover': {
borderColor: '#999',
backgroundColor: '#f5f5f5'
}
}}
>
{`${lane.truckLanceCode} (${lane.unassigned}/${lane.total})`}
</Button>
))}
</Stack>
</Box>
))}
</Stack>
)}
<Grid item xs={4}>
<Box sx={{
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
height: '100%'
}}>
<Stack
direction="row"
spacing={0.5}
sx={{
alignItems: 'center',
height: '100%'
}}
>
<Button
variant="contained"
size="small"
sx={{
py: 0.5, // 增加垂直padding
px: 1.25, // 增加水平padding
height: '40px', // 增加按钮高度
fontSize: '0.75rem',
lineHeight: 1.2, // 添加行高控制
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
'&.Mui-disabled': {
height: '40px'
}
}}
onClick={handleAllDraft}
>
{t("Print All Draft")} ({releasedOrderCount})
</Button>
<Button
variant="contained"
size="small"
sx={{
py: 0.5,
px: 1.25,
height: '40px',
fontSize: '0.75rem',
lineHeight: 1.2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
'&.Mui-disabled': {
height: '40px'
}
}}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleDraft}
>
{t("Print Draft")}
</Button>
<Button
variant="contained"
disabled={!printButtonsEnabled}
size="small"
sx={{
py: 0.5,
px: 1.25,
height: '40px',
fontSize: '0.75rem',
lineHeight: 1.2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
'&.Mui-disabled': {
height: '40px'
}
}}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleDNandLabel}
>
{t("Print Pick Order and DN Label")}
</Button>
<Button
variant="contained"
disabled={!printButtonsEnabled}
size="small"
sx={{
py: 0.5,
px: 1.25,
height: '40px',
fontSize: '0.75rem',
lineHeight: 1.2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
'&.Mui-disabled': {
height: '40px'
}
}}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleDN}
>
{t("Print Pick Order")}
</Button>
<Button
variant="contained"
disabled={!printButtonsEnabled}
size="small"
sx={{
py: 0.5,
px: 1.25,
height: '40px',
fontSize: '0.75rem',
lineHeight: 1.2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
'&.Mui-disabled': {
height: '40px'
}
}}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleLabel}
>
{t("Print DN Label")}
</Button>
</Stack>
</Box>
</Grid>
{/* ✅ Updated print buttons with completion status */}
<Grid item xs>
<Box sx={{ width: '100%', display: 'flex', justifyContent: 'flex-end' }}>
<Stack direction="row" spacing={1}>
<Button variant="contained" onClick={handleAllDraft}>
{t("Print All Draft")} ({releasedOrderCount})
</Button>
<Button
variant="contained"
// disabled={!printButtonsEnabled}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleDraft}
>
{t("Print Draft")}
</Button>
<Button
variant="contained"
disabled={!printButtonsEnabled}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleDNandLabel}
>
{t("Print Pick Order and DN Label")}
</Button>
<Button
variant="contained"
disabled={!printButtonsEnabled}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleDN}
>
{t("Print Pick Order")}
</Button>
<Button
variant="contained"
disabled={!printButtonsEnabled}
title={!printButtonsEnabled ? t("All lots must be completed before printing") : ""}
onClick={handleLabel}
>
{t("Print DN Label")}
</Button>
</Stack>
</Box>
</Grid>
</Grid>
</Grid>
</Grid>
</Stack>
</Box>
</Grid>
</Box>

{/* Tabs section - ✅ Move the click handler here */}
<Box sx={{


+ 34
- 260
src/components/FinishedGoodSearch/GoodPickExecution.tsx 查看文件

@@ -49,6 +49,8 @@ import { SessionWithTokens } from "@/config/authConfig";
import { fetchStockInLineInfo } from "@/app/api/po/actions";
import GoodPickExecutionForm from "./GoodPickExecutionForm";
import FGPickOrderCard from "./FGPickOrderCard";
import FinishedGoodFloorLanePanel from "./FGPickOrderCard";
import FGPickOrderInfoCard from "./FGPickOrderInfoCard";
interface Props {
filterArgs: Record<string, any>;
onFgPickOrdersChange?: (fgPickOrders: FGPickOrderResponse[]) => void;
@@ -963,16 +965,24 @@ const PickExecution: React.FC<Props> = ({ filterArgs, onFgPickOrdersChange }) =>

return (
<FormProvider {...formProps}>
{/* Search Box */}
{/* ✅ 条件渲染:没有活动订单时显示楼层选择面板 */}
{!combinedDataLoading && fgPickOrders.length === 0 ? (
<FinishedGoodFloorLanePanel
onPickOrderAssigned={() => {
if (currentUserId) {
fetchAllCombinedLotData(currentUserId);
}
}}
/>
) : (
// ✅ 有活动订单时,显示 FG 订单信息卡片
<Box>
{fgPickOrdersLoading ? (
<Box sx={{ display: 'flex', justifyContent: 'center', p: 3 }}>
<CircularProgress />
</Box>
) : (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<Box>
{fgPickOrders.length === 0 ? (
<Box sx={{ p: 3, textAlign: 'center' }}>
<Typography variant="body2" color="text.secondary">
@@ -980,276 +990,40 @@ const PickExecution: React.FC<Props> = ({ filterArgs, onFgPickOrdersChange }) =>
</Typography>
</Box>
) : (
// ✅ 使用新的 FGPickOrderInfoCard 组件(类似 DoInfoCard 的格式)
fgPickOrders.map((fgOrder) => (
<FGPickOrderCard
<FGPickOrderInfoCard
key={fgOrder.pickOrderId}
fgOrder={fgOrder}
onQrCodeClick={handleQrCodeClick}
/>
))
)}
</Box>
)}
</Box>



{/*

<Box>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 2 }}>
<Typography variant="h6" gutterBottom sx={{ mb: 0 }}>
{t("All Pick Order Lots")}
</Typography>
</Box>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>{t("Index")}</TableCell>
<TableCell>{t("Route")}</TableCell>
<TableCell>{t("Item Name")}</TableCell>
<TableCell>{t("Lot#")}</TableCell>

<TableCell align="right">{t("Lot Required Pick Qty")}</TableCell>

<TableCell align="center">{t("Lot Actual Pick Qty")}</TableCell>

<TableCell align="center">{t("Action")}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{paginatedData.length === 0 ? (
<TableRow>
<TableCell colSpan={11} align="center">
<Typography variant="body2" color="text.secondary">
{t("No data available")}
</Typography>
</TableCell>
</TableRow>
) : (
paginatedData.map((lot, index) => (
<TableRow
key={`${lot.pickOrderLineId}-${lot.lotId}`}
sx={{
backgroundColor: lot.lotAvailability === 'rejected' ? 'grey.100' : 'inherit',
opacity: lot.lotAvailability === 'rejected' ? 0.6 : 1,
'& .MuiTableCell-root': {
color: lot.lotAvailability === 'rejected' ? 'text.disabled' : 'inherit'
}
}}
>
<TableCell>
<Typography variant="body2" fontWeight="bold">
{lot.routerIndex || index + 1}
</Typography>
</TableCell>
<TableCell>
<Typography variant="body2">
{lot.routerRoute || '-'}
</Typography>
</TableCell>
<TableCell>{lot.itemName}</TableCell>
<TableCell>
<Box>
<Typography
sx={{
color: lot.lotAvailability === 'rejected' ? 'text.disabled' : 'inherit',
opacity: lot.lotAvailability === 'rejected' ? 0.6 : 1
}}
>
{lot.lotNo}
</Typography>
</Box>
</TableCell>

<TableCell align="right">
{(() => {
const inQty = lot.inQty || 0;
const outQty = lot.outQty || 0;
const result = inQty - outQty;
return result.toLocaleString();
})()}
</TableCell>
<TableCell align="center">

{!lot.stockOutLineId ? (
<Button
variant="outlined"
size="small"
onClick={() => {
setSelectedLotForQr(lot);
setQrModalOpen(true);
resetScan();
}}
disabled={
(lot.lotAvailability === 'expired' ||
lot.lotAvailability === 'status_unavailable' ||
lot.lotAvailability === 'rejected')
}
sx={{
fontSize: '0.7rem',
py: 0.5,
minHeight: '40px',
whiteSpace: 'nowrap',
minWidth: '80px',
}}
startIcon={<QrCodeIcon />}
title="Click to scan QR code"
>
{t("Scan")}
</Button>
) : (
// ✅ When stockOutLineId exists, show TextField + Issue button
<Stack direction="row" spacing={1} alignItems="center">
<TextField
type="number"
size="small"
value={pickQtyData[`${lot.pickOrderLineId}-${lot.lotId}`] || ''}
onChange={(e) => {
const lotKey = `${lot.pickOrderLineId}-${lot.lotId}`;
handlePickQtyChange(lotKey, parseFloat(e.target.value) || 0);
}}
disabled={
(lot.lotAvailability === 'expired' ||
lot.lotAvailability === 'status_unavailable' ||
lot.lotAvailability === 'rejected') ||
lot.stockOutLineStatus === 'completed'
}
inputProps={{
min: 0,
max: calculateRemainingRequiredQty(lot),
step: 0.01
}}
sx={{
width: '60px',
height: '28px',
'& .MuiInputBase-input': {
fontSize: '0.7rem',
textAlign: 'center',
padding: '6px 8px'
}
}}
placeholder="0"
/>
<Button
variant="outlined"
size="small"
onClick={() => handlePickExecutionForm(lot)}
sx={{
fontSize: '0.7rem',
py: 0.5,
minHeight: '28px',
minWidth: '60px',
borderColor: 'warning.main',
color: 'warning.main'
}}
title="Report missing or bad items"
>
{t("Issue")}
</Button>
</Stack>
)}
</TableCell>

<TableCell align="center">
<Stack direction="column" spacing={1} alignItems="center">
<Button
variant="contained"
onClick={() => {
handleSubmitPickQty(lot);
}}
disabled={
(lot.lotAvailability === 'expired' ||
lot.lotAvailability === 'status_unavailable' ||
lot.lotAvailability === 'rejected') ||
!pickQtyData[`${lot.pickOrderLineId}-${lot.lotId}`] ||
!lot.stockOutLineStatus ||
!['pending','checked', 'partially_completed'].includes(lot.stockOutLineStatus.toLowerCase())
}
sx={{
fontSize: '0.75rem',
py: 0.5,
minHeight: '28px'
}}
>
{t("Submit")}
</Button>
</Stack>
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</TableContainer>
*/}
{/*
<TablePagination
component="div"
count={combinedLotData.length}
page={paginationController.pageNum}
rowsPerPage={paginationController.pageSize}
onPageChange={handlePageChange}
onRowsPerPageChange={handlePageSizeChange}
rowsPerPageOptions={[10, 25, 50]}
labelRowsPerPage={t("Rows per page")}
labelDisplayedRows={({ from, to, count }) =>
`${from}-${to} of ${count !== -1 ? count : `more than ${to}`}`
}
/>
</Box>
</Stack>

)}
{/* Modals */}
<QrCodeModal
open={qrModalOpen}
onClose={() => setQrModalOpen(false)}
lot={selectedLotForQr}
onQrCodeSubmit={handleQrCodeSubmit}
combinedLotData={combinedLotData}
/>
<GoodPickExecutionForm
open={pickExecutionFormOpen}
onClose={() => {
setQrModalOpen(false);
setSelectedLotForQr(null);
stopScan();
resetScan();
setPickExecutionFormOpen(false);
setSelectedLotForExecutionForm(null);
}}
lot={selectedLotForQr}
combinedLotData={combinedLotData} // ✅ Add this prop
onQrCodeSubmit={handleQrCodeSubmitFromModal}
onSubmit={handlePickExecutionFormSubmit}
selectedLot={selectedLotForExecutionForm}
selectedPickOrderLine={null}
pickOrderId={selectedLotForExecutionForm?.pickOrderId}
pickOrderCreateDate={null}
/>

{pickExecutionFormOpen && selectedLotForExecutionForm && (
<GoodPickExecutionForm
open={pickExecutionFormOpen}
onClose={() => {
setPickExecutionFormOpen(false);
setSelectedLotForExecutionForm(null);
}}
onSubmit={handlePickExecutionFormSubmit}
selectedLot={selectedLotForExecutionForm}
selectedPickOrderLine={{
id: selectedLotForExecutionForm.pickOrderLineId,
itemId: selectedLotForExecutionForm.itemId,
itemCode: selectedLotForExecutionForm.itemCode,
itemName: selectedLotForExecutionForm.itemName,
pickOrderCode: selectedLotForExecutionForm.pickOrderCode,
// ✅ Add missing required properties from GetPickOrderLineInfo interface
availableQty: selectedLotForExecutionForm.availableQty || 0,
requiredQty: selectedLotForExecutionForm.requiredQty || 0,
uomCode: selectedLotForExecutionForm.uomCode || '',
uomDesc: selectedLotForExecutionForm.uomDesc || '',
pickedQty: selectedLotForExecutionForm.actualPickQty || 0, // ✅ Use pickedQty instead of actualPickQty
suggestedList: [] // ✅ Add required suggestedList property
}}
pickOrderId={selectedLotForExecutionForm.pickOrderId}
pickOrderCreateDate={new Date()}
/>
)}
*/}
</FormProvider>
);
};


+ 59
- 45
src/components/FinishedGoodSearch/GoodPickExecutionRecord.tsx 查看文件

@@ -270,54 +270,68 @@ const GoodPickExecutionRecord: React.FC<Props> = ({ filterArgs }) => {
</Typography>
</Box>

{/* FG Pick Orders 信息 */}
<Box sx={{ mb: 2 }}>
{selectedDoPickOrder.fgPickOrders.map((fgOrder, index) => (
<FGPickOrderCard
key={index}
fgOrder={fgOrder}
onQrCodeClick={() => {}} // 只读模式
/>
))}
{/* 订单基本信息 */}
<Box sx={{ mb: 2, p: 2, backgroundColor: '#f5f5f5', borderRadius: 1 }}>
<Typography variant="h6" gutterBottom>
{t("Order Information")}
</Typography>
<Typography variant="body2">
<strong>{t("Shop Name")}:</strong> {selectedDoPickOrder.shopName}
</Typography>
<Typography variant="body2">
<strong>{t("Delivery No")}:</strong> {selectedDoPickOrder.deliveryNo}
</Typography>
<Typography variant="body2">
<strong>{t("Completed Date")}:</strong> {dayjs(selectedDoPickOrder.completedDate).format(OUTPUT_DATE_FORMAT)}
</Typography>
</Box>

{/* 类似 GoodPickExecution 的表格 */}
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>{t("Pick Order Code")}</TableCell>
<TableCell>{t("Item Code")}</TableCell>
<TableCell>{t("Item Name")}</TableCell>
<TableCell>{t("Lot No")}</TableCell>
<TableCell>{t("Location")}</TableCell>
<TableCell>{t("Required Qty")}</TableCell>
<TableCell>{t("Actual Pick Qty")}</TableCell>
<TableCell>{t("Submitted Status")}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{detailLotData.map((lot, index) => (
<TableRow key={index}>
<TableCell>{lot.pickOrderCode}</TableCell>
<TableCell>{lot.itemCode}</TableCell>
<TableCell>{lot.itemName}</TableCell>
<TableCell>{lot.lotNo}</TableCell>
<TableCell>{lot.location}</TableCell>
<TableCell>{lot.requiredQty}</TableCell>
<TableCell>{lot.actualPickQty}</TableCell>
<TableCell>
<Chip
label={t(lot.processingStatus)}
color={lot.processingStatus === 'completed' ? 'success' : 'default'}
size="small"
/>
</TableCell>
{/* ✅ 添加数据检查 */}
{detailLotData.length === 0 ? (
<Box sx={{ p: 3, textAlign: 'center' }}>
<Typography variant="body2" color="text.secondary">
{t("No lot details found for this order")}
</Typography>
</Box>
) : (
/* 显示完成数据的表格 */
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>{t("Pick Order Code")}</TableCell>
<TableCell>{t("Item Code")}</TableCell>
<TableCell>{t("Item Name")}</TableCell>
<TableCell>{t("Lot No")}</TableCell>
<TableCell>{t("Location")}</TableCell>
<TableCell>{t("Required Qty")}</TableCell>
<TableCell>{t("Actual Pick Qty")}</TableCell>
<TableCell>{t("Submitted Status")}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</TableHead>
<TableBody>
{detailLotData.map((lot, index) => (
<TableRow key={index}>
<TableCell>{lot.pickOrderCode || 'N/A'}</TableCell>
<TableCell>{lot.itemCode || 'N/A'}</TableCell>
<TableCell>{lot.itemName || 'N/A'}</TableCell>
<TableCell>{lot.lotNo || 'N/A'}</TableCell>
<TableCell>{lot.location || 'N/A'}</TableCell>
<TableCell>{lot.requiredQty || 0}</TableCell>
<TableCell>{lot.actualPickQty || 0}</TableCell>
<TableCell>
<Chip
label={t(lot.processingStatus || 'unknown')}
color={lot.processingStatus === 'completed' ? 'success' : 'default'}
size="small"
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
)}
</Box>
</FormProvider>
);


Loading…
取消
儲存