Files
shanxia2.0/backend/app/services/pl_transport_site_service.py
T
2026-09-13 13:08:52 +08:00

131 lines
3.6 KiB
Python

"""运输计划 · 工厂现场链接(与地磅出入库单解耦)"""
from __future__ import annotations
import secrets
from dataclasses import dataclass
from datetime import date, datetime
from decimal import Decimal
from typing import Optional
from sqlalchemy.orm import Session
from app.core.utils import generate_uuid
from app.models.pl_models import (
PlPlan,
PlPlanProduct,
PlTransport,
PlTransportSiteLink,
)
from app.services.db.mappers import parse_date_str
from app.services.pl_dibang_bridge_service import (
_plan_type_to_business_type,
_product_quantity,
resolve_partner_company,
)
@dataclass
class TransportSiteLinkResult:
plan_product_id: str
product_name: str
site_link_id: str
plan_no: str
business_type: str
def _normalize_plan_date(plan: PlPlan) -> date:
plan_date = plan.plan_date
if isinstance(plan_date, datetime):
return plan_date.date()
if isinstance(plan_date, str):
parsed = parse_date_str(plan_date)
return parsed or date.today()
if isinstance(plan_date, date):
return plan_date
return date.today()
def revoke_site_links_for_transport(
db: Session,
*,
tenant_no: str,
transport_id: str,
user_id: Optional[str],
) -> None:
"""调整运输时作废旧现场链接。"""
rows = (
db.query(PlTransportSiteLink)
.filter(
PlTransportSiteLink.tenant_no == tenant_no,
PlTransportSiteLink.transport_id == transport_id,
PlTransportSiteLink.del_flag == 0,
)
.all()
)
for row in rows:
row.del_flag = 1
row.update_by = user_id
if rows:
db.flush()
def sync_site_links_for_transport(
db: Session,
*,
tenant_no: str,
plan: PlPlan,
products: list[PlPlanProduct],
transport: PlTransport,
user_id: Optional[str],
dept_id: str,
) -> list[TransportSiteLinkResult]:
"""入库/出库安排运输:按产品生成现场链接(不写 db_inbound_outbound)。"""
business_type = _plan_type_to_business_type(plan.plan_type)
if not business_type:
return []
partner = resolve_partner_company(plan, plan.plan_type)
if not partner:
raise ValueError("无法解析往来单位,请检查合同供方/需方信息")
plan_date = _normalize_plan_date(plan)
license_plate = (transport.license_plate or plan.license_plate or "").strip()
plan_no = (plan.plan_no or "").strip()
results: list[TransportSiteLinkResult] = []
for product in products:
token = secrets.token_urlsafe(32)[:64]
row = PlTransportSiteLink(
id=generate_uuid(),
tenant_no=tenant_no,
transport_id=transport.id,
plan_id=plan.id,
plan_product_id=product.id,
site_access_token=token,
business_type=business_type,
partner_company=partner,
product_id=product.product_id,
product=product.product_name,
specification=product.model,
quantity=Decimal(str(_product_quantity(product))),
vehicle_no=license_plate,
plan_no=plan_no or None,
plan_date=plan_date,
remark=f"运输计划 {plan_no}",
create_by=user_id,
create_dept_id=dept_id,
)
db.add(row)
results.append(
TransportSiteLinkResult(
plan_product_id=product.id,
product_name=product.product_name or "",
site_link_id=row.id,
plan_no=plan_no,
business_type=business_type,
)
)
db.flush()
return results