pilot_delivery.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. """中试服务交付管理 API(交付信息、交付物料、交付方式)"""
  2. from typing import List, Optional
  3. from fastapi import APIRouter, Depends, Query
  4. from pydantic import BaseModel
  5. from sqlalchemy.orm import Session
  6. from app.core.database import get_db
  7. from app.core.menu_guard import require_admin_or_super_admin
  8. from app.core.response import error_response, success_response
  9. from app.crud import pilot_delivery
  10. from app.models.models import SysUser
  11. router = APIRouter(prefix="/web/admin", tags=["中试服务交付管理"])
  12. def _get_tenant_no(db: Session, user: dict) -> str:
  13. user_id = user.get("user_id")
  14. if not user_id:
  15. raise PermissionError("用户身份信息缺失,无法确定租户")
  16. sys_user = db.query(SysUser).filter(SysUser.id == user_id).first()
  17. if not sys_user or not sys_user.tenant_no:
  18. raise PermissionError("用户租户信息缺失")
  19. return sys_user.tenant_no
  20. # ---------------------------------------------------------------------------
  21. # Pydantic Schemas
  22. # ---------------------------------------------------------------------------
  23. class IdBody(BaseModel):
  24. id: str
  25. class DeliverySaveBody(BaseModel):
  26. remark: Optional[str] = None
  27. class DeliveryMaterialItem(BaseModel):
  28. material_name: str
  29. qty: Optional[float] = None
  30. unit_id: Optional[str] = None
  31. remark: Optional[str] = None
  32. class DeliveryMaterialSaveBody(BaseModel):
  33. delivery_id: str
  34. items: List[DeliveryMaterialItem]
  35. class DeliveryMethodSaveBody(BaseModel):
  36. delivery_id: str
  37. delivery_mode: str
  38. delivery_attachments: Optional[str] = None
  39. ship_time: Optional[str] = None
  40. handover_temp: Optional[str] = None
  41. pickup_person: Optional[str] = None
  42. pickup_phone: Optional[str] = None
  43. sender_name: Optional[str] = None
  44. express_company_id: Optional[str] = None
  45. waybill_no: Optional[str] = None
  46. express_fee: Optional[float] = None
  47. eta_time: Optional[str] = None
  48. remark: Optional[str] = None
  49. class DeliveryCreateBody(BaseModel):
  50. infusion_schedule_id: str
  51. remark: Optional[str] = None
  52. # ---------------------------------------------------------------------------
  53. # 1. 交付信息 CRUD
  54. # ---------------------------------------------------------------------------
  55. @router.get("/pilot-delivery/detail")
  56. async def get_by_schedule(
  57. infusion_schedule_id: str = Query(...),
  58. user: dict = Depends(require_admin_or_super_admin),
  59. db: Session = Depends(get_db),
  60. ):
  61. tenant_no = _get_tenant_no(db, user)
  62. result = pilot_delivery.get_delivery_by_schedule(
  63. db, schedule_id=infusion_schedule_id, tenant_no=tenant_no
  64. )
  65. if result is None:
  66. return success_response(None)
  67. return success_response(result)
  68. @router.get("/pilot-delivery/list-by-application")
  69. async def list_by_application(
  70. application_id: str = Query(...),
  71. user: dict = Depends(require_admin_or_super_admin),
  72. db: Session = Depends(get_db),
  73. ):
  74. tenant_no = _get_tenant_no(db, user)
  75. result = pilot_delivery.list_deliveries_by_application(
  76. db, application_id=application_id, tenant_no=tenant_no
  77. )
  78. return success_response(result)
  79. @router.post("/pilot-delivery/create")
  80. async def create_delivery(
  81. body: DeliveryCreateBody,
  82. user: dict = Depends(require_admin_or_super_admin),
  83. db: Session = Depends(get_db),
  84. ):
  85. try:
  86. tenant_no = _get_tenant_no(db, user)
  87. data = {"remark": body.remark}
  88. result = pilot_delivery.create_delivery(
  89. db,
  90. schedule_id=body.infusion_schedule_id,
  91. data=data,
  92. tenant_no=tenant_no,
  93. user_id=user.get("user_id"),
  94. dept_id=user.get("region_id", ""),
  95. )
  96. return success_response(result, message="创建成功")
  97. except ValueError as e:
  98. return error_response(400, str(e))
  99. @router.delete("/pilot-delivery/delete")
  100. async def soft_delete(
  101. body: IdBody,
  102. user: dict = Depends(require_admin_or_super_admin),
  103. db: Session = Depends(get_db),
  104. ):
  105. try:
  106. tenant_no = _get_tenant_no(db, user)
  107. pilot_delivery.soft_delete_delivery(
  108. db, delivery_id=body.id, tenant_no=tenant_no
  109. )
  110. return success_response(None, message="删除成功")
  111. except ValueError as e:
  112. return error_response(400, str(e))
  113. # ---------------------------------------------------------------------------
  114. # 2. 交付物料
  115. # ---------------------------------------------------------------------------
  116. @router.get("/pilot-delivery/materials")
  117. async def list_materials(
  118. delivery_id: str = Query(...),
  119. user: dict = Depends(require_admin_or_super_admin),
  120. db: Session = Depends(get_db),
  121. ):
  122. tenant_no = _get_tenant_no(db, user)
  123. result = pilot_delivery.list_delivery_materials(
  124. db, delivery_id=delivery_id, tenant_no=tenant_no
  125. )
  126. return success_response(result)
  127. @router.post("/pilot-delivery/materials/save")
  128. async def save_materials(
  129. body: DeliveryMaterialSaveBody,
  130. user: dict = Depends(require_admin_or_super_admin),
  131. db: Session = Depends(get_db),
  132. ):
  133. try:
  134. tenant_no = _get_tenant_no(db, user)
  135. items_json = [item.dict() for item in body.items]
  136. result = pilot_delivery.save_delivery_materials(
  137. db,
  138. delivery_id=body.delivery_id,
  139. items_json=items_json,
  140. tenant_no=tenant_no,
  141. user_id=user.get("user_id"),
  142. )
  143. return success_response(result, message="保存成功")
  144. except ValueError as e:
  145. return error_response(400, str(e))
  146. # ---------------------------------------------------------------------------
  147. # 3. 交付方式
  148. # ---------------------------------------------------------------------------
  149. @router.get("/pilot-delivery/method")
  150. async def get_method(
  151. delivery_id: str = Query(...),
  152. user: dict = Depends(require_admin_or_super_admin),
  153. db: Session = Depends(get_db),
  154. ):
  155. tenant_no = _get_tenant_no(db, user)
  156. result = pilot_delivery.get_delivery_method(
  157. db, delivery_id=delivery_id, tenant_no=tenant_no
  158. )
  159. if result is None:
  160. return success_response(None)
  161. return success_response(result)
  162. @router.post("/pilot-delivery/method/save")
  163. async def save_method(
  164. body: DeliveryMethodSaveBody,
  165. user: dict = Depends(require_admin_or_super_admin),
  166. db: Session = Depends(get_db),
  167. ):
  168. try:
  169. tenant_no = _get_tenant_no(db, user)
  170. data = {
  171. "delivery_mode": body.delivery_mode,
  172. "delivery_attachments": body.delivery_attachments,
  173. "ship_time": body.ship_time,
  174. "handover_temp": body.handover_temp,
  175. "pickup_person": body.pickup_person,
  176. "pickup_phone": body.pickup_phone,
  177. "sender_name": body.sender_name,
  178. "express_company_id": body.express_company_id,
  179. "waybill_no": body.waybill_no,
  180. "express_fee": body.express_fee,
  181. "eta_time": body.eta_time,
  182. "remark": body.remark,
  183. }
  184. result = pilot_delivery.save_delivery_method(
  185. db,
  186. delivery_id=body.delivery_id,
  187. data=data,
  188. tenant_no=tenant_no,
  189. user_id=user.get("user_id"),
  190. )
  191. return success_response(result, message="保存成功")
  192. except ValueError as e:
  193. return error_response(400, str(e))