如何 return 字典值与 api.onchange

how to return dictionary value with api.onchange

我想要 return hpp_line table 中的 BoM 材料,@api.onchange, 不幸的是,我遇到了一些错误。这是我在 paket.py 文件

上的代码
from odoo import models, fields, api
class Paket(models.Model):
   _name = 'paket.perjalanan'
.....
equipment_id = fields.Many2one('product.product', string='Package')
hpp_line = fields.One2many('hpp.line', 'paket_id', string='HPP Line', readonly=True)
.....
@api.onchange('equipment_id','hpp_line')
def _select_bom_list(self):
    for x in self.equipment_id.product_tmpl_id.bom_ids.bom_line_ids:
        subtotal = x.product_qty * x.product_id.product_tmpl_id.list_price          

        return {
            'value' : {
                'hpp_line' : {                      
                    # 'paket_id' : self.hpp_line.id,
                    'product_id' : x.product_id.id,
                    'product_qty' : x.product_qty,
                    'product_uom_id' : x.product_uom_id.name,
                    'unit_price' : x.product_id.product_tmpl_id.list_price,
                    'subtotal' : subtotal
                }
            }
        }   

这是我的 hpp_line.py 文件

class HppLine(models.Model):
   _name = 'hpp.line'

   paket_id = fields.Many2one('paket.perjalanan')
   product_id = fields.Char(string='Produk')
   product_qty = fields.Integer(string='QTY', readonly=True)
   product_uom_id = fields.Char(string='UoM')
   unit_price = fields.Integer(string='Unit Price', readonly=True)
   subtotal = fields.Integer(string='Sub Total', readonly=True, store=True)

这也是我的 xml 代码

               <page string="HPP Lines">
                <field name='hpp_line'>
                  <tree>
                    <field name='product_id'/>
                    <field name='product_qty'/>
                    <!-- <field name='product_uom_id'/> -->
                    <field name='unit_price'/>
                    <field name='subtotal'/>
                  </tree>
                </field>
              </page>

所以这是条件,当我更改 equipment_id 时,hpp_line 自动 return 它是 bom_line_ids in mrp.bom.line

但我收到这样的错误消息

Traceback (most recent call last):


 File "/home/odoo/odoo/odoo.10/odoo/http.py", line 642, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "/home/odoo/odoo/odoo.10/odoo/http.py", line 684, in dispatch
    result = self._call_function(**self.params)
  File "/home/odoo/odoo/odoo.10/odoo/http.py", line 334, in _call_function
    return checked_call(self.db, *args, **kwargs)
  File "/home/odoo/odoo/odoo.10/odoo/service/model.py", line 101, in wrapper
    return f(dbname, *args, **kwargs)
  File "/home/odoo/odoo/odoo.10/odoo/http.py", line 327, in checked_call
    result = self.endpoint(*a, **kw)
  File "/home/odoo/odoo/odoo.10/odoo/http.py", line 942, in __call__
    return self.method(*args, **kw)
  File "/home/odoo/odoo/odoo.10/odoo/http.py", line 507, in response_wrap
    response = f(*args, **kw)
  File "/home/odoo/odoo/addons/travel/web/controllers/main.py", line 895, in call_kw
    return self._call_kw(model, method, args, kwargs)
  File "/home/odoo/odoo/addons/travel/web/controllers/main.py", line 887, in _call_kw
    return call_kw(request.env[model], method, args, kwargs)
  File "/home/odoo/odoo/odoo.10/odoo/api.py", line 689, in call_kw
    return call_kw_multi(method, model, args, kwargs)
  File "/home/odoo/odoo/odoo.10/odoo/api.py", line 680, in call_kw_multi
    result = method(recs, *args, **kwargs)
  File "/home/odoo/odoo/odoo.10/odoo/models.py", line 5522, in onchange
    record._onchange_eval(name, field_onchange[name], result)
  File "/home/odoo/odoo/odoo.10/odoo/models.py", line 5421, in _onchange_eval
    process(method_res)
  File "/home/odoo/odoo/odoo.10/odoo/models.py", line 5400, in process
    self.update({key: val for key, val in res['value'].iteritems() if key in self._fields})
  File "/home/odoo/odoo/odoo.10/odoo/models.py", line 5042, in update
    record[name] = value
  File "/home/odoo/odoo/odoo.10/odoo/models.py", line 5245, in __setitem__
    return self._fields[key].__set__(self, value)
  File "/home/odoo/odoo/odoo.10/odoo/fields.py", line 933, in __set__
    value = self.convert_to_cache(value, record)
  File "/home/odoo/odoo/odoo.10/odoo/fields.py", line 2064, in convert_to_cache
    raise ValueError("Wrong value for %s: %s" % (self, value))
ValueError: Wrong value for paket.perjalanan.hpp_line: {'product_uom_id': u'kg', 'subtotal': 100.0, 'product_id': 38, 'unit_price': 100.0, 'product_qty': 1.0}

问题是 hpp_line 是一个 o2m 字段,因此您需要以 ORM 写入格式为 o2m 和 m2m 命令操作写入值。

如果你想添加一个新行,你可以这样做:

@api.onchange('equipment_id','hpp_line')
def _select_bom_list(self):
    hpp_value = []
    for x in self.equipment_id.product_tmpl_id.bom_ids.bom_line_ids:
        hpp_value.append(
            (0, 0, {
                'product_id': x.product_id.id,
                'product_qty': x.product_qty,
                'product_uom_id': x.product_uom_id.name,
                'unit_price': x.product_id.product_tmpl_id.list_price,
                'subtotal': x.product_qty * x.product_id.product_tmpl_id.list_price
            })
        )

    return {
        'value' : {
            'hpp_line': hpp_value
        }
    } 
@api.onchange('equipment_id')
def _bom_selection(self):
    value = {
        'value' : {
            'hpp_line' : []
        }       
    }
    for x in self.equipment_id.product_tmpl_id.bom_ids.bom_line_ids:
        subtotal = x.product_qty * x.product_id.product_tmpl_id.list_price  
        listing = [
            (0,0,{
                'product_id' : x.product_id.id,
                'product_qty' : x.product_qty,
                'unit_price' : x.product_id.product_tmpl_id.list_price,
                'subtotal' : subtotal
            })                      
        ]

        value['value'].setdefault('hpp_line').append(listing)

    return value

我尝试了不同的方式,因为我不知道如何有效地循环列表