协同办公

Odoo 活动为什么能一键变会议:`mail.activity` 到 `calendar.event` 的桥接、时区回写与反馈落点讲透

很多人以为‘把活动变成会议’只是打开一个日历表单。源码里这其实是一座正式桥梁:活动会带着业务记录上下文、负责人、说明进入 `calendar.event`,后续改截止日期还会回写会议开始日,而完成反馈也会追加到会议备注中。

协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 里的“从活动创建会议”不是前端 convenience,而是 mail.activitycalendar.event 的一条正式集成链。

活动不是丢给日历一个标题就结束;它会把业务记录语境、负责人、说明和原活动关联一起带进会议,并在后续改期时继续保持同步。

这也是为什么活动、会议、业务记录三者经常能在界面上彼此跳转而不散架。


一、创建会议时到底带了什么

addons/calendar/models/mail_activity.pyaction_create_calendar_event() 很值得看。

它往日历动作里塞了很多默认值:

  • 原活动类型
  • 原业务模型和记录 ID
  • 记录名称
  • 活动说明 note
  • 参与人默认取负责人 partner
  • 原活动 ID
  • 初始日期取活动截止日

这说明它不是“创建一条新日历记录”,而是带着原业务上下文去开会


二、为什么改活动截止日,会议时间也会跟着动

很多人觉得这很神奇,或者很烦。

源码里 write() 明确处理了这种同步:

  • 如果活动已经绑定 calendar_event_id
  • 又有人修改了 date_deadline
  • 系统会尝试回推会议开始时间

但这里有个关键边界:

  • 全天事件按日期差直接平移
  • 非全天事件要结合用户时区,判断“日”是否改变

所以这不是简单把 datetime 全量覆盖,而是尽量保留会议原本时刻语义,只调整所属日期。


三、为什么这里必须关心时区

如果你粗暴地把活动截止日从 Date 映射到会议 Datetime,最容易出的问题就是:

  • 用户改的是 3 月 20 日
  • 会议却被推成前一天深夜或后一天凌晨

Odoo 在这里做的事,本质上是在防这种错位。

它先把旧开始时间转到用户时区,再算日期差,再回写新开始时间。这样做的目的不是完美,而是让“改日期”尽量保持人的直觉。


四、完成活动后的反馈为什么会进会议备注

_action_done() 也不是只把活动关掉。

如果这条活动绑了会议,反馈文本会被追加进 calendar.event.notes

这点很像真实办公:

  • 活动是待办入口
  • 会议是协作容器
  • 反馈则应该沉淀到会议上下文里

这意味着如果你把活动当作一次性按钮,可能会忽视它其实在给日历协作对象补历史。


五、最容易误解的边界

1)活动说明和会议备注不是同一字段

创建时会带过去,但后续不是“永远双向镜像”。

2)活动截止日也不是会议开始时间的简单别名

它们是桥接关系,不是同字段。

3)删活动不一定只影响活动

如果走 unlink_w_meeting(),关联会议也会一起删。


六、适合它的场景与不适合它的场景

适合:

  • 售前跟进转会议
  • 项目任务转评审会
  • 人事流程转面谈/回访

不太适合:

  • 只想记一个私人待办,但不需要形成正式会议上下文
  • 频繁批量改日期且不希望影响已排好的会议时段

七、排错顺序

当用户说“我改了活动日期,会议怎么变了”时,按这个顺序查:

  1. 这条活动是否已绑定 calendar_event_id
  2. 会议是不是全天事件
  3. 当前用户时区是什么
  4. 这次修改的是活动截止日还是直接改了会议开始时间
  5. 是否在完成活动时写入了反馈,导致会议备注看起来“被改过”

最后一句

Odoo 把活动转会议的真正目的,不是少点几次按钮,而是让待办、日历和业务记录共享同一个协作上下文。

理解这一点,你就知道这条桥接为什么值得被认真设计。

DISCUSSION

评论区

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