[IMP] runbot_merge: support for merging partners w/ github_login

The logic of the partner merge wizard is to collect all relevant data
from source partners, write them to a destination partner, then remove
the sources.

This... doesn't work when the field in question has a UNIQUE
constraint (like github_login), because it's going to copy the value
from a source onto a dest which will blow the constraint, and so the
copy fails. In that case the user first has to *move over* the unique
field's value then they can use the wizard.

Just fix for the github login: take all sources, remove (and store)
their github logins, then write the login onto the dst.

An alternative would have been to *defer* the constraint, however:

* it only works on unique constraints, not unique indexes
* it requires the constraint to be declared DEFERRABLE

Closes #301
This commit is contained in:
Xavier Morel 2020-03-16 14:16:01 +01:00
parent 1440aec251
commit 5f8ad6a626
3 changed files with 42 additions and 0 deletions

View File

@ -1063,6 +1063,10 @@ class Model:
return val
# because it's difficult to discriminate between methods and fields
def _call(self, name, *args, **kwargs):
return self._env(self._model, name, self._ids, *args, **kwargs)
def __setattr__(self, fieldname, value):
assert self._fields[fieldname]['type'] not in ('many2one', 'one2many', 'many2many')
self._env(self._model, 'write', self._ids, {fieldname: value})

View File

@ -31,6 +31,22 @@ class Partner(models.Model):
email = ''
partner.formatted_email = '%s <%s>' % (partner.name, email)
class PartnerMerge(models.TransientModel):
_inherit = 'base.partner.merge.automatic.wizard'
@api.model
def _update_values(self, src_partners, dst_partner):
# sift down through src partners, removing all github_login and keeping
# the last one
new_login = None
for p in src_partners:
new_login = p.github_login or new_login
if new_login:
src_partners.write({'github_login': False})
if new_login and not dst_partner.github_login:
dst_partner.github_login = new_login
super()._update_values(src_partners, dst_partner)
class ReviewRights(models.Model):
_name = 'res.partner.review'
_description = "mapping of review rights between partners and repos"

View File

@ -0,0 +1,22 @@
def test_partner_merge(env):
p_src = env['res.partner'].create({
'name': 'kfhsf',
'github_login': 'tyu'
}) | env['res.partner'].create({
'name': "xxx",
'github_login': 'xxx'
})
# proper login with useful info
p_dest = env['res.partner'].create({
'name': 'Partner P. Partnersson',
'github_login': ''
})
env['base.partner.merge.automatic.wizard'].create({
'state': 'selection',
'partner_ids': (p_src + p_dest).ids,
'dst_partner_id': p_dest.id,
})._call('action_merge')
assert not p_src.exists()
assert p_dest.name == 'Partner P. Partnersson'
assert p_dest.github_login == 'xxx'