Browse Source

work in progress

pull/406/head
Tom 8 years ago
parent
commit
bbc68efa45
  1. 38
      base_partner_merge/README.rst
  2. 2
      base_partner_merge/__init__.py
  3. 4
      base_partner_merge/__openerp__.py
  4. 6
      base_partner_merge/hooks.py
  5. 72
      base_partner_merge/tests/test_merge.py
  6. 1
      base_partner_merge/views/base_partner_merge.xml

38
base_partner_merge/README.rst

@ -2,20 +2,38 @@
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
============================
Deduplicate contact (No CRM)
============================
========================
Deduplicate contacts OCA
========================
This module installs the deduplicate wizard from CRM without the dependency on CRM.
This module installs the deduplicate wizard from Odoo CRM, but without the
dependency on the CRM module and with some extra features.
If you have CRM installed you don't need this module.
The extra features are:
- Can be installed with or without the CRM module
- Deduplicate also on `ref` (partner reference)
- To deduplicate only a subset of partners (eg. one category), the context
variable `extra_domain` may contain a domain string to search on before
deduplicating. (TODO: offer this in the wizard)
- A function `deduplicate_on_field(self, field, domain=[]):` is added to the
`res.partner` object. It takes the field to deduplicate on as a parameter,
as well as the domain mentioned above. It can be called from `ir.cron`
Automated Actions.
Installation Installation
============ ============
To install this module, you need to have crm module present (but not installed).
This is because we reuse the existing wizard without installing CRM.
To install this module, you need to have `crm` module present on the system.
This is because we reuse the existing code from Odoo CRM.
Known issues
============
If this module is installed, `crm` module installation gives an error.
Workaround for this is to remove this module, install `crm`, then install
this module again.
Bug Tracker Bug Tracker
@ -34,6 +52,7 @@ Contributors
------------ ------------
* Charbel Jacquin <charbel.jacquin@camptocamp.com> * Charbel Jacquin <charbel.jacquin@camptocamp.com>
* Holger Brunn <hbrunn@therp.nl>
* Tom Blauwendraat <tom@sunflowerweb.nl> * Tom Blauwendraat <tom@sunflowerweb.nl>
* Terrence Nzaywa <terrence@sunflowerweb.nl> * Terrence Nzaywa <terrence@sunflowerweb.nl>
@ -41,8 +60,9 @@ Author
------ ------
Yannick Vaucher Yannick Vaucher
Based on Holger Brunn's idea.
Backport to 8.0 by Tom Blauwendraat and Terrence Nzaywa
Based on Holger Brunn's idea
Backported to 8.0 by Tom Blauwendraat and Terrence Nzaywa
Features added by Tom Blauwendraat
Maintainer Maintainer
---------- ----------

2
base_partner_merge/__init__.py

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from . import base_partner_merge # NOQA from . import base_partner_merge # NOQA
from .hooks import post_load_hook from .hooks import post_load_hook
from . import models

4
base_partner_merge/__openerp__.py

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
{ {
'name': "Deduplicate Contacts (No CRM)",
'author': "Camptocamp,Odoo Community Association (OCA)",
'name': "Deduplicate Contacts (OCA)",
'author': "Camptocamp,Sunflower IT,Odoo Community Association (OCA)",
'category': 'Generic Modules/Base', 'category': 'Generic Modules/Base',
'version': '8.0.1.0.0', 'version': '8.0.1.0.0',
'license': 'AGPL-3', 'license': 'AGPL-3',

6
base_partner_merge/hooks.py

@ -6,7 +6,8 @@ from openerp.models import MetaModel
def post_load_hook(): def post_load_hook():
"""We try to be smart here: If the crm module is to be loaded too
"""
We try to be smart here: If the crm module is to be loaded too
(or is already loaded), we remove our own models again in order not to (or is already loaded), we remove our own models again in order not to
clash with the CRM ones: https://github.com/OCA/partner-contact/issues/283 clash with the CRM ones: https://github.com/OCA/partner-contact/issues/283
""" """
@ -15,6 +16,7 @@ def post_load_hook():
if 'graph' in frame.f_locals: if 'graph' in frame.f_locals:
graph = frame.f_locals['graph'] graph = frame.f_locals['graph']
package = frame.f_locals['package'] package = frame.f_locals['package']
package.data['data'].remove('views/base_partner_merge.xml')
if any(p.name == 'crm' for p in graph): if any(p.name == 'crm' for p in graph):
# so crm is installed, then we need to remove your model # so crm is installed, then we need to remove your model
# from the list of models to be registered # from the list of models to be registered
@ -22,5 +24,7 @@ def post_load_hook():
# to be ditched (if crm is in their mro) # to be ditched (if crm is in their mro)
MetaModel.module_to_models['base_partner_merge'] = [] MetaModel.module_to_models['base_partner_merge'] = []
# and in this case, we also don't want to load our xml files # and in this case, we also don't want to load our xml files
else:
# if crm is not installed, we
package.data['data'].remove('views/base_partner_merge.xml') package.data['data'].remove('views/base_partner_merge.xml')
break break

72
base_partner_merge/tests/test_merge.py

@ -2,9 +2,9 @@
# © 2017 Sunflower IT <http://sunflowerweb.nl> # © 2017 Sunflower IT <http://sunflowerweb.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import os
from openerp.tests.common import TransactionCase from openerp.tests.common import TransactionCase
class PartnerMergeTestCase(TransactionCase): class PartnerMergeTestCase(TransactionCase):
"""Tests for Partner Merge""" """Tests for Partner Merge"""
@ -13,40 +13,52 @@ class PartnerMergeTestCase(TransactionCase):
self.partner = self.env['res.partner'] self.partner = self.env['res.partner']
self.merge_wizard = \ self.merge_wizard = \
self.env['base.partner.merge.automatic.wizard'] self.env['base.partner.merge.automatic.wizard']
self.donald_domain = [('name', '=', 'Donald Duck')]
self.mickey_domain = [('name', '=', 'Mickey Mouse')]
def test_10_all_functionality(self):
# Delete all Donald Ducks
donald_domain = [('name', '=', 'Donald Duck')]
self.partner.search(donald_domain).unlink()
# Create two partners called Donald Duck
partner_donald = self.partner.create({
'name': 'Donald Duck',
'email': 'donald@sunflowerweb.nl',
})
partner_donald2 = self.partner.create({
'name': 'Donald Duck',
'email': 'donald@therp.nl',
})
def _unlink_all(self):
self.partner.search(self.donald_domain).unlink()
self.partner.search(self.mickey_domain).unlink()
# Test if there are two Donald Ducks
donalds = self.partner.search(donald_domain)
self.assertEquals(len(donalds), 2)
def _count_donalds_mickeys(self, donalds, mickeys):
self.assertEquals(
len(self.partner.search(self.donald_domain)), donalds)
self.assertEquals(
len(self.partner.search(self.mickey_domain)), mickeys)
# Merge them,
wizard_id = self.merge_wizard.create({
'group_by_name': True,
'state': "option"
})
wizard_id.automatic_process_cb()
def _create_duplicates(self, field1, value1, field2, values2):
for value2 in values2:
self.partner.create({
field1: value1,
field2: value2,
})
# Test if there is now one Donald Duck
donalds = self.partner.search(donald_domain)
self.assertEquals(len(donalds), 1)
# Delete all Donald Ducks
self.partner.search(donald_domain).unlink()
def test_10_all_functionality(self):
""" All functionality """
# Create users with duplicate names
self._unlink_all()
self._create_duplicates('name', 'Donald Duck', 'email',
['donald@therp.nl', 'donald@sunflowerweb.nl'])
self._create_duplicates('name', 'Mickey Mouse', 'email',
['mickey@therp.nl', 'mickey@sunflowerweb.nl'])
# Test if there are two Donald Ducks and Mickey Mouses
self._count_donalds_mickeys(2, 2)
# Merge all names that start with 'D',
self.partner.deduplicate_on_field('name',
domain=[('name', 'like', 'D%')])
# Test if there is one Donald but still two Mickeys
self._count_donalds_mickeys(1, 2)
# Create users with duplicate references
self._unlink_all()
self._create_duplicates('ref', 'DD123',
'name', ['Donald Duck', 'Mickey Mouse'])
# Merge on reference, leaving out guys that have no ref
self.partner.deduplicate_on_field('ref',
domain=[('ref', '!=', False)])
# Test if only one remains after
self.assertEquals(len(self.partner.search([
('ref', '=', 'DD123')])), 1)

1
base_partner_merge/views/base_partner_merge.xml

@ -79,6 +79,7 @@
<field name='group_by_is_company' /> <field name='group_by_is_company' />
<field name='group_by_vat' /> <field name='group_by_vat' />
<field name='group_by_parent_id' /> <field name='group_by_parent_id' />
<field name='group_by_ref' />
</group> </group>
<group string="Exclude contacts having" <group string="Exclude contacts having"
attrs="{'invisible': [('state', 'not in', ('option',))]}"> attrs="{'invisible': [('state', 'not in', ('option',))]}">

Loading…
Cancel
Save