如何在基于stock.move的报表中读取stock picking及stock move line中的字段并修复报表
如何在基于stock.move的报表中读取stock picking及stock move line中的字段并修复报表
看起来你是在Odoo里做一个基于stock.move的称重标签报表,现在遇到了从stock.picking和stock.move.line读取字段的问题,我来帮你一步步修复这个报表:
一、先理清数据关联逻辑
你的报表绑定的是stock.move模型(在report action里model设为了stock.move),所以模板里的doc指代的是单条库存移动记录,而不是拣货单(stock.picking)。你需要通过doc.picking_id关联到对应的拣货单,通过doc.move_line_ids关联到对应的库存移动明细行。
二、具体代码修复
下面是调整后的模板和报表配置,我会标注关键修改点:
1. 修复后的报表模板
<!-- Report Template --> <template id="report_stock_picking_template"> <t t-call="web.html_container"> <t t-call="stock_picking_report.report_stock_picking_styles"/> <t t-foreach="docs" t-as="doc"> <div class="label-container"> <h4 class="label-title">Weighing Label</h4> <table class="label-table"> <!-- 读取stock.picking中的mrp_product_id和batch --> <tr t-if="doc.picking_id"> <td class="label-cell">Product: <span t-esc="doc.picking_id.mrp_product_id.name if doc.picking_id.mrp_product_id else 'N/A'"/></td> <td class="label-cell">ID: <span t-esc="doc.picking_id.mrp_product_id.id if doc.picking_id.mrp_product_id else 'N/A'"/></td> </tr> <tr t-if="doc.picking_id"> <td class="label-cell" colspan="2">Batch No: <span t-esc="doc.picking_id.batch if doc.picking_id.batch else 'N/A'"/></td> </tr> <!-- 当前stock.move对应的产品信息 --> <tr> <td class="label-cell">Item: <span t-esc="doc.product_id.name"/></td> <td class="label-cell">ID: <span t-esc="doc.product_id.id"/></td> </tr> <!-- 读取stock.move_line中的expiration_date,或从关联批次获取 --> <tr> <td class="label-cell"> Exp: <span t-if="doc.move_line_ids and doc.move_line_ids[0].expiration_date" t-esc="doc.move_line_ids[0].expiration_date" t-options='{"widget": "date"}'/> <span t-elif="doc.lot_id and doc.lot_id.expiration_date" t-esc="doc.lot_id.expiration_date" t-options='{"widget": "date"}'/> <span t-else>N/A</span> </td> <td class="label-cell">Control No: <span t-esc="doc.lot_id.name if doc.lot_id else 'N/A'"/></td> </tr> </table> </div> </t> </t> </template>
2. 关键修改说明
- 空值防护:给所有关联字段加上
t-if判断和默认值(比如'N/A'),避免因为某个字段为空导致报表渲染失败。 - 保质期字段优化:
- 优先从当前move的第一条明细行(
doc.move_line_ids[0])读取expiration_date(符合你说的该字段在stock move line中的设定) - 同时兼容从批次(
doc.lot_id)读取保质期的场景(这是Odoo的常规配置,防止你的字段实际在批次上的情况)
- 优先从当前move的第一条明细行(
- Control No修复:把
doc.lot_ids.name改成doc.lot_id.name,因为stock.move关联的是单个批次(lot_id是Many2one字段,lot_ids是错误的字段名)
3. 报表Action保持不变(如果没有其他问题)
你的报表Action配置是正确的,绑定到stock.move模型没问题,不需要修改:
<!-- Report Action --> <record id="action_report_stock_picking" model="ir.actions.report"> <field name="name">Weighing Label</field> <field name="model">stock.move</field> <field name="report_type">qweb-pdf</field> <field name="report_name">stock_picking_report.report_stock_picking_template</field> <field name="report_file">stock_picking_report.report_stock_picking_template</field> <field name="binding_model_id" ref="stock.model_stock_move"/> <field name="binding_type">report</field> </record>
三、额外注意事项
- 确保
stock.picking模型确实有mrp_product_id和batch这两个自定义字段,并且权限配置正确(报表用户能读取这些字段) - 如果你的库存移动对应多条明细行(
move_line_ids),可能需要循环遍历明细行来展示每条的保质期,而不是只取第一条 - 测试时可以先找一条有完整数据的
stock.move记录来预览报表,验证每个字段都能正确显示
备注:内容来源于stack exchange,提问作者Dahlia
相关产品推荐
相关产品推荐

