You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo MRP模块product_qty字段扩展:双单位转换异常问题

生产订单双计量单位数量输入问题解决

需求与现状

需要在创建生产订单时支持两种数量输入方式:

  • 常规方式:在原有product_qty字段输入主计量单位(如“个”)的数量
  • 辅助方式:新增字段输入辅助计量单位(如“箱”)的数量,自动转换为主单位数量并填充至product_qty,转换比例随产品动态变化

已完成的开发:

  • 在产品模型新增转换比例字段
  • 在mrp.production模型添加关联字段pastones_por_unidad(关联产品的转换比例),新增辅助数量字段unidades
  • 已实现从product_qty到unidades的正向转换逻辑

遇到的问题

  1. 希望通过计算字段或onchange更新product_qty,但不想重写字段(避免破坏原有功能),不知道如何合理扩展
  2. 使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:13:17