diff --git a/src/app/api/pickOrder/actions.ts b/src/app/api/pickOrder/actions.ts index 69c9252..46d63ac 100644 --- a/src/app/api/pickOrder/actions.ts +++ b/src/app/api/pickOrder/actions.ts @@ -462,6 +462,7 @@ export interface LaneBtn { loadingSequence?: number | null; unassigned: number; total: number; + handlerName: string; } export interface QrPickBatchSubmitRequest { @@ -804,6 +805,7 @@ export const fetchFGPickOrdersByUserId = async (userId: number) => { }; /** DO workbench: FG headers from `delivery_order_pick_order`, not `do_pick_order_line`. */ + /* export const fetchFGPickOrdersByUserIdWorkbench = async (userId: number) => { return serverFetchJson( @@ -1190,6 +1192,7 @@ export const fetchAllPickOrderLotsHierarchical = cache(async (userId: number): P }); /** DO workbench: hierarchical lots where header is `delivery_order_pick_order`. */ +/* export const fetchAllPickOrderLotsHierarchicalWorkbench = cache(async (userId: number): Promise => { try { const data = await serverFetchJson( @@ -1208,6 +1211,7 @@ export const fetchAllPickOrderLotsHierarchicalWorkbench = cache(async (userId: n }; } }); +*/ export const fetchLotDetailsByDoPickOrderRecordId = async (doPickOrderRecordId: number): Promise<{ fgInfo: any; pickOrders: any[]; diff --git a/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx b/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx index 995c74b..b7c50c7 100644 --- a/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx +++ b/src/components/FinishedGoodSearch/FinishedGoodFloorLanePanel.tsx @@ -601,39 +601,55 @@ const getDateLabel = (offset: number) => { flexWrap="wrap" sx={{ flex: 1, gap: 1 }} > - {slots.map((slot) => ( - - ))} + {slots.map((slot) => { + const hasHandler = + !!slot.lane.handlerName?.trim() && slot.lane.total > slot.lane.unassigned; + + return ( + + ); +})} diff --git a/src/components/PickOrderSearch/newcreatitem.tsx b/src/components/PickOrderSearch/newcreatitem.tsx index 8eda1b2..4cd647e 100644 --- a/src/components/PickOrderSearch/newcreatitem.tsx +++ b/src/components/PickOrderSearch/newcreatitem.tsx @@ -241,16 +241,24 @@ const NewCreateItem: React.FC = ({ filterArgs, searchQuery, onPickOrderCr // Handle quantity change in search results const handleSearchQtyChange = useCallback((itemId: number, newQty: number | null) => { + const getClampedQty = (qty: number | null, stock?: number) => { + if (qty === null) return null; + const maxQty = Math.max(0, stock ?? 0); + return Math.max(1, Math.min(qty, maxQty)); + }; + setFilteredItems(prev => prev.map(item => - item.id === itemId ? { ...item, qty: newQty } : item + item.id === itemId ? { ...item, qty: getClampedQty(newQty, item.currentStockBalance) } : item ) ); // Auto-update created items if this item exists there setCreatedItems(prev => prev.map(item => - item.itemId === itemId ? { ...item, qty: newQty || 1 } : item + item.itemId === itemId + ? { ...item, qty: getClampedQty(newQty, item.currentStockBalance) || 1 } + : item ) ); }, []); @@ -297,7 +305,12 @@ const NewCreateItem: React.FC = ({ filterArgs, searchQuery, onPickOrderCr const handleQtyChange = useCallback((itemId: number, newQty: number) => { setCreatedItems(prev => prev.map(item => - item.itemId === itemId ? { ...item, qty: newQty } : item + item.itemId === itemId + ? { + ...item, + qty: Math.max(1, Math.min(newQty, Math.max(0, item.currentStockBalance ?? 0))), + } + : item ) ); }, []); @@ -567,6 +580,15 @@ const handleQtyBlur = useCallback((itemId: number) => { alert(t("Please select at least one item to submit")); return; } + + const invalidQtyItems = selectedCreatedItems.filter((item) => { + const stock = item.currentStockBalance ?? 0; + return item.qty <= 0 || item.qty > stock; + }); + if (invalidQtyItems.length > 0) { + alert(t("Order quantity cannot exceed available stock.")); + return; + } // 修复:自动填充 type 为 "Consumable",不再强制用户选择 // if (!data.type) { @@ -946,6 +968,7 @@ const handleQtyBlur = useCallback((itemId: number) => { }} inputProps={{ min: 1, + max: item.currentStockBalance || 0, step: 1, style: { textAlign: 'center' } }} @@ -1033,6 +1056,7 @@ const handleQtyBlur = useCallback((itemId: number) => { }} inputProps={{ min: 1, + max: item.currentStockBalance || 0, step: 1, style: { textAlign: 'center' } // Center the text }} @@ -1118,9 +1142,15 @@ const handleQtyBlur = useCallback((itemId: number) => { // 添加数量变更处理函数 const handleSecondSearchQtyChange = useCallback((itemId: number, newQty: number | null) => { + const getClampedQty = (qty: number | null, stock?: number) => { + if (qty === null) return null; + const maxQty = Math.max(0, stock ?? 0); + return Math.max(1, Math.min(qty, maxQty)); + }; + setSecondSearchResults(prev => prev.map(item => - item.id === itemId ? { ...item, qty: newQty } : item + item.id === itemId ? { ...item, qty: getClampedQty(newQty, item.currentStockBalance) } : item ) ); @@ -1254,6 +1284,8 @@ const handleQtyBlur = useCallback((itemId: number) => { } }} inputProps={{ + min: 1, + max: item.currentStockBalance || 0, style: { textAlign: 'center' } }} sx={{ @@ -1797,6 +1829,8 @@ const CustomSearchResultsTable = () => { handleQtyBlur(item.id); }} inputProps={{ + min: 1, + max: item.currentStockBalance || 0, style: { textAlign: 'center' } }} sx={{