CRM 深度

Odoo CRM 线索为什么还在堆积:Pause Assignment、空 quota 与成员 domain 漏斗的排查顺序

很多团队看到 CRM 里未分配线索堆积,会先怀疑 cron 没跑。基于 Odoo 官方源码,这篇文章按真正执行顺序拆开:team 是否参与分配、线索是否进入候选池、成员 quota 是否已空、preferred domain 与 assignment domain 是否把候选漏掉,以及为什么命不中成员时系统根本不会转商机。

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

先说结论

Odoo CRM 里“线索一直没人接”,很多时候不是 cron 坏了,而是线索在某一层筛选里被自然挡住了。

源码里的真实顺序不是“看到 lead 就直接派给销售”,而是:

  1. 先看 team 能不能参加本轮分配
  2. 再看这条 lead 能不能进入 team 候选池
  3. 进入 team 后,再看有没有成员仍有 quota 且没 opt-out
  4. 然后再用 preferred domain / assignment domain 做成员匹配
  5. 只有真正命中成员后,系统才会 convert_opportunity() 并写入负责人。

所以排查时最怕的,不是“什么都不懂”,而是一上来只盯着 cron 日志。真正高频的问题,常常出在配置漏斗本身。


一、第一步先别看成员,先看 team 有没有资格参加

_cron_assign_leads() 并不是对所有团队一视同仁。

它先筛 team:

  • 这个 team 必须启用了 leads 或 opportunities;
  • team 自己不能 assignment_optout=True
  • 后续 _allocate_leads() 里如果 assignment_max=0,这个 team 也会直接被跳过。

这意味着:

只要 team 级别已经被排除,后面成员 quota、成员 domain 配得再漂亮,都不会生效。

很多实施现场的误判就在这里: 用户看到成员还在、销售也在线,就以为自动分配应该继续跑;但其实 team 级别已经暂停了,后面的成员逻辑根本没有入场机会。


二、第二步看 lead 有没有进候选池,而不是先问“为什么没人接”

_allocate_leads() 对候选线索有一层非常硬的过滤:

  • team_id=False
  • user_id=False
  • 不是 won
  • create_date 不能晚于 crm.assignment.delay 允许的时间
  • 如果 cron 走默认参数,还要求创建时间落在最近 creation_delta_days=7 天内
  • 还要满足 team 的 assignment_domain

这几条合起来,已经能解释大量“看起来像漏派”的案例。

典型误区 1:线索已经挂了 team 或负责人,还以为会再自动分配

不会。

team 分配阶段只吃“没有 team、没有 user”的线索; 成员分配阶段则只吃“已有 team,但还没有 user,也还没 date_open”的线索。

也就是说,一旦线索已经被某段流程手工认领、接口写入负责人,或者提前带上了 team,它走的就不是同一条入口了。

典型误区 2:新线索刚进来几秒,为什么没立刻分派

因为源码支持 crm.assignment.delay

它的设计目的,就是给其它自动化规则留缓冲时间,让系统先完成来源清洗、打分、补字段或去重准备,再把 lead 送进自动分配。

所以“刚创建 = 应该马上派单”本来就不是 Odoo 的默认世界观。


三、第三步再看成员:不是有人在 team 里,就代表他本轮能接单

到了 _assign_and_convert_leads(),源码先做的不是分配,而是筛成员:

  • assignment_optout=False
  • _get_assignment_quota(...) > 0

只要这两条不满足,成员就不会进入 members_to_assign

换句话说:

“成员还在团队里” ≠ “本轮还能接线索”。

1)Pause Assignment 是最直观也最容易漏看的开关

成员勾了 Pause Assignment,他仍然属于 team,但本轮会被完全跳过。

这很适合请假、培训、短期停接线索的场景; 也因此特别容易造成一种错觉:

  • 组织架构没变;
  • 销售还在 team 名单里;
  • 但系统就是不给他分线索。

答案往往不是 bug,而是他被 opt-out 了。

2)quota 归零后,成员也会像“隐身”一样消失

crm.team.member._get_assignment_quota() 并不是拿 assignment_max 当“今天最多多少条”。

它先把 assignment_max 折算成 30 天平均能力,再用最近 24 小时已分配数量去抵扣。

因此常见现象是:

  • 月容量看起来不小;
  • 但今天前面几轮 cron 已经分过;
  • 结果这轮 _get_assignment_quota() 返回 0 或负数;
  • 成员直接被排除,后面匹配不到人。

从业务感觉上看,这像“系统没继续派”; 从源码逻辑上看,这其实是系统在主动限流


四、第四步才轮到 domain:很多线索不是没人,而是没人“有资格”接

当可分配成员被筛出来后,源码不会立刻 round-robin。

它会先做两层漏斗:

  1. preferred domain 优先池
  2. 普通 assignment domain 池

并且 lead 会按 probability 从高到低排序去命中成员。

这里最关键的不是“轮转”,而是“有没有命中任何一个成员的 domain”。

preferred domain 太窄时,会出现什么

源码会先找同时满足:

  • 成员 assignment_domain
  • 成员 assignment_domain_preferred

的 lead,先做一轮优先分配。

这本意是把更匹配的线索优先喂给更适合的人; 但如果 preferred domain 设得过窄,就会出现:

  • 你以为系统会优先给某销售;
  • 实际上根本没有 lead 命中这组条件;
  • 然后它才退回普通 domain 分配。

assignment domain 太严时,会出现真正的“堆积”

第二轮里,源码为每个成员计算:

  • to_assign.filtered_domain(member.assignment_domain)

如果某条 lead 对所有成员都不命中,那么这条线索就会留在 to_assign 里,本轮谁也接不到

这类问题看起来最像“cron 没跑”,因为:

  • team 明明拿到了 lead;
  • 但最终没有 user 被写进去;
  • 线索也没有被 convert 成 opportunity。

实际上不是任务没执行,而是执行完后没找到合法接手人


五、为什么“没有负责人”时连商机都看不到

_assign_and_convert_leads() 里真正落库的关键动作是:

  • 找到命中的成员;
  • 调用 convert_opportunity(..., user_ids=member.user_id.ids)

所以如果没有成员命中:

  • 不会写负责人;
  • 不会转 opportunity;
  • date_open 也不会按这条链路推进。

这就是为什么有些团队会说:

“线索都进来了,但销售漏斗里没看到新增商机。”

很多时候原因并不是“转商机按钮坏了”,而是前面的成员筛选根本没成功。


六、正确的排查顺序,不要一上来查 cron

如果你在 CRM 里看到未分配线索堆积,建议按这个顺序看:

1. team 级别

  • team 是否 assignment_optout
  • team 是否启用了 leads / opportunities
  • team 的 assignment_max 是否大于 0
  • team 的 assignment_domain 是否把候选范围卡得太死

2. 线索入口

  • lead 是否仍然 team_id=Falseuser_id=False
  • lead 是否已赢单 / 非 live
  • create_date 是否被 crm.assignment.delay 挡住
  • lead 是否早于 cron 默认看的 7 天窗口

3. 成员级别

  • 成员是否 Pause Assignment
  • _get_assignment_quota() 是否已经耗尽
  • 成员 assignment_domain 是否过严
  • assignment_domain_preferred 是否窄到几乎永远命不中

4. 结果验证

  • 是否真的写入了 user_id
  • 是否因此触发了 convert_opportunity()
  • 是否仍有 team 内未认领 lead 卡在 date_open=False

这个顺序的好处是:

从“有没有资格入场”一路查到“有没有命中接手人”,不会在错误层级绕圈子。


七、实战建议:把“平均发牌”思维改成“漏斗诊断”思维

很多公司在理解线索分配时,还停留在“系统应该自动平均发给销售”的直觉里。

但 Odoo CRM 的源码显然不是这么设计的。

它更像一个多层漏斗:

  • 先过滤不该进来的线索;
  • 再限制今天不该继续接单的人;
  • 再按匹配规则把合适 lead 送到合适成员;
  • 找不到合法成员时,就宁可不分,也不瞎发。

这套设计未必让结果“看起来平均”,但它非常接近真实业务里的约束式分配。


最后一句话总结

Odoo CRM 里线索堆积,通常不是“没人跑任务”,而是线索在 team 资格、时间窗口、成员 quota 或 domain 匹配中的某一层漏斗里被挡住了。

DISCUSSION

评论区

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