qc_lab_test_item.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. """实验室自检项目 CRUD"""
  2. from __future__ import annotations
  3. from datetime import datetime
  4. from typing import Any, Dict, List, Optional, Tuple
  5. from sqlalchemy import and_, func, or_
  6. from sqlalchemy.orm import Session
  7. from app.core.utils import generate_uuid
  8. from app.models.models import BizQcLabTestItem
  9. def _row_to_dict(r: BizQcLabTestItem) -> Dict[str, Any]:
  10. return {
  11. "id": r.id,
  12. "itemCode": r.item_code,
  13. "itemName": r.item_name,
  14. "description": r.description or "",
  15. "status": r.status or "1",
  16. "orderNum": r.order_num if r.order_num is not None else 0,
  17. "remark": r.remark or "",
  18. "createTime": r.create_time.strftime("%Y-%m-%d %H:%M:%S") if r.create_time else "",
  19. "updateTime": r.update_time.strftime("%Y-%m-%d %H:%M:%S") if r.update_time else "",
  20. }
  21. def item_code_exists(
  22. db: Session, code: str, tenant_no: str, exclude_id: Optional[str] = None
  23. ) -> bool:
  24. c = (code or "").strip()
  25. if not c:
  26. return False
  27. q = db.query(BizQcLabTestItem).filter(
  28. BizQcLabTestItem.item_code == c,
  29. BizQcLabTestItem.tenant_no == tenant_no,
  30. BizQcLabTestItem.del_flag == 0,
  31. )
  32. if exclude_id:
  33. q = q.filter(BizQcLabTestItem.id != exclude_id)
  34. return q.first() is not None
  35. def list_lab_items(
  36. db: Session,
  37. *,
  38. page: int = 1,
  39. page_size: int = 10,
  40. keyword: Optional[str] = None,
  41. status: Optional[str] = None,
  42. tenant_no: Optional[str] = None,
  43. user_info=None,
  44. ) -> Tuple[List[Dict[str, Any]], int]:
  45. def _filtered():
  46. q0 = db.query(BizQcLabTestItem).filter(BizQcLabTestItem.del_flag == 0)
  47. if tenant_no:
  48. q0 = q0.filter(BizQcLabTestItem.tenant_no == tenant_no)
  49. kw = (keyword or "").strip()
  50. if kw:
  51. like = f"%{kw}%"
  52. q0 = q0.filter(
  53. or_(BizQcLabTestItem.item_code.like(like), BizQcLabTestItem.item_name.like(like))
  54. )
  55. st = (status or "").strip()
  56. if st in ("0", "1"):
  57. q0 = q0.filter(BizQcLabTestItem.status == st)
  58. if user_info:
  59. from app.core.data_scope import apply_data_scope
  60. q0 = apply_data_scope(q0, BizQcLabTestItem, user_info, db, tenant_no)
  61. return q0
  62. total = _filtered().order_by(None).with_entities(func.count(BizQcLabTestItem.id)).scalar() or 0
  63. page = max(1, page)
  64. page_size = min(max(1, page_size), 100)
  65. rows = (
  66. _filtered()
  67. .order_by(BizQcLabTestItem.order_num.asc(), BizQcLabTestItem.create_time.desc())
  68. .offset((page - 1) * page_size)
  69. .limit(page_size)
  70. .all()
  71. )
  72. return [_row_to_dict(x) for x in rows], int(total)
  73. def list_active_lab_items(db: Session, tenant_no: str, *, user_info=None) -> List[Dict[str, Any]]:
  74. q = db.query(BizQcLabTestItem).filter(
  75. BizQcLabTestItem.tenant_no == tenant_no,
  76. BizQcLabTestItem.del_flag == 0,
  77. BizQcLabTestItem.status == "1",
  78. )
  79. if user_info:
  80. from app.core.data_scope import apply_data_scope
  81. q = apply_data_scope(q, BizQcLabTestItem, user_info, db, tenant_no)
  82. rows = q.order_by(BizQcLabTestItem.order_num.asc(), BizQcLabTestItem.create_time.desc()).all()
  83. return [_row_to_dict(x) for x in rows]
  84. def get_lab_item(
  85. db: Session, row_id: str, tenant_no: Optional[str] = None
  86. ) -> Optional[BizQcLabTestItem]:
  87. q = db.query(BizQcLabTestItem).filter(
  88. BizQcLabTestItem.id == row_id, BizQcLabTestItem.del_flag == 0
  89. )
  90. if tenant_no:
  91. q = q.filter(BizQcLabTestItem.tenant_no == tenant_no)
  92. return q.first()
  93. def create_lab_item(
  94. db: Session,
  95. *,
  96. item_code: str,
  97. item_name: str,
  98. description: Optional[str] = None,
  99. status: str = "1",
  100. tenant_no: str,
  101. order_num: Optional[int] = None,
  102. remark: Optional[str] = None,
  103. user_id: Optional[str] = None,
  104. create_dept_id: str = "",
  105. ) -> BizQcLabTestItem:
  106. code = (item_code or "").strip()
  107. if not code:
  108. raise ValueError("项目编码不能为空")
  109. if item_code_exists(db, code, tenant_no):
  110. raise ValueError("项目编码已存在")
  111. name = (item_name or "").strip()
  112. if not name:
  113. raise ValueError("项目名称不能为空")
  114. st = (status or "1").strip()
  115. if st not in ("0", "1"):
  116. raise ValueError("状态无效")
  117. obj = BizQcLabTestItem(
  118. id=generate_uuid(),
  119. item_code=code,
  120. item_name=name,
  121. description=(description or "").strip() or None,
  122. status=st,
  123. tenant_no=tenant_no,
  124. order_num=order_num if order_num is not None else 0,
  125. remark=(remark or "").strip() or None,
  126. create_by=user_id,
  127. create_dept_id=create_dept_id or "",
  128. create_time=datetime.now(),
  129. update_by=user_id,
  130. update_time=datetime.now(),
  131. del_flag=0,
  132. )
  133. db.add(obj)
  134. db.commit()
  135. db.refresh(obj)
  136. return obj
  137. def update_lab_item(
  138. db: Session,
  139. row_id: str,
  140. *,
  141. item_code: Optional[str] = None,
  142. item_name: Optional[str] = None,
  143. description: Optional[str] = None,
  144. status: Optional[str] = None,
  145. order_num: Optional[int] = None,
  146. remark: Optional[str] = None,
  147. user_id: Optional[str] = None,
  148. tenant_no: Optional[str] = None,
  149. ) -> BizQcLabTestItem:
  150. obj = get_lab_item(db, row_id, tenant_no=tenant_no)
  151. if not obj:
  152. raise ValueError("项目不存在")
  153. if item_code is not None:
  154. code = item_code.strip()
  155. if not code:
  156. raise ValueError("项目编码不能为空")
  157. if code != obj.item_code and item_code_exists(db, code, obj.tenant_no, exclude_id=row_id):
  158. raise ValueError("项目编码已存在")
  159. obj.item_code = code
  160. if item_name is not None:
  161. name = (item_name or "").strip()
  162. if not name:
  163. raise ValueError("项目名称不能为空")
  164. obj.item_name = name
  165. if description is not None:
  166. obj.description = (description or "").strip() or None
  167. if status is not None:
  168. st = status.strip()
  169. if st not in ("0", "1"):
  170. raise ValueError("状态无效")
  171. obj.status = st
  172. if order_num is not None:
  173. obj.order_num = order_num
  174. if remark is not None:
  175. obj.remark = (remark or "").strip() or None
  176. obj.update_by = user_id
  177. obj.update_time = datetime.now()
  178. db.add(obj)
  179. db.commit()
  180. db.refresh(obj)
  181. return obj
  182. def soft_delete_lab_item(db: Session, row_id: str, tenant_no: Optional[str] = None) -> None:
  183. obj = get_lab_item(db, row_id, tenant_no=tenant_no)
  184. if not obj:
  185. raise ValueError("项目不存在")
  186. obj.del_flag = 1
  187. obj.update_time = datetime.now()
  188. db.add(obj)
  189. db.commit()