diff options
| -rw-r--r-- | odoo/addons/test_new_api/models/test_new_api.py | 32 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/security/ir.model.access.csv | 2 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_new_fields.py | 2 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_onchange.py | 38 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/views/test_new_api_views.xml | 26 | ||||
| -rw-r--r-- | odoo/fields.py | 5 | ||||
| -rw-r--r-- | odoo/models.py | 2 |
7 files changed, 102 insertions, 5 deletions
diff --git a/odoo/addons/test_new_api/models/test_new_api.py b/odoo/addons/test_new_api/models/test_new_api.py index 27af01e335b..2cb28702520 100644 --- a/odoo/addons/test_new_api/models/test_new_api.py +++ b/odoo/addons/test_new_api/models/test_new_api.py @@ -1147,3 +1147,35 @@ class ComputeMember(models.Model): container = self.env['test_new_api.compute.container'] for member in self: member.container_id = container.search([('name', '=', member.name)], limit=1) + + +class ComputeEditable(models.Model): + _name = _description = 'test_new_api.compute_editable' + + line_ids = fields.One2many('test_new_api.compute_editable.line', 'parent_id') + + @api.onchange('line_ids') + def _onchange_line_ids(self): + for line in self.line_ids: + # even if 'same' is not in the view, it should be the same as 'value' + line.count += line.same + + +class ComputeEditableLine(models.Model): + _name = _description = 'test_new_api.compute_editable.line' + + parent_id = fields.Many2one('test_new_api.compute_editable') + value = fields.Integer() + same = fields.Integer(compute='_compute_same', store=True) + edit = fields.Integer(compute='_compute_edit', store=True, readonly=False) + count = fields.Integer() + + @api.depends('value') + def _compute_same(self): + for line in self: + line.same = line.value + + @api.depends('value') + def _compute_edit(self): + for line in self: + line.edit = line.value diff --git a/odoo/addons/test_new_api/security/ir.model.access.csv b/odoo/addons/test_new_api/security/ir.model.access.csv index 71a309d5d1a..021d7127b05 100644 --- a/odoo/addons/test_new_api/security/ir.model.access.csv +++ b/odoo/addons/test_new_api/security/ir.model.access.csv @@ -66,3 +66,5 @@ access_test_new_api_model_shared_cache_compute_parent,access_test_new_api.model_ access_test_new_api_model_shared_cache_compute_line,access_test_new_api.model_shared_cache_compute_line,model_test_new_api_model_shared_cache_compute_line,,1,1,1,1 access_test_new_api_compute_container,access_test_new_api_compute_container,model_test_new_api_compute_container,,1,1,1,1 access_test_new_api_compute_member,access_test_new_api_compute_member,model_test_new_api_compute_member,,1,1,1,1 +access_test_new_api_compute_editable,access_test_new_api_compute_editable,model_test_new_api_compute_editable,,1,1,1,1 +access_test_new_api_compute_editable_line,access_test_new_api_compute_editable_line,model_test_new_api_compute_editable_line,,1,1,1,1 diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 9986cd674c3..4c9aaf00f5e 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -1345,7 +1345,7 @@ class TestFields(TransactionCaseWithUserDemo): new_origin = Model.new({'name': 'Bar'}, origin=real_record) new_record = Model.new({'name': 'Baz'}) self.assertEqual(real_record.display_name, 'Foo') - self.assertEqual(new_origin.display_name, 'Foo') + self.assertEqual(new_origin.display_name, 'Bar') self.assertEqual(new_record.display_name, 'Baz') # computed stored field with recomputation: always computed diff --git a/odoo/addons/test_new_api/tests/test_onchange.py b/odoo/addons/test_new_api/tests/test_onchange.py index 38c7b8be531..1b424777bc0 100644 --- a/odoo/addons/test_new_api/tests/test_onchange.py +++ b/odoo/addons/test_new_api/tests/test_onchange.py @@ -4,7 +4,7 @@ from unittest.mock import patch from odoo.addons.base.tests.common import SavepointCaseWithUserDemo -from odoo.tests import common +from odoo.tests import common, Form def strip_prefix(prefix, names): size = len(prefix) @@ -751,3 +751,39 @@ class TestComputeOnchange(common.TransactionCase): with form.child_ids.edit(2) as line: line.cost = 30 self.assertEqual(form.cost, 61) + + def test_onchange_editable_compute_one2many(self): + # create a record with a computed editable field ('edit') on lines + record = self.env['test_new_api.compute_editable'].create({'line_ids': [(0, 0, {'value': 7})]}) + record.flush() + line = record.line_ids + self.assertRecordValues(line, [{'value': 7, 'edit': 7, 'count': 0}]) + + # retrieve the onchange spec for calling 'onchange' + spec = Form(record)._view['onchange'] + + # The onchange on 'line_ids' should increment 'count' and keep the value + # of 'edit' (this field should not be recomputed), whatever the order of + # the fields in the dictionary. This ensures that the value set by the + # user on a computed editable field on a line is not lost. + line_ids = [ + (1, line.id, {'value': 8, 'edit': 9, 'count': 0}), + (0, 0, {'value': 8, 'edit': 9, 'count': 0}), + ] + result = record.onchange({'line_ids': line_ids}, 'line_ids', spec) + expected = {'value': { + 'line_ids': [ + (5,), + (1, line.id, {'value': 8, 'edit': 9, 'count': 8}), + (0, 0, {'value': 8, 'edit': 9, 'count': 8}), + ], + }} + self.assertEqual(result, expected) + + # change dict order in lines, and try again + line_ids = [ + (op, id_, dict(reversed(list(vals.items())))) + for op, id_, vals in line_ids + ] + result = record.onchange({'line_ids': line_ids}, 'line_ids', spec) + self.assertEqual(result, expected) diff --git a/odoo/addons/test_new_api/views/test_new_api_views.xml b/odoo/addons/test_new_api/views/test_new_api_views.xml index cd995456def..2595be58e6c 100644 --- a/odoo/addons/test_new_api/views/test_new_api_views.xml +++ b/odoo/addons/test_new_api/views/test_new_api_views.xml @@ -341,5 +341,31 @@ </form> </field> </record> + + <!-- compute_editable view --> + <record id="compute_editable_form" model="ir.ui.view"> + <field name="name">test_new_api.compute_editable.form</field> + <field name="model">test_new_api.compute_editable</field> + <field name="arch" type="xml"> + <form> + <sheet> + <field name="line_ids" mode="tree"> + <tree editable="bottom"> + <field name="value"/> + <field name="edit"/> + <field name="count"/> + </tree> + <form> + <!-- this view makes sure that field "same" is not considered --> + <field name="value"/> + <field name="edit"/> + <field name="count"/> + </form> + </field> + </sheet> + </form> + </field> + </record> + </data> </odoo> diff --git a/odoo/fields.py b/odoo/fields.py index 603e2a90a3e..8ddc0c1b422 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -956,7 +956,8 @@ class Field(MetaField('DummyField', (object,), {})): # not stored and not computed -> default # # on a new record w/ origin: - # stored -> fetch from origin (computation done above) + # stored and not (computed and readonly) -> fetch from origin + # stored and computed and readonly -> compute # not stored and computed -> compute # not stored and not computed -> default # @@ -982,7 +983,7 @@ class Field(MetaField('DummyField', (object,), {})): ])) value = env.cache.get(record, self) - elif self.store and record._origin: + elif self.store and record._origin and not (self.compute and self.readonly): # new record with origin: fetch from origin value = self.convert_to_cache(record._origin[self.name], record) env.cache.set(record, self, value) diff --git a/odoo/models.py b/odoo/models.py index 23e51ed9be0..1102cd93f7f 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -6148,7 +6148,7 @@ Fields: # store changed values in cache; also trigger recomputations based on # subfields (e.g., line.a has been modified, line.b is computed stored # and depends on line.a, but line.b is not in the form view) - record._update_cache(changed_values, validate=True) + record._update_cache(changed_values, validate=False) # update snapshot0 with changed values for name in names: |
