From fbd53ad55ae19cc7b6802c5905e21b7fd6987270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Sun, 12 Mar 2023 23:42:00 +0100 Subject: [PATCH] pattern_import_export: fix o2m purge option --- pattern_import_export/demo/demo.xml | 36 +++++++++++++++ pattern_import_export/models/__init__.py | 1 + pattern_import_export/models/fields.py | 22 +++++++++ pattern_import_export/models/ir_fields.py | 5 +- .../tests/test_pattern_import.py | 46 +++++++++++++++++-- 5 files changed, 102 insertions(+), 8 deletions(-) create mode 100644 pattern_import_export/models/fields.py diff --git a/pattern_import_export/demo/demo.xml b/pattern_import_export/demo/demo.xml index 5297c3ef..d166a766 100644 --- a/pattern_import_export/demo/demo.xml +++ b/pattern_import_export/demo/demo.xml @@ -35,6 +35,15 @@ Partner with contact res.partner + + Currency + res.currency + + + Currency Rate + res.currency.rate + + @@ -44,6 +53,15 @@ + + + + + + @@ -104,5 +122,23 @@ + + rate_ids + + 3 + + + + name + + + + rate + + + diff --git a/pattern_import_export/models/__init__.py b/pattern_import_export/models/__init__.py index ba425303..c0efd423 100644 --- a/pattern_import_export/models/__init__.py +++ b/pattern_import_export/models/__init__.py @@ -8,3 +8,4 @@ from . import pattern_file from . import pattern_chunk from . import ir_attachment +from . import fields diff --git a/pattern_import_export/models/fields.py b/pattern_import_export/models/fields.py new file mode 100644 index 00000000..fa53aba1 --- /dev/null +++ b/pattern_import_export/models/fields.py @@ -0,0 +1,22 @@ +# Copyright 2023 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +from odoo import fields + +ori_write_real = fields.One2many.write_real + + +def write_real(self, records_commands_list, create=False): + if not create: + for recs, commands in records_commands_list: + if recs.env.context.get("pattern_config", {}).get("purge_one2many"): + update_ids = [cmd[1] for cmd in commands if cmd[0] == 1] + for item in recs[self.name]: + if item.id not in update_ids: + commands.append((3, item.id, 0)) + return ori_write_real(self, records_commands_list, create=create) + + +fields.One2many.write_real = write_real diff --git a/pattern_import_export/models/ir_fields.py b/pattern_import_export/models/ir_fields.py index 4add32ca..657a6970 100644 --- a/pattern_import_export/models/ir_fields.py +++ b/pattern_import_export/models/ir_fields.py @@ -155,7 +155,4 @@ def _str_to_one2many(self, model, field, records): # raising an error with the split # see original method called by super records[0][".id"] = str(records[0][".id"]) - commands, warnings = super()._str_to_one2many(model, field, records) - if self._context.get("pattern_config", {}).get("purge_one2many"): - commands.insert(0, (5, 0, 0)) - return commands, warnings + return super()._str_to_one2many(model, field, records) diff --git a/pattern_import_export/tests/test_pattern_import.py b/pattern_import_export/tests/test_pattern_import.py index db4ecd97..cebb829f 100644 --- a/pattern_import_export/tests/test_pattern_import.py +++ b/pattern_import_export/tests/test_pattern_import.py @@ -14,6 +14,10 @@ def setUpClass(cls): super().setUpClass() cls.pattern_config_m2m.export_format = "json" cls.pattern_config.export_format = "json" + cls.pattern_config_currency = cls.env.ref( + "pattern_import_export.demo_pattern_config_currency" + ) + cls.pattern_config_currency.export_format = "json" def run_pattern_file(self, pattern_file): model = self.env[pattern_file.pattern_config_id.model_id.model].with_context( @@ -331,7 +335,7 @@ def test_o2m_with_empty_value(self): self.assertEqual(partners[0].name, unique_name) self.assertEqual(partners[0].child_ids, partners[1]) - def _helper_o2m_update(self): + def _case_o2m_update_no_delete_cascade(self): unique_name = str(uuid4()) partner = self.env["res.partner"].create( { @@ -359,20 +363,54 @@ def _helper_o2m_update(self): self.assertPatternDone(pattern_file) return partner, child_1, child_2 - def test_o2m_update_with_purge(self): + def _case_o2m_update_with_delete_cascade(self): + currency = self.env.ref("base.EUR") + currency.write( + { + "rate_ids": [ + (5, 0, 0), + (0, 0, {"name": "1999-12-02", "rate": 1}), + (0, 0, {"name": "2000-01-30", "rate": 2}), + ] + } + ) + data = [ + { + ".id": currency.id, + "rate_ids|1|name#key": "1999-12-02", + "rate_ids|1|rate": 1.5, + "rate_ids|2|name#key": "2022-01-01", + "rate_ids|2|rate": 3, + } + ] + pattern_file = self.create_pattern(self.pattern_config_currency, "import", data) + self.run_pattern_file(pattern_file) + self.assertPatternDone(pattern_file) + return currency + + def test_o2m_update_with_purge_no_delete_cascade(self): self.pattern_config.purge_one2many = True - partner, child_1, child_2 = self._helper_o2m_update() + partner, child_1, child_2 = self._case_o2m_update_no_delete_cascade() self.assertEqual(len(partner.child_ids), 3) self.assertIn(child_1, partner.child_ids) self.assertNotIn(child_2, partner.child_ids) def test_o2m_update_without_purge(self): self.pattern_config.purge_one2many = False - partner, child_1, child_2 = self._helper_o2m_update() + partner, child_1, child_2 = self._case_o2m_update_no_delete_cascade() self.assertEqual(len(partner.child_ids), 4) self.assertIn(child_1, partner.child_ids) self.assertIn(child_2, partner.child_ids) + def test_o2m_update_with_purge_with_delete_cascade(self): + self.pattern_config_currency.purge_one2many = True + currency = self._case_o2m_update_with_delete_cascade() + self.assertEqual(len(currency.rate_ids), 2) + + def test_o2m_update_without_purge_with_delete_cascade(self): + currency = self._case_o2m_update_with_delete_cascade() + self.assertEqual(len(currency.rate_ids), 3) + def test_empty_m2m_with_o2m(self): unique_name = str(uuid4()) partner2_name = str(uuid4())