94 lines
2.8 KiB
Python
94 lines
2.8 KiB
Python
# 1 号药城导出行 → 表 2 operate_type=2。不对加购行。
|
||
|
||
from __future__ import annotations
|
||
|
||
import uuid
|
||
from dataclasses import dataclass
|
||
from decimal import Decimal, ROUND_HALF_UP
|
||
from typing import Any
|
||
|
||
YAOEX_PLATFORM_TYPE = 66
|
||
OPERATE_TYPE_PAY = 2
|
||
PUSH_NOT_SENT = 0
|
||
UNASSIGNED_OMS_ID = 0
|
||
PAID_STATUSES = {"待发货", "待收货", "已完成"}
|
||
|
||
|
||
# 金额收到四位小数,四舍五入。接口 2 组包也按这个精度。
|
||
def money4(value: object) -> Decimal:
|
||
return Decimal(str(value)).quantize(Decimal("0.0001"), rounding=ROUND_HALF_UP)
|
||
|
||
|
||
# 生成支付明细号。表 2 用它区分同一订单下的不同行。
|
||
def new_pay_dtl_id() -> str:
|
||
return uuid.uuid4().hex
|
||
|
||
|
||
# 1 号药城导出的一行订单明细。只取已支付状态落表。
|
||
@dataclass(frozen=True)
|
||
class MallLine:
|
||
order_no: str
|
||
parent_order_no: str
|
||
supplier_name: str
|
||
status: str
|
||
goods_name: str
|
||
product_code: str
|
||
bar_code: str
|
||
unit_price: Decimal
|
||
pay_price: Decimal
|
||
qty: int
|
||
goods_amount: Decimal
|
||
order_paid: Decimal
|
||
|
||
|
||
# 支付匹配结果:可落库的行、对不上的行、重复订单、状态未付。
|
||
@dataclass
|
||
class MatchResult:
|
||
rows: list[dict[str, Any]]
|
||
unmatched: list[tuple[MallLine, str]]
|
||
skipped_dup: list[MallLine]
|
||
skipped_status: list[MallLine]
|
||
|
||
|
||
# 筛出待发货、待收货、已完成的行。同一支付订单号已落过的跳过。条码超长不对上。
|
||
def match_pay_lines(
|
||
lines: list[MallLine],
|
||
existing_order_nos: set[str],
|
||
) -> MatchResult:
|
||
result = MatchResult(rows=[], unmatched=[], skipped_dup=[], skipped_status=[])
|
||
for line in lines:
|
||
if line.status not in PAID_STATUSES:
|
||
result.skipped_status.append(line)
|
||
continue
|
||
if line.order_no in existing_order_nos:
|
||
result.skipped_dup.append(line)
|
||
continue
|
||
if len(line.bar_code) > 40:
|
||
result.unmatched.append((line, "BAR_CODE_TOO_LONG"))
|
||
continue
|
||
result.rows.append(build_pay_row(line))
|
||
return result
|
||
|
||
|
||
# 把一条已支付明细收成表 2 支付行。operate_type=2,oms_id 先填 0,不改加购行。
|
||
def build_pay_row(line: MallLine) -> dict[str, Any]:
|
||
price = money4(line.pay_price)
|
||
qty = int(line.qty)
|
||
return {
|
||
"operate_type": OPERATE_TYPE_PAY,
|
||
"oms_id": UNASSIGNED_OMS_ID,
|
||
"platform_type": YAOEX_PLATFORM_TYPE,
|
||
"supplier_name": line.supplier_name,
|
||
"bar_code": line.bar_code,
|
||
"purchase_price": price,
|
||
"purchase_qty": qty,
|
||
"purchase_total": money4(price * qty),
|
||
"status": None,
|
||
"fail_reason": None,
|
||
"pay_order_no": line.order_no,
|
||
"pay_order_dtl_id": new_pay_dtl_id(),
|
||
"push_status": PUSH_NOT_SENT,
|
||
"org_code": None,
|
||
"multi_platform_flag": 0,
|
||
}
|