"""审核 & 付款接口 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)