122 lines
3.9 KiB
Python
122 lines
3.9 KiB
Python
# 表 2:写支付行。
|
||
#
|
||
# 连接从 rpa_oracle 池取。库故障对外「数据库不可用」,不含 ORA 原文。
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
from rpa_oracle import RepoUnavailable, job_pool
|
||
|
||
CREATE_USER_NAME = "rpa-cart"
|
||
from settle import YAOEX_PLATFORM_TYPE
|
||
|
||
_SELECT_PAY_ORDER_NOS = """
|
||
SELECT DISTINCT pay_order_no
|
||
FROM rpa_cart_settlement_goods_data
|
||
WHERE operate_type = 2
|
||
AND platform_type = :platform_type
|
||
AND pay_order_no 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",
|
||
)
|
||
|
||
|
||
# 回滚当前事务。回滚本身失败则忽略。
|
||
def _rollback(conn) -> None:
|
||
try:
|
||
conn.rollback()
|
||
except Exception:
|
||
pass
|
||
|
||
|
||
# 支付班次连 Oracle 的仓库,管表 2 operate_type=2 的读写。
|
||
class OraclePayRepo:
|
||
# 挂上连接池。方法里按次 acquire。
|
||
def __init__(self, pool):
|
||
self._pool = pool
|
||
|
||
# 按环境变量建班次池。缺 HOST / 用户 / 密码抛「数据库不可用」。
|
||
@classmethod
|
||
def from_env(cls) -> "OraclePayRepo":
|
||
return cls(pool=job_pool())
|
||
|
||
# 读表 2 已有的 1 号药城支付单号,空值丢掉。
|
||
def load_existing_pay_order_nos(self) -> set[str]:
|
||
try:
|
||
with self._pool.acquire() as conn:
|
||
try:
|
||
with conn.cursor() as cur:
|
||
cur.execute(
|
||
_SELECT_PAY_ORDER_NOS,
|
||
{"platform_type": YAOEX_PLATFORM_TYPE},
|
||
)
|
||
return {
|
||
str(order_no)
|
||
for (order_no,) in cur.fetchall()
|
||
if order_no
|
||
}
|
||
except Exception as exc:
|
||
if isinstance(exc, RepoUnavailable):
|
||
raise
|
||
raise RepoUnavailable("数据库不可用") from exc
|
||
except RepoUnavailable:
|
||
raise
|
||
except Exception as exc:
|
||
raise RepoUnavailable("数据库不可用") from exc
|
||
|
||
# 把支付行一次 executemany 插入表 2。空列表直接返回。同一连接同一事务。
|
||
def save_pay_rows(self, rows: list[dict[str, Any]]) -> None:
|
||
if not rows:
|
||
return
|
||
binds = []
|
||
for row in rows:
|
||
payload = {key: row.get(key) for key in _PAY_BIND_KEYS}
|
||
payload["create_user_name"] = CREATE_USER_NAME
|
||
binds.append(payload)
|
||
try:
|
||
with self._pool.acquire() as conn:
|
||
try:
|
||
with conn.cursor() as cur:
|
||
cur.executemany(_INSERT_PAY, binds)
|
||
conn.commit()
|
||
except Exception as exc:
|
||
_rollback(conn)
|
||
if isinstance(exc, RepoUnavailable):
|
||
raise
|
||
raise RepoUnavailable("数据库不可用") from exc
|
||
except RepoUnavailable:
|
||
raise
|
||
except Exception as exc:
|
||
raise RepoUnavailable("数据库不可用") from exc
|