outbound_release_review.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. """出库放行审核 API"""
  2. from typing import Optional
  3. from fastapi import APIRouter, Depends, Query
  4. from sqlalchemy.orm import Session
  5. from app.core.database import get_db
  6. from app.core.menu_guard import require_admin_or_super_admin, require_menu_code
  7. from app.core.response import error_response, success_response
  8. from app.crud import outbound_release_review as svc
  9. from app.models.models import SysUser
  10. from app.schemas.outbound_release_review import (
  11. OutboundBatchReviewBody,
  12. OutboundReviewSubmitBody,
  13. )
  14. from app.schemas.outbound_release_material import OutboundReleaseMaterialSaveBody
  15. from app.crud import outbound_release_material as orm_svc
  16. router = APIRouter(prefix="/web/admin", tags=["出库放行审核"])
  17. def _get_tenant_no(db: Session, user: dict) -> str:
  18. user_id = user.get("user_id")
  19. if not user_id:
  20. raise PermissionError("用户身份信息缺失")
  21. sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
  22. if not sys_user or not sys_user.tenant_no:
  23. raise PermissionError("用户租户信息缺失")
  24. return sys_user.tenant_no
  25. def _get_current_user_id(user: dict) -> str:
  26. user_id = user.get("user_id")
  27. if not user_id:
  28. raise PermissionError("用户身份信息缺失")
  29. return str(user_id)
  30. @router.get("/pilot-release-reviews")
  31. async def list_pilot_release_reviews(
  32. page: int = Query(1, ge=1),
  33. pageSize: int = Query(10, ge=1, le=100),
  34. keyword: Optional[str] = None,
  35. reviewConclusion: Optional[str] = None,
  36. scheduleStatus: Optional[str] = None,
  37. qcStatus: Optional[str] = None,
  38. bizType: Optional[str] = None,
  39. infusionTimeStart: Optional[str] = None,
  40. infusionTimeEnd: Optional[str] = None,
  41. reviewPhase: Optional[str] = Query(None),
  42. readyForReviewOnly: Optional[bool] = Query(None),
  43. db: Session = Depends(get_db),
  44. user: dict = Depends(require_menu_code("biz:outboundReleaseReview:list")),
  45. ):
  46. try:
  47. tenant_no = _get_tenant_no(db, user)
  48. result = svc.list_reviews_paginated(
  49. db,
  50. tenant_no=tenant_no,
  51. keyword=keyword,
  52. review_conclusion=reviewConclusion,
  53. schedule_status=scheduleStatus,
  54. qc_status=qcStatus,
  55. biz_type=bizType,
  56. infusion_time_start=infusionTimeStart,
  57. infusion_time_end=infusionTimeEnd,
  58. review_phase=reviewPhase,
  59. ready_for_review_only=readyForReviewOnly,
  60. page=page,
  61. page_size=pageSize,
  62. user_info=user,
  63. )
  64. return success_response(result)
  65. except PermissionError as e:
  66. return error_response(403, str(e))
  67. except Exception as e:
  68. return error_response(400, str(e))
  69. @router.get("/pilot-release-reviews/{schedule_id}/detail")
  70. async def get_pilot_release_review_detail(
  71. schedule_id: str,
  72. db: Session = Depends(get_db),
  73. user: dict = Depends(require_menu_code("biz:outboundReleaseReview:list")),
  74. ):
  75. try:
  76. tenant_no = _get_tenant_no(db, user)
  77. detail = svc.get_schedule_detail(db, schedule_id, tenant_no)
  78. if not detail:
  79. return error_response(404, "输注计划不存在")
  80. return success_response(detail)
  81. except PermissionError as e:
  82. return error_response(403, str(e))
  83. except Exception as e:
  84. return error_response(400, str(e))
  85. @router.put("/pilot-release-reviews/{schedule_id}/review")
  86. async def submit_single_review(
  87. schedule_id: str,
  88. body: OutboundReviewSubmitBody,
  89. db: Session = Depends(get_db),
  90. user: dict = Depends(require_admin_or_super_admin),
  91. ):
  92. try:
  93. tenant_no = _get_tenant_no(db, user)
  94. user_id = _get_current_user_id(user)
  95. result = svc.review_schedule(
  96. db,
  97. schedule_id,
  98. conclusion=body.reviewConclusion,
  99. remark=body.reviewRemark,
  100. attachments=body.reviewAttachments,
  101. tenant_no=tenant_no,
  102. user_id=user_id,
  103. )
  104. db.commit()
  105. return success_response(result)
  106. except PermissionError as e:
  107. return error_response(403, str(e))
  108. except ValueError as e:
  109. return error_response(400, str(e))
  110. except Exception as e:
  111. return error_response(400, str(e))
  112. @router.put("/pilot-release-reviews/batch-review")
  113. async def batch_review(
  114. body: OutboundBatchReviewBody,
  115. db: Session = Depends(get_db),
  116. user: dict = Depends(require_admin_or_super_admin),
  117. ):
  118. try:
  119. tenant_no = _get_tenant_no(db, user)
  120. user_id = _get_current_user_id(user)
  121. result = svc.batch_review(
  122. db,
  123. body.scheduleIds,
  124. conclusion=body.reviewConclusion,
  125. remark=body.reviewRemark,
  126. attachments=body.reviewAttachments,
  127. tenant_no=tenant_no,
  128. user_id=user_id,
  129. )
  130. db.commit()
  131. return success_response(result)
  132. except PermissionError as e:
  133. return error_response(403, str(e))
  134. except ValueError as e:
  135. return error_response(400, str(e))
  136. except Exception as e:
  137. return error_response(400, str(e))
  138. @router.get("/pilot-release-reviews/{schedule_id}/outbound-materials")
  139. async def get_outbound_release_materials(
  140. schedule_id: str,
  141. db: Session = Depends(get_db),
  142. user: dict = Depends(require_menu_code("biz:outboundReleaseReview:list")),
  143. ):
  144. try:
  145. tenant_no = _get_tenant_no(db, user)
  146. result = orm_svc.get_outbound_material(db, schedule_id, tenant_no)
  147. return success_response(result)
  148. except PermissionError as e:
  149. return error_response(403, str(e))
  150. except Exception as e:
  151. if hasattr(e, "status_code") and getattr(e, "status_code") == 404:
  152. return error_response(404, str(getattr(e, "detail", e)))
  153. return error_response(400, str(getattr(e, "detail", e)))
  154. @router.put("/pilot-release-reviews/{schedule_id}/outbound-materials")
  155. async def save_outbound_release_materials(
  156. schedule_id: str,
  157. body: OutboundReleaseMaterialSaveBody,
  158. db: Session = Depends(get_db),
  159. user: dict = Depends(require_admin_or_super_admin),
  160. ):
  161. try:
  162. tenant_no = _get_tenant_no(db, user)
  163. user_id = _get_current_user_id(user)
  164. sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
  165. dept_id = (sys_user.dept_id or "") if sys_user else ""
  166. result = orm_svc.save_outbound_material(
  167. db,
  168. schedule_id,
  169. paper_attachments=body.paperAttachments,
  170. paper_materials=[p.model_dump(by_alias=True) for p in body.paperMaterials],
  171. remark=body.remark,
  172. cells=[c.model_dump(by_alias=True) for c in body.cells],
  173. qc_materials=[m.model_dump(by_alias=True) for m in body.qcMaterials],
  174. tenant_no=tenant_no,
  175. user_id=user_id,
  176. create_dept_id=dept_id,
  177. )
  178. db.commit()
  179. return success_response(result)
  180. except PermissionError as e:
  181. return error_response(403, str(e))
  182. except Exception as e:
  183. db.rollback()
  184. if hasattr(e, "status_code"):
  185. code = int(getattr(e, "status_code", 400))
  186. detail = getattr(e, "detail", str(e))
  187. return error_response(code, detail if isinstance(detail, str) else str(detail))
  188. return error_response(400, str(getattr(e, "detail", e)))