diff --git a/src/components/PoDetail/PoDetail.tsx b/src/components/PoDetail/PoDetail.tsx index 993433dc..403cd0c6 100644 --- a/src/components/PoDetail/PoDetail.tsx +++ b/src/components/PoDetail/PoDetail.tsx @@ -207,7 +207,7 @@ interface PolInputResult { dnQty: string, } -/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ const PoDetail: React.FC = ({ po, warehouse, printerCombo }) => { const cameras = useContext(CameraContext); const { data: session } = useSession(); diff --git a/src/components/PoDetail/PoDetailRow.tsx b/src/components/PoDetail/PoDetailRow.tsx index d16c5259..d688df85 100644 --- a/src/components/PoDetail/PoDetailRow.tsx +++ b/src/components/PoDetail/PoDetailRow.tsx @@ -77,7 +77,7 @@ type Props = { onSubmitted: (row: PurchaseOrderLine) => void; }; -/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ export const PoDetailRow = memo(function PoDetailRow({ row, selected, diff --git a/src/components/PoDetail/PoInputGrid.tsx b/src/components/PoDetail/PoInputGrid.tsx index c8c038b8..c41dbef7 100644 --- a/src/components/PoDetail/PoInputGrid.tsx +++ b/src/components/PoDetail/PoInputGrid.tsx @@ -155,7 +155,7 @@ class ProcessRowUpdateError extends Error { } } -/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ function PoInputGrid({ // qc, setRows, diff --git a/src/components/PoDetail/PutAwayForm.tsx b/src/components/PoDetail/PutAwayForm.tsx index 0aa74b4b..545273b6 100644 --- a/src/components/PoDetail/PutAwayForm.tsx +++ b/src/components/PoDetail/PutAwayForm.tsx @@ -55,6 +55,7 @@ import dayjs from "dayjs"; import arraySupport from "dayjs/plugin/arraySupport"; import { dummyPutAwayLine } from "../Qc/dummyQcTemplate"; import { GridRowModesModel } from "@mui/x-data-grid"; +import { displayPutAwayLineQtyFromOriginSil } from "./originSilPutAwayQty"; dayjs.extend(arraySupport); interface Props { @@ -86,6 +87,7 @@ const style = { width: "auto", }; +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ const PutAwayForm: React.FC = ({ itemDetail, warehouse=[], disabled, suggestedLocationCode, setRowModesModel, setRowSelectionModel }) => { const { t } = useTranslation("purchaseOrder"); const apiRef = useGridApiRef(); @@ -241,8 +243,13 @@ const PutAwayForm: React.FC = ({ itemDetail, warehouse=[], disabled, sugg headerAlign: "right", align: "right", renderCell(params) { + const displayQty = displayPutAwayLineQtyFromOriginSil( + itemDetail, + Number(params.value), + params.row._isNew, + ); return - {params.value} + {displayQty} } }, @@ -309,7 +316,7 @@ const PutAwayForm: React.FC = ({ itemDetail, warehouse=[], disabled, sugg // return <>100 // }, // }, - ], []) + ], [itemDetail, t]) const validation = useCallback( (newRow: GridRowModel): EntryError => { @@ -395,7 +402,7 @@ const PutAwayForm: React.FC = ({ itemDetail, warehouse=[], disabled, sugg diff --git a/src/components/PoDetail/QcStockInModal.tsx b/src/components/PoDetail/QcStockInModal.tsx index 56d5a87a..841f3111 100644 --- a/src/components/PoDetail/QcStockInModal.tsx +++ b/src/components/PoDetail/QcStockInModal.tsx @@ -21,6 +21,7 @@ import { useTranslation } from "react-i18next"; import StockInForm from "../StockIn/StockInForm"; import QcComponent from "../Qc/QcComponent"; import PutAwayForm from "./PutAwayForm"; +import { mapPutAwayLinesFromOriginSil } from "./originSilPutAwayQty"; import { GridRowModes, GridRowSelectionModel, useGridApiRef } from "@mui/x-data-grid"; import {msg, submitDialogWithWarning} from "../Swal/CustomAlerts"; import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToDateTimeString } from "@/app/utils/formatUtil"; @@ -71,7 +72,7 @@ interface CommonProps extends Omit { interface Props extends CommonProps { // itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] }; } -/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ const PoQcStockInModalVer2: React.FC = ({ open, onClose, @@ -205,7 +206,7 @@ const PoQcStockInModalVer2: React.FC = ({ // escResult: (d.escResult && d.escResult?.length > 0) ? d.escResult : [], // qcResult: (d.qcResult && d.qcResult?.length > 0) ? d.qcResult : [],//[...dummyQCData], warehouseId: d.defaultWarehouseId ?? 1, - putAwayLines: d.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false, _disableDelete: true})) ?? [], + putAwayLines: mapPutAwayLinesFromOriginSil(d, d.putAwayLines), } as ModalFormInput ) } return undefined diff --git a/src/components/PoDetail/StockInLineRowActions.tsx b/src/components/PoDetail/StockInLineRowActions.tsx index c1431741..c34e153c 100644 --- a/src/components/PoDetail/StockInLineRowActions.tsx +++ b/src/components/PoDetail/StockInLineRowActions.tsx @@ -26,7 +26,7 @@ type Props = { onRound?: (mode: StockQtyRoundMode) => void; }; -/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ export default function StockInLineRowActions({ btnSx, onPrimaryClick, diff --git a/src/components/PoDetail/originSilPutAwayQty.ts b/src/components/PoDetail/originSilPutAwayQty.ts new file mode 100644 index 00000000..2e3fa15d --- /dev/null +++ b/src/components/PoDetail/originSilPutAwayQty.ts @@ -0,0 +1,60 @@ +import { PutAwayLine, StockInLine } from "@/app/api/stockIn"; + +type OriginSil = Pick< + StockInLine, + "jobOrderId" | "purchaseAcceptedQty" | "acceptedQty" +>; + +/** + * FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 + * Path A: inventory_lot_line → inventory_lot → stock_in_line (the SIL that opened the lot). + * Never use inventory_lot_line.inQty — ADJ/TKE is added onto the same line later. + * + * PO: purchaseAcceptedQty (M18 / 採購單位) + * JO: acceptedQty (庫存/生產單位;JO 通常沒有 acceptedQtyM18) + */ +export function originSilPutAwayDisplayQty(origin: OriginSil): number { + if (origin.jobOrderId) { + const stock = Number(origin.acceptedQty); + return Number.isFinite(stock) && stock > 0 ? stock : 0; + } + const purchase = Number(origin.purchaseAcceptedQty); + if (Number.isFinite(purchase) && purchase > 0) return purchase; + const stock = Number(origin.acceptedQty); + return Number.isFinite(stock) && stock > 0 ? stock : 0; +} + +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ +export function originSilPutAwayStockQty(origin: OriginSil): number { + const stock = Number(origin.acceptedQty); + return Number.isFinite(stock) && stock > 0 ? stock : 0; +} + +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ +export function mapPutAwayLinesFromOriginSil( + origin: OriginSil, + lines: PutAwayLine[] | undefined, +): PutAwayLine[] { + const existing = lines ?? []; + const displayQty = originSilPutAwayDisplayQty(origin); + const stockQty = originSilPutAwayStockQty(origin); + return existing.map((line) => ({ + ...line, + printQty: 1, + _isNew: false, + _disableDelete: true, + ...(displayQty > 0 ? { qty: displayQty } : {}), + ...(stockQty > 0 ? { stockQty } : {}), + })); +} + +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ +export function displayPutAwayLineQtyFromOriginSil( + origin: OriginSil, + lineQty: number, + isNew: boolean | undefined, +): number { + if (isNew) return lineQty; + const originQty = originSilPutAwayDisplayQty(origin); + return originQty > 0 ? originQty : lineQty; +} diff --git a/src/components/PoDetail/stockQtyRound.ts b/src/components/PoDetail/stockQtyRound.ts index c2d066b6..630c9acc 100644 --- a/src/components/PoDetail/stockQtyRound.ts +++ b/src/components/PoDetail/stockQtyRound.ts @@ -81,6 +81,7 @@ function convertPoBatchToStockQty( } /** + * FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 * Preview converted stock qty for a 來貨數 batch. * Matches create-stock-in: ratio convert, then integer HALF_UP for 包/箱/PCS, else 2 decimals. */ @@ -104,7 +105,7 @@ export function isNotIntegerQty(qty: number): boolean { } /** - * FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 + * FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 * PO 收貨/品檢:pending 或 escalated 且庫存數量非整數時需選擇 CEILING / FLOOR */ export function needsPoQcStockQtyRound( @@ -118,7 +119,7 @@ export function needsPoQcStockQtyRound( return isNotIntegerQty(Number(acceptedQty ?? 0)); } -/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ export function roundStockQty(before: number, mode: StockQtyRoundMode): number { if (mode === "CEILING") return Math.ceil(before); return Math.floor(before); diff --git a/src/components/Qc/QcStockInModal.tsx b/src/components/Qc/QcStockInModal.tsx index c6b2b53d..b38d37dd 100644 --- a/src/components/Qc/QcStockInModal.tsx +++ b/src/components/Qc/QcStockInModal.tsx @@ -24,6 +24,7 @@ import PutAwayForm from "../PoDetail/PutAwayForm"; import { GridRowModes, GridRowSelectionModel, useGridApiRef } from "@mui/x-data-grid"; import {msg, submitDialogWithWarning} from "../Swal/CustomAlerts"; import { needsPoQcStockQtyRound } from "../PoDetail/stockQtyRound"; +import { mapPutAwayLinesFromOriginSil } from "../PoDetail/originSilPutAwayQty"; import { INPUT_DATE_FORMAT, arrayToDateString, dayjsToDateTimeString } from "@/app/utils/formatUtil"; import dayjs from "dayjs"; import { fetchPoQrcode } from "@/app/api/pdf/actions"; @@ -73,7 +74,7 @@ interface Props extends CommonProps { // itemDetail: StockInLine & { qcResult?: PurchaseQcResult[] } & { escResult?: EscalationResult[] }; } -/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.4 | 2026-09-10 */ +/** FP-MTMS Version Checklist | Functions Ref. No. 56 | v1.0.5 | 2026-09-18 */ const QcStockInModal: React.FC = ({ open, onClose, @@ -231,7 +232,7 @@ const QcStockInModal: React.FC = ({ // escResult: (d.escResult && d.escResult?.length > 0) ? d.escResult : [], // qcResult: (d.qcResult && d.qcResult?.length > 0) ? d.qcResult : [],//[...dummyQCData], warehouseId: d.defaultWarehouseId ?? 1141, - putAwayLines: d.putAwayLines?.map((line) => ({...line, printQty: 1, _isNew: false, _disableDelete: true})) ?? [], + putAwayLines: mapPutAwayLinesFromOriginSil(d, d.putAwayLines), } as ModalFormInput ) } return undefined