From cc77560f4378b8984d50d9a7946793ba3d532dd3 Mon Sep 17 00:00:00 2001
From: Christophe Matthieu
Date: Mon, 6 May 2013 14:25:38 +0200
Subject: [PATCH 1/6] [IMP] crm: base_partner_merge: The 'Automatic Merge'
button open the wizard. Add field to choice the partner destination
bzr revid: chm@openerp.com-20130506122538-8hi7znmq4pjooasf
---
addons/crm/base_partner_merge.py | 73 ++++++++++++++++++++------
addons/crm/base_partner_merge_view.xml | 5 +-
2 files changed, 60 insertions(+), 18 deletions(-)
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index b2645e7fb79..b40016b2635 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -101,6 +101,7 @@ class MergePartnerAutomatic(osv.TransientModel):
'current_line_id': fields.many2one('base.partner.merge.line', 'Current Line'),
'line_ids': fields.one2many('base.partner.merge.line', 'wizard_id', 'Lines'),
'partner_ids': fields.many2many('res.partner', string='Contacts'),
+ 'dst_partner_id': fields.many2one('res.partner', string='Destination Contact'),
'exclude_contact': fields.boolean('A user associated to the contact'),
'exclude_journal_item': fields.boolean('Journal Items associated to the contact'),
@@ -111,6 +112,13 @@ class MergePartnerAutomatic(osv.TransientModel):
'state': 'option',
}
+ def onchange_partner_ids(self, cr, uid, ids, partner_ids=[], context=None):
+ if partner_ids and isinstance(partner_ids[0], (list, tuple)):
+ partner_ids = partner_ids[0][2]
+ else:
+ partner_ids = []
+ return {'domain': {'dst_partner_id': [('id', 'in', partner_ids)]}}
+
def get_fk_on(self, cr, table):
q = """ SELECT cl1.relname as table,
att1.attname as column
@@ -254,6 +262,7 @@ class MergePartnerAutomatic(osv.TransientModel):
if field._type not in ('many2many', 'one2many', 'function'):
for item in itertools.chain(src_partners, [dst_partner]):
if item[column]:
+ print column, item[column]
values[column] = write_serializer(column, item[column])
values.pop('id', None)
@@ -266,20 +275,23 @@ class MergePartnerAutomatic(osv.TransientModel):
_logger.info('Skip recursive partner hierarchies for parent_id %s of partner: %s', parent_id, dst_partner.id)
@mute_logger('openerp.osv.expression', 'openerp.osv.orm')
- def _merge(self, cr, uid, partner_ids, context=None):
+ def _merge(self, cr, uid, partner_ids, dst_partner_id=None, context=None):
proxy = self.pool.get('res.partner')
partner_ids = proxy.exists(cr, uid, list(partner_ids), context=context)
if len(partner_ids) < 2:
return
- partners = proxy.browse(cr, uid, list(partner_ids), context=context)
- ordered_partners = sorted(sorted(partners,
- key=operator.attrgetter('create_date'), reverse=True),
- key=operator.attrgetter('active'), reverse=True)
-
- dst_partner = ordered_partners[-1]
- src_partners = ordered_partners[:-1]
+ if dst_partner_id and dst_partner_id in partner_ids:
+ partner_obj = self.pool.get('res.partner')
+ def f(x):
+ return x != dst_partner_id
+ src_partners = partner_obj.browse(cr, uid, list(filter(f, partner_ids)), context=context)
+ dst_partner = partner_obj.browse(cr, uid, list(partner_ids), context=context)
+ else:
+ ordered_partners = self._get_ordered_partner(cr, uid, partner_ids, context)
+ dst_partner = ordered_partners[-1]
+ src_partners = ordered_partners[:-1]
_logger.info("dst_partner: %s", dst_partner.id)
call_it = lambda function: function(cr, uid, src_partners, dst_partner,
@@ -414,9 +426,16 @@ class MergePartnerAutomatic(osv.TransientModel):
this = self.browse(cr, uid, ids[0], context=context)
if this.current_line_id:
this.current_line_id.unlink()
- return self._next_screen(this)
+ return self._next_screen(cr, uid, this)
- def _next_screen(self, this):
+ def _get_ordered_partner(self, cr, uid, partner_ids, context=None):
+ partners = self.pool.get('res.partner').browse(cr, uid, list(partner_ids), context=context)
+ ordered_partners = sorted(sorted(partners,
+ key=operator.attrgetter('create_date'), reverse=True),
+ key=operator.attrgetter('active'), reverse=True)
+ return ordered_partners
+
+ def _next_screen(self, cr, uid, this):
this.refresh()
values = {}
if this.line_ids:
@@ -426,6 +445,7 @@ class MergePartnerAutomatic(osv.TransientModel):
values.update({
'current_line_id': current_line.id,
'partner_ids': [(6, 0, current_partner_ids)],
+ 'dst_partner_id': self._get_ordered_partner(cr, uid, current_partner_ids, context)[-1].id,
'state': 'selection',
})
else:
@@ -525,7 +545,7 @@ class MergePartnerAutomatic(osv.TransientModel):
query = self._generate_query(groups, this.maximum_group)
self._process_query(cr, uid, ids, query, context=context)
- return self._next_screen(this)
+ return self._next_screen(cr, uid, this)
def automatic_process_cb(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
@@ -666,7 +686,7 @@ class MergePartnerAutomatic(osv.TransientModel):
# p1.parent_id = p1.id
# """)
- return self._next_screen(this)
+ return self._next_screen(cr, uid, this)
def merge_cb(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
@@ -685,11 +705,11 @@ class MergePartnerAutomatic(osv.TransientModel):
'target': 'new',
}
- self._merge(cr, uid, partner_ids, context=context)
+ self._merge(cr, uid, partner_ids, this.dst_partner_id, context=context)
this.current_line_id.unlink()
- return self._next_screen(this)
+ return self._next_screen(cr, uid, this)
def merge_multi(self, cr, uid, ids, context=None):
@@ -709,9 +729,29 @@ class MergePartnerAutomatic(osv.TransientModel):
_("You can't use this wizard with only one Partner")
)
- self._merge(cr, uid, partner_ids, context=context)
+ ordered_partner = self._get_ordered_partner(cr, uid, partner_ids, context)
+ def f(x): return x.id
- return True
+ current_line_id = self.pool.get('base.partner.merge.line').create(cr, uid, {'min_id': ordered_partner[-1].id, 'aggr_ids': map(f, ordered_partner)})
+ context.update({
+ 'default_state': 'selection',
+ 'default_partner_ids': [(6, 0, partner_ids)],
+ 'default_dst_partner_id': ordered_partner[-1].id,
+ 'default_current_line_id': current_line_id,
+ 'default_number_group': 1,
+ 'default_maximum_group': 1,
+ })
+
+ action = {
+ 'view_type': 'form',
+ 'view_mode': 'form',
+ 'res_model': self._name,
+ 'res_id': False,
+ 'type': 'ir.actions.act_window',
+ 'target': 'new',
+ 'context': context
+ }
+ return action
def auto_set_parent_id(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
@@ -758,3 +798,4 @@ class MergePartnerAutomatic(osv.TransientModel):
WHERE id != %s AND email LIKE '%%%s'
""" % (id, id, email))
return False
+
diff --git a/addons/crm/base_partner_merge_view.xml b/addons/crm/base_partner_merge_view.xml
index 74e7a72d7a8..dd344b122bc 100644
--- a/addons/crm/base_partner_merge_view.xml
+++ b/addons/crm/base_partner_merge_view.xml
@@ -98,7 +98,8 @@
redirected to the aggregated contact. You can remove
contacts from this list to avoid merging them.
-
+
+
@@ -117,7 +118,7 @@
- pool.get('base.partner.merge.automatic.wizard').merge_multi(cr, uid, None, context)
+ action = pool.get('base.partner.merge.automatic.wizard').merge_multi(cr, uid, None, context)
True
Automatic Merge
From cffffc9cd6c6d9d50183c4b1648fb6a1ef9915d6 Mon Sep 17 00:00:00 2001
From: Olivier Dony
Date: Wed, 8 May 2013 17:00:37 +0200
Subject: [PATCH 2/6] [FIX] crm: missing context propagation
bzr revid: odo@openerp.com-20130508150037-qtdsx3gpirwr10re
---
addons/crm/base_partner_merge.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index b40016b2635..704f2b03aec 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -426,7 +426,7 @@ class MergePartnerAutomatic(osv.TransientModel):
this = self.browse(cr, uid, ids[0], context=context)
if this.current_line_id:
this.current_line_id.unlink()
- return self._next_screen(cr, uid, this)
+ return self._next_screen(cr, uid, this, context)
def _get_ordered_partner(self, cr, uid, partner_ids, context=None):
partners = self.pool.get('res.partner').browse(cr, uid, list(partner_ids), context=context)
@@ -435,7 +435,7 @@ class MergePartnerAutomatic(osv.TransientModel):
key=operator.attrgetter('active'), reverse=True)
return ordered_partners
- def _next_screen(self, cr, uid, this):
+ def _next_screen(self, cr, uid, this, context=None):
this.refresh()
values = {}
if this.line_ids:
@@ -545,7 +545,7 @@ class MergePartnerAutomatic(osv.TransientModel):
query = self._generate_query(groups, this.maximum_group)
self._process_query(cr, uid, ids, query, context=context)
- return self._next_screen(cr, uid, this)
+ return self._next_screen(cr, uid, this, context)
def automatic_process_cb(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
@@ -686,7 +686,7 @@ class MergePartnerAutomatic(osv.TransientModel):
# p1.parent_id = p1.id
# """)
- return self._next_screen(cr, uid, this)
+ return self._next_screen(cr, uid, this, context)
def merge_cb(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
@@ -709,7 +709,7 @@ class MergePartnerAutomatic(osv.TransientModel):
this.current_line_id.unlink()
- return self._next_screen(cr, uid, this)
+ return self._next_screen(cr, uid, this, context)
def merge_multi(self, cr, uid, ids, context=None):
From 4229cff81cc27596bc81e1745046a9802014fd81 Mon Sep 17 00:00:00 2001
From: Olivier Dony
Date: Wed, 8 May 2013 18:27:42 +0200
Subject: [PATCH 3/6] [FIX] crm: simplify + fix multiple programming errors in
partner merge wizard
bzr revid: odo@openerp.com-20130508162742-qxdrjg93r6md1tw5
---
addons/crm/base_partner_merge.py | 78 ++++++--------------------
addons/crm/base_partner_merge_view.xml | 32 +++--------
2 files changed, 26 insertions(+), 84 deletions(-)
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index 704f2b03aec..f51d6afb188 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -108,16 +108,20 @@ class MergePartnerAutomatic(osv.TransientModel):
'maximum_group': fields.integer("Maximum of Group of Contacts"),
}
- _defaults = {
- 'state': 'option',
- }
+ def default_get(self, cr, uid, fields, context=None):
+ if context is None:
+ context = {}
+ res = super(MergePartnerAutomatic, self).default_get(cr, uid, fields, context)
+ if context.get('active_model') == 'res.partner' and context.get('active_ids'):
+ partner_ids = context['active_ids']
+ res['state'] = 'selection'
+ res['partner_ids'] = partner_ids
+ res['dst_partner_id'] = self._get_ordered_partner(cr, uid, partner_ids, context=context)[-1].id
+ return res
- def onchange_partner_ids(self, cr, uid, ids, partner_ids=[], context=None):
- if partner_ids and isinstance(partner_ids[0], (list, tuple)):
- partner_ids = partner_ids[0][2]
- else:
- partner_ids = []
- return {'domain': {'dst_partner_id': [('id', 'in', partner_ids)]}}
+ _defaults = {
+ 'state': 'option'
+ }
def get_fk_on(self, cr, table):
q = """ SELECT cl1.relname as table,
@@ -262,7 +266,6 @@ class MergePartnerAutomatic(osv.TransientModel):
if field._type not in ('many2many', 'one2many', 'function'):
for item in itertools.chain(src_partners, [dst_partner]):
if item[column]:
- print column, item[column]
values[column] = write_serializer(column, item[column])
values.pop('id', None)
@@ -275,19 +278,15 @@ class MergePartnerAutomatic(osv.TransientModel):
_logger.info('Skip recursive partner hierarchies for parent_id %s of partner: %s', parent_id, dst_partner.id)
@mute_logger('openerp.osv.expression', 'openerp.osv.orm')
- def _merge(self, cr, uid, partner_ids, dst_partner_id=None, context=None):
+ def _merge(self, cr, uid, partner_ids, dst_partner=None, context=None):
proxy = self.pool.get('res.partner')
partner_ids = proxy.exists(cr, uid, list(partner_ids), context=context)
if len(partner_ids) < 2:
return
- if dst_partner_id and dst_partner_id in partner_ids:
- partner_obj = self.pool.get('res.partner')
- def f(x):
- return x != dst_partner_id
- src_partners = partner_obj.browse(cr, uid, list(filter(f, partner_ids)), context=context)
- dst_partner = partner_obj.browse(cr, uid, list(partner_ids), context=context)
+ if dst_partner and dst_partner.id in partner_ids:
+ src_partners = proxy.browse(cr, uid, [id for id in partner_ids if id != dst_partner.id], context=context)
else:
ordered_partners = self._get_ordered_partner(cr, uid, partner_ids, context)
dst_partner = ordered_partners[-1]
@@ -707,52 +706,11 @@ class MergePartnerAutomatic(osv.TransientModel):
self._merge(cr, uid, partner_ids, this.dst_partner_id, context=context)
- this.current_line_id.unlink()
+ if this.current_line_id:
+ this.current_line_id.unlink()
return self._next_screen(cr, uid, this, context)
- def merge_multi(self, cr, uid, ids, context=None):
-
- active_model = context.get('active_model')
- if active_model != 'res.partner':
- raise osv.except_osv(
- _('Error'),
- _('This wizard can only used with the Partners')
- )
-
- partner_ids = context.get('active_ids', [])
-
- MINIMAL_NUMBER = 2
- if len(partner_ids) < MINIMAL_NUMBER:
- raise osv.except_osv(
- _('Error'),
- _("You can't use this wizard with only one Partner")
- )
-
- ordered_partner = self._get_ordered_partner(cr, uid, partner_ids, context)
- def f(x): return x.id
-
- current_line_id = self.pool.get('base.partner.merge.line').create(cr, uid, {'min_id': ordered_partner[-1].id, 'aggr_ids': map(f, ordered_partner)})
- context.update({
- 'default_state': 'selection',
- 'default_partner_ids': [(6, 0, partner_ids)],
- 'default_dst_partner_id': ordered_partner[-1].id,
- 'default_current_line_id': current_line_id,
- 'default_number_group': 1,
- 'default_maximum_group': 1,
- })
-
- action = {
- 'view_type': 'form',
- 'view_mode': 'form',
- 'res_model': self._name,
- 'res_id': False,
- 'type': 'ir.actions.act_window',
- 'target': 'new',
- 'context': context
- }
- return action
-
def auto_set_parent_id(self, cr, uid, ids, context=None):
assert is_integer_list(ids)
diff --git a/addons/crm/base_partner_merge_view.xml b/addons/crm/base_partner_merge_view.xml
index dd344b122bc..8ce0b5fd99f 100644
--- a/addons/crm/base_partner_merge_view.xml
+++ b/addons/crm/base_partner_merge_view.xml
@@ -68,9 +68,9 @@
OpenERP will propose you to merge only those having
all these fields in common. (not one of the fields).
-
+
-
+
@@ -98,16 +98,15 @@
redirected to the aggregated contact. You can remove
contacts from this list to avoid merging them.
-
-
+
+
-
+
-
@@ -115,24 +114,9 @@
-
-
- action = pool.get('base.partner.merge.automatic.wizard').merge_multi(cr, uid, None, context)
- True
-
- Automatic Merge
-
- code
- ir.actions.server
-
-
-
-
- res.partner
- Automatic Merge
-
-
+
+
From b6f6b718cad48f83d92d3f4378a2437c8e20b538 Mon Sep 17 00:00:00 2001
From: Christophe Matthieu
Date: Fri, 17 May 2013 10:50:40 +0200
Subject: [PATCH 4/6] [IMP] base_partner_merge: use SUPERUSER_ID for merged
contact. Add exception when the active user is not the SUPERUSER_ID if the
emails is differents or if they are more of one contact with Journal Items.
bzr revid: chm@openerp.com-20130517085040-u9n1v0a22uruqhca
---
addons/crm/base_partner_merge.py | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index f51d6afb188..743f14000a8 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -13,6 +13,7 @@ from openerp.tools import mute_logger
# Validation Library https://pypi.python.org/pypi/validate_email/1.1
from .validate_email import validate_email
+import openerp
from openerp.osv import osv, orm
from openerp.osv import fields
from openerp.osv.orm import browse_record
@@ -216,8 +217,8 @@ class MergePartnerAutomatic(osv.TransientModel):
if proxy is None:
return
domain = [(field_model, '=', 'res.partner'), (field_id, '=', src.id)]
- ids = proxy.search(cr, uid, domain, context=context)
- return proxy.write(cr, uid, ids, {field_id: dst_partner.id}, context=context)
+ ids = proxy.search(cr, openerp.SUPERUSER_ID, domain, context=context)
+ return proxy.write(cr, openerp.SUPERUSER_ID, ids, {field_id: dst_partner.id}, context=context)
update_records = functools.partial(update_records, context=context)
@@ -231,9 +232,9 @@ class MergePartnerAutomatic(osv.TransientModel):
proxy = self.pool['ir.model.fields']
domain = [('ttype', '=', 'reference')]
- record_ids = proxy.search(cr, uid, domain, context=context)
+ record_ids = proxy.search(cr, openerp.SUPERUSER_ID, domain, context=context)
- for record in proxy.browse(cr, uid, record_ids, context=context):
+ for record in proxy.browse(cr, openerp.SUPERUSER_ID, record_ids, context=context):
proxy_model = self.pool[record.model]
field_type = proxy_model._columns.get(record.name).__class__._type
@@ -245,11 +246,11 @@ class MergePartnerAutomatic(osv.TransientModel):
domain = [
(record.name, '=', 'res.partner,%d' % partner.id)
]
- model_ids = proxy_model.search(cr, uid, domain, context=context)
+ model_ids = proxy_model.search(cr, openerp.SUPERUSER_ID, domain, context=context)
values = {
record.name: 'res.partner,%d' % dst_partner.id,
}
- proxy_model.write(cr, uid, model_ids, values, context=context)
+ proxy_model.write(cr, openerp.SUPERUSER_ID, model_ids, values, context=context)
def _update_values(self, cr, uid, src_partners, dst_partner, context=None):
_logger.debug('_update_values for dst_partner: %s for src_partners: %r', dst_partner.id, list(map(operator.attrgetter('id'), src_partners)))
@@ -285,6 +286,9 @@ class MergePartnerAutomatic(osv.TransientModel):
if len(partner_ids) < 2:
return
+ if openerp.SUPERUSER_ID != uid and len([partner.email for partner in proxy.browse(cr, uid, partner_ids, context=context)]) > 1:
+ raise osv.except_osv(_('Error'), _("All contacts must have the same email address. Only your Administrator can merge several contacts with different email address."))
+
if dst_partner and dst_partner.id in partner_ids:
src_partners = proxy.browse(cr, uid, [id for id in partner_ids if id != dst_partner.id], context=context)
else:
@@ -293,6 +297,10 @@ class MergePartnerAutomatic(osv.TransientModel):
src_partners = ordered_partners[:-1]
_logger.info("dst_partner: %s", dst_partner.id)
+ if openerp.SUPERUSER_ID != uid and self._model_is_installed(cr, uid, 'account.move.line', context=context) and \
+ self.pool.get('account.move.line').search(cr, openerp.SUPERUSER_ID, [('partner_id', 'in', [partner.id for partner in src_partners])], context=context):
+ raise osv.except_osv(_('Error'), _("Only one contact can have Journal Items, and this contact must be the destination contact. Only your Administrator can merge several contacts with Journal Items."))
+
call_it = lambda function: function(cr, uid, src_partners, dst_partner,
context=context)
@@ -300,12 +308,11 @@ class MergePartnerAutomatic(osv.TransientModel):
call_it(self._update_reference_fields)
call_it(self._update_values)
- _logger.info("---merged---")
+ _logger.info('(uid = %s) merged the partners %r with %s', uid, list(map(operator.attrgetter('id'), src_partners)), dst_partner.id)
for partner in src_partners:
partner.unlink()
-
def clean_emails(self, cr, uid, context=None):
"""
Clean the email address of the partner, if there is an email field with
@@ -756,4 +763,3 @@ class MergePartnerAutomatic(osv.TransientModel):
WHERE id != %s AND email LIKE '%%%s'
""" % (id, id, email))
return False
-
From a5bf0f3181492ee4bc6014ba0da9b84c0a136772 Mon Sep 17 00:00:00 2001
From: Olivier Dony
Date: Wed, 22 May 2013 13:11:31 +0200
Subject: [PATCH 5/6] [FIX] crm: partner merge wizard: fix detection of
duplicate emails + improve error messages
bzr revid: odo@openerp.com-20130522111131-y1urx7qx280f3tdl
---
addons/crm/base_partner_merge.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index 743f14000a8..d2d964833b3 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -286,8 +286,8 @@ class MergePartnerAutomatic(osv.TransientModel):
if len(partner_ids) < 2:
return
- if openerp.SUPERUSER_ID != uid and len([partner.email for partner in proxy.browse(cr, uid, partner_ids, context=context)]) > 1:
- raise osv.except_osv(_('Error'), _("All contacts must have the same email address. Only your Administrator can merge several contacts with different email address."))
+ if openerp.SUPERUSER_ID != uid and len(set(partner.email for partner in proxy.browse(cr, uid, partner_ids, context=context))) > 1:
+ raise osv.except_osv(_('Error'), _("All contacts must have the same email. Only the Administrator can merge contacts with different emails."))
if dst_partner and dst_partner.id in partner_ids:
src_partners = proxy.browse(cr, uid, [id for id in partner_ids if id != dst_partner.id], context=context)
@@ -299,7 +299,7 @@ class MergePartnerAutomatic(osv.TransientModel):
if openerp.SUPERUSER_ID != uid and self._model_is_installed(cr, uid, 'account.move.line', context=context) and \
self.pool.get('account.move.line').search(cr, openerp.SUPERUSER_ID, [('partner_id', 'in', [partner.id for partner in src_partners])], context=context):
- raise osv.except_osv(_('Error'), _("Only one contact can have Journal Items, and this contact must be the destination contact. Only your Administrator can merge several contacts with Journal Items."))
+ raise osv.except_osv(_('Error'), _("Only the destination contact may be linked to existing Journal Items. Please ask the Administrator if you need to merge several contacts linked to existing Journal Items."))
call_it = lambda function: function(cr, uid, src_partners, dst_partner,
context=context)
From 8def4f274a64dcdcf1d397467b44ade50fbdb22f Mon Sep 17 00:00:00 2001
From: Olivier Dony
Date: Wed, 22 May 2013 13:54:08 +0200
Subject: [PATCH 6/6] [IMP] crm: partner merge wizard: prevent merging more
than 3 contacts together + log note in partner history
bzr revid: odo@openerp.com-20130522115408-ef82getdyo2otg3q
---
addons/crm/base_partner_merge.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py
index d2d964833b3..0a8e37b14b7 100644
--- a/addons/crm/base_partner_merge.py
+++ b/addons/crm/base_partner_merge.py
@@ -286,6 +286,9 @@ class MergePartnerAutomatic(osv.TransientModel):
if len(partner_ids) < 2:
return
+ if len(partner_ids) > 3:
+ raise osv.except_osv(_('Error'), _("For safety reasons, you cannot merge more than 3 contacts together. You can re-open the wizard several times if needed."))
+
if openerp.SUPERUSER_ID != uid and len(set(partner.email for partner in proxy.browse(cr, uid, partner_ids, context=context))) > 1:
raise osv.except_osv(_('Error'), _("All contacts must have the same email. Only the Administrator can merge contacts with different emails."))
@@ -309,7 +312,8 @@ class MergePartnerAutomatic(osv.TransientModel):
call_it(self._update_values)
_logger.info('(uid = %s) merged the partners %r with %s', uid, list(map(operator.attrgetter('id'), src_partners)), dst_partner.id)
-
+ dst_partner.message_post(body='%s %s'%(_("Merged with the following partners:"), ", ".join('%s<%s>(ID %s)' % (p.name, p.email or 'n/a', p.id) for p in src_partners)))
+
for partner in src_partners:
partner.unlink()