feat(production): extend CRUD for outbound work orders — biz_type, yzf status, list/detail enrichment

This commit is contained in:
zlwu committed 2026-05-26 18:04:03 +08:00
1 parent d93b16ab0c
commit d84f5056f2
1 file changed
+110 -1
+110 -1
View File
@@ -33,6 +33,7 @@ _WORK_ORDER_STATUS_LABELS = {
"dpz": "待配置",
"jxz": "进行中",
"ywc": "已完成",
"yzf": "已作废",
}
_RECEPTION_SOURCE_LABELS = {
"cell_storage": "细胞存储",
@@ -100,6 +101,8 @@ def _wo_to_dict(wo: BizProductionWorkOrder) -> Dict[str, Any]:
getattr(wo, "reception_source", "cell_storage") or "cell_storage",
),
"infusionScheduleId": getattr(wo, "infusion_schedule_id", None) or None,
"bizType": getattr(wo, "biz_type", None) or None,
"bizTypeLabel": {"pilot_service": "中试服务", "clinical_application": "临床应用"}.get(getattr(wo, "biz_type", None) or "", ""),
"workOrderStatus": wo.work_order_status,
"workOrderStatusLabel": _WORK_ORDER_STATUS_LABELS.get(wo.work_order_status, wo.work_order_status),
"receptionTime": "",
@@ -117,6 +120,65 @@ def _enrich_wo_items(db: Session, items: List[Dict[str, Any]]) -> List[Dict[str,
return qc_wo_svc._enrich_work_order_list_items(db, items)
_BIZ_TYPE_LABELS = {"pilot_service": "中试服务", "clinical_application": "临床应用"}
def _enrich_outbound_items(db: Session, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
"""为 outbound 类型工单附加申请单号、细胞类型、规格、输注时间等关联数据。"""
from app.models.models import (
BizPilotApplication,
BizPilotInfusionPlan,
BizPilotInfusionSchedule,
)
outbound_ids = [
it["infusionScheduleId"]
for it in items
if it.get("workOrderType") == "outbound" and it.get("infusionScheduleId")
]
if not outbound_ids:
return items
schedules = (
db.query(BizPilotInfusionSchedule)
.filter(
BizPilotInfusionSchedule.id.in_(outbound_ids),
BizPilotInfusionSchedule.del_flag == 0,
)
.all()
)
sched_map = {s.id: s for s in schedules}
plan_ids = list({s.infusion_plan_id for s in schedules if s.infusion_plan_id})
plan_map = {}
if plan_ids:
plans = db.query(BizPilotInfusionPlan).filter(BizPilotInfusionPlan.id.in_(plan_ids)).all()
plan_map = {p.id: p for p in plans}
app_ids = list({p.pilot_application_id for p in plan_map.values() if p.pilot_application_id})
app_map = {}
if app_ids:
apps = db.query(BizPilotApplication).filter(BizPilotApplication.id.in_(app_ids)).all()
app_map = {a.id: a for a in apps}
for it in items:
if it.get("workOrderType") != "outbound" or not it.get("infusionScheduleId"):
continue
sched = sched_map.get(it["infusionScheduleId"])
if not sched:
continue
plan = plan_map.get(sched.infusion_plan_id) if sched.infusion_plan_id else None
app = app_map.get(plan.pilot_application_id) if plan and plan.pilot_application_id else None
it["applicationNo"] = app.application_no if app else ""
it["cellType"] = sched.cell_type or ""
it["specText"] = sched.spec_text or ""
it["infusionTime"] = _fmt_dt(sched.infusion_time) if sched.infusion_time else ""
it["infusionLocation"] = sched.infusion_location or ""
return items
def _reception_source_label(source: Optional[str]) -> str:
key = (source or "").strip() or "cell_storage"
return _RECEPTION_SOURCE_LABELS.get(key, key)
@@ -157,10 +219,54 @@ def _attach_reception_detail(
}
def _attach_outbound_detail(
db: Session, wo: BizProductionWorkOrder, out: Dict[str, Any]
) -> None:
"""outbound 工单详情附加申请单 + 输注计划信息。"""
from app.models.models import (
BizPilotApplication,
BizPilotInfusionPlan,
BizPilotInfusionSchedule,
)
_APP_STATUS_LABELS = {"dks": "待开始", "jxz": "进行中", "ywc": "已完成", "yzf": "已作废"}
sched = (
db.query(BizPilotInfusionSchedule)
.filter(BizPilotInfusionSchedule.id == wo.infusion_schedule_id, BizPilotInfusionSchedule.del_flag == 0)
.first()
)
plan = None
app = None
if sched and sched.infusion_plan_id:
plan = db.query(BizPilotInfusionPlan).filter(BizPilotInfusionPlan.id == sched.infusion_plan_id).first()
if plan and plan.pilot_application_id:
app = db.query(BizPilotApplication).filter(BizPilotApplication.id == plan.pilot_application_id).first()
out["reception"] = {}
out["pilotApplication"] = {
"applicationNo": app.application_no if app else "",
"applicationName": app.application_name if app else "",
"applicationStatus": app.application_status if app else "",
"applicationStatusLabel": _APP_STATUS_LABELS.get(app.application_status, "") if app else "",
} if app else {}
out["infusionSchedule"] = {
"cellType": sched.cell_type if sched else "",
"specText": sched.spec_text if sched else "",
"infusionTime": _fmt_dt(sched.infusion_time) if sched and sched.infusion_time else "",
"infusionLocation": sched.infusion_location if sched else "",
"infusionMethod": sched.infusion_method if sched else "",
"scheduleStatus": sched.schedule_status if sched else "",
} if sched else {}
def _wo_to_response_dict(db: Session, wo: BizProductionWorkOrder) -> Dict[str, Any]:
"""工单响应(含接收记录关联的样本类型、接收人、接收时间及 reception 详情)。"""
out = _enrich_wo_items(db, [_wo_to_dict(wo)])[0]
_attach_reception_detail(db, wo, out, wo.tenant_no or "")
if wo.work_order_type == "outbound" and wo.infusion_schedule_id:
_attach_outbound_detail(db, wo, out)
else:
_attach_reception_detail(db, wo, out, wo.tenant_no or "")
return out
@@ -341,6 +447,7 @@ def list_production_work_orders(
.all()
)
items = _enrich_wo_items(db, [_wo_to_dict(x) for x in rows])
items = _enrich_outbound_items(db, items)
return {"items": items, "total": int(total)}
@@ -643,6 +750,7 @@ def create_outbound_production_work_order(
user_id: Optional[str] = None,
create_dept_id: str = "",
remark: str = "",
biz_type: str = "pilot_service",
) -> BizProductionWorkOrder:
existing = (
db.query(BizProductionWorkOrder)
@@ -666,6 +774,7 @@ def create_outbound_production_work_order(
sample_code=None,
reception_source="outbound",
infusion_schedule_id=schedule_id,
biz_type=biz_type,
work_order_status="dpz",
tenant_no=tenant_no,
remark=remark,