制造标签链路

Odoo 制造标签为什么有时自动打、有时要你自己选:完工自动打印、批次批量生成与标签版式链路讲透

从 mrp.production._get_autoprint_done_report_actions、_autoprint_generated_lot、_autoprint_mass_generated_lots 到 action_open_label_layout / action_open_label_type,理解 Odoo 制造标签并不是单一按钮,而是按触发时机、打印对象和格式能力拆成几条独立链路。

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

很多团队会把“制造标签打印”理解成一个功能点:完工后打一张标签,结束。

但 Odoo 源码里,这件事其实被拆成了至少三类不同场景:

  1. 制造单完成后自动打印
  2. 生成 lot / serial 时立刻打印
  3. 用户临时决定打印什么标签、用什么版式

如果不把这三条链路分清,你就会经常遇到一种错觉:明明都是打印标签,为什么这次自动打了,那次却弹窗口让你选,换成 ZPL 又是一套行为?

真正的核心方法:_get_autoprint_done_report_actions()

addons/mrp/models/mrp_production.py 里,制造单完工后的自动打印主入口是 _get_autoprint_done_report_actions()

它不是“返回一个打印动作”那么简单,而是返回一个 动作列表。这已经说明设计思路:完工后可能要连续打印多种不同文档

源码里按条件拆了几组动作:

  • 生产单据本身(production order)
  • 成品标签(finished product labels)
  • 接收报告(reception report)
  • 接收标签(reception labels)
  • lot 标签(done MRP lot labels)

也就是说,Odoo 的制造打印不是一个 report toggle,而是一个按 picking type 配置驱动的打印队列

为什么有时打印成品标签,有时打印 lot 标签

这是很多实施现场最容易混淆的点。

成品标签:面向“成品 move / 产品本身”

picking_type_id.auto_print_done_mrp_product_labels 打开时,系统会按 mrp_product_label_to_print 决定输出格式:

  • pdfaction_report_finished_product
  • zpllabel_manufacture_template

这类标签更像“这批做出来的产品要贴什么商品标签”。

lot 标签:面向“已经落到 move line / lot 的追溯对象”

当用户拥有 stock.group_production_lot,且 auto_print_done_mrp_lot 开启时,系统会从 move_finished_ids.move_line_ids.lot_id 中收集 lot,再决定打印 PDF 还是 ZPL。

这条链路强调的是追溯单元,而不是商品展示单元。

换句话说:

  • product label 更偏“我要给成品贴业务标签”;
  • lot label 更偏“我要给这次产出的追溯对象贴身份标签”。

两者看起来都叫标签,但对象层级不同,所以配置和打印动作也分开。

为什么“生成批次号”后的打印又是另一套方法

_autoprint_generated_lot()_autoprint_mass_generated_lots() 处理的不是“完工之后”的场景,而是“批次 / 序列号刚被生成”的场景。

这里的时间点往前挪了:

  • 不是等 MO done;
  • 而是在 lot_producing_ids 生成之后,就可以立即打印。

这非常符合现场操作:有些工厂是先打追溯标签,再贴到工件、周转箱或工单卡上,后续才继续报工。

源码里同样支持 PDF / ZPL 两种格式,但它依赖的是另一组配置:generated_mrp_lot_label_to_print。这说明 Odoo 认为“生成时打印”和“完工时打印”是两个独立决策,而不是一个总开关。

action_open_label_layout()action_open_label_type() 在解决什么问题

自动打印解决的是默认流程,但制造现场经常还有临时打印需求。这时,Odoo 提供两个手动入口。

action_open_label_layout():先选版式,再打产品标签

这个 action 会打开 product.label.layout,并把:

  • default_product_ids
  • default_move_ids
  • default_move_quantity = 'move'

塞进上下文。

意思是:你不是抽象地为产品打标签,而是基于这批成品 move 来打印,数量也跟 move 走。

action_open_label_type():先决定打印 lot 还是产品

如果当前用户有 lot 权限、并且成品 move line 上已经有 lot_id,系统会优先弹 picking.label.type,让用户先选“打哪种标签”;否则就直接回退到 action_open_label_layout()

这个设计很妙:

  • 没 lot 的时候,不必多问,直接走产品标签;
  • 有 lot 的时候,先让用户决定打印对象层级。

它不是多此一举,而是在避免“系统替你假设你到底想打印产品标签还是 lot 标签”。

为什么源码里到处在区分 PDF 和 ZPL

因为 Odoo 这里不是把“格式”当成视图皮肤,而是把它当作不同输出通道

  • PDF 更适合办公室、通用打印机和人工补打;
  • ZPL 更适合标签机、现场自动贴标和批量流水线。

因此源码不是一个 report 模板里切 CSS,而是直接映射到不同 report action。实施时如果只测 PDF 不测 ZPL,通常上线后现场就会踩坑。

实施和定制时最容易忽略的三个点

1. 不要把所有打印都绑在 MO done 上

如果你的现场需要“先有码、后报工”,应优先理解 generated lot 的打印链路,而不是硬改完工动作。

2. picking type 配置是打印策略的真正开关

很多人只盯制造单按钮,忽略了真正影响行为的是 picking type 上的 auto print 配置以及对应格式字段。没配对,再多定制前端按钮也没用。

3. 标签对象层级要先说清楚

项目讨论里如果只说“打印标签”,大概率会埋雷。你至少要问清:

  • 打产品标签还是 lot 标签?
  • 完工时自动打还是生成批次时就打?
  • PDF 还是 ZPL?
  • 数量跟产品、move,还是跟 lot 走?

这些问题在源码里已经被拆开,实施方案也应该跟着拆开。

一句话总结

Odoo 制造标签之所以看起来“有时自动打、有时又让你选”,不是因为逻辑混乱,而是因为它把 打印时机、打印对象、输出格式 三件事认真拆开了。理解这三层后,制造标签就不再是一个模糊功能,而是一条可配置、可扩展的现场交付链路。

DISCUSSION

评论区

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