From 5d9ab196fd8c485c38cdcf1fe6a86090b9e84201 Mon Sep 17 00:00:00 2001 From: ernesto Date: Fri, 8 Feb 2019 09:26:42 -0500 Subject: [PATCH] [MIG] base_import_match: Migration to 12.0 [UPD] README.rst [UPD] Update base_import_match.pot --- base_import_match/README.rst | 73 ++- base_import_match/__init__.py | 1 - base_import_match/__manifest__.py | 6 +- base_import_match/data/base_import_match.xml | 6 +- base_import_match/demo/base_import_match.xml | 10 +- base_import_match/i18n/base_import_match.pot | 88 +-- base_import_match/models/__init__.py | 1 - base_import_match/models/base.py | 9 +- base_import_match/models/base_import.py | 2 +- base_import_match/readme/CONFIGURE.rst | 16 + base_import_match/readme/CONTRIBUTORS.rst | 4 + base_import_match/readme/DESCRIPTION.rst | 46 ++ base_import_match/readme/ROADMAP.rst | 2 + base_import_match/readme/USAGE.rst | 5 + .../static/description/index.html | 511 ++++++++++++++++++ base_import_match/tests/__init__.py | 1 - .../tests/import_data/res_partner_email.csv | 2 +- .../tests/import_data/res_partner_name.csv | 2 +- .../res_partner_parent_name_is_company.csv | 2 +- .../tests/import_data/res_partner_vat.csv | 2 +- base_import_match/tests/test_import.py | 23 +- .../views/base_import_match_view.xml | 2 +- 22 files changed, 715 insertions(+), 99 deletions(-) create mode 100644 base_import_match/readme/CONFIGURE.rst create mode 100644 base_import_match/readme/CONTRIBUTORS.rst create mode 100644 base_import_match/readme/DESCRIPTION.rst create mode 100644 base_import_match/readme/ROADMAP.rst create mode 100644 base_import_match/readme/USAGE.rst create mode 100644 base_import_match/static/description/index.html diff --git a/base_import_match/README.rst b/base_import_match/README.rst index c11ff80bb..fde91affc 100644 --- a/base_import_match/README.rst +++ b/base_import_match/README.rst @@ -1,11 +1,30 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 - ================= Base Import Match ================= +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--backend-lightgray.png?logo=github + :target: https://github.com/OCA/server-backend/tree/12.0/base_import_match + :alt: OCA/server-backend +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-backend-12-0/server-backend-12-0-base_import_match + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/253/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + By default, when importing data (like CSV import) with the ``base_import`` module, Odoo follows this rule: @@ -53,6 +72,11 @@ By default 2 rules are installed for production instances: In demo instances there are more examples. +**Table of contents** + +.. contents:: + :local: + Configuration ============= @@ -82,11 +106,7 @@ To use this module, you need to: #. Go to any list view. #. Press *Import* and follow the import procedure as usual. -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/149/10.0 - -Known Issues / Roadmap +Known issues / Roadmap ====================== * Add a setting to throw an error when multiple matches are found, instead of @@ -95,31 +115,42 @@ Known Issues / Roadmap Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. In case of trouble, please -check there if your issue has already been reported. If you spotted it first, -help us smashing it by providing a detailed and welcomed feedback. +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* Tecnativa + Contributors ------------- +~~~~~~~~~~~~ + +* `Tecnativa `_: + * Jairo Llopis + * Vicent Cubells + * Ernesto Tejeda -* Jairo Llopis -* Vicent Cubells +Maintainers +~~~~~~~~~~~ -Maintainer ----------- +This module is maintained by the OCA. .. image:: https://odoo-community.org/logo.png :alt: Odoo Community Association :target: https://odoo-community.org -This module is maintained by the OCA. - OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/server-backend `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_import_match/__init__.py b/base_import_match/__init__.py index 197214cdd..4724f5f1e 100644 --- a/base_import_match/__init__.py +++ b/base_import_match/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis # Copyright 2016 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/base_import_match/__manifest__.py b/base_import_match/__manifest__.py index a9068280b..2cc6afe6a 100644 --- a/base_import_match/__manifest__.py +++ b/base_import_match/__manifest__.py @@ -1,15 +1,13 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis # Copyright 2016 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Base Import Match", "summary": "Try to avoid duplicates before importing", - "version": "10.0.1.0.0", + "version": "12.0.1.0.0", "category": "Tools", "website": "https://tecnativa.com", - "author": "Grupo ESOC Ingeniería de Servicios," - "Tecnativa, " + "author": "Tecnativa, " "Odoo Community Association (OCA)", "license": "AGPL-3", "application": False, diff --git a/base_import_match/data/base_import_match.xml b/base_import_match/data/base_import_match.xml index b2995871b..9cc7f91e4 100644 --- a/base_import_match/data/base_import_match.xml +++ b/base_import_match/data/base_import_match.xml @@ -11,11 +11,11 @@ - + - + True True @@ -27,7 +27,7 @@ - + diff --git a/base_import_match/demo/base_import_match.xml b/base_import_match/demo/base_import_match.xml index 4e9af7f42..4125a9d0f 100644 --- a/base_import_match/demo/base_import_match.xml +++ b/base_import_match/demo/base_import_match.xml @@ -11,15 +11,15 @@ - + - + - + @@ -29,7 +29,7 @@ - + @@ -39,7 +39,7 @@ - + diff --git a/base_import_match/i18n/base_import_match.pot b/base_import_match/i18n/base_import_match.pot index 6816ab933..fc8871333 100644 --- a/base_import_match/i18n/base_import_match.pot +++ b/base_import_match/i18n/base_import_match.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 10.0\n" +"Project-Id-Version: Odoo Server 12.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: <>\n" "Language-Team: \n" @@ -14,19 +14,24 @@ msgstr "" "Plural-Forms: \n" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_conditional +#: model:ir.model,name:base_import_match.model_base +msgid "Base" +msgstr "" + +#. module: base_import_match +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__conditional msgid "Conditional" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_create_uid -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_create_uid +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__create_uid +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__create_uid msgid "Created by" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_create_date -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_create_date +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__create_date +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__create_date msgid "Created on" msgstr "" @@ -36,23 +41,23 @@ msgid "Deduplicate settings prior to CSV imports." msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_display_name -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_display_name +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__display_name +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__display_name msgid "Display Name" msgstr "" #. module: base_import_match -#: model:ir.model.fields,help:base_import_match.field_base_import_match_field_conditional +#: model:ir.model.fields,help:base_import_match.field_base_import_match_field__conditional msgid "Enable if you want to use this field only in some conditions." msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_field_id +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__field_id msgid "Field" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_name +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__name msgid "Field Name" msgstr "" @@ -62,99 +67,98 @@ msgid "Field import match definition" msgstr "" #. module: base_import_match -#: model:ir.model.fields,help:base_import_match.field_base_import_match_field_field_id +#: model:ir.model.fields,help:base_import_match.field_base_import_match_field__field_id msgid "Field that will be part of an unique key." msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_ids +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__field_ids msgid "Fields" msgstr "" #. module: base_import_match -#: model:ir.model.fields,help:base_import_match.field_base_import_match_field_ids +#: model:ir.model.fields,help:base_import_match.field_base_import_match__field_ids msgid "Fields that will define an unique key." msgstr "" #. module: base_import_match -#: model:ir.ui.view,arch_db:base_import_match.match_search_view +#: model_terms:ir.ui.view,arch_db:base_import_match.match_search_view msgid "Group By" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_id -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_id +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__id +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__id msgid "ID" msgstr "" #. module: base_import_match -#: model:ir.model.fields,help:base_import_match.field_base_import_match_field_imported_value +#: model:ir.model.fields,help:base_import_match.field_base_import_match_field__imported_value msgid "If the imported value is not this, the whole matching rule will be discarded. Be careful, this data is always treated as a string, and comparison is case-sensitive so if you set 'True', it will NOT match '1' nor 'true', only EXACTLY 'True'." msgstr "" #. module: base_import_match #: model:ir.actions.act_window,name:base_import_match.match_action #: model:ir.ui.menu,name:base_import_match.match_menu -#: model:ir.ui.view,arch_db:base_import_match.match_form_view -#: model:ir.ui.view,arch_db:base_import_match.match_search_view -#: model:ir.ui.view,arch_db:base_import_match.match_tree_view +#: model_terms:ir.ui.view,arch_db:base_import_match.match_form_view +#: model_terms:ir.ui.view,arch_db:base_import_match.match_search_view +#: model_terms:ir.ui.view,arch_db:base_import_match.match_tree_view msgid "Import Match" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_imported_value -msgid "Imported value" +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__imported_value +msgid "Imported Value" msgstr "" #. module: base_import_match -#: model:ir.model.fields,help:base_import_match.field_base_import_match_field_model_id -#: model:ir.model.fields,help:base_import_match.field_base_import_match_model_id +#: model:ir.model.fields,help:base_import_match.field_base_import_match__model_id +#: model:ir.model.fields,help:base_import_match.field_base_import_match_field__model_id msgid "In this model you will apply the match." msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match___last_update -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field___last_update +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match____last_update +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field____last_update msgid "Last Modified on" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_write_uid -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_write_uid +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__write_uid +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__write_uid msgid "Last Updated by" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_write_date -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_write_date +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__write_date +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__write_date msgid "Last Updated on" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_match_id +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__match_id msgid "Match" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field_model_id -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_model_id -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_model_name -#: model:ir.ui.view,arch_db:base_import_match.match_search_view +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__model_id +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_field__model_id +#: model_terms:ir.ui.view,arch_db:base_import_match.match_search_view msgid "Model" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_name -msgid "Name" +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__model_name +msgid "Model name" msgstr "" #. module: base_import_match -#: model:ir.model.fields,field_description:base_import_match.field_base_import_match_sequence -msgid "Sequence" +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__name +msgid "Name" msgstr "" #. module: base_import_match -#: model:ir.model,name:base_import_match.model_base -msgid "base" +#: model:ir.model.fields,field_description:base_import_match.field_base_import_match__sequence +msgid "Sequence" msgstr "" diff --git a/base_import_match/models/__init__.py b/base_import_match/models/__init__.py index 45ac4f350..09759b3ad 100644 --- a/base_import_match/models/__init__.py +++ b/base_import_match/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis # Copyright 2016 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/base_import_match/models/base.py b/base_import_match/models/base.py index 62dff40bf..55bb21c02 100644 --- a/base_import_match/models/base.py +++ b/base_import_match/models/base.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Jairo Llopis # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import api, models @@ -20,7 +19,8 @@ class Base(models.AbstractModel): if self.env["base_import.match"]._usable_rules(self._name, fields): newdata = list() # Data conversion to ORM format - import_fields = map(models.fix_import_export_id_paths, fields) + import_fields = list( + map(models.fix_import_export_id_paths, fields)) converted_data = self._convert_records( self._extract_records(import_fields, data)) # Mock Odoo to believe the user is importing the ID field @@ -44,7 +44,10 @@ class Base(models.AbstractModel): match = self.env["base_import.match"]._match_find( self, record, row) # Give a valid XMLID to this row if a match was found - row["id"] = (match._BaseModel__export_xml_id() + # 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", u"")) # Store the modified row, in the same order as fields newdata.append(tuple(row[f] for f in clean_fields)) diff --git a/base_import_match/models/base_import.py b/base_import_match/models/base_import.py index 9350ce5ab..e07e6cfca 100644 --- a/base_import_match/models/base_import.py +++ b/base_import_match/models/base_import.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis # Copyright 2016 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). @@ -26,6 +25,7 @@ class BaseImportMatch(models.Model): domain=[("transient", "=", False)], help="In this model you will apply the match.") model_name = fields.Char( + string="Model name", related="model_id.model", store=True, index=True) diff --git a/base_import_match/readme/CONFIGURE.rst b/base_import_match/readme/CONFIGURE.rst new file mode 100644 index 000000000..1fd3de060 --- /dev/null +++ b/base_import_match/readme/CONFIGURE.rst @@ -0,0 +1,16 @@ +To configure this module, you need to: + +#. Go to *Settings > Technical > Database Structure > Import Match*. +#. *Create*. +#. Choose a *Model*. +#. Choose the *Fields* that conform a unique key in that model. +#. If the rule must be used only for certain imported values, check + *Conditional* and enter the **exact string** that is going to be imported + in *Imported value*. + + #. Keep in mind that the match here is evaluated as a case sensitive + **text string** always. If you enter e.g. ``True``, it will match that + string, but will not match ``1`` or ``true``. +#. *Save*. + +In that list view, you can sort rules by drag and drop. diff --git a/base_import_match/readme/CONTRIBUTORS.rst b/base_import_match/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..f487f9601 --- /dev/null +++ b/base_import_match/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* `Tecnativa `_: + * Jairo Llopis + * Vicent Cubells + * Ernesto Tejeda diff --git a/base_import_match/readme/DESCRIPTION.rst b/base_import_match/readme/DESCRIPTION.rst new file mode 100644 index 000000000..ffaeade95 --- /dev/null +++ b/base_import_match/readme/DESCRIPTION.rst @@ -0,0 +1,46 @@ +By default, when importing data (like CSV import) with the ``base_import`` +module, Odoo follows this rule: + +- If you import the XMLID of a record, make an **update**. +- If you do not, **create** a new record. + +This module allows you to set additional rules to match if a given import is an +update or a new record. + +This is useful when you need to sync heterogeneous databases, and the field you +use to match records in those databases with Odoo's is not the XMLID but the +name, VAT, email, etc. + +After installing this module, the import logic will be changed to: + +- If you import the XMLID of a record, make an **update**. +- If you do not: + + - If there are import match rules for the model you are importing: + + - Discard the rules that require fields you are not importing. + - Traverse the remaining rules one by one in order to find a match in the database. + + - Skip the rule if it requires a special condition that is not + satisfied. + - If one match is found: + + - Stop traversing the rest of valid rules. + - **Update** that record. + - If zero or multiple matches are found: + + - Continue with the next rule. + - If all rules are exhausted and no single match is found: + + - **Create** a new record. + - If there are no match rules for your model: + + - **Create** a new record. + +By default 2 rules are installed for production instances: + +- One rule that will allow you to update companies based on their VAT, when + ``is_company`` is ``True``. +- One rule that will allow you to update users based on their login. + +In demo instances there are more examples. diff --git a/base_import_match/readme/ROADMAP.rst b/base_import_match/readme/ROADMAP.rst new file mode 100644 index 000000000..38f6cf0ea --- /dev/null +++ b/base_import_match/readme/ROADMAP.rst @@ -0,0 +1,2 @@ +* Add a setting to throw an error when multiple matches are found, instead of + falling back to creation of new record. diff --git a/base_import_match/readme/USAGE.rst b/base_import_match/readme/USAGE.rst new file mode 100644 index 000000000..7e0d6cdc0 --- /dev/null +++ b/base_import_match/readme/USAGE.rst @@ -0,0 +1,5 @@ +To use this module, you need to: + +#. Follow steps in **Configuration** section above. +#. Go to any list view. +#. Press *Import* and follow the import procedure as usual. diff --git a/base_import_match/static/description/index.html b/base_import_match/static/description/index.html new file mode 100644 index 000000000..8fff819c1 --- /dev/null +++ b/base_import_match/static/description/index.html @@ -0,0 +1,511 @@ + + + + + + +Base Import Match + + + +
+

Base Import Match

+ + +

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

+

By default, when importing data (like CSV import) with the base_import +module, Odoo follows this rule:

+
    +
  • If you import the XMLID of a record, make an update.
  • +
  • If you do not, create a new record.
  • +
+

This module allows you to set additional rules to match if a given import is an +update or a new record.

+

This is useful when you need to sync heterogeneous databases, and the field you +use to match records in those databases with Odoo’s is not the XMLID but the +name, VAT, email, etc.

+

After installing this module, the import logic will be changed to:

+
    +
  • If you import the XMLID of a record, make an update.
  • +
  • If you do not:
      +
    • If there are import match rules for the model you are importing:
        +
      • Discard the rules that require fields you are not importing.
      • +
      • Traverse the remaining rules one by one in order to find a match in the database.
          +
        • Skip the rule if it requires a special condition that is not +satisfied.
        • +
        • If one match is found:
            +
          • Stop traversing the rest of valid rules.
          • +
          • Update that record.
          • +
          +
        • +
        • If zero or multiple matches are found:
            +
          • Continue with the next rule.
          • +
          +
        • +
        • If all rules are exhausted and no single match is found:
            +
          • Create a new record.
          • +
          +
        • +
        +
      • +
      +
    • +
    • If there are no match rules for your model:
        +
      • Create a new record.
      • +
      +
    • +
    +
  • +
+

By default 2 rules are installed for production instances:

+
    +
  • One rule that will allow you to update companies based on their VAT, when +is_company is True.
  • +
  • One rule that will allow you to update users based on their login.
  • +
+

In demo instances there are more examples.

+

Table of contents

+ +
+

Configuration

+

To configure this module, you need to:

+
    +
  1. Go to Settings > Technical > Database Structure > Import Match.
  2. +
  3. Create.
  4. +
  5. Choose a Model.
  6. +
  7. Choose the Fields that conform a unique key in that model.
  8. +
  9. If the rule must be used only for certain imported values, check +Conditional and enter the exact string that is going to be imported +in Imported value.
      +
    1. Keep in mind that the match here is evaluated as a case sensitive +text string always. If you enter e.g. True, it will match that +string, but will not match 1 or true.
    2. +
    +
  10. +
  11. Save.
  12. +
+

In that list view, you can sort rules by drag and drop.

+
+
+

Usage

+

To use this module, you need to:

+
    +
  1. Follow steps in Configuration section above.
  2. +
  3. Go to any list view.
  4. +
  5. Press Import and follow the import procedure as usual.
  6. +
+
+
+

Known issues / Roadmap

+
    +
  • Add a setting to throw an error when multiple matches are found, instead of +falling back to creation of new record.
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Tecnativa
  • +
+
+
+

Contributors

+
    +
  • Tecnativa: +* Jairo Llopis +* Vicent Cubells +* Ernesto Tejeda
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/server-backend project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/base_import_match/tests/__init__.py b/base_import_match/tests/__init__.py index 1d8b5f1b2..ff1f96e72 100644 --- a/base_import_match/tests/__init__.py +++ b/base_import_match/tests/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis # Copyright 2016 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). diff --git a/base_import_match/tests/import_data/res_partner_email.csv b/base_import_match/tests/import_data/res_partner_email.csv index 983b91133..c4564a51d 100644 --- a/base_import_match/tests/import_data/res_partner_email.csv +++ b/base_import_match/tests/import_data/res_partner_email.csv @@ -1,2 +1,2 @@ email,name -michel.fletcher@agrolait.example.com,Michel Fletcher Changed +floyd.steward34@example.com,Floyd Steward Changed diff --git a/base_import_match/tests/import_data/res_partner_name.csv b/base_import_match/tests/import_data/res_partner_name.csv index c1a109590..82327b9cd 100644 --- a/base_import_match/tests/import_data/res_partner_name.csv +++ b/base_import_match/tests/import_data/res_partner_name.csv @@ -1,2 +1,2 @@ function,name -Function Changed,Michel Fletcher +Function Changed,Floyd Steward diff --git a/base_import_match/tests/import_data/res_partner_parent_name_is_company.csv b/base_import_match/tests/import_data/res_partner_parent_name_is_company.csv index 2d433d94e..8487e0b93 100644 --- a/base_import_match/tests/import_data/res_partner_parent_name_is_company.csv +++ b/base_import_match/tests/import_data/res_partner_parent_name_is_company.csv @@ -1,2 +1,2 @@ name,is_company,parent_id/id,email -Michel Fletcher,False,base.res_partner_2,changed@agrolait.example.com +Floyd Steward,False,base.res_partner_2,floyd.steward34.changed@example.com diff --git a/base_import_match/tests/import_data/res_partner_vat.csv b/base_import_match/tests/import_data/res_partner_vat.csv index acc3188cf..a4b25ad25 100644 --- a/base_import_match/tests/import_data/res_partner_vat.csv +++ b/base_import_match/tests/import_data/res_partner_vat.csv @@ -1,2 +1,2 @@ name,vat,is_company -Agrolait Changed,BE0477472701,True +Deco Addict Changed,BE0477472701,True diff --git a/base_import_match/tests/test_import.py b/base_import_match/tests/test_import.py index b7d977fa1..e266084d7 100644 --- a/base_import_match/tests/test_import.py +++ b/base_import_match/tests/test_import.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2016 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis # Copyright 2016 Tecnativa - Vicent Cubells # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). @@ -28,34 +27,34 @@ class ImportCase(TransactionCase): def test_res_partner_vat(self): """Change name based on VAT.""" - agrolait = self.env.ref("base.res_partner_2") - agrolait.vat = "BE0477472701" + deco_addict = self.env.ref("base.res_partner_2") + deco_addict.vat = "BE0477472701" record = self._base_import_record("res.partner", "res_partner_vat") - record.do(["name", "vat", "is_company"], OPTIONS) - agrolait.env.invalidate_all() - self.assertEqual(agrolait.name, "Agrolait Changed") + record.do(["name", "vat", "is_company"], [], OPTIONS) + deco_addict.env.cache.invalidate() + self.assertEqual(deco_addict.name, "Deco Addict Changed") def test_res_partner_parent_name_is_company(self): """Change email based on parent_id, name and is_company.""" record = self._base_import_record( "res.partner", "res_partner_parent_name_is_company") - record.do(["name", "is_company", "parent_id/id", "email"], OPTIONS) + record.do(["name", "is_company", "parent_id/id", "email"], [], OPTIONS) self.assertEqual( self.env.ref("base.res_partner_address_4").email, - "changed@agrolait.example.com") + "floyd.steward34.changed@example.com") def test_res_partner_email(self): """Change name based on email.""" record = self._base_import_record("res.partner", "res_partner_email") - record.do(["email", "name"], OPTIONS) + record.do(["email", "name"], [], OPTIONS) self.assertEqual( self.env.ref("base.res_partner_address_4").name, - "Michel Fletcher Changed") + "Floyd Steward Changed") def test_res_partner_name(self): """Change function based on name.""" record = self._base_import_record("res.partner", "res_partner_name") - record.do(["function", "name"], OPTIONS) + record.do(["function", "name"], [], OPTIONS) self.assertEqual( self.env.ref("base.res_partner_address_4").function, "Function Changed") @@ -63,7 +62,7 @@ class ImportCase(TransactionCase): def test_res_users_login(self): """Change name based on login.""" record = self._base_import_record("res.users", "res_users_login") - record.do(["login", "name"], OPTIONS) + record.do(["login", "name"], [], OPTIONS) self.assertEqual( self.env.ref("base.user_demo").name, "Demo User Changed") diff --git a/base_import_match/views/base_import_match_view.xml b/base_import_match/views/base_import_match_view.xml index 11c9e8245..88cb9b354 100644 --- a/base_import_match/views/base_import_match_view.xml +++ b/base_import_match/views/base_import_match_view.xml @@ -62,7 +62,7 @@ - +