feat(qc): extend outbound work order list API with application/infusion fields and bizType filter
This commit is contained in:
1 parent
fa60330752
commit
c9f369a276
2 files changed
+83
-1
No files matched your search
@@ -596,6 +596,7 @@ async def list_qc_work_orders(
|
||||
keyword: Optional[str] = None,
|
||||
workOrderStatus: Optional[str] = None,
|
||||
workOrderType: Optional[str] = None,
|
||||
bizType: Optional[str] = Query(None, alias="bizType"),
|
||||
createTimeStart: Optional[str] = Query(None, alias="createTimeStart"),
|
||||
createTimeEnd: Optional[str] = Query(None, alias="createTimeEnd"),
|
||||
db: Session = Depends(get_db),
|
||||
@@ -610,6 +611,7 @@ async def list_qc_work_orders(
|
||||
keyword=keyword,
|
||||
work_order_status=workOrderStatus,
|
||||
work_order_type=workOrderType,
|
||||
biz_type=bizType,
|
||||
create_time_start=createTimeStart,
|
||||
create_time_end=createTimeEnd,
|
||||
tenant_no=tenant_no,
|
||||
|
||||
@@ -21,6 +21,9 @@ from app.models.models import (
|
||||
BizCellProduct,
|
||||
BizCellSampleType,
|
||||
BizCollectionProtocol,
|
||||
BizPilotApplication,
|
||||
BizPilotInfusionPlan,
|
||||
BizPilotInfusionSchedule,
|
||||
BizProtocolSample,
|
||||
BizQcLabTestItem,
|
||||
BizQcTask,
|
||||
@@ -53,6 +56,7 @@ _DONATION_STATUS_LABELS = {
|
||||
"dsx": "待生效", "sxz": "生效中", "ygq": "已过期", "yzf": "已作废", "zckc": "转细胞存储"
|
||||
}
|
||||
_CONCLUSION_LABELS = {"tg": "通过", "btg": "不通过"}
|
||||
_OUTBOUND_BIZ_TYPE_LABELS = {"pilot_service": "中试服务", "clinical_application": "临床应用"}
|
||||
|
||||
|
||||
def _dec(v: Any) -> Optional[float]:
|
||||
@@ -130,6 +134,63 @@ def _enrich_work_order_cell_products(
|
||||
return items
|
||||
|
||||
|
||||
def _enrich_outbound_work_orders(
|
||||
db: Session, tenant_no: str, items: List[Dict[str, Any]]
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""为 outbound 类型工单批量补充申请单/输注计划信息。"""
|
||||
outbound = [x for x in items if x.get("workOrderType") == "outbound"]
|
||||
if not outbound:
|
||||
return items
|
||||
schedule_ids = list({x.get("infusionScheduleId") for x in outbound if x.get("infusionScheduleId")})
|
||||
if not schedule_ids:
|
||||
return items
|
||||
# 查输注计划 → 输注方案 → 申请单
|
||||
schedules = {
|
||||
s.id: s
|
||||
for s in db.query(BizPilotInfusionSchedule)
|
||||
.filter(
|
||||
BizPilotInfusionSchedule.id.in_(schedule_ids),
|
||||
BizPilotInfusionSchedule.tenant_no == tenant_no,
|
||||
BizPilotInfusionSchedule.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
}
|
||||
plan_ids = list({s.infusion_plan_id for s in schedules.values() if s.infusion_plan_id})
|
||||
plans = {
|
||||
p.id: p
|
||||
for p in db.query(BizPilotInfusionPlan)
|
||||
.filter(
|
||||
BizPilotInfusionPlan.id.in_(plan_ids),
|
||||
BizPilotInfusionPlan.tenant_no == tenant_no,
|
||||
BizPilotInfusionPlan.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
} if plan_ids else {}
|
||||
app_ids = list({p.pilot_application_id for p in plans.values() if p.pilot_application_id})
|
||||
apps = {
|
||||
a.id: a
|
||||
for a in db.query(BizPilotApplication)
|
||||
.filter(
|
||||
BizPilotApplication.id.in_(app_ids),
|
||||
BizPilotApplication.tenant_no == tenant_no,
|
||||
BizPilotApplication.del_flag == 0,
|
||||
)
|
||||
.all()
|
||||
} if app_ids else {}
|
||||
for item in outbound:
|
||||
sid = item.get("infusionScheduleId") or ""
|
||||
sched = schedules.get(sid)
|
||||
if not sched:
|
||||
continue
|
||||
plan = plans.get(sched.infusion_plan_id or "")
|
||||
app = apps.get(plan.pilot_application_id or "") if plan else None
|
||||
item["applicationNo"] = app.application_no or "" if app else ""
|
||||
item["applicationName"] = app.application_name or "" if app else ""
|
||||
item["channelName"] = app.channel_name or "" if app else ""
|
||||
item["infusionTime"] = _fmt_dt(sched.infusion_time)
|
||||
return items
|
||||
|
||||
|
||||
def _accept_conclusion_label(v: Optional[str]) -> str:
|
||||
key = (v or "").strip()
|
||||
return _ACCEPT_CONCLUSION_LABELS.get(key, key)
|
||||
@@ -290,13 +351,20 @@ def _gen_daily_no(db: Session, tenant_no: str, prefix: str) -> str:
|
||||
return f"{prefix}{day}{cnt + 1:04d}"
|
||||
|
||||
|
||||
def _wo_to_dict(wo: BizQcWorkOrder) -> Dict[str, Any]:
|
||||
def _wo_to_dict(
|
||||
wo: BizQcWorkOrder,
|
||||
*,
|
||||
outbound_info: Optional[Dict[str, Any]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
wo_type = getattr(wo, "work_order_type", None) or "inbound"
|
||||
recv_source_raw = getattr(wo, "reception_source", None)
|
||||
if wo_type == "temporary":
|
||||
recv_source = (recv_source_raw or "").strip()
|
||||
else:
|
||||
recv_source = (recv_source_raw or "cell_storage").strip() or "cell_storage"
|
||||
biz_type = getattr(wo, "biz_type", None) or ""
|
||||
is_outbound = wo_type == "outbound"
|
||||
ob = outbound_info or {}
|
||||
return {
|
||||
"id": wo.id,
|
||||
"workOrderNo": wo.work_order_no,
|
||||
@@ -311,6 +379,12 @@ def _wo_to_dict(wo: BizQcWorkOrder) -> Dict[str, Any]:
|
||||
"qcBizType": _work_order_qc_biz_type(wo),
|
||||
"qcBizTypeLabel": _qc_biz_type_label(_work_order_qc_biz_type(wo)),
|
||||
"infusionScheduleId": getattr(wo, "infusion_schedule_id", None) or None,
|
||||
"bizType": biz_type if is_outbound else "",
|
||||
"bizTypeLabel": _OUTBOUND_BIZ_TYPE_LABELS.get(biz_type, "") if is_outbound else "",
|
||||
"applicationNo": ob.get("applicationNo", "") if is_outbound else "",
|
||||
"applicationName": ob.get("applicationName", "") if is_outbound else "",
|
||||
"channelName": ob.get("channelName", "") if is_outbound else "",
|
||||
"infusionTime": ob.get("infusionTime", "") if is_outbound else "",
|
||||
"cellProductId": getattr(wo, "cell_product_id", None) or "",
|
||||
"cellProductCode": "",
|
||||
"cellProductName": "",
|
||||
@@ -458,6 +532,7 @@ def list_work_orders(
|
||||
keyword: Optional[str] = None,
|
||||
work_order_status: Optional[str] = None,
|
||||
work_order_type: Optional[str] = None,
|
||||
biz_type: Optional[str] = None,
|
||||
create_time_start: Optional[str] = None,
|
||||
create_time_end: Optional[str] = None,
|
||||
tenant_no: Optional[str] = None,
|
||||
@@ -470,6 +545,9 @@ def list_work_orders(
|
||||
wt = (work_order_type or "").strip()
|
||||
if wt:
|
||||
q0 = q0.filter(BizQcWorkOrder.work_order_type == wt)
|
||||
bt = (biz_type or "").strip()
|
||||
if bt:
|
||||
q0 = q0.filter(BizQcWorkOrder.biz_type == bt)
|
||||
kw = (keyword or "").strip()
|
||||
if kw:
|
||||
like = f"%{kw}%"
|
||||
@@ -511,6 +589,7 @@ def list_work_orders(
|
||||
items = _enrich_work_order_list_items(db, items)
|
||||
if tenant_no:
|
||||
items = _enrich_work_order_cell_products(db, tenant_no, items)
|
||||
items = _enrich_outbound_work_orders(db, tenant_no, items)
|
||||
return items, int(total)
|
||||
|
||||
|
||||
@@ -1500,6 +1579,7 @@ def create_outbound_qc_work_order(
|
||||
sample_code=None,
|
||||
reception_source="outbound",
|
||||
qc_biz_type="outbound",
|
||||
biz_type="pilot_service",
|
||||
infusion_schedule_id=schedule_id,
|
||||
cell_product_id=cell_product_id or None,
|
||||
work_order_status="dpz",
|
||||
|
||||
Reference in new issue
Block a user