POS 条码规则

Odoo POS 扫码为什么不是“识别条码就行”:nomenclature、GS1 fallback 与嵌入式数量/价格/折扣规则讲透

很多人把 POS 扫码理解成“枪扫一下,系统认出商品”,但 Odoo 真正处理的是条码规则、GS1 解析、fallback parser、包装条码以及数量/价格/折扣的嵌入语义。本文结合 point_of_sale 源码讲清:为什么有些码能直接带出重量或金额、为什么 GS1 码不合规时会报不兼容、以及遇到扫码错货时应该按什么顺序排查。

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

很多团队上线 POS 时,对扫码的期待往往只有一句话:

扫一下,能出商品就算成功。

这在业务上太粗了。Odoo POS 的扫码不是“查一个 product.barcode”,而是一套“先解析语义、再决定动作”的规则系统。 也正因为如此,扫码问题经常不是商品没建出来,而是条码被解析成了错误的类型,或者压根没有进入正确的 parser。

先说结论:Odoo POS 的扫码链路分两层——先由 barcode nomenclature 解析“这串码代表什么”,再由前端回调决定“拿它干什么”。 识别失败时,真正要看的不是商品主数据本身,而是规则、GS1 兼容性、fallback parser、包装条码与前端注册的动作映射。

第一层不是找商品,而是先判定“条码语义”

static/src/app/services/barcode_reader_service.js 里,POS 收到扫描结果后不会直接搜 product.product。它先交给 BarcodeParser.parse_barcode(),把这串码解释成一个“类型化结果”。

models/barcode_rule.py 里,POS 扩展了多种条码类型,包括:

  • weight:称重商品;
  • price:带价商品;
  • discount:带折扣商品;
  • client:客户;
  • cashier:收银员。

也就是说,同样是扫一个码,Odoo 先决定它是“商品条码”还是“客户码/员工码/动作码”,再决定回调到哪个业务处理器。 这就是为什么有时你明明扫的是一串合法数字,却不会加商品,而是切换客户、登录员工,或者直接弹未知条码警告。

GS1 不是“高级点的条码”,而是可携带业务数据的编码结构

很多零售团队会碰到一个现象:

  • 某些秤码一扫就能带出重量;
  • 某些价签一扫就自动带出价格;
  • 某些码明明很长,POS 却提示不兼容。

原因通常在 GS1。

barcode_reader_service.js 中,Odoo 对 GS1 条码有单独判断:如果解析结果是数组,但里面没有 product 元素,就会抛出 GS1BarcodeError。这背后的意思很明确:GS1 可以带很多段信息,但至少得先把“商品是谁”说清楚。

所以“扫码长度很长”不代表可用;“供应商说这是 GS1”也不代表 Odoo 就一定能吃下。只要核心应用标识和规则没对齐,POS 就会把它视为不兼容格式。

fallback nomenclature 的作用,不是补商品,而是补解析器

这点特别容易被误解。

源码里如果主 parser 抛出 GS1BarcodeError,而 session 里配置了 fallback_nomenclature_id,POS 会再用一套 fallback parser 重试。注意,它补的不是商品库,而是“第二套条码解释规则”。

这意味着 fallback 更适合解决下面这类混扫场景:

  • 门店同时存在 GS1 秤码和老式内部价签;
  • 总部推 GS1,但部分旧设备还在吐 legacy barcode;
  • 同一收银台既扫商品,也扫会员卡和员工卡。

如果你的问题本质上是“条码没建到商品上”,配置 fallback 并不会救你;但如果问题是“这串码根本没被主 parser 正确解释”,fallback 往往就是关键。

包装条码与嵌入式数量,为什么常常被误诊成库存问题

pos_store.jspos_order_line.js 里有一条很容易被忽视的路径:POS 不只认商品主条码,也会认 product.uom 上的包装条码。源码甚至会根据包装对应的 UoM 因子,自动换算出数量。

这就解释了一个现场高频坑:

一扫不是“加一个”,而是“加一箱 / 一包 / 一托盘”。

很多人第一反应去查库存单位,实际上应该先查:

  1. 这把枪扫到的是商品主条码,还是包装条码;
  2. 包装条码绑定的 UoM 因子是不是错了;
  3. 门店是不是把“外箱码”当成“单品码”贴在了前台。

所以数量异常不一定是 stock bug,很可能只是条码语义被设计成了包装级别。

为什么有的扫描会直接改数量、改金额、改折扣

因为 POS 支持“嵌入式业务量”。

在默认条码模式里,weight / price / discount 三类规则都不是简单查主数据,而是把条码里某一段解析成业务值,再应用到订单行。这也是称重、生鲜、预打折标贴能在前台成立的原因。

但它也带来一个边界:如果商品、规则和位数定义没完全一致,POS 并不是“差一点也能凑合”,而是会稳定地产生错误数量或错误金额。 这类错单往往最危险,因为系统不会报错,只会“算错但看起来很顺”。

最容易踩的四个误区

误区一:未知条码就等于商品没建

不对。也可能是条码被解析成了一个没有注册回调的类型,或者压根没命中当前 nomenclature。

误区二:GS1 报不兼容时,补个商品条码就能解决

不对。报错说明 parser 没把它解释成一个合法 GS1 结构,先看规则而不是先补主数据。

误区三:fallback 是“兜底搜索”

不是。它是兜底解析器,不是兜底商品查询。

误区四:称重码错数一定是秤没校准

不一定。很多时候是 Odoo 这边的位数、前缀、decimal 规则或包装 UoM 定义不匹配。

实战排错顺序,建议按这五步走

遇到 POS 扫码异常,不要一上来重建商品。更高效的顺序是:

  1. 先确认 session 正在使用哪套 nomenclature,有没有配置 fallback;
  2. 再判断条码应属哪一类:product、client、cashier、weight、price、discount;
  3. 检查是不是包装条码而非商品主条码,尤其是整箱销售场景;
  4. 如果是 GS1 或秤码,核对前缀、位数、decimal 规则与样码
  5. 最后再回头看商品、客户、员工主数据是否存在且已加载进 POS。

这个顺序的意义在于:先排“解释器”,再排“数据”。因为在 Odoo POS 里,绝大多数扫码怪问题,本质都不是数据库里没有这件商品,而是系统把这串码理解成了别的东西,或者根本没理解。

你真正要管的,不是扫码枪,而是条码语义治理

门店现场往往把扫码问题归咎于枪、浏览器或网络,但从 Odoo 源码看,扫码链路真正的稳定性来自三件事:

  • 条码规则有没有统一;
  • 新旧编码体系有没有清晰切换;
  • 包装、称重、折扣、客户、员工条码是否互不冲突。

所以 POS 扫码项目做得好不好,看的不是“能不能扫”,而是:同一把枪扫进来的每一串码,是否都只有一种明确、可预期的业务含义。

这才是 Odoo POS 条码体系真正的深水区。

DISCUSSION

评论区

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