AutoRpa/rpa_contract/tests/test_job.py

169 lines
5.4 KiB
Python

from datetime import date
from decimal import Decimal
from errors import DiligenceError, NodeError
from job import outcome_from_run, run_batch
from persist import KIND_DILIGENCE, KIND_FAIL, 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
def test_job_merges_same_supplier_and_writes_table4():
repo = MemoryContractRepo(
[
_row(),
_row(fid=2, oms_id=2026100502, goods_id="G0002"),
_row(fid=3, oms_id=2026100503, contract_entry_status=0, contract_no="HT-OLD"),
]
)
calls: list = []
def runner(draft):
calls.append(draft)
return ContractOutcome(KIND_OK, "HT20261005001", None)
run_batch(repo, runner=runner)
assert len(calls) == 1
assert [line.goods_code for line in calls[0].goods_lines] == [
"QX0100167583",
"QX0100167583",
]
assert [line.mdm_code for line in calls[0].goods_lines] == [
"QX0100167583",
"QX0100167583",
]
assert calls[0].customer_code == "DW0100046361"
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[2].process_status == 1
assert repo.table3[3].process_status == 0
def test_job_marks_diligence_fail():
repo = MemoryContractRepo([_row()])
def runner(draft):
return ContractOutcome(KIND_DILIGENCE, None, "客户未尽调")
run_batch(repo, runner=runner)
assert repo.table3[1].process_status == 2
assert "客户未尽调" in repo.table3[1].process_result
assert repo.table4[0]["contract_status"] == 3
assert repo.table4[0]["contract_no"] is None
assert repo.table4[0]["contract_fail_reason"] == "客户未尽调"
def test_job_skips_runner_when_mdm_missing():
repo = MemoryContractRepo([_row(supplier_mdm_code="")])
called = {"n": 0}
def runner(draft):
called["n"] += 1
return ContractOutcome(KIND_OK, "HT-X", None)
run_batch(repo, runner=runner)
assert called["n"] == 0
assert repo.table3[1].process_status == 2
assert "缺少供应商MDM码" in repo.table3[1].process_result
def test_outcome_from_run_maps_diligence():
def run():
raise DiligenceError("客户未尽调")
out = outcome_from_run(run)
assert out.kind == KIND_DILIGENCE
assert out.reason == "客户未尽调"
assert out.contract_no is None
def test_outcome_from_run_maps_empty_number_to_fail():
out = outcome_from_run(lambda: "")
assert out.kind == KIND_FAIL
assert "未读取到真实合同编号" in (out.reason or "")
def test_outcome_from_run_ok():
out = outcome_from_run(lambda: "HT9")
assert out == ContractOutcome(KIND_OK, "HT9", None)
def test_outcome_from_run_maps_node_error():
def run():
raise NodeError("客商加载失败")
out = outcome_from_run(run)
assert out.kind == KIND_FAIL
assert "客商加载失败" in (out.reason or "")