企业 POS / 外卖聚合

Odoo 企业版 POS 接 UrbanPiper 为什么不是“把外卖单同步进来”而已:打印锁、配送状态与取餐 OTP 链路讲透

从 pos_urban_piper 拆解第三方外卖接单:为什么线上单不能删、为何自动打印只能发生一次、配送平台扩展字段又如何进入备餐屏。

POS 企业
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 4 阅读

第三方外卖平台接入的难点不在“收到一张订单”,而在 Odoo 内部如何保证它既能进后厨、又不能被误删,还能把平台配送语义保留下来。

核心链路

  1. pos_urban_piper/models/pos_order.pypos.order 补了 delivery_statusdelivery_provider_iddelivery_identifierdelivery_jsondelivery_rider_jsonprep_time 等字段。也就是说,平台单不是普通 POS 单多一个备注,而是整套配送语义都被落进订单模型。
  2. _unlink_except_online_order() 明确禁止删除带 delivery_identifier 的线上单。企业版不允许店员把平台单当本地误单直接删掉,因为这会破坏与平台的对账和状态同步。
  3. mark_urbanpiper_prep_order_as_printed() 先执行 SELECT ... FOR UPDATE NOWAIT 锁定订单,再检查 last_order_preparation_change 里的 urbanpiper_printed 标记,只允许自动打印一次。这个细节解决的是多终端、多线程下的重复出单。
  4. pos_prep_order.py 里,_compute_order_otp() 会从 delivery_json.order.details.ext_platforms 里抽取平台侧 OTP,同时标记是否为测试订单。于是备餐/交付流程看到的不只是订单号,而是可核销的取餐凭证。
  5. 因此 UrbanPiper 集成的主链路是:平台字段入单 -> 后厨打印防重 -> 配送状态与 OTP 进入履约流程,而不是“第三方把 JSON 扔给 POS 就结束”。

关键源码位置

  • /home/ubuntu/odoo-temp/enterprise/pos_urban_piper/models/pos_order.py
  • /home/ubuntu/odoo-temp/enterprise/pos_urban_piper/models/pos_prep_order.py

容易误解的地方

  • 误区一:外卖单导入后就和本地单一样。实际上它带着专门的 delivery 状态和 provider 语义。
  • 误区二:自动打印重复几次无所谓。线上聚合场景里重复打印往往意味着重复制作。
  • 误区三:OTP 只是展示字段。对某些平台场景,它直接影响骑手/顾客交付核验。

实战注意事项

  • 若门店反馈“平台单消失了”,先看是不是有人尝试删除线上单而被逻辑拒绝。
  • 排查重复厨打时,重点查看 last_order_preparation_change 中的 urbanpiper_printed 标记和数据库锁冲突。
  • 接更多聚合平台时,尽量把平台识别、配送状态、OTP 都收敛在统一字段结构里,避免前后厨各解析一套 JSON。

结语

企业版这些代码共同说明一件事:真正可上线的业务流程,靠的不是“页面上看起来能点通”,而是权限、状态、时机、对账口径和跨模块回写都被收紧。理解这些边界,实施和二开时就不容易走进“功能演示能跑、真实业务一用就散”的坑。

DISCUSSION

评论区

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