feat(production): extend CRUD for outbound work orders — biz_type, yzf status, list/detail enrichment
This commit is contained in:
1 parent
d93b16ab0c
commit
d84f5056f2
1 file changed
+110
-1
@@ -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,
|
||||
|
||||
Reference in new issue
Block a user