"""SDS 同步公共管道:映射订单(含内联 items)→ upsert 到 PG。""" from __future__ import annotations from typing import Any, Callable from flows.shared import resolve_courier_source from flows.shared.db import SyncDB from flows.shared.mappers import map_sds_goods, map_sds_order def map_sds_records( raw_orders: list[Any], channel_map: dict[int, str | None], channel_refresh: Callable[[], dict[int, str | None]] | None = None, skip_unpaid: bool = True, ) -> tuple[list[Any], list[Any], int]: """映射 SDS 订单+商品。返回 (order_inputs, goods_inputs, skipped_unpaid)。""" order_inputs: list[Any] = [] goods_inputs: list[Any] = [] refreshed: set[int] = set() skipped_unpaid = 0 for raw in raw_orders: courier = None if channel_refresh is not None: courier = resolve_courier_source(raw.logistics_id, channel_map, channel_refresh, refreshed) try: o = map_sds_order(raw, channel_map, courier) except Exception as err: # noqa: BLE001 print(f"[SDS] 映射订单失败 {getattr(raw, 'no', '?')}: {err}") continue if skip_unpaid and o.systemStatus == "待付款": skipped_unpaid += 1 continue order_inputs.append(o) for item in raw.items or []: try: goods_inputs.append(map_sds_goods(item, o.orderNo, o.createdAt)) except Exception as err: # noqa: BLE001 print(f"[SDS] 映射商品失败 order={o.orderNo}: {err}") return order_inputs, goods_inputs, skipped_unpaid def sync_sds_records( raw_orders: list[Any], channel_map: dict[int, str | None], db: SyncDB, channel_refresh: Callable[[], dict[int, str | None]] | None = None, skip_unpaid: bool = True, ) -> dict[str, int]: order_inputs, goods_inputs, skipped = map_sds_records( raw_orders, channel_map, channel_refresh, skip_unpaid ) stats = db.sync_orders_and_goods(order_inputs, goods_inputs) stats["orderCount"] = len(order_inputs) stats["goodsCount"] = len(goods_inputs) stats["skippedUnpaid"] = skipped return stats