diff options
| author | Xavier Morel <xmo@odoo.com> | 2020-07-17 08:38:21 +0000 |
|---|---|---|
| committer | Raphael Collet <rco@odoo.com> | 2020-07-20 11:42:58 +0000 |
| commit | b3761a8cba6f24bbcb4b35f14e076965d1210f69 (patch) | |
| tree | e610ddb26702da9f7d822e19ae2fabc02137c1f1 | |
| parent | 8f09ef294a6aa7a845114474658cf0b4f32c46e1 (diff) | |
[FIX] core: fix handling of removals in sub-o2m
Issue is specifically in the case of an onchange removing a record in
an o2m in an o2m (so a sub-o2m) if loading an *existing* record in the
SSF: since the server pretty much only returns a REMOVE_ALL followed
by the records to keep or create, conserving the removal information
requires diffing the value currently stored in the form and the result
fo the onchange.
Diff which was properly done for top-level o2ms, but not for the ones
below that (apparently forgot this bit when improving support for
nested o2ms earlier this year).
X-original-commit: 177d009541cca589c6ebb85fc051b893ec001536
| -rw-r--r-- | odoo/addons/test_testing_utilities/ir.model.access.csv | 1 | ||||
| -rw-r--r-- | odoo/addons/test_testing_utilities/models.py | 14 | ||||
| -rw-r--r-- | odoo/addons/test_testing_utilities/tests/test_form_impl.py | 26 | ||||
| -rw-r--r-- | odoo/tests/common.py | 2 |
4 files changed, 42 insertions, 1 deletions
diff --git a/odoo/addons/test_testing_utilities/ir.model.access.csv b/odoo/addons/test_testing_utilities/ir.model.access.csv index c060e4b77e9..5f7c8a1777c 100644 --- a/odoo/addons/test_testing_utilities/ir.model.access.csv +++ b/odoo/addons/test_testing_utilities/ir.model.access.csv @@ -20,6 +20,7 @@ access_test_testing_utilities_onchange_count_sub,access_test_testing_utilities_o access_o2m_readonly_subfield_parent,access_o2m_readonly_subfield_parent,model_o2m_readonly_subfield_parent,,1,1,1,1 access_o2m_readonly_subfield_child,access_o2m_readonly_subfield_child,model_o2m_readonly_subfield_child,,1,1,1,1 access_test_testing_utilities_req_bool,access_test_testing_utilities_req_bool,model_test_testing_utilities_req_bool,,1,0,0,0 +access_o2m_changes_parent,access_o2m_changes_parent,model_o2m_changes_parent,base.group_user,1,0,0,0 access_o2m_changes_children,access_o2m_changes_children,model_o2m_changes_children,base.group_user,1,0,0,0 access_o2m_changes_children_lines,access_o2m_changes_children_lines,model_o2m_changes_children_lines,base.group_user,1,0,0,0 access_ttu_product,access_ttu_product,model_ttu_product,base.group_user,1,0,0,0 diff --git a/odoo/addons/test_testing_utilities/models.py b/odoo/addons/test_testing_utilities/models.py index cf2b4f0e8c6..8796526653a 100644 --- a/odoo/addons/test_testing_utilities/models.py +++ b/odoo/addons/test_testing_utilities/models.py @@ -280,12 +280,26 @@ class ReqBool(models.Model): f_bool = fields.Boolean(required=True) +class O2MChangesParent(models.Model): + _name = _description = 'o2m_changes_parent' + + name = fields.Char() + line_ids = fields.One2many('o2m_changes_children', 'parent_id') + + @api.onchange('name') + def _onchange_name(self): + for line in self.line_ids: + line.line_ids = [(2, l.id, False) for l in line.line_ids] + [ + (0, 0, {'v': 0, 'vv': 0}) + ] + class O2MChangesChildren(models.Model): _name = _description = 'o2m_changes_children' name = fields.Char() v = fields.Integer() line_ids = fields.One2many('o2m_changes_children.lines', 'parent_id') + parent_id = fields.Many2one('o2m_changes_parent') @api.onchange('v') def _onchange_v(self): diff --git a/odoo/addons/test_testing_utilities/tests/test_form_impl.py b/odoo/addons/test_testing_utilities/tests/test_form_impl.py index 6e108b43fb1..af49d27cbe5 100644 --- a/odoo/addons/test_testing_utilities/tests/test_form_impl.py +++ b/odoo/addons/test_testing_utilities/tests/test_form_impl.py @@ -667,6 +667,32 @@ class TestNestedO2M(TransactionCase): form.qty_producing = 2 form.save() + def test_remove(self): + """ onchanges can remove o2m records which haven't been loaded yet due + to lazy loading of o2ms. The removal information should still be + retained, otherwise due to the stateful update system we end up + retaining records we don't even know exist. + """ + # create structure with sub-sub-children + r = self.env['o2m_changes_parent'].create({ + 'name': "A", + 'line_ids': [ + (0, 0, { + 'name': 'line 1', + 'v': 42, + 'line_ids': [(0, 0, {'v': 1, 'vv': 1})], + }) + ] + }) + + with Form(r) as f: + f.name = 'B' + + self.assertEqual(len(r.line_ids), 1) + self.assertEqual(len(r.line_ids.line_ids), 1) + self.assertEqual(r.line_ids.line_ids.v, 0) + self.assertEqual(r.line_ids.line_ids.vv, 0) + class TestEdition(TransactionCase): """ These use the context manager form as we don't need the record post-save (we already have it) and it's easier to see what bits act on diff --git a/odoo/tests/common.py b/odoo/tests/common.py index dc557682709..f5a83487cf1 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -2074,7 +2074,7 @@ class Form(object): stored = UpdateDict(record_to_values(subfields, record)) updates = ( - (k, self._cleanup_onchange(subfields[k], v, None)) + (k, self._cleanup_onchange(subfields[k], v, stored.get(k))) for k, v in command[2].items() if k in subfields ) |
