先说结论
Odoo CRM 的 company_id,在多公司场景里不是一个随便填的归属字段。
源码把它当成一条一致性约束线:
- 不能和 team 的公司冲突
- 不能超出负责人允许的公司范围
- 有 partner 时会受 partner 公司约束
- team 没公司时,还会参考当前环境公司和用户可见公司
所以很多人看到线索“自己换公司”,其实不是系统抽风,
而是 crm.lead._compute_company_id() 在主动修正不一致状态。
一、为什么 Odoo 要把 company_id 做成计算字段
company_id 不是单纯用户输入后就永远不动。
在 CRM 里,一条线索会同时连接多种归属:
team_iduser_idpartner_id- 当前环境公司
env.company - 当前允许公司
env.companies
如果不做统一计算,最常见的脏状态就是:
- team 属于公司 A
- salesperson 只属于公司 B
- partner 属于公司 C
- lead 自己却挂在公司 D
这种记录一旦多起来,权限、报表、邮件入口、客户可见性都会乱。
所以 Odoo 干脆把它做成“自动求一个尽量一致的公司”。
二、源码的优先级不是简单固定值,而是先校验再提议
_compute_company_id() 先看已有 proposal 是否还能成立。
只要出现下面这些情况,原 company 就会被打回:
- 负责人有值,但该公司不在负责人可用公司里
- team 有公司,lead 公司却和 team 公司不一致
- team 没公司且无人负责,不适合硬保留旧公司
- team 和 user 都没有,而 partner 也不支持这个公司归属
也就是说,源码第一步不是“给你算个新值”, 而是先问:
你当前这个 company_id 还站得住吗?
站不住,就重算。
三、真正的提议顺序:team > user > partner
如果现有 company 失效,源码会按这个顺序提议:
- team 有公司,就用 team.company_id
- 否则看 user
- 若当前环境公司也在用户可用公司里,优先用
env.company- 否则退回用户默认公司与env.companies的交集 - 否则看 partner.company_id
- 都没有,就留空
这个顺序非常有业务意味:
- 先保证 pipeline 归属稳定
- 再保证负责人上下文可执行
- 最后才由客户公司兜底
所以 CRM 多公司不是简单“跟客户走”或“跟用户走”, 而是有明显偏向 team/pipeline 的设计。
四、为什么 team 没公司时,当前登录公司会突然变重要
测试里有个很典型的场景:
- 用户默认公司是公司 B
- 但当前登录环境切在公司 A
- team 又没有设置 company
这时源码会优先考虑 env.company 是否也在用户可见公司里。
如果在,就用当前环境公司。
这说明 Odoo 在多公司 CRM 里,很重视“你此刻正在以哪家公司的业务视角工作”。
这也解释了现场经常出现的一个现象:
- 同一个用户
- 在不同当前公司下创建 lead
- company_id 结果不一样
这不是 bug,而是设计。
五、partner 会把线索公司“拉回去”
如果 lead 已挂了 partner,partner.company_id 的约束会变强。
测试里甚至验证了这样一种情况:
- 线索先挂到 company A 的 partner
- 然后尝试写入一个只属于 company B 的负责人
- 直接触发错误
也就是说,在多公司 CRM 里,客户不是随便挂的参考信息, 而是会反向约束 lead 的公司边界。
这很合理。
因为如果客户主数据属于公司 A, 线索却被交给公司 B 的不可见团队继续推进, 后面权限和协作一定出问题。
六、为什么邮件 alias 和自动创建场景更要懂这条规则
多公司下,很多 lead 不是手工创建,而是:
- 通过邮件 alias 自动进来
- 通过自动分配/计划任务生成
- 在
sudo上下文里被系统创建
测试专门覆盖了这些场景,说明 Odoo 官方自己也知道:
- 自动入口最容易把 company 搞错
- 一旦搞错,肉眼一开始可能看不出来
- 但后续权限和统计会慢慢全部偏掉
所以 company_id 的一致性规则,不只是给手工表单用的,
也是给自动化入口兜底的。
七、实战里最容易误解的 5 件事
1. 以为 company_id 只是报表维度
错。它还是权限和业务可见性的硬边界。
2. 以为负责人一改,company 不会动
错。负责人可用公司范围会影响 lead company。
3. 以为 partner 只是联系人信息
错。partner 在多公司里也会约束归属边界。
4. 以为当前环境公司无关紧要
错。team 无公司时,env.company 可能就是关键决策项。
5. 以为自动创建场景和手工创建一样简单
错。自动入口更需要 company coherence 兜底。
八、一句话记忆法
Odoo CRM 多公司线索的 company_id,不是谁最后手工填了什么,而是谁在 team、user、partner 和当前公司这四股力量里更能形成一致状态。
理解这个规则,多公司 CRM 的很多“诡异现象”都会变得很正常。
DISCUSSION
评论区