先说结论
Odoo Lunch 的重点,不是“做一个点餐界面”,而是把 供应商什么时候接单、在哪些地点可订、何时自动发单、该提醒哪些人、钱包还能不能扣 这些办公室订餐约束收进一套流程。
从 /home/ubuntu/odoo-temp/addons/lunch/models/lunch_supplier.py、lunch_order.py、lunch_alert.py、lunch_product.py 和 lunch_cashmove.py 来看,Lunch 更像一个轻量内部运营系统,而不是缩小版外卖平台。
第一层:为什么供应商对象本身就像一张运营日历
lunch.supplier 上除了联系人信息,还有:
mon ~ sunautomatic_email_timemomenttzsend_byavailable_location_idsdeliverycron_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 只是写个送餐地址
不是。它直接影响商品可见性、供应商可用性和提醒触达范围。
实战上怎么用最顺
建议这样理解和落地:
- 先把供应商可用星期、时区和发单时间配对
- 办公点分清 location,不要全塞一个默认地址
- 用 alert 做轻运营,不要把所有人都一股脑广播
- 让产品和供应商的 active 状态跟着真实业务走
- 把钱包规则当订单前置约束,而不是事后对账
最后总结
Odoo Lunch 最有意思的地方,不在“点餐”本身,而在它把 供应商时间表、地点路由、自动发单和轻量提醒运营 做成了一套闭环。
所以它更像一个办公室团餐调度系统,而不是一个迷你商城。
DISCUSSION
评论区