电话弹屏的关键不是“找到一个客户”,而是根据 partner、机会数量、订阅数量和权限给出不同入口动作。
主要参考:
- `enterprise/voip_crm/models/res_partner.py`
enterprise/voip_crm/models/voip_call.pyenterprise/voip_sale_subscription/models/voip_call.py-
enterprise/voip_sale_subscription/tests/test_voip_call.py
一、这不是单模块按钮,而是一条跨模块链路
很多人把这个功能理解成某个界面上的一个按钮、一个 smart button,或者一次自动创建。但从源码看,真正重要的是:上游对象先保留业务上下文,中间层做状态/域/权限判断,下游对象再接住这个上下文继续工作。只看最后一个界面动作,很容易把问题看窄。
二、核心跨链路是怎么跑通的
- 电话记录先依赖 partner 解析;没有 partner 时,商机动作会直接带着
default_phone打开新建表单。 - 如果 partner 只有一个机会,侧栏可直接跳 form;多个机会则进入 list;没有机会则回到新建 opportunity。
- 企业订阅扩展又给 call 加了一条
voip_action_open_subscription(),让同一个电话上下文可以继续切进 partner 的 subscription 视图。
这就是为什么我把它归类为“跨模块链路”题:这里至少同时牵涉了业务对象、会计/项目/销售对象,以及状态或权限判断,而不是单个模型内部的小机制。
三、最容易踩错的边界
- opportunity_count 与 subscription_count 都通过 related 字段暴露,并受销售组权限控制,不会对无权用户裸奔。
- Store 字段只在能读 CRM 时才返回商机数量,避免电话面板越权泄露销售信息。
- 入口动作不是硬编码 URL,而是根据记录数量返回 form/list/create,不同客服会看到不同下一步。
这些边界决定了数据是否还能回到正确的模块继续流动。如果边界被自定义绕开,后面最常见的结果就是:报表看起来还能出, drill-down 却已经解释不通。
四、落地时最值得先验的三件事
- 如果电话团队同时处理销售与续费,别只给一个“打开客户”按钮,应该保留商机/订阅双入口。
- 号码归属错误时,先看 partner 解析,再看 action context。
- 权限测试一定要覆盖销售、客服和普通员工三类角色。
五、结论
同一个来电上下文里,商机、订阅和新建动作是并行路由,不是一个固定按钮。 这也是企业版功能最容易被低估的地方:看上去只是一个入口,实质上是在多个子系统之间持续传递状态、上下文、数据或权限。
- 电话记录先依赖 partner 解析;没有 partner 时,商机动作会直接带着
DISCUSSION
评论区