- tests/core: 新增 BaseHttpClient 统一 HTTP 封装(直连绕行/超时/日志/自定义编码); db_helper 追加 Db 长连接类(事务/mogrify/自动重连),既有函数不动 - tests/apis/yun8: 21 个 step 方法按域拆分为 5 个 Mixin(driver/accounting/ audit_payment/receipt/third_party),Yun8Pipeline 24 步编排原样迁移, SQL 全部参数化并集中至 sql_templates - tests/api: 5 阶段有序 P0 E2E 用例(业务失败由 print 改为真实报错)+ README 迁移(删除明文密码段,修正步骤编号漂移) - yun8_sync 目录退役:配置并入 test_config.yaml 的 yun8_api 段; 造数 CLI 保留(python -m tests.apis.yun8.cli,兼容旧 config.yaml 结构) - pytest.ini 注册 api/yun8_sync marker;requirements.txt 补 requests>=2.28 - 静态验证: compileall / 全仓 collect 24 条 / marker 过滤 / CLI --help / 客户端与 pipeline 离线实例化 / SQL 占位符核对 / cross_end 兼容
174 lines
7.4 KiB
Python
174 lines
7.4 KiB
Python
"""审核 & 付款接口 Mixin — step10-16(管理端)。
|
||
|
||
所有方法签名/返回值/默认值与旧 yun8_sync/client.py 逐字一致,
|
||
仅将原始 requests.Session 调用替换为 BaseHttpClient(self.admin_http)。
|
||
|
||
Usage:
|
||
from tests.apis.yun8.audit_payment_api import AuditPaymentApi
|
||
class Yun8ApiClient(AuditPaymentApi, ...): ...
|
||
"""
|
||
|
||
import math
|
||
|
||
|
||
class AuditPaymentApi:
|
||
"""审核 & 付款接口(挂载于 Yun8ApiClient,依赖 admin_http / ac / pm 属性)。"""
|
||
|
||
# ==================================================================
|
||
# Step 10: 查询运单审核
|
||
# ==================================================================
|
||
def step10_query_audit(self, order_code: str,
|
||
page_size: int = 20, page_num: int = 1) -> dict:
|
||
"""
|
||
GET /ntocc-tms-api/orderDetail (status=6 已结算, isSettle=1)
|
||
Admin 端查询已结算运单用于审核。
|
||
"""
|
||
params = {
|
||
"isAbnormalHelp": "",
|
||
"gmtCreatedRange": "",
|
||
"lastLoadingTimeRange": "",
|
||
"fillTimeRange": "",
|
||
"lastUnloadingTimeRange": "",
|
||
"signTimeRange": "",
|
||
"settleTimeRange": "",
|
||
"gmtModifiedRange": "",
|
||
"pageNum": page_num,
|
||
"pageSize": page_size,
|
||
"isSettle": "1",
|
||
"status": "6",
|
||
"payerReceiverLinkMan": self.ac.get("payer_receiver_link_man", ""),
|
||
"sortField": "",
|
||
"sortType": "",
|
||
"orderCode": order_code,
|
||
}
|
||
return self.admin_http.get("/ntocc-tms-api/orderDetail", params)
|
||
|
||
# ==================================================================
|
||
# Step 11: 核算审核通过
|
||
# ==================================================================
|
||
def step11_approve_audit(self, code: str) -> dict:
|
||
"""
|
||
POST /ntocc-tms-api/orderDetail/auditOrderDetail?orderDetailCodes={code}&isPass=true
|
||
"""
|
||
params = {"orderDetailCodes": code, "isPass": "true"}
|
||
return self.admin_http.request_with_encoded_query(
|
||
"POST", "/ntocc-tms-api/orderDetail/auditOrderDetail", params=params)
|
||
|
||
# ==================================================================
|
||
# Step 12: 队长分账预览 (captainSplitAdjustPreview)
|
||
# ==================================================================
|
||
def step12_captain_split_preview(self, order_detail_code: str) -> dict:
|
||
"""
|
||
GET /ntocc-tms-api/orderDetail/captainSplitAdjustPreview/{code}
|
||
仅在 payerReceiver 不为空且 captainSplitMode=2 时调用。
|
||
"""
|
||
path = f"/ntocc-tms-api/orderDetail/captainSplitAdjustPreview/{order_detail_code}"
|
||
return self.admin_http.get(path)
|
||
|
||
# Step 13: 队长分账调整 (adjustCaptainSplit)
|
||
# ==================================================================
|
||
def step13_adjust_captain_split(self, order_detail_code: str,
|
||
latest_driver_amount: float,
|
||
delivery_oil_fee: float) -> dict:
|
||
"""
|
||
POST /ntocc-tms-api/orderDetail/adjustCaptainSplit
|
||
Content-Type: application/json;charset=UTF-8
|
||
|
||
driverAmount = ceil(latestDriverAmount * 0.8 * 100) / 100
|
||
captainAmount = latestDriverAmount - driverAmount
|
||
oilFee = deliveryOilFee
|
||
"""
|
||
driver_amount = math.ceil(latest_driver_amount * 0.8 * 100) / 100.0
|
||
captain_amount = round(latest_driver_amount - driver_amount, 2)
|
||
body = {
|
||
"orderDetailCode": order_detail_code,
|
||
"driverAmount": str(driver_amount),
|
||
"captainAmount": str(captain_amount),
|
||
"oilFee": delivery_oil_fee,
|
||
}
|
||
return self.admin_http.post_json(
|
||
"/ntocc-tms-api/orderDetail/adjustCaptainSplit", body)
|
||
|
||
# Step 14: 单油卡充值 (singleOil)
|
||
# ==================================================================
|
||
def step14_single_oil(self, order_detail_code: str, amount: str = "0.03",
|
||
pay_type: str = "1", category: str = "1") -> dict:
|
||
"""
|
||
POST /ntocc-tms-api/finance/singleOil
|
||
Query params: payType, amount, orderDetailCode, category, isAdvancePayment
|
||
No body (content-length: 0)
|
||
|
||
在垫资-财务打款之前调用,处理油卡充值。
|
||
"""
|
||
params = {
|
||
"payType": pay_type,
|
||
"amount": amount,
|
||
"orderDetailCode": order_detail_code,
|
||
"category": category,
|
||
"isAdvancePayment": "1",
|
||
}
|
||
return self.admin_http.request_with_encoded_query(
|
||
"POST", "/ntocc-tms-api/finance/singleOil", params=params)
|
||
|
||
# ==================================================================
|
||
# Step 15: 垫资-财务打款
|
||
# ==================================================================
|
||
def step15_pay_to_driver(self, code: str, amount: str = None,
|
||
delivery_cash_fee: str = None,
|
||
driver_actual_freight: str = None,
|
||
plan_driver_payout: str = "0",
|
||
plan_captain_payout: str = "0") -> dict:
|
||
"""
|
||
POST /ntocc-tms-api/arpaTransfer/payToDriver
|
||
amount / deliveryCashFee / driverActualFreight 由 pipeline 从 step07 传入
|
||
planDriverPayout / planCaptainPayout 来自队长分账步骤,无分账时为 "0"
|
||
"""
|
||
if amount is None:
|
||
amount = "0.27"
|
||
if delivery_cash_fee is None:
|
||
delivery_cash_fee = "0.27"
|
||
if driver_actual_freight is None:
|
||
driver_actual_freight = "0.3"
|
||
params = {
|
||
"payTypes": self.pm.get("pay_types", "3,4,5,9,10,11"),
|
||
"amount": amount,
|
||
"orderDetailCode": code,
|
||
"infoFee": "0",
|
||
"pageNum": "1",
|
||
"pageSize": "20",
|
||
"totaltotal": "0",
|
||
"payerRole": "0",
|
||
"isAdvancePayment": "1",
|
||
"planDriverPayout": plan_driver_payout,
|
||
"planCaptainPayout": plan_captain_payout,
|
||
"allotAmount": "0",
|
||
"deliveryCashFee": delivery_cash_fee,
|
||
"driverActualFreight": driver_actual_freight,
|
||
"total": "0",
|
||
"payPlatform": self.pm.get("pay_platform", "3"),
|
||
"smsCode": self.pm.get("sms_code", "1234"),
|
||
"phone": self.pm.get("phone", "13888888888"),
|
||
}
|
||
return self.admin_http.request_with_encoded_query(
|
||
"POST", "/ntocc-tms-api/arpaTransfer/payToDriver", params=params)
|
||
|
||
# ==================================================================
|
||
# Step 16: 垫资-货主打款 (申请付款)
|
||
# ==================================================================
|
||
def step16_apply_for_payment(self, code: str, total_amount: str = None) -> dict:
|
||
"""
|
||
POST /ntocc-tms-api/orderDetail/applicationForPayment
|
||
totalAmount 应从 pipeline 传入 (step06 的 shipmentActualCash)
|
||
"""
|
||
if total_amount is None:
|
||
total_amount = "0.32"
|
||
params = {
|
||
"payType": self.pm.get("pay_type", "arpa_2"),
|
||
"totalAmount": total_amount,
|
||
"codes": code,
|
||
"payPlatform": self.pm.get("pay_platform", "3"),
|
||
"isAdvancePayment": "1",
|
||
}
|
||
return self.admin_http.request_with_encoded_query(
|
||
"POST", "/ntocc-tms-api/orderDetail/applicationForPayment", params=params)
|