其他深度

Odoo 午餐为什么不只是“内部点餐”:供应商日历、自动发单 Cron、地点可用性与提醒广播讲透

很多人把 Odoo Lunch 看成办公室小福利,但源码里的 supplier、cron、location、alert 和 cashmove 说明它其实是一套“受时间与地点约束的内部订餐系统”。看懂这条链,午餐模块才不会被误用成一个简化商城。

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

先说结论

Odoo Lunch 的重点,不是“做一个点餐界面”,而是把 供应商什么时候接单、在哪些地点可订、何时自动发单、该提醒哪些人、钱包还能不能扣 这些办公室订餐约束收进一套流程。

/home/ubuntu/odoo-temp/addons/lunch/models/lunch_supplier.pylunch_order.pylunch_alert.pylunch_product.pylunch_cashmove.py 来看,Lunch 更像一个轻量内部运营系统,而不是缩小版外卖平台。

第一层:为什么供应商对象本身就像一张运营日历

lunch.supplier 上除了联系人信息,还有:

  • mon ~ sun
  • automatic_email_time
  • moment
  • tz
  • send_by
  • available_location_ids
  • delivery
  • cron_id

这说明供应商不是静态资料卡,而是“这家店在什么时间、以什么方式、服务哪些办公点”的规则中心。

尤其 tz + automatic_email_time + cron_id 这组字段非常关键:

Lunch 不是用户点完就结束,而是系统要在合适时间把当天订单发给供应商。

这和普通电商完全不一样。电商是每笔订单独立流转;Lunch 更像每天收口一次的办公室团餐机制。

第二层:为什么改供应商星期规则会取消未来订单

lunch.supplier.write() 里,如果某些工作日从可用变成不可用,会调用 _cancel_future_days(),把未来仍在 new / ordered 状态、且落在这些星期几的订单直接取消。

这个逻辑很有产品味道,因为它表达的是:

  • 供应商可用日不是展示信息
  • 而是实际的接单约束

换句话说,供应商日历一旦变化,系统会主动修正未来订单,而不是等到当天人工发现“今天这家没开门”。

第三层:自动发单为什么交给动态 Cron

lunch.supplier.create() 会给每个供应商配一条 ir.cron,随后 _sync_cron() 按供应商自己的时区和发送时间重算:

  • cron 是否 active
  • nextcall 在何时
  • code 调哪条 _send_auto_email()

这说明 Lunch 的自动发单不是一个全局定时任务硬编码循环,而是每个供应商自己驱动自己的发送节奏

好处很明显:

  • A 供应商 10:30 截单
  • B 供应商 11:45 截单
  • 北京办公室和巴黎办公室还可以按各自时区算

这种粒度对于分办公室、多供应商场景很实用。

第四层:地点为什么不是简单地址字段

lunch.location 很轻,看起来只有名字和地址;但在业务链里,它的作用并不轻。

因为:

  • 供应商可以配置 available_location_ids
  • 产品搜索会走 _search_is_available_at()
  • 订单有 lunch_location_id
  • 提醒 lunch.alert 也能限定 location_ids
  • 用户还会记住自己的 last_lunch_location_id

这意味着地点在 Lunch 里不是展示文本,而是一个过滤和路由维度。

办公室订餐最常见的复杂度,恰恰不是菜品,而是:

  • 哪个楼层/园区可送
  • 哪些人该看到哪家供应商
  • 某次提醒是否只发给某办公点的人

Odoo 把这些都挂回 location 维度,思路是对的。

第五层:提醒为什么单独建 lunch.alert

lunch.alert 支持:

  • app 内 alert
  • chat notification
  • everyone / last_week / last_month / last_year 收件人范围
  • 星期与截止日期控制
  • 自己的 cron 调度
  • 按地点过滤

这说明 Lunch 的提醒不是“发个公告”那么简单,而是一个带定向规则的广播系统。

尤其 _notify_chat() 会按历史下单行为筛用户,这很实用:

  • 上周下过单的人,最可能今天还会下
  • 很久没点过的人,不一定值得被频繁打扰

这类人群选择虽然不复杂,但已经体现了产品在做“低打扰运营”。

第六层:为什么钱包规则仍然贯穿整个流程

之前我们已经写过 merge / wallet / deadline,那篇更偏订单对象本身。

这次从源码继续看,会发现钱包并没有被边缘化:

  • display_add_button 会先按当天未提交订单金额预扣
  • _check_wallet() 在下单关键路径再次校验
  • lunch.cashmove.get_wallet_balance() 还会把公司最低补贴阈值算进去

这意味着 Lunch 的整个产品判断是:

先保证规则成立,再让用户继续加单。

所以它不是福利展示页,而是一个明确带预算边界的内部消费系统。

最容易误解的三个点

误区一:Lunch 就是一个公司内部外卖页

不是。它真正难的是供应商日历、地点限制、提醒节奏和订单收口。

误区二:Cron 只是技术实现细节

也不是。Lunch 的发单节奏本身就是业务规则的一部分。

误区三:Location 只是写个送餐地址

不是。它直接影响商品可见性、供应商可用性和提醒触达范围。

实战上怎么用最顺

建议这样理解和落地:

  1. 先把供应商可用星期、时区和发单时间配对
  2. 办公点分清 location,不要全塞一个默认地址
  3. 用 alert 做轻运营,不要把所有人都一股脑广播
  4. 让产品和供应商的 active 状态跟着真实业务走
  5. 把钱包规则当订单前置约束,而不是事后对账

最后总结

Odoo Lunch 最有意思的地方,不在“点餐”本身,而在它把 供应商时间表、地点路由、自动发单和轻量提醒运营 做成了一套闭环。

所以它更像一个办公室团餐调度系统,而不是一个迷你商城。

DISCUSSION

评论区

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