From c18ce5d535474f8cd69ef0711fcefd015ed32da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=20De=20Caluw=C3=A9?= Date: Tue, 4 Oct 2022 14:12:03 +0000 Subject: [PATCH] [FIX] mail: remove related mail activities on model removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unlinking a model during uninstallation can potentially fail when the query removing any related mail activity types fails. This happens when such a record is still referenced in the mail_activity table. Explicitly removing related mail activities (as is done for the activity types and other related mail data) resolves the issue. Two tests are added, one that demonstrates the general flow and a regression test triggering the behavior that caused a bug in the uninstall procedure of the hr_holidays module. closes odoo/odoo#104152 X-original-commit: b315f7f562fc84a09d99d6e7676567eb6f285402 Signed-off-by: Raphael Collet Signed-off-by: De Caluwé Tom (tdc) --- addons/hr_holidays/tests/__init__.py | 1 + addons/hr_holidays/tests/test_uninstall.py | 28 +++++++++++++++++++ addons/mail/models/ir_model.py | 4 +++ addons/mail/tests/__init__.py | 1 + addons/mail/tests/test_uninstall.py | 31 ++++++++++++++++++++++ 5 files changed, 65 insertions(+) create mode 100644 addons/hr_holidays/tests/test_uninstall.py create mode 100644 addons/mail/tests/test_uninstall.py diff --git a/addons/hr_holidays/tests/__init__.py b/addons/hr_holidays/tests/__init__.py index f983d595fc5..da196a0ade6 100644 --- a/addons/hr_holidays/tests/__init__.py +++ b/addons/hr_holidays/tests/__init__.py @@ -16,3 +16,4 @@ from . import test_company_leave from . import test_res_partner from . import test_stress_days from . import test_global_leaves +from . import test_uninstall diff --git a/addons/hr_holidays/tests/test_uninstall.py b/addons/hr_holidays/tests/test_uninstall.py new file mode 100644 index 00000000000..461e1ab7e21 --- /dev/null +++ b/addons/hr_holidays/tests/test_uninstall.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG +from odoo.tests import tagged, TransactionCase + + +@tagged('-at_install', 'post_install') +class TestHrLeaveUninstall(TransactionCase): + def test_unlink_model(self): + model = self.env['ir.model'].search([('model', '=', 'hr.leave')]) + activity_type = self.env['mail.activity'].search([ + ('res_model', '=', 'hr.leave') + ]).activity_type_id + + self.assertTrue(activity_type) + self.assertIn('hr.leave', activity_type.mapped('res_model')) + + model.sudo().with_context(**{MODULE_UNINSTALL_FLAG: True}).unlink() + self.assertFalse(model.exists()) + + domain = [('res_model', '=', 'hr.leave')] + self.assertFalse(self.env['mail.activity'].search(domain)) + self.assertFalse(self.env['mail.activity.type'].search(domain)) + self.assertFalse(self.env['mail.followers'].search(domain)) + self.assertFalse(self.env['mail.message'].search([ + ('model', '=', 'hr.leave'), + ])) diff --git a/addons/mail/models/ir_model.py b/addons/mail/models/ir_model.py index d763849132b..55e62cc9ebe 100644 --- a/addons/mail/models/ir_model.py +++ b/addons/mail/models/ir_model.py @@ -22,6 +22,10 @@ class IrModel(models.Model): def unlink(self): # Delete followers, messages and attachments for models that will be unlinked. models = tuple(self.mapped('model')) + model_ids = tuple(self.ids) + + query = "DELETE FROM mail_activity WHERE res_model_id IN %s" + self.env.cr.execute(query, [model_ids]) query = "DELETE FROM mail_activity_type WHERE res_model IN %s" self.env.cr.execute(query, [models]) diff --git a/addons/mail/tests/__init__.py b/addons/mail/tests/__init__.py index eaf51ea9ab6..4f050f4c3cd 100644 --- a/addons/mail/tests/__init__.py +++ b/addons/mail/tests/__init__.py @@ -14,4 +14,5 @@ from . import test_res_partner from . import test_res_users from . import test_res_users_settings from . import test_rtc +from . import test_uninstall from . import test_update_notification diff --git a/addons/mail/tests/test_uninstall.py b/addons/mail/tests/test_uninstall.py new file mode 100644 index 00000000000..07a59a4ca97 --- /dev/null +++ b/addons/mail/tests/test_uninstall.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests import tagged, TransactionCase + + +@tagged('-at_install', 'post_install') +class TestMailUninstall(TransactionCase): + def test_unlink_model(self): + model = self.env['ir.model'].create({ + 'name': 'Test Model', + 'model': 'x_test_model', + 'state': 'manual', + 'is_mail_thread': True, + }) + activity_type = self.env['mail.activity.type'].create({ + 'name': 'Test Activity Type', + 'res_model': model.model, + }) + record = self.env[model.model].create({}) + + activity = self.env['mail.activity'].create({ + 'activity_type_id': activity_type.id, + 'res_model_id': model.id, + 'res_id': record.id, + }) + + model.unlink() + self.assertFalse(model.exists()) + self.assertFalse(activity_type.exists()) + self.assertFalse(activity.exists())