outbound_release_review.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  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. db: Session = Depends(get_db),
  42. user: dict = Depends(require_menu_code("biz:outboundReleaseReview:list")),
  43. ):
  44. try:
  45. tenant_no = _get_tenant_no(db, user)
  46. result = svc.list_reviews_paginated(
  47. db,
  48. tenant_no=tenant_no,
  49. keyword=keyword,
  50. review_conclusion=reviewConclusion,
  51. schedule_status=scheduleStatus,
  52. qc_status=qcStatus,
  53. biz_type=bizType,
  54. infusion_time_start=infusionTimeStart,
  55. infusion_time_end=infusionTimeEnd,
  56. page=page,
  57. page_size=pageSize,
  58. user_info=user,
  59. )
  60. return success_response(result)
  61. except PermissionError as e:
  62. return error_response(403, str(e))
  63. except Exception as e:
  64. return error_response(400, str(e))
  65. @router.get("/pilot-release-reviews/{schedule_id}/detail")
  66. async def get_pilot_release_review_detail(
  67. schedule_id: str,
  68. db: Session = Depends(get_db),
  69. user: dict = Depends(require_menu_code("biz:outboundReleaseReview:list")),
  70. ):
  71. try:
  72. tenant_no = _get_tenant_no(db, user)
  73. detail = svc.get_schedule_detail(db, schedule_id, tenant_no)
  74. if not detail:
  75. return error_response(404, "输注计划不存在")
  76. return success_response(detail)
  77. except PermissionError as e:
  78. return error_response(403, str(e))
  79. except Exception as e:
  80. return error_response(400, str(e))
  81. @router.put("/pilot-release-reviews/{schedule_id}/review")
  82. async def submit_single_review(
  83. schedule_id: str,
  84. body: OutboundReviewSubmitBody,
  85. db: Session = Depends(get_db),
  86. user: dict = Depends(require_admin_or_super_admin),
  87. ):
  88. try:
  89. tenant_no = _get_tenant_no(db, user)
  90. user_id = _get_current_user_id(user)
  91. result = svc.review_schedule(
  92. db,
  93. schedule_id,
  94. conclusion=body.reviewConclusion,
  95. remark=body.reviewRemark,
  96. attachments=body.reviewAttachments,
  97. tenant_no=tenant_no,
  98. user_id=user_id,
  99. )
  100. db.commit()
  101. return success_response(result)
  102. except PermissionError as e:
  103. return error_response(403, str(e))
  104. except ValueError as e:
  105. return error_response(400, str(e))
  106. except Exception as e:
  107. return error_response(400, str(e))
  108. @router.put("/pilot-release-reviews/batch-review")
  109. async def batch_review(
  110. body: OutboundBatchReviewBody,
  111. db: Session = Depends(get_db),
  112. user: dict = Depends(require_admin_or_super_admin),
  113. ):
  114. try:
  115. tenant_no = _get_tenant_no(db, user)
  116. user_id = _get_current_user_id(user)
  117. result = svc.batch_review(
  118. db,
  119. body.scheduleIds,
  120. conclusion=body.reviewConclusion,
  121. remark=body.reviewRemark,
  122. attachments=body.reviewAttachments,
  123. tenant_no=tenant_no,
  124. user_id=user_id,
  125. )
  126. db.commit()
  127. return success_response(result)
  128. except PermissionError as e:
  129. return error_response(403, str(e))
  130. except ValueError as e:
  131. return error_response(400, str(e))
  132. except Exception as e:
  133. return error_response(400, str(e))
  134. @router.get("/pilot-release-reviews/{schedule_id}/outbound-materials")
  135. async def get_outbound_release_materials(
  136. schedule_id: str,
  137. db: Session = Depends(get_db),
  138. user: dict = Depends(require_menu_code("biz:outboundReleaseReview:list")),
  139. ):
  140. try:
  141. tenant_no = _get_tenant_no(db, user)
  142. result = orm_svc.get_outbound_material(db, schedule_id, tenant_no)
  143. return success_response(result)
  144. except PermissionError as e:
  145. return error_response(403, str(e))
  146. except Exception as e:
  147. if hasattr(e, "status_code") and getattr(e, "status_code") == 404:
  148. return error_response(404, str(getattr(e, "detail", e)))
  149. return error_response(400, str(getattr(e, "detail", e)))
  150. @router.put("/pilot-release-reviews/{schedule_id}/outbound-materials")
  151. async def save_outbound_release_materials(
  152. schedule_id: str,
  153. body: OutboundReleaseMaterialSaveBody,
  154. db: Session = Depends(get_db),
  155. user: dict = Depends(require_admin_or_super_admin),
  156. ):
  157. try:
  158. tenant_no = _get_tenant_no(db, user)
  159. user_id = _get_current_user_id(user)
  160. sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
  161. dept_id = (sys_user.dept_id or "") if sys_user else ""
  162. result = orm_svc.save_outbound_material(
  163. db,
  164. schedule_id,
  165. paper_attachments=body.paperAttachments,
  166. paper_materials=[p.model_dump(by_alias=True) for p in body.paperMaterials],
  167. remark=body.remark,
  168. cells=[c.model_dump(by_alias=True) for c in body.cells],
  169. qc_materials=[m.model_dump(by_alias=True) for m in body.qcMaterials],
  170. tenant_no=tenant_no,
  171. user_id=user_id,
  172. create_dept_id=dept_id,
  173. )
  174. db.commit()
  175. return success_response(result)
  176. except PermissionError as e:
  177. return error_response(403, str(e))
  178. except Exception as e:
  179. db.rollback()
  180. if hasattr(e, "status_code"):
  181. code = int(getattr(e, "status_code", 400))
  182. detail = getattr(e, "detail", str(e))
  183. return error_response(code, detail if isinstance(detail, str) else str(detail))
  184. return error_response(400, str(getattr(e, "detail", e)))