Empty output qty fields no longer stick at 0; empty submits as 0. Hide leave-JO back on step page so users return to the process steps list instead. Co-authored-by: Cursor <[email protected]>stockTakeUpdate^2
| @@ -906,7 +906,7 @@ export const fetchAllJoborderProductProcessInfo = cache(async (type?: string | n | |||
| ); | |||
| }); | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.7 | 2026-08-06 */ | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.11 | 2026-10-29 */ | |||
| export const fetchJoborderProductProcessesPage = cache(async (params: { | |||
| /** Job order / process date(YYYY-MM-DD) */ | |||
| date?: string | null; | |||
| @@ -17,25 +17,42 @@ import CheckCircleIcon from "@mui/icons-material/CheckCircle"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { UpdateProductProcessLineQtyRequest } from "@/app/api/jo/actions"; | |||
| type QtyInput = number | ""; | |||
| export type ProductionOutputFormData = Omit< | |||
| UpdateProductProcessLineQtyRequest, | |||
| | "outputFromProcessQty" | |||
| | "byproductQty" | |||
| | "defectQty" | |||
| | "defect2Qty" | |||
| | "defect3Qty" | |||
| | "scrapQty" | |||
| > & { | |||
| outputFromProcessQty: QtyInput; | |||
| byproductQty: QtyInput; | |||
| defectQty: QtyInput; | |||
| defect2Qty: QtyInput; | |||
| defect3Qty: QtyInput; | |||
| scrapQty: QtyInput; | |||
| }; | |||
| const parseQtyInput = (raw: string): QtyInput => { | |||
| if (raw === "") return ""; | |||
| const n = parseInt(raw, 10); | |||
| return Number.isNaN(n) ? "" : n; | |||
| }; | |||
| export const toSubmitQty = (v: QtyInput | null | undefined): number => | |||
| v === "" || v == null || Number.isNaN(Number(v)) ? 0 : Number(v); | |||
| interface ProductionOutputFormProps { | |||
| outputData: (UpdateProductProcessLineQtyRequest & { | |||
| byproductName: string; | |||
| byproductQty: number; | |||
| byproductUom: string; | |||
| }); | |||
| setOutputData: React.Dispatch< | |||
| React.SetStateAction< | |||
| UpdateProductProcessLineQtyRequest & { | |||
| byproductName: string; | |||
| byproductQty: number; | |||
| byproductUom: string; | |||
| } | |||
| > | |||
| >; | |||
| outputData: ProductionOutputFormData; | |||
| setOutputData: React.Dispatch<React.SetStateAction<ProductionOutputFormData>>; | |||
| onSubmit: () => Promise<void> | void; | |||
| onCancel: () => void; | |||
| } | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.1 | 2026-10-29 */ | |||
| const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({ | |||
| outputData, | |||
| setOutputData, | |||
| @@ -68,7 +85,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({ | |||
| onChange={(e) => | |||
| setOutputData({ | |||
| ...outputData, | |||
| outputFromProcessQty: parseInt(e.target.value) || 0, | |||
| outputFromProcessQty: parseQtyInput(e.target.value), | |||
| }) | |||
| } | |||
| /> | |||
| @@ -103,7 +120,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({ | |||
| onChange={(e) => | |||
| setOutputData({ | |||
| ...outputData, | |||
| byproductQty: parseInt(e.target.value) || 0, | |||
| byproductQty: parseQtyInput(e.target.value), | |||
| }) | |||
| } | |||
| /> | |||
| @@ -138,7 +155,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({ | |||
| onChange={(e) => | |||
| setOutputData({ | |||
| ...outputData, | |||
| defectQty: parseInt(e.target.value) || 0, | |||
| defectQty: parseQtyInput(e.target.value), | |||
| }) | |||
| } | |||
| /> | |||
| @@ -173,7 +190,7 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({ | |||
| onChange={(e) => | |||
| setOutputData({ | |||
| ...outputData, | |||
| scrapQty: parseInt(e.target.value) || 0, | |||
| scrapQty: parseQtyInput(e.target.value), | |||
| }) | |||
| } | |||
| /> | |||
| @@ -207,4 +224,4 @@ const ProductionOutputForm: React.FC<ProductionOutputFormProps> = ({ | |||
| ); | |||
| }; | |||
| export default ProductionOutputForm; | |||
| export default ProductionOutputForm; | |||
| @@ -5,47 +5,47 @@ import { | |||
| Button, | |||
| Typography, | |||
| } from "@mui/material"; | |||
| import ArrowBackIcon from "@mui/icons-material/ArrowBack"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { | |||
| fetchProductProcessLineDetail, | |||
| updateProductProcessLineQty, | |||
| UpdateProductProcessLineQtyRequest, | |||
| JobOrderProcessLineDetailResponse, | |||
| } from "@/app/api/jo/actions"; | |||
| import ProductionOutputForm from "./ProductionOutputForm"; | |||
| import ProductionOutputForm, { | |||
| ProductionOutputFormData, | |||
| toSubmitQty, | |||
| } from "./ProductionOutputForm"; | |||
| interface ProductionOutputFormPageProps { | |||
| lineId: number | null; | |||
| onBack: () => void; | |||
| } | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.1 | 2026-10-29 */ | |||
| const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({ | |||
| lineId, | |||
| onBack, | |||
| }) => { | |||
| const { t } = useTranslation(); | |||
| const { t } = useTranslation(["common", "jo", "productionProcess"]); | |||
| const [lineDetail, setLineDetail] = useState<JobOrderProcessLineDetailResponse | null>(null); | |||
| const [outputData, setOutputData] = useState<UpdateProductProcessLineQtyRequest & { | |||
| byproductName: string; | |||
| byproductQty: number; | |||
| byproductUom: string; | |||
| }>({ | |||
| const [outputData, setOutputData] = useState<ProductionOutputFormData>({ | |||
| productProcessLineId: lineId ?? 0, | |||
| outputFromProcessQty: 0, | |||
| outputFromProcessQty: "", | |||
| outputFromProcessUom: "", | |||
| defectQty: 0, | |||
| defectQty: "", | |||
| defectUom: "", | |||
| defect2Qty: 0, | |||
| defect2Qty: "", | |||
| defect2Uom: "", | |||
| defect3Qty: 0, | |||
| defect3Qty: "", | |||
| defect3Uom: "", | |||
| defectDescription: "", | |||
| defectDescription2: "", | |||
| defectDescription3: "", | |||
| scrapQty: 0, | |||
| scrapQty: "", | |||
| scrapUom: "", | |||
| byproductName: "", | |||
| byproductQty: 0, | |||
| byproductQty: "", | |||
| byproductUom: "", | |||
| }); | |||
| @@ -60,14 +60,14 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({ | |||
| setOutputData((prev) => ({ | |||
| ...prev, | |||
| productProcessLineId: detail.id, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || 0, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || "", | |||
| outputFromProcessUom: (detail as any).outputFromProcessUom || "", | |||
| defectQty: detail.defectQty || 0, | |||
| defectQty: detail.defectQty || "", | |||
| defectUom: detail.defectUom || "", | |||
| scrapQty: detail.scrapQty || 0, | |||
| scrapQty: detail.scrapQty || "", | |||
| scrapUom: detail.scrapUom || "", | |||
| byproductName: detail.byproductName || "", | |||
| byproductQty: detail.byproductQty || 0, | |||
| byproductQty: detail.byproductQty || "", | |||
| byproductUom: detail.byproductUom || "", | |||
| })); | |||
| }) | |||
| @@ -84,6 +84,12 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({ | |||
| await updateProductProcessLineQty({ | |||
| ...outputData, | |||
| productProcessLineId: lineDetail.id || 0, | |||
| outputFromProcessQty: toSubmitQty(outputData.outputFromProcessQty), | |||
| byproductQty: toSubmitQty(outputData.byproductQty), | |||
| defectQty: toSubmitQty(outputData.defectQty), | |||
| defect2Qty: toSubmitQty(outputData.defect2Qty), | |||
| defect3Qty: toSubmitQty(outputData.defect3Qty), | |||
| scrapQty: toSubmitQty(outputData.scrapQty), | |||
| }); | |||
| console.log("Output data submitted successfully"); | |||
| @@ -94,14 +100,14 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({ | |||
| setOutputData((prev) => ({ | |||
| ...prev, | |||
| productProcessLineId: detail.id, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || 0, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || "", | |||
| outputFromProcessUom: (detail as any).outputFromProcessUom || "", | |||
| defectQty: detail.defectQty || 0, | |||
| defectQty: detail.defectQty || "", | |||
| defectUom: detail.defectUom || "", | |||
| scrapQty: detail.scrapQty || 0, | |||
| scrapQty: detail.scrapQty || "", | |||
| scrapUom: detail.scrapUom || "", | |||
| byproductName: detail.byproductName || "", | |||
| byproductQty: detail.byproductQty || 0, | |||
| byproductQty: detail.byproductQty || "", | |||
| byproductUom: detail.byproductUom || "", | |||
| })); | |||
| @@ -116,8 +122,13 @@ const ProductionOutputFormPage: React.FC<ProductionOutputFormPageProps> = ({ | |||
| return ( | |||
| <Box> | |||
| <Box sx={{ mb: 2 }}> | |||
| <Button variant="outlined" onClick={onBack}> | |||
| {t("Back to List")} | |||
| <Button | |||
| variant="outlined" | |||
| size="small" | |||
| onClick={onBack} | |||
| startIcon={<ArrowBackIcon />} | |||
| > | |||
| {t("Back to Process Steps")} | |||
| </Button> | |||
| </Box> | |||
| @@ -64,13 +64,16 @@ interface ProductProcessDetailProps { | |||
| jobOrderId: number; | |||
| onBack: () => void; | |||
| fromJosave?: boolean; | |||
| /** 進入步驟執行頁時通知父層(用來隱藏「返回列表」) */ | |||
| onStepViewChange?: (inStepView: boolean) => void; | |||
| } | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 50 | v1.0.1 | 2026-08-10 */ | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 50 | v1.0.2 | 2026-10-29 */ | |||
| const ProductionProcessDetail: React.FC<ProductProcessDetailProps> = ({ | |||
| jobOrderId, | |||
| onBack, | |||
| fromJosave, | |||
| onStepViewChange, | |||
| }) => { | |||
| // console.log(" ProductionProcessDetail RENDER", { jobOrderId, fromJosave }); | |||
| @@ -143,6 +146,12 @@ const fetchProcessDetailRef = useRef<() => Promise<void>>(); | |||
| useEffect(() => { | |||
| onBackRef.current = onBack; | |||
| }, [onBack]); | |||
| useEffect(() => { | |||
| const inStepView = isExecutingLine && selectedLineId != null; | |||
| onStepViewChange?.(inStepView); | |||
| return () => onStepViewChange?.(false); | |||
| }, [isExecutingLine, selectedLineId, onStepViewChange]); | |||
| // 获取 process 和 lines 数据 | |||
| const fetchProcessDetail = useCallback(async () => { | |||
| // console.log(" fetchProcessDetail CALLED", { jobOrderId, timestamp: new Date().toISOString() }); | |||
| @@ -54,7 +54,7 @@ interface ProductProcessJobOrderDetailProps { | |||
| initialTabIndex?: number; | |||
| } | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.7 | 2026-08-06 */ | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.11 | 2026-10-29 */ | |||
| const ProductionProcessJobOrderDetail: React.FC<ProductProcessJobOrderDetailProps> = ({ | |||
| jobOrderId, | |||
| onBack, | |||
| @@ -68,6 +68,7 @@ const ProductionProcessJobOrderDetail: React.FC<ProductProcessJobOrderDetailProp | |||
| const [inventoryData, setInventoryData] = useState<InventoryResult[]>([]); | |||
| const [tabIndex, setTabIndex] = useState(initialTabIndex); | |||
| const [selectedProcessId, setSelectedProcessId] = useState<number | null>(null); | |||
| const [inStepView, setInStepView] = useState(false); | |||
| const [operationPriority, setOperationPriority] = useState<number>(50); | |||
| const [openOperationPriorityDialog, setOpenOperationPriorityDialog] = useState(false); | |||
| const [openPlanStartDialog, setOpenPlanStartDialog] = useState(false); | |||
| @@ -320,6 +321,9 @@ const handleRelease = useCallback(async (jobOrderId: number) => { | |||
| const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>( | |||
| (_e, newValue) => { | |||
| setTabIndex(newValue); | |||
| if (newValue !== 2) { | |||
| setInStepView(false); | |||
| } | |||
| }, | |||
| [], | |||
| ); | |||
| @@ -796,12 +800,14 @@ const handleRelease = useCallback(async (jobOrderId: number) => { | |||
| return ( | |||
| <Box> | |||
| {/* 返回按钮 */} | |||
| <Box sx={{ mb: 2 }}> | |||
| <Button variant="outlined" onClick={onBack} startIcon={<ArrowBackIcon />}> | |||
| {t("Back to List")} | |||
| </Button> | |||
| </Box> | |||
| {/* 步驟執行頁不顯示「返回列表」,避免誤離開工單 */} | |||
| {!inStepView && ( | |||
| <Box sx={{ mb: 2 }}> | |||
| <Button variant="outlined" onClick={onBack} startIcon={<ArrowBackIcon />}> | |||
| {t("Back to List")} | |||
| </Button> | |||
| </Box> | |||
| )} | |||
| {/* 标签页 */} | |||
| <Box sx={{ borderBottom: '1px solid #e0e0e0' }}> | |||
| @@ -833,6 +839,7 @@ const handleRelease = useCallback(async (jobOrderId: number) => { | |||
| }} | |||
| fromJosave={Boolean(fromJosave && !isPutAwayed)} | |||
| onStepViewChange={setInStepView} | |||
| /> | |||
| )} | |||
| {tabIndex === 3 && <ProductionProcessesLineRemarkTableContent />} | |||
| @@ -179,7 +179,7 @@ function isWaitingQcPutAway( | |||
| return s !== "completed" && s !== "rejected"; | |||
| } | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.10 | 2026-10-15 */ | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.11 | 2026-10-29 */ | |||
| const ProductProcessList: React.FC<ProductProcessListProps> = ({ | |||
| onSelectProcess, | |||
| printerCombo, | |||
| @@ -28,6 +28,7 @@ import CheckCircleIcon from "@mui/icons-material/CheckCircle"; | |||
| import StopIcon from "@mui/icons-material/Stop"; | |||
| import PauseIcon from "@mui/icons-material/Pause"; | |||
| import PlayArrowIcon from "@mui/icons-material/PlayArrow"; | |||
| import ArrowBackIcon from "@mui/icons-material/ArrowBack"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { | |||
| JobOrderProcessLineDetailResponse, | |||
| @@ -47,6 +48,35 @@ import { fetchNameList, NameList } from "@/app/api/user/actions"; | |||
| import BagConsumptionForm from "./BagConsumptionForm"; // ✅ 添加导入 | |||
| import OverallTimeRemainingCard from "./OverallTimeRemainingCard"; // ✅ 添加导入 | |||
| import dayjs from "dayjs"; | |||
| type QtyInput = number | ""; | |||
| type OutputFormState = Omit< | |||
| UpdateProductProcessLineQtyRequest, | |||
| | "outputFromProcessQty" | |||
| | "byproductQty" | |||
| | "defectQty" | |||
| | "defect2Qty" | |||
| | "defect3Qty" | |||
| | "scrapQty" | |||
| > & { | |||
| outputFromProcessQty: QtyInput; | |||
| byproductQty: QtyInput; | |||
| defectQty: QtyInput; | |||
| defect2Qty: QtyInput; | |||
| defect3Qty: QtyInput; | |||
| scrapQty: QtyInput; | |||
| }; | |||
| const parseQtyInput = (raw: string): QtyInput => { | |||
| if (raw === "") return ""; | |||
| const n = parseInt(raw, 10); | |||
| return Number.isNaN(n) ? "" : n; | |||
| }; | |||
| const toSubmitQty = (v: QtyInput | null | undefined): number => | |||
| v === "" || v == null || Number.isNaN(Number(v)) ? 0 : Number(v); | |||
| interface ProductionProcessStepExecutionProps { | |||
| lineId: number | null; | |||
| onBack: () => void; | |||
| @@ -55,7 +85,7 @@ interface ProductionProcessStepExecutionProps { | |||
| jobOrderId?: number; // ✅ 添加 | |||
| } | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.0 | 2026-08-10 */ | |||
| /** FP-MTMS Version Checklist | Functions Ref. No. 59 | v1.0.1 | 2026-10-29 */ | |||
| const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionProps> = ({ | |||
| lineId, | |||
| onBack, | |||
| @@ -75,24 +105,20 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| lineStatusNorm === "autopass"; | |||
| const isPassStatus = lineStatusNorm === "pass"; | |||
| const isAutoPassStatus = lineStatusNorm === "autopass"; | |||
| const [outputData, setOutputData] = useState<UpdateProductProcessLineQtyRequest & { | |||
| byproductName: string; | |||
| byproductQty: number; | |||
| byproductUom: string; | |||
| }>({ | |||
| const [outputData, setOutputData] = useState<OutputFormState>({ | |||
| productProcessLineId: lineId ?? 0, | |||
| outputFromProcessQty: 0, | |||
| outputFromProcessQty: "", | |||
| outputFromProcessUom: "", | |||
| defectQty: 0, | |||
| defectQty: "", | |||
| defectUom: "", | |||
| scrapQty: 0, | |||
| scrapQty: "", | |||
| scrapUom: "", | |||
| byproductName: "", | |||
| byproductQty: 0, | |||
| byproductQty: "", | |||
| byproductUom: "", | |||
| defect2Qty: 0, | |||
| defect2Qty: "", | |||
| defect2Uom: "", | |||
| defect3Qty: 0, | |||
| defect3Qty: "", | |||
| defect3Uom: "", | |||
| defectDescription: "", | |||
| defectDescription2: "", | |||
| @@ -153,14 +179,14 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| setOutputData(prev => ({ | |||
| ...prev, | |||
| productProcessLineId: detail.id, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || 0, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || "", | |||
| outputFromProcessUom: (detail as any).outputFromProcessUom || "", | |||
| defectQty: detail.defectQty || 0, | |||
| defectQty: detail.defectQty || "", | |||
| defectUom: detail.defectUom || "", | |||
| scrapQty: detail.scrapQty || 0, | |||
| scrapQty: detail.scrapQty || "", | |||
| scrapUom: detail.scrapUom || "", | |||
| byproductName: detail.byproductName || "", | |||
| byproductQty: detail.byproductQty || 0, | |||
| byproductQty: detail.byproductQty || "", | |||
| byproductUom: detail.byproductUom || "" | |||
| })); | |||
| }) | |||
| @@ -351,20 +377,20 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| await updateProductProcessLineQty({ | |||
| productProcessLineId: lineDetail?.id || 0 as number, | |||
| byproductName: outputData.byproductName, | |||
| byproductQty: outputData.byproductQty, | |||
| byproductQty: toSubmitQty(outputData.byproductQty), | |||
| byproductUom: outputData.byproductUom, | |||
| outputFromProcessQty: outputData.outputFromProcessQty, | |||
| outputFromProcessQty: toSubmitQty(outputData.outputFromProcessQty), | |||
| outputFromProcessUom: outputData.outputFromProcessUom, | |||
| defectQty: outputData.defectQty, | |||
| defectQty: toSubmitQty(outputData.defectQty), | |||
| defectUom: outputData.defectUom, | |||
| defect2Qty: outputData.defect2Qty, | |||
| defect2Qty: toSubmitQty(outputData.defect2Qty), | |||
| defect2Uom: outputData.defect2Uom, | |||
| defect3Qty: outputData.defect3Qty, | |||
| defect3Qty: toSubmitQty(outputData.defect3Qty), | |||
| defect3Uom: outputData.defect3Uom, | |||
| defectDescription: outputData.defectDescription, | |||
| defectDescription2: outputData.defectDescription2, | |||
| defectDescription3: outputData.defectDescription3, | |||
| scrapQty: outputData.scrapQty, | |||
| scrapQty: toSubmitQty(outputData.scrapQty), | |||
| scrapUom: outputData.scrapUom, | |||
| }); | |||
| @@ -383,21 +409,21 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| setOutputData(prev => ({ | |||
| ...prev, | |||
| productProcessLineId: detail.id, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || 0, | |||
| outputFromProcessQty: (detail as any).outputFromProcessQty || "", | |||
| outputFromProcessUom: (detail as any).outputFromProcessUom || "", | |||
| defectQty: detail.defectQty || 0, | |||
| defectQty: detail.defectQty || "", | |||
| defectUom: detail.defectUom || "", | |||
| defectDescription: detail.defectDescription || "", | |||
| defectDescription2: detail.defectDescription2 || "", | |||
| defectDescription3: detail.defectDescription3 || "", | |||
| defectQty2: detail.defectQty2 || 0, | |||
| defectUom2: detail.defectUom2 || "", | |||
| defectQty3: detail.defectQty3 || 0, | |||
| defectUom3: detail.defectUom3 || "", | |||
| scrapQty: detail.scrapQty || 0, | |||
| defect2Qty: (detail as any).defect2Qty || "", | |||
| defect2Uom: (detail as any).defect2Uom || "", | |||
| defect3Qty: (detail as any).defect3Qty || "", | |||
| defect3Uom: (detail as any).defect3Uom || "", | |||
| scrapQty: detail.scrapQty || "", | |||
| scrapUom: detail.scrapUom || "", | |||
| byproductName: detail.byproductName || "", | |||
| byproductQty: detail.byproductQty || 0, | |||
| byproductQty: detail.byproductQty || "", | |||
| byproductUom: detail.byproductUom || "" | |||
| })); | |||
| }) | |||
| @@ -561,8 +587,13 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| return ( | |||
| <Box> | |||
| <Box sx={{ mb: 2 }}> | |||
| <Button variant="outlined" onClick={onBack}> | |||
| {t("Back to List")} | |||
| <Button | |||
| variant="outlined" | |||
| size="small" | |||
| onClick={onBack} | |||
| startIcon={<ArrowBackIcon />} | |||
| > | |||
| {t("Back to Process Steps")} | |||
| </Button> | |||
| </Box> | |||
| {processData && ( | |||
| @@ -812,7 +843,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| value={outputData.outputFromProcessQty} | |||
| onChange={(e) => setOutputData({ | |||
| ...outputData, | |||
| outputFromProcessQty: parseInt(e.target.value) || 0 | |||
| outputFromProcessQty: parseQtyInput(e.target.value) | |||
| })} | |||
| /> | |||
| </TableCell> | |||
| @@ -854,7 +885,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| value={outputData.defectQty} | |||
| onChange={(e) => setOutputData({ | |||
| ...outputData, | |||
| defectQty: parseInt(e.target.value) || 0 | |||
| defectQty: parseQtyInput(e.target.value) | |||
| })} | |||
| /> | |||
| </TableCell> | |||
| @@ -902,7 +933,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| value={outputData.defect2Qty} | |||
| onChange={(e) => setOutputData({ | |||
| ...outputData, | |||
| defect2Qty: parseInt(e.target.value) || 0 | |||
| defect2Qty: parseQtyInput(e.target.value) | |||
| })} | |||
| /> | |||
| </TableCell> | |||
| @@ -950,7 +981,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| value={outputData.defect3Qty} | |||
| onChange={(e) => setOutputData({ | |||
| ...outputData, | |||
| defect3Qty: parseInt(e.target.value) || 0 | |||
| defect3Qty: parseQtyInput(e.target.value) | |||
| })} | |||
| /> | |||
| </TableCell> | |||
| @@ -998,7 +1029,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||
| value={outputData.scrapQty} | |||
| onChange={(e) => setOutputData({ | |||
| ...outputData, | |||
| scrapQty: parseInt(e.target.value) || 0 | |||
| scrapQty: parseQtyInput(e.target.value) | |||
| })} | |||
| /> | |||
| </TableCell> | |||
| @@ -32,6 +32,8 @@ | |||
| "BOM Type": "BOM Type", | |||
| "Back": "Back", | |||
| "Back to List": "Back to List", | |||
| "Back to Process": "Back to Process Steps", | |||
| "Back to Process Steps": "Back to Process Steps", | |||
| "Bad Item Qty": "Bad Item Qty", | |||
| "Bad Package Qty": "Bad Package Qty", | |||
| "Bag": "Bag", | |||
| @@ -10,6 +10,8 @@ | |||
| "Auto-refresh every 10 minutes": "Auto-refresh every 10 minutes", | |||
| "Back": "Back", | |||
| "Back to List": "Back to List", | |||
| "Back to Process": "Back to Process Steps", | |||
| "Back to Process Steps": "Back to Process Steps", | |||
| "Bag": "Bag", | |||
| "Bag Consumption": "Bag Consumption", | |||
| "Balance": "Balance", | |||
| @@ -34,6 +34,8 @@ | |||
| "BOM Type": "BOM 類型", | |||
| "Back": "返回", | |||
| "Back to List": "返回列表", | |||
| "Back to Process": "返回列表", | |||
| "Back to Process Steps": "返回列表", | |||
| "Bad Item Qty": "不良物品數量", | |||
| "Bad Package Qty": "不良包裝數量", | |||
| "Bag": "包裝袋", | |||
| @@ -10,6 +10,8 @@ | |||
| "Auto-refresh every 10 minutes": "每10分鐘自動刷新", | |||
| "Back": "返回", | |||
| "Back to List": "返回列表", | |||
| "Back to Process": "返回列表", | |||
| "Back to Process Steps": "返回列表", | |||
| "Bag": "包裝袋", | |||
| "Bag Consumption": "包裝袋消耗", | |||
| "Balance": "可用數量", | |||