From 2548b7a007c398158e589cdd896186e173326657 Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Wed, 11 Mar 2026 17:57:03 +0800 Subject: [PATCH] update stock in line --- src/app/api/stockIn/index.ts | 5 ++ src/components/PoDetail/PoDetail.tsx | 45 ++++++++---- src/components/PoDetail/PoInputGrid.tsx | 9 +-- src/components/PoDetail/QcStockInModal.tsx | 4 +- src/components/PutAwayScan/PutAwayModal.tsx | 12 ++-- src/components/StockIn/StockInForm.tsx | 79 +++++++++------------ 6 files changed, 86 insertions(+), 68 deletions(-) diff --git a/src/app/api/stockIn/index.ts b/src/app/api/stockIn/index.ts index 67a8c34..b4951bc 100644 --- a/src/app/api/stockIn/index.ts +++ b/src/app/api/stockIn/index.ts @@ -109,6 +109,8 @@ export interface StockInLine { itemType: string; demandQty: number; acceptedQty: number; + purchaseDemandQty?: number; + purchaseAcceptedQty?: number; qty?: number; receivedQty?: number; processed?: number; @@ -124,6 +126,8 @@ export interface StockInLine { lotNo?: string; poCode?: string; uom?: Uom; + purchaseUomDesc?: string; + stockUomDesc?: string; joCode?: string; warehouseCode?: string; defaultWarehouseId: number; // id for now @@ -150,6 +154,7 @@ export interface EscalationInput { export interface PutAwayLine { id?: number qty: number + stockQty?: number warehouseId: number; warehouse: string; printQty: number; diff --git a/src/components/PoDetail/PoDetail.tsx b/src/components/PoDetail/PoDetail.tsx index 6a726f3..4edadb5 100644 --- a/src/components/PoDetail/PoDetail.tsx +++ b/src/components/PoDetail/PoDetail.tsx @@ -451,7 +451,10 @@ const PoDetail: React.FC = ({ po, warehouse, printerCombo }) => { const oldId = row.id; const acceptedQty = Number(polInputList[rowIndex].dnQty); if (isNaN(acceptedQty) || acceptedQty <= 0) { alert("來貨數量必須大於0!"); return; } // Temp check, need update - + if (!Number.isInteger(acceptedQty)) { + alert("來貨數量必須是整數(不能有小數)!"); + return; + } const postData = { dnNo: dnFormProps.watch("dnNo"), receiptDate: outputDateStringToInputDateString(dnFormProps.watch("receiptDate")), @@ -491,22 +494,30 @@ const PoDetail: React.FC = ({ po, warehouse, printerCombo }) => { break; case "dnQty": // Allow empty input - if (raw.trim() === '') { - polInputList[rowIndex].dnQty = 0; - break; - } + const trimmed = raw.trim(); + if (trimmed === "") { + polInputList[rowIndex].dnQty = 0; + break; + } + /* // Keep digits only const cleaned = raw.replace(/[^\d]/g, ''); if (cleaned === '') { // If the user typed only non-digits, keep previous value break; } +*/ + const parsed = Number(trimmed); - // Parse and clamp to non-negative integer - const next = Math.max(0, Math.floor(Number(cleaned))); - polInputList[rowIndex].dnQty = next; + // 不是合法數字(例如 "abc") + if (!Number.isFinite(parsed)) { + polInputList[rowIndex].dnQty = 0; // 或保留舊值,看你需求 break; + } + + polInputList[rowIndex].dnQty = parsed; // 這裡允許小數,先存起來 + break; default: break; } @@ -515,9 +526,16 @@ const PoDetail: React.FC = ({ po, warehouse, printerCombo }) => { // const [focusField, setFocusField] = useState(); - const purchaseToStockRatio = (row.stockUom.purchaseRatioN ?? 1) / (row.stockUom.purchaseRatioD ?? 1) * (row.stockUom.stockRatioD ?? 1) / (row.stockUom.stockRatioN ?? 1) - const receivedTotal = decimalFormatter.format(row.stockInLine.filter((sil) => sil.purchaseOrderLineId === row.id).reduce((acc, cur) => acc + (cur.acceptedQty ?? 0),0) * purchaseToStockRatio); - const highlightColor = (Number(receivedTotal.replace(/,/g, '')) <= 0) ? "red" : "inherit"; + // 本批收貨數量(訂單單位): 使用者在該行輸入的 dnQty + const batchPurchaseQty = polInputList[rowIndex]?.dnQty ?? 0; + + // 已來貨總數(庫存單位): 同一 POL 底下所有 stock_in_line.acceptedQty 的合計 + const totalStockReceived = row.stockInLine + .filter((sil) => sil.purchaseOrderLineId === row.id) + .reduce((acc, cur) => acc + (cur.acceptedQty ?? 0), 0); + const receivedTotalText = decimalFormatter.format(totalStockReceived); + const highlightColor = + Number(receivedTotalText.replace(/,/g, "")) <= 0 ? "red" : "inherit"; return ( <> @@ -552,7 +570,10 @@ const PoDetail: React.FC = ({ po, warehouse, printerCombo }) => { {integerFormatter.format(row.processed)} {row.uom?.udfudesc} {/* {decimalFormatter.format(row.stockUom.stockQty)} */} - {receivedTotal} + {/* {receivedTotal} */} + + {decimalFormatter.format(totalStockReceived)} + {row.stockUom.stockUomDesc} {/* {decimalFormatter.format(totalWeight)} {weightUnit} diff --git a/src/components/PoDetail/PoInputGrid.tsx b/src/components/PoDetail/PoInputGrid.tsx index fb66411..bccde84 100644 --- a/src/components/PoDetail/PoInputGrid.tsx +++ b/src/components/PoDetail/PoInputGrid.tsx @@ -524,7 +524,8 @@ function PoInputGrid({ // editable: true, // replace with tooltip + content renderCell: (params) => { - return integerFormatter.format(params.value) + const qty = params.row.purchaseAcceptedQty ?? params.row.acceptedQty ?? 0; + return integerFormatter.format(qty); } }, { @@ -545,9 +546,9 @@ function PoInputGrid({ // editable: true, // replace with tooltip + content renderCell: (params) => { - const baseQty = (params.row.acceptedQty ?? 0) * (itemDetail.stockUom.purchaseRatioN ?? 1) / (itemDetail.stockUom.purchaseRatioD ?? 1) - const stockQty = baseQty * (itemDetail.stockUom.stockRatioD ?? 1) / (itemDetail.stockUom.stockRatioN ?? 1) - return decimalFormatter.format(stockQty) + // acceptedQty 現在就是庫存單位數量 + const stockQty = params.row.acceptedQty ?? 0; + return decimalFormatter.format(stockQty); } }, { diff --git a/src/components/PoDetail/QcStockInModal.tsx b/src/components/PoDetail/QcStockInModal.tsx index 2a4011b..1a88e30 100644 --- a/src/components/PoDetail/QcStockInModal.tsx +++ b/src/components/PoDetail/QcStockInModal.tsx @@ -198,7 +198,7 @@ const PoQcStockInModalVer2: React.FC = ({ expiryDate: d.expiryDate ? arrayToDateString(d.expiryDate, "input") : undefined, receiptDate: d.receiptDate ? arrayToDateString(d.receiptDate, "input") : dayjs().add(0, "month").format(INPUT_DATE_FORMAT), - acceptQty: d.demandQty?? d.acceptedQty, + acceptQty: d.acceptedQty ?? d.demandQty, // escResult: (d.escResult && d.escResult?.length > 0) ? d.escResult : [], // qcResult: (d.qcResult && d.qcResult?.length > 0) ? d.qcResult : [],//[...dummyQCData], warehouseId: d.defaultWarehouseId ?? 1, @@ -451,7 +451,7 @@ const PoQcStockInModalVer2: React.FC = ({ async (data, event) => { // Extract only putaway related fields const putawayData = { - acceptQty: Number(data.acceptQty?? (stockInLineInfo?.demandQty?? (stockInLineInfo?.acceptedQty))), //TODO improve + acceptQty: Number(data.acceptQty ?? (stockInLineInfo?.acceptedQty ?? stockInLineInfo?.demandQty)), //TODO improve warehouseId: data.warehouseId, status: data.status, //TODO Fix it! // ...data, diff --git a/src/components/PutAwayScan/PutAwayModal.tsx b/src/components/PutAwayScan/PutAwayModal.tsx index 4119ed9..b4b0a5e 100644 --- a/src/components/PutAwayScan/PutAwayModal.tsx +++ b/src/components/PutAwayScan/PutAwayModal.tsx @@ -251,7 +251,7 @@ const PutAwayModal: React.FC = ({ open, onClose, warehouse, stockInLineId formProps.reset({ ...defaultNewValue }) - const total = itemDetail.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0; + const total = itemDetail.putAwayLines?.reduce((sum, p) => sum + (p.stockQty ?? p.qty ?? 0), 0) ?? 0; setPutQty(itemDetail?.acceptedQty - total); // ✅ Get first warehouse from existing put away lines @@ -294,7 +294,7 @@ const PutAwayModal: React.FC = ({ open, onClose, warehouse, stockInLineId const res = await fetchStockInLineInfo(stockInLineId); console.log("%c Fetched Stock In Line Info:", "color:gold", res); - const total = res.putAwayLines?.reduce((sum, p) => sum + p.qty, 0) ?? 0; + const total = res.putAwayLines?.reduce((sum, p) => sum + (p.stockQty ?? p.qty ?? 0), 0) ?? 0; setTotalPutAwayQty(total); setItemDetail(res); } catch (e) { @@ -346,6 +346,10 @@ const PutAwayModal: React.FC = ({ open, onClose, warehouse, stockInLineId // qty: acceptQty; // } try { + if (!itemDetail?.id || itemDetail.acceptedQty === undefined || itemDetail.acceptedQty === null) { + alert("找不到收貨數量(acceptedQty),請重新掃碼再試。"); + return; + } // 确定最终使用的 warehouseId const effectiveWarehouseId = warehouseId > 0 ? warehouseId @@ -361,8 +365,8 @@ const PutAwayModal: React.FC = ({ open, onClose, warehouse, stockInLineId purchaseOrderId: itemDetail?.purchaseOrderId, purchaseOrderLineId: itemDetail?.purchaseOrderLineId, itemId: itemDetail?.itemId, - acceptedQty: itemDetail?.acceptedQty, - acceptQty: itemDetail?.acceptedQty, + acceptedQty: Number(itemDetail.acceptedQty), + acceptQty: Number(itemDetail.acceptedQty), status: "received", // purchaseOrderId: parseInt(params.get("id")!), // purchaseOrderLineId: itemDetail?.purchaseOrderLineId, diff --git a/src/components/StockIn/StockInForm.tsx b/src/components/StockIn/StockInForm.tsx index 376ca93..c22c7ad 100644 --- a/src/components/StockIn/StockInForm.tsx +++ b/src/components/StockIn/StockInForm.tsx @@ -370,47 +370,38 @@ const StockInForm: React.FC = ({ /> )} - {putawayMode && ( + {putawayMode ? ( + <> + + + + + + + + sum + (p.stockQty ?? 0), 0) ?? 0} (${itemDetail.stockUomDesc ?? ""})`} + /> + + + ) : ( - - - )} - - - - - {putawayMode ? ( - sum + p.qty, 0) ?? 0} - // disabled={true} - // disabled={disabled} - // error={Boolean(errors.acceptedQty)} - // helperText={errors.acceptedQty?.message} - /> - ) : ( = ({ {...register("acceptedQty", { required: "acceptedQty required!", })} - // disabled={true} - // disabled={disabled} - // error={Boolean(errors.acceptedQty)} - // helperText={errors.acceptedQty?.message} /> - )} - + + )} {/*