| @@ -36,6 +36,7 @@ import { QrCodeScanner } from "../QrCodeScannerProvider/QrCodeScannerProvider"; | |||||
| import { msg } from "../Swal/CustomAlerts"; | import { msg } from "../Swal/CustomAlerts"; | ||||
| import { PutAwayRecord } from "."; | import { PutAwayRecord } from "."; | ||||
| import FgStockInForm from "../StockIn/FgStockInForm"; | import FgStockInForm from "../StockIn/FgStockInForm"; | ||||
| import Swal from "sweetalert2"; | |||||
| interface Props extends Omit<ModalProps, "children"> { | interface Props extends Omit<ModalProps, "children"> { | ||||
| @@ -153,18 +154,22 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId | |||||
| scanner.startScan(); | scanner.startScan(); | ||||
| console.log("%c Scanning started ", "color:cyan"); | console.log("%c Scanning started ", "color:cyan"); | ||||
| }; | }; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (warehouseId > 0) { // Scanned Warehouse | if (warehouseId > 0) { // Scanned Warehouse | ||||
| if (scanner.isScanning) { | if (scanner.isScanning) { | ||||
| setIsOpenScanner(false); | setIsOpenScanner(false); | ||||
| setVerified(true); | setVerified(true); | ||||
| msg("貨倉掃瞄成功!") | |||||
| msg("貨倉掃瞄成功!"); | |||||
| scanner.resetScan(); | scanner.resetScan(); | ||||
| console.log("%c Scanner reset", "color:cyan"); | console.log("%c Scanner reset", "color:cyan"); | ||||
| } | } | ||||
| } | } | ||||
| }, [warehouseId]) | }, [warehouseId]) | ||||
| const warehouseDisplay = useMemo(() => { | |||||
| const wh = warehouse.find((w) => w.id == warehouseId) ?? warehouse.find((w) => w.id == 1); | |||||
| return <>{wh?.name} <br/> [{wh?.code}]</>; | |||||
| }, [warehouse, warehouseId, verified]); | |||||
| // useEffect(() => { // Restart scanner for changing warehouse | // useEffect(() => { // Restart scanner for changing warehouse | ||||
| // if (warehouseId > 0) { | // if (warehouseId > 0) { | ||||
| @@ -379,20 +384,21 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId | |||||
| </Grid> | </Grid> | ||||
| <Grid container> | <Grid container> | ||||
| <Typography variant="h4" sx={{ fontWeight: 'bold', color: 'black' }} noWrap> | <Typography variant="h4" sx={{ fontWeight: 'bold', color: 'black' }} noWrap> | ||||
| {warehouseId > 0 ? `${warehouse.find((w) => w.id == warehouseId)?.name}` | |||||
| : `${warehouse.find((w) => w.id == 1)?.name} (建議)`} | |||||
| {warehouseDisplay} <span style={{fontSize: "45px", color: "black"}}>{verified ? "" : `(建議)`}</span> | |||||
| </Typography> | </Typography> | ||||
| </Grid> | </Grid> | ||||
| </Box> | </Box> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={3}> | <Grid item xs={3}> | ||||
| <Box sx={{ height: '100%', p: 2, textAlign: 'center' }}> | |||||
| <Box sx={{ height: '100%', p: 2, textAlign: 'center', display: "flex", | |||||
| flexDirection: "column", justifyContent: "center", }}> | |||||
| <TextField | <TextField | ||||
| type="number" // TODO fix the "e" input | |||||
| type="number" | |||||
| label={t("putQty")} | label={t("putQty")} | ||||
| fullWidth | fullWidth | ||||
| sx={{ | sx={{ | ||||
| flex: 1, | |||||
| "& .MuiInputBase-input": { | "& .MuiInputBase-input": { | ||||
| padding: "20px 14px 5px", | padding: "20px 14px 5px", | ||||
| fontSize: "50px", | fontSize: "50px", | ||||
| @@ -403,7 +409,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId | |||||
| borderColor: "black", | borderColor: "black", | ||||
| }, | }, | ||||
| "& .MuiInputLabel-root": { | "& .MuiInputLabel-root": { | ||||
| fontSize: "30px", | |||||
| fontSize: 30, | |||||
| top: "-5px", | top: "-5px", | ||||
| color: "black", | color: "black", | ||||
| }, | }, | ||||
| @@ -30,7 +30,7 @@ type Props = { | |||||
| warehouse : WarehouseResult[]; | warehouse : WarehouseResult[]; | ||||
| }; | }; | ||||
| type ScanStatusType = "pending" | "rescan"; | |||||
| type ScanStatusType = "pending" | "scanning" | "retry"; | |||||
| const PutAwayScan: React.FC<Props> = ({ warehouse }) => { | const PutAwayScan: React.FC<Props> = ({ warehouse }) => { | ||||
| const { t } = useTranslation("putAway"); | const { t } = useTranslation("putAway"); | ||||
| @@ -54,7 +54,7 @@ const PutAwayScan: React.FC<Props> = ({ warehouse }) => { | |||||
| const resetScan = (error : string = "") => { | const resetScan = (error : string = "") => { | ||||
| if (error !== "") { | if (error !== "") { | ||||
| console.log("%c Scan failed, error: ", "color:red", error); | console.log("%c Scan failed, error: ", "color:red", error); | ||||
| setScanDisplay("rescan"); | |||||
| setScanDisplay("retry"); | |||||
| } else { | } else { | ||||
| console.log("%c Scan reset", "color:red"); | console.log("%c Scan reset", "color:red"); | ||||
| } | } | ||||
| @@ -111,6 +111,31 @@ const PutAwayScan: React.FC<Props> = ({ warehouse }) => { | |||||
| } | } | ||||
| }, [scanner.result]); | }, [scanner.result]); | ||||
| // Get Scanner State | |||||
| useEffect(() => { | |||||
| if (scanner.state) { | |||||
| // | |||||
| } | |||||
| }, [scanner.state]); | |||||
| const displayText = useMemo(() => { | |||||
| switch (scanner.state) { | |||||
| case "pending": | |||||
| return t("Pending scan"); | |||||
| case "scanning": | |||||
| return t("Scanning"); | |||||
| case "retry": | |||||
| return t("Rescan"); | |||||
| default: | |||||
| return t("Pending scan"); | |||||
| } | |||||
| // if (scanDisplay == "pending") { | |||||
| // return t("Pending scan"); | |||||
| // } else if (scanDisplay == "retry") { | |||||
| // return t("Rescan"); | |||||
| // } | |||||
| }, [scanner.state]); | |||||
| return (<> | return (<> | ||||
| <Paper sx={{ | <Paper sx={{ | ||||
| display: 'flex', | display: 'flex', | ||||
| @@ -120,7 +145,7 @@ const PutAwayScan: React.FC<Props> = ({ warehouse }) => { | |||||
| textAlign: 'center',}} | textAlign: 'center',}} | ||||
| > | > | ||||
| <Typography variant="h4"> | <Typography variant="h4"> | ||||
| {scanDisplay == "pending" ? t("Pending scan") : t("Rescan")} | |||||
| {displayText} | |||||
| </Typography> | </Typography> | ||||
| <QrCodeScanner sx={{padding: "10px", fontSize : "150px"}}/> | <QrCodeScanner sx={{padding: "10px", fontSize : "150px"}}/> | ||||
| @@ -16,6 +16,8 @@ export interface QrCodeScanner { | |||||
| stopScan: () => void; | stopScan: () => void; | ||||
| resetScan: () => void; | resetScan: () => void; | ||||
| result: QrCodeInfo | undefined; | result: QrCodeInfo | undefined; | ||||
| state: "scanning" | "pending" | "retry"; | |||||
| error: string | undefined; | |||||
| } | } | ||||
| interface QrCodeScannerProviderProps { | interface QrCodeScannerProviderProps { | ||||
| @@ -35,6 +37,8 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({ | |||||
| const [leftCurlyBraceCount, setLeftCurlyBraceCount] = useState<number>(0); | const [leftCurlyBraceCount, setLeftCurlyBraceCount] = useState<number>(0); | ||||
| const [rightCurlyBraceCount, setRightCurlyBraceCount] = useState<number>(0); | const [rightCurlyBraceCount, setRightCurlyBraceCount] = useState<number>(0); | ||||
| const [scanResult, setScanResult] = useState<QrCodeInfo | undefined>() | const [scanResult, setScanResult] = useState<QrCodeInfo | undefined>() | ||||
| const [scanState, setScanState] = useState<"scanning" | "pending" | "retry">("pending"); | |||||
| const [scanError, setScanError] = useState<string | undefined>() // TODO return scan error message | |||||
| const resetScannerInput = useCallback(() => { | const resetScannerInput = useCallback(() => { | ||||
| setKeys(() => []); | setKeys(() => []); | ||||
| @@ -51,6 +55,8 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({ | |||||
| if (error.length > 0) { | if (error.length > 0) { | ||||
| console.log("%c Error:", "color:red", error); | console.log("%c Error:", "color:red", error); | ||||
| console.log("%c key:", "color:red", keys); | |||||
| setScanState("retry"); | |||||
| } | } | ||||
| }, []); | }, []); | ||||
| @@ -127,10 +133,15 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({ | |||||
| // Update Qr Code Scanner Values | // Update Qr Code Scanner Values | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (rightCurlyBraceCount > leftCurlyBraceCount || leftCurlyBraceCount > 1) { // Prevent multiple scan | if (rightCurlyBraceCount > leftCurlyBraceCount || leftCurlyBraceCount > 1) { // Prevent multiple scan | ||||
| setScanState("retry"); | |||||
| setScanError("Too many scans at once"); | |||||
| resetQrCodeScanner("Too many scans at once"); | resetQrCodeScanner("Too many scans at once"); | ||||
| } else { | } else { | ||||
| if (leftCurlyBraceCount == 1 && keys.length == 1) | if (leftCurlyBraceCount == 1 && keys.length == 1) | ||||
| { console.log("%c Scan detected, waiting for inputs...", "color:cyan"); } | |||||
| { | |||||
| setScanState("scanning"); | |||||
| console.log("%c Scan detected, waiting for inputs...", "color:cyan"); | |||||
| } | |||||
| if ( | if ( | ||||
| leftCurlyBraceCount !== 0 && | leftCurlyBraceCount !== 0 && | ||||
| rightCurlyBraceCount !== 0 && | rightCurlyBraceCount !== 0 && | ||||
| @@ -138,6 +149,7 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({ | |||||
| ) { | ) { | ||||
| const startBrace = keys.indexOf("{"); | const startBrace = keys.indexOf("{"); | ||||
| const endBrace = keys.lastIndexOf("}"); | const endBrace = keys.lastIndexOf("}"); | ||||
| setScanState("pending"); | |||||
| setQrCodeScannerValues((value) => [ | setQrCodeScannerValues((value) => [ | ||||
| ...value, | ...value, | ||||
| keys.join("").substring(startBrace, endBrace + 1), | keys.join("").substring(startBrace, endBrace + 1), | ||||
| @@ -201,6 +213,8 @@ const QrCodeScannerProvider: React.FC<QrCodeScannerProviderProps> = ({ | |||||
| stopScan: endQrCodeScanner, | stopScan: endQrCodeScanner, | ||||
| resetScan: resetQrCodeScanner, | resetScan: resetQrCodeScanner, | ||||
| result: scanResult, | result: scanResult, | ||||
| state: scanState, | |||||
| error: scanError, | |||||
| }} | }} | ||||
| > | > | ||||
| {children} | {children} | ||||
| @@ -67,7 +67,7 @@ const textfieldSx = { | |||||
| transform: "translate(14px, 1.2rem) scale(1)", | transform: "translate(14px, 1.2rem) scale(1)", | ||||
| "&.MuiInputLabel-shrink": { | "&.MuiInputLabel-shrink": { | ||||
| fontSize: 24, | fontSize: 24, | ||||
| transform: "translate(14px, -9px) scale(1)", | |||||
| transform: "translate(14px, -0.5rem) scale(1)", | |||||
| }, | }, | ||||
| // [theme.breakpoints.down("sm")]: { | // [theme.breakpoints.down("sm")]: { | ||||
| // fontSize: "1rem", | // fontSize: "1rem", | ||||
| @@ -60,7 +60,7 @@ const textfieldSx = { | |||||
| transform: "translate(14px, 1.2rem) scale(1)", | transform: "translate(14px, 1.2rem) scale(1)", | ||||
| "&.MuiInputLabel-shrink": { | "&.MuiInputLabel-shrink": { | ||||
| fontSize: 24, | fontSize: 24, | ||||
| transform: "translate(14px, -9px) scale(1)", | |||||
| transform: "translate(14px, -0.5rem) scale(1)", | |||||
| }, | }, | ||||
| // [theme.breakpoints.down("sm")]: { | // [theme.breakpoints.down("sm")]: { | ||||
| // fontSize: "1rem", | // fontSize: "1rem", | ||||
| @@ -20,5 +20,6 @@ | |||||
| "lotNo": "貨品批號", | "lotNo": "貨品批號", | ||||
| "poCode": "採購訂單編號", | "poCode": "採購訂單編號", | ||||
| "itemCode": "貨品編號", | "itemCode": "貨品編號", | ||||
| "uom": "單位" | |||||
| "uom": "單位", | |||||
| "Scanning": "掃瞄中,請稍後..." | |||||
| } | } | ||||