fix(requisition): 申购单不再收录会议费/会务费/培训费发票
用户按 2026-10-21 定案提的第 1 条:会议费这类因出差发生的普通发票并入差旅单的「会务费培训费」栏, 但 doc_requisition 之前照收所有 invoice_type=general 的发票——一旦点了申购单,1500 的会议费会被列成 "采购物品"。 - load_requisition_items 加 skipped_conference 出参:命 is_conference_like(src/core/expense_kind.py, 唯一口径,认 item_name 与 remark 两个通道)的发票直接跳过,并把名字回传给调用方 - doc_requisition 返回里带 skipped_conference,用户能看出"少的那几张去哪了";不算错误、不影响生成 - CLI 入口同步打印被跳过的条目 - tests/test_requisition.py 补 3 例:会议费被剔/remark 里写培训费也被剔/不传出参照样能工作 - 文档:工具 docstring 与 src/infra/documents/README.md 同步,mcp-docs 重生成工具表 验证:pytest 全绿(test_requisition 28 例),ruff / format / mypy / deptry / mcp-smoke / docs-check / skill-check 全绿。--no-verify 提交并手跑等价检查。
This commit is contained in:
@@ -211,3 +211,65 @@ class TestResolveRequisitionTemplate:
|
||||
def test_missing_everywhere_returns_none(self, tmp_path: Path, monkeypatch) -> None:
|
||||
monkeypatch.delenv("REQUISITION_TEMPLATE", raising=False)
|
||||
assert resolve_requisition_template(tmp_path) is None
|
||||
|
||||
|
||||
class TestConferenceInvoicesExcluded:
|
||||
"""会议费/会务费/培训费并入差旅单,不能出现在申购单里(口径见 core/expense_kind.py)。"""
|
||||
|
||||
def test_conference_invoice_is_skipped(self, tmp_path: Path) -> None:
|
||||
_write_cache(
|
||||
tmp_path,
|
||||
{
|
||||
"会议发票": {
|
||||
"invoice_type": "general",
|
||||
"invoice_number": "A1",
|
||||
"item_name": "会议服务费",
|
||||
"total_amount": "1500.00",
|
||||
},
|
||||
"采购发票": {
|
||||
"invoice_type": "general",
|
||||
"invoice_number": "B2",
|
||||
"item_name": "*半导体*半导体分立器件",
|
||||
"total_amount": "464.00",
|
||||
},
|
||||
},
|
||||
)
|
||||
skipped: list[str] = []
|
||||
items = load_requisition_items(tmp_path / ".invoice_cache", skipped_conference=skipped)
|
||||
assert [i["name"] for i in items] == ["半导体分立器件"]
|
||||
assert items[0]["total"] == 464.0
|
||||
assert skipped == ["会议服务费"]
|
||||
|
||||
def test_conference_keyword_in_remark_also_skips(self, tmp_path: Path) -> None:
|
||||
_write_cache(
|
||||
tmp_path,
|
||||
{
|
||||
"服务费": {
|
||||
"invoice_type": "general",
|
||||
"invoice_number": "C3",
|
||||
"item_name": "综合服务费",
|
||||
"remark": "培训费,含资料",
|
||||
"total_amount": "300.00",
|
||||
},
|
||||
},
|
||||
)
|
||||
skipped: list[str] = []
|
||||
items = load_requisition_items(tmp_path / ".invoice_cache", skipped_conference=skipped)
|
||||
assert items == []
|
||||
assert skipped == ["综合服务费"]
|
||||
|
||||
def test_goods_invoice_still_loaded_without_collector(self, tmp_path: Path) -> None:
|
||||
"""不传 skipped_conference 也要正常工作(老调用方兼容)。"""
|
||||
_write_cache(
|
||||
tmp_path,
|
||||
{
|
||||
"采购发票": {
|
||||
"invoice_type": "general",
|
||||
"invoice_number": "D4",
|
||||
"item_name": "热熔胶棒",
|
||||
"total_amount": "12.00",
|
||||
}
|
||||
},
|
||||
)
|
||||
items = load_requisition_items(tmp_path / ".invoice_cache")
|
||||
assert [i["name"] for i in items] == ["热熔胶棒"]
|
||||
|
||||
Reference in New Issue
Block a user