先说结论
Odoo POS 的“共享挂单”不是一句“让几个收银台看到同一批草稿单”就能讲完。
在 point_of_sale 里,这件事至少包含四层约束:
- 哪些收银配置之间允许互信;
- 这些配置是否使用同一种货币;
- 前端到底该拉哪些 draft
pos.order; - 已取消、已变化、已不存在的挂单如何从界面回收。
所以它的本质不是简单广播,而是:
在多个 POS 配置之间,建立一条可控的草稿订单共享通道。
一、为什么共享关系不是“全店自动可见”
源码里关键字段是 trusted_config_ids。
对应的方法 _add_trusted_config_id() / _remove_trusted_config_id() 看起来很朴素,但设计意图很明确:
- 共享不是全局开关;
- 它是配置与配置之间的显式互信关系;
- 只有被纳入 trusted 集合的配置,才会进入开放订单同步范围。
这背后其实是在解决一个现实问题:
- 同一家门店里可能有多个收银台;
- 但不是所有收银台都应该共享所有挂单;
- 有的前台是堂食,有的是自助机,有的是外带窗口;
- 如果无差别互通,收银员会在界面里看到一堆不属于自己业务语境的草稿单。
所以 Odoo 不是默认“越共享越方便”,而是先问:
- 这两个配置之间有没有业务上的互信关系?
二、为什么源码一定要做币种一致性校验
_check_trusted_config_ids_currency() 是这条链里最值得重视的约束之一。
它会直接阻止:
- 被互信的两个 POS 配置使用不同币种。
报错也很直接:
- 不能和使用不同货币的配置共享 open orders。
这个限制非常合理。因为挂单共享看起来只是“订单换个前台继续结账”,但订单里其实已经带着:
- 商品单价;
- 税;
- 折扣;
- 支付预期;
- 小票展示语义。
如果 A 配置是人民币,B 配置是美元,你把一张 draft 单直接共享过去,前端就会立刻碰上很多不一致:
- 显示货币不一致;
- 付款方式金额语义不一致;
- rounding / 收款差额边界不一致;
- 客户看到的小票金额上下文混乱。
所以这不是“保守限制”,而是为了避免把一张订单从一套价格语境硬塞进另一套语境。
三、前端为什么不是“把所有 draft 单都拉下来”
在 devices_synchronisation.js 里,constructOrdersDomain() 会专门给 pos.order 组装 domain。
它不是简单查:
- state = draft
而是把条件做成:
- 当前已同步记录如果
write_date更新了,要重新拉; - 当前记录如果状态变了,也要重新拉;
- 对于新增 draft 单,还要求
config_id在[当前配置, ...trusted_config_ids]里。
这说明前端同步解决的是两个问题:
- 旧记录有没有变化;
- 有没有新的共享草稿单进入视野。
如果只做第二件事,前端会看不到已存在挂单的状态变化; 如果只做第一件事,新开出的共享挂单又不会出现。
Odoo 把两者并在一个 domain 里,就是为了让 open orders 既能增量更新,也能补收新增记录。
四、为什么服务端还要返回 deleted_record_ids
read_config_open_orders() 不只返回 dynamic_records,还会回传:
deleted_record_ids
而且对 pos.order 有特殊处理:
- 已取消订单必须强制从前端删除。
这非常关键,因为共享挂单最大的风险,不是“看不到新单”,而是:
- 继续看到本该消失的旧单。
一旦取消单、失效单、或已经不存在的记录仍残留在界面里,收银员就可能:
- 错误接手;
- 误以为还能继续支付;
- 在高峰时段重复操作。
所以 Odoo 同步的不只是“新增/更新”,还同步“应该消失的东西”。
五、为什么这套机制更像“共享工作台”,而不是“订单转移”
很多人会把共享挂单理解成“把订单从 A 收银台转移到 B 收银台”。
但从源码看,它更接近:
- 多终端共同观察同一批开放草稿单;
- 谁来接手结账,取决于后续操作;
- 订单本身仍保留自己的业务状态,不因为被别人看见就立刻迁移。
也就是说,Odoo 设计的不是一个“强转单”模型,而是一个:
在受控配置集合里共享可继续处理的 draft 订单池。
这比“订单归属硬切换”灵活得多,也更适合多设备门店场景。
六、最容易误解的几个点
误解 1:共享挂单就是多端实时广播
不完全对。它背后还有 trusted config 关系、domain 约束和回收机制。
误解 2:只要看得到挂单,就能安全接手
不对。币种一致性就是第一道硬边界。
误解 3:同步只关心新增记录
不对。写入时间变化、状态变化、取消删除都必须同步。
误解 4:共享挂单等于转单
不对。更准确地说,它是一个多终端共享开放草稿池的机制。
七、做定制时最该保留什么
如果你要扩展 POS 共享挂单,最值得保留的是这三件事:
- 继续用 trusted config 显式表达共享关系;
- 继续保留币种一致性这种硬约束;
- 继续把前端同步做成“新增 + 变更 + 删除回收”三件事一起处理。
很多粗暴定制会直接去掉这些限制,短期看像是更灵活,长期就会变成:
- 草稿池越来越脏;
- 不同收银语境混在一起;
- 收银员界面信息污染越来越严重。
最后一句
理解 Odoo POS 的共享挂单,重点不是“几台机器能不能互相看单”,而是看懂这条主链:
trusted config 建立共享范围 → currency 校验建立价格边界 → open orders domain 拉取新增与变更 → deleted ids 回收失效记录。
看懂以后你就会明白,Odoo 保护的不是“共享”本身,而是共享之后仍然不乱。
DISCUSSION
评论区