# 返利班结果:查号 / 送审 → 表 4 更新与插入、表 3 状态。 # # 搜不到把表 4 process_status 改回 0、表 3 改回 0。送审成功才插 action_code=2。 # 系统故障原因列写短码,不写异常原文。人名固定系统管理员。 from __future__ import annotations from dataclasses import dataclass, field KIND_OK = "ok" KIND_FAIL = "fail" KIND_NOT_FOUND = "not_found" KIND_HOLD = "hold" USER_NAME = "系统管理员" PROCESS_PENDING = 0 PROCESS_DONE = 1 PROCESS_RESULT_MAX = 1000 AGREEMENT_REASON_MAX = 500 # 一组合同的查号/录协议结果:成功带总单/细单号,失败带原因。 # # error_text 只给审计表,不进原因列。 @dataclass(frozen=True) class AgreementOutcome: kind: str agreement_id: str | None agreement_dtl_id: str | None reason: str | None error_text: str | None = None # 同一合同号下本班领到的起草行和只录协议行。 @dataclass class RebateGroup: contract_no: str drafts: list[dict] = field(default_factory=list) protocols: list[dict] = field(default_factory=list) # 一组合同要写回 Oracle 的表 4 更新/插入/释放和表 3 回写。 @dataclass(frozen=True) class GroupSave: table4_updates: list[dict] table4_inserts: list[dict] table4_release_fids: list[int] table3_updates: list[dict] # 把原因截到 max_len 字,超长末尾加省略号。 def clip(text: str, max_len: int) -> str: text = (text or "").strip() if len(text) <= max_len: return text return text[: max_len - 1] + "…" # 送审成功且总单号非空才算这一组过。 def agreement_ok(outcome: AgreementOutcome) -> bool: return outcome.kind == KIND_OK and bool((outcome.agreement_id or "").strip()) # 搜不到:起草行 process_status 改回 0,表 3 改回 0,不插协议行。 def build_not_found(group: RebateGroup) -> GroupSave: return GroupSave( table4_updates=[], table4_inserts=[], table4_release_fids=[int(row["fid"]) for row in group.drafts], table3_updates=[ {"fid": int(row["fid"]), "process_status": 0, "process_result": ""} for row in group.protocols ], ) def build_found(group: RebateGroup, outcome: AgreementOutcome) -> GroupSave: """搜到后按成败写表 4 / 表 3。 送审成功:起草行 contract_status=2、process_status=1,并按 oms_id 插 action_code=2。 确认失败:起草行 process_status 改回 0。读号失败保持 process_status=3,不插协议行。 只录协议行先补一条 action_code=1。只有确认没有单据才放回待领。 """ if outcome.kind == KIND_HOLD: reason = clip(outcome.reason or "读号失败", AGREEMENT_REASON_MAX) return GroupSave( table4_updates=[ { "fid": int(row["fid"]), "contract_status": 1, "process_status": 3, "agreement_fail_reason": reason, } for row in group.drafts ], table4_inserts=[], table4_release_fids=[], table3_updates=[ { "fid": int(row["fid"]), "process_status": 3, "process_result": reason, } for row in group.protocols ], ) ok = agreement_ok(outcome) number = (group.contract_no or "").strip() fail_reason = clip(outcome.reason or "协议录入失败", AGREEMENT_REASON_MAX) updates = [ { "fid": int(row["fid"]), "contract_status": 2 if ok else 1, "process_status": PROCESS_DONE if ok else PROCESS_PENDING, "agreement_fail_reason": None if ok else fail_reason, } for row in group.drafts ] inserts: list[dict] = [] seen_protocol: dict[int, dict] = {} for row in group.protocols: seen_protocol.setdefault(int(row["oms_id"]), row) for row in seen_protocol.values(): inserts.append(_action1_success(row, number)) if ok: seen_oms: dict[int, dict] = {} for row in group.drafts + group.protocols: seen_oms.setdefault(int(row["oms_id"]), row) for row in seen_oms.values(): inserts.append(_action2(row, number, outcome)) process_status = 1 process_result = "协议已录入" else: process_status = 2 process_result = clip(outcome.reason or "协议录入失败", PROCESS_RESULT_MAX) table3_updates = [ { "fid": int(row["fid"]), "process_status": process_status, "process_result": process_result, } for row in group.protocols ] return GroupSave( table4_updates=updates, table4_inserts=inserts, table4_release_fids=[], table3_updates=table3_updates, ) # 只录协议行补一条表 4 起草成功记录,action_code=1、contract_status=2。 def _action1_success(row: dict, contract_no: str) -> dict: return { "oms_id": int(row["oms_id"]), "action_code": 1, "contract_status": 2, "contract_fail_reason": None, "contract_no": contract_no, "agreement_status": None, "agreement_fail_reason": None, "agreement_id": None, "agreement_dtl_id": None, "push_status": 0, "process_status": PROCESS_DONE, "org_code": row.get("org_code"), "create_user_id": 0, "create_user_name": USER_NAME, "update_user_id": 0, "update_user_name": USER_NAME, } # 送审成功插一条协议行,action_code=2、agreement_status=1,带总单/细单号。 def _action2(row: dict, contract_no: str, outcome: AgreementOutcome) -> dict: return { "oms_id": int(row["oms_id"]), "action_code": 2, "contract_status": None, "contract_fail_reason": None, "contract_no": contract_no, "agreement_status": 1, "agreement_fail_reason": None, "agreement_id": (outcome.agreement_id or "").strip() or None, "agreement_dtl_id": (outcome.agreement_dtl_id or "").strip() or None, "push_status": 0, "process_status": PROCESS_DONE, "org_code": row.get("org_code"), "create_user_id": 0, "create_user_name": USER_NAME, "update_user_id": 0, "update_user_name": USER_NAME, }