浏览代码

update putaway scan

master
kelvinsuen 3 个月前
父节点
当前提交
f85eeaf7c3
共有 8 个文件被更改,包括 130 次插入47 次删除
  1. +4
    -0
      src/app/global.css
  2. +1
    -1
      src/components/PoDetail/PoDetail.tsx
  3. +2
    -1
      src/components/PoDetail/QcStockInModal.tsx
  4. +32
    -14
      src/components/PoDetail/StockInForm.tsx
  5. +86
    -29
      src/components/PutAwayScan/PutAwayModal.tsx
  6. +3
    -0
      src/components/Swal/CustomAlerts.tsx
  7. +1
    -1
      src/i18n/zh/purchaseOrder.json
  8. +1
    -1
      src/i18n/zh/putAway.json

+ 4
- 0
src/app/global.css 查看文件

@@ -4,4 +4,8 @@

html, body {
overscroll-behavior: none;
}

.swal2-custom-zindex {
z-index: 10000 !important;
}

+ 1
- 1
src/components/PoDetail/PoDetail.tsx 查看文件

@@ -815,7 +815,7 @@ const PoDetail: React.FC<Props> = ({ po, qc, warehouse, printerCombo }) => {
<TableCell sx={{ width: '125px' }}>{t("itemNo")}</TableCell>
<TableCell align="left" sx={{ width: '125px' }}>{t("itemName")}</TableCell>
<TableCell align="right">{t("qty")}</TableCell>
<TableCell align="right">{t("processed")}</TableCell>
<TableCell align="right">{t("processedQty")}</TableCell>
<TableCell align="left">{t("uom")}</TableCell>
<TableCell align="right">{t("receivedTotal")}</TableCell>
<TableCell align="left">{t("Stock UoM")}</TableCell>


+ 2
- 1
src/components/PoDetail/QcStockInModal.tsx 查看文件

@@ -26,7 +26,7 @@ import QcComponent from "./QcComponent";
import { dummyPutAwayLine, dummyQCData } from "./dummyQcTemplate";
import PutAwayForm from "./PutAwayForm";
import { GridRowModes, GridRowSelectionModel, useGridApiRef } from "@mui/x-data-grid";
import {submitDialogWithWarning} from "../Swal/CustomAlerts";
import {msg, submitDialogWithWarning} from "../Swal/CustomAlerts";
import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToInputDateString } from "@/app/utils/formatUtil";
import dayjs from "dayjs";
import { fetchPoQrcode } from "@/app/api/pdf/actions";
@@ -342,6 +342,7 @@ const [qcItems, setQcItems] = useState(dummyQCData)
} else {
closeHandler({}, "backdropClick");
}
msg("已更新來貨狀態");
return ;

},


+ 32
- 14
src/components/PoDetail/StockInForm.tsx 查看文件

@@ -338,20 +338,38 @@ const StockInForm: React.FC<Props> = ({
disabled={true}
/>
</Grid>
<Grid item xs={6}>
<TextField
label={t("acceptedQty")}
fullWidth
disabled={true}
{...register("acceptedQty", {
required: "acceptedQty required!",
})}
// disabled={true}
// disabled={disabled}
// error={Boolean(errors.acceptedQty)}
// helperText={errors.acceptedQty?.message}
/>
</Grid>
{putawayMode ? (
<Grid item xs={6}>
<TextField
label={`${t("processedQty")} / ${t("acceptedQty")}`}
fullWidth
disabled={true}
value={
`${itemDetail.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0} / ${itemDetail.acceptedQty}`
}
// disabled={true}
// disabled={disabled}
// error={Boolean(errors.acceptedQty)}
// helperText={errors.acceptedQty?.message}
/>
</Grid>
) : (
<Grid item xs={6}>
<TextField
label={t("acceptedQty")}
fullWidth
disabled={true}
{...register("acceptedQty", {
required: "acceptedQty required!",
})}
// disabled={true}
// disabled={disabled}
// error={Boolean(errors.acceptedQty)}
// helperText={errors.acceptedQty?.message}
/>
</Grid>
)
}
{/* <Grid item xs={4}>
<TextField
label={t("acceptedWeight")}


+ 86
- 29
src/components/PutAwayScan/PutAwayModal.tsx 查看文件

@@ -51,7 +51,7 @@ const style = {
bgcolor: "background.paper",
pt: 5,
px: 5,
pb: 10,
pb: 5,
// width: "auto",
width: { xs: "90%", sm: "90%", md: "90%" },
};
@@ -77,11 +77,14 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
const [isOpenScanner, setIsOpenScanner] = useState<boolean>(false);
const [itemDetail, setItemDetail] = useState<StockInLine>();
const [putAwayQty, setPutAwayQty] = useState<number>(0);
const [unavailableText, setUnavailableText] = useState<string | undefined>(
undefined,
);
const [putQty, setPutQty] = useState<number>(itemDetail?.demandQty ?? 0);
const [verified, setVerified] = useState<boolean>(false);
const [qtyError, setQtyError] = useState<string>("");
const defaultNewValue = useMemo(() => {
// console.log("%c ItemDetail", "color:purple", itemDetail);
@@ -121,6 +124,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
(...args) => {
setVerified(false);
setItemDetail(undefined);
setPutAwayQty(0);
onClose?.(...args);
// reset();
},
@@ -153,11 +157,19 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
if (scanner.isScanning) {
setIsOpenScanner(false);
setVerified(true);
scanner.stopScan();
console.log("%c Scanner stopped", "color:cyan");
msg("貨倉掃瞄成功!")
scanner.resetScan();
console.log("%c Scanner reset", "color:cyan");
}
}
}, [warehouseId])
// useEffect(() => { // Restart scanner for changing warehouse
// if (warehouseId > 0) {
// scanner.startScan();
// console.log("%c Scanner restarted", "color:cyan");
// }
// }, [isOpenScanner])

useLayoutEffect(() => {
if (itemDetail !== undefined) {
@@ -185,20 +197,25 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
const fetchStockInLine = useCallback(
async (stockInLineId: number) => {
setUnavailableText(undefined);
const res = await fetchStockInLineInfo(stockInLineId);
console.log("%c Fetched Stock In Line Info:", "color:gold", res);
setItemDetail(res);
try {
const res = await fetchStockInLineInfo(stockInLineId);
console.log("%c Fetched Stock In Line Info:", "color:gold", res);

const totalPutAwayQty = res.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0;
setPutAwayQty(totalPutAwayQty);
setItemDetail(res);
} catch (e) {
console.log("%c Error when fetching Stock In Line: ", "color:red", e);
alert("錯誤的二維碼");
closeHandler({}, "backdropClick");
}
},
[formProps, itemDetail, fetchStockInLineInfo],
);

useEffect(() => {
if (stockInLineId) { fetchStockInLine(stockInLineId); }
}, [stockInLineId]);

const [verified, setVerified] = useState<boolean>(false);

const [qtyError, setQtyError] = useState<string>("");
}, [stockInLineId]);

const validateQty = useCallback((qty : number = putQty) => {
// if (isNaN(putQty) || putQty === undefined || putQty === null || typeof(putQty) != "number") {
@@ -207,10 +224,14 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
if (!Number.isInteger(qty)) {
setQtyError(t("value must be integer"));
}
if (qty > itemDetail?.acceptedQty!!) {
if (qty > itemDetail?.acceptedQty!! - putAwayQty) {
setQtyError(`${t("putQty must not greater than")} ${
itemDetail?.acceptedQty}` );
} else
itemDetail?.acceptedQty!! - putAwayQty}` );
} else
// if (qty > itemDetail?.acceptedQty!!) {
// setQtyError(`${t("putQty must not greater than")} ${
// itemDetail?.acceptedQty}` );
// } else
if (qty < 1) {
setQtyError(t("minimal value is 1"));
} else {
@@ -303,7 +324,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
<Grid item xs={12}>
<StockInForm itemDetail={itemDetail} disabled={true} putawayMode={true}/>
</Grid>
<Paper sx={{ padding: 2, width: "100%", backgroundColor: verified ? '#bceb19' : '#FCD34D' }}>
<Paper sx={{ mt: 2, padding: 2, width: "100%", backgroundColor: verified ? '#bceb19' : '#FCD34D' }}>
<Grid
container
spacing={2}
@@ -320,14 +341,14 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
<Grid container>
{verified? (
<>
<CheckCircle sx={{color:"green", fontSize: "35px"}}/>
<CheckCircle sx={{color:"green", fontSize: "35px", mr: 1}}/>
<Typography variant="h5" component="h2" sx={{ fontWeight: 'bold', color: 'black' }} noWrap>
掃瞄完成
</Typography>
</>
) : (
<>
<ErrorOutline sx={{color:"red", fontSize: "35px"}}/>
<ErrorOutline sx={{color:"red", fontSize: "35px", mr: 1}}/>
<Typography variant="h5" component="h2" sx={{ fontWeight: 'bold', color: 'black' }} noWrap>
請掃瞄倉庫二維碼
</Typography>
@@ -338,8 +359,8 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
</Grid>
<Grid container>
<Typography variant="h4" sx={{ fontWeight: 'bold', color: 'black' }} noWrap>
{`${warehouseId > 0 ? warehouse.find((w) => w.id == warehouseId)?.name
: warehouse.find((w) => w.id == 3)?.name}`}
{warehouseId > 0 ? `${warehouse.find((w) => w.id == warehouseId)?.name}`
: `${warehouse.find((w) => w.id == 1)?.name} (預設)`}
</Typography>
</Grid>

@@ -351,13 +372,40 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
type="number" // TODO fix the "e" input
label={t("putQty")}
fullWidth
sx={{fontSize: "25px", height: "100%"}}
defaultValue={itemDetail.demandQty}
sx={{
"& .MuiInputBase-input": {
padding: "20px 14px 5px",
fontSize: "50px",
fontWeight: "bold",
},
"& .MuiInputBase-root": {
height: "100%",
borderColor: "black",
},
"& .MuiInputLabel-root": {
fontSize: "30px",
top: "-5px",
color: "black",
},
"& .MuiFormHelperText-root": {
fontSize: "20px",
marginTop: "8px",
lineHeight: "1.2",
},
}}
defaultValue={itemDetail?.acceptedQty!! - putAwayQty}
// defaultValue={itemDetail.demandQty}
onChange={(e) => {
const value = e.target.value;
validateQty(Number(value));
setPutQty(Number(value));
}}
onKeyDown={(e) => {
// Prevent non-numeric characters
if (["e", "E", "+", "-", "."].includes(e.key)) {
e.preventDefault();
}
}}
// onBlur={(e) => {
// const value = e.target.value;
// setPutQty(Number(value));
@@ -375,7 +423,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
<Grid item xs={4}>
<Box
sx={{
p: 2,
p: 1,
textAlign: 'center',
height: '100%', // Ensure D stretches to full height
display: 'flex',
@@ -387,17 +435,27 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
type="submit"
variant="contained"
startIcon={<Check />}
color="primary"
// sx={{ mx: 3, minWidth: "120px", height: "120px",
// padding: "12px 12px", fontSize: "24px"}}
color="secondary"
sx={{
height: "100%",
flex: "0 0 auto",
padding: "8px 16px",
fontSize: { xs: "16px", sm: "20px", md: "24px" },
fontSize: { xs: "20px", sm: "24px", md: "30px" },
whiteSpace: "nowrap",
textAlign: "center",}}
textAlign: "center",
border: "3px solid", // Add outline
borderColor: "blue",
"&:hover": {
borderColor: "grey.200", // Slightly different color on hover
backgroundColor: "secondary.dark", // Darker background on hover
},
"&:disabled": {
borderColor: "grey.400", // Visible outline even when disabled
opacity: 0.7, // Slightly faded but still visible
},
}}
// onClick={formProps.handleSubmit()}
disabled={!verified}
disabled={!verified || qtyError != ""}
>
{t("confirm putaway")}
</Button>
@@ -435,7 +493,6 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId
)}
</Grid>
</Grid>

<Modal open={isOpenScanner} onClose={scannerCloseHandler}>
<Box sx={scannerStyle}>
<Typography variant="h4" sx={{


+ 3
- 0
src/components/Swal/CustomAlerts.tsx 查看文件

@@ -19,6 +19,9 @@ export const msg = (title: SweetAlertTitle) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
},
customClass: {
container: 'swal2-custom-zindex',
},
}).fire({
icon: "success",
title: title,


+ 1
- 1
src/i18n/zh/purchaseOrder.json 查看文件

@@ -43,7 +43,7 @@
"total weight": "總重量",
"weight unit": "重量單位",
"price": "訂單貨值",
"processed": "已上架數量",
"processedQty": "已上架數量",
"expiryDate": "到期日",
"acceptedQty": "是次來貨數量",
"putawayQty": "上架數量",


+ 1
- 1
src/i18n/zh/putAway.json 查看文件

@@ -9,7 +9,7 @@
"Please scan warehouse qr code": "請掃瞄倉庫二維碼",
"scan loading": "載入中,請稍候…",
"warehouse": "倉庫",
"putQty": "上架數量",
"putQty": "是次上架數量",
"minimal value is 1": "最小為1",
"putQty must not greater than": "上架數量不得大於",
"value must be integer": "必須是整數",


正在加载...
取消
保存