企业 采购应计

Odoo 企业版采购关账为什么不是“看未开票采购单”而已:prepaid expense、bill to receive 与 accrual 搜索口径讲透

purchase_accountant 不是给采购单多几个筛选器这么简单。它重写的是关账观察角度:哪些采购行其实是 prepaid expense,哪些还属于

企业 采购
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

月末关账最怕“未开票采购”这四个字听起来简单,落到采购行却根本不是一个维度。

这篇文章主要参考了以下企业版源码与测试入口:

  • enterprise/purchase_accountant/models/purchase_order_line.py

一、这个模块真正解决的不是表面动作,而是跨模块语义对齐

purchase_accountant 不是给采购单多几个筛选器这么简单。它重写的是关账观察角度:哪些采购行其实是 prepaid expense,哪些还属于 bill to receive,聚合和 read_group 时哪些字段必须跳过或打补丁。

如果只看 UI,很容易把它理解成一个按钮、一张表或一个新视图。但从 purchase_accountant 的模型、测试和桥接关系看,官方真正关心的是:前台动作发生以后,后端主链路能不能继续保持同一套业务语义

二、核心机制链路

1. prepaid expense 与 bill to receive 不是同一类

_search_prepaid_expense() 与 _search_bill_to_receive() 分开定义查询,说明系统明确区分“已经形成预付/待摊逻辑”和“还应收到供应商票据”两类业务。

2. accual 视角需要专门 domain

_get_accrual_domain() 与 _get_accrual_line_ids(mode) 表明,关账不是泛用采购列表,而是围绕应计审查建立独立取数口径。

3. 聚合时要跳过会误导的字段

_read_group() 与 _get_aggregates_to_skip_and_fields_to_patch() 说明,普通采购列表的 groupby/aggregate 放到关账面板并不总是正确,需要补丁避免统计口径被污染。

三、最容易被误解的边界

  • 把 purchase closing 等同于“未开票采购单列表”。
  • 将 prepaid expense 和 bill to receive 混为一谈,导致后续会计动作方向错。
  • 直接复用普通 read_group 结果做关账分析,忽略 accrual 专属修补。

这些误解之所以常见,往往是因为大家只看见“入口动作”,却没有继续追到模型方法、状态切换、聚合口径和测试场景里去看 Odoo 究竟把什么当成事实、把什么当成辅助信息。

四、实施与排查时,建议按这个顺序看

  • 先用两类 search 分别验证采购行落在哪个集合。
  • 再核对 accrual domain 是否覆盖正确状态与日期。
  • 最后检查 read_group 结果有没有被 patch 成关账所需口径。

对企业版功能来说,排查顺序非常重要。很多看似是“结果不对”的问题,真正根因往往更早:字段上下文没带过去、桥接对象没建、状态机没推进、或者权限/公司边界一开始就错了。

五、结论

采购关账之所以难,不是因为单据多,而是因为采购行在会计视角下会分裂成不同的应计语义;purchase_accountant 正是在这里补了脑。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。