sample_storage_cert_qc.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. """样本储存证质检信息 CRUD。"""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from typing import Any, Dict, Optional
  5. from sqlalchemy.orm import Session
  6. from app.core.utils import generate_uuid
  7. from app.models.models import (
  8. BizCellSampleType,
  9. BizCollectionProtocol,
  10. BizProtocolPartyCustomer,
  11. BizProtocolSample,
  12. BizSampleStorageCertQc,
  13. )
  14. from app.services.sample_storage_cert_qc import (
  15. dumps_payload,
  16. empty_detail,
  17. loads_payload,
  18. normalize_payload,
  19. resolve_sample_type_key,
  20. )
  21. def _row_to_dict(
  22. row: BizSampleStorageCertQc,
  23. *,
  24. protocol_code: str = "",
  25. mother_name: str = "",
  26. sample_type_name: str = "",
  27. ) -> Dict[str, Any]:
  28. return {
  29. "id": row.id,
  30. "sampleCode": row.sample_code or "",
  31. "labFlowCode": row.sample_code or "",
  32. "protocolCode": protocol_code or "",
  33. "motherName": mother_name or "",
  34. "sampleTypeName": sample_type_name or "",
  35. "sampleTypeKey": row.sample_type_key,
  36. "collectionProtocolId": row.collection_protocol_id or "",
  37. "qcWorkOrderId": row.qc_work_order_id or "",
  38. "filledFlag": str(row.filled_flag or "0") == "1",
  39. "payload": loads_payload(row.payload),
  40. "createTime": row.create_time.isoformat(sep=" ", timespec="seconds") if row.create_time else "",
  41. "updateTime": row.update_time.isoformat(sep=" ", timespec="seconds") if row.update_time else "",
  42. }
  43. def _load_sample_context(db: Session, tenant_no: str, sample_code: str):
  44. code = (sample_code or "").strip()
  45. if not code:
  46. return None
  47. sample = (
  48. db.query(BizProtocolSample)
  49. .filter(
  50. BizProtocolSample.tenant_no == tenant_no,
  51. BizProtocolSample.sample_code == code,
  52. BizProtocolSample.del_flag == 0,
  53. )
  54. .first()
  55. )
  56. if not sample:
  57. return None
  58. type_name = ""
  59. if sample.sample_type_id:
  60. st = (
  61. db.query(BizCellSampleType)
  62. .filter(
  63. BizCellSampleType.id == sample.sample_type_id,
  64. BizCellSampleType.del_flag == 0,
  65. )
  66. .first()
  67. )
  68. if st:
  69. type_name = st.type_name or ""
  70. protocol_code = ""
  71. mother_name = ""
  72. if sample.collection_protocol_id:
  73. proto = (
  74. db.query(BizCollectionProtocol)
  75. .filter(
  76. BizCollectionProtocol.id == sample.collection_protocol_id,
  77. BizCollectionProtocol.tenant_no == tenant_no,
  78. BizCollectionProtocol.del_flag == 0,
  79. )
  80. .first()
  81. )
  82. if proto:
  83. protocol_code = proto.protocol_no or ""
  84. pc = (
  85. db.query(BizProtocolPartyCustomer)
  86. .filter(
  87. BizProtocolPartyCustomer.collection_protocol_id == sample.collection_protocol_id,
  88. BizProtocolPartyCustomer.tenant_no == tenant_no,
  89. BizProtocolPartyCustomer.del_flag == 0,
  90. )
  91. .first()
  92. )
  93. if pc:
  94. mother_name = pc.mother_name or ""
  95. return sample, type_name, protocol_code, mother_name
  96. def get_detail(db: Session, tenant_no: str, sample_code: str) -> Optional[Dict[str, Any]]:
  97. """样本不存在返回 None;存在但未填返回 empty_detail。"""
  98. ctx = _load_sample_context(db, tenant_no, sample_code)
  99. if not ctx:
  100. return None
  101. sample, type_name, protocol_code, mother_name = ctx
  102. key = resolve_sample_type_key(type_name)
  103. row = (
  104. db.query(BizSampleStorageCertQc)
  105. .filter(
  106. BizSampleStorageCertQc.tenant_no == tenant_no,
  107. BizSampleStorageCertQc.sample_code == sample.sample_code,
  108. BizSampleStorageCertQc.del_flag == 0,
  109. )
  110. .first()
  111. )
  112. if not row:
  113. return empty_detail(
  114. sample_code=sample.sample_code or "",
  115. protocol_code=protocol_code,
  116. mother_name=mother_name,
  117. sample_type_name=type_name,
  118. sample_type_key=key,
  119. collection_protocol_id=sample.collection_protocol_id or "",
  120. )
  121. return _row_to_dict(
  122. row,
  123. protocol_code=protocol_code,
  124. mother_name=mother_name,
  125. sample_type_name=type_name,
  126. )
  127. def upsert(
  128. db: Session,
  129. *,
  130. tenant_no: str,
  131. user_id: str,
  132. sample_code: str,
  133. payload: Any,
  134. qc_work_order_id: Optional[str] = None,
  135. ) -> Dict[str, Any]:
  136. ctx = _load_sample_context(db, tenant_no, sample_code)
  137. if not ctx:
  138. raise ValueError("样本不存在")
  139. sample, type_name, protocol_code, mother_name = ctx
  140. key = resolve_sample_type_key(type_name)
  141. if not key:
  142. raise ValueError("该样本类型不支持填写储存证质检信息")
  143. clean = normalize_payload(payload)
  144. now = datetime.now()
  145. row = (
  146. db.query(BizSampleStorageCertQc)
  147. .filter(
  148. BizSampleStorageCertQc.tenant_no == tenant_no,
  149. BizSampleStorageCertQc.sample_code == sample.sample_code,
  150. BizSampleStorageCertQc.del_flag == 0,
  151. )
  152. .first()
  153. )
  154. if not row:
  155. row = BizSampleStorageCertQc(
  156. id=generate_uuid(),
  157. sample_code=sample.sample_code,
  158. collection_protocol_id=sample.collection_protocol_id,
  159. qc_work_order_id=(qc_work_order_id or None),
  160. sample_type_key=key,
  161. payload=dumps_payload(clean),
  162. filled_flag="1",
  163. tenant_no=tenant_no,
  164. create_by=user_id,
  165. create_dept_id="",
  166. create_time=now,
  167. update_by=user_id,
  168. update_time=now,
  169. del_flag=0,
  170. )
  171. db.add(row)
  172. else:
  173. row.collection_protocol_id = sample.collection_protocol_id
  174. row.sample_type_key = key
  175. row.payload = dumps_payload(clean)
  176. row.filled_flag = "1"
  177. if qc_work_order_id:
  178. row.qc_work_order_id = qc_work_order_id
  179. row.update_by = user_id
  180. row.update_time = now
  181. db.commit()
  182. db.refresh(row)
  183. return _row_to_dict(
  184. row,
  185. protocol_code=protocol_code,
  186. mother_name=mother_name,
  187. sample_type_name=type_name,
  188. )