企业版催款

Odoo 企业版 Account Follow-up 为什么不是“逾期就催”而已:next action date、no followup 与负责人选派边界讲透

很多人把 Odoo 企业版催款理解成“发封提醒邮件”。真正看 account_followup 源码会发现,官方做的是一套客户级催收状态机:先按逾期与 level 算出 followup_line,再结合 next_action_date、no_followup、责任人分配和 activity 创建,决定今天到底该不该催、催到哪一级、由谁跟。

企业 会计
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

很多人对 Odoo 企业版 Account Follow-up 的第一印象是:

  • 发票逾期;
  • 系统发提醒;
  • 财务跟催。

但如果只是这样,它根本不需要单独一套 follow-up 引擎。

account_followup 的 partner、followup line 和测试代码串起来看,会发现官方真正做的是一件更细的事:

它不是在“逾期时发消息”,而是在“客户维度上维护一套催收阶段与下一动作时间表”。

这套机制里,至少有四个核心边界:

  1. 当前客户属于哪个催收 level
  2. 今天到底该不该执行下一次提醒
  3. 哪些未核销行虽然逾期,但被排除出 follow-up
  4. 创建活动时,到底该指派给谁。

一、真正的核心不是单张发票,而是 partner 级 follow-up 状态

源码里计算的重点不是某张 invoice,而是 res.partner 上这些字段:

  • followup_status
  • followup_line_id
  • followup_next_action_date
  • followup_responsible_id
  • total_due / total_overdue / total_overdue_followup

这很说明问题。

Odoo 没把催收设计成“发票逐张发提醒”,而是:

  • 先把客户所有相关未核销分录收敛起来;
  • 再计算这个客户当前站在哪个催收阶段;
  • 然后决定是否该执行下一次动作。

所以它更像一个 客户催收控制面板,不是发票通知器。


二、为什么 with_overdue_invoicesin_need_of_action 不是一回事

followup_status 里最关键的区分是:

  • with_overdue_invoices
  • in_need_of_action
  • no_action_needed

很多人容易把前两个混成一个意思:反正都有逾期。

其实源码语义完全不同。

with_overdue_invoices

表示:

  • 客户确实还有逾期;
  • 但现在还不到下一次催收执行点;
  • 或刚刚执行完一轮,正在等下一步窗口。

in_need_of_action

表示:

  • 当前催收等级已经触发;
  • followup_next_action_date 已到;
  • 系统认为今天应该有人真正处理。

所以一个客户可以有逾期,但今天未必需要动作。

这正是企业催收里“有问题”和“该现在处理”之间的区别。


三、为什么 followup_next_action_date 很关键

这字段是整套引擎最容易被低估的地方。

每执行一次 follow-up,系统不会只是记一条日志,它还会根据当前 level 推算下一个动作日期。

account_followup.followup.line._get_next_date() 的逻辑大意是:

  • 如果后面还有更高一级 level,就用 下一级 delay - 当前 delay 算下次日期;
  • 如果没有下一级,就参考前一级或当前 delay 继续往后推。

测试里能看到这种效果:

  • 第一次 follow-up 后,不是立刻又触发第二次;
  • 而是把 followup_next_action_date 推到未来某天;
  • 到期前状态可能只是 with_overdue_invoices
  • 到期后才变成 in_need_of_action

这说明系统不是“每天扫到逾期就催”,而是:

每次催收动作都会自己生成下一次节奏。

这就是典型的 dunning cadence,不是一次性消息发送。


四、为什么 no_followup 会影响状态而不只是隐藏行

account.move.line.no_followup 是另一个很关键的边界。

源码在汇总 overdue 金额时,会专门区分:

  • 普通 overdue;
  • overdue 但 no_followup=True
  • 真正进入 follow-up 范围的 overdue。

所以 partner 上会有:

  • total_overdue
  • total_overdue_followup

这两个值不是同一个东西。

这意味着什么?

意味着你可以有:

  • 客户账面上确实存在逾期;
  • 但这些逾期行被标记为不参与催收;
  • 最终客户状态可能直接变成 no_action_needed

测试也覆盖了:

  • 当所有未核销行都被设成 no_followup=True 时;
  • 即使客观上逾期还存在;
  • follow-up 状态也会被压成无需动作。

所以 no_followup 不是 UI 勾选项,而是“从催收引擎里剔除这笔账”的业务开关。


五、为什么负责人选择不是简单取 partner.salesperson

_get_followup_responsible() 是很值得读的一段。

很多系统做催收责任人,会直接用:

  • 客户销售;
  • 或财务负责人。

Odoo 的逻辑更细,候选人是分层回退的:

  1. 如果 level 配置要求 account_manager,优先取 partner 的 user_id
  2. 如果要求 salesperson,会优先看逾期发票上的 invoice_user_id
  3. 若 partner 自己设置了 followup_responsible_id,也可直接接管;
  4. 候选人失活时还要继续 fallback;
  5. 最后才回退到默认负责用户。

测试还特别覆盖了:

  • 多张发票不同 salesperson 时,优先取残值更高那张对应的人;
  • 如果该人已归档,不应该再被选中。

这说明 Odoo 的目标不是“找一个理论负责人”,而是:

尽量找到“对当前逾期款项最有上下文、且仍然活跃可处理”的那个人。


六、为什么活动创建可以一次分配给多个销售

当 follow-up line 配了 create_activity=True 且负责人类型是 salesperson 时,源码允许为多张逾期发票对应的多个销售同时建 activity。

这很有意思。

因为它说明官方默认不是一定要把所有催款责任压到一个人头上。

如果同一客户欠款分散在不同销售名下,那么系统会接受:

  • 多个人各自收到要跟进的任务;
  • 而不是强行只保留一个主负责人。

这更符合大客户、多单据、多销售协同场景。


七、为什么 follow-up line 不是“模板列表”,而是时间阶梯

account_followup.followup.line 里的核心不是模板本身,而是:

  • delay
  • send_email
  • send_sms
  • create_activity
  • activity_default_responsible_type
  • auto_execute

这说明 line 的本质不是“第 N 封催款文案”,而是:

某个逾期阶段该采取什么动作。

你可以把它理解成催收时间阶梯:

  • 逾期前 10 天提醒;
  • 逾期后 10 天建活动;
  • 逾期后 30 天升级动作。

line 里的 message template 只是动作载体,不是主角。


八、为什么 status 计算要基于所有未核销分录聚合

partner 的总欠款和逾期金额不是按 invoice 单独循环算的,而是直接对未核销 move line 聚合:

  • 按 account_type;
  • 按 overdue 与否;
  • no_followup
  • 按 partner。

这带来两个结果:

  1. 性能更稳定:适合大批量客户催收面板;
  2. 视角更统一:同一客户下多张单据会自然合并成一个催收事实。

这再次说明它不是“逐单提醒器”,而是客户级引擎。


九、为什么执行 follow-up 后状态不会立刻清成正常

很多人会误解为:

  • 我已经发过提醒;
  • 那这次催收就结束了;
  • 应该恢复正常。

并不是。

执行 follow-up 后,若发票仍未回款:

  • partner 仍然可能处于 with_overdue_invoices
  • 只是暂时不需要动作;
  • 要等 next_action_date 到了,再升级为 in_need_of_action

执行动作并不代表问题解决,只代表已进入下一个等待窗口。

这点对理解催收节奏非常关键。


十、实战里最容易误解的 4 个点

误区 1:逾期就一定要催

不对。

还要看 followup_next_action_date 是否已到。

误区 2:no_followup 只是界面排除

不是。

它会直接影响 follow-up 状态和可催金额。

误区 3:负责人永远是客户销售

也不对。

系统会结合发票销售、partner 负责人和 fallback 规则动态选人。

误区 4:催收执行一次后客户就“正常”

不对。

更多是从“该动作”切到“等待下一次动作”。


总结

account_followup 串起来看,你会发现 Odoo 企业版并不是做了一个“逾期发提醒”的小工具。

它真正做的是一套 partner 级催收状态机:

  • followup_line 表达逾期阶段;
  • followup_next_action_date 控制催收节奏;
  • no_followup 把特定分录排除出催收引擎;
  • responsible fallback 选出真正该跟的人;
  • activity / email / SMS 落地动作;
  • with_overdue_invoices / in_need_of_action 区分“有问题”和“该现在处理”。

所以 Odoo 企业版 Account Follow-up 的本质,不是“催款通知”,而是“围绕客户欠款状态维护一条时间化的催收工作流”。

这才是源码真正值得学的地方。


参考源码 - enterprise/account_followup/models/account_followup.py - enterprise/account_followup/models/res_partner.py - enterprise/account_followup/tests/test_account_followup.py

DISCUSSION

评论区

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