催款最容易被误解成“模板邮件 + 定时任务”。但 account_followup 真正承担的,是把 会计分录层面的逾期信息 翻译成 伙伴层面的催款动作。如果这一步做不好,销售会觉得系统乱发,财务会觉得系统不可信,客户则会收到重复甚至错误的提醒。
主要参考:
enterprise/account_followup/models/res_partner.pyenterprise/account_followup/models/followup_report.pyenterprise/account_followup/views/res_partner_views.xml
一、系统先算“谁该被催”,不是先算“发什么”
_get_all_followup_data() 的出发点是伙伴而不是单笔发票。它会把该伙伴名下未核销、已逾期或接近逾期的分录收拢,再决定当前 follow-up level。这个设计很重要:现实里客户不会按单据理解催款,而是按“你们说我欠了多少钱”理解。
对新手来说,第一个误区就是把 follow-up 当作 invoice 级功能。源码恰恰相反:它先聚合,再决定动作。也因此你在界面上看到的一封催款信,背后往往对应多条 move line。
二、伙伴级聚合之后,才会进入联系人与渠道选择
_execute_followup_partner() 不是简单地“有逾期就发”。它会先判断等级是否允许自动动作,再结合联系人、邮件、短信、活动等能力决定执行什么。对于企业环境,这一步的价值是把“谁来收这封提醒”从会计分录里抽离出来。
实战里最容易踩的坑有两个:
- 伙伴下面有多个联系人,但真正能收款项提醒的联系人并不完整;
- 业务方以为只要 partner 有 email 就能自动发,实际上还要看当前等级配置与渠道是否可用。
三、follow-up report 不是装饰,它决定附件内容是否可信
很多团队只关心邮件有没有发出去,却不关心附件里的账龄和明细是否自洽。followup_report.py 在这里承担的是“把逾期事实转成客户可读文档”的工作。换句话说,邮件只是壳,报告才是证据。
这也是为什么企业版催款比普通提醒更像一条闭环:
- 伙伴级收集待催项目;
- 判断当前 follow-up level;
- 生成对应文本、附件和动作;
- 记录消息或活动,留下后续追踪入口。
四、cron 只是复用同一条主链路,不是另一套逻辑
_cron_execute_followup_company() 的价值,在于它没有偷偷实现一套“定时版催款”。它复用伙伴级执行逻辑,只是在公司维度批量挑选待处理对象。这样做的好处非常现实:人工触发和定时触发不容易出现口径漂移。
如果你的团队遇到“手点正常、定时不正常”,优先排查的不是模板,而是:
- 公司范围下筛出的伙伴是否一致;
- 当前等级是否允许自动动作;
- 联系人/渠道是否在定时上下文里可用;
- 附件生成是否被基础数据卡住。
五、新手最常误解的三个边界
- 催款对象是伙伴,不是单张发票。 单据只是证据来源。
- 自动化不是无条件群发。 等级、联系人、渠道和公司上下文都会影响结果。
- 报告附件不是可有可无。 没有可信附件,催款就缺少可核对依据。
六、落地建议
- 先整理 partner/contact 主数据,再谈自动催款,否则系统只能放大脏数据。
- 让财务先验证不同 follow-up level 的动作组合,再开 cron。
- 对高价值客户,建议把自动提醒与人工活动并用,别把 follow-up 当成纯机器人流程。
七、结论
account_followup 的难点从来不是“把邮件定时发出去”,而是把逾期分录、伙伴关系、联系人选择和提醒证据拼成一条可信的催款链。理解了这一点,企业版催款才不容易从自动化工具退化成制造误会的工具。
DISCUSSION
评论区