先说结论
在 Odoo CRM 里,lead 不是永远独立于客户主数据的“临时草稿”。
一旦 partner_id 建立起来,源码会开始维护一套同步边界:
- 地址是“全有或全无”同步
- 邮箱和电话是“有差异才提示/回写”
- 语言、职位、网站等字段更偏向从 partner 借值
- 但如果用户已经在 lead 上输入了值,也不会无脑覆盖
所以 CRM 表单里的联系方式编辑,不只是界面操作, 而是在决定:
这条线索是暂时独立,还是正在向客户主数据靠拢。
一、为什么挂上 partner 后,很多字段会自动变
crm.lead 里一大批字段是 compute + readonly=False + store=True:
contact_namepartner_nameemail_fromphonefunctionwebsitelang_id- 地址字段一整组
这意味着它们既能让用户在表单里改,
又会在 partner_id 变化时触发重算逻辑。
也就是说,lead 不是单纯“拷贝 partner 一次就脱钩”, 而是保留了相当强的联动关系。
二、地址为什么最容易让人误判
源码里 _prepare_address_values_from_partner() 很值得注意。
它的策略是:
- 如果 partner 任一地址字段有值,就整组地址字段从 partner 同步
- 如果 partner 整组地址都空,就保留 lead 原来的地址值
这就是典型的 all or nothing 语义。
为什么这么设计?
因为地址最怕“半套来自客户、半套来自 lead 手填”。
比如:
- 街道来自旧客户档案
- 城市来自业务员手工改写
- 国家来自另一个联系人
最后看上去像完整地址,实际上是拼接垃圾。
所以 Odoo 宁可粗一点,也要避免“混血地址”。
三、邮箱和电话不是简单覆盖,而是有差异判断
邮箱走 _get_partner_email_update(),电话走 _get_partner_phone_update()。
这两个方法的设计都很克制:
- 必须先有
partner_id - lead 当前值和 partner 当前值要真的不同
- 还会做规范化比较,而不是只比原始字符串
- 如果 lead 是空值,
force_void=False时不会轻易把 partner 也清空
这意味着 Odoo 不希望出现两种极端:
- 一改 lead 就无脑覆盖 partner
- partner 明明已挂接,却完全不再同步
它要的是第三种效果:
当 lead 已经代表这个客户时,差异要被感知;但空值和格式差异不能随便把主数据改脏。
四、为什么“+86”和“0086”不该被当成两个电话
电话比较时,源码会先尝试格式化:
self._phone_format(...)partner._phone_format(...)
也就是说,Odoo 比较电话不是只看字面文本, 而是尽量比“格式化后的同义号码”。
邮箱也类似,会做 normalize。
这背后的目的很明确:
- 避免因为大小写不同,误判成两个邮箱
- 避免因为国际区号写法不同,误判成两个电话
如果不先标准化,CRM 同步会变得非常吵: 表单总在提示“将更新 partner”,但其实业务含义根本没变。
五、为什么有时挂了 partner,lead 上原来的信息没被清掉
源码在 _prepare_values_from_partner() 里用了一个很实用的原则:
- 对非地址类字段,优先拿 partner 的值
- 但 partner 没值时,保留 lead 现有值
例如:
- partner 没 website,不要把 lead 的 website 清掉
- partner 没 function,不要把 lead 的 function 清掉
这说明 Odoo 并不认为 partner 永远更权威, 而是认为:
客户主数据优先,但不能因为主数据暂时缺项,就反向抹掉线索上已经采集到的信息。
这在销售早期阶段很重要。 因为 lead 往往先采到碎片信息,客户档案反而还没补齐。
六、commercial_partner_id 和 partner_name 的作用常被低估
当 lead 还没明确联系人时,源码仍会尝试根据:
partner_name- 现有公司 partner
来推导 commercial_partner_id。
这说明 Odoo 在设计上很在意一件事:
- 联系人未必马上明确
- 但公司归属最好尽早明确
因为一旦公司归属清楚:
- 重复检测更稳
- 后续转商机更顺
- 联系人创建时 parent company 更容易落对
所以很多人以为 partner_name 只是展示字段,
其实它也是客户归属链路的一部分。
七、质量字段不是摆设:email_state 和 phone_state
源码会计算:
email_statephone_state
而且不是简单看“有值/没值”, 而是尝试验证格式合法性。
这两个字段真正的价值,不是好看, 而是帮团队在 lead 早期就发现:
- 邮箱格式有问题
- 电话无法标准化
- 这条 lead 即使推进,也可能在后续联系阶段掉链子
很多团队只盯金额和阶段, 忽视联系方式质量,最后 pipeline 看上去很满,实则可联系率很低。
八、实战里最容易踩的 5 个坑
1. 以为 lead 联系方式永远不会影响客户
错。只要挂了 partner,很多字段就不再完全独立。
2. 以为地址字段能局部拼接
错。源码刻意避免这种混合地址。
3. 以为空字符串也只是普通修改
错。邮箱/电话同步逻辑会特别防范“把有效客户资料清空”。
4. 以为格式不同就是值不同
错。邮箱和电话都会尽量先规范化再比较。
5. 以为 partner 一定比 lead 信息更完整
错。源码保留了“partner 缺值时沿用 lead 值”的空间。
九、一句话记忆法
Odoo CRM 里,lead 挂上 partner 之后,不是彻底并表,也不是彻底脱钩,而是进入一套‘有条件同步、尽量防脏数据’的边界机制。
理解这个边界,才知道哪些字段该在 lead 上改,哪些该回到客户档案改。
DISCUSSION
评论区