规则诊断

Odoo 库存规则报告为什么不是“路线图打印版”:stock.rules.report、递归找规则与缺口诊断顺序讲透

很多人打开 Odoo 的 Stock Rules Report,以为那只是把 route 画成一张图。其实它真正有价值的地方,是把某个产品从目标库位往上递归命中的规则链可视化,帮助你诊断“为什么这里补不到货”。本文把这套诊断思路讲透。

库存
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的 Stock Rules Report,最不该被理解成“把库存路线画出来给你看看”。

它真正的价值是:

把某个产品在某个仓库视角下,沿着库位和规则递归命中的补货链可视化。

所以它最适合回答的问题不是:

  • 我们系统里配置了哪些 route?

而是:

  • 对这件产品、这个仓库、这个目标库位来说,系统到底会命中哪条规则链?
  • 为什么链条在某一步断了?
  • 为什么这里看起来应该能补,系统却补不到?

这就是“路线图”和“诊断工具”的根本区别。


为什么它不是普通 route 图

如果只是画 route 图,系统完全可以:

  • 把 route、rule、location 读出来;
  • 按配置关系连个线。

但 Odoo 的这份报告不是从“配置台账”出发,而是从:

  • 某个具体 product;
  • 某个 warehouse 组合;
  • 某个 location 递归追规则。

也就是说,它不是问“系统里有什么路”,而是在问:

这个具体场景下,系统会走哪条路。

这就天然更偏排错。


入口为什么叫 action_open_routes_diagram()

product.py 里,入口方法是 action_open_routes_diagram()

这个名字很容易让人误会成纯展示。

但你看内部逻辑会发现:

  • 如果用户没有多仓权限且产品唯一,Odoo 甚至会直接触发 report action;
  • 否则才先弹出 stock.rules.report 向导,让你选仓库后打印。

这说明“diagram”只是表现形式。 真正业务目的是:

  • 在给定产品和仓库上下文下,生成一份可用来判断规则命中的报告。

stock.rules.report 向导本身其实很薄

addons/stock/wizard/stock_rules_report.py 里的 transient model 很轻:

  • default_get() 根据上下文补产品和默认仓库;
  • _prepare_report_data() 只整理 product_idwarehouse_ids
  • print_report() 直接调用 report action。

这层设计很有意思:

  • 向导不负责业务推导;
  • 向导只负责收集你想诊断的上下文。

这也意味着,真正有价值的逻辑在报表背后,不在弹窗表单本身。


核心抓手:_get_rules_from_location()

最值得盯住的方法,是 product.py 里的 _get_rules_from_location()

这个方法的工作方式非常关键:

  1. 从当前 location 的 warehouse 视角出发;
  2. 调用 stock.rule._get_rule(...) 找当前命中的 rule;
  3. 如果没找到,就返回现有 seen_rules;
  4. 如果找到的 rule 已经见过,直接抛错,防止 endless loop;
  5. 如果 rule 是 make_to_stock,或者 action 不是 pull/pull_push,递归停止;
  6. 否则继续往 rule.location_src_id 递归找上游规则。

这段逻辑几乎把这份报告的灵魂讲完了。

因为它说明:

报告不是平铺所有规则,而是递归还原“这个需求会被谁往上游继续拉”。


为什么递归方向这么重要

很多人理解库存路线时,会下意识从“供给仓往需求仓”顺着看。

但补货诊断往往更适合反着看:

  • 这个目标库位要货;
  • 系统打算从哪里补;
  • 那个来源地如果自己没货,又会继续向哪里拉;
  • 直到链条结束,或者断掉。

_get_rules_from_location() 选择的正是这种逆向还原思路。

这也是为什么它特别适合查:

  • 缺少上游规则;
  • route 选错仓;
  • pull chain 在中间断裂;
  • 配置出现循环依赖。

seen_rules 和 endless loop 防护说明了什么

源码里一旦发现某条 rule 已经出现在 seen_rules 里,就直接抛:

  • Invalid rule's configuration, ... causes an endless loop

这个保护特别值得实施顾问重视。

因为它说明 Odoo 官方非常清楚:

  • route / rule 的问题不只是“找不到路”;
  • 还可能是“路绕成了圈”。

所以这份报告不是装饰性图表,而是有明确防错语义的配置诊断工具。


为什么 make_to_stock 会让递归停下

当 rule 的 procure_methodmake_to_stock,或者 action 不属于 pull/pull_push 时,方法就不再继续往上追。

这背后的业务逻辑是:

  • 一旦来到 make_to_stock,系统认为需求到这里就交给本地库存语义解决;
  • 它不再把这个节点继续解释成一条上游拉动链。

所以报告展现的不是“所有可能的库存动作”,而是:

  • 这条补货需求会沿着 pull 逻辑追到哪里为止。

这也是它和完整库存全景图区别最大的地方。


这份报告最适合查什么问题

最典型的,是这三类:

1. 某个仓 / 某个库位为什么补不到货

你想知道不是“有没有 route”,而是“当前产品在这里到底命中了哪条 rule”。

2. 为什么系统停在中间某个位置,不再往上游补

往往是:

  • rule action 不再属于 pull 系;
  • 或者命中了 make_to_stock;
  • 或者根本没有匹配到 rule。

3. 为什么改完 route 后反而报循环或异常

这时 seen_rules 防护就很容易帮你识别配置闭环。


为什么它不适合拿来当执行结果证明

Stock Rules Report 说到底还是规则命中解释

它并不等于:

  • procurement 一定会成功;
  • 采购单 / 调拨单一定会被创建;
  • lead time、供应商、库存可用量一定都满足。

因为真正执行时还要受这些影响:

  • 供应商配置;
  • 补货量;
  • 调度器是否跑到;
  • 多公司、多仓、库存可用量;
  • 各类业务规则是否完整。

所以你应该把这份报告当成:

规则链解释器

而不是:

执行结果保证书。


实施排错的推荐顺序

如果现场说“这件货明明有路线,但就是补不过来”,建议这么查:

  1. 先打开 Stock Rules Report,看目标仓下的规则链有没有命中;
  2. 如果链条断了,回看 _get_rules_from_location() 对应节点的 location 和 route;
  3. 如果链条成环,优先拆循环,而不是继续补别的规则;
  4. 只有规则链解释清楚后,再去看 procurement、供应商、在途和可用量问题。

也就是说:

  • 先查“有没有一条说得通的路”;
  • 再查“这条路能不能真正走通”。

一句话总结

Odoo 的 stock.rules.report 不是一张好看的流程图。

它真正的价值在于:

  • 围绕具体产品和仓库上下文,
  • 递归还原规则链,
  • 暴露链条断点、错误终点和循环依赖,
  • 帮你判断“为什么系统没有按你以为的方式补货”。

最准确的理解是:

它是 route 配置的诊断镜,不是 route 配置的宣传册。

DISCUSSION

评论区

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