|
|
|
@@ -82,6 +82,10 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
const params = useSearchParams(); |
|
|
|
|
|
|
|
const [isOpenScanner, setIsOpenScanner] = useState<boolean>(false); |
|
|
|
const [firstWarehouseId, setFirstWarehouseId] = useState<number | null>(null); |
|
|
|
const [warehouseMismatchError, setWarehouseMismatchError] = useState<string>(""); |
|
|
|
|
|
|
|
const [firstWarehouseInfo, setFirstWarehouseInfo] = useState<{name: string, code: string} | null>(null); |
|
|
|
|
|
|
|
const [itemDetail, setItemDetail] = useState<StockInLine>(); |
|
|
|
const [totalPutAwayQty, setTotalPutAwayQty] = useState<number>(0); |
|
|
|
@@ -89,7 +93,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
undefined, |
|
|
|
); |
|
|
|
|
|
|
|
const [putQty, setPutQty] = useState<number>(itemDetail?.demandQty ?? 0); |
|
|
|
const [putQty, setPutQty] = useState<number>(itemDetail?.acceptedQty ?? 0); |
|
|
|
const [verified, setVerified] = useState<boolean>(false); |
|
|
|
const [qtyError, setQtyError] = useState<string>(""); |
|
|
|
|
|
|
|
@@ -108,7 +112,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
productionDate: itemDetail?.productionDate ? arrayToDateString(itemDetail?.productionDate, "input") : undefined, |
|
|
|
expiryDate: itemDetail?.expiryDate ? arrayToDateString(itemDetail?.expiryDate, "input") : undefined, |
|
|
|
receiptDate: itemDetail?.receiptDate ? arrayToDateString(itemDetail?.receiptDate, "input") : undefined, |
|
|
|
// acceptQty: itemDetail.demandQty?? itemDetail.acceptedQty, |
|
|
|
acceptQty: itemDetail?.acceptedQty ?? 0, |
|
|
|
defaultWarehouseId: itemDetail?.defaultWarehouseId ?? 1, |
|
|
|
} as ModalFormInput |
|
|
|
) |
|
|
|
@@ -159,21 +163,37 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
console.log("%c Scanning started ", "color:cyan"); |
|
|
|
}; |
|
|
|
useEffect(() => { |
|
|
|
if (warehouseId > 0) { // Scanned Warehouse |
|
|
|
if (warehouseId > 0 && firstWarehouseId !== null) { |
|
|
|
if (warehouseId !== firstWarehouseId) { |
|
|
|
const firstWh = warehouse.find((w) => w.id == firstWarehouseId); |
|
|
|
const scannedWh = warehouse.find((w) => w.id == warehouseId); |
|
|
|
setWarehouseMismatchError("倉庫不匹配!必須使用首次上架的倉庫"); |
|
|
|
setVerified(false); |
|
|
|
} else { |
|
|
|
setWarehouseMismatchError(""); |
|
|
|
if (scanner.isScanning) { |
|
|
|
setIsOpenScanner(false); |
|
|
|
setVerified(true); |
|
|
|
msg("貨倉掃瞄成功!"); |
|
|
|
scanner.resetScan(); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (warehouseId > 0 && firstWarehouseId === null) { |
|
|
|
// First put away - no validation needed |
|
|
|
if (scanner.isScanning) { |
|
|
|
setIsOpenScanner(false); |
|
|
|
setVerified(true); |
|
|
|
msg("貨倉掃瞄成功!"); |
|
|
|
scanner.resetScan(); |
|
|
|
console.log("%c Scanner reset", "color:cyan"); |
|
|
|
} |
|
|
|
} |
|
|
|
}, [warehouseId]) |
|
|
|
}, [warehouseId, firstWarehouseId]) |
|
|
|
|
|
|
|
const warehouseDisplay = useMemo(() => { |
|
|
|
const targetWarehouseId = firstWarehouseId || warehouseId || 1; |
|
|
|
const wh = warehouse.find((w) => w.id == warehouseId) ?? warehouse.find((w) => w.id == 1); |
|
|
|
return <>{wh?.name} <br/> [{wh?.code}]</>; |
|
|
|
}, [warehouse, warehouseId, verified]); |
|
|
|
}, [warehouse, warehouseId, firstWarehouseId,verified]); |
|
|
|
|
|
|
|
// useEffect(() => { // Restart scanner for changing warehouse |
|
|
|
// if (warehouseId > 0) { |
|
|
|
@@ -189,7 +209,25 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
...defaultNewValue |
|
|
|
}) |
|
|
|
const total = itemDetail.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0; |
|
|
|
setPutQty(itemDetail?.demandQty - total); |
|
|
|
setPutQty(itemDetail?.acceptedQty - total); |
|
|
|
|
|
|
|
// ✅ Get first warehouse from existing put away lines |
|
|
|
const firstPutAwayLine = itemDetail.putAwayLines?.[0]; |
|
|
|
if (firstPutAwayLine?.warehouseId) { |
|
|
|
setFirstWarehouseId(firstPutAwayLine.warehouseId); |
|
|
|
// ✅ Store first warehouse info for display |
|
|
|
const firstWh = warehouse.find((w) => w.id == firstPutAwayLine.warehouseId); |
|
|
|
if (firstWh) { |
|
|
|
setFirstWarehouseInfo({ |
|
|
|
name: firstWh.name || "", |
|
|
|
code: firstWh.code || "" |
|
|
|
}); |
|
|
|
} |
|
|
|
} else { |
|
|
|
setFirstWarehouseId(null); |
|
|
|
setFirstWarehouseInfo(null); |
|
|
|
} |
|
|
|
|
|
|
|
console.log("%c Loaded data:", "color:lime", defaultNewValue); |
|
|
|
} else { |
|
|
|
switch (itemDetail.status) { |
|
|
|
@@ -236,10 +274,15 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
if (!Number.isInteger(qty)) { |
|
|
|
setQtyError(t("value must be integer")); |
|
|
|
} |
|
|
|
if (qty > itemDetail?.demandQty!! - totalPutAwayQty) { |
|
|
|
//if (qty > itemDetail?.demandQty!! - totalPutAwayQty) { |
|
|
|
//setQtyError(`${t("putQty must not greater than")} ${ |
|
|
|
// itemDetail?.demandQty!! - totalPutAwayQty}` ); |
|
|
|
//} |
|
|
|
if (qty > itemDetail?.acceptedQty!! - totalPutAwayQty) { |
|
|
|
setQtyError(`${t("putQty must not greater than")} ${ |
|
|
|
itemDetail?.demandQty!! - totalPutAwayQty}` ); |
|
|
|
} else |
|
|
|
itemDetail?.acceptedQty!! - totalPutAwayQty}` ); |
|
|
|
} |
|
|
|
else |
|
|
|
// if (qty > itemDetail?.acceptedQty!!) { |
|
|
|
// setQtyError(`${t("putQty must not greater than")} ${ |
|
|
|
// itemDetail?.acceptedQty}` ); |
|
|
|
@@ -260,6 +303,10 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
// qty: acceptQty; |
|
|
|
// } |
|
|
|
try { |
|
|
|
if (firstWarehouseId !== null && warehouseId !== firstWarehouseId) { |
|
|
|
setWarehouseMismatchError("倉庫不匹配!必須使用首次上架的倉庫"); |
|
|
|
return; |
|
|
|
} |
|
|
|
const args = { |
|
|
|
// ...itemDetail, |
|
|
|
id: itemDetail?.id, |
|
|
|
@@ -267,7 +314,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
purchaseOrderLineId: itemDetail?.purchaseOrderLineId, |
|
|
|
itemId: itemDetail?.itemId, |
|
|
|
acceptedQty: itemDetail?.acceptedQty, |
|
|
|
acceptQty: itemDetail?.demandQty, |
|
|
|
acceptQty: itemDetail?.acceptedQty, |
|
|
|
status: "received", |
|
|
|
// purchaseOrderId: parseInt(params.get("id")!), |
|
|
|
// purchaseOrderLineId: itemDetail?.purchaseOrderLineId, |
|
|
|
@@ -329,7 +376,7 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
console.log(e); |
|
|
|
} |
|
|
|
}, |
|
|
|
[t, itemDetail, putQty, warehouseId], |
|
|
|
[t, itemDetail, putQty, warehouseId, firstWarehouseId], |
|
|
|
); |
|
|
|
|
|
|
|
return ( |
|
|
|
@@ -419,7 +466,9 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
}} |
|
|
|
noWrap |
|
|
|
> |
|
|
|
請掃瞄倉庫二維碼 |
|
|
|
{warehouseMismatchError || (firstWarehouseId !== null && warehouseId > 0 && warehouseId !== firstWarehouseId) |
|
|
|
? "倉庫不匹配!請掃瞄首次上架的倉庫" |
|
|
|
: "請掃瞄倉庫二維碼"} |
|
|
|
</Typography> |
|
|
|
</> |
|
|
|
) |
|
|
|
@@ -480,8 +529,9 @@ const PutAwayModal: React.FC<Props> = ({ open, onClose, warehouse, stockInLineId |
|
|
|
lineHeight: "1.1", |
|
|
|
}, |
|
|
|
}} |
|
|
|
defaultValue={itemDetail?.demandQty!! - totalPutAwayQty} |
|
|
|
// defaultValue={itemDetail?.demandQty!! - totalPutAwayQty} |
|
|
|
// defaultValue={itemDetail.demandQty} |
|
|
|
defaultValue={itemDetail?.acceptedQty!! - totalPutAwayQty} |
|
|
|
onChange={(e) => { |
|
|
|
const value = e.target.value; |
|
|
|
validateQty(Number(value)); |
|
|
|
|