feat: 合同班内存领取并写表4

This commit is contained in:
Yuuuu 2026-10-05 22:56:46 +08:00
parent e8ef1a77fc
commit 71fc1c3b60
3 changed files with 197 additions and 1 deletions

91
rpa_contract/persist.py Normal file
View File

@ -0,0 +1,91 @@
"""合同班结果:ContractOutcome → 表 4 行 + 表 3 状态。"""
from __future__ import annotations
from dataclasses import dataclass
from repo import PurchaseContractRow
KIND_OK = "ok"
KIND_DILIGENCE = "diligence"
KIND_FAIL = "fail"
STAMP = "合同班"
PROCESS_RESULT_MAX = 1000
FAIL_REASON_MAX = 500
@dataclass(frozen=True)
class ContractOutcome:
kind: str
contract_no: str | None
reason: str | None
@dataclass(frozen=True)
class GroupSave:
fids: list[int]
process_status: int
process_result: str
table4_rows: list[dict]
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:
kind = outcome.kind
number = (outcome.contract_no or "").strip() or None
if kind == KIND_OK and number:
process_status = 1
process_result = "合同已提交"
contract_status = 1
fail_reason = None
contract_no = number
elif kind == KIND_DILIGENCE:
process_status = 2
process_result = clip("客户未尽调", PROCESS_RESULT_MAX)
contract_status = 3
fail_reason = "客户未尽调"
contract_no = None
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
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,
"org_code": row.org_code,
"create_user_id": 0,
"create_user_name": STAMP,
"update_user_id": 0,
"update_user_name": STAMP,
}
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,
)

View File

@ -1,9 +1,10 @@
"""表 3 合同行与仓库。Memory / Oracle 在后续任务补全。""" """表 3 领取、表 4 写入。Oracle 仓库后续任务补全。"""
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass from dataclasses import dataclass
from datetime import date from datetime import date
from decimal import Decimal from decimal import Decimal
from typing import Any
@dataclass @dataclass
@ -34,3 +35,35 @@ class PurchaseContractRow:
goods_mdm_code: str | None goods_mdm_code: str | None
supplier_mdm_code: str | None supplier_mdm_code: str | None
process_result: str = "" process_result: str = ""
class MemoryContractRepo:
def __init__(self, rows: list[PurchaseContractRow]):
self.table3 = {row.fid: row for row in rows}
self.table4: list[dict] = []
self._next_fid = 1
def claim_pending(self, limit: int | None = None) -> list[PurchaseContractRow]:
from group import is_claimable
pending = sorted(
(row for row in self.table3.values() if is_claimable(row)),
key=lambda row: row.fid,
)
if limit is not None:
pending = pending[:limit]
for row in pending:
row.process_status = 3
return pending
def save_group(self, payload: Any) -> None:
for row in payload.table4_rows:
item = dict(row)
item["fid"] = self._next_fid
self._next_fid += 1
self.table4.append(item)
for fid in payload.fids:
target = self.table3[fid]
target.process_status = payload.process_status
target.process_result = payload.process_result

View File

@ -0,0 +1,72 @@
from datetime import date
from decimal import Decimal
from persist import KIND_OK, ContractOutcome, build_save
from repo import MemoryContractRepo, PurchaseContractRow
def _row(**overrides) -> PurchaseContractRow:
data = dict(
fid=1,
oms_id=2026100501,
supplier_id="SUP001",
supplier_name="示例供应商",
contract_sign_date=date(2026, 10, 1),
contract_start_date=date(2026, 10, 2),
contract_end_date=date(2027, 9, 30),
payment_term=90,
goods_id="G0001",
goods_name="阿莫西林胶囊",
reg_no="国药准字H20201234",
spec="0.25g*24粒",
unit="盒",
qty=Decimal("10.0000"),
unit_price=Decimal("100.0000"),
purchaser_id="P001",
purchaser_name="张三",
planner_id="PL001",
planner_name="李四",
contract_entry_status=None,
contract_no=None,
process_status=0,
org_code="901",
goods_mdm_code="QX0100167583",
supplier_mdm_code="DW0100046361",
)
data.update(overrides)
return PurchaseContractRow(**data)
def test_claim_pending_sets_processing_and_skips_protocol_rerun():
repo = MemoryContractRepo(
[
_row(),
_row(fid=2, oms_id=2026100502, process_status=1),
_row(fid=3, oms_id=2026100503, contract_entry_status=0, contract_no="HT-OLD"),
]
)
claimed = repo.claim_pending()
assert [row.fid for row in claimed] == [1]
assert repo.table3[1].process_status == 3
assert repo.table3[3].process_status == 0
def test_save_group_inserts_one_table4_row_per_oms_id():
repo = MemoryContractRepo(
[
_row(),
_row(fid=2, oms_id=2026100501, goods_id="G0002"),
_row(fid=3, oms_id=2026100502, goods_id="G0003"),
]
)
repo.claim_pending()
outcome = ContractOutcome(KIND_OK, "HT20261005001", None)
payload = build_save(list(repo.table3.values()), outcome)
repo.save_group(payload)
assert [row["oms_id"] for row in repo.table4] == [2026100501, 2026100502]
assert {row["contract_no"] for row in repo.table4} == {"HT20261005001"}
assert {row["action_code"] for row in repo.table4} == {1}
assert {row["contract_status"] for row in repo.table4} == {1}
assert {row["push_status"] for row in repo.table4} == {0}
assert repo.table3[1].process_status == 1
assert repo.table3[3].process_status == 1