diff --git a/addons/auth_signup/views/res_users_views.xml b/addons/auth_signup/views/res_users_views.xml index 02705599b8c..5e2383ccb48 100644 --- a/addons/auth_signup/views/res_users_views.xml +++ b/addons/auth_signup/views/res_users_views.xml @@ -38,11 +38,9 @@ res.users - - state == 'new' - - - + + diff --git a/addons/auth_totp/views/res_users_views.xml b/addons/auth_totp/views/res_users_views.xml index ba5e8f7ce6f..b9a95e5d9c7 100644 --- a/addons/auth_totp/views/res_users_views.xml +++ b/addons/auth_totp/views/res_users_views.xml @@ -8,7 +8,6 @@ - diff --git a/addons/calendar/views/calendar_views.xml b/addons/calendar/views/calendar_views.xml index be9f9066f65..400712cb5fb 100644 --- a/addons/calendar/views/calendar_views.xml +++ b/addons/calendar/views/calendar_views.xml @@ -346,7 +346,8 @@ - + diff --git a/addons/crm_livechat/tests/test_crm_lead.py b/addons/crm_livechat/tests/test_crm_lead.py index c5736357338..31af9e1c956 100644 --- a/addons/crm_livechat/tests/test_crm_lead.py +++ b/addons/crm_livechat/tests/test_crm_lead.py @@ -16,14 +16,14 @@ class TestLivechatLead(TestCrmCommon): cls.env, login='user_anonymous', name='Anonymous Website', email=False, company_id=cls.company_main.id, - notification_type='inbox', + notification_type='email', groups='base.group_public', ) cls.user_portal = mail_new_test_user( cls.env, login='user_portal', name='Paulette Portal', email='user_portal@test.example.com', company_id=cls.company_main.id, - notification_type='inbox', + notification_type='email', groups='base.group_portal', ) diff --git a/addons/im_livechat/views/res_users_views.xml b/addons/im_livechat/views/res_users_views.xml index 0ded2190802..187b6a4bf24 100644 --- a/addons/im_livechat/views/res_users_views.xml +++ b/addons/im_livechat/views/res_users_views.xml @@ -9,7 +9,8 @@ - + @@ -21,7 +22,8 @@ - + diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index 5c1b43c120b..2c24311836d 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -22,11 +22,25 @@ class Users(models.Model): ('email', 'Handle by Emails'), ('inbox', 'Handle in Odoo')], 'Notification', required=True, default='email', + compute='_compute_notification_type', store=True, readonly=False, help="Policy on how to handle Chatter notifications:\n" "- Handle by Emails: notifications are sent to your email address\n" "- Handle in Odoo: notifications appear in your Odoo Inbox") res_users_settings_ids = fields.One2many('res.users.settings', 'user_id') + _sql_constraints = [( + "notification_type", + "CHECK (notification_type = 'email' OR NOT share)", + "Only internal user can receive notifications in Odoo", + )] + + @api.depends('share') + def _compute_notification_type(self): + for user in self: + # Only the internal users can receive notifications in Odoo + if user.share or not user.notification_type: + user.notification_type = 'email' + # ------------------------------------------------------------ # CRUD # ------------------------------------------------------------ diff --git a/addons/mail/tests/__init__.py b/addons/mail/tests/__init__.py index e1c33cc3fdf..e56729715bd 100644 --- a/addons/mail/tests/__init__.py +++ b/addons/mail/tests/__init__.py @@ -9,6 +9,7 @@ from . import test_mail_render from . import test_mail_template from . import test_mail_tools from . import test_res_partner +from . import test_res_users from . import test_res_users_settings from . import test_rtc from . import test_update_notification diff --git a/addons/mail/tests/test_res_users.py b/addons/mail/tests/test_res_users.py new file mode 100644 index 00000000000..3dba356da83 --- /dev/null +++ b/addons/mail/tests/test_res_users.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from psycopg2 import IntegrityError + +from odoo.addons.mail.tests.common import MailCommon, mail_new_test_user +from odoo.tools import mute_logger + + +class TestUser(MailCommon): + + @mute_logger('odoo.sql_db') + def test_notification_type_constraint(self): + with self.assertRaises(IntegrityError, msg='Portal user can not receive notification in Odoo'): + mail_new_test_user( + self.env, + login='user_test_constraint_2', + name='Test User 2', + email='user_test_constraint_2@test.example.com', + notification_type='inbox', + groups='base.group_portal', + ) diff --git a/addons/mail/views/res_users_views.xml b/addons/mail/views/res_users_views.xml index a181a337c93..1b663a6c491 100644 --- a/addons/mail/views/res_users_views.xml +++ b/addons/mail/views/res_users_views.xml @@ -27,7 +27,8 @@ - + diff --git a/addons/mail_bot/views/res_users_views.xml b/addons/mail_bot/views/res_users_views.xml index e714ff6b438..2d56c986796 100644 --- a/addons/mail_bot/views/res_users_views.xml +++ b/addons/mail_bot/views/res_users_views.xml @@ -8,7 +8,8 @@ - + @@ -22,7 +23,8 @@ - + diff --git a/addons/website_blog/tests/common.py b/addons/website_blog/tests/common.py index d23691e9d07..e38f906d904 100644 --- a/addons/website_blog/tests/common.py +++ b/addons/website_blog/tests/common.py @@ -32,7 +32,7 @@ class TestWebsiteBlogCommon(common.TransactionCase): 'name': 'Cedric Public', 'login': 'cedric', 'email': 'cedric.public@example.com', - 'notification_type': 'inbox', + 'notification_type': 'email', 'groups_id': [(6, 0, [group_public_id])] }) diff --git a/addons/website_blog/tests/test_website_blog_flow.py b/addons/website_blog/tests/test_website_blog_flow.py index ebd7c0bc25e..2b6eae51596 100644 --- a/addons/website_blog/tests/test_website_blog_flow.py +++ b/addons/website_blog/tests/test_website_blog_flow.py @@ -16,7 +16,7 @@ class TestWebsiteBlogFlow(TestWebsiteBlogCommon): 'name': 'Dorian Portal', 'login': 'portal_user', 'email': 'portal_user@example.com', - 'notification_type': 'inbox', + 'notification_type': 'email', 'groups_id': [(6, 0, [group_portal.id])] }) diff --git a/addons/website_crm_partner_assign/tests/test_partner_assign.py b/addons/website_crm_partner_assign/tests/test_partner_assign.py index bc0ad24fad7..43250c16641 100644 --- a/addons/website_crm_partner_assign/tests/test_partner_assign.py +++ b/addons/website_crm_partner_assign/tests/test_partner_assign.py @@ -102,7 +102,7 @@ class TestPartnerLeadPortal(TestCrmCommon): company_id=self.env.ref("base.main_company").id, grade_id=self.grade.id, user_id=self.user_sales_manager.id, - notification_type='inbox', + notification_type='email', groups='base.group_portal', ) diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index cbfc6616563..c144a1f1ab3 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -271,6 +271,7 @@ class Users(models.Model): 'image_1024', 'image_512', 'image_256', 'image_128', 'lang', 'tz', 'tz_offset', 'groups_id', 'partner_id', '__last_update', 'action_id', 'avatar_1920', 'avatar_1024', 'avatar_512', 'avatar_256', 'avatar_128', + 'share', ] @property @@ -1235,7 +1236,8 @@ class GroupsView(models.Model): user_type_field_name = field_name user_type_readonly = str({'readonly': [(user_type_field_name, '!=', group_employee.id)]}) attrs['widget'] = 'radio' - attrs['groups'] = 'base.group_no_one' + # Trigger the on_change of this "virtual field" + attrs['on_change'] = '1' xml1.append(E.field(name=field_name, **attrs)) xml1.append(E.newline()) @@ -1273,9 +1275,9 @@ class GroupsView(models.Model): xml2.append(E.group(*(xml_by_category[xml_cat]), col="2", string=master_category_name)) xml = E.field( - E.group(*(xml1), col="2"), + E.group(*(xml1), col="2", groups="base.group_no_one"), E.group(*(xml2), col="2", attrs=str(user_type_attrs)), - E.group(*(xml3), col="4", attrs=str(user_type_attrs)), name="groups_id", position="replace") + E.group(*(xml3), col="4", attrs=str(user_type_attrs), groups="base.group_no_one"), name="groups_id", position="replace") xml.addprevious(etree.Comment("GENERATED AUTOMATICALLY BY GROUPS")) # serialize and update the view @@ -1431,6 +1433,22 @@ class UsersView(models.Model): return values def onchange(self, values, field_name, field_onchange): + # field_name can be either a string, a list or Falsy + if isinstance(field_name, list): + names = field_name + elif field_name: + names = [field_name] + else: + names = [] + + if any(is_reified_group(field) for field in names): + field_name = ( + ['groups_id'] + + [field for field in names if not is_reified_group(field)] + ) + values.pop('groups_id', None) + values.update(self._remove_reified_groups(values)) + field_onchange['groups_id'] = '' result = super().onchange(values, field_name, field_onchange) if not field_name: # merged default_get diff --git a/odoo/addons/base/tests/test_res_users.py b/odoo/addons/base/tests/test_res_users.py index fa93dca0407..81161fa6f72 100644 --- a/odoo/addons/base/tests/test_res_users.py +++ b/odoo/addons/base/tests/test_res_users.py @@ -171,3 +171,28 @@ class TestUsers2(TransactionCase): user.write({fname: group2.id}) self.assertEqual(user.groups_id & groups, groups) self.assertEqual(user.read([fname])[0][fname], group2.id) + + def test_reified_groups_on_change(self): + """Test that a change on a reified fields trigger the onchange of groups_id.""" + group_public = self.env.ref('base.group_public') + group_portal = self.env.ref('base.group_portal') + group_user = self.env.ref('base.group_user') + + # Build the reified group field name + user_groups = group_public | group_portal | group_user + user_groups_ids = [str(group_id) for group_id in sorted(user_groups.ids)] + group_field_name = f"sel_groups_{'_'.join(user_groups_ids)}" + + user_form = Form(self.env['res.users'], view='base.view_users_form') + user_form.name = "Test" + user_form.login = "Test" + self.assertFalse(user_form.share) + + setattr(user_form, group_field_name, group_portal.id) + self.assertTrue(user_form.share, 'The groups_id onchange should have been triggered') + + setattr(user_form, group_field_name, group_user.id) + self.assertFalse(user_form.share, 'The groups_id onchange should have been triggered') + + setattr(user_form, group_field_name, group_public.id) + self.assertTrue(user_form.share, 'The groups_id onchange should have been triggered') diff --git a/odoo/addons/base/views/res_users_views.xml b/odoo/addons/base/views/res_users_views.xml index dee5cba9102..e0769cc1b2e 100644 --- a/odoo/addons/base/views/res_users_views.xml +++ b/odoo/addons/base/views/res_users_views.xml @@ -223,6 +223,7 @@ + @@ -251,7 +252,8 @@ - + @@ -320,7 +322,8 @@ - + + @@ -453,6 +456,7 @@ +