| @@ -5,7 +5,7 @@ import { Stack, Typography } from "@mui/material"; | |||||
| import { Metadata } from "next"; | import { Metadata } from "next"; | ||||
| import React, { Suspense } from "react"; | import React, { Suspense } from "react"; | ||||
| import GeneralLoading from "@/components/General/GeneralLoading"; | import GeneralLoading from "@/components/General/GeneralLoading"; | ||||
| import JodetailSearchWrapper from "@/components/Jodetail/FinishedGoodSearchWrapper"; | |||||
| export const metadata: Metadata = { | export const metadata: Metadata = { | ||||
| title: "Job Order Pickexcution" | title: "Job Order Pickexcution" | ||||
| } | } | ||||
| @@ -29,7 +29,7 @@ const jo: React.FC = async () => { | |||||
| </Stack> | </Stack> | ||||
| <I18nProvider namespaces={["jo", "common", "pickOrder"]}> | <I18nProvider namespaces={["jo", "common", "pickOrder"]}> | ||||
| <Suspense fallback={<GeneralLoading />}> | <Suspense fallback={<GeneralLoading />}> | ||||
| <JodetailSearch pickOrders={[]} /> | |||||
| <JodetailSearchWrapper /> | |||||
| </Suspense> | </Suspense> | ||||
| </I18nProvider> | </I18nProvider> | ||||
| </> | </> | ||||
| @@ -769,7 +769,8 @@ export async function PrintPickRecord(request: PrintPickRecordRequest){ | |||||
| params.append('printQty', request.printQty.toString()); | params.append('printQty', request.printQty.toString()); | ||||
| } | } | ||||
| const response = await serverFetchWithNoContent(`${BASE_API_URL}/jo/print-PickRecord?${params.toString()}`,{ | |||||
| //const response = await serverFetchWithNoContent(`${BASE_API_URL}/jo/print-PickRecord?${params.toString()}`,{ | |||||
| const response = await serverFetchWithNoContent(`${BASE_API_URL}/jo/newPrint-PickRecord?${params.toString()}`,{ | |||||
| method: "GET" | method: "GET" | ||||
| }); | }); | ||||
| @@ -42,7 +42,7 @@ import { | |||||
| import SearchBox, { Criterion } from "../SearchBox"; | import SearchBox, { Criterion } from "../SearchBox"; | ||||
| import { useSession } from "next-auth/react"; | import { useSession } from "next-auth/react"; | ||||
| import { SessionWithTokens } from "@/config/authConfig"; | import { SessionWithTokens } from "@/config/authConfig"; | ||||
| import { PrinterCombo } from "@/app/api/settings/printer"; | |||||
| interface Props { | interface Props { | ||||
| filterArgs: Record<string, any>; | filterArgs: Record<string, any>; | ||||
| } | } | ||||
| @@ -1,13 +1,14 @@ | |||||
| import { fetchPickOrders } from "@/app/api/pickOrder"; | import { fetchPickOrders } from "@/app/api/pickOrder"; | ||||
| import { fetchPrinterCombo } from "@/app/api/settings/printer"; | |||||
| import GeneralLoading from "../General/GeneralLoading"; | import GeneralLoading from "../General/GeneralLoading"; | ||||
| import PickOrderSearch from "./FinishedGoodSearchWrapper"; | |||||
| import JodetailSearch from "./JodetailSearch"; | |||||
| interface SubComponents { | interface SubComponents { | ||||
| Loading: typeof GeneralLoading; | Loading: typeof GeneralLoading; | ||||
| } | } | ||||
| const FinishedGoodSearchWrapper: React.FC & SubComponents = async () => { | |||||
| const [pickOrders] = await Promise.all([ | |||||
| const JodetailSearchWrapper: React.FC & SubComponents = async () => { | |||||
| const [pickOrders, printerCombo] = await Promise.all([ | |||||
| fetchPickOrders({ | fetchPickOrders({ | ||||
| code: undefined, | code: undefined, | ||||
| targetDateFrom: undefined, | targetDateFrom: undefined, | ||||
| @@ -16,11 +17,13 @@ const FinishedGoodSearchWrapper: React.FC & SubComponents = async () => { | |||||
| status: undefined, | status: undefined, | ||||
| itemName: undefined, | itemName: undefined, | ||||
| }), | }), | ||||
| fetchPrinterCombo(), | |||||
| ]); | ]); | ||||
| console.log("%c printerCombo:", "color:green", printerCombo); | |||||
| return <FinishedGoodSearchWrapper pickOrders={pickOrders} />; | |||||
| return <JodetailSearch pickOrders={pickOrders} printerCombo={printerCombo} />; | |||||
| }; | }; | ||||
| FinishedGoodSearchWrapper.Loading = GeneralLoading; | |||||
| JodetailSearchWrapper.Loading = GeneralLoading; | |||||
| export default FinishedGoodSearchWrapper; | |||||
| export default JodetailSearchWrapper; | |||||
| @@ -37,6 +37,7 @@ import { fetchPrinterCombo } from "@/app/api/settings/printer"; | |||||
| import { PrinterCombo } from "@/app/api/settings/printer"; | import { PrinterCombo } from "@/app/api/settings/printer"; | ||||
| interface Props { | interface Props { | ||||
| pickOrders: PickOrderResult[]; | pickOrders: PickOrderResult[]; | ||||
| printerCombo: PrinterCombo[]; | |||||
| } | } | ||||
| type SearchQuery = Partial< | type SearchQuery = Partial< | ||||
| @@ -45,7 +46,7 @@ type SearchQuery = Partial< | |||||
| type SearchParamNames = keyof SearchQuery; | type SearchParamNames = keyof SearchQuery; | ||||
| const JodetailSearch: React.FC<Props> = ({ pickOrders }) => { | |||||
| const JodetailSearch: React.FC<Props> = ({ pickOrders, printerCombo }) => { | |||||
| const { t } = useTranslation("jo"); | const { t } = useTranslation("jo"); | ||||
| const { data: session } = useSession() as { data: SessionWithTokens | null }; | const { data: session } = useSession() as { data: SessionWithTokens | null }; | ||||
| const currentUserId = session?.id ? parseInt(session.id) : undefined; | const currentUserId = session?.id ? parseInt(session.id) : undefined; | ||||
| @@ -65,7 +66,7 @@ const [hasAssignedJobOrders, setHasAssignedJobOrders] = useState(false); | |||||
| const [hasDataTab0, setHasDataTab0] = useState(false); | const [hasDataTab0, setHasDataTab0] = useState(false); | ||||
| const [hasDataTab1, setHasDataTab1] = useState(false); | const [hasDataTab1, setHasDataTab1] = useState(false); | ||||
| const hasAnyAssignedData = hasDataTab0 || hasDataTab1; | const hasAnyAssignedData = hasDataTab0 || hasDataTab1; | ||||
| const [printers, setPrinters] = useState<PrinterCombo[]>([]); | |||||
| //const [printers, setPrinters] = useState<PrinterCombo[]>([]); | |||||
| const [hideCompletedUntilNext, setHideCompletedUntilNext] = useState<boolean>( | const [hideCompletedUntilNext, setHideCompletedUntilNext] = useState<boolean>( | ||||
| typeof window !== 'undefined' && localStorage.getItem('hideCompletedUntilNext') === 'true' | typeof window !== 'undefined' && localStorage.getItem('hideCompletedUntilNext') === 'true' | ||||
| ); | ); | ||||
| @@ -95,6 +96,7 @@ const [printers, setPrinters] = useState<PrinterCombo[]>([]); | |||||
| window.removeEventListener('jobOrderDataStatus', handleJobOrderDataChange as EventListener); | window.removeEventListener('jobOrderDataStatus', handleJobOrderDataChange as EventListener); | ||||
| }; | }; | ||||
| }, []); | }, []); | ||||
| /* | |||||
| useEffect(() => { | useEffect(() => { | ||||
| const fetchPrinters = async () => { | const fetchPrinters = async () => { | ||||
| try { | try { | ||||
| @@ -108,6 +110,7 @@ const [printers, setPrinters] = useState<PrinterCombo[]>([]); | |||||
| }; | }; | ||||
| fetchPrinters(); | fetchPrinters(); | ||||
| }, []); | }, []); | ||||
| */ | |||||
| useEffect(() => { | useEffect(() => { | ||||
| const onAssigned = () => { | const onAssigned = () => { | ||||
| localStorage.removeItem('hideCompletedUntilNext'); | localStorage.removeItem('hideCompletedUntilNext'); | ||||
| @@ -482,7 +485,7 @@ const [printers, setPrinters] = useState<PrinterCombo[]>([]); | |||||
| p: 2 | p: 2 | ||||
| }}> | }}> | ||||
| {tabIndex === 0 && <JobPickExecution filterArgs={filterArgs} />} | {tabIndex === 0 && <JobPickExecution filterArgs={filterArgs} />} | ||||
| {tabIndex === 1 && <CompleteJobOrderRecord filterArgs={filterArgs} printerCombo={printers} />} | |||||
| {tabIndex === 1 && <CompleteJobOrderRecord filterArgs={filterArgs} printerCombo={printerCombo} />} | |||||
| {tabIndex === 2 && <JobPickExecutionsecondscan filterArgs={filterArgs} />} | {tabIndex === 2 && <JobPickExecutionsecondscan filterArgs={filterArgs} />} | ||||
| {/* {tabIndex === 3 && <FInishedJobOrderRecord filterArgs={filterArgs} />} */} | {/* {tabIndex === 3 && <FInishedJobOrderRecord filterArgs={filterArgs} />} */} | ||||
| </Box> | </Box> | ||||
| @@ -101,7 +101,7 @@ interface LotDetail { | |||||
| uomDesc: string; | uomDesc: string; | ||||
| } | } | ||||
| const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs ,printerCombo=[]}) => { | |||||
| const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs ,printerCombo}) => { | |||||
| const { t } = useTranslation("jo"); | const { t } = useTranslation("jo"); | ||||
| const router = useRouter(); | const router = useRouter(); | ||||
| const { data: session } = useSession() as { data: SessionWithTokens | null }; | const { data: session } = useSession() as { data: SessionWithTokens | null }; | ||||
| @@ -131,6 +131,7 @@ const CompleteJobOrderRecord: React.FC<Props> = ({ filterArgs ,printerCombo=[]}) | |||||
| }; | }; | ||||
| const availablePrinters = useMemo(() => { | const availablePrinters = useMemo(() => { | ||||
| if (printerCombo.length === 0) { | if (printerCombo.length === 0) { | ||||
| console.log("No printers available, using default demo printer"); | |||||
| return [defaultDemoPrinter]; | return [defaultDemoPrinter]; | ||||
| } | } | ||||
| return printerCombo; | return printerCombo; | ||||
| @@ -221,10 +221,13 @@ const handleRelease = useCallback(() => { | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={6}> | <Grid item xs={6}> | ||||
| <TextField | <TextField | ||||
| label={t("Is Dark | Dense | Float")} | |||||
| label={t("Is Dark | Dense | Float| Scrap Rate| Allergic Substance")} | |||||
| fullWidth | fullWidth | ||||
| disabled={true} | disabled={true} | ||||
| value={processData?.isDark + " | " + processData?.isDense + " | " + processData?.isFloat || ""} | |||||
| value={processData?.isDark + " | " + processData?.isDense + " | " + processData?.isFloat + " | " | |||||
| //+ processData?.scrapRate + " | " + processData?.allergicSubstance | |||||
| + " " + " | " + " " | |||||
| || ""} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| @@ -276,7 +276,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||||
| </TableRow> | </TableRow> | ||||
| {/* By-product */} | {/* By-product */} | ||||
| {/* | |||||
| <TableRow> | <TableRow> | ||||
| <TableCell> | <TableCell> | ||||
| <Typography fontWeight={500}>{t("By-product")}</Typography> | <Typography fontWeight={500}>{t("By-product")}</Typography> | ||||
| @@ -293,7 +293,7 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||||
| <Typography>{lineDetail.byproductUom || "-"}</Typography> | <Typography>{lineDetail.byproductUom || "-"}</Typography> | ||||
| </TableCell> | </TableCell> | ||||
| </TableRow> | </TableRow> | ||||
| */} | |||||
| {/* Defect */} | {/* Defect */} | ||||
| <TableRow sx={{ bgcolor: 'warning.50' }}> | <TableRow sx={{ bgcolor: 'warning.50' }}> | ||||
| @@ -398,9 +398,10 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||||
| <Table size="small"> | <Table size="small"> | ||||
| <TableHead> | <TableHead> | ||||
| <TableRow> | <TableRow> | ||||
| <TableCell width="30%">{t("Type")}</TableCell> | |||||
| <TableCell width="35%">{t("Quantity")}</TableCell> | |||||
| <TableCell width="35%">{t("Unit")}</TableCell> | |||||
| <TableCell width="25%" align="center">{t("Type")}</TableCell> | |||||
| <TableCell width="25%" align="center">{t("Quantity")}</TableCell> | |||||
| <TableCell width="25%" align="center">{t("Unit")}</TableCell> | |||||
| <TableCell width="25%" align="center">{t(" ")}</TableCell> | |||||
| </TableRow> | </TableRow> | ||||
| </TableHead> | </TableHead> | ||||
| <TableBody> | <TableBody> | ||||
| @@ -432,8 +433,13 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||||
| })} | })} | ||||
| /> | /> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell> | |||||
| <Typography fontSize={15} align="center"> <strong>{t("Description")}</strong></Typography> | |||||
| </TableCell> | |||||
| </TableRow> | </TableRow> | ||||
| {/* byproduct */} | {/* byproduct */} | ||||
| {/* | |||||
| <TableRow> | <TableRow> | ||||
| <TableCell> | <TableCell> | ||||
| <Stack> | <Stack> | ||||
| @@ -464,11 +470,11 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||||
| /> | /> | ||||
| </TableCell> | </TableCell> | ||||
| </TableRow> | </TableRow> | ||||
| {/* defect */} | |||||
| */} | |||||
| {/* defect 1 */} | |||||
| <TableRow sx={{ bgcolor: 'warning.50' }}> | <TableRow sx={{ bgcolor: 'warning.50' }}> | ||||
| <TableCell> | <TableCell> | ||||
| <Typography fontWeight={500} color="warning.dark">{t("Defect")}</Typography> | |||||
| <Typography fontWeight={500} color="warning.dark">{t("Defect")}{t("(1)")}</Typography> | |||||
| </TableCell> | </TableCell> | ||||
| <TableCell> | <TableCell> | ||||
| <TextField | <TextField | ||||
| @@ -493,8 +499,98 @@ const ProductionProcessStepExecution: React.FC<ProductionProcessStepExecutionPro | |||||
| })} | })} | ||||
| /> | /> | ||||
| </TableCell> | </TableCell> | ||||
| <TableCell> | |||||
| <TextField | |||||
| fullWidth | |||||
| size="small" | |||||
| //value={outputData.defectUom} | |||||
| onChange={(e) => setOutputData({ | |||||
| ...outputData, | |||||
| defectUom: e.target.value | |||||
| })} | |||||
| /> | |||||
| </TableCell> | |||||
| </TableRow> | |||||
| {/* defect 2 */} | |||||
| <TableRow sx={{ bgcolor: 'warning.50' }}> | |||||
| <TableCell> | |||||
| <Typography fontWeight={500} color="warning.dark">{t("Defect")}{t("(2)")}</Typography> | |||||
| </TableCell> | |||||
| <TableCell> | |||||
| <TextField | |||||
| type="number" | |||||
| fullWidth | |||||
| size="small" | |||||
| value={outputData.defectQty} | |||||
| onChange={(e) => setOutputData({ | |||||
| ...outputData, | |||||
| defectQty: parseInt(e.target.value) || 0 | |||||
| })} | |||||
| /> | |||||
| </TableCell> | |||||
| <TableCell> | |||||
| <TextField | |||||
| fullWidth | |||||
| size="small" | |||||
| value={outputData.defectUom} | |||||
| onChange={(e) => setOutputData({ | |||||
| ...outputData, | |||||
| defectUom: e.target.value | |||||
| })} | |||||
| /> | |||||
| </TableCell> | |||||
| <TableCell> | |||||
| <TextField | |||||
| fullWidth | |||||
| size="small" | |||||
| //value={outputData.defectUom} | |||||
| onChange={(e) => setOutputData({ | |||||
| ...outputData, | |||||
| defectUom: e.target.value | |||||
| })} | |||||
| /> | |||||
| </TableCell> | |||||
| </TableRow> | |||||
| {/* defect 3 */} | |||||
| <TableRow sx={{ bgcolor: 'warning.50' }}> | |||||
| <TableCell> | |||||
| <Typography fontWeight={500} color="warning.dark">{t("Defect")}{t("(3)")}</Typography> | |||||
| </TableCell> | |||||
| <TableCell> | |||||
| <TextField | |||||
| type="number" | |||||
| fullWidth | |||||
| size="small" | |||||
| value={outputData.defectQty} | |||||
| onChange={(e) => setOutputData({ | |||||
| ...outputData, | |||||
| defectQty: parseInt(e.target.value) || 0 | |||||
| })} | |||||
| /> | |||||
| </TableCell> | |||||
| <TableCell> | |||||
| <TextField | |||||
| fullWidth | |||||
| size="small" | |||||
| value={outputData.defectUom} | |||||
| onChange={(e) => setOutputData({ | |||||
| ...outputData, | |||||
| defectUom: e.target.value | |||||
| })} | |||||
| /> | |||||
| </TableCell> | |||||
| <TableCell> | |||||
| <TextField | |||||
| fullWidth | |||||
| size="small" | |||||
| //value={outputData.defectUom} | |||||
| onChange={(e) => setOutputData({ | |||||
| ...outputData, | |||||
| defectUom: e.target.value | |||||
| })} | |||||
| /> | |||||
| </TableCell> | |||||
| </TableRow> | </TableRow> | ||||
| {/* scrap */} | {/* scrap */} | ||||
| <TableRow sx={{ bgcolor: 'error.50' }}> | <TableRow sx={{ bgcolor: 'error.50' }}> | ||||
| <TableCell> | <TableCell> | ||||
| @@ -103,6 +103,7 @@ | |||||
| "Stop Scan": "停止掃碼", | "Stop Scan": "停止掃碼", | ||||
| "Scan Result": "掃碼結果", | "Scan Result": "掃碼結果", | ||||
| "Expiry Date": "有效期", | "Expiry Date": "有效期", | ||||
| "Is Dark | Dense | Float| Scrap Rate| Allergic Substance": "顔色深淺度 | 濃淡 | 浮沉 | 損耗率 | 過敏原", | |||||
| "Pick Order Code": "提料單編號", | "Pick Order Code": "提料單編號", | ||||
| "Target Date": "需求日期", | "Target Date": "需求日期", | ||||
| "Lot Required Pick Qty": "批號需求數量", | "Lot Required Pick Qty": "批號需求數量", | ||||
| @@ -116,10 +117,10 @@ | |||||
| "By-product": "副產品", | "By-product": "副產品", | ||||
| "Complete Step": "完成步驟", | "Complete Step": "完成步驟", | ||||
| "Defect": "缺陷", | |||||
| "Output from Process": "流程輸出", | |||||
| "Defect": "不良品", | |||||
| "Output from Process": "工序產出", | |||||
| "Quantity": "數量", | "Quantity": "數量", | ||||
| "Scrap": "廢料", | |||||
| "Scrap": "損耗", | |||||
| "Unit": "單位", | "Unit": "單位", | ||||
| "Back to List": "返回列表", | "Back to List": "返回列表", | ||||
| "Production Output Data Entry": "生產輸出數據輸入", | "Production Output Data Entry": "生產輸出數據輸入", | ||||
| @@ -166,7 +167,7 @@ | |||||
| "View": "查看", | "View": "查看", | ||||
| "Back": "返回", | "Back": "返回", | ||||
| "BoM Material": "物料清單", | "BoM Material": "物料清單", | ||||
| "Is Dark | Dense | Float": "顔色深淺度 | 濃淡 | 浮沉", | |||||
| "Is Dark | Dense | Float | Scrap Rate | Allergic Substance": "顔色深淺度 | 濃淡 | 浮沉 | 損耗率 | 過敏原", | |||||
| "Item Code": "物料編號", | "Item Code": "物料編號", | ||||
| "Item Name": "物料名稱", | "Item Name": "物料名稱", | ||||
| "Job Order Info": "工單信息", | "Job Order Info": "工單信息", | ||||