AutoRpa/rpa_cart/repo.py

122 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 表 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