198 lines
6.8 KiB
Python
198 lines
6.8 KiB
Python
import json
|
|
from datetime import date
|
|
from decimal import Decimal
|
|
from pathlib import Path
|
|
|
|
from group import (
|
|
draft_from_group,
|
|
drafts_from_oms_payload,
|
|
group_by_supplier,
|
|
is_claimable,
|
|
is_oms_envelope,
|
|
missing_mdm_reason,
|
|
money4,
|
|
row_from_oms_item,
|
|
)
|
|
from repo import PurchaseContractRow
|
|
|
|
_OMS_EXAMPLE = (
|
|
Path(__file__).resolve().parent.parent / "examples" / "oms_purchase_contract.json"
|
|
)
|
|
|
|
|
|
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_protocol_rerun_is_not_claimable():
|
|
row = _row(contract_entry_status=0, contract_no="HT-OLD")
|
|
assert is_claimable(row) is False
|
|
|
|
|
|
def test_blank_contract_no_is_still_claimable():
|
|
assert is_claimable(_row(contract_entry_status=0, contract_no=" ")) is True
|
|
assert is_claimable(_row(contract_entry_status=0, contract_no="")) is True
|
|
assert is_claimable(_row(contract_entry_status=0, contract_no=None)) is True
|
|
|
|
|
|
def test_processing_or_done_is_not_claimable():
|
|
assert is_claimable(_row(process_status=3)) is False
|
|
assert is_claimable(_row(process_status=1)) is False
|
|
|
|
|
|
def test_group_by_supplier_keeps_fid_order_and_first_header():
|
|
rows = [
|
|
_row(fid=2, supplier_id="B", payment_term=30, supplier_mdm_code="MDM-B"),
|
|
_row(fid=1, supplier_id="A", payment_term=90, supplier_mdm_code="MDM-A"),
|
|
_row(fid=3, supplier_id="A", payment_term=60, oms_id=2026100502, goods_id="G0002"),
|
|
]
|
|
groups = group_by_supplier(rows)
|
|
assert [g[0].supplier_id for g in groups] == ["A", "B"]
|
|
assert [r.fid for r in groups[0]] == [1, 3]
|
|
draft = draft_from_group(groups[0])
|
|
assert draft.customer_code == "MDM-A"
|
|
assert draft.payment_days == "90"
|
|
assert draft.order_date == "2026-10-01"
|
|
assert draft.contract_sign_date == "2026-10-01"
|
|
assert draft.contract_start_date == "2026-10-02"
|
|
assert draft.contract_end_date == "2027-09-30"
|
|
assert draft.amount == "2000.0000"
|
|
assert draft.source_type == ""
|
|
assert draft.contract_category == ""
|
|
assert draft.settlement_type == ""
|
|
assert draft.is_prepayment == ""
|
|
assert draft.payment_method == ""
|
|
assert len(draft.goods_lines) == 2
|
|
assert draft.goods_lines[0].goods_code == "QX0100167583"
|
|
assert draft.goods_lines[0].operation_code == "QX0100167583"
|
|
assert draft.goods_lines[0].mdm_code == "QX0100167583"
|
|
assert draft.goods_lines[0].unit_price == "100.0000"
|
|
assert draft.belong_year == "2026"
|
|
|
|
|
|
# 同供应商但货主或三个日期任一不同,不得收成同一张草稿。
|
|
def test_same_supplier_splits_when_org_or_dates_differ():
|
|
rows = [
|
|
_row(fid=1, supplier_id="A"),
|
|
_row(fid=2, supplier_id="A", org_code="902", oms_id=2),
|
|
_row(fid=3, supplier_id="A", contract_sign_date=date(2026, 11, 1), oms_id=3),
|
|
_row(fid=4, supplier_id="A", contract_start_date=date(2026, 11, 2), oms_id=4),
|
|
_row(fid=5, supplier_id="A", contract_end_date=date(2028, 1, 1), oms_id=5),
|
|
_row(fid=6, supplier_id="A", oms_id=6, goods_id="G0009"),
|
|
]
|
|
groups = group_by_supplier(rows)
|
|
drafts = {
|
|
tuple(row.fid for row in group): draft_from_group(group) for group in groups
|
|
}
|
|
assert len(groups) == 5
|
|
assert (1, 6) in drafts
|
|
assert drafts[(1, 6)].amount == "2000.0000"
|
|
assert len(drafts[(1, 6)].goods_lines) == 2
|
|
for fid in (2, 3, 4, 5):
|
|
assert (fid,) in drafts
|
|
assert len(drafts[(fid,)].goods_lines) == 1
|
|
|
|
|
|
def test_missing_mdm_reason():
|
|
rows = [_row(supplier_mdm_code="")]
|
|
assert missing_mdm_reason(rows) == "缺少供应商MDM码"
|
|
assert missing_mdm_reason([_row(goods_mdm_code="")]) == "缺少货品MDM码"
|
|
assert missing_mdm_reason([_row()]) is None
|
|
|
|
|
|
def test_money4():
|
|
assert money4(Decimal("10.5")) == "10.5000"
|
|
|
|
|
|
def test_oms_envelope_skips_protocol_and_merges_same_supplier():
|
|
payload = json.loads(_OMS_EXAMPLE.read_text(encoding="utf-8"))
|
|
assert is_oms_envelope(payload) is True
|
|
drafts = drafts_from_oms_payload(payload)
|
|
assert len(drafts) == 1
|
|
draft = drafts[0]
|
|
assert draft.customer_code == "DW0100046361"
|
|
assert draft.customer_name == "重庆亿昊药业有限公司"
|
|
assert draft.order_date == "2026-10-25"
|
|
assert draft.contract_sign_date == "2026-10-25"
|
|
assert draft.contract_start_date == "2026-10-25"
|
|
assert draft.contract_end_date == "2027-10-24"
|
|
assert draft.amount == "300.0000"
|
|
assert draft.payment_days == "30"
|
|
assert draft.belong_year == "2026"
|
|
assert draft.submit_mode == "submit"
|
|
assert [line.mdm_code for line in draft.goods_lines] == [
|
|
"FQX0100020661",
|
|
"FQX0100031787",
|
|
"FQX0100044037",
|
|
]
|
|
assert [line.quantity for line in draft.goods_lines] == [10.0, 10.0, 10.0]
|
|
|
|
|
|
def test_oms_item_maps_mdm_and_dates():
|
|
row = row_from_oms_item(
|
|
{
|
|
"fid": 9,
|
|
"omsId": 2026102509,
|
|
"supplierId": "SUP001",
|
|
"supplierName": "重庆亿昊药业有限公司",
|
|
"contractSignDate": "2026-10-25",
|
|
"contractStartDate": "2026-10-26",
|
|
"contractEndDate": "2027-10-24",
|
|
"paymentTerm": 90,
|
|
"goodsId": "G1",
|
|
"goodsName": "阿莫西林胶囊",
|
|
"regNo": "H1",
|
|
"spec": "0.25g",
|
|
"unit": "盒",
|
|
"qty": "2.0000",
|
|
"unitPrice": "12.5000",
|
|
"purchaserId": "P1",
|
|
"purchaserName": "张三",
|
|
"plannerId": "PL1",
|
|
"plannerName": "李四",
|
|
"orgCode": "901",
|
|
"goodsMdmCode": "FQX0100020661",
|
|
"supplierMdmCode": "DW0100046361",
|
|
}
|
|
)
|
|
assert row.fid == 9
|
|
assert row.oms_id == 2026102509
|
|
assert row.goods_mdm_code == "FQX0100020661"
|
|
assert row.supplier_mdm_code == "DW0100046361"
|
|
assert row.contract_start_date == date(2026, 10, 26)
|
|
assert row.qty == Decimal("2.0000")
|
|
assert is_claimable(row) is True
|
|
|
|
|
|
def test_page_draft_json_is_not_oms_envelope():
|
|
assert is_oms_envelope({"jobId": "x", "goodsLines": []}) is False
|
|
assert is_oms_envelope({"data": []}) is True
|