先说结论
Odoo Lunch 不是一个“把菜单搬到系统里”的小工具,而是一套专门面向公司内部集体订餐的轻运营模型。
从 /home/ubuntu/odoo-temp/addons/lunch/models/lunch_order.py 看,lunch.order 关注的不只是“你点了什么”,还同时管:
- 当天能不能订
- 供应商今天接不接单
- 是否过了截止时间
- 同一个人的相同订单要不要合并
- 钱包余额够不够
- 配料选择是否满足规则
所以它真正解决的问题不是点餐动作本身,而是:
公司里很多人每天都在下单,系统怎样既让流程顺滑,又避免订单碎片化和财务失控。
第一层:为什么午餐订单不是“每点一次就新建一条”
create() 里最有意思的逻辑之一,就是 _find_matching_lines()。
当用户新建订单时,系统会先查:
- 同一个用户
- 同一个产品
- 同一天
- 同样备注
- 同样取餐地点
- 同样状态
- 同样配料组合
如果找到匹配行,不是继续新建,而是:
- 直接
update_quantity(1) - 把数量加到已有订单上
这说明 Lunch 的核心目标之一,是减少碎片订单。
为什么这很重要? 因为内部订餐和普通电商不同:
- 同一个人可能反复改数量
- 同一办公室大量订单需要统一汇总给供应商
- 后台更关心“最终要送几份”,而不是“按钮被点了几次”
所以 Odoo 默认把重复下单理解成数量变更,而不是新增业务对象。
第二层:为什么编辑订单时也会尝试再合并
write() 里还有一层更细的处理。
当这些信息变化时:
- 备注
- 配料
- 状态
- 用户
- 产品
- 取餐地点
系统会再次尝试找匹配订单,把相同内容的订单合并,并把旧行 active=False 处理掉。
这很能体现 Lunch 的产品思路:
- 用户看到的是“我在改我的午餐”
- 系统内部维护的是“最终汇总后应发给供应商的订单结构”
因此 Lunch 不是把每次界面操作都当成不可变历史,而是更重视最终汇总结果。
这和采购、销售那种强调订单原子性的模型很不一样。
第三层:钱包余额为什么会影响“还能不能继续点”
_compute_display_add_button() 里,系统会先统计:
- 这个用户当天所有
new状态订单 - 它们累计多少钱
- 再去调用
lunch.cashmove算钱包余额
最后只有在余额覆盖当前订单价格时,才显示继续添加按钮。
这说明 Lunch 的“余额控制”不是结算时最后拦一次,而是在用户持续点单的过程中就介入。
这样做有两个好处:
1. 减少无效下单
用户一开始就知道自己还能不能加,而不是最后统一报错。
2. 保证内部补贴或预充值规则可执行
很多公司午餐系统不是实时付款,而是预存或公司补贴余额机制。 如果前面不控,后面会很难对账。
所以 Lunch 在这里其实已经开始碰内部财务边界了。
第四层:为什么截止时间和可订日期是订单级判断
Lunch 里同时有两类时间边界:
available_on_dateorder_deadline_passed
逻辑大致是:
- 供应商今天是否营业
- 指定日期是否能订
- 如果就是今天,当前时间是否已经过了供应商截止时间
很多人会觉得这个判断应该挂在供应商上就够了。 但 Odoo 放在订单级计算,原因很实际:
- 同一个供应商,不同订单日期结果不同
- 同一个用户今天能不能订,和明天能不能订,不是同一个问题
- 界面渲染时需要直接判断当前订单状态
也就是说,供应商定义的是规则,订单承担的是规则在本次订餐上的结果。
第五层:配料选择为什么要做严格约束
Lunch 不是简单地让你勾几个加料选项。
在模型里,配料被拆成:
topping_ids_1topping_ids_2topping_ids_3
并且每组都可能有不同数量要求,比如:
- 必选一个
- 至少选一个
- 可以不选
_check_topping_quantity() 会按供应商规则校验这些约束。
这说明 Odoo 的 Lunch 不是把加料当成自由文本,而是在试图标准化餐品配置。
这样做的价值在于:
- 订单更容易汇总
- 供应商收到的信息更规范
- 价格与配置更容易对应
- 用户少犯“忘选必选项”的错误
第六层:为什么 Lunch 仍然保留状态机
state 包含:
neworderedsentconfirmedcancelled
这说明 Lunch 虽然轻量,但它并不只是个人收藏夹式购物车。
它仍然是一条有内部处理过程的链:
- 用户先选餐
- 内部确认并汇总
- 再发给供应商
- 最后确认收到
这对于办公室统一订餐非常合理。
因为真正难的不是“某个人点了什么”,而是:
- 什么时候汇总
- 谁发给供应商
- 供应商是否接单
- 实际是否收到了餐
所以状态机虽然简单,但很必要。
最容易误解的三个点
误区一:Lunch 就是个小商城
不是。它更像一个内部订餐调度系统,重点在汇总、余额和规则控制。
误区二:订单合并是可有可无的小优化
其实非常关键。没有合并,内部订餐在高频场景下会迅速碎成很多重复小单。
误区三:余额校验只是页面提示
也不是。它和 cashmove 绑定,背后直接关系到公司补贴或预付金规则是否能落地。
实战上最该关注什么
如果你想把 Lunch 用得顺,最重要的是先配好三类规则:
- 供应商规则:营业日、截止时间、加料标签、加料数量限制
- 资金规则:钱包充值、公司补贴、余额不足时的处理方式
- 汇总规则:谁来把
new/ordered/sent这些状态推进下去
当这三层跑顺后,Lunch 的体验会非常像一个“低摩擦但强约束”的公司内部服务。
最后一句
Odoo Lunch 看似轻,但它很懂办公室订餐真正的麻烦在哪里:
- 同一人会反复改单
- 供应商有截止时间
- 配料规则容易出错
- 公司还要控制余额和补贴
所以它不是在做一个外卖 App,而是在做一套适合组织内部运转的订餐机制。
DISCUSSION
评论区