Files
shanxia2.0/backend/app/services/pl/freight_party_customers.py
T
2026-10-06 17:55:20 +08:00

86 lines
3.0 KiB
Python

"""运费未结算计划:装货/送货客户名称聚合。"""
from __future__ import annotations
from collections import defaultdict
from typing import Iterable, List, Optional, Sequence, Tuple
from sqlalchemy.orm import Session
from app.models.pl_models import PlPlan, PlPlanDelivery, PlPlanLoad
def unique_customer_names(names: Iterable[Optional[str]]) -> List[str]:
out: List[str] = []
seen: set[str] = set()
for raw in names:
name = (raw or "").strip()
if not name or name in seen:
continue
seen.add(name)
out.append(name)
return out
def resolve_plan_party_customers(
*,
load_names: Sequence[Optional[str]],
delivery_names: Sequence[Optional[str]],
fallback_supplier: Optional[str] = None,
fallback_customer: Optional[str] = None,
fallback_destination: Optional[str] = None,
) -> Tuple[List[str], List[str]]:
load = unique_customer_names(load_names)
if not load:
load = unique_customer_names([fallback_supplier])
delivery = unique_customer_names(delivery_names)
if not delivery:
delivery = unique_customer_names([fallback_customer]) or unique_customer_names(
[fallback_destination]
)
return load, delivery
def load_plan_party_customers_map(
db: Session,
tenant_no: str,
plans: Sequence[PlPlan],
) -> dict[str, Tuple[List[str], List[str]]]:
"""批量读取停靠段客户名;无停靠数据时回退计划主表供应商/客户。"""
plan_ids = [p.id for p in plans if getattr(p, "id", None)]
loads_by_plan: dict[str, List[Optional[str]]] = defaultdict(list)
deliveries_by_plan: dict[str, List[Optional[str]]] = defaultdict(list)
if plan_ids:
for plan_id, name in (
db.query(PlPlanLoad.plan_id, PlPlanLoad.customer_name)
.filter(
PlPlanLoad.tenant_no == tenant_no,
PlPlanLoad.plan_id.in_(plan_ids),
PlPlanLoad.del_flag == 0,
)
.order_by(PlPlanLoad.order_num.asc(), PlPlanLoad.create_time.asc())
.all()
):
loads_by_plan[plan_id].append(name)
for plan_id, name in (
db.query(PlPlanDelivery.plan_id, PlPlanDelivery.customer_name)
.filter(
PlPlanDelivery.tenant_no == tenant_no,
PlPlanDelivery.plan_id.in_(plan_ids),
PlPlanDelivery.del_flag == 0,
)
.order_by(PlPlanDelivery.seq.asc(), PlPlanDelivery.create_time.asc())
.all()
):
deliveries_by_plan[plan_id].append(name)
result: dict[str, Tuple[List[str], List[str]]] = {}
for plan in plans:
result[plan.id] = resolve_plan_party_customers(
load_names=loads_by_plan.get(plan.id, []),
delivery_names=deliveries_by_plan.get(plan.id, []),
fallback_supplier=plan.supplier_name,
fallback_customer=plan.customer_name,
fallback_destination=plan.destination_name,
)
return result