Skip to content

Commit

Permalink
[FIX] event_registration_partner_unique: avoid constraint on merge
Browse files Browse the repository at this point in the history
When a user merges two contacts an error will raise if there are event
with a unique partner constraint when both partner were atendees. With
these changes, we let the user get rid of those duplicated attendees.

TT45921
  • Loading branch information
chienandalu committed Nov 14, 2023
1 parent 80a92d9 commit 6218ee7
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 24 deletions.
2 changes: 1 addition & 1 deletion event_registration_partner_unique/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Unique Partner per Event
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:fa39a5416b9a53ff743d770b11ab214277fe38d04077dfa770174e259f481c29
!! source digest: sha256:3d53fec9f6993c3a355d0cac4a4fc844e5290c7466ea731d4f6174c8486d9249
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
1 change: 1 addition & 0 deletions event_registration_partner_unique/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from . import models
from . import wizards
2 changes: 1 addition & 1 deletion event_registration_partner_unique/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@
"application": False,
"installable": True,
"depends": ["event", "partner_event"],
"data": ["views/event_event_view.xml"],
"data": ["views/event_event_view.xml", "wizards/base_partner_merge_views.xml"],
}
35 changes: 23 additions & 12 deletions event_registration_partner_unique/models/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class EventEvent(models.Model):
@api.constrains("forbid_duplicates", "registration_ids")
def _check_forbid_duplicates(self):
"""Ensure no duplicated attendee are found in the event."""
if self.env.context.get("skip_registration_partner_unique"):
return

Check warning on line 22 in event_registration_partner_unique/models/event.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/models/event.py#L22

Added line #L22 was not covered by tests
return self.filtered(
"forbid_duplicates"
).registration_ids._check_forbid_duplicates()
Expand All @@ -29,19 +31,28 @@ class EventRegistration(models.Model):
@api.constrains("event_id", "attendee_partner_id")
def _check_forbid_duplicates(self):
"""Ensure no duplicated attendees are found in the event."""
if self.env.context.get("skip_registration_partner_unique"):
return

Check warning on line 35 in event_registration_partner_unique/models/event.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/models/event.py#L35

Added line #L35 was not covered by tests
for event_reg, dupes in self._find_duplicated_attendees():
if not dupes:
continue
raise ValidationError(
_("Duplicated partners found in event %(name)s: %(partners)s.")
% {
"name": event_reg.event_id.display_name,
"partners": ", ".join(
partner_id.display_name
for partner_id in dupes.mapped("attendee_partner_id")
),
}
)

def _find_duplicated_attendees(self):
for event_reg in self.filtered("event_id.forbid_duplicates"):
dupes = self.search(event_reg._duplicate_search_domain())
if dupes:
raise ValidationError(
_("Duplicated partners found in event %(name)s: %(partners)s.")
% {
"name": event_reg.event_id.display_name,
"partners": ", ".join(
partner_id.display_name
for partner_id in dupes.mapped("attendee_partner_id")
),
}
)
dupes = self.search(
event_reg._duplicate_search_domain(), order="create_date desc"
)
yield event_reg, dupes

def _duplicate_search_domain(self):
"""What to look for when searching duplicates."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ <h1 class="title">Unique Partner per Event</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:fa39a5416b9a53ff743d770b11ab214277fe38d04077dfa770174e259f481c29
!! source digest: sha256:3d53fec9f6993c3a355d0cac4a4fc844e5290c7466ea731d4f6174c8486d9249
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/event/tree/15.0/event_registration_partner_unique"><img alt="OCA/event" src="https://img.shields.io/badge/github-OCA%2Fevent-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/event-15-0/event-15-0-event_registration_partner_unique"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/event&amp;target_branch=15.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module is intended for backend use only, and extends the functionality
Expand Down
36 changes: 27 additions & 9 deletions event_registration_partner_unique/tests/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,39 @@
# Copyright 2020 Tecnativa - Víctor Martínez
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

from odoo import fields
from odoo.exceptions import ValidationError
from odoo.tests.common import TransactionCase


class DuplicatedPartnerCase(TransactionCase):
def setUp(self):
super().setUp()
self.event = self.env.ref("event.event_0")
self.event.forbid_duplicates = False
self.partner = self.env.ref("base.res_partner_1")
self.registration = self.env["event.registration"].create(
@classmethod
def setUpClass(cls):
super().setUpClass()
# Remove this variable in v16 and put instead:
# from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT
DISABLED_MAIL_CONTEXT = {
"tracking_disable": True,
"mail_create_nolog": True,
"mail_create_nosubscribe": True,
"mail_notrack": True,
"no_reset_password": True,
}
cls.env = cls.env(context=dict(cls.env.context, **DISABLED_MAIL_CONTEXT))
cls.event = cls.env["event.event"].create(
{
"event_id": self.event.id,
"partner_id": self.partner.id,
"attendee_partner_id": self.partner.id,
"name": "Test event",
"date_begin": fields.Datetime.now(),
"date_end": fields.Datetime.now(),
}
)
cls.event.forbid_duplicates = False
cls.partner = cls.env["res.partner"].create({"name": "Mr. Odoo"})
cls.registration = cls.env["event.registration"].create(
{
"event_id": cls.event.id,
"partner_id": cls.partner.id,
"attendee_partner_id": cls.partner.id,
}
)

Expand Down
1 change: 1 addition & 0 deletions event_registration_partner_unique/wizards/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import base_partner_merge
33 changes: 33 additions & 0 deletions event_registration_partner_unique/wizards/base_partner_merge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright 2023 Tecnativa - David Vidal
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models


class BasePartnerMergeAutomaticWizard(models.TransientModel):
_inherit = "base.partner.merge.automatic.wizard"

merge_duplicated_registrations = fields.Boolean(
help="If the merged partners were linked to registrations in an event that had "
"unique attendees flag we'll take only the oldest one",
)

def action_merge(self):
"""Allow to get rid of duplicated registrations linked to the merged partners"""
if not self.merge_duplicated_registrations:
return super().action_merge()

Check warning on line 17 in event_registration_partner_unique/wizards/base_partner_merge.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/wizards/base_partner_merge.py#L17

Added line #L17 was not covered by tests
# Skip the constraints and do the partner merge first
res = super(

Check warning on line 19 in event_registration_partner_unique/wizards/base_partner_merge.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/wizards/base_partner_merge.py#L19

Added line #L19 was not covered by tests
BasePartnerMergeAutomaticWizard,
self.with_context(skip_registration_partner_unique=True),
).action_merge()
# Now let's merge the attendees
dupes_to_unlink = self.env["event.registration"]
partner_registrations = self.dst_partner_id.event_registration_ids

Check warning on line 25 in event_registration_partner_unique/wizards/base_partner_merge.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/wizards/base_partner_merge.py#L24-L25

Added lines #L24 - L25 were not covered by tests
for attendee, dupes in partner_registrations._find_duplicated_attendees():
# Keep the oldest one -> min id will be
event_attendees_for_partner = attendee + dupes

Check warning on line 28 in event_registration_partner_unique/wizards/base_partner_merge.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/wizards/base_partner_merge.py#L28

Added line #L28 was not covered by tests
attendee_to_keep = min(event_attendees_for_partner, key=lambda x: x.id)
dupes_to_unlink += event_attendees_for_partner - attendee_to_keep

Check warning on line 30 in event_registration_partner_unique/wizards/base_partner_merge.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/wizards/base_partner_merge.py#L30

Added line #L30 was not covered by tests
# Call with skipping context to avoid triggering the constraint again
dupes_to_unlink.with_context(skip_registration_partner_unique=True).unlink()
return res

Check warning on line 33 in event_registration_partner_unique/wizards/base_partner_merge.py

View check run for this annotation

Codecov / codecov/patch

event_registration_partner_unique/wizards/base_partner_merge.py#L32-L33

Added lines #L32 - L33 were not covered by tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="base_partner_merge_automatic_wizard_form" model="ir.ui.view">
<field name="inherit_id" ref="base.base_partner_merge_automatic_wizard_form" />
<field name='model'>base.partner.merge.automatic.wizard</field>
<field name='arch' type='xml'>
<field name="dst_partner_id" position="after">
<field name="merge_duplicated_registrations" />
</field>
</field>
</record>
</odoo>

0 comments on commit 6218ee7

Please sign in to comment.