test_sample_code_correction.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. """样本编码全链路纠错服务测试。"""
  2. from datetime import datetime
  3. from sqlalchemy import create_engine
  4. from sqlalchemy.orm import sessionmaker
  5. from app.models.base import Base
  6. from app.models.models import (
  7. BizCellProduct,
  8. BizProductionTaskInput,
  9. BizProductionWorkOrder,
  10. BizProtocolPaymentSchedule,
  11. BizProtocolPaymentTransfer,
  12. BizProtocolSample,
  13. BizProtocolSamplePayment,
  14. BizProtocolSampleTransport,
  15. BizQcTask,
  16. BizQcWorkOrder,
  17. BizSampleCode,
  18. BizSampleCodeCorrectionLog,
  19. BizSampleCustomerService,
  20. BizSampleFreightItem,
  21. BizSampleInsurance,
  22. BizSampleProductionReception,
  23. BizSampleReception,
  24. BizSampleStorageCert,
  25. BizSampleStorageCertQc,
  26. BizStorageReleaseReview,
  27. )
  28. from app.models.research_donation import (
  29. BizResearchDonationSample,
  30. BizResearchDonationSampleTransport,
  31. )
  32. from app.services import sample_code_correction as svc
  33. def _session():
  34. engine = create_engine("sqlite:///:memory:")
  35. Base.metadata.create_all(
  36. engine,
  37. tables=[
  38. BizProtocolSample.__table__,
  39. BizResearchDonationSample.__table__,
  40. BizSampleCode.__table__,
  41. BizProtocolSamplePayment.__table__,
  42. BizProtocolPaymentSchedule.__table__,
  43. BizProtocolPaymentTransfer.__table__,
  44. BizProtocolSampleTransport.__table__,
  45. BizResearchDonationSampleTransport.__table__,
  46. BizSampleFreightItem.__table__,
  47. BizSampleReception.__table__,
  48. BizQcWorkOrder.__table__,
  49. BizQcTask.__table__,
  50. BizStorageReleaseReview.__table__,
  51. BizSampleStorageCertQc.__table__,
  52. BizSampleProductionReception.__table__,
  53. BizProductionWorkOrder.__table__,
  54. BizProductionTaskInput.__table__,
  55. BizSampleStorageCert.__table__,
  56. BizSampleInsurance.__table__,
  57. BizSampleCustomerService.__table__,
  58. BizSampleCodeCorrectionLog.__table__,
  59. BizCellProduct.__table__,
  60. ],
  61. )
  62. return sessionmaker(bind=engine)()
  63. def _add_protocol_sample(db, *, code="OLD-001", sample_code_id=None, sid="ps-1"):
  64. now = datetime.now()
  65. row = BizProtocolSample(
  66. id=sid,
  67. collection_protocol_id="cp-1",
  68. sample_code_id=sample_code_id,
  69. sample_code=code,
  70. tenant_no="tenant-a",
  71. create_dept_id="",
  72. create_time=now,
  73. update_time=now,
  74. del_flag=0,
  75. )
  76. db.add(row)
  77. return row
  78. def test_preview_and_apply_cascades_downstream():
  79. db = _session()
  80. now = datetime.now()
  81. pool = BizSampleCode(
  82. id="pool-old",
  83. sample_code="OLD-001",
  84. issued=1,
  85. tenant_no="tenant-a",
  86. create_dept_id="",
  87. create_time=now,
  88. update_time=now,
  89. del_flag=0,
  90. )
  91. db.add(pool)
  92. _add_protocol_sample(db, code="OLD-001", sample_code_id="pool-old")
  93. db.add(
  94. BizSampleReception(
  95. id="recv-1",
  96. protocol_sample_id="ps-1",
  97. collection_protocol_id="cp-1",
  98. reception_time=now,
  99. accept_conclusion="js",
  100. sample_code="OLD-001",
  101. reception_source="cell_storage",
  102. tenant_no="tenant-a",
  103. create_dept_id="",
  104. create_time=now,
  105. update_time=now,
  106. del_flag=0,
  107. )
  108. )
  109. db.add(
  110. BizQcWorkOrder(
  111. id="qc-1",
  112. work_order_no="QC-001",
  113. sample_code="OLD-001",
  114. reception_source="cell_storage",
  115. tenant_no="tenant-a",
  116. create_dept_id="",
  117. create_time=now,
  118. update_time=now,
  119. del_flag=0,
  120. )
  121. )
  122. db.add(
  123. BizQcTask(
  124. id="qct-1",
  125. work_order_id="qc-1",
  126. task_no="QCT-001",
  127. task_type="sysz",
  128. source_line_id="line-1",
  129. item_code="ITEM",
  130. item_name="项目",
  131. sample_code="OLD-001",
  132. tenant_no="tenant-a",
  133. create_dept_id="",
  134. create_time=now,
  135. update_time=now,
  136. del_flag=0,
  137. )
  138. )
  139. db.add(
  140. BizProductionWorkOrder(
  141. id="pwo-1",
  142. work_order_no="PWO-001",
  143. sample_code="OLD-001",
  144. reception_source="cell_storage",
  145. tenant_no="tenant-a",
  146. create_dept_id="",
  147. create_time=now,
  148. update_time=now,
  149. del_flag=0,
  150. )
  151. )
  152. db.add(
  153. BizProductionTaskInput(
  154. id="pti-1",
  155. task_id="pt-1",
  156. input_type="sample",
  157. input_code="OLD-001",
  158. tenant_no="tenant-a",
  159. create_dept_id="",
  160. create_time=now,
  161. update_time=now,
  162. del_flag=0,
  163. )
  164. )
  165. db.add(
  166. BizSampleStorageCert(
  167. id="cert-1",
  168. sample_code="OLD-001",
  169. tenant_no="tenant-a",
  170. create_dept_id="",
  171. create_time=now,
  172. update_time=now,
  173. del_flag=0,
  174. )
  175. )
  176. db.commit()
  177. preview = svc.preview_correction(
  178. db,
  179. tenant_no="tenant-a",
  180. reception_source="cell_storage",
  181. old_sample_code="OLD-001",
  182. new_sample_code="NEW-001",
  183. )
  184. assert preview["ok"] is True
  185. assert preview["totalAffectedRows"] >= 5
  186. tables = {i["table"] for i in preview["impacts"]}
  187. assert "biz_protocol_sample" in tables
  188. assert "biz_sample_reception" in tables
  189. assert "biz_qc_work_order" in tables
  190. assert "biz_production_task_input" in tables
  191. result = svc.apply_correction(
  192. db,
  193. tenant_no="tenant-a",
  194. reception_source="cell_storage",
  195. old_sample_code="OLD-001",
  196. new_sample_code="NEW-001",
  197. reason="填错编码",
  198. user_id="u1",
  199. )
  200. assert result["ok"] is True
  201. ps = (
  202. db.query(BizProtocolSample)
  203. .filter(BizProtocolSample.id == "ps-1")
  204. .one()
  205. )
  206. assert ps.sample_code == "NEW-001"
  207. pool_row = db.query(BizSampleCode).filter(BizSampleCode.id == "pool-old").one()
  208. assert pool_row.sample_code == "NEW-001"
  209. assert (
  210. db.query(BizSampleReception)
  211. .filter(BizSampleReception.id == "recv-1")
  212. .one()
  213. .sample_code
  214. == "NEW-001"
  215. )
  216. assert (
  217. db.query(BizQcTask).filter(BizQcTask.id == "qct-1").one().sample_code
  218. == "NEW-001"
  219. )
  220. assert (
  221. db.query(BizProductionTaskInput)
  222. .filter(BizProductionTaskInput.id == "pti-1")
  223. .one()
  224. .input_code
  225. == "NEW-001"
  226. )
  227. assert (
  228. db.query(BizSampleStorageCert)
  229. .filter(BizSampleStorageCert.id == "cert-1")
  230. .one()
  231. .sample_code
  232. == "NEW-001"
  233. )
  234. log = db.query(BizSampleCodeCorrectionLog).one()
  235. assert log.old_sample_code == "OLD-001"
  236. assert log.new_sample_code == "NEW-001"
  237. assert log.reason == "填错编码"
  238. def test_preview_blocks_when_new_code_occupied():
  239. db = _session()
  240. _add_protocol_sample(db, code="OLD-001", sid="ps-1")
  241. _add_protocol_sample(db, code="NEW-001", sid="ps-2")
  242. db.commit()
  243. preview = svc.preview_correction(
  244. db,
  245. tenant_no="tenant-a",
  246. reception_source="cell_storage",
  247. old_sample_code="OLD-001",
  248. new_sample_code="NEW-001",
  249. )
  250. assert preview["ok"] is False
  251. assert any("占用" in b for b in preview["blockers"])
  252. def test_donation_source_updates_donation_sample():
  253. db = _session()
  254. now = datetime.now()
  255. db.add(
  256. BizResearchDonationSample(
  257. id="ds-1",
  258. research_donation_id="rd-1",
  259. sample_code="JZ2026010001",
  260. tenant_no="tenant-a",
  261. create_dept_id="",
  262. create_time=now,
  263. update_time=now,
  264. del_flag=0,
  265. )
  266. )
  267. db.add(
  268. BizSampleReception(
  269. id="recv-d",
  270. protocol_sample_id="",
  271. collection_protocol_id="",
  272. donation_sample_id="ds-1",
  273. research_donation_id="rd-1",
  274. reception_time=now,
  275. accept_conclusion="js",
  276. sample_code="JZ2026010001",
  277. reception_source="research_donation",
  278. tenant_no="tenant-a",
  279. create_dept_id="",
  280. create_time=now,
  281. update_time=now,
  282. del_flag=0,
  283. )
  284. )
  285. db.commit()
  286. result = svc.apply_correction(
  287. db,
  288. tenant_no="tenant-a",
  289. reception_source="research_donation",
  290. old_sample_code="JZ2026010001",
  291. new_sample_code="JZ2026010099",
  292. reason="捐赠码纠错",
  293. user_id="u1",
  294. )
  295. assert result["ok"] is True
  296. assert (
  297. db.query(BizResearchDonationSample)
  298. .filter(BizResearchDonationSample.id == "ds-1")
  299. .one()
  300. .sample_code
  301. == "JZ2026010099"
  302. )
  303. assert (
  304. db.query(BizSampleReception)
  305. .filter(BizSampleReception.id == "recv-d")
  306. .one()
  307. .sample_code
  308. == "JZ2026010099"
  309. )