@@ -54,8 +54,7 @@ import QrCodeIcon from "@mui/icons-material/QrCode"; | |||||
import { downloadFile } from "@/app/utils/commonUtil"; | import { downloadFile } from "@/app/utils/commonUtil"; | ||||
import { fetchPoQrcode } from "@/app/api/pdf/actions"; | import { fetchPoQrcode } from "@/app/api/pdf/actions"; | ||||
import { fetchQcResult } from "@/app/api/qc/actions"; | import { fetchQcResult } from "@/app/api/qc/actions"; | ||||
import PoQcStockInModal from "./PoQcStockInModal"; | |||||
import { notifyActionSuccess } from "../Toast/Toast"; | |||||
import PoQcStockInModal from "./PoQcStockInModal" | |||||
import DoDisturbIcon from "@mui/icons-material/DoDisturb"; | import DoDisturbIcon from "@mui/icons-material/DoDisturb"; | ||||
interface ResultWithId { | interface ResultWithId { | ||||
@@ -181,7 +180,6 @@ function PoInputGrid({ | |||||
) as StockInLine[] | ) as StockInLine[] | ||||
); | ); | ||||
setBtnIsLoading(false); | setBtnIsLoading(false); | ||||
notifyActionSuccess(); | |||||
// do post directly to test | // do post directly to test | ||||
// openStartModal(); | // openStartModal(); | ||||
}, 200); | }, 200); | ||||
@@ -44,6 +44,7 @@ import ReactQrCodeScanner, { | |||||
ScannerConfig, | ScannerConfig, | ||||
} from "../ReactQrCodeScanner/ReactQrCodeScanner"; | } from "../ReactQrCodeScanner/ReactQrCodeScanner"; | ||||
import { QrCodeInfo } from "@/app/api/qrcode"; | import { QrCodeInfo } from "@/app/api/qrcode"; | ||||
import { useQcCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | |||||
interface Props { | interface Props { | ||||
itemDetail: StockInLine; | itemDetail: StockInLine; | ||||
@@ -210,6 +211,30 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
[onCloseScanner] | [onCloseScanner] | ||||
); | ); | ||||
// QR Code Scanner | |||||
const scanner = useQcCodeScanner() | |||||
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", "completed"); | setValue("status", "completed"); | ||||
}, []); | }, []); | ||||
@@ -408,7 +433,8 @@ const PutawayForm: React.FC<Props> = ({ itemDetail, warehouse, disabled }) => { | |||||
<Modal open={isOpenScanner} onClose={closeHandler}> | <Modal open={isOpenScanner} onClose={closeHandler}> | ||||
<Box sx={style}> | <Box sx={style}> | ||||
<ReactQrCodeScanner scannerConfig={scannerConfig} /> | |||||
<Typography variant="h4">{t("Please scan warehouse qr code.")}</Typography> | |||||
{/* <ReactQrCodeScanner scannerConfig={scannerConfig} /> */} | |||||
</Box> | </Box> | ||||
</Modal> | </Modal> | ||||
</Grid> | </Grid> | ||||
@@ -19,6 +19,7 @@ import { QrCodeInfo } from "@/app/api/qrcode"; | |||||
import { Check } from "@mui/icons-material"; | import { Check } from "@mui/icons-material"; | ||||
import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
import { useSearchParams } from "next/navigation"; | import { useSearchParams } from "next/navigation"; | ||||
import { useQcCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | |||||
interface Props extends Omit<ModalProps, "children"> { | interface Props extends Omit<ModalProps, "children"> { | ||||
warehouse: WarehouseResult[]; | warehouse: WarehouseResult[]; | ||||
@@ -72,6 +73,30 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||||
[] | [] | ||||
); | ); | ||||
// QR Code Scanner | |||||
const scanner = useQcCodeScanner() | |||||
useEffect(() => { | |||||
if (open && !scanner.isScanning) { | |||||
scanner.startScan() | |||||
} else if (!open && scanner.isScanning) { | |||||
scanner.stopScan() | |||||
} | |||||
}, [open]) | |||||
useEffect(() => { | |||||
if (scanner.values.length > 0 && !Boolean(itemDetail)) { | |||||
console.log(scanner.values[0]) | |||||
const data: QrCodeInfo = JSON.parse(scanner.values[0]); | |||||
console.log(data); | |||||
if (data.stockInLineId) { | |||||
console.log("still got in"); | |||||
console.log(data.stockInLineId); | |||||
setStockInLineId(data.stockInLineId); | |||||
} | |||||
scanner.resetScan() | |||||
} | |||||
}, [scanner.values]) | |||||
const [itemDetail, setItemDetail] = useState<StockInLine>(); | const [itemDetail, setItemDetail] = useState<StockInLine>(); | ||||
const [disabledSubmit, setDisabledSubmit] = useState(false); | const [disabledSubmit, setDisabledSubmit] = useState(false); | ||||
const [unavailableText, setUnavailableText] = useState<string | undefined>(undefined) | const [unavailableText, setUnavailableText] = useState<string | undefined>(undefined) | ||||
@@ -115,13 +140,13 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||||
//////////////////////// modify this mess later ////////////////////// | //////////////////////// modify this mess later ////////////////////// | ||||
const args = { | const args = { | ||||
id: itemDetail?.id, | |||||
purchaseOrderId: parseInt(params.get("id")!!), | |||||
purchaseOrderLineId: itemDetail?.purchaseOrderLineId, | |||||
itemId: itemDetail?.itemId, | |||||
acceptedQty: data.acceptedQty, | |||||
warehouseId: data.warehouseId, | |||||
// ...data, | |||||
id: itemDetail?.id, | |||||
purchaseOrderId: parseInt(params.get("id")!!), | |||||
purchaseOrderLineId: itemDetail?.purchaseOrderLineId, | |||||
itemId: itemDetail?.itemId, | |||||
acceptedQty: data.acceptedQty, | |||||
warehouseId: data.warehouseId, | |||||
// ...data, | |||||
// productionDate: productionDate, | // productionDate: productionDate, | ||||
} as StockInLineEntry & ModalFormInput; | } as StockInLineEntry & ModalFormInput; | ||||
////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||
@@ -160,28 +185,32 @@ const QrModal: React.FC<Props> = ({ open, onClose, warehouse }) => { | |||||
> | > | ||||
<Grid container xs={12}> | <Grid container xs={12}> | ||||
<Grid item xs={12}> | <Grid item xs={12}> | ||||
{itemDetail != undefined ? ( | |||||
unavailableText != undefined ? <Typography variant="h4" marginInlineEnd={2}>{unavailableText}</Typography> | |||||
: ( | |||||
<> | |||||
<PutawayForm itemDetail={itemDetail} warehouse={warehouse} disabled={false}/> | |||||
<Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
<Button | |||||
name="submit" | |||||
variant="contained" | |||||
startIcon={<Check />} | |||||
type="submit" | |||||
disabled={disabledSubmit} | |||||
> | |||||
{t("submit")} | |||||
</Button> | |||||
</Stack> | |||||
</> | |||||
{ | |||||
itemDetail != undefined ? ( | |||||
unavailableText != undefined ? <Typography variant="h4" marginInlineEnd={2}>{unavailableText}</Typography> | |||||
: ( | |||||
<> | |||||
<PutawayForm itemDetail={itemDetail} warehouse={warehouse} disabled={false} /> | |||||
<Stack direction="row" justifyContent="flex-end" gap={1}> | |||||
<Button | |||||
name="submit" | |||||
variant="contained" | |||||
startIcon={<Check />} | |||||
type="submit" | |||||
disabled={disabledSubmit} | |||||
> | |||||
{t("submit")} | |||||
</Button> | |||||
</Stack> | |||||
</> | |||||
) | |||||
) | ) | ||||
) : ( | |||||
<ReactQrCodeScanner scannerConfig={scannerConfig} /> | |||||
)} | |||||
: ( | |||||
// <ReactQrCodeScanner scannerConfig={scannerConfig} /> | |||||
<Typography variant="h4">{t("Will start binding procedure after scanning item qr code.")}</Typography> | |||||
) | |||||
} | |||||
</Grid> | </Grid> | ||||
</Grid> | </Grid> | ||||
</Box> | </Box> | ||||
@@ -0,0 +1,99 @@ | |||||
"use client"; | |||||
import { ReactNode, createContext, useCallback, useContext, useEffect, useState } from "react"; | |||||
interface QcCodeScanner { | |||||
values: string[]; | |||||
isScanning: boolean; | |||||
startScan: () => void; | |||||
stopScan: () => void; | |||||
resetScan: () => void; | |||||
} | |||||
interface QrCodeScannerProviderProps { | |||||
children: ReactNode; | |||||
} | |||||
export const QcCodeScannerContext = createContext<QcCodeScanner | undefined>(undefined) | |||||
const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({ children }) => { | |||||
const [qcCodeScannerValues, setQrCodeScannerValues] = useState<string[]>([]); | |||||
const [isScanning, setIsScanning] = useState<boolean>(false); | |||||
const [keys, setKeys] = useState<string[]>([]); | |||||
const [leftCurlyBraceCount, setLeftCurlyBraceCount] = useState<number>(0); | |||||
const [rightCurlyBraceCount, setRightCurlyBraceCount] = useState<number>(0); | |||||
const resetQrCodeScanner = useCallback(() => { | |||||
setQrCodeScannerValues(() => []) | |||||
}, []) | |||||
const startQrCodeScanner = useCallback(() => { | |||||
resetQrCodeScanner() | |||||
setIsScanning(() => true) | |||||
}, []) | |||||
const endQrCodeScanner = useCallback(() => { | |||||
setIsScanning(() => false) | |||||
}, []) | |||||
// Check the KeyDown | |||||
useEffect(() => { | |||||
if (isScanning) { | |||||
const handleKeyDown = (event: KeyboardEvent) => { | |||||
if (event.key.length === 1) { | |||||
setKeys((key) => [...key, event.key]) | |||||
} | |||||
if (event.key === "{") { | |||||
setLeftCurlyBraceCount((count) => count + 1) | |||||
} else if (event.key === "}") { | |||||
setRightCurlyBraceCount((count) => count + 1) | |||||
} | |||||
} | |||||
document.addEventListener('keydown', handleKeyDown); | |||||
return () => { | |||||
document.removeEventListener('keydown', handleKeyDown); | |||||
}; | |||||
}; | |||||
}, [isScanning]) | |||||
// Update Qr Code Scanner Values | |||||
useEffect(() => { | |||||
if (leftCurlyBraceCount !== 0 && rightCurlyBraceCount !== 0 && leftCurlyBraceCount === rightCurlyBraceCount) { | |||||
const startBrace = keys.indexOf('{'); | |||||
const endBrace = keys.lastIndexOf('}'); | |||||
setQrCodeScannerValues((value) => [...value, keys.join("").substring(startBrace, endBrace + 1)]) | |||||
console.log(keys) | |||||
console.log(qcCodeScannerValues) | |||||
// reset | |||||
setKeys(() => []) | |||||
setLeftCurlyBraceCount(() => 0) | |||||
setRightCurlyBraceCount(() => 0) | |||||
} | |||||
}, [keys, leftCurlyBraceCount, rightCurlyBraceCount]) | |||||
return ( | |||||
<QcCodeScannerContext.Provider value={{ | |||||
values: qcCodeScannerValues, | |||||
isScanning: isScanning, | |||||
startScan: startQrCodeScanner, | |||||
stopScan: endQrCodeScanner, | |||||
resetScan: resetQrCodeScanner, | |||||
}}> | |||||
{children} | |||||
</QcCodeScannerContext.Provider> | |||||
) | |||||
} | |||||
export const useQcCodeScanner = (): QcCodeScanner => { | |||||
const context = useContext(QcCodeScannerContext); | |||||
if (!context) { | |||||
throw new Error('useQcCodeScanner must be used within a QcCodeScannerProvider'); | |||||
} | |||||
return context; | |||||
}; | |||||
export default QrCodeScannerProvider; |