|
|
|
@@ -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={{ |
|
|
|
|