141 lines
4.3 KiB
Python
141 lines
4.3 KiB
Python
"""表 2:读加购成功行,写支付行。"""
|
||
from __future__ import annotations
|
||
|
||
from collections.abc import Callable
|
||
from typing import Any
|
||
|
||
from db import CREATE_USER_NAME, RepoUnavailable, connect_from_env, oracle_dsn
|
||
from settle import CartCandidate, YAOEX_PLATFORM_TYPE
|
||
|
||
_SELECT_CART = """
|
||
SELECT fid, oms_id, platform_type, supplier_name, bar_code,
|
||
purchase_qty, NVL(org_code, '') AS org_code, multi_platform_flag
|
||
FROM rpa_cart_settlement_goods_data
|
||
WHERE operate_type = 1
|
||
AND status = 1
|
||
AND platform_type = :platform_type
|
||
ORDER BY fid
|
||
"""
|
||
|
||
_SELECT_PAY_KEYS = """
|
||
SELECT pay_order_no, pay_order_dtl_id
|
||
FROM rpa_cart_settlement_goods_data
|
||
WHERE operate_type = 2
|
||
AND platform_type = :platform_type
|
||
AND pay_order_no IS NOT NULL
|
||
AND pay_order_dtl_id IS NOT NULL
|
||
"""
|
||
|
||
_INSERT_PAY = """
|
||
INSERT INTO rpa_cart_settlement_goods_data (
|
||
operate_type, oms_id, platform_type, supplier_name, bar_code,
|
||
purchase_price, purchase_qty, purchase_total, status, fail_reason,
|
||
pay_order_no, pay_order_dtl_id, push_status, create_time,
|
||
org_code, multi_platform_flag, create_user_name
|
||
) VALUES (
|
||
:operate_type, :oms_id, :platform_type, :supplier_name, :bar_code,
|
||
:purchase_price, :purchase_qty, :purchase_total, :status, :fail_reason,
|
||
:pay_order_no, :pay_order_dtl_id, :push_status, SYSDATE,
|
||
:org_code, :multi_platform_flag, :create_user_name
|
||
)
|
||
"""
|
||
|
||
_PAY_BIND_KEYS = (
|
||
"operate_type",
|
||
"oms_id",
|
||
"platform_type",
|
||
"supplier_name",
|
||
"bar_code",
|
||
"purchase_price",
|
||
"purchase_qty",
|
||
"purchase_total",
|
||
"status",
|
||
"fail_reason",
|
||
"pay_order_no",
|
||
"pay_order_dtl_id",
|
||
"push_status",
|
||
"org_code",
|
||
"multi_platform_flag",
|
||
)
|
||
|
||
|
||
class EmptyPayRepo:
|
||
def load_cart_candidates(self) -> list[CartCandidate]:
|
||
return []
|
||
|
||
def load_existing_pay_keys(self) -> set[tuple[str, str]]:
|
||
return set()
|
||
|
||
def save_pay_rows(self, rows: list[dict[str, Any]]) -> None:
|
||
return
|
||
|
||
|
||
class OraclePayRepo:
|
||
def __init__(self, connect: Callable):
|
||
self._connect = connect
|
||
|
||
@classmethod
|
||
def from_env(cls) -> "OraclePayRepo":
|
||
oracle_dsn()
|
||
return cls(connect=connect_from_env)
|
||
|
||
def load_cart_candidates(self) -> list[CartCandidate]:
|
||
conn = self._connect()
|
||
try:
|
||
with conn.cursor() as cur:
|
||
cur.execute(_SELECT_CART, {"platform_type": YAOEX_PLATFORM_TYPE})
|
||
return [_cart_from_rec(cur, rec) for rec in cur.fetchall()]
|
||
except Exception as exc:
|
||
raise RepoUnavailable(str(exc)) from exc
|
||
finally:
|
||
conn.close()
|
||
|
||
def load_existing_pay_keys(self) -> set[tuple[str, str]]:
|
||
conn = self._connect()
|
||
try:
|
||
with conn.cursor() as cur:
|
||
cur.execute(_SELECT_PAY_KEYS, {"platform_type": YAOEX_PLATFORM_TYPE})
|
||
return {
|
||
(str(order_no), str(dtl_id))
|
||
for order_no, dtl_id in cur.fetchall()
|
||
if order_no and dtl_id
|
||
}
|
||
except Exception as exc:
|
||
raise RepoUnavailable(str(exc)) from exc
|
||
finally:
|
||
conn.close()
|
||
|
||
def save_pay_rows(self, rows: list[dict[str, Any]]) -> None:
|
||
if not rows:
|
||
return
|
||
conn = self._connect()
|
||
try:
|
||
with conn.cursor() as cur:
|
||
for row in rows:
|
||
payload = {key: row.get(key) for key in _PAY_BIND_KEYS}
|
||
payload["create_user_name"] = CREATE_USER_NAME
|
||
cur.execute(_INSERT_PAY, payload)
|
||
conn.commit()
|
||
except Exception as exc:
|
||
try:
|
||
conn.rollback()
|
||
except Exception:
|
||
pass
|
||
raise RepoUnavailable(str(exc)) from exc
|
||
finally:
|
||
conn.close()
|
||
|
||
|
||
def _cart_from_rec(cur, rec) -> CartCandidate:
|
||
cols = [item[0].lower() for item in cur.description]
|
||
data = dict(zip(cols, rec))
|
||
return CartCandidate(
|
||
fid=int(data["fid"]),
|
||
oms_id=int(data["oms_id"]),
|
||
supplier_name=str(data.get("supplier_name") or ""),
|
||
bar_code=str(data.get("bar_code") or ""),
|
||
purchase_qty=int(data.get("purchase_qty") or 0),
|
||
org_code=str(data.get("org_code") or ""),
|
||
multi_platform_flag=int(data.get("multi_platform_flag") or 0),
|
||
)
|