库存现场最怕的不是扫不出条码,而是扫出来以后进错入口:该开 picking 时进了产品页,该进 lot 时又被当成 picking name。
这篇文章主要参考:
enterprise/stock_barcode/controllers/stock_barcode.pyenterprise/stock_barcode/models/stock_picking.pyenterprise/stock_barcode_barcodelookup/controllers/stock_barcode.py
一、主菜单扫描不是“查一张表”,而是动作路由器
/stock_barcode/scan_from_main_menu 先尝试用公司 nomenclature 解析条码。若是 GS1,会优先把结果归类成 product / package / location / dest_location;若只是 alias,则先把条码改写成真实 code,再继续后面的链路。
这一步的意义是:Odoo 先决定“你扫到的是什么语义”,再决定“该打开什么页面”。因此同一串字符,在不同条码规则与权限组下,后续动作并不一定相同。
二、真正的 fallback 顺序决定了为什么“同一条码今天能用、明天不能用”
如果没有明确的 barcode_type,主控制器会按顺序尝试:
_try_open_picking()_try_open_picking_type()- 多库位时
_try_new_internal_picking() _try_open_product_location()- lot / package 入口
而 stock.picking.filter_on_barcode() 内部又会继续做一层 picking 过滤:产品条码、包装条码、包裹、lot,最后才回退到 picking name。也就是说,主菜单是第一层路由,具体业务对象过滤是第二层路由。
三、常见误区:把 GS1 命中看成“肯定会开到正确单据”
并不会。GS1 只是帮助系统判断语义类型,并不保证当前上下文里一定存在可操作对象。
例如 filter_on_barcode() 里会限制:
- 当前 operation type
- picking 不能是
cancel/done/draft - lot 需满足公司边界
- package / packaging / product 命中后还要检查是否真有 ready picking
所以现场经常出现“明明识别到了 product,却提示没有 ready picking”的情况。问题不在扫码器,而在当前上下文可执行对象为空。
四、实施时最该检查什么
- 公司是否启用了正确的
nomenclature_id - 用户是否具备 multi-locations / lots / packages 权限
- 条码到底是 product barcode、packaging barcode 还是 package name
- 当前 operation type 下是否真的存在
assigned/confirmed的目标单据
五、结论
库存条码主菜单真正做的是“先识别语义,再路由动作,再在上下文里过滤业务对象”。理解这一点,很多“同一个条码为什么开到不同地方”的问题就不神秘了。
DISCUSSION
评论区