其他深度

Odoo 活动展位为什么要先管库存再谈招商:套餐模板、可售状态与赞助商转化链路讲透

很多团队做活动展位时,先想着卖给谁、展示谁,却忽略了更底层的资源建模。Odoo 的 event_booth 先把展位当活动库存,再通过分类、活动模板同步、前台可售统计和确认后 sponsor 生成,把招商和官网展示连成一条线。

其他
进阶 开发者 2 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的活动展位,最核心的设计不是“记录哪个客户租了哪个摊位”,而是先把展位当成可复制、可统计、可售卖的活动库存

/home/ubuntu/odoo-temp/addons/event_booth/models/event_event.pyevent_booth.pyevent_booth_category.py,以及 website_event_booth_exhibitor/models/event_booth.py 来看,这条链大概是:

  1. 用活动模板预制 booth 套餐
  2. 在具体活动里同步成真实展位库存
  3. 用 available / unavailable 管理是否还能卖
  4. 在前台只暴露仍有库存的 booth category
  5. 展位确认后,再转成 sponsor / exhibitor 展示对象

这意味着 Odoo 的 booth 设计重点,不是先做客户台账,而是先做活动资源管理


第一层:为什么展位分类不是装饰字段,而是套餐层

event.booth.category 看起来很简单,字段并不多:

  • name
  • sequence
  • description
  • 图片能力
  • booth_ids

但它的业务意义一点也不简单。

因为在活动招商里,真正先被售卖的通常不是某个具体坐标,而是某种套餐层级:

  • 标准展位
  • 高级展位
  • VIP 展位

所以分类对象本质上承担了三个职责:

1. 商品化命名

让销售和市场有统一对外话术。

2. 前台展示入口

不同层级可以有不同描述、图片和曝光方式。

3. sponsor/exhibitor 规则来源

在扩展模块里,是否生成 sponsor、对应哪种 sponsor type,都是从 booth category 往下传。

也就是说,booth category 不是“给后台好看一点”,而是招商套餐层。


第二层:为什么活动类型切换时,只替换可售 booth,不碰已售 booth

event.event._compute_event_booth_ids() 这段逻辑非常值得细读。

当活动类型变化时,系统会:

  • 删除当前仍 available 的 booth
  • 保留已经不再 available 的 booth
  • 再把新活动模板里的 booth 行同步进来

这个动作非常成熟。

因为活动模板更新时,最怕的就是两种错误:

错误一:全量覆盖

如果把已经卖掉的 booth 也一起重置,已经确认的招商结果会被误伤。

错误二:完全不更新

那新模板配置又无法真正落到具体活动上。

Odoo 的处理是只替换“还没卖出去的库存”,保留“已经被业务占用的资源”。

这其实就是电商和票务系统常见的一个原则:

模板可以更新,但不能抹掉已经成交的资源。

对活动团队来说,这一点特别重要。 因为很多大型展会都会在招商过程中不断微调套餐结构,如果系统不能安全同步模板,后台迟早乱套。


第三层:为什么 booth 统计要分 total 和 available

event.event 上有:

  • event_booth_count
  • event_booth_count_available
  • event_booth_category_available_ids

看起来像普通统计字段,实际上非常关键。

因为招商执行最需要的从来不是“有多少展位”,而是:

  • 还有多少能卖
  • 还剩哪些档位能卖

如果只看总量,运营会被一种假象误导:

  • 总数很多,似乎资源还充足

但实际可能是:

  • 标准位全没了
  • 只剩高价套餐
  • 前台继续展示所有品类,导致客户频繁点到售罄项

event_booth_category_available_ids 明确表达了一个非常适合前台的概念:

官网展示应该围绕“还有库存的套餐层”来做,而不是围绕后台全部定义来做。

这能直接减少前台无效咨询。


第四层:为什么展位确认的核心动作是状态变化,而不是写客户字段

event.booth 的状态非常克制:

  • available
  • unavailable

很多人会觉得这太简单。 但恰恰因为简单,它才适合作为库存系统的主状态。

对于 booth 来说,最关键的业务问题往往就一个:

  • 这个资源还卖不卖得出去?

一旦 booth 被客户占用,它就不该再被当作可售库存。

这时候最重要的不是把各种复杂招商阶段都塞进 booth,而是保持 booth 继续承担“库存位”的职责。

销售漏斗、合同审批、回款进度,可以在 CRM 或销售单里细分。 但 booth 自己应该尽量稳定地代表:

  • 是哪一个活动资源
  • 是否可售
  • 当前由谁占用

这也是一种很典型的 Odoo 风格:

让每个对象只承担最核心的一层语义,不把所有流程都硬堆进一个状态字段。


第五层:为什么确认后要发活动消息,而不是只改状态

_post_confirmation_message() 会在 booth 被确认后往活动消息流里发通知。

这说明 Odoo 把展位确认当成活动级事件,而不是 booth 私有改动。

这件事的价值非常现实:

1. 招商动作进入活动协作上下文

项目经理、运营、销售看到的是同一条事件流,不必各自维护平行台账。

2. 展位确认留痕更清楚

后续追查某个 booth 何时被确认,不会只剩下一次冷冰冰的字段 write。

3. 官网、物料、现场准备可以围绕同一事件启动

一旦 booth 确认,后面的 sponsor 资料收集、官网展示、现场搭建就都可以接上。

活动系统里很多混乱,都来自“后台改了状态,但没人知道那意味着什么”。 Odoo 这里显然不想让 booth 确认成为一个静默动作。


website_event_booth_exhibitor 扩展里,booth 会多出:

  • use_sponsor
  • sponsor_type_id
  • sponsor_id
  • 一系列 sponsor 的 related 展示字段

更关键的是 _get_or_create_sponsor()_action_post_confirm()

  • 如果 booth category 启用了 sponsor 逻辑
  • 且当前 booth 已有 partner
  • 确认时就按 partner + sponsor_type + exhibitor_type + event 去找 sponsor
  • 找不到才新建

这个设计特别像真正的招商流程。

因为活动官网上的 sponsor,应该是确认后的展示实体,而不是招商早期所有潜在客户的混合池。

如果 sponsor 从一开始就由人工到处乱建,很快会发生三种问题:

1. 潜在客户和已确认展商混在一起

官网展示和实际成交状态不一致。

2. 同一家企业在不同活动、不同级别下互相串台

品牌资料、赞助等级、活动归属都会混乱。

3. booth 和 sponsor 双方维护,最终不同步

后台库存一套,官网展示一套。

所以 sponsor 最合理的诞生时机,本来就该是在 booth 确认之后。


扩展模型里大量 sponsor 信息都不是直接存到 booth,而是 related 到 sponsor_id

  • sponsor_name
  • sponsor_email
  • sponsor_phone
  • sponsor_subtitle
  • sponsor_website_description
  • sponsor_image_512

这代表 Odoo 在主动划清边界:

Booth

负责资源占用与招商执行。

负责品牌展示与官网传播。

这两个对象有关联,但不是同一个层次。

如果把官网展示资料直接堆进 booth:

  • 销售一改 booth 联系人,官网信息可能被污染
  • 市场同事完善品牌描述时,又会碰到招商执行字段

而 related 的做法把入口和展示主体拆开了:

  • booth 是业务入口
  • sponsor 是传播主体

这比“所有字段都放在一个表里”稳得多。


实施上最应该守住的三个边界

1. booth 状态是库存状态,不是完整销售漏斗

别把 available / unavailable 强行演化成十几个招商阶段。

2. sponsor 应该来自确认后的 booth,而不是脱链手工维护

否则库存与官网展示迟早分家。

3. 活动模板同步应当只影响未售库存

别让模板更新破坏已成交资源。


最后一句

Odoo booth 机制最值得学的地方,不是“能不能卖展位”,而是它先把展位当成库存和套餐,再把 sponsor 当成确认后的展示实体

这条顺序一旦反过来,系统就会越来越像一堆联系人备注; 这条顺序守住了,活动招商、官网展示和现场执行才会真正围绕同一套对象运转。

DISCUSSION

评论区

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