| @@ -1,4 +1,4 @@ | |||||
| import React, { useState } from "react"; | |||||
| import React, { createContext, useContext, useState, useCallback, Dispatch, SetStateAction } from "react"; | |||||
| import { | import { | ||||
| Card, | Card, | ||||
| CardHeader, | CardHeader, | ||||
| @@ -7,6 +7,7 @@ import { | |||||
| Collapse, | Collapse, | ||||
| Checkbox, | Checkbox, | ||||
| Box, | Box, | ||||
| FormControlLabel, | |||||
| } from "@mui/material"; | } from "@mui/material"; | ||||
| import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; | import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; | ||||
| import ExpandLessIcon from "@mui/icons-material/ExpandLess"; | import ExpandLessIcon from "@mui/icons-material/ExpandLess"; | ||||
| @@ -18,6 +19,19 @@ interface CollapsibleCardProps { | |||||
| showFilter?: boolean; | showFilter?: boolean; | ||||
| filterText?: string; | filterText?: string; | ||||
| } | } | ||||
| interface CardFilterContextType { | |||||
| filter: boolean; | |||||
| onFilterChange: (checked: boolean) => void; | |||||
| filterText: string; | |||||
| setOnFilterChange: (override: () => void) => void; | |||||
| } | |||||
| export const CardFilterContext = createContext<CardFilterContextType>({ | |||||
| filter: false, | |||||
| onFilterChange: (checked: boolean) => {}, | |||||
| filterText: "FilterText", | |||||
| setOnFilterChange: () => {}, //Not working yet | |||||
| }); | |||||
| const CollapsibleCard: React.FC<CollapsibleCardProps> = ({ | const CollapsibleCard: React.FC<CollapsibleCardProps> = ({ | ||||
| title, | title, | ||||
| @@ -28,38 +42,51 @@ const CollapsibleCard: React.FC<CollapsibleCardProps> = ({ | |||||
| }) => { | }) => { | ||||
| const [filter, setFilter] = useState(false); | const [filter, setFilter] = useState(false); | ||||
| const [open, setOpen] = useState(defaultOpen); | |||||
| const [onFilterChange, setOnFilterChange] = useState<() => void>(); | |||||
| const onFilterChange = (bool : boolean) => { | |||||
| setFilter(bool); | |||||
| const handleFilterChange = useCallback((checked : boolean) => { | |||||
| if (onFilterChange) { | |||||
| onFilterChange(); | |||||
| } | |||||
| setFilter(checked); | |||||
| setOpen(true); | setOpen(true); | ||||
| } | |||||
| const [open, setOpen] = useState(defaultOpen); | |||||
| }, [onFilterChange]); | |||||
| return ( | return ( | ||||
| <Card> | |||||
| <CardHeader | |||||
| title={title} | |||||
| action={ | |||||
| <Box display="flex" justifyContent="flex-end" alignItems="center" gap={1}> | |||||
| {showFilter && ( | |||||
| <> | |||||
| <Checkbox | |||||
| sx={{textAlign: "left"}} | |||||
| checked={filter} | |||||
| onChange={(e) => {onFilterChange(e.target.checked);}} | |||||
| // disabled={!isEmpty(pickOrder.consoCode)} | |||||
| /> <span style={{paddingRight: 20}}>{filterText}</span> | |||||
| </>)} | |||||
| <IconButton onClick={() => setOpen((v) => !v)}> | |||||
| {open ? <ExpandLessIcon /> : <ExpandMoreIcon />} | |||||
| </IconButton> | |||||
| </Box> | |||||
| } | |||||
| /> | |||||
| <Collapse in={open}> | |||||
| <CardContent>{children}</CardContent> | |||||
| </Collapse> | |||||
| </Card> | |||||
| <CardFilterContext.Provider value={{ | |||||
| filter, onFilterChange: handleFilterChange, filterText, setOnFilterChange | |||||
| }}> | |||||
| <Card> | |||||
| <CardHeader | |||||
| title={title} | |||||
| action={ | |||||
| <Box display="flex" justifyContent="flex-end" alignItems="center" gap={1}> | |||||
| {showFilter && ( | |||||
| <> | |||||
| <FormControlLabel | |||||
| control={ | |||||
| <Checkbox | |||||
| checked={filter} | |||||
| onChange={(e) => handleFilterChange(e.target.checked)} | |||||
| /> | |||||
| } | |||||
| label={filterText} // Use filterText as the label | |||||
| sx={{ marginRight: 2 }} // Optional: Adjust spacing | |||||
| /> | |||||
| </>)} | |||||
| <IconButton onClick={() => setOpen((v) => !v)}> | |||||
| {open ? <ExpandLessIcon /> : <ExpandMoreIcon />} | |||||
| </IconButton> | |||||
| </Box> | |||||
| } | |||||
| /> | |||||
| <Collapse in={open}> | |||||
| <CardContent>{children}</CardContent> | |||||
| </Collapse> | |||||
| </Card> | |||||
| </CardFilterContext.Provider> | |||||
| ); | ); | ||||
| }; | }; | ||||
| @@ -46,6 +46,8 @@ const DashboardPage: React.FC<Props> = ({ | |||||
| <CollapsibleCard | <CollapsibleCard | ||||
| title={`${t("Responsible Escalation List")} (${t("pending")} : ${ | title={`${t("Responsible Escalation List")} (${t("pending")} : ${ | ||||
| getPendingLog().length > 0 ? getPendingLog().length : t("No")})`} | getPendingLog().length > 0 ? getPendingLog().length : t("No")})`} | ||||
| showFilter={true} | |||||
| filterText={t("show completed logs")} | |||||
| // defaultOpen={getPendingLog().length > 0} // TODO Fix default not opening | // defaultOpen={getPendingLog().length > 0} // TODO Fix default not opening | ||||
| > | > | ||||
| <CardContent> | <CardContent> | ||||
| @@ -2,13 +2,14 @@ | |||||
| import { Box, Card, CardActionArea, CardContent, CardHeader, Grid, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from "@mui/material"; | import { Box, Card, CardActionArea, CardContent, CardHeader, Grid, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography } from "@mui/material"; | ||||
| import { useRouter } from "next/navigation"; | import { useRouter } from "next/navigation"; | ||||
| import { useCallback, useMemo, useState } from "react"; | |||||
| import { useCallback, useContext, useEffect, useMemo, useState } from "react"; | |||||
| import { usePathname } from "next/navigation"; | import { usePathname } from "next/navigation"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { EscalationResult } from "@/app/api/escalation"; | import { EscalationResult } from "@/app/api/escalation"; | ||||
| import { Column } from "@/components/SearchResults"; | import { Column } from "@/components/SearchResults"; | ||||
| import SearchResults from "@/components/SearchResults/SearchResults"; | import SearchResults from "@/components/SearchResults/SearchResults"; | ||||
| import { arrayToDateString, arrayToDateTimeString } from "@/app/utils/formatUtil"; | import { arrayToDateString, arrayToDateTimeString } from "@/app/utils/formatUtil"; | ||||
| import { CardFilterContext } from "@/components/CollapsibleCard/CollapsibleCard"; | |||||
| export type IQCItems = { | export type IQCItems = { | ||||
| id: number; | id: number; | ||||
| @@ -36,6 +37,20 @@ const EscalationLogTable: React.FC<Props> = ({ | |||||
| const router = useRouter(); | const router = useRouter(); | ||||
| const [selectedId, setSelectedId] = useState<number | null>(null); | const [selectedId, setSelectedId] = useState<number | null>(null); | ||||
| const [escalationLogs, setEscalationLogs] = useState<EscalationResult[]>([]); | |||||
| const useCardFilter = useContext(CardFilterContext); | |||||
| const showCompleted = useCardFilter.filter; | |||||
| useEffect(() => { | |||||
| if (showCompleted) { | |||||
| setEscalationLogs(items); | |||||
| } else { | |||||
| const filteredEscLog = items.filter(log => log.status == "pending"); | |||||
| setEscalationLogs(filteredEscLog); | |||||
| } | |||||
| }, [showCompleted, items]) | |||||
| const navigateTo = useCallback( | const navigateTo = useCallback( | ||||
| (item: EscalationResult) => { | (item: EscalationResult) => { | ||||
| setSelectedId(item.id); | setSelectedId(item.id); | ||||
| @@ -237,7 +252,7 @@ const EscalationLogTable: React.FC<Props> = ({ | |||||
| return ( | return ( | ||||
| <SearchResults | <SearchResults | ||||
| onRowClick={onRowClick} | onRowClick={onRowClick} | ||||
| items={items} | |||||
| items={escalationLogs} | |||||
| columns={getColumnByType(type)} | columns={getColumnByType(type)} | ||||
| isAutoPaging={false} | isAutoPaging={false} | ||||
| /> | /> | ||||
| @@ -443,7 +443,7 @@ const closeNewModal = useCallback(() => { | |||||
| const status = sil?.status?.toLowerCase(); | const status = sil?.status?.toLowerCase(); | ||||
| let btnSx = {label:"", color:""}; | let btnSx = {label:"", color:""}; | ||||
| switch (status) { | switch (status) { | ||||
| case "received": btnSx = {label: t("putaway processing"), color:"secondary.main"}; break; | |||||
| case "received": btnSx = {label: t("view putaway"), color:"secondary.main"}; break; | |||||
| case "escalated": if (sessionToken?.id == sil?.handlerId) { | case "escalated": if (sessionToken?.id == sil?.handlerId) { | ||||
| btnSx = {label: t("escalation processing"), color:"warning.main"}; | btnSx = {label: t("escalation processing"), color:"warning.main"}; | ||||
| break;} | break;} | ||||
| @@ -198,56 +198,6 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| [], | [], | ||||
| ); | ); | ||||
| const onOpenScanner = useCallback(() => { | |||||
| setOpenScanner(true); | |||||
| }, []); | |||||
| const onCloseScanner = useCallback(() => { | |||||
| setOpenScanner(false); | |||||
| }, []); | |||||
| const scannerConfig = useMemo<ScannerConfig>( | |||||
| () => ({ | |||||
| onUpdate: (err, result) => { | |||||
| console.log(result); | |||||
| console.log(Boolean(result)); | |||||
| if (result) { | |||||
| const data: QrCodeInfo = JSON.parse(result.getText()); | |||||
| console.log(data); | |||||
| if (data.warehouseId) { | |||||
| console.log(data.warehouseId); | |||||
| setWarehouseId(data.warehouseId); | |||||
| onCloseScanner(); | |||||
| } | |||||
| } else return; | |||||
| }, | |||||
| }), | |||||
| [onCloseScanner], | |||||
| ); | |||||
| // QR Code Scanner | |||||
| const scanner = useQrCodeScannerContext(); | |||||
| useEffect(() => { | |||||
| if (isOpenScanner) { | |||||
| scanner.startScan(); | |||||
| } else if (!isOpenScanner) { | |||||
| scanner.stopScan(); | |||||
| } | |||||
| }, [isOpenScanner]); | |||||
| useEffect(() => { | |||||
| if (scanner.values.length > 0) { | |||||
| console.log(scanner.values[0]); | |||||
| const data: QrCodeInfo = JSON.parse(scanner.values[0]); | |||||
| console.log(data); | |||||
| if (data.warehouseId) { | |||||
| console.log(data.warehouseId); | |||||
| setWarehouseId(data.warehouseId); | |||||
| onCloseScanner(); | |||||
| } | |||||
| scanner.resetScan(); | |||||
| } | |||||
| }, [scanner.values]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| setValue("status", "received"); | setValue("status", "received"); | ||||
| // setValue("status", "completed"); | // setValue("status", "completed"); | ||||
| @@ -536,7 +486,7 @@ const PutAwayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled, setRowM | |||||
| {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | {/* <QrCode content={qrContent} sx={{ width: 200, height: 200 }} /> */} | ||||
| <InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | <InputDataGrid<PutAwayInput, PutAwayLine, EntryError> | ||||
| apiRef={apiRef} | apiRef={apiRef} | ||||
| checkboxSelection={true} | |||||
| checkboxSelection={false} | |||||
| _formKey={"putAwayLines"} | _formKey={"putAwayLines"} | ||||
| columns={columns} | columns={columns} | ||||
| validateRow={validation} | validateRow={validation} | ||||
| @@ -239,13 +239,19 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||||
| { | { | ||||
| field: "code", | field: "code", | ||||
| headerName: t("qcItem"), | headerName: t("qcItem"), | ||||
| wrapText: true, | |||||
| flex: 2, | flex: 2, | ||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| const index = params.api.getRowIndexRelativeToVisibleRows(params.id) + 1; | const index = params.api.getRowIndexRelativeToVisibleRows(params.id) + 1; | ||||
| return ( | return ( | ||||
| <Box> | |||||
| <Box | |||||
| sx={{ | |||||
| lineHeight: 1.5, | |||||
| padding: "4px", | |||||
| }} | |||||
| > | |||||
| <b>{`${index}. ${params.value}`}</b><br/> | <b>{`${index}. ${params.value}`}</b><br/> | ||||
| {params.row.name}<br/> | |||||
| {params.row.name} | |||||
| </Box> | </Box> | ||||
| )}, | )}, | ||||
| }, | }, | ||||
| @@ -433,7 +439,7 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||||
| const setDefaultQcDecision = (status : string | undefined) => { | const setDefaultQcDecision = (status : string | undefined) => { | ||||
| const param = status?.toLowerCase(); | const param = status?.toLowerCase(); | ||||
| if (param !== undefined && param !== null) { | if (param !== undefined && param !== null) { | ||||
| if (param == "completed" || param == "partially_completed") { | |||||
| if (param == "received" || param == "completed" || param == "partially_completed") { | |||||
| return 1; | return 1; | ||||
| } else if (param == "rejected") { | } else if (param == "rejected") { | ||||
| return 2; | return 2; | ||||
| @@ -456,6 +462,13 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||||
| // return row.id || `${row.name}-${Math.random().toString(36).substr(2, 9)}`; | // return row.id || `${row.name}-${Math.random().toString(36).substr(2, 9)}`; | ||||
| }; | }; | ||||
| const getRowHeight = (row :any) => { // Not used? | |||||
| console.log("row", row); | |||||
| if (!row.model.name) { | |||||
| return (row.model.name.length ?? 10) * 1.2 + 30; | |||||
| } else { return 60} | |||||
| }; | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <Grid container justifyContent="flex-start" alignItems="flex-start"> | <Grid container justifyContent="flex-start" alignItems="flex-start"> | ||||
| @@ -504,8 +517,10 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||||
| rows={qcResult} | rows={qcResult} | ||||
| // rows={qcResult && qcResult.length > 0 ? qcResult : qcItems} | // rows={qcResult && qcResult.length > 0 ? qcResult : qcItems} | ||||
| // rows={disabled? qcResult:qcItems} | // rows={disabled? qcResult:qcItems} | ||||
| autoHeight | |||||
| // autoHeight | |||||
| sortModel={[]} | sortModel={[]} | ||||
| // getRowHeight={getRowHeight} | |||||
| getRowHeight={() => 'auto'} | |||||
| getRowId={getRowId} | getRowId={getRowId} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| @@ -548,17 +563,13 @@ const QcComponent: React.FC<Props> = ({ itemDetail, disabled = false }) => { | |||||
| sortModel={[]} | sortModel={[]} | ||||
| /> | /> | ||||
| </CollapsibleCard> | </CollapsibleCard> | ||||
| {/* <StyledDataGrid | |||||
| rows={escalationHistory} | |||||
| columns={columns} | |||||
| onRowSelectionModelChange={(newRowSelectionModel) => { | |||||
| setRowSelectionModel(newRowSelectionModel); | |||||
| }} | |||||
| /> */} | |||||
| </Grid> | </Grid> | ||||
| </> | </> | ||||
| )} | )} | ||||
| <Grid item xs={12}> | <Grid item xs={12}> | ||||
| <Typography variant="h6" display="block" marginBlockEnd={1}> | |||||
| {t("Qc Decision")} | |||||
| </Typography> | |||||
| <FormControl> | <FormControl> | ||||
| <Controller | <Controller | ||||
| name="qcDecision" | name="qcDecision" | ||||
| @@ -6,10 +6,14 @@ import { | |||||
| Autocomplete, | Autocomplete, | ||||
| Box, | Box, | ||||
| Button, | Button, | ||||
| Divider, | |||||
| Grid, | Grid, | ||||
| Modal, | Modal, | ||||
| ModalProps, | ModalProps, | ||||
| Stack, | Stack, | ||||
| Tab, | |||||
| Tabs, | |||||
| TabsProps, | |||||
| TextField, | TextField, | ||||
| Typography, | Typography, | ||||
| } from "@mui/material"; | } from "@mui/material"; | ||||
| @@ -34,6 +38,7 @@ import { GridRowModesModel } from "@mui/x-data-grid"; | |||||
| import { isEmpty } from "lodash"; | import { isEmpty } from "lodash"; | ||||
| import { EscalationCombo } from "@/app/api/user"; | import { EscalationCombo } from "@/app/api/user"; | ||||
| import { truncateSync } from "fs"; | import { truncateSync } from "fs"; | ||||
| import PutAwayGrid from "./PutAwayGrid"; | |||||
| const style = { | const style = { | ||||
| @@ -47,7 +52,7 @@ const style = { | |||||
| pb: 10, | pb: 10, | ||||
| display: "block", | display: "block", | ||||
| width: { xs: "90%", sm: "90%", md: "90%" }, | width: { xs: "90%", sm: "90%", md: "90%" }, | ||||
| // height: { xs: "60%", sm: "60%", md: "60%" }, | |||||
| height: { xs: "90%", sm: "90%", md: "90%" }, | |||||
| }; | }; | ||||
| interface CommonProps extends Omit<ModalProps, "children"> { | interface CommonProps extends Omit<ModalProps, "children"> { | ||||
| // setRows: Dispatch<SetStateAction<PurchaseOrderLine[]>>; | // setRows: Dispatch<SetStateAction<PurchaseOrderLine[]>>; | ||||
| @@ -95,6 +100,14 @@ const PoQcStockInModalVer2: React.FC<Props> = ({ | |||||
| // Select Printer | // Select Printer | ||||
| const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]); | const [selectedPrinter, setSelectedPrinter] = useState(printerCombo[0]); | ||||
| const [tabIndex, setTabIndex] = useState(0); | |||||
| const handleTabChange = useCallback<NonNullable<TabsProps["onChange"]>>( | |||||
| (_e, newValue) => { | |||||
| setTabIndex(newValue); | |||||
| }, | |||||
| [], | |||||
| ); | |||||
| const defaultNewValue = useMemo(() => { | const defaultNewValue = useMemo(() => { | ||||
| return ( | return ( | ||||
| @@ -150,6 +163,8 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| setViewOnly(isViewOnly) | setViewOnly(isViewOnly) | ||||
| } | } | ||||
| console.log("Modal ItemDetail updated:", itemDetail); | console.log("Modal ItemDetail updated:", itemDetail); | ||||
| console.log("%c SHOW PUTAWAY? ", "color:lime", showPutaway); | |||||
| if (showPutaway) { setTabIndex(1); } else { setTabIndex(0); } | |||||
| }, [itemDetail]); | }, [itemDetail]); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| @@ -158,8 +173,7 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| }) | }) | ||||
| setQcItems(dummyQCData); | setQcItems(dummyQCData); | ||||
| setOpenPutaway(isPutaway); | |||||
| // setOpenPutaway(isPutaway); | |||||
| }, [open]) | }, [open]) | ||||
| const [openPutaway, setOpenPutaway] = useState(false); | const [openPutaway, setOpenPutaway] = useState(false); | ||||
| @@ -322,7 +336,9 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| if (qcData.qcAccept) { | if (qcData.qcAccept) { | ||||
| // submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?", | // submitDialogWithWarning(onOpenPutaway, t, {title:"Save success, confirm to proceed?", | ||||
| // confirmButtonText: t("confirm putaway"), html: ""}); | // confirmButtonText: t("confirm putaway"), html: ""}); | ||||
| onOpenPutaway(); | |||||
| // onOpenPutaway(); | |||||
| closeHandler({}, "backdropClick"); | |||||
| // setTabIndex(1); // Need to go Putaway tab? | |||||
| } else { | } else { | ||||
| closeHandler({}, "backdropClick"); | closeHandler({}, "backdropClick"); | ||||
| } | } | ||||
| @@ -463,6 +479,11 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| const acceptQty = formProps.watch("acceptedQty") | const acceptQty = formProps.watch("acceptedQty") | ||||
| const showPutaway = useMemo(() => { | |||||
| const status = itemDetail.status; | |||||
| return status !== "pending" && status !== "escalated" && status !== "rejected"; | |||||
| }, [itemDetail]); | |||||
| const checkQcIsPassed = useCallback((qcItems: PurchaseQcResult[]) => { | const checkQcIsPassed = useCallback((qcItems: PurchaseQcResult[]) => { | ||||
| const isPassed = qcItems.every((qc) => qc.qcPassed); | const isPassed = qcItems.every((qc) => qc.qcPassed); | ||||
| console.log(isPassed) | console.log(isPassed) | ||||
| @@ -492,88 +513,36 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| overflowY: "auto", | overflowY: "auto", | ||||
| marginLeft: 3, | marginLeft: 3, | ||||
| marginRight: 3, | marginRight: 3, | ||||
| // overflow: "hidden", | |||||
| }} | }} | ||||
| > | > | ||||
| {openPutaway ? ( | |||||
| <Box | |||||
| component="form" | |||||
| onSubmit={formProps.handleSubmit(onSubmitPutaway)} | |||||
| <Box sx={{ position: 'sticky', top: 0, bgcolor: 'background.paper', | |||||
| zIndex: 5, borderBottom: 2, borderColor: 'divider', width: "100%" }}> | |||||
| <Tabs | |||||
| value={tabIndex} | |||||
| onChange={handleTabChange} | |||||
| variant="scrollable" | |||||
| > | > | ||||
| <PutAwayForm | |||||
| itemDetail={itemDetail} | |||||
| warehouse={warehouse!} | |||||
| disabled={viewOnly} | |||||
| setRowModesModel={setPafRowModesModel} | |||||
| setRowSelectionModel={setPafRowSelectionModel} | |||||
| /> | |||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
| <Autocomplete | |||||
| disableClearable | |||||
| options={printerCombo} | |||||
| defaultValue={selectedPrinter} | |||||
| onChange={(event, value) => { | |||||
| setSelectedPrinter(value) | |||||
| }} | |||||
| renderInput={(params) => ( | |||||
| <TextField | |||||
| {...params} | |||||
| variant="outlined" | |||||
| label={t("Printer")} | |||||
| sx={{ width: 300}} | |||||
| /> | |||||
| )} | |||||
| /> | |||||
| <Button | |||||
| id="printButton" | |||||
| type="button" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={handlePrint} | |||||
| disabled={isPrinting || printerCombo.length <= 0 || pafSubmitDisable} | |||||
| > | |||||
| {isPrinting ? t("Printing") : t("print")} | |||||
| </Button> | |||||
| <Button | |||||
| id="putawaySubmit" | |||||
| type="submit" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={formProps.handleSubmit(onSubmitPutaway)} | |||||
| disabled={pafSubmitDisable} | |||||
| > | |||||
| {t("confirm putaway")} | |||||
| </Button> | |||||
| </Stack> | |||||
| </Box> | |||||
| ) : ( | |||||
| <> | |||||
| <Grid | |||||
| container | |||||
| justifyContent="flex-start" | |||||
| alignItems="flex-start" | |||||
| > | |||||
| <Grid item xs={12}> | |||||
| <Typography variant="h6" display="block" marginBlockEnd={1}> | |||||
| {t("qc processing")} | |||||
| </Typography> | |||||
| </Grid> | |||||
| <Grid item xs={12}> | |||||
| <StockInForm itemDetail={itemDetail} disabled={viewOnly} /> | |||||
| </Grid> | |||||
| <Tab label={ | |||||
| showPutaway ? t("dn and qc info") : t("qc processing") | |||||
| } iconPosition="end" /> | |||||
| {showPutaway && <Tab label={t("putaway processing")} iconPosition="end" />} | |||||
| </Tabs> | |||||
| </Box> | |||||
| <Grid | |||||
| container | |||||
| justifyContent="flex-start" | |||||
| alignItems="flex-start" | |||||
| > | |||||
| <Grid item xs={12}> | |||||
| {tabIndex === 0 && <> | |||||
| <Grid item xs={12}> | |||||
| <Typography variant="h6" display="block" marginBlockEnd={1}> | |||||
| {t("Delivery Detail")} | |||||
| </Typography> | |||||
| </Grid> | </Grid> | ||||
| {/* <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
| <Button | |||||
| id="stockInSubmit" | |||||
| type="button" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| onClick={formProps.handleSubmit(onSubmitStockIn)} | |||||
| > | |||||
| {t("submitStockIn")} | |||||
| </Button> | |||||
| </Stack> */} | |||||
| <StockInForm itemDetail={itemDetail} disabled={viewOnly || showPutaway} /> | |||||
| <Grid | <Grid | ||||
| container | container | ||||
| justifyContent="flex-start" | justifyContent="flex-start" | ||||
| @@ -582,13 +551,13 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| <QcComponent | <QcComponent | ||||
| // qc={qc!} | // qc={qc!} | ||||
| itemDetail={itemDetail} | itemDetail={itemDetail} | ||||
| disabled={viewOnly} | |||||
| disabled={viewOnly || showPutaway} | |||||
| // qcItems={qcItems} | // qcItems={qcItems} | ||||
| // setQcItems={setQcItems} | // setQcItems={setQcItems} | ||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | <Stack direction="row" justifyContent="flex-end" gap={1}> | ||||
| {!viewOnly && (<Button | |||||
| {(!viewOnly && !showPutaway) && (<Button | |||||
| id="qcSubmit" | id="qcSubmit" | ||||
| type="button" | type="button" | ||||
| variant="contained" | variant="contained" | ||||
| @@ -599,8 +568,75 @@ const [qcItems, setQcItems] = useState(dummyQCData) | |||||
| {t("confirm qc result")} | {t("confirm qc result")} | ||||
| </Button>)} | </Button>)} | ||||
| </Stack> | </Stack> | ||||
| </> | |||||
| )} | |||||
| </>} | |||||
| {tabIndex === 1 && | |||||
| <Box | |||||
| // component="form" | |||||
| // onSubmit={formProps.handleSubmit(onSubmitPutaway)} | |||||
| > | |||||
| <Grid | |||||
| container | |||||
| justifyContent="flex-start" | |||||
| alignItems="flex-start" | |||||
| > | |||||
| <PutAwayForm | |||||
| itemDetail={itemDetail} | |||||
| warehouse={warehouse!} | |||||
| disabled={viewOnly} | |||||
| setRowModesModel={setPafRowModesModel} | |||||
| setRowSelectionModel={setPafRowSelectionModel} | |||||
| /> | |||||
| {/* <PutAwayGrid | |||||
| itemDetail={itemDetail} | |||||
| warehouse={warehouse!} | |||||
| disabled={viewOnly} | |||||
| /> */} | |||||
| <Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
| <Autocomplete | |||||
| disableClearable | |||||
| options={printerCombo} | |||||
| defaultValue={selectedPrinter} | |||||
| onChange={(event, value) => { | |||||
| setSelectedPrinter(value) | |||||
| }} | |||||
| renderInput={(params) => ( | |||||
| <TextField | |||||
| {...params} | |||||
| variant="outlined" | |||||
| label={t("Printer")} | |||||
| sx={{ width: 300}} | |||||
| /> | |||||
| )} | |||||
| /> | |||||
| <Button | |||||
| id="printButton" | |||||
| type="button" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={handlePrint} | |||||
| disabled={isPrinting || printerCombo.length <= 0 || pafSubmitDisable} | |||||
| > | |||||
| {isPrinting ? t("Printing") : t("print")} | |||||
| </Button> | |||||
| {/* <Button | |||||
| id="putawaySubmit" | |||||
| type="submit" | |||||
| variant="contained" | |||||
| color="primary" | |||||
| sx={{ mt: 1 }} | |||||
| onClick={formProps.handleSubmit(onSubmitPutaway)} | |||||
| disabled={pafSubmitDisable} | |||||
| > | |||||
| {t("confirm putaway")} | |||||
| </Button> */} | |||||
| </Stack> | |||||
| </Grid> | |||||
| </Box> | |||||
| } | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Box> | </Box> | ||||
| </Modal> | </Modal> | ||||
| </FormProvider> | </FormProvider> | ||||
| @@ -54,5 +54,6 @@ | |||||
| "escalated datetime": "上報時間", | "escalated datetime": "上報時間", | ||||
| "escalateFrom": "上報同事", | "escalateFrom": "上報同事", | ||||
| "No": "無", | "No": "無", | ||||
| "Responsible Escalation List": "負責的上報列表" | |||||
| "Responsible Escalation List": "負責的上報列表", | |||||
| "show completed logs": "顯示已完成上報" | |||||
| } | } | ||||
| @@ -100,6 +100,7 @@ | |||||
| "Default Warehouse": "預設倉庫", | "Default Warehouse": "預設倉庫", | ||||
| "Select warehouse": "選擇倉庫", | "Select warehouse": "選擇倉庫", | ||||
| "Putaway Detail": "上架詳情", | "Putaway Detail": "上架詳情", | ||||
| "Delivery Detail": "來貨詳情", | |||||
| "LotNo": "批號", | "LotNo": "批號", | ||||
| "Po Code": "採購訂單編號", | "Po Code": "採購訂單編號", | ||||
| "No Warehouse": "沒有倉庫", | "No Warehouse": "沒有倉庫", | ||||
| @@ -109,7 +110,8 @@ | |||||
| "Accept submit": "接受來貨", | "Accept submit": "接受來貨", | ||||
| "qc processing": "處理來貨及品檢", | "qc processing": "處理來貨及品檢", | ||||
| "putaway processing": "處理來貨及上架", | "putaway processing": "處理來貨及上架", | ||||
| "view stockin": "查看收貨及品檢", | |||||
| "view stockin": "查看收貨詳情", | |||||
| "view putaway": "查看上架詳情", | |||||
| "putawayBtn": "上架", | "putawayBtn": "上架", | ||||
| "dnNo": "送貨單編號", | "dnNo": "送貨單編號", | ||||
| "dnDate": "送貨單日期", | "dnDate": "送貨單日期", | ||||
| @@ -144,5 +146,7 @@ | |||||
| "No Option": "沒有選項", | "No Option": "沒有選項", | ||||
| "receivedTotal": "已來貨總數", | "receivedTotal": "已來貨總數", | ||||
| "QC Record": "品檢記錄", | "QC Record": "品檢記錄", | ||||
| "value must be integer": "請輸入整數" | |||||
| "value must be integer": "請輸入整數", | |||||
| "dn and qc info": "來貨及品檢詳情", | |||||
| "Qc Decision": "品檢詳情" | |||||
| } | } | ||||