Odoo MRP模块product_qty字段扩展:双单位转换异常问题
生产订单双计量单位数量输入问题解决
需求与现状
需要在创建生产订单时支持两种数量输入方式:
- 常规方式:在原有
product_qty字段输入主计量单位(如“个”)的数量 - 辅助方式:新增字段输入辅助计量单位(如“箱”)的数量,自动转换为主单位数量并填充至
product_qty,转换比例随产品动态变化
已完成的开发:
- 在产品模型新增转换比例字段
- 在
mrp.production模型添加关联字段pastones_por_unidad(关联产品的转换比例),新增辅助数量字段unidades - 已实现从
product_qty到unidades的正向转换逻辑
遇到的问题
- 希望通过计算字段或onchange更新
product_qty,但不想重写字段(避免破坏原有功能),不知道如何合理扩展 - 使用onchange尝试从
unidades反向更新product_qty时,选中产品后订单状态会立刻变为“To finish”,且product_qty未正常更新
现有代码
from odoo import fields, models, api class MrpProduction(models.Model): _inherit='mrp.production' unidades= fields.Integer(string='Unidades', compute='_compute_unidades', readonly=False) #Field to insert "Boxes" pastones_por_unidad= fields.Integer(string='Pastones por Unidad', related='product_id.pastones_por_unidad', readonly=True) #Related "Units/Box" field # This works, to change the number of boxes based on the produc_qty introduced @api.depends('product_qty', 'pastones_por_unidad') def _compute_unidades(self): for production in self: if production.pastones_por_unidad !=0: production.unidades = production.product_qty // production.pastones_por_unidad else: production.unidades =0 # The other way around doesn't, trying to write directly on "product_qty" @api.onchange('unidades') def _onchange_product_qty(self): self.product_qty = self.unidades * self.pastones_por_unidad
解决方案
方案1:使用计算字段反向方法(推荐)
利用Odoo计算字段的inverse属性实现反向转换,无需重写product_qty,同时避免onchange触发的异常:
from odoo import fields, models, api class MrpProduction(models.Model): _inherit='mrp.production' unidades = fields.Integer( string='箱数', compute='_compute_unidades', readonly=False, store=True, # 存储字段值,减少重复计算 inverse='_inverse_unidades' # 定义反向转换方法 ) pastones_por_unidad = fields.Integer( string='每箱数量', related='product_id.pastones_por_unidad', readonly=True ) @api.depends('product_qty', 'pastones_por_unidad') def _compute_unidades(self): for production in self: if production.pastones_por_unidad != 0: production.unidades = production.product_qty // production.pastones_por_unidad else: production.unidades = 0 def _inverse_unidades(self): # 反向计算:从箱数转换为主单位数量 for production in self: # 仅当转换比例和箱数都有效时执行计算 if production.pastones_por_unidad != 0 and production.unidades is not None: new_qty = production.unidades * production.pastones_por_unidad # 仅当数值变化时更新,避免不必要的状态触发 if production.product_qty != new_qty: production.product_qty = new_qty
方案2:优化onchange方法
如果坚持使用onchange,需增加条件判断避免无效赋值,同时扩展触发条件:
from odoo import fields, models, api class MrpProduction(models.Model): _inherit='mrp.production' unidades= fields.Integer(string='箱数', compute='_compute_unidades', readonly=False) pastones_por_unidad= fields.Integer(string='每箱数量', related='product_id.pastones_por_unidad', readonly=True) @api.depends('product_qty', 'pastones_por_unidad') def _compute_unidades(self): for production in self: if production.pastones_por_unidad !=0: production.unidades = production.product_qty // production.pastones_por_unidad else: production.unidades =0 @api.onchange('unidades', 'pastones_por_unidad') def _onchange_product_qty(self): # 确保产品已选中、转换比例有效且箱数不为空 if self.pastones_por_unidad and self.unidades is not None: new_qty = self.unidades * self.pastones_por_unidad if self.product_qty != new_qty: self.product_qty = new_qty
说明
- 方案1的反向计算方法更符合Odoo的字段设计逻辑,能避免onchange可能引发的意外状态变更
- 两种方案都通过条件判断避免了无效值赋值,防止
product_qty被设为0触发订单状态异常 - 无需重写
product_qty字段,完全保留原有功能的同时实现扩展
内容的提问来源于stack exchange,提问作者abeato
相关产品推荐
相关产品推荐

