CRM 深度

Odoo CRM 安排会议为什么总像‘懂你的下一步’:opportunity 上下文、smart calendar 与 reschedule 取时逻辑讲透

很多人觉得 Odoo CRM 的 Schedule Meeting 只是打开日历窗口。源码里它会把商机、客户、team、标题和最相关的时间范围一起塞进上下文,Reschedule 还会优先锚定当前用户的下一活动会议。

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

先说结论

Odoo CRM 的 Schedule Meeting,不是简单打开 calendar.event 的创建窗口。

源码真正做的是:

  1. 把当前商机上下文完整注入日历动作
  2. 根据已有会议分布,决定更适合周视图还是月视图
  3. 在 Reschedule 时,优先把你带回最相关的那场会
  4. 当会议真正创建后,再回写 CRM 跟进日志

所以它看起来像“系统懂你要安排什么”, 其实是 CRM 和 Calendar 在源码里提前对齐了业务语义。


一、为什么从商机点 Schedule Meeting,会自动带出客户和标题

action_schedule_meeting() 会往 action context 里塞很多默认值:

  • default_opportunity_id
  • default_partner_id
  • default_partner_ids
  • default_team_id
  • default_name

翻译成界面体验就是:

  • 会议默认绑到当前 opportunity
  • 联系人默认带上当前客户
  • 参会人列表会把当前用户和客户一起带上
  • team 也保留下来
  • 会议标题直接继承商机名

所以它不是“从 CRM 跳到 Calendar”, 而是“带着 CRM 语义去打开 Calendar”。


二、smart calendar 为什么有时打开周视图,有时打开月视图

如果当前记录是 opportunity, 并且 smart_calendar=True, Odoo 会调用 _get_opportunity_meeting_view_parameters()

这个方法会先把与该机会关联的会议读出来, 再做一层判断:

  • 没有会议:周视图,定位到现在
  • 只有一场相关会议:周视图,定位到这场会开始日期
  • 多场会议都落在同一周:周视图,方便连续排期
  • 跨周分布:月视图,更适合全局看安排

这背后的产品思路很清楚:

安排会议时,用户需要的不是固定视图,而是“最能看清这笔机会时间结构”的视图。


三、为什么源码要特别处理 allday 和时区

_get_opportunity_meeting_view_parameters() 里有一段很容易被忽略:

  • 普通会议时间会换算到用户时区
  • 但 allday event 不按用户时区回算,而是直接用原始日期范围

原因是全天事件如果再做一次时区换算, 很容易看起来“前一天开始”或“后一天结束”, 把本来很直观的排期弄歪。

所以 Odoo 在这里的原则是:

  • 精确时刻型会议 用用户时区理解
  • 全天占位型会议 用自然日理解

这很符合销售日程的真实使用场景。


四、为什么系统优先看“未结束会议”而不是全部历史会议

源码不会把所有历史会议一股脑拿来决定初始视图。 它先筛:

  • 还没结束的会议
  • 如果没有,再退回全部会议

这说明 Odoo 认为用户打开“安排会议”时, 主要是在处理 接下来的节奏, 而不是回顾已经结束的拜访。

所以页面默认锚点应该尽量贴近未来, 而不是被一堆过去的会议拖偏。


五、Reschedule 为什么总爱跳到“我自己的那场”

action_reschedule_meeting() 在关闭 smart calendar 之后, 会额外找:

  • 当前 opportunity 上
  • 属于当前用户的第一条 activity
  • 如果它挂着 calendar_event_id
  • 就把 initial_date 锚到那场会议开始时间

也就是说,Reschedule 的思路不是“重开整张日历给你自己找”, 而是:

优先把你带回你现在最可能要改的那一场。

这对销售来说非常合理。 因为 reschedule 通常不是重新规划整个账户, 而是改动一场具体会。


六、为什么从 activity 创建会议,也会继承同样的 CRM 上下文

mail.activity.action_create_calendar_event() 在 CRM 场景下会再补一层:

  • 如果这条 activity 对应的 calendar event 连着 opportunity
  • 就重用 opportunity.action_schedule_meeting(smart_calendar=False) 的 context
  • 再把 initial_date 锚到现有会议开始时间

这意味着:

  • 从商机表单点 Schedule Meeting
  • 从 activity 点 Create Event

两条路虽然入口不同, 但 Odoo 在尽量维持同一套会议上下文语义。

这就是为什么用户会感觉 CRM、活动和日历三者衔接得比较自然。


七、会议创建后为什么会自动写回 CRM

calendar.event.create() 在 CRM 扩展里还做了一件事:

  • 如果事件绑着 opportunity_id
  • 且不是从 activity 反推出来的现成事件
  • 就调用 event.opportunity_id.log_meeting(event)

这让会议不只是日历对象, 它也会变成 CRM 跟进历史的一部分。

换句话说,Odoo 不把 meeting 当孤立动作, 而是当作机会推进链路上的正式信号。


一句话记忆法

Odoo CRM 的会议安排不是“打开日历”,而是“带着商机上下文打开最相关的时间视角,并把会议再写回销售推进链路”。

DISCUSSION

评论区

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