浏览代码

update

master
CANCERYS\kw093 3 个月前
父节点
当前提交
b7b3f637f9
共有 3 个文件被更改,包括 98 次插入69 次删除
  1. +15
    -1
      src/app/api/pickOrder/actions.ts
  2. +81
    -67
      src/components/FinishedGoodSearch/GoodPickExecution.tsx
  3. +2
    -1
      src/components/PickOrderSearch/LotTable.tsx

+ 15
- 1
src/app/api/pickOrder/actions.ts 查看文件

@@ -244,7 +244,21 @@ export interface PickOrderCompletionResponse {
}>; }>;
}; };
} }

export interface UpdateSuggestedLotLineIdRequest {
newLotLineId: number;
}
export const updateSuggestedLotLineId = async (suggestedPickLotId: number, newLotLineId: number) => {
const response = await serverFetchJson<PostPickOrderResponse<UpdateSuggestedLotLineIdRequest>>(
`${BASE_API_URL}/suggestedPickLot/update-suggested-lot/${suggestedPickLotId}`,
{
method: "POST",
body: JSON.stringify({ newLotLineId }),
headers: { "Content-Type": "application/json" },
},
);
revalidateTag("pickorder");
return response;
};
export const autoAssignAndReleasePickOrder = async (userId: number): Promise<AutoAssignReleaseResponse> => { export const autoAssignAndReleasePickOrder = async (userId: number): Promise<AutoAssignReleaseResponse> => {
const response = await serverFetchJson<AutoAssignReleaseResponse>( const response = await serverFetchJson<AutoAssignReleaseResponse>(
`${BASE_API_URL}/pickOrder/auto-assign-release/${userId}`, `${BASE_API_URL}/pickOrder/auto-assign-release/${userId}`,


+ 81
- 67
src/components/FinishedGoodSearch/GoodPickExecution.tsx 查看文件

@@ -59,7 +59,8 @@ const QrCodeModal: React.FC<{
onClose: () => void; onClose: () => void;
lot: any | null; lot: any | null;
onQrCodeSubmit: (lotNo: string) => void; onQrCodeSubmit: (lotNo: string) => void;
}> = ({ open, onClose, lot, onQrCodeSubmit }) => {
combinedLotData: any[]; // ✅ Add this prop
}> = ({ open, onClose, lot, onQrCodeSubmit, combinedLotData }) => {
const { t } = useTranslation("pickOrder"); const { t } = useTranslation("pickOrder");
const { values: qrValues, isScanning, startScan, stopScan, resetScan } = useQrCodeScannerContext(); const { values: qrValues, isScanning, startScan, stopScan, resetScan } = useQrCodeScannerContext();
const [manualInput, setManualInput] = useState<string>(''); const [manualInput, setManualInput] = useState<string>('');
@@ -398,11 +399,15 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
// const handleAutoAssignAndRelease = useCallback(async () => { ... }); // 删除这个函数 // const handleAutoAssignAndRelease = useCallback(async () => { ... }); // 删除这个函数


// ✅ Handle QR code submission for matched lot (external scanning) // ✅ Handle QR code submission for matched lot (external scanning)
const handleQrCodeSubmit = useCallback(async (lotNo: string) => {
// ✅ Handle QR code submission for matched lot (external scanning)
const handleQrCodeSubmit = useCallback(async (lotNo: string) => {
console.log(`✅ Processing QR Code for lot: ${lotNo}`); console.log(`✅ Processing QR Code for lot: ${lotNo}`);
console.log(`🔍 Available lots:`, combinedLotData.map(lot => lot.lotNo));
const matchingLots = combinedLotData.filter(lot =>
// ✅ Use current data without refreshing to avoid infinite loop
const currentLotData = combinedLotData;
console.log(`🔍 Available lots:`, currentLotData.map(lot => lot.lotNo));
const matchingLots = currentLotData.filter(lot =>
lot.lotNo === lotNo || lot.lotNo === lotNo ||
lot.lotNo?.toLowerCase() === lotNo.toLowerCase() lot.lotNo?.toLowerCase() === lotNo.toLowerCase()
); );
@@ -430,7 +435,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
existsCount++; existsCount++;
} else { } else {
const stockOutLineData: CreateStockOutLine = { const stockOutLineData: CreateStockOutLine = {
consoCode: matchingLot.pickOrderConsoCode, // ✅ Use pickOrderConsoCode instead of pickOrderCode
consoCode: matchingLot.pickOrderConsoCode,
pickOrderLineId: matchingLot.pickOrderLineId, pickOrderLineId: matchingLot.pickOrderLineId,
inventoryLotLineId: matchingLot.lotId, inventoryLotLineId: matchingLot.lotId,
qty: 0.0 qty: 0.0
@@ -447,40 +452,56 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
console.log(`✅ Stock out line created successfully for line ${matchingLot.pickOrderLineId}`); console.log(`✅ Stock out line created successfully for line ${matchingLot.pickOrderLineId}`);
successCount++; successCount++;
} else { } else {
console.error(`❌ Unexpected response for line ${matchingLot.pickOrderLineId}:`, result);
console.error(`❌ Failed to create stock out line for line ${matchingLot.pickOrderLineId}:`, result);
errorCount++; errorCount++;
} }
} }
const lotKey = `${matchingLot.pickOrderLineId}-${matchingLot.lotId}`;
setPickQtyData(prev => ({
...prev,
[lotKey]: matchingLot.requiredQty
}));
} }
// ✅ Always refresh data after processing (success or failure)
console.log("🔄 Refreshing data after QR code processing...");
await fetchAllCombinedLotData();
if (successCount > 0 || existsCount > 0) { if (successCount > 0 || existsCount > 0) {
console.log(`✅ QR Code processing completed: ${successCount} created, ${existsCount} already existed`);
setQrScanSuccess(true); setQrScanSuccess(true);
setQrScanError(false);
console.log(`✅ QR Code processing completed: ${successCount} created, ${existsCount} already existed, ${errorCount} errors`);
setQrScanInput(''); // Clear input after successful processing
// ✅ Clear success state after a delay
setTimeout(() => {
setQrScanSuccess(false);
}, 2000);
} else { } else {
console.error(`❌ QR Code processing failed: ${errorCount} errors`);
setQrScanError(true); setQrScanError(true);
setQrScanSuccess(false); setQrScanSuccess(false);
console.error(`❌ All operations failed for lot ${lotNo}`);
return;
// ✅ Clear error state after a delay
setTimeout(() => {
setQrScanError(false);
}, 3000);
} }
await fetchAllCombinedLotData();
setQrScanInput('');
console.log("Stock out line process completed successfully!");
} catch (error) { } catch (error) {
console.error("Error creating stock out line:", error);
console.error("❌ Error processing QR code:", error);
setQrScanError(true); setQrScanError(true);
setQrScanSuccess(false); setQrScanSuccess(false);
// ✅ Still refresh data even on error
await fetchAllCombinedLotData();
// ✅ Clear error state after a delay
setTimeout(() => {
setQrScanError(false);
}, 3000);
} }
}, [combinedLotData, fetchAllCombinedLotData]); }, [combinedLotData, fetchAllCombinedLotData]);


const handleManualInputSubmit = useCallback(() => {
if (qrScanInput.trim() !== '') {
handleQrCodeSubmit(qrScanInput.trim());
}
}, [qrScanInput, handleQrCodeSubmit]);

// ✅ Handle QR code submission from modal (internal scanning) // ✅ Handle QR code submission from modal (internal scanning)
const handleQrCodeSubmitFromModal = useCallback(async (lotNo: string) => { const handleQrCodeSubmitFromModal = useCallback(async (lotNo: string) => {
if (selectedLotForQr && selectedLotForQr.lotNo === lotNo) { if (selectedLotForQr && selectedLotForQr.lotNo === lotNo) {
@@ -523,22 +544,44 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
} }
}, [selectedLotForQr, fetchAllCombinedLotData]); }, [selectedLotForQr, fetchAllCombinedLotData]);


// ✅ External QR scanning - process QR codes from outside the page
// ✅ Outside QR scanning - process QR codes from outside the page automatically
useEffect(() => { useEffect(() => {
if (qrValues.length > 0 && combinedLotData.length > 0) { if (qrValues.length > 0 && combinedLotData.length > 0) {
const latestQr = qrValues[qrValues.length - 1]; const latestQr = qrValues[qrValues.length - 1];
const qrContent = latestQr.replace(/[{}]/g, '');
setQrScanInput(qrContent);
handleQrCodeSubmit(qrContent);
// Extract lot number from QR code
let lotNo = '';
try {
const qrData = JSON.parse(latestQr);
if (qrData.stockInLineId && qrData.itemId) {
// For JSON QR codes, we need to fetch the lot number
fetchStockInLineInfo(qrData.stockInLineId)
.then((stockInLineInfo) => {
console.log("Outside QR scan - Stock in line info:", stockInLineInfo);
const extractedLotNo = stockInLineInfo.lotNo;
if (extractedLotNo) {
console.log(`Outside QR scan detected (JSON): ${extractedLotNo}`);
handleQrCodeSubmit(extractedLotNo);
}
})
.catch((error) => {
console.error("Outside QR scan - Error fetching stock in line info:", error);
});
return; // Exit early for JSON QR codes
}
} catch (error) {
// Not JSON format, treat as direct lot number
lotNo = latestQr.replace(/[{}]/g, '');
}
// For direct lot number QR codes
if (lotNo) {
console.log(`Outside QR scan detected (direct): ${lotNo}`);
handleQrCodeSubmit(lotNo);
}
} }
}, [qrValues, combinedLotData, handleQrCodeSubmit]); }, [qrValues, combinedLotData, handleQrCodeSubmit]);


const handleManualInputSubmit = useCallback(() => {
if (qrScanInput.trim() !== '') {
handleQrCodeSubmit(qrScanInput.trim());
}
}, [qrScanInput, handleQrCodeSubmit]);


const handlePickQtyChange = useCallback((lotKey: string, value: number | string) => { const handlePickQtyChange = useCallback((lotKey: string, value: number | string) => {
if (value === '' || value === null || value === undefined) { if (value === '' || value === null || value === undefined) {
@@ -836,41 +879,8 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
<Typography variant="h6" gutterBottom sx={{ mb: 0 }}> <Typography variant="h6" gutterBottom sx={{ mb: 0 }}>
{t("All Pick Order Lots")} {t("All Pick Order Lots")}
</Typography> </Typography>
{/* ✅ External QR scan input - for scanning from outside the page */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
<TextField
size="small"
value={qrScanInput}
onChange={(e) => setQrScanInput(e.target.value)}
onKeyPress={(e) => {
if (e.key === 'Enter') {
handleManualInputSubmit();
}
}}
error={qrScanError}
color={qrScanSuccess ? 'success' : undefined}
helperText={
qrScanError
? t("Lot number not found")
: qrScanSuccess
? t("Lot processed successfully")
: t("Enter lot number or scan QR code")
}
placeholder={t("Enter lot number...")}
sx={{ minWidth: '250px' }}
InputProps={{
startAdornment: <QrCodeIcon sx={{ mr: 1, color: isScanning ? 'primary.main' : 'text.secondary' }} />,
}}
/>
<Button
variant="outlined"
onClick={handleManualInputSubmit}
disabled={!qrScanInput.trim()}
size="small"
>
{t("Submit")}
</Button>
</Box>
</Box> </Box>
<TableContainer component={Paper}> <TableContainer component={Paper}>
@@ -923,7 +933,9 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
}} }}
> >
{lot.lotNo} {lot.lotNo}
</Typography> </Typography>
{/*
{lot.lotAvailability !== 'available' && ( {lot.lotAvailability !== 'available' && (
<Typography variant="caption" color="error" display="block"> <Typography variant="caption" color="error" display="block">
({lot.lotAvailability === 'expired' ? 'Expired' : ({lot.lotAvailability === 'expired' ? 'Expired' :
@@ -931,7 +943,8 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
lot.lotAvailability === 'rejected' ? 'Rejected' : lot.lotAvailability === 'rejected' ? 'Rejected' :
'Unavailable'}) 'Unavailable'})
</Typography> </Typography>
)}
)*/}
</Box> </Box>
</TableCell> </TableCell>
<TableCell>{lot.pickOrderTargetDate}</TableCell> <TableCell>{lot.pickOrderTargetDate}</TableCell>
@@ -1091,6 +1104,7 @@ const PickExecution: React.FC<Props> = ({ filterArgs }) => {
resetScan(); resetScan();
}} }}
lot={selectedLotForQr} lot={selectedLotForQr}
combinedLotData={combinedLotData} // ✅ Add this prop
onQrCodeSubmit={handleQrCodeSubmitFromModal} onQrCodeSubmit={handleQrCodeSubmitFromModal}
/> />




+ 2
- 1
src/components/PickOrderSearch/LotTable.tsx 查看文件

@@ -620,6 +620,7 @@ const LotTable: React.FC<LotTableProps> = ({
> >
{lot.lotNo} {lot.lotNo}
</Typography> </Typography>
{/*
{lot.lotAvailability !== 'available' && ( {lot.lotAvailability !== 'available' && (
<Typography variant="caption" color="error" display="block"> <Typography variant="caption" color="error" display="block">
({lot.lotAvailability === 'expired' ? 'Expired' : ({lot.lotAvailability === 'expired' ? 'Expired' :
@@ -627,7 +628,7 @@ const LotTable: React.FC<LotTableProps> = ({
lot.lotAvailability === 'rejected' ? 'Rejected' : // ✅ 添加 rejected 显示 lot.lotAvailability === 'rejected' ? 'Rejected' : // ✅ 添加 rejected 显示
'Unavailable'}) 'Unavailable'})
</Typography> </Typography>
)}
)} */}
</Box> </Box>
</TableCell> </TableCell>
<TableCell>{lot.expiryDate}</TableCell> <TableCell>{lot.expiryDate}</TableCell>


正在加载...
取消
保存