Jelajahi Sumber

feat(storage-release): add hide-voided predicate helpers

Document protocol inactive and all-inbound-WO-void semantics for list filtering.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 3 bulan lalu
induk
melakukan
a922ad12f4

+ 15 - 0
backend/app/crud/storage_release_review.py

@@ -8,6 +8,7 @@ from sqlalchemy import and_, exists, func, or_
 from sqlalchemy.orm import Session
 
 from app.core.db_collation import eq_unicode
+from app.core.protocol_status_display import INACTIVE_PROTOCOL_STATUSES
 from app.core.utils import generate_uuid
 from app.utils.sample_special import sample_special_to_dict
 from app.models.models import (
@@ -160,6 +161,20 @@ def normalize_ready_for_review_only(raw) -> Optional[bool]:
     return None
 
 
+def is_inactive_protocol_status_for_hide(status) -> bool:
+    """True when protocol/donation status is yzf or sdfq (list-hide rule)."""
+    code = (status or "").strip().lower()
+    return code in INACTIVE_PROTOCOL_STATUSES
+
+
+def inbound_work_orders_all_void(statuses) -> bool:
+    """True when there is ≥1 non-empty status and every one equals yzf."""
+    cleaned = [(s or "").strip() for s in (statuses or [])]
+    if not cleaned or not any(s for s in cleaned):
+        return False
+    return all(s.lower() == "yzf" for s in cleaned)
+
+
 def _qc_work_order_exists_for_review_sample(
     tenant_no: str, *, unfinished_only: bool = False
 ):

+ 35 - 0
backend/tests/test_storage_release_review_hide_voided.py

@@ -0,0 +1,35 @@
+from app.core.protocol_status_display import INACTIVE_PROTOCOL_STATUSES
+from app.crud.storage_release_review import (
+    inbound_work_orders_all_void,
+    is_inactive_protocol_status_for_hide,
+)
+
+
+def test_inactive_protocol_statuses_match_shared_constant():
+    assert is_inactive_protocol_status_for_hide("yzf") is True
+    assert is_inactive_protocol_status_for_hide("sdfq") is True
+    assert is_inactive_protocol_status_for_hide(" SDFQ ") is True
+    assert is_inactive_protocol_status_for_hide("sxz") is False
+    assert is_inactive_protocol_status_for_hide("zky") is False
+    assert is_inactive_protocol_status_for_hide("") is False
+    assert is_inactive_protocol_status_for_hide(None) is False
+    assert set(INACTIVE_PROTOCOL_STATUSES) == {"yzf", "sdfq"}
+
+
+def test_inbound_work_orders_all_void_requires_at_least_one():
+    assert inbound_work_orders_all_void([]) is False
+    assert inbound_work_orders_all_void([""]) is False
+    assert inbound_work_orders_all_void(["  "]) is False
+
+
+def test_inbound_work_orders_all_void_true_when_every_status_is_yzf():
+    assert inbound_work_orders_all_void(["yzf"]) is True
+    assert inbound_work_orders_all_void(["yzf", "yzf"]) is True
+    assert inbound_work_orders_all_void([" YZF ", "yzf"]) is True
+
+
+def test_inbound_work_orders_all_void_false_when_any_non_void():
+    assert inbound_work_orders_all_void(["yzf", "ywc"]) is False
+    assert inbound_work_orders_all_void(["dpz"]) is False
+    assert inbound_work_orders_all_void(["ywc"]) is False
+    assert inbound_work_orders_all_void(["yzf", ""]) is False