193 lines
6.4 KiB
Python
193 lines
6.4 KiB
Python
# 返利班结果:查号 / 送审 → 表 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,
|
||
}
|