Files
shanxia2.0/backend/app/crud/pilot_outbound_status_sync.py
T
2026-05-27 05:23:28 +08:00

214 lines
6.0 KiB
Python

"""中试服务出库生产/质检工单与输注计划生产状态、质检状态双向联动。"""
from __future__ import annotations
from datetime import datetime
from typing import Optional
from sqlalchemy.orm import Session
from app.models.models import (
BizPilotInfusionSchedule,
BizProductionWorkOrder,
BizQcWorkOrder,
)
def _is_pilot_outbound_production(wo: BizProductionWorkOrder) -> bool:
return (
(getattr(wo, "work_order_type", None) or "") == "outbound"
and (getattr(wo, "biz_type", None) or "") == "pilot_service"
and bool(getattr(wo, "infusion_schedule_id", None))
)
def _is_pilot_outbound_qc(wo: BizQcWorkOrder) -> bool:
return (
(getattr(wo, "work_order_type", None) or "") == "outbound"
and (getattr(wo, "biz_type", None) or "") == "pilot_service"
and bool(getattr(wo, "infusion_schedule_id", None))
)
def _get_schedule(
db: Session, schedule_id: str, tenant_no: str
) -> Optional[BizPilotInfusionSchedule]:
if not (schedule_id or "").strip():
return None
return (
db.query(BizPilotInfusionSchedule)
.filter(
BizPilotInfusionSchedule.id == schedule_id.strip(),
BizPilotInfusionSchedule.tenant_no == tenant_no,
BizPilotInfusionSchedule.del_flag == 0,
)
.first()
)
def _touch(row, user_id: Optional[str]) -> None:
now = datetime.now()
if user_id:
row.update_by = user_id
row.update_time = now
def sync_schedule_from_production_work_order(
db: Session,
wo: BizProductionWorkOrder,
*,
user_id: Optional[str] = None,
) -> None:
"""出库生产工单状态 → 输注计划 schedule_status。"""
if not _is_pilot_outbound_production(wo):
return
sched = _get_schedule(db, wo.infusion_schedule_id or "", wo.tenant_no or "")
if not sched:
return
wo_status = (wo.work_order_status or "").strip()
current = (sched.schedule_status or "").strip()
new_status: Optional[str] = None
if wo_status in ("dpz", "jxz"):
if current not in ("ysc", "yjf", "yqx"):
new_status = "dsc"
elif wo_status == "ywc":
if current not in ("yjf", "yqx"):
new_status = "ysc"
elif wo_status == "yzf":
new_status = "yqx"
if new_status and new_status != current:
sched.schedule_status = new_status
_touch(sched, user_id)
db.add(sched)
def sync_schedule_from_qc_work_order(
db: Session,
wo: BizQcWorkOrder,
*,
user_id: Optional[str] = None,
) -> None:
"""出库质检工单状态 → 输注计划 qc_status。"""
if not _is_pilot_outbound_qc(wo):
return
sched = _get_schedule(db, wo.infusion_schedule_id or "", wo.tenant_no or "")
if not sched:
return
wo_status = (wo.work_order_status or "").strip()
current = (sched.qc_status or "").strip()
new_status: Optional[str] = None
if wo_status in ("dpz", "ypz"):
if current not in ("yzj", "yqx"):
new_status = "dzc"
elif wo_status == "ywc":
if current != "yqx":
new_status = "yzj"
elif wo_status == "yzf":
new_status = "yqx"
if new_status and new_status != current:
sched.qc_status = new_status
_touch(sched, user_id)
db.add(sched)
def sync_production_work_order_from_schedule(
db: Session,
schedule: BizPilotInfusionSchedule,
*,
user_id: Optional[str] = None,
) -> None:
"""输注计划 schedule_status → 出库生产工单状态。"""
schedule_id = schedule.id or ""
tenant_no = schedule.tenant_no or ""
if not schedule_id:
return
wo = (
db.query(BizProductionWorkOrder)
.filter(
BizProductionWorkOrder.infusion_schedule_id == schedule_id,
BizProductionWorkOrder.tenant_no == tenant_no,
BizProductionWorkOrder.del_flag == 0,
BizProductionWorkOrder.work_order_type == "outbound",
BizProductionWorkOrder.biz_type == "pilot_service",
)
.first()
)
if not wo:
return
sched_status = (schedule.schedule_status or "").strip()
current = (wo.work_order_status or "").strip()
new_status: Optional[str] = None
if sched_status in ("ysc", "yjf"):
if current not in ("ywc", "yzf"):
new_status = "ywc"
elif sched_status == "yqx":
if current != "ywc":
new_status = "yzf"
if new_status and new_status != current:
wo.work_order_status = new_status
_touch(wo, user_id)
db.add(wo)
def sync_qc_work_order_from_schedule(
db: Session,
schedule: BizPilotInfusionSchedule,
*,
user_id: Optional[str] = None,
) -> None:
"""输注计划 qc_status → 出库质检工单状态。"""
schedule_id = schedule.id or ""
tenant_no = schedule.tenant_no or ""
if not schedule_id:
return
wo = (
db.query(BizQcWorkOrder)
.filter(
BizQcWorkOrder.infusion_schedule_id == schedule_id,
BizQcWorkOrder.tenant_no == tenant_no,
BizQcWorkOrder.del_flag == 0,
BizQcWorkOrder.work_order_type == "outbound",
BizQcWorkOrder.biz_type == "pilot_service",
)
.first()
)
if not wo:
return
qc_status = (schedule.qc_status or "").strip()
current = (wo.work_order_status or "").strip()
new_status: Optional[str] = None
if qc_status == "yzj":
if current not in ("ywc", "yzf"):
new_status = "ywc"
elif qc_status == "yqx":
if current != "ywc":
new_status = "yzf"
if new_status and new_status != current:
wo.work_order_status = new_status
_touch(wo, user_id)
db.add(wo)
def sync_pilot_outbound_from_schedule(
db: Session,
schedule: BizPilotInfusionSchedule,
*,
user_id: Optional[str] = None,
) -> None:
"""输注计划状态变更后,回写关联出库工单。"""
sync_production_work_order_from_schedule(db, schedule, user_id=user_id)
sync_qc_work_order_from_schedule(db, schedule, user_id=user_id)