项目深度

Odoo 项目阶段里的客户评分为什么不是“发一封满意度邮件”:rating_active、阶段触发与定期催评链路讲透

Odoo 项目里的客户评分,不是简单给任务发一封评价邮件。它把评分能力绑在任务阶段上,还会控制消息子类型、邮件模板启停和定期调度发送。本文把这套自动化机制拆开讲。

项目
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

很多人第一次看到 Odoo 项目里的客户评分,会以为它只是:

  • 任务完成后
  • 自动发一封满意度调查邮件

但从 /home/ubuntu/odoo-temp/addons/project/models/project_task_type.pyproject_task.py 来看,它真正的设计不是“任务发邮件”,而是:

  • 阶段是否开启评分
  • 评分在什么时候发送
  • 评分模板是否可用
  • 系统消息类型是否显隐
  • 周期性催评由谁统一调度

也就是说,Odoo 把“客户评分”建模成了 阶段级规则,而不是任务上的临时动作。

评分邮件只是结果,真正的控制中心在 task stage。


第一层:评分能力不是挂在任务上,而是挂在阶段上

project.task.type 里有一组很关键的字段:

  • rating_active
  • rating_status
  • rating_status_period
  • rating_template_id
  • rating_request_deadline

这套字段说明了一个核心事实:

Odoo 不是问“这张任务要不要发评分”,而是在问“进入这个阶段的任务,应该按什么规则发评分”。

这和很多人的直觉不一样。

因为直觉上你会把评分理解成任务动作;但 Odoo 更像是在做流程建模:

  • 某个阶段代表“适合收集反馈”
  • 所有进入这个阶段的任务,遵守相同规则

这比手工在每张任务上打勾稳得多,也更适合规模化交付团队。


第二层:为什么官方把评分开关和模板开关绑在一起

project.task.type.write() 里有一段很有代表性的逻辑。

rating_active 被打开或关闭时,Odoo 不只是改一个布尔值,而是连带处理:

  • project.mt_project_task_rating 的 hidden/default
  • project.mt_task_rating 的 hidden
  • project.rating_project_request_email_template 的 active

这说明官方对评分功能的理解是:

  • 它不只是一个字段
  • 它还牵涉到消息追踪入口
  • 还牵涉到默认评分邮件模板是否应该处于启用状态

换句话说,评分被视为一整套“流程能力包”。

这也是为什么你不能把它当“随手发一封满意度邮件”来看。


第三层:评分触发不是只有一种,阶段支持不同发送节奏

rating_statusrating_status_period 很关键。

从字段帮助和计算逻辑可看出,阶段评分至少支持这样的语义:

  • 一次性触发
  • 周期性触发

_compute_rating_request_deadline() 会根据周期生成下一个发送截止时间:

  • daily → 1 天
  • weekly → 7 天
  • bimonthly → 15 天
  • monthly → 30 天
  • quarterly → 90 天
  • yearly → 365 天

这意味着 Odoo 的目标不是“任务完结发一次问卷”,而是:

只要任务仍处在某个需要持续跟踪满意度的阶段,就可以按节奏重复发送评分请求。

这特别适合长期服务型项目,比如:

  • 运维支持
  • 持续顾问服务
  • 多轮交付阶段

第四层:定期催评不是每张任务自己跑,而是阶段级调度统一扫

project.task.type._send_rating_all() 很能说明官方设计。

它会:

  1. 查出所有 rating_active=Truerating_status='periodic'rating_request_deadline 到期的阶段
  2. 对这些阶段下的项目任务统一调用 stage.project_ids.task_ids._send_task_rating_mail()
  3. 然后把阶段自己的下一次 deadline 重算

这里非常值得注意的一点是:

  • 扫描单位是 stage,不是 task

这说明 Odoo 把“到点了该催评分”理解成一种流程规则巡检,而不是每条任务各自持有一个 cron。

这样设计有两个好处:

1. 调度模型更简单

不用给每张任务都维护单独的定时状态。

2. 规则更统一

一个阶段代表一套服务承诺;所有处于这个阶段的任务按同一规则被处理。


第五层:真正发评分时,Odoo 还会检查对象是否适合发送

project_task.py 里,任务发评分请求时并不是无脑发。

_send_task_rating_mail() 附近逻辑看,它会关注:

  • 阶段上是否有 rating_template_id
  • 是否能得到 partner
  • partner 不能等于当前内部用户
  • 模板发送时还会考虑语言
  • 模板不会对 is_template 任务乱发

这背后体现的是一个很现实的边界:

评分对象必须是“真实外部协作对象”,而不是系统里的任意关联联系人。

否则你就会得到很多荒谬情况:

  • 给内部员工发客户满意度邮件
  • 给模板任务发评分
  • 语言错乱
  • 没客户却强行发空邮件

官方显然在尽量避免这些事故。


第六层:为什么这套设计比“任务完成发问卷”更成熟

如果只做“done 就发问卷”,你会很快遇到这些问题:

  • 某些项目阶段并不代表真正完成
  • 有些项目要持续收集反馈,不是只收一次
  • 不同阶段的邮件口径可能不同
  • 某些阶段要禁用评分

而 Odoo 用阶段建模后,这些问题就自然有了解法:

  • 用阶段表达业务语义
  • 用模板表达沟通口径
  • 用状态和周期表达触发时机

这也是 ERP 产品常见的建模思路:

不是围着按钮设计,而是围着流程节点设计。


新手最容易误解的 4 件事

1. 以为评分就是任务上的一个邮件按钮

不对。评分核心逻辑在 project.task.type

2. 以为每个任务自己记住下次什么时候催评

不对。定期巡检的主入口是阶段级 _send_rating_all()

3. 以为开启评分只影响发不发邮件

不对。它还会影响消息子类型和模板启停。

4. 以为任何 partner 都能收到评分请求

不对。任务发送时还会检查 partner、模板、语言以及模板任务等边界。


实战上最该注意什么

1. 如果你要自定义评分时机,先想清楚是“任务规则”还是“阶段规则”

很多需求更适合扩展阶段,而不是往任务里硬塞字段。

2. 不要只改前端勾选项

评分相关的消息类型、模板激活状态也可能要一起校准。

3. 周期性催评场景,要特别注意不要重复轰炸客户

虽然官方支持 periodic,但业务上仍要控制阶段语义和周期长度。


一句话记忆法

Odoo 项目评分不是“任务发问卷”,而是“阶段定义规则、调度按阶段巡检、任务在合适对象上执行发送”的一整套自动化机制。

DISCUSSION

评论区

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