feat(backend): add QC material batch stockStatus helpers.
Normalize available/exhausted filter values and document remaining_qty matching for list filtering. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
5fc460c69a
commit
0f461851b5
2 files changed
+61
No files matched your search
@@ -0,0 +1,24 @@
|
||||
"""质检物料入库批次:按剩余数量过滤的语义辅助。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal
|
||||
from typing import Any, Optional
|
||||
|
||||
|
||||
def normalize_batch_stock_status(stock_status: Optional[str]) -> Optional[str]:
|
||||
"""返回 'available' | 'exhausted';全部 / 空 / 非法 → None(不加剩余数量条件)。"""
|
||||
s = (stock_status or "").strip().lower()
|
||||
if s in ("available", "exhausted"):
|
||||
return s
|
||||
return None
|
||||
|
||||
|
||||
def batch_matches_stock_status(remaining_qty: Any, stock_status: Optional[str]) -> bool:
|
||||
"""纯函数判定(供单测);list_batches 用 SQL 等价条件。"""
|
||||
mode = normalize_batch_stock_status(stock_status)
|
||||
if mode is None:
|
||||
return True
|
||||
qty = Decimal(str(remaining_qty if remaining_qty is not None else 0))
|
||||
if mode == "available":
|
||||
return qty > 0
|
||||
return qty == 0
|
||||
@@ -0,0 +1,37 @@
|
||||
"""质检物料批次列表:剩余库存过滤语义。"""
|
||||
import unittest
|
||||
from decimal import Decimal
|
||||
|
||||
from app.crud.qc_material_batch_stock_status import (
|
||||
batch_matches_stock_status,
|
||||
normalize_batch_stock_status,
|
||||
)
|
||||
|
||||
|
||||
class TestNormalizeBatchStockStatus(unittest.TestCase):
|
||||
def test_available_and_exhausted(self):
|
||||
self.assertEqual(normalize_batch_stock_status("available"), "available")
|
||||
self.assertEqual(normalize_batch_stock_status("exhausted"), "exhausted")
|
||||
self.assertEqual(normalize_batch_stock_status(" Available "), "available")
|
||||
|
||||
def test_all_empty_invalid_map_to_none(self):
|
||||
self.assertIsNone(normalize_batch_stock_status(None))
|
||||
self.assertIsNone(normalize_batch_stock_status(""))
|
||||
self.assertIsNone(normalize_batch_stock_status("all"))
|
||||
self.assertIsNone(normalize_batch_stock_status("bogus"))
|
||||
|
||||
|
||||
class TestBatchMatchesStockStatus(unittest.TestCase):
|
||||
def test_all_always_true(self):
|
||||
self.assertTrue(batch_matches_stock_status(0, "all"))
|
||||
self.assertTrue(batch_matches_stock_status(1, None))
|
||||
|
||||
def test_available_gt_zero(self):
|
||||
self.assertTrue(batch_matches_stock_status(Decimal("0.1"), "available"))
|
||||
self.assertFalse(batch_matches_stock_status(0, "available"))
|
||||
self.assertFalse(batch_matches_stock_status(Decimal("0"), "available"))
|
||||
|
||||
def test_exhausted_eq_zero(self):
|
||||
self.assertTrue(batch_matches_stock_status(0, "exhausted"))
|
||||
self.assertTrue(batch_matches_stock_status(Decimal("0.0000"), "exhausted"))
|
||||
self.assertFalse(batch_matches_stock_status(1, "exhausted"))
|
||||
Reference in new issue
Block a user