storage_release_review.py 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. from typing import Optional
  2. from fastapi import APIRouter, Depends, Query
  3. from sqlalchemy.orm import Session
  4. from app.core.database import get_db
  5. from app.core.menu_guard import (
  6. require_admin_or_super_admin,
  7. require_any_menu_code,
  8. user_has_menu_perm,
  9. )
  10. from app.core.response import error_response, success_response
  11. from app.crud import storage_release_review as srr_svc
  12. from app.models.models import SysUser
  13. from app.schemas.storage_release_review import (
  14. BatchReviewBody,
  15. BatchStoreBody,
  16. ReviewSubmitBody,
  17. )
  18. router = APIRouter(prefix="/web/admin", tags=["入库放行审核"])
  19. def _get_tenant_no(db: Session, user: dict) -> str:
  20. user_id = user.get("user_id")
  21. if not user_id:
  22. raise PermissionError("用户身份信息缺失,无法确定租户")
  23. sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
  24. if not sys_user or not sys_user.tenant_no:
  25. raise PermissionError("用户租户信息缺失")
  26. return sys_user.tenant_no
  27. def _get_current_user_id(user: dict) -> str:
  28. user_id = user.get("user_id")
  29. if not user_id:
  30. raise PermissionError("用户身份信息缺失")
  31. return str(user_id)
  32. STORAGE_RELEASE_READ_MENU_CODES = (
  33. "biz:storageReleaseReview:list",
  34. "production:storageReleaseReview:list",
  35. "quality:storageReleaseReview:list",
  36. )
  37. STORAGE_RELEASE_WRITE_MENU_CODES = (
  38. "production:storageReleaseReview:list",
  39. "quality:storageReleaseReview:list",
  40. )
  41. def _ensure_review_side_write(db: Session, user: dict, review_side: str) -> str:
  42. side = srr_svc.normalize_review_side(review_side)
  43. if side not in ("production", "qc"):
  44. raise ValueError("审核侧无效")
  45. menu = srr_svc.review_side_required_menu(side)
  46. if not menu or not user_has_menu_perm(db, user, menu):
  47. raise PermissionError("无权提交该侧审核")
  48. return side
  49. def _ensure_storage_write(db: Session, user: dict) -> None:
  50. if not any(user_has_menu_perm(db, user, code) for code in STORAGE_RELEASE_WRITE_MENU_CODES):
  51. raise PermissionError("无权执行入库操作")
  52. @router.get("/storage-release-reviews")
  53. async def list_storage_release_reviews(
  54. page: int = Query(1, ge=1),
  55. pageSize: int = Query(10, ge=1, le=100),
  56. keyword: Optional[str] = None,
  57. receptionSource: Optional[str] = None,
  58. reviewConclusion: Optional[str] = None,
  59. storageStatus: Optional[str] = None,
  60. reviewPhase: Optional[str] = None,
  61. qcWorkOrderCompleted: Optional[bool] = Query(None),
  62. readyForReviewOnly: Optional[bool] = Query(None),
  63. reviewSide: Optional[str] = None,
  64. prodReviewConclusion: Optional[str] = None,
  65. qcReviewConclusion: Optional[str] = None,
  66. db: Session = Depends(get_db),
  67. user: dict = Depends(require_any_menu_code(*STORAGE_RELEASE_READ_MENU_CODES)),
  68. ):
  69. try:
  70. tenant_no = _get_tenant_no(db, user)
  71. result = srr_svc.list_reviews(
  72. db,
  73. tenant_no=tenant_no,
  74. page=page,
  75. page_size=pageSize,
  76. reception_source=receptionSource,
  77. review_conclusion=reviewConclusion,
  78. storage_status=storageStatus,
  79. keyword=keyword,
  80. review_phase=reviewPhase,
  81. qc_work_order_completed=qcWorkOrderCompleted,
  82. ready_for_review_only=readyForReviewOnly,
  83. review_side=reviewSide,
  84. prod_review_conclusion=prodReviewConclusion,
  85. qc_review_conclusion=qcReviewConclusion,
  86. user_info=user,
  87. )
  88. return success_response(result)
  89. except PermissionError as e:
  90. return error_response(403, str(e))
  91. except Exception as e:
  92. return error_response(400, str(e))
  93. @router.get("/storage-release-reviews/{review_id}")
  94. async def get_storage_release_review_detail(
  95. review_id: str,
  96. db: Session = Depends(get_db),
  97. user: dict = Depends(require_any_menu_code(*STORAGE_RELEASE_READ_MENU_CODES)),
  98. ):
  99. try:
  100. tenant_no = _get_tenant_no(db, user)
  101. detail = srr_svc.get_review_detail(db, review_id, tenant_no)
  102. if not detail:
  103. return error_response(404, "审核记录不存在")
  104. return success_response(detail)
  105. except PermissionError as e:
  106. return error_response(403, str(e))
  107. except Exception as e:
  108. return error_response(400, str(e))
  109. @router.put("/storage-release-reviews/{review_id}/review")
  110. async def submit_single_review(
  111. review_id: str,
  112. body: ReviewSubmitBody,
  113. db: Session = Depends(get_db),
  114. user: dict = Depends(require_admin_or_super_admin),
  115. ):
  116. try:
  117. tenant_no = _get_tenant_no(db, user)
  118. user_id = _get_current_user_id(user)
  119. side = _ensure_review_side_write(db, user, body.reviewSide)
  120. rev = srr_svc.submit_review(
  121. db,
  122. review_id,
  123. review_side=side,
  124. review_conclusion=body.reviewConclusion,
  125. review_remark=body.reviewRemark,
  126. review_attachments=body.reviewAttachments,
  127. tenant_no=tenant_no,
  128. user_id=user_id,
  129. )
  130. db.commit()
  131. return success_response(srr_svc._row_to_dict(rev))
  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.put("/storage-release-reviews/batch-review")
  139. async def batch_review(
  140. body: BatchReviewBody,
  141. db: Session = Depends(get_db),
  142. user: dict = Depends(require_admin_or_super_admin),
  143. ):
  144. try:
  145. tenant_no = _get_tenant_no(db, user)
  146. user_id = _get_current_user_id(user)
  147. side = _ensure_review_side_write(db, user, body.reviewSide)
  148. result = srr_svc.batch_submit_review(
  149. db,
  150. body.ids,
  151. review_side=side,
  152. review_conclusion=body.reviewConclusion,
  153. review_remark=body.reviewRemark,
  154. review_attachments=body.reviewAttachments,
  155. tenant_no=tenant_no,
  156. user_id=user_id,
  157. )
  158. db.commit()
  159. return success_response(result)
  160. except PermissionError as e:
  161. return error_response(403, str(e))
  162. except ValueError as e:
  163. return error_response(400, str(e))
  164. except Exception as e:
  165. return error_response(400, str(e))
  166. @router.put("/storage-release-reviews/{review_id}/store")
  167. async def store_single_sample(
  168. review_id: str,
  169. db: Session = Depends(get_db),
  170. user: dict = Depends(require_admin_or_super_admin),
  171. ):
  172. try:
  173. tenant_no = _get_tenant_no(db, user)
  174. user_id = _get_current_user_id(user)
  175. _ensure_storage_write(db, user)
  176. rev = srr_svc.store_sample(
  177. db,
  178. review_id,
  179. tenant_no=tenant_no,
  180. user_id=user_id,
  181. )
  182. db.commit()
  183. return success_response(srr_svc._row_to_dict(rev))
  184. except PermissionError as e:
  185. return error_response(403, str(e))
  186. except ValueError as e:
  187. return error_response(400, str(e))
  188. except Exception as e:
  189. return error_response(400, str(e))
  190. @router.put("/storage-release-reviews/batch-store")
  191. async def batch_store_samples(
  192. body: BatchStoreBody,
  193. db: Session = Depends(get_db),
  194. user: dict = Depends(require_admin_or_super_admin),
  195. ):
  196. try:
  197. tenant_no = _get_tenant_no(db, user)
  198. user_id = _get_current_user_id(user)
  199. _ensure_storage_write(db, user)
  200. result = srr_svc.batch_store_samples(
  201. db,
  202. body.ids,
  203. tenant_no=tenant_no,
  204. user_id=user_id,
  205. )
  206. db.commit()
  207. return success_response(result)
  208. except PermissionError as e:
  209. return error_response(403, str(e))
  210. except ValueError as e:
  211. return error_response(400, str(e))
  212. except Exception as e:
  213. return error_response(400, str(e))