From c7b53b8f68e394cb09ee6c028c483c40a1e21e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Tue, 21 Nov 2023 11:37:06 +0100 Subject: [PATCH] [FIX] mail: batch _inverse_notification_type This makes the "medium" populate of `res.users` take few seconds rather than 2min30 on my machine. The issue was that `write` (not in batch) is calling `_subscribe_users_automatically` not in batch, which is particularly slow. `discuss_channel_nosubscribe` is removed because it was uneffective. The condition was only on create, but the group change in `_inverse_notification_type` was systematically triggering the auto-subscribe outside of create anyway, which is what we want. Part-of: odoo/odoo#142734 --- addons/mail/models/discuss/res_users.py | 6 +----- addons/mail/models/res_users.py | 10 ++++------ addons/mail/tests/common.py | 4 +--- .../tests/discuss/test_discuss_channel_member.py | 16 ++++++++-------- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/addons/mail/models/discuss/res_users.py b/addons/mail/models/discuss/res_users.py index 00befd533e1..7f20ce5d366 100644 --- a/addons/mail/models/discuss/res_users.py +++ b/addons/mail/models/discuss/res_users.py @@ -10,11 +10,7 @@ class ResUsers(models.Model): @api.model_create_multi def create(self, vals_list): users = super().create(vals_list) - # Auto-subscribe to channels unless skip explicitly requested - if not self.env.context.get("discuss_channel_nosubscribe"): - self.env["discuss.channel"].search( - [("group_ids", "in", users.groups_id.ids)] - )._subscribe_users_automatically() + self.env["discuss.channel"].search([("group_ids", "in", users.groups_id.ids)])._subscribe_users_automatically() return users def write(self, vals): diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 1169ddd9096..559ae1613f7 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -2,7 +2,7 @@ from collections import defaultdict -from odoo import _, api, fields, models, modules, tools +from odoo import _, api, Command, fields, models, modules, tools from odoo.tools import email_normalize @@ -53,11 +53,9 @@ class Users(models.Model): def _inverse_notification_type(self): inbox_group = self.env.ref('mail.group_mail_notification_type_inbox') - for user in self: - if user.notification_type == 'inbox': - user.groups_id += inbox_group - else: - user.groups_id -= inbox_group + inbox_users = self.filtered(lambda user: user.notification_type == 'inbox') + inbox_users.write({"groups_id": [Command.link(inbox_group.id)]}) + (self - inbox_users).write({"groups_id": [Command.unlink(inbox_group.id)]}) # ------------------------------------------------------------ # CRUD diff --git a/addons/mail/tests/common.py b/addons/mail/tests/common.py index fc8c4b7cc32..97a81e22f5f 100644 --- a/addons/mail/tests/common.py +++ b/addons/mail/tests/common.py @@ -27,8 +27,7 @@ from odoo.tools.translate import code_translations mail_new_test_user = partial(new_test_user, context={'mail_create_nolog': True, 'mail_create_nosubscribe': True, 'mail_notrack': True, - 'no_reset_password': True, - 'discuss_channel_nosubscribe': True}) + 'no_reset_password': True}) class MockEmail(common.BaseCase, MockSmtplibCase): @@ -736,7 +735,6 @@ class MailCase(MockEmail): ("UNKNOWN", "Unknown error") """ _test_context = { - 'discuss_channel_nosubscribe': True, 'mail_create_nolog': True, 'mail_create_nosubscribe': True, 'mail_notrack': True, diff --git a/addons/mail/tests/discuss/test_discuss_channel_member.py b/addons/mail/tests/discuss/test_discuss_channel_member.py index 580f0032257..8a742fcc351 100644 --- a/addons/mail/tests/discuss/test_discuss_channel_member.py +++ b/addons/mail/tests/discuss/test_discuss_channel_member.py @@ -1,8 +1,8 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo.addons.mail.tests.common import MailCommon, mail_new_test_user +from odoo.addons.mail.tests.common import MailCommon from odoo.exceptions import AccessError, UserError, ValidationError -from odoo.tests.common import tagged +from odoo.tests.common import new_test_user, tagged @tagged("post_install", "-at_install") @@ -20,19 +20,19 @@ class TestDiscussChannelMember(MailCommon): 'model': cls.secret_group._name, 'res_id': cls.secret_group.id, }) - cls.user_1 = mail_new_test_user( + cls.user_1 = new_test_user( cls.env, login="user_1", name="User 1", groups="base.group_user,mail.secret_group" ) - cls.user_2 = mail_new_test_user( + cls.user_2 = new_test_user( cls.env, login="user_2", name="User 2", groups="base.group_user,mail.secret_group" ) - cls.user_3 = mail_new_test_user( + cls.user_3 = new_test_user( cls.env, login="user_3", name="User 3", groups="base.group_user,mail.secret_group" ) - cls.user_portal = mail_new_test_user( + cls.user_portal = new_test_user( cls.env, login="user_portal", name="User Portal", groups="base.group_portal" ) - cls.user_public = mail_new_test_user( + cls.user_public = new_test_user( cls.env, login="user_public", name="User Public", groups="base.group_public" ) @@ -75,7 +75,7 @@ class TestDiscussChannelMember(MailCommon): }) # User 2 can not write on `discuss.channel.member` to join the group - channel_member = self.env['discuss.channel.member'].with_user(self.user_2).search([('partner_id', '=', self.user_2.partner_id.id)])[0] + channel_member = self.env['discuss.channel.member'].with_user(self.user_2).search([('is_self', '=', True)])[0] with self.assertRaises(AccessError): channel_member.channel_id = self.group.id with self.assertRaises(AccessError):