From c7c90ba867fa5c228c6bb776d1262c4dc0c2cb0b Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Fri, 13 Sep 2019 14:48:04 +0200 Subject: [PATCH] [FIX] onchange_helper: Values recieved as input must be preserved. The goal of this lib is to play the onchange methods to get values for the fields not yet filled into the received list of values used to createor update a record. Therefore, the values from the user must be preserved. If we don't process on this way and you play the onchange methods on a sale.order for a new line with 'product_id' and 'product_uom_qty', the product_uom_qty will be reset to 1 when the onchange for product_id will be played and we'll lost the initial value for product_uom_qty --- onchange_helper/models/models.py | 9 ++++++++ .../tests/test_onchange_helper.py | 22 +++++-------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/onchange_helper/models/models.py b/onchange_helper/models/models.py index 5505153ec..c59265305 100644 --- a/onchange_helper/models/models.py +++ b/onchange_helper/models/models.py @@ -128,6 +128,7 @@ class Base(models.AbstractModel): This method reimplement the onchange method to be able to work on the current recordset if provided. """ + updated_values = values.copy() env = self.env if self: self.ensure_one() @@ -197,6 +198,14 @@ class Base(models.AbstractModel): dirty |= set(dirties) todo.extend(dirties) + # preserve values to update since these are the one selected + # by the user. + for f in dirties: + field = self._fields[f] + if (f in updated_values and + field.type not in ("one2many", "many2many")): + record[f] = values[f] + # prepare the result to return a dictionary with the new values for # the dirty fields result = {} diff --git a/test_onchange_helper/tests/test_onchange_helper.py b/test_onchange_helper/tests/test_onchange_helper.py index ee774e669..e123aa649 100644 --- a/test_onchange_helper/tests/test_onchange_helper.py +++ b/test_onchange_helper/tests/test_onchange_helper.py @@ -13,6 +13,7 @@ class TestOnchangeHelper(common.TransactionCase): self.Category = self.env["test_onchange_helper.category"] self.Message = self.env["test_onchange_helper.message"] self.Discussion = self.env["test_onchange_helper.discussion"] + self.maxDiff = None @contextmanager def assertNoOrmWrite(self, model): @@ -38,7 +39,7 @@ class TestOnchangeHelper(common.TransactionCase): def test_play_onchanges_many2one_new_record(self): root = self.Category.create({"name": "root"}) - values = {"name": "test", "parent": root.id, "root_categ": False} + values = {"name": "test", "parent": root.id} self.env.invalidate_all() with self.assertNoOrmWrite(self.Category): @@ -46,20 +47,10 @@ class TestOnchangeHelper(common.TransactionCase): self.assertIn("root_categ", result) self.assertEqual(result["root_categ"], root.id) - values.update(result) - values["parent"] = False - - self.env.invalidate_all() - with self.assertNoOrmWrite(self.Category): - result = self.Category.play_onchanges(values, "parent") - # since the root_categ is already False into values the field is not - # changed by the onchange - self.assertNotIn("root_categ", result) - def test_play_onchanges_many2one_existing_record(self): root = self.Category.create({"name": "root"}) - values = {"name": "test", "parent": root.id, "root_categ": False} + values = {"name": "test", "parent": root.id} self.env.invalidate_all() with self.assertNoOrmWrite(self.Category): @@ -275,15 +266,13 @@ class TestOnchangeHelper(common.TransactionCase): values = { "name": discussion.name, "moderator": demo.id, - "categories": [(4, cat.id) for cat in discussion.categories], - "messages": [(4, msg.id) for msg in discussion.messages], - "participants": [(4, usr.id) for usr in discussion.participants], - } + } self.env.invalidate_all() with self.assertNoOrmWrite(discussion): result = discussion.play_onchanges(values, "moderator") self.assertIn("participants", result) + self.assertTrue(discussion.participants) self.assertItemsEqual( result["participants"], [(5,)] + [(4, user.id) for user in discussion.participants + demo], @@ -304,7 +293,6 @@ class TestOnchangeHelper(common.TransactionCase): "categories": [(4, cat.id) for cat in discussion.categories], "messages": messages, "participants": [(4, usr.id) for usr in discussion.participants], - "message_concat": False, } with self.assertNoOrmWrite(discussion): result = discussion.play_onchanges(values, "messages")