|
|
|
@@ -178,7 +178,7 @@ function isWaitingQcPutAway( |
|
|
|
return s !== "completed" && s !== "rejected"; |
|
|
|
} |
|
|
|
|
|
|
|
/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.7 | 2026-08-06 */ |
|
|
|
/** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.8 | 2026-08-09 */ |
|
|
|
const ProductProcessList: React.FC<ProductProcessListProps> = ({ |
|
|
|
onSelectProcess, |
|
|
|
printerCombo, |
|
|
|
@@ -447,7 +447,7 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ |
|
|
|
return productionCache; |
|
|
|
}, [listTab, productionCache, pendingQcCache, putawayedCache, offPlanRows]); |
|
|
|
|
|
|
|
// QC 的业务判定:同一个 jobOrder 下,所有 productProcess 的所有 lines 都必须是 Completed/Pass |
|
|
|
// QC ready: same JO — all lines Completed/Pass (sibling 包裝 auto-Pass on backend) + has SIL |
|
|
|
const jobOrderQcReadyById = useMemo(() => { |
|
|
|
const byJobOrder = new Map<number, AllJoborderProductProcessInfoResponse[]>(); |
|
|
|
for (const p of tabProcesses) { |
|
|
|
@@ -465,31 +465,11 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ |
|
|
|
|
|
|
|
byJobOrder.forEach((jobOrderProcesses, jobOrderId) => { |
|
|
|
const hasStockInLine = jobOrderProcesses.some((p) => p.stockInLineId != null); |
|
|
|
const allLines = jobOrderProcesses.flatMap((p) => p.lines ?? []); |
|
|
|
const allLinesDone = |
|
|
|
allLines.length > 0 && allLines.every((l) => isDone(l.status)); |
|
|
|
|
|
|
|
const packingProcesses = jobOrderProcesses.filter( |
|
|
|
(p) => String((p as any).code ?? "").trim() === "包裝", |
|
|
|
); |
|
|
|
const nonPackingProcesses = jobOrderProcesses.filter( |
|
|
|
(p) => String((p as any).code ?? "").trim() !== "包裝", |
|
|
|
); |
|
|
|
|
|
|
|
const allNonPackingDone = |
|
|
|
nonPackingProcesses.length === 0 || |
|
|
|
nonPackingProcesses.every((p) => { |
|
|
|
const lines = p.lines ?? []; |
|
|
|
return lines.length > 0 && lines.every((l) => isDone(l.status)); |
|
|
|
}); |
|
|
|
|
|
|
|
const hasOnePackingDone = |
|
|
|
packingProcesses.length > 0 && |
|
|
|
packingProcesses.some((p) => { |
|
|
|
const lines = p.lines ?? []; |
|
|
|
return lines.some((l) => isDone(l.status)); |
|
|
|
}); |
|
|
|
|
|
|
|
const packingOk = packingProcesses.length === 0 ? true : hasOnePackingDone; |
|
|
|
|
|
|
|
result.set(jobOrderId, hasStockInLine && allNonPackingDone && packingOk); |
|
|
|
result.set(jobOrderId, hasStockInLine && allLinesDone); |
|
|
|
}); |
|
|
|
|
|
|
|
return result; |
|
|
|
|