"""单元测试:发票字段抽取(不依赖 PaddleOCR) 直接喂文本,验证字段抽取与金额校验逻辑。 """ import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent sys.path.insert(0, str(ROOT)) # 强制 UTF-8 输出(Windows cp936 默认中文乱码) try: sys.stdout.reconfigure(encoding="utf-8") except Exception: pass from app.services import extract_invoice # noqa: E402 SAMPLE_VAT_ELEC = """ 增值税电子普通发票 发票代码: 011002000000 发票号码: 12345678 开票日期: 2024年05月20日 名称: 上海某科技有限公司 纳税人识别号: 91310115MA1K3X9Y8A 名称: 北京某某贸易有限公司 纳税人识别号: 91110108MA01K3X9Y8A 金额 ¥1234.56 税额 ¥74.07 价税合计 ¥1308.63 (贰仟零捌元陆角叁分) 备注: """ SAMPLE_VAT_SPECIAL = """ 增值税专用发票 发票代码 011002100111 发票号码 87654321 开 票 日 期: 2023年12月01日 名 称: 深圳某有限公司 纳税人识别号: 91440300MA5DCBA123 名 称: 广州某科技股份公司 纳税人识别号: 91440101MA59ABC987 不含税价 ¥10000.00 税率 13% 税 额 ¥1300.00 价税合计(大写)壹万壹仟叁佰元整 (小写)¥11300.00 """ def test_vat_electronic(): fields = extract_invoice(SAMPLE_VAT_ELEC) print(fields.model_dump_json(indent=2)) assert fields.invoice_type == "增值税电子普通发票" assert fields.invoice_code == "011002000000" assert fields.invoice_no == "12345678" assert fields.invoice_date == "2024-05-20" assert fields.amount is not None and abs(fields.amount - 1308.63) < 0.01 def test_vat_special(): fields = extract_invoice(SAMPLE_VAT_SPECIAL) print(fields.model_dump_json(indent=2)) assert fields.invoice_type == "增值税专用发票" assert fields.invoice_no == "87654321" assert fields.invoice_date == "2023-12-01" assert fields.amount is not None and abs(fields.amount - 11300.0) < 0.01 # 大写金额提取(壹万壹仟叁佰元整) assert fields.amount_cn is not None assert "壹万" in fields.amount_cn or "万" in fields.amount_cn # 大写 vs 小写一致 assert fields.amount_match is True def test_amount_consistency(): """大写小写一致""" from app.utils import amount_consistent assert amount_consistent("贰佰元整", 200.0) is True assert amount_consistent("壹仟元整", 1000.0) is True # 不一致 assert amount_consistent("贰佰元整", 300.0) is False if __name__ == "__main__": test_vat_electronic() print("-" * 60) test_vat_special() print("-" * 60) test_amount_consistency() print("✅ all tests passed")