From 188a44ef2393eec853ca79b6de12c6ee696e9d60 Mon Sep 17 00:00:00 2001 From: Rad0van Date: Tue, 18 Jan 2022 22:38:27 +0100 Subject: [PATCH 1/2] [FIX] base_import_match: importing related o2m records The original code did improperly handle importing related one2many records where at best all their attribute values would get overwritten by last of them. This was caused by mapping them only by their first part. --- base_import_match/README.rst | 3 +- base_import_match/models/base.py | 47 ++++++++++--------- base_import_match/readme/CONTRIBUTORS.rst | 1 + .../static/description/index.html | 3 +- .../res_partner_email_one2many.csv | 4 ++ base_import_match/tests/test_import.py | 41 ++++++++++++++++ 6 files changed, 75 insertions(+), 24 deletions(-) create mode 100644 base_import_match/tests/import_data/res_partner_email_one2many.csv diff --git a/base_import_match/README.rst b/base_import_match/README.rst index 481fb6dd8..1f87c7b14 100644 --- a/base_import_match/README.rst +++ b/base_import_match/README.rst @@ -7,7 +7,7 @@ Base Import Match !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:40f62ca1ed4ddafbe04e1dba6fafb257e2262df0dc6dc19eda7aa8c466d9c1b0 + !! source digest: sha256:a814a82527acac6bf3fec5490bf37a35060a58c552bed21fec066ed77b7bed01 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -140,6 +140,7 @@ Contributors * Jairo Llopis * Vicent Cubells * Ernesto Tejeda +* Radovan Skolnik Maintainers ~~~~~~~~~~~ diff --git a/base_import_match/models/base.py b/base_import_match/models/base.py index e6ab20861..74ff41ed7 100644 --- a/base_import_match/models/base.py +++ b/base_import_match/models/base.py @@ -26,30 +26,33 @@ def load(self, fields, data): # Mock Odoo to believe the user is importing the ID field if "id" not in fields: fields.append("id") - import_fields.append(["id"]) # Needed to match with converted data field names - clean_fields = [f[0] for f in import_fields] for dbid, xmlid, record, info in converted_data: - row = dict(zip(clean_fields, data[info["record"]])) - match = self - if xmlid: - # Skip rows with ID, they do not need all this - row["id"] = xmlid - newdata.append(tuple(row[f] for f in clean_fields)) - continue - elif dbid: - # Find the xmlid for this dbid - match = self.browse(dbid) - else: - # Store records that match a combination - match = self.env["base_import.match"]._match_find(self, record, row) - # Give a valid XMLID to this row if a match was found - # To generate externals IDS. - match.export_data(fields) - ext_id = match.get_external_id() - row["id"] = ext_id[match.id] if match else row.get("id", "") - # Store the modified row, in the same order as fields - newdata.append(tuple(row[f] for f in clean_fields)) + # In case of one2many on empty lines one record may contain several rows + for row_index in range(info["rows"]["from"], info["rows"]["to"] + 1): + row = dict(zip(fields, data[row_index])) + match = self + if xmlid: + # Skip rows with ID, they do not need all this + row["id"] = xmlid + continue + elif dbid: + # Find the xmlid for this dbid + match = self.browse(dbid) + elif row_index == info["rows"]["from"]: + # Store records that match a combination + # But only for first row of record, + # because the rest contain one2many fields + match = self.env["base_import.match"]._match_find( + self, record, row + ) + # Give a valid XMLID to this row if a match was found + # To generate externals IDS. + match.export_data(fields) + ext_id = match.get_external_id() + row["id"] = ext_id[match.id] if match else row.get("id", "") + # Store the modified row, in the same order as fields + newdata.append(tuple(row[f] for f in fields)) # We will import the patched data to get updates on matches data = newdata # Normal method handles the rest of the job diff --git a/base_import_match/readme/CONTRIBUTORS.rst b/base_import_match/readme/CONTRIBUTORS.rst index f487f9601..964a50910 100644 --- a/base_import_match/readme/CONTRIBUTORS.rst +++ b/base_import_match/readme/CONTRIBUTORS.rst @@ -2,3 +2,4 @@ * Jairo Llopis * Vicent Cubells * Ernesto Tejeda +* Radovan Skolnik diff --git a/base_import_match/static/description/index.html b/base_import_match/static/description/index.html index c26345306..1be322516 100644 --- a/base_import_match/static/description/index.html +++ b/base_import_match/static/description/index.html @@ -367,7 +367,7 @@

Base Import Match

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:40f62ca1ed4ddafbe04e1dba6fafb257e2262df0dc6dc19eda7aa8c466d9c1b0 +!! source digest: sha256:a814a82527acac6bf3fec5490bf37a35060a58c552bed21fec066ed77b7bed01 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/server-backend Translate me on Weblate Try me on Runboat

By default, when importing data (like CSV import) with the base_import @@ -495,6 +495,7 @@

Contributors

* Jairo Llopis * Vicent Cubells * Ernesto Tejeda +
  • Radovan Skolnik <radovan@skolnik.info>
  • diff --git a/base_import_match/tests/import_data/res_partner_email_one2many.csv b/base_import_match/tests/import_data/res_partner_email_one2many.csv new file mode 100644 index 000000000..f95307cad --- /dev/null +++ b/base_import_match/tests/import_data/res_partner_email_one2many.csv @@ -0,0 +1,4 @@ +email,function,child_ids/name,child_ids/color,child_ids/email +floyd.steward34@example.com,Bug Fixer,Bart Steward,666,bart.steward@example.com +,,Lisa Steward,777,lisa.steward@example.com +,,Maggie Steward,555,maggie.steward@example.com diff --git a/base_import_match/tests/test_import.py b/base_import_match/tests/test_import.py index b234e8b60..fe779ffcb 100644 --- a/base_import_match/tests/test_import.py +++ b/base_import_match/tests/test_import.py @@ -105,3 +105,44 @@ def test_res_users_login(self): record = self._base_import_record("res.users", "res_users_login") record.do(["login", "name"], [], OPTIONS) self.assertEqual(self.env.ref("base.user_demo").name, "Demo User Changed") + + def test_res_partner_email_one2many(self): + """Change function based on email and import one2many record.""" + record = self._base_import_record("res.partner", "res_partner_email_one2many") + record.do( + [ + "email", + "function", + "child_ids/name", + "child_ids/color", + "child_ids/email", + ], + [], + OPTIONS, + ) + self.assertEqual( + self.env.ref("base.res_partner_address_4").function, "Bug Fixer" + ) + self.assertTrue( + self.env.ref("base.res_partner_address_4").child_ids, + ) + self.assertEqual( + len(self.env.ref("base.res_partner_address_4").child_ids), + 3, + ) + self.assertEqual( + set(self.env.ref("base.res_partner_address_4").mapped("child_ids.name")), + {"Bart Steward", "Lisa Steward", "Maggie Steward"}, + ) + self.assertEqual( + set(self.env.ref("base.res_partner_address_4").mapped("child_ids.email")), + { + "bart.steward@example.com", + "lisa.steward@example.com", + "maggie.steward@example.com", + }, + ) + self.assertEqual( + set(self.env.ref("base.res_partner_address_4").mapped("child_ids.color")), + {666, 777, 555}, + ) From 2d21ec816c2cd0f045f6ef0a079c7f3c72128b3d Mon Sep 17 00:00:00 2001 From: sergiocorato Date: Wed, 17 Jul 2024 14:35:04 +0200 Subject: [PATCH 2/2] [FIX] import with external id not added to newdata --- base_import_match/models/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/base_import_match/models/base.py b/base_import_match/models/base.py index 74ff41ed7..660c7c94a 100644 --- a/base_import_match/models/base.py +++ b/base_import_match/models/base.py @@ -35,6 +35,7 @@ def load(self, fields, data): if xmlid: # Skip rows with ID, they do not need all this row["id"] = xmlid + newdata.append(tuple(row[f] for f in fields)) continue elif dbid: # Find the xmlid for this dbid