CRM 深度

Odoo CRM 自动分配为什么不是‘平均发线索’:team 容量、成员 quota 和 preferred domain 讲透

很多团队以为 Odoo 的自动分配就是轮流把 lead 派给销售。源码其实复杂得多:先按 team 容量做分桶,再按成员 quota、domain 和 preferred domain 做二次分配,还会顺手 deduplicate。

CRM Odoo 开发
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 7 阅读

先说结论

Odoo CRM 的自动分配,不是“来了 10 条线索,3 个人一人分 3 条,最后 1 条随便给谁”。

源码真正做的是两层分配:

  1. 先把未分配 lead 分到不同 sales team
  2. 再把 team 里的 lead 分到具体成员

而且每一层都不是平均主义,而是会同时考虑:

  • team 的总容量 assignment_max
  • 成员过去 24 小时和 30 天的负载
  • 团队 domain
  • 成员 domain
  • preferred domain
  • 新线索创建后的延迟窗口
  • 重复线索去重

所以 Odoo 的分配逻辑,更像:

按容量、规则和优先匹配做带约束的投放

而不是“按人数均匀发牌”。


一、自动分配其实分成 team 层和 member 层

crm.team 里有两个关键动作:

  • _allocate_leads()
  • _assign_and_convert_leads()

前者负责:

  • 给 lead 找 team

后者负责:

  • 在 team 内找 salesperson
  • 并在分给 salesperson 时把 lead 转成 opportunity

这点很容易被忽视。

很多人以为自动分配只是在“给负责人”。

其实 Odoo 先问的是:

  • 这条 lead 该进哪条 team pipeline?

然后才问:

  • 在这个 pipeline 里,谁该接它?

这就是为什么 team 配置和成员配置都很重要。


二、team 层不是均分,而是按容量做加权分配

_allocate_leads() 的注释写得非常明白:

  • 只看还没分配的 lead
  • 只看未赢单、未归档的 live lead
  • 默认只看最近几天创建的 lead
  • 可额外设置 crm.assignment.delay
  • 然后按 team 的 assignment_max 做加权选择

也就是说,两个 team 同时匹配一批 lead 时, Odoo 不是简单一半一半, 而更像按“可承接能力”比例去分。

如果 Team A 的月容量是 90,Team B 是 30, 那 A 理论上就应该拿到更多线索。

这比平均分更接近真实业务。

因为现实里销售团队从来不是人人等大、组组等大。


三、为什么系统有时不碰“老 lead”

_allocate_leads() 里有一个很容易漏看的参数:creation_delta_days

默认 cron 分配时,系统只考虑最近一段时间创建的 lead,而不是把历史积压全翻出来一起洗牌。

再配合 crm.assignment.delay,意思就更清楚了:

  • 新 lead 刚进来后,可以先留一点缓冲时间
  • 让别的自动规则、人工校验、入口清洗先跑完
  • 然后再进入 assignment 流程

这其实很实用。

因为很多公司并不希望“刚进系统 3 秒钟的 lead”立刻被派单。

比如还要先做:

  • 来源清洗
  • 基础去重
  • 地区识别
  • SLA 预处理

所以 Odoo 的分配逻辑里,天然有一个“别太急”的设计。


四、team domain 先决定“这类 lead 归哪组”

每个 team 可以有 assignment_domain

它的意思不是“组里谁来接”, 而是:

这个 team 有资格接什么 lead。

比如你可以让某个 team 只接:

  • 高优先级 lead
  • 某个国家的线索
  • 某类来源的线索
  • 某些产品线机会

源码甚至在约束里直接校验这个 domain 格式对不对。

这说明 Odoo 并不把它当成临时玩法, 而是把它当成正式分配规则的一部分。

如果多个 team 的 domain 有重叠,系统会按容量加权去分。

如果某个 team 根本匹配不到 lead,它就不会被硬塞线索。


五、成员 quota 不是月配额直发,而是折算成日额度

很多人看到 assignment_max,直觉会以为:

  • 这个月最多给他 30 条

源码不是这么粗暴做的。

crm.team.member._get_assignment_quota() 里, 系统先算:

  • assignment_max / 30

再四舍五入成当天 quota。

然后如果不是 force_quota=True,还要再减去:

  • 过去 24 小时已经分给他的数量 lead_day_count

这就意味着:

成员配置的其实是平均月承载能力,系统真正执行的是按天限流。

这设计非常合理。

因为自动分配 cron 可能一天跑多次, 如果不做“日剩余额度”,系统会在同一天里不断给同一个人塞线索。


六、为什么有的人总能先拿到更合适的 lead

这和 assignment_domain_preferred 有关。

_assign_and_convert_leads() 在 team 内分配时,明显做了两轮:

第一轮:先分 preferred leads

系统先看成员有没有 assignment_domain_preferred

如果有,就优先把命中的 lead 先分给这些成员。

而且排序时还会优先考虑高概率 lead。

第二轮:再用普通 domain 补满

剩下没分掉的,再按普通 assignment_domain 去匹配,继续 round robin。

这意味着 preferred domain 的语义不是“只允许接某类线索”, 而更像:

当这类线索出现时,优先给我。

这是比单纯 domain 更细的一层控制。

比如:

  • 某个销售擅长制造行业,优先接制造线索
  • 某个销售专做高概率大单,优先吃高价值机会
  • 某个销售会法语,优先接法语区来单

七、自动分配顺手还会做去重

在 team 层 _allocate_leads() 里,还有一件非常重要的事:

  • 分配过程中会调用 deduplicate / merge

也就是说,Odoo 不想把重复 lead 派给不同 team 或不同销售。

这是一个非常“运营导向”的设计。

因为在真实 CRM 里,最可怕的不是少分一条, 而是同一个客户被两个人同时跟。

所以源码选择了一个更稳的顺序:

  • 先找候选 lead
  • 发现明显重复就先 merge
  • 再把结果分下去

这就是为什么 Odoo 的 lead assignment,实际上也是 pipeline hygiene 的一部分。


八、为什么手动分配和 cron 分配结果还会不同

action_assign_leads()_cron_assign_leads() 的差别之一在于:

  • 手动分配会强制 force_quota=True
  • 并且 creation_delta_days=0

翻成人话:

  • 手动点“Assign Leads”时,系统更像是在做一次“强制清仓式分配”
  • 自动 cron 更像“按日节奏温和分发”

这就解释了一个常见现象:

  • cron 没分那么多
  • 经理手动点一下却突然分出一批

不是系统不一致, 而是本来就是两种策略。


九、实战里最容易踩的 5 个坑

1. 以为自动分配就该平均

平均不等于合理。Odoo 追求的是容量匹配,不是数学平均。

2. team domain 和 member domain 混着用

team domain 决定先归哪组,member domain 决定组里谁接。两层含义不同。

3. 不理解 preferred domain

它不是普通过滤,而是“优先权”设计。

4. 忽略 creation delay

有些入口需要先清洗再派单,太快反而会放大脏数据。

5. 只盯 user_id,不盯 dedup

重复 lead 不先控住,分配做得再漂亮,pipeline 一样会脏。


十、一句话记忆法

Odoo CRM 自动分配不是平均发牌,而是先按 team 容量做分桶,再按成员 quota、domain 和优先规则做二次分配。

理解这一句,很多“为什么系统没平均分”“为什么这个销售总先接到某类 lead”的疑问就通了。

DISCUSSION

评论区

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