diff --git a/src/app/api/stockLedgerFix/client.ts b/src/app/api/stockLedgerFix/client.ts index 80577459..2b0d9778 100644 --- a/src/app/api/stockLedgerFix/client.ts +++ b/src/app/api/stockLedgerFix/client.ts @@ -95,33 +95,6 @@ export type StockLedgerFixScopeDetail = { parts: StockLedgerFixCheckPart[]; }; -export type StockLedgerFixAdjRow = { - lotLineId: number; - inventoryId: number | null; - itemCode: string | null; - lineIn: string; - lineOut: string; - ledgerIn: string; - ledgerOut: string; - missIn: string; - missOut: string; - overIssue: string; -}; - -export type StockLedgerFixAdjPreview = { - adjDate: string; - lotCount: number; - adjInCount: number; - adjOutCount: number; - skippedNegCount: number; - sumMissIn: string; - sumMissOut: string; - skuNet: string; - overIssueCount: number; - sumOverIssue: string; - rows: StockLedgerFixAdjRow[]; -}; - export type StockLedgerFixAdjResponse = { adjDate: string; insertedIn: number; @@ -132,22 +105,6 @@ export type StockLedgerFixAdjResponse = { dayRowsWritten: number; }; -export async function fetchStockLedgerFixAdjPreview( - adjDate?: string, -): Promise { - const response = await axiosInstance.get( - `${NEXT_PUBLIC_API_URL}/stock-ledger-fix/adj`, - { - params: { - rowLimit: 20, - ...(adjDate ? { adjDate } : {}), - }, - timeout: 600000, - }, - ); - return response.data; -} - export async function runStockLedgerFixAdj( adjDate?: string, ): Promise { diff --git a/src/components/StockLedgerFix/StockLedgerFixPageClient.tsx b/src/components/StockLedgerFix/StockLedgerFixPageClient.tsx index c9be243a..08bcc880 100644 --- a/src/components/StockLedgerFix/StockLedgerFixPageClient.tsx +++ b/src/components/StockLedgerFix/StockLedgerFixPageClient.tsx @@ -27,7 +27,6 @@ import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import dayjs, { type Dayjs } from "dayjs"; import "dayjs/locale/zh-hk"; import { - fetchStockLedgerFixAdjPreview, runStockLedgerFixAdj, fetchStockLedgerFixDay, fetchStockLedgerFixInventory, @@ -41,7 +40,6 @@ import { searchStockLedgerFixInventory, searchStockLedgerFixLot, downloadStockLedgerFixSql, - type StockLedgerFixAdjPreview, type StockLedgerFixCheckPart, type StockLedgerFixDayDetail, type StockLedgerFixInventoryPreview, @@ -291,10 +289,7 @@ const StockLedgerFixPageClient: React.FC = () => { const [inventoryRunning, setInventoryRunning] = useState(false); const [inventoryError, setInventoryError] = useState(null); const [inventoryMessage, setInventoryMessage] = useState(null); - const adjLoadInFlight = useRef(false); const adjRunInFlight = useRef(false); - const [adjPreview, setAdjPreview] = useState(null); - const [adjLoading, setAdjLoading] = useState(false); const [adjRunning, setAdjRunning] = useState(false); const [adjError, setAdjError] = useState(null); const [adjMessage, setAdjMessage] = useState(null); @@ -348,32 +343,6 @@ const StockLedgerFixPageClient: React.FC = () => { } }, []); - const loadAdjPreview = useCallback(async () => { - if (adjLoadInFlight.current) return; - const d = adjDate.trim(); - if (!d) { - setAdjError("請填 ADJ 日期"); - return; - } - if (d > dayjs().format("YYYY-MM-DD")) { - setAdjError("ADJ 日期不能是未來"); - return; - } - adjLoadInFlight.current = true; - setAdjLoading(true); - setAdjError(null); - try { - setAdjPreview(await fetchStockLedgerFixAdjPreview(d)); - } catch (e) { - console.error(e); - setAdjError(apiErrorMessage(e, "無法載入 ADJ 預覽(需要 ADMIN / TESTING)")); - setAdjPreview(null); - } finally { - setAdjLoading(false); - adjLoadInFlight.current = false; - } - }, [adjDate]); - useEffect(() => { void loadInventory(); }, [loadInventory]); @@ -450,13 +419,17 @@ const StockLedgerFixPageClient: React.FC = () => { const onAdjApply = async () => { if (adjRunInFlight.current) return; - const d = adjDate.trim() || adjPreview?.adjDate; + const d = adjDate.trim(); if (!d) { - setAdjError("請填 ADJ 日期並先預覽"); + setAdjError("請填 ADJ 日期"); + return; + } + if (d > dayjs().format("YYYY-MM-DD")) { + setAdjError("ADJ 日期不能是未來"); return; } const ok = window.confirm( - `會在 ${d} 先修超發 remain→0(${adjPreview?.overIssueCount ?? 0} 條 lot,合計 ${adjPreview?.sumOverIssue ?? "?"},會改 lot inQty)。再補 miss ADJ:入向 ${adjPreview?.adjInCount ?? 0} 筆、出向 ${adjPreview?.adjOutCount ?? 0} 筆。入向全部掛同一張入倉單、出向全部掛同一張出倉單(miss 不改 lot 數量)。缺入合計 ${adjPreview?.sumMissIn ?? "?"}、缺出合計 ${adjPreview?.sumMissOut ?? "?"}。確定?`, + `會在 ${d} 對最後餘額不等於 onHandQty 的庫存桶各寫一筆 ADJ(入或出),掛在既有 lot 上。不改 lot line、不改 inventory。已對齊的桶不會再寫。確定?`, ); if (!ok) return; adjRunInFlight.current = true; @@ -466,9 +439,8 @@ const StockLedgerFixPageClient: React.FC = () => { try { const res = await runStockLedgerFixAdj(d); setAdjMessage( - `ADJ ${res.adjDate}:超發 remain→0 ${res.overIssuePatched}、入 ${res.insertedIn}、出 ${res.insertedOut}、lotQty ${res.filledLotQty}、balance ${res.filledBalance}、日結 ${res.dayRowsWritten}`, + `ADJ ${res.adjDate}:入 ${res.insertedIn}、出 ${res.insertedOut}、lotQty ${res.filledLotQty}、balance ${res.filledBalance}、日結 ${res.dayRowsWritten}`, ); - await loadAdjPreview(); } catch (e) { console.error(e); setAdjError(apiErrorMessage(e, "ADJ 對齊失敗")); @@ -744,13 +716,11 @@ const StockLedgerFixPageClient: React.FC = () => { - 2.7 ADJ:超發 remain→0,再對齊 ledger + 2.7 ADJ:對齊最後餘額與 onHandQty - 請先選 ADJ 日期再預覽。預設昨天;freeze dump 夜可選今天(例如 31/8 23:17 寫 ADJ 到 - 31/8)。先處理超發(line 入少於出):把該 lot 的 inQty 補到等於 outQty(remain=0,trigger - 重算 inventory)。再處理 miss:line 與 ledger 有差就 ADJ,掛既有 lot 的入/出倉行(不改 lot - 數量)。一次 Apply 共用一張入倉單、一張出倉單,下面多行;同一 ADJ 日期再跑會沿用這兩張單。 - 明細最多 20 列。 + 選 ADJ 日期後直接執行。預設昨天;freeze dump 夜可選今天。最後餘額低於 onHandQty + 的桶補一筆入倉 ADJ,高於 onHandQty 的桶補一筆出倉 ADJ,掛在既有 lot 上。不改 lot + line、不改 inventory。一次執行共用一張入倉單、一張出倉單;已對齊的桶再跑不會再寫。 { value={adjDate} onChange={(e) => { setAdjDate(e.target.value); - setAdjPreview(null); setAdjMessage(null); }} - disabled={adjLoading || adjRunning} + disabled={adjRunning} InputLabelProps={{ shrink: true }} inputProps={{ max: dayjs().format("YYYY-MM-DD") }} />