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 @@
+