1

I have these two fields.

'name'              : fields.char('Name'),
'addresses'         : fields.one2many('res.partner.address', 'partner','Addresses'),

This function:

def addresses_change(self, cr, uid, ids, name, addresses, context=None):
        value = {}

        new_addresses = []
        address_pool = self.pool.get('res.partner.address')
        for address in address_pool.browse(cr, uid, addresses[0][2], context=context):
            new_addresses.append((1,address.id,{'street':'wall street','zip':'7777','partner': ids[0],'active':True}))

        value.update(name='whatever')
        value.update(addresses=new_addresses)
        return {'value':value}

And these view fields:

<field name="name" on_change="addresses_change(name,addresses)"/>
<field name="addresses" on_change="addresses_change(name,addresses)"/>

Now when I change name, both name and addresses are updated. But when I change addresses its own value isn't updated but the name is updated. So this bizarre behavior affects only one2many fields. Why is this?

And how do I add on_change event to one2many fields that can update its own value?

EDIT: I found out that this is might be a limitation in odoo, have they fixed this issue? Link to the issue

William Wino
  • 3,599
  • 7
  • 38
  • 61
  • That limitation is with the `@api.onchange` decorator in Odoo v8. What version are you using? I don't know if OpenERP 7 has the same limitation. I think you can use a link to update all the table like in the sale order lines in the quotations – ChesuCR Sep 01 '15 at 10:26
  • I use Odoo v8, and I've tried both @api.onchange and on_change attribute method. Both don't work. Yea I'm thinking of that too, but that would be a hassle for the user. I want it to execute automatically, any workaround? – William Wino Sep 01 '15 at 10:30
  • I've been following the issue for months, I don't think there is an easy solution – ChesuCR Sep 01 '15 at 10:33
  • I don't understand, this is so simple, they could've just treated the one2many field on_change function as though it is called from another field AFTER they do whatever they wanna do on the client side. After all we expect the on_change to be executed AFTER everything else is done right? This is probably the easiest issue they could fix. – William Wino Sep 01 '15 at 13:02
  • It seems that somebody created a [pull request with the changes](https://github.com/odoo/odoo/issues/2693#issuecomment-142571564) – ChesuCR Sep 23 '15 at 11:34

2 Answers2

3

Apply the following patch on the lastest version of models.py (the version commited on Tue Aug 4 15:22:33 2015 +0200):

--- a/openerp/models.py
+++ b/openerp/models.py
@@ -5897,9 +5897,9 @@ class BaseModel(object):

         # At the moment, the client does not support updates on a *2many field
         # while this one is modified by the user.
-        if field_name and not isinstance(field_name, list) and \
-                self._fields[field_name].type in ('one2many', 'many2many'):
-            result['value'].pop(field_name, None)
+        ## if field_name and not isinstance(field_name, list) and \
+        ##         self._fields[field_name].type in ('one2many', 'many2many'):
+        ##     result['value'].pop(field_name, None)

         return result

In other words, just comment the lines 5900 to 5902 of the openerp/models.py file.

Of course, there is a big disadvantage with this solution - you need to apply the patch every time the models.py file is updated in the Odoo distribution you use.

There is a considerable risk too - they say that the Web client is not dealing well with one2many and many2many fields updated in onchange event. I did not discover any problem with that right now but I'll continue to test my development installation of Odoo...

Andrei Boyanov
  • 2,309
  • 15
  • 18
0

I created a Pull Request to odoo version 8

https://github.com/odoo/odoo/issues/2693

with the changes mentioned in the issues and here

    if field_name and not isinstance(field_name, list) and \
-                self._fields[field_name].type in ('one2many', 'many2many'):
+        if field_name and not isinstance(field_name, list):