Approvals 里最隐蔽的错,常常不是“点不了提交”,而是系统把错误的人当成申请人或经理,导致 approver 列表看起来正常,实际责任链已经偏了。
主要参考:
enterprise/approvals/models/approval_request.pyenterprise/approvals/tests/test_approvals.py中test_employee_in_user_company
一、request owner 不是任意用户选择器
_get_request_owner_id_domain() 限制了申请人必须是内部用户,而且 company_ids 要落在当前环境公司集合里。也就是说,请求归属不是“系统里有人就能选”,而是必须满足内部身份与公司可见范围。
这对共享账号、外部协作者、跨公司代理提单很关键:表单能看到,不代表模型允许你把单挂到那个人身上。
二、经理审批依赖 hr.employee,而不是 res.users 的层级字段
action_confirm() 与 _compute_approver_ids() 都会去找 hr.employee:先用 request_owner_id 找员工,再用员工的 parent_id.user_id 找经理用户。换句话说,审批链的“经理”语义来自员工档案,不来自用户表本身。
如果 HR 档案不全,系统报的也不是“审批规则不对”,而是:没有经理、经理没有用户、或者经理没在 approver 列表里。
三、跨公司最容易踩的是“找到了错误公司的员工档案”
测试 test_employee_in_user_company 很有代表性:同一个用户可能存在多条员工记录,但正确经理只能从当前公司那条员工记录上解析。Odoo 明确把 company_id 放进 employee 搜索条件里,就是为了避免把别家公司的上级链错带进来。
这说明一个实施原则:多公司里 HR 主数据如果没按公司切干净,Approvals 会最先把问题暴露出来。
四、为什么有人改了申请人后审批人跟着变
_compute_approver_ids() 依赖 category_id 和 request_owner_id。申请人一改,系统就可能重新生成 approver 行:默认审批人保留,经理注入重算,甚至序列顺序也会变化。
所以申请人字段不是“抬头信息”,而是审批链的输入参数。
五、实战建议
- 先补齐员工档案、经理关系、公司归属,再谈经理必审。
- 多公司场景下,检查同一用户是否挂了多条 employee。
- 如果允许审批专员代提,不要把“代提人”和“业务归属人”混成同一个 request owner。
- 改申请人后要重新核对 approver 列表,不要以为旧链路会自动正确延续。
六、结论
Approvals 里的申请人与经理,并不是表单上的两个名字,而是整个责任链计算的起点。只要 HR 档案、公司域或 owner 语义有一点模糊,后面的审批链就会跟着歪。
DISCUSSION
评论区