119 lines
3.7 KiB
Python
119 lines
3.7 KiB
Python
# 合同班结果:ContractOutcome → 表 4 行 + 表 3 状态。
|
||
|
||
from __future__ import annotations
|
||
|
||
from dataclasses import dataclass
|
||
|
||
from repo import PurchaseContractRow
|
||
|
||
KIND_OK = "ok"
|
||
KIND_DILIGENCE = "diligence"
|
||
KIND_FAIL = "fail"
|
||
KIND_HOLD = "hold"
|
||
# 提交后没读到号。下一班看到这个结果只查号,不再起草。
|
||
LOOKUP_ONLY_RESULT = "只查号"
|
||
USER_NAME = "系统管理员"
|
||
TABLE4_PENDING = 0
|
||
TABLE4_SKIP = 2
|
||
PROCESS_RESULT_MAX = 1000
|
||
FAIL_REASON_MAX = 500
|
||
|
||
|
||
# 录合同结果。error_text 只给审计表,不进原因列。
|
||
@dataclass(frozen=True)
|
||
class ContractOutcome:
|
||
kind: str
|
||
contract_no: str | None
|
||
reason: str | None
|
||
error_text: str | None = None
|
||
|
||
|
||
# 一组合同要写回的内容:表 3 的 fid 和状态,以及表 4 起草行。
|
||
@dataclass(frozen=True)
|
||
class GroupSave:
|
||
fids: list[int]
|
||
process_status: int
|
||
process_result: str
|
||
table4_rows: list[dict]
|
||
|
||
|
||
# 原因超长时截断并加省略号,避免写爆表 3 / 表 4 的原因列。
|
||
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 build_save(rows: list[PurchaseContractRow], outcome: ContractOutcome) -> GroupSave:
|
||
"""按录合同结果生成落库内容。
|
||
|
||
读到合同号:表 3 成功,表 4 起草行待返利领取。
|
||
未尽调或失败:表 3 失败,表 4 记失败并不再领。
|
||
查重多条或提交后没读到号:表 3 停在 3,不写表 4。同一 oms_id 只留一行。
|
||
"""
|
||
kind = outcome.kind
|
||
number = (outcome.contract_no or "").strip() or None
|
||
if kind == KIND_HOLD:
|
||
return GroupSave(
|
||
fids=[row.fid for row in rows],
|
||
process_status=3,
|
||
process_result=clip(outcome.reason or LOOKUP_ONLY_RESULT, PROCESS_RESULT_MAX),
|
||
table4_rows=[],
|
||
)
|
||
if kind == KIND_OK and number:
|
||
process_status = 1
|
||
process_result = "合同已提交"
|
||
contract_status = 1
|
||
fail_reason = None
|
||
contract_no = number
|
||
table4_process_status = TABLE4_PENDING
|
||
elif kind == KIND_DILIGENCE:
|
||
process_status = 2
|
||
process_result = clip("客户未尽调", PROCESS_RESULT_MAX)
|
||
contract_status = 3
|
||
fail_reason = "客户未尽调"
|
||
contract_no = None
|
||
table4_process_status = TABLE4_SKIP
|
||
else:
|
||
reason = outcome.reason or "合同录入失败"
|
||
if kind == KIND_OK and not number:
|
||
reason = "submit 模式未读取到真实合同编号"
|
||
process_status = 2
|
||
process_result = clip(reason, PROCESS_RESULT_MAX)
|
||
contract_status = 3
|
||
fail_reason = clip(reason, FAIL_REASON_MAX)
|
||
contract_no = None
|
||
table4_process_status = TABLE4_SKIP
|
||
|
||
seen: dict[int, PurchaseContractRow] = {}
|
||
for row in rows:
|
||
seen.setdefault(row.oms_id, row)
|
||
table4 = [
|
||
{
|
||
"oms_id": row.oms_id,
|
||
"action_code": 1,
|
||
"contract_status": contract_status,
|
||
"contract_fail_reason": fail_reason,
|
||
"contract_no": contract_no,
|
||
"agreement_status": None,
|
||
"agreement_fail_reason": None,
|
||
"agreement_id": None,
|
||
"agreement_dtl_id": None,
|
||
"push_status": 0,
|
||
"process_status": table4_process_status,
|
||
"org_code": row.org_code,
|
||
"create_user_id": 0,
|
||
"create_user_name": USER_NAME,
|
||
"update_user_id": 0,
|
||
"update_user_name": USER_NAME,
|
||
}
|
||
for row in seen.values()
|
||
]
|
||
return GroupSave(
|
||
fids=[row.fid for row in rows],
|
||
process_status=process_status,
|
||
process_result=process_result,
|
||
table4_rows=table4,
|
||
)
|