采购权限

Odoo 采购权限为什么不是“能看单就能批单”:用户组、审批权、锁单与供应商信息可见边界讲透

很多团队会把 Odoo 采购权限简化成“采购员能下单,经理能审批”。源码其实更细:有 purchase user 才能看到部分采购统计与字段,有 purchase manager 才能越过双重审批阈值,而确认后是否自动锁单还会进一步限制取消和修改责任。

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

先说结论

Odoo 采购权限不是一句“采购员建单、经理批单”就能讲完。

从源码看,至少有三层边界叠在一起:

  1. 你是不是采购用户,决定你能不能看到部分采购信息
  2. 你是不是采购经理,决定你能不能越过审批阈值
  3. 订单确认后是否锁单,决定你后续还能不能随便取消或修改

所以真正的责任划分更像:

可见性、审批权、锁单控制,是三套不同但串联的安全边界。


这篇为什么不是已有“双重审批”文章重复

站里已有文章已经讲过:

  • button_confirm() 如何决定走 purchase 还是 to approve
  • _approval_allowed() 如何看金额、币种和经理组

那篇重点在审批分流逻辑

这篇换个角度,回答一个组织治理问题:

  • 谁能看到采购相关信息
  • 谁能代表组织承诺采购
  • 谁要对确认后的锁定状态负责

也就是说,这篇讲的是职责边界,不是单一审批算法。


第一层:不是所有人都能看到同样的采购信息

addons/purchase/models/res_partner.py 里,purchase_order_count 的计算开头就先判断:

  • 当前用户是否有 purchase.group_purchase_user

如果没有:

  • 直接返回,不给采购统计

同一个文件里,purchase_order_count 字段本身也带了:

  • groups='purchase.group_purchase_user'

这说明采购访问不是只有“能不能打开采购菜单”那么简单。

连合作伙伴上的采购计数、采购统计这些信息,也要先过采购用户组。

这就是典型的可见性边界


第二层:采购用户和采购经理不是一个安全等级

purchase.order._approval_allowed() 里,能直接通过审批的情况有三种:

  1. 公司配置为 one_step
  2. 双重审批但金额低于阈值
  3. 当前用户属于 purchase.group_purchase_manager

第三条特别关键。

它说明经理组的意义不是“多看一个菜单”,而是:

  • 在组织上拥有越过阈值直接批准采购承诺的权力

所以 purchase.group_purchase_manager 不是普通功能组,而是授权组

这个边界如果配错,就会出现两类问题:

  • 普通采购员本不该批的大额单被直接放行
  • 真正负责的人却发现自己还要卡在 to approve

第三层:button_confirm()button_approve() 其实分配了两种责任

purchase_order.py 里:

  • button_confirm() 负责把单据推入审批分流
  • button_approve() 负责真正把单据写成 purchase

并且 button_approve() 还会:

  • 写入 date_approve
  • 在公司启用锁单时把 locked = True

这意味着:

  • Confirm 更像“我认为这张单业务上成立,可以送审/送批”
  • Approve 才像“组织正式承诺这笔采购”

如果你把两者混成一个动作,就很容易低估经理审批的责任。


第四层:锁单不是界面美化,而是确认后责任收口

源码里 button_approve() 会在 lock_confirmed_po == 'lock' 时自动锁单。

button_cancel() 又明确规定:

  • 如果采购单已锁,不能直接取消
  • 必须先解锁

同时,如果已有非草稿/非取消的供应商账单,也不能取消采购单。

这就说明锁单并不是“让页面看起来严肃一点”,而是:

  • 限制确认后随意改单
  • 把后续变更动作抬升成显式责任
  • 防止采购承诺与账单事实脱节

所以锁单其实是权限治理的后半段。

前半段是“谁能批”,后半段是“批完后谁敢改”。


第五层:供应商信息回写还会绕开普通用户权限边界

_add_supplier_to_product() 里,源码最后用了:

  • product_tmpl_id.sudo().write(vals)

注释写得很明白:

  • supplier info should be added regardless of the user access rights

这非常值得注意。

因为它说明 Odoo 在采购确认时,认为“把供应商补进产品供应商列表”是业务上应保证完成的动作,哪怕当前操作者不具备完整产品写权限。

这就形成了另一个边界:

  • 用户权限限制的是日常直接编辑能力
  • 但某些采购确认副作用会被系统以 sudo 方式落地

如果你不知道这点,就会在排错时误会:

  • 为什么这个采购员明明没产品维护权,系统还是更新了 vendor 资料?

答案是:这是源码有意为之。


组织里最容易配错的 5 个点

1)把 purchase user 和 purchase manager 混发

这样会让审批边界虚化,大额单谁都能过。

2)只盯菜单权限,不看字段/统计可见性

采购统计、合作伙伴采购信息本身就受组限制。

3)把 Confirm 当成最终审批

在双重审批场景下,Confirm 只是把责任推到下一层。

4)启用锁单却没定义解锁责任人

最后就会出现“谁都不敢改、又谁都偷偷来问管理员”的混乱状态。

5)忽视 sudo 写 supplierinfo 的副作用

这会影响你对“谁改了供应商资料”的审计判断。


落地建议

如果你要把采购职责分得清楚,至少应该把规则写明:

  1. 采购用户:能建单、跟单、看采购统计到什么程度
  2. 采购经理:哪些金额/哪些公司可直接批
  3. 锁单后变更:谁能解锁,何时允许取消
  4. 主数据副作用:确认采购会不会自动补 vendor 信息,是否要记录审计

这样配置下来,Odoo 的采购安全边界才会和组织责任真正对齐。


一句话记忆

Odoo 采购权限不是单一审批开关,而是“采购可见性 + 经理审批权 + 确认后锁单控制”三层边界一起定义的责任系统。

DISCUSSION

评论区

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