summaryrefslogtreecommitdiff
path: root/odoo
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2020-07-17 08:38:21 +0000
committerRaphael Collet <rco@odoo.com>2020-07-20 11:42:58 +0000
commitb3761a8cba6f24bbcb4b35f14e076965d1210f69 (patch)
treee610ddb26702da9f7d822e19ae2fabc02137c1f1 /odoo
parent8f09ef294a6aa7a845114474658cf0b4f32c46e1 (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
Diffstat (limited to 'odoo')
-rw-r--r--odoo/addons/test_testing_utilities/ir.model.access.csv1
-rw-r--r--odoo/addons/test_testing_utilities/models.py14
-rw-r--r--odoo/addons/test_testing_utilities/tests/test_form_impl.py26
-rw-r--r--odoo/tests/common.py2
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
)