86 lines
3.0 KiB
Python
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
|