第三十九章 Extract API
篇别:第九篇 API 与系统集成
本章学习目标
- 理解 文档解析 / OCR(Extract) 在 费报、发票入账 等流程中的 位置。
- 能设计 上传 → 轮询状态 → 应用字段 的 异步工作流,并处理 低置信度与人工复核。
- 掌握 集成测试 策略:Mock HTTP、fixture JSON、CI 不调真实云。
- 关注 合规:影像保留、访问控制、跨境数据传输。
导读:Extract 是「人机协同」流水线
自动提取 供应商发票、小票、合同 能减少录入;但 模型会错、扫描质量差、版式陌生 时,100% 自动过账 往往 不可接受。产品形态上常见:上传附件 → Extract 服务返回候选字段与置信度 → 用户确认或会计规则兜底 → 写入 account.move 等业务单据。本章与 会计模块、第三方 OCR SaaS 强相关,API 细节以官方与订阅版本文档为准。
39.1 文档解析 API(新增)
39.1.1 知识要点
- 流程:上传文档(PDF/图片) → 异步解析 → 轮询或 webhook 拿结果 → 映射到 Odoo 字段 → 创建/更新业务记录。
- 置信度:字段级 score;低于阈值 标红、强制人工确认 或 留空。
- 与 account 衔接:
account.move行、税、伙伴匹配;伙伴 可 fuzzy match + 人工选。 - 幂等:同一 附件 hash 不重复扣费 / 不重复建单(若服务商支持 idempotency key)。
- 语言与时区:日期格式、小数分隔符 依赖 locale;统一服务端规范化。
39.1.2 案例(伪流程)
1. POST /extract/upload → { job_id }
2. GET /extract/status/{job_id} until succeeded
3. GET /extract/result/{job_id} → { lines: [{ label, value, confidence }] }
4. Odoo: 打开 wizard,用户调字段 → action_apply → account.move.create(...)
39.1.3 截图占位

39.1.4 本节练习
- 简答:低置信度字段 应如何处理?(至少 人工确认、留空、规则默认 三选一以上。)
- 判断:Extract 返回的金额 可直接
sudo入账,无需会计审核。( )
参考答案提示:2. 错(视内控;多数组织需 复核)。
39.2 集成测试(新增)
39.2.1 知识要点
- Mock:
unittest.mock.patch("requests.post")返回 fixture JSON;断言 映射逻辑,不依赖外网。 - Fixture:脱敏真实响应 存
tests/fixtures/extract_invoice_ok.json;版本化 API schema。 - 负例:超时、422、空结果、部分字段缺失;确保 UserError 友好。
- CI:禁止 使用 生产 API Key;staging key 亦建议 Mock 优先。
39.2.2 案例
from unittest.mock import patch, Mock
@patch("requests.post")
def test_map_extract_to_move_line(mock_post):
mock_post.return_value = Mock(status_code=200, json=lambda: {"lines": [{"k": "total", "v": "100.00", "c": 0.99}]})
# 调用你的解析函数,断言生成的 move line 金额
39.2.3 截图占位

39.2.4 本节练习
- 实操:写一个 单元测试,断言 fixture JSON 映射到 发票行 的 数量/价格(可简化模型)。
- 简答:为何 CI 不宜 每次调用 真实云 Extract?
参考答案提示:2. 费用、不稳定、速率限制、密钥泄露风险。
本章综合练习
- 合规:票据影像 保留期限 与 访问控制(组、审计、加密备份 各提一条)。
- 成本:按量计费 API 的 缓存与去重 策略(附件 hash、任务去重、批量上传窗口)。
- 综合:画出 「用户上传 → 会计过账」 的 泳道图(用户、Odoo、Extract 服务 三泳道)。
- 实操:列出 三种 应拒绝自动入账 的业务信号(低置信度、缺税号、金额异常 等)。
本章对应白皮书目录:第三十九章 Extract API。