|
|
@@ -241,16 +241,24 @@ const NewCreateItem: React.FC<Props> = ({ filterArgs, searchQuery, onPickOrderCr |
|
|
|
|
|
|
|
|
// Handle quantity change in search results |
|
|
// Handle quantity change in search results |
|
|
const handleSearchQtyChange = useCallback((itemId: number, newQty: number | null) => { |
|
|
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 => |
|
|
setFilteredItems(prev => |
|
|
prev.map(item => |
|
|
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 |
|
|
// Auto-update created items if this item exists there |
|
|
setCreatedItems(prev => |
|
|
setCreatedItems(prev => |
|
|
prev.map(item => |
|
|
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<Props> = ({ filterArgs, searchQuery, onPickOrderCr |
|
|
const handleQtyChange = useCallback((itemId: number, newQty: number) => { |
|
|
const handleQtyChange = useCallback((itemId: number, newQty: number) => { |
|
|
setCreatedItems(prev => |
|
|
setCreatedItems(prev => |
|
|
prev.map(item => |
|
|
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")); |
|
|
alert(t("Please select at least one item to submit")); |
|
|
return; |
|
|
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",不再强制用户选择 |
|
|
// 修复:自动填充 type 为 "Consumable",不再强制用户选择 |
|
|
// if (!data.type) { |
|
|
// if (!data.type) { |
|
|
@@ -946,6 +968,7 @@ const handleQtyBlur = useCallback((itemId: number) => { |
|
|
}} |
|
|
}} |
|
|
inputProps={{ |
|
|
inputProps={{ |
|
|
min: 1, |
|
|
min: 1, |
|
|
|
|
|
max: item.currentStockBalance || 0, |
|
|
step: 1, |
|
|
step: 1, |
|
|
style: { textAlign: 'center' } |
|
|
style: { textAlign: 'center' } |
|
|
}} |
|
|
}} |
|
|
@@ -1033,6 +1056,7 @@ const handleQtyBlur = useCallback((itemId: number) => { |
|
|
}} |
|
|
}} |
|
|
inputProps={{ |
|
|
inputProps={{ |
|
|
min: 1, |
|
|
min: 1, |
|
|
|
|
|
max: item.currentStockBalance || 0, |
|
|
step: 1, |
|
|
step: 1, |
|
|
style: { textAlign: 'center' } // Center the text |
|
|
style: { textAlign: 'center' } // Center the text |
|
|
}} |
|
|
}} |
|
|
@@ -1118,9 +1142,15 @@ const handleQtyBlur = useCallback((itemId: number) => { |
|
|
|
|
|
|
|
|
// 添加数量变更处理函数 |
|
|
// 添加数量变更处理函数 |
|
|
const handleSecondSearchQtyChange = useCallback((itemId: number, newQty: number | null) => { |
|
|
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 => |
|
|
setSecondSearchResults(prev => |
|
|
prev.map(item => |
|
|
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={{ |
|
|
inputProps={{ |
|
|
|
|
|
min: 1, |
|
|
|
|
|
max: item.currentStockBalance || 0, |
|
|
style: { textAlign: 'center' } |
|
|
style: { textAlign: 'center' } |
|
|
}} |
|
|
}} |
|
|
sx={{ |
|
|
sx={{ |
|
|
@@ -1797,6 +1829,8 @@ const CustomSearchResultsTable = () => { |
|
|
handleQtyBlur(item.id); |
|
|
handleQtyBlur(item.id); |
|
|
}} |
|
|
}} |
|
|
inputProps={{ |
|
|
inputProps={{ |
|
|
|
|
|
min: 1, |
|
|
|
|
|
max: item.currentStockBalance || 0, |
|
|
style: { textAlign: 'center' } |
|
|
style: { textAlign: 'center' } |
|
|
}} |
|
|
}} |
|
|
sx={{ |
|
|
sx={{ |
|
|
|