summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/mail/models/res_users.py17
-rw-r--r--addons/test_mail/tests/test_mail_channel.py35
2 files changed, 52 insertions, 0 deletions
diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py
index ce00a1d2b72..ba8e9def72d 100644
--- a/addons/mail/models/res_users.py
+++ b/addons/mail/models/res_users.py
@@ -86,6 +86,8 @@ GROUP BY channel_moderator.res_users_id""", [tuple(self.ids)])
def write(self, vals):
write_res = super(Users, self).write(vals)
+ if 'active' in vals and not vals['active']:
+ self._unsubscribe_from_channels()
sel_groups = [vals[k] for k in vals if is_selection_groups(k) and vals[k]]
if vals.get('groups_id'):
# form: {'group_ids': [(3, 10), (3, 3), (4, 10), (4, 3)]} or {'group_ids': [(6, 0, [ids]}
@@ -96,6 +98,21 @@ GROUP BY channel_moderator.res_users_id""", [tuple(self.ids)])
self.env['mail.channel'].search([('group_ids', 'in', sel_groups)])._subscribe_users()
return write_res
+ def unlink(self):
+ self._unsubscribe_from_channels()
+ return super().unlink()
+
+ def _unsubscribe_from_channels(self):
+ """ This method un-subscribes users from private mail channels. Main purpose of this
+ method is to prevent sending internal communication to archived / deleted users.
+ We do not un-subscribes users from public channels because in most common cases,
+ public channels are mailing list (e-mail based) and so users should always receive
+ updates from public channels until they manually un-subscribe themselves.
+ """
+ self.mapped('partner_id.channel_ids').filtered(lambda c: c.public != 'public').write({
+ 'channel_partner_ids': [(3, pid) for pid in self.mapped('partner_id').ids]
+ })
+
@api.model
def systray_get_activities(self):
query = """SELECT m.id, count(*), act.res_model as model,
diff --git a/addons/test_mail/tests/test_mail_channel.py b/addons/test_mail/tests/test_mail_channel.py
index 8bbd60c5a9d..e54d90ff8b7 100644
--- a/addons/test_mail/tests/test_mail_channel.py
+++ b/addons/test_mail/tests/test_mail_channel.py
@@ -191,6 +191,41 @@ class TestChannelFeatures(TestMailCommon):
self.test_channel.message_post(body="Test", message_type='comment', subtype_xmlid='mail.mt_comment')
self.assertSentEmail(self.test_channel.env.user.partner_id, [self.test_partner])
+ @mute_logger('odoo.models.unlink')
+ def test_channel_auto_unsubscribe_archived_or_deleted_users(self):
+ """Archiving / deleting a user should automatically unsubscribe related partner from private channels"""
+ test_channel_private = self.env['mail.channel'].with_context(self._test_context).create({
+ 'name': 'Winden caves',
+ 'description': 'Channel to travel through time',
+ 'public': 'private',
+ })
+ test_channel_group = self.env['mail.channel'].with_context(self._test_context).create({
+ 'name': 'Sic Mundus',
+ 'public': 'groups',
+ 'group_public_id': self.env.ref('base.group_user').id})
+
+ test_user = self.env['res.users'].create({
+ "login": "adam",
+ "name": "Jonas",
+ })
+ test_partner = test_user.partner_id
+
+ self._join_channel(self.test_channel, self.user_employee.partner_id | test_partner)
+ self._join_channel(test_channel_private, self.user_employee.partner_id | test_partner)
+ self._join_channel(test_channel_group, self.user_employee.partner_id | test_partner)
+
+ # Unsubscribe archived user from the private channels, but not from public channels
+ self.user_employee.active = False
+ self.assertEqual(test_channel_private.channel_partner_ids, test_partner)
+ self.assertEqual(test_channel_group.channel_partner_ids, test_partner)
+ self.assertEqual(self.test_channel.channel_partner_ids, self.user_employee.partner_id | test_partner)
+
+ # Unsubscribe deleted user from the private channels, but not from public channels
+ test_user.unlink()
+ self.assertEqual(test_channel_private.channel_partner_ids, self.env['res.partner'])
+ self.assertEqual(test_channel_group.channel_partner_ids, self.env['res.partner'])
+ self.assertEqual(self.test_channel.channel_partner_ids, self.user_employee.partner_id | test_partner)
+
@tagged('moderation')
class TestChannelModeration(TestMailCommon):