From 75478a366242f264d8c3cb206b8d91548e03befc Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Fri, 12 Aug 2016 22:05:58 +0200 Subject: [PATCH] crm_deduplicate_filter =========================================== Exclude some records from the deduplication =========================================== This module extends the possibilities of the contact deduplication allowing to filter the applicable set according several criteria. For now, only the filter for restricting the deduplication to only companies or only contacts is implemented. Usage ===== To use this module, you need to: "Parent company set (Contacts)" in the section 'Exclude contacts having'. kind of records. --- partner_deduplicate_filter/README.rst | 65 +++++++++++ partner_deduplicate_filter/__init__.py | 4 + partner_deduplicate_filter/__openerp__.py | 20 ++++ partner_deduplicate_filter/i18n/es.po | 32 ++++++ .../static/description/icon.png | Bin 0 -> 11387 bytes .../static/description/icon.svg | 102 ++++++++++++++++++ partner_deduplicate_filter/tests/__init__.py | 4 + .../tests/test_crm_deduplicate_filter.py | 77 +++++++++++++ .../wizards/__init__.py | 5 + .../wizards/partner_merge.py | 35 ++++++ .../wizards/partner_merge_view.xml | 21 ++++ 11 files changed, 365 insertions(+) create mode 100644 partner_deduplicate_filter/README.rst create mode 100644 partner_deduplicate_filter/__init__.py create mode 100644 partner_deduplicate_filter/__openerp__.py create mode 100644 partner_deduplicate_filter/i18n/es.po create mode 100644 partner_deduplicate_filter/static/description/icon.png create mode 100644 partner_deduplicate_filter/static/description/icon.svg create mode 100644 partner_deduplicate_filter/tests/__init__.py create mode 100644 partner_deduplicate_filter/tests/test_crm_deduplicate_filter.py create mode 100644 partner_deduplicate_filter/wizards/__init__.py create mode 100644 partner_deduplicate_filter/wizards/partner_merge.py create mode 100644 partner_deduplicate_filter/wizards/partner_merge_view.xml diff --git a/partner_deduplicate_filter/README.rst b/partner_deduplicate_filter/README.rst new file mode 100644 index 000000000..6aa5c85f8 --- /dev/null +++ b/partner_deduplicate_filter/README.rst @@ -0,0 +1,65 @@ +.. 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 + +=========================================== +Exclude some records from the deduplication +=========================================== + +This module extends the possibilities of the contact deduplication allowing +to filter the applicable set according to several criteria. + +For now, only the filter for restricting the deduplication to only companies or +only contacts is implemented. + +Usage +===== + +To use this module, you need to: + +#. Go to *Sales > Tools > Deduplicate Contacts*. +#. Mark "'Is a company?' field selected", "Parent company not set" or + "Parent company set (Contacts)" in the section 'Exclude contacts having'. +#. This criteria will be used for excluding in the deduplication the selected + kind of records. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/111/8.0 + +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. + +Credits +======= + +Images +------ + +* `Funnel `_. +* `Arrow `_. + +Contributors +------------ + +* Pedro M. Baeza + +Maintainer +---------- + +.. 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. diff --git a/partner_deduplicate_filter/__init__.py b/partner_deduplicate_filter/__init__.py new file mode 100644 index 000000000..f8944f05c --- /dev/null +++ b/partner_deduplicate_filter/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import wizards diff --git a/partner_deduplicate_filter/__openerp__.py b/partner_deduplicate_filter/__openerp__.py new file mode 100644 index 000000000..d7c531952 --- /dev/null +++ b/partner_deduplicate_filter/__openerp__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Exclude records from the deduplication", + "version": "8.0.1.0.0", + "category": "Tools", + "website": "https://www.tecnativa.com", + "author": "Tecnativa, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "installable": True, + "depends": [ + "crm", + ], + "data": [ + 'wizards/partner_merge_view.xml', + ], +} diff --git a/partner_deduplicate_filter/i18n/es.po b/partner_deduplicate_filter/i18n/es.po new file mode 100644 index 000000000..7ad3becf5 --- /dev/null +++ b/partner_deduplicate_filter/i18n/es.po @@ -0,0 +1,32 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * crm_deduplicate_filter +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-08-12 19:57+0000\n" +"PO-Revision-Date: 2016-08-12 19:57+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: crm_deduplicate_filter +#: field:base.partner.merge.automatic.wizard,exclude_is_company:0 +msgid "'Is a company?' field selected" +msgstr "El campo '¿Es una compañía?' seleccionado" + +#. module: crm_deduplicate_filter +#: field:base.partner.merge.automatic.wizard,exclude_parent:0 +msgid "Parent company set (Contacts)" +msgstr "La compañía padre establecida (Contactos)" + +#. module: crm_deduplicate_filter +#: field:base.partner.merge.automatic.wizard,exclude_not_parent:0 +msgid "Parent company not set" +msgstr "La compañía padre no establecida" + diff --git a/partner_deduplicate_filter/static/description/icon.png b/partner_deduplicate_filter/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..49b724769a98a98c05cd6fbb0e9df437a78c627a GIT binary patch literal 11387 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 qqd^-mt!`AAdN72z=Zl{_gI;Ic#Ha4J4 + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/partner_deduplicate_filter/tests/__init__.py b/partner_deduplicate_filter/tests/__init__.py new file mode 100644 index 000000000..4945339d8 --- /dev/null +++ b/partner_deduplicate_filter/tests/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import test_crm_deduplicate_filter diff --git a/partner_deduplicate_filter/tests/test_crm_deduplicate_filter.py b/partner_deduplicate_filter/tests/test_crm_deduplicate_filter.py new file mode 100644 index 000000000..b6777fa56 --- /dev/null +++ b/partner_deduplicate_filter/tests/test_crm_deduplicate_filter.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests import common +from openerp.tools.safe_eval import safe_eval + + +class TestDeduplicateFilter(common.TransactionCase): + def setUp(self): + super(TestDeduplicateFilter, self).setUp() + self.partner_1 = self.env['res.partner'].create({ + 'name': 'Partner 1', + 'email': 'partner1@example.org', + 'is_company': True, + 'parent_id': False, + }) + self.partner_1.copy() + self.partner_2 = self.env['res.partner'].create({ + 'name': 'Partner 2', + 'email': 'partner2@example.org', + 'is_company': False, + 'parent_id': self.partner_1.id, + }) + self.partner_2.copy() + self.partner_3 = self.env['res.partner'].create({ + 'name': 'Partner 3', + 'email': 'partner3@example.org', + 'is_company': False, + 'parent_id': False, + }) + self.partner_3.copy() + self.wizard = self.env['base.partner.merge.automatic.wizard'].create({ + 'group_by_email': True, + }) + + def test_deduplicate_exclude_is_company(self): + self.wizard.exclude_is_company = True + self.wizard.start_process_cb() + matched_founds = 0 + for line in self.wizard.line_ids: + match_ids = safe_eval(line.aggr_ids) + if self.partner_1.id in match_ids: + self.assertTrue(False, 'Partner with is company not excluded') + if self.partner_2.id in match_ids: + matched_founds += 1 + if self.partner_3.id in match_ids: + matched_founds += 1 + self.assertEqual(matched_founds, 2) + + def test_deduplicate_exclude_not_parent(self): + self.wizard.exclude_not_parent = True + self.wizard.start_process_cb() + matched_founds = 0 + for line in self.wizard.line_ids: + match_ids = safe_eval(line.aggr_ids) + if self.partner_1.id in match_ids: + self.assertTrue(False, 'Partner without parent not excluded') + if self.partner_3.id in match_ids: + self.assertTrue(False, 'Partner without parent not excluded') + if self.partner_2.id in match_ids: + matched_founds += 1 + self.assertEqual(matched_founds, 1) + + def test_deduplicate_exclude_parent(self): + self.wizard.exclude_parent = True + self.wizard.start_process_cb() + matched_founds = 0 + for line in self.wizard.line_ids: + match_ids = safe_eval(line.aggr_ids) + if self.partner_2.id in match_ids: + self.assertTrue(False, 'Partner with parent not excluded') + if self.partner_1.id in match_ids: + matched_founds += 1 + if self.partner_3.id in match_ids: + matched_founds += 1 + self.assertEqual(matched_founds, 2) diff --git a/partner_deduplicate_filter/wizards/__init__.py b/partner_deduplicate_filter/wizards/__init__.py new file mode 100644 index 000000000..c93eadfed --- /dev/null +++ b/partner_deduplicate_filter/wizards/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 Antiun Ingeniería S.L. - Jairo Llopis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import partner_merge diff --git a/partner_deduplicate_filter/wizards/partner_merge.py b/partner_deduplicate_filter/wizards/partner_merge.py new file mode 100644 index 000000000..26381b791 --- /dev/null +++ b/partner_deduplicate_filter/wizards/partner_merge.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Copyright 2016 Pedro M. Baeza +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp import api, fields, models + + +class BasePartnerMergeAutomaticWizard(models.TransientModel): + _inherit = "base.partner.merge.automatic.wizard" + + exclude_is_company = fields.Boolean("'Is a company?' field selected") + exclude_not_parent = fields.Boolean("Parent company not set") + exclude_parent = fields.Boolean("Parent company set (Contacts)") + + @api.multi + def _process_query(self, query): + if any([self.exclude_is_company, self.exclude_not_parent, + self.exclude_parent]): + filters = [] + if self.exclude_is_company: + filters.append("is_company = False") + if self.exclude_not_parent: + filters.append("parent_id IS NOT NULL") + if self.exclude_parent: + filters.append("parent_id IS NULL") + index_where = query.find('WHERE') + index_group_by = query.find('GROUP BY') + subquery = "%s" % ' AND '.join(filters) + if index_where > 0: + subquery = "AND (%s) " % subquery + else: # pragma: no cover + subquery = "WHERE %s " % subquery + query = query[:index_group_by] + subquery + query[index_group_by:] + return super(BasePartnerMergeAutomaticWizard, self)._process_query( + query) diff --git a/partner_deduplicate_filter/wizards/partner_merge_view.xml b/partner_deduplicate_filter/wizards/partner_merge_view.xml new file mode 100644 index 000000000..26d0b5465 --- /dev/null +++ b/partner_deduplicate_filter/wizards/partner_merge_view.xml @@ -0,0 +1,21 @@ + + + + + + + + base.partner.merge.automatic.wizard + + + + + + + + + + + +