Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion base_ux/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
##############################################################################
{
"name": "Base UX",
"version": "19.0.1.4.0",
"version": "19.0.1.5.0",
"category": "Base",
"sequence": 14,
"summary": "",
Expand Down
1 change: 1 addition & 0 deletions base_ux/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# directory
##############################################################################
from . import ir_actions_act_window
from . import base_partner_merge
from . import res_partner
from . import res_country_state
from . import res_company
Expand Down
47 changes: 47 additions & 0 deletions base_ux/models/base_partner_merge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
##############################################################################
# For copyright and license notices, see __manifest__.py file in module root
# directory
##############################################################################
from collections import defaultdict

from odoo import Command, models


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

def _deduplicate_mail_followers(self, src_partners, dst_partner):
followers_by_document = defaultdict(lambda: self.env["mail.followers"])
partners_to_merge = src_partners | dst_partner
followers = (
self.env["mail.followers"]
.sudo()
.search(
[
("partner_id", "in", partners_to_merge.ids),
]
)
)

for follower in followers:
res_id = follower.res_id.id if hasattr(follower.res_id, "id") else follower.res_id
key = (follower.res_model, res_id or 0)
followers_by_document[key] = followers_by_document[key] | follower

for grouped_followers in followers_by_document.values():
if len(grouped_followers) < 2:
continue

keeper = grouped_followers.filtered(lambda follower: follower.partner_id == dst_partner)[:1]
keeper = keeper or grouped_followers[:1]
duplicates = grouped_followers - keeper
subtype_ids = grouped_followers.mapped("subtype_ids")

if set(subtype_ids.ids) != set(keeper.subtype_ids.ids):
keeper.write({"subtype_ids": [Command.set(subtype_ids.ids)]})

duplicates.unlink()

def _update_foreign_keys(self, src_partners, dst_partner):
self._deduplicate_mail_followers(src_partners, dst_partner)
return super()._update_foreign_keys(src_partners, dst_partner)
1 change: 1 addition & 0 deletions base_ux/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_base_partner_merge
69 changes: 69 additions & 0 deletions base_ux/tests/test_base_partner_merge.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
##############################################################################
# For copyright and license notices, see __manifest__.py file in module root
# directory
##############################################################################
from odoo import Command
from odoo.tests import Form, TransactionCase, tagged


@tagged("-at_install", "post_install")
class TestBasePartnerMerge(TransactionCase):
def test_merge_partners_with_duplicated_followers(self):
partner_model = self.env["res.partner"]
followers_model = self.env["mail.followers"].sudo()
subtype_comment = self.env.ref("mail.mt_comment")
subtype_note = self.env.ref("mail.mt_note")

document_partner = partner_model.create({"name": "Document partner"})
src_partner = partner_model.create({"name": "Source partner", "email": "merge@test.example.com"})
extra_src_partner = partner_model.create({"name": "Extra source", "email": "merge@test.example.com"})
dst_partner = partner_model.create({"name": "Destination partner", "email": "merge@test.example.com"})

followers_model.create(
[
{
"res_model": document_partner._name,
"res_id": document_partner.id,
"partner_id": src_partner.id,
"subtype_ids": [Command.set(subtype_comment.ids)],
},
{
"res_model": document_partner._name,
"res_id": document_partner.id,
"partner_id": extra_src_partner.id,
"subtype_ids": [Command.set(subtype_note.ids)],
},
{
"res_model": document_partner._name,
"res_id": document_partner.id,
"partner_id": dst_partner.id,
},
]
)

merge_form = Form(
self.env["base.partner.merge.automatic.wizard"].with_context(
active_model="res.partner",
active_ids=(src_partner | extra_src_partner | dst_partner).ids,
)
)
merge_form.dst_partner_id = dst_partner
merge_wizard = merge_form.save()

merge_wizard.action_merge()

self.assertFalse(src_partner.exists())
self.assertFalse(extra_src_partner.exists())
self.assertTrue(dst_partner.exists())

merged_followers = followers_model.search(
[
("res_model", "=", document_partner._name),
("res_id", "=", document_partner.id),
("partner_id", "in", [src_partner.id, extra_src_partner.id, dst_partner.id]),
]
)

self.assertEqual(len(merged_followers), 1)
self.assertEqual(merged_followers.partner_id, dst_partner)
self.assertSetEqual(set(merged_followers.subtype_ids.ids), {subtype_comment.id, subtype_note.id})
Loading