Files
shanxia2.0/backend/app/services/pl_transport_effect_service.py
T
wuzilongandCursor d22b06dbe7 feat(pl): 易制毒先安排待确认与购买证管理
含易制毒计划安排后进入已安排待确认,确认通过后再占合同并生成链接/地磅;新增购买证/运输证主数据、产品行关联、余量校验与 OCR 配置,并停止跟踪 api_key/app.pid。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-09 18:41:10 +08:00

112 lines
3.6 KiB
Python

"""运输计划生效副作用:确认生效时重建;打回待确认时撤销。"""
from __future__ import annotations
import secrets
from typing import Any, Optional
from fastapi import HTTPException
from sqlalchemy.orm import Session
from app.models.pl_models import PlPlan, PlPlanProduct, PlTransport
from app.services.pl_dibang_bridge_service import (
plan_has_load_stop,
revoke_regeneratable_dibang_for_transport,
sync_dibang_for_transport,
)
from app.services.pl_internal_customer import plan_requires_site_link
from app.services.pl_io_order_service import (
apply_dibang_prefill_to_order,
create_io_order_for_transport,
void_io_orders_for_plan,
)
from app.services.pl_transport_stop_feedback_service import ensure_transport_site_token
def revoke_transport_effective_effects(
db: Session,
*,
tenant_no: str,
plan: PlPlan,
transport: Optional[PlTransport],
user_id: str,
) -> None:
"""打回待确认:作废出入库、撤销可重生地磅、清空现场/司机外链令牌(保留运输单与车辆)。"""
if transport is not None:
revoke_regeneratable_dibang_for_transport(
db,
tenant_no=tenant_no,
transport_id=transport.id,
user_id=user_id,
)
transport.site_access_token = None
transport.driver_access_token = None
void_io_orders_for_plan(
db,
tenant_no=tenant_no,
plan_id=plan.id,
user_id=user_id,
)
def apply_confirm_effective_effects(
db: Session,
*,
tenant_no: str,
plan: PlPlan,
products: list[PlPlanProduct],
transport: PlTransport,
user_id: str,
dept_id: str,
) -> dict[str, Any]:
"""确认生效:生成司机令牌、现场/出入库链接;地磅按计划类型尝试同步(无段选项时走 legacy)。"""
token = (transport.driver_access_token or "").strip()
if not token:
transport.driver_access_token = secrets.token_urlsafe(32)[:64]
needs_site_link = plan_requires_site_link(db, tenant_no=tenant_no, plan=plan)
if needs_site_link:
if plan_has_load_stop(db, tenant_no, plan.id):
ensure_transport_site_token(transport)
elif plan.plan_type in ("inbound", "outbound"):
try:
void_io_orders_for_plan(
db,
tenant_no=tenant_no,
plan_id=plan.id,
user_id=user_id,
)
create_io_order_for_transport(
db,
tenant_no=tenant_no,
plan=plan,
products=products,
transport=transport,
user_id=user_id,
dept_id=dept_id or "",
after_dibang=False,
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc)) from exc
if plan.plan_type in ("inbound", "outbound") and not plan_has_load_stop(
db, tenant_no, plan.id
):
try:
sync_dibang_for_transport(
db,
tenant_no=tenant_no,
plan=plan,
products=products,
transport=transport,
user_id=user_id,
dept_id=dept_id or "",
)
apply_dibang_prefill_to_order(
db, tenant_no=tenant_no, plan=plan, transport=transport
)
except ValueError:
# 确认时地磅非强制:无勾选上下文时跳过,避免阻断生效
pass
return {"ok": True}