"""接口 2:从表 2 取未推行,组装文档报文。 同一 omsId 的加购行必须在同一批 data 里。一批最多 500 条。 不改 push_status,不向订单中心发 HTTP(路径仍空)。 """ from __future__ import annotations from collections import OrderedDict from decimal import Decimal, ROUND_HALF_UP MAX_BATCH = 500 def load_cart_settlement_envelope(repo, limit: int = MAX_BATCH) -> dict: return build_cart_settlement_envelope(repo.list_unpushed(), limit=limit) def build_cart_settlement_envelope(rows: list[dict], limit: int = MAX_BATCH) -> dict: chosen = _take_complete_groups(rows, limit) return {"data": [_to_item(row) for row in chosen]} def _take_complete_groups(rows: list[dict], limit: int) -> list[dict]: groups: OrderedDict = OrderedDict() for row in rows: groups.setdefault(row["oms_id"], []).append(row) batch: list[dict] = [] for group in groups.values(): if len(batch) + len(group) > limit and batch: break batch.extend(group) return batch def _to_item(row: dict) -> dict: return { "fid": _as_int(row["fid"]), "operateType": _as_int(row["operate_type"]), "omsId": _as_int(row["oms_id"]), "platformType": _as_int(row["platform_type"]), "supplierName": row["supplier_name"], "barCode": row["bar_code"], "purchasePrice": _money4(row["purchase_price"]), "purchaseQty": _as_int(row["purchase_qty"]), "purchaseTotal": _money4(row["purchase_total"]), "status": _as_int(row["status"]) if row.get("status") is not None else None, "failReason": row.get("fail_reason"), "payOrderNo": row.get("pay_order_no"), "payOrderDtlId": row.get("pay_order_dtl_id"), "orgCode": row.get("org_code"), } def _as_int(value): if value is None: return None return int(value) def _money4(value) -> str: amount = Decimal(str(value)).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP) return f"{amount:.4f}"