sample_special.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. """协议/捐赠样本 · 特殊标记字段工具。"""
  2. from __future__ import annotations
  3. from typing import Any, Dict, Optional
  4. def _truthy_flag(value: Any) -> bool:
  5. if value is True or value == 1:
  6. return True
  7. if isinstance(value, str):
  8. return value.strip().lower() in ("1", "true", "yes")
  9. return False
  10. def sample_special_to_dict(sample: Any) -> Dict[str, Any]:
  11. if sample is None:
  12. return {"isSpecial": False, "specialRemark": ""}
  13. return {
  14. "isSpecial": bool(getattr(sample, "is_special", 0)),
  15. "specialRemark": (getattr(sample, "special_remark", None) or "").strip(),
  16. }
  17. def validate_sample_special_raw(raw: dict, *, index: Optional[int] = None) -> None:
  18. is_special = _truthy_flag(raw.get("is_special"))
  19. remark = (raw.get("special_remark") or "").strip()
  20. prefix = f"样本第{index + 1}行:" if index is not None else ""
  21. if is_special and not remark:
  22. raise ValueError(f"{prefix}特殊样本须填写特殊说明")
  23. if len(remark) > 256:
  24. raise ValueError(f"{prefix}特殊说明不能超过256个字符")
  25. def apply_sample_special_fields(obj: Any, raw: dict) -> None:
  26. is_special = _truthy_flag(raw.get("is_special"))
  27. remark = (raw.get("special_remark") or "").strip()
  28. obj.is_special = 1 if is_special else 0
  29. obj.special_remark = remark if is_special and remark else None
  30. def apply_inbound_sample_special_mark_fields(obj: Any, raw: dict) -> None:
  31. """质检等场景:取消勾选时保留 special_remark,仅清除 is_special 标记。"""
  32. is_special = _truthy_flag(raw.get("is_special"))
  33. remark = (raw.get("special_remark") or "").strip()
  34. obj.is_special = 1 if is_special else 0
  35. if is_special:
  36. obj.special_remark = remark if remark else None
  37. elif remark:
  38. obj.special_remark = remark
  39. def apply_special_to_item_from_samples(
  40. item: Dict[str, Any],
  41. *,
  42. source: str,
  43. protocol_sample_id: str,
  44. donation_sample_id: str,
  45. protocol_samples: Dict[str, Any],
  46. donation_samples: Dict[str, Any],
  47. ) -> None:
  48. sample = None
  49. if source == "research_donation":
  50. sample = donation_samples.get(donation_sample_id or "")
  51. else:
  52. sample = protocol_samples.get(protocol_sample_id or "")
  53. item.update(sample_special_to_dict(sample))