[IMP] mail: support mentioning people on channels

PURPOSE

Remove channel ability to follow records as it mainly adds noise without a lot
of added value. Simplify channel notification flow by using directly members
and not a delegation through a channel self-following trick. Remove followers
being channels and posting with added listeners being channels.

SPECIFICATIONS

Support mentioning partners on channels like done on other documents. When
there is an user input (comment or email) that mentions someone that specific
recipient is not notified. Its notification will be done in Inbox or email
depending on its choice or customer state.

This feature somehow replaces the follower-based support that is now removed
on channels. It allows to ping people and send them notifications. It is
less broad (limited to a post with ping) but already gives flexibility when
using channels.

LINKS

Task ID-2070632 (main task)
Task ID-2419762 (followup task)
COM PR odoo/odoo#62859
ENT PR odoo/enterprise#15172
UPG PR odoo/upgrade#2005
This commit is contained in:
Thibault Delavallée
2021-03-17 18:15:58 +00:00
parent b564638c3c
commit 33f5095e6b
2 changed files with 57 additions and 8 deletions
+47 -8
View File
@@ -460,13 +460,24 @@ class Channel(models.Model):
``MailThread._notify_thread()`` for more details about its content
and use;
"""
recipients_data = []
# get values from msg_vals or from message if msg_vals doen't exists
msg_sudo = message.sudo()
mailing_channels = self.filtered('email_send')
message_type = msg_vals.get('message_type', 'email') if msg_vals else msg_sudo.message_type
pids = msg_vals.get('partner_ids', []) if msg_vals else msg_sudo.partner_ids.ids
# notify only user input (comment or incoming emails)
if message_type not in ('comment', 'email'):
return {'partners': [], 'channels': []}
# notify only mailing lists or if mentioning recipients
if not mailing_channels and not pids:
return {'partners': [], 'channels': []}
email_from = tools.email_normalize(msg_vals.get('email_from') or msg_sudo.email_from)
author_id = msg_vals.get('author_id') or msg_sudo.author_id.id
recipients_data = []
if mailing_channels:
msg_sudo = message.sudo()
email_from = tools.email_normalize(msg_vals.get('email_from') or msg_sudo.email_from)
author_id = msg_vals.get('author_id') or message.author_id.id
except_pids = [author_id] if author_id else []
sql_query = """
SELECT DISTINCT ON (partner.id) partner.id
FROM res_partner partner
@@ -477,17 +488,45 @@ class Channel(models.Model):
AND (partner.email != %s or partner.email IS NULL)
AND channel.id = ANY(%s)
AND partner.id != ANY(%s)"""
self.env.cr.execute(sql_query, (email_from, mailing_channels.ids, except_pids, ))
for partner_id in self._cr.fetchall():
self.env.cr.execute(
sql_query,
(email_from, mailing_channels.ids, [author_id] if author_id else [], )
)
for partner_id, in self._cr.fetchall():
# ocn_client: will add partners to recipient recipient_data. more ocn notifications. We neeed to filter them maybe
recipients_data.append({
'id': partner_id[0],
'id': partner_id,
'share': True,
'active': True,
'notif': 'email',
'type': 'channel_email',
'groups': []
})
remaining = [pid for pid in pids if pid not in [recipient['id'] for recipient in recipients_data]]
if remaining:
sql_query = """
SELECT DISTINCT ON (partner.id) partner.id,
partner.partner_share,
users.notification_type
FROM res_partner partner
LEFT JOIN res_users users on partner.id = users.partner_id
WHERE partner.active IS TRUE
AND partner.email != %s
AND partner.id = ANY(%s) AND partner.id != ANY(%s)"""
self.env.cr.execute(
sql_query,
(email_from, remaining, [author_id] if author_id else [], )
)
for partner_id, partner_share, notif in self._cr.fetchall():
# ocn_client: will add partners to recipient recipient_data. more ocn notifications. We neeed to filter them maybe
recipients_data.append({
'id': partner_id,
'share': partner_share,
'active': True,
'notif': notif or 'email',
'type': 'user' if not partner_share and notif else 'customer',
'groups': [],
})
return {'partners': recipients_data, 'channels': []}
+10
View File
@@ -254,6 +254,16 @@ class TestChannelInternals(MailCommon):
channel.message_post(body="Test", message_type='comment', subtype_xmlid='mail.mt_comment')
self.assertSentEmail(self.partner_employee, [self.test_partner])
@mute_logger('odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
def test_channel_recipients_mention(self):
""" Posting a message on a classic channel should support mentioning somebody """
self.test_channel.write({'alias_name': False})
with self.mock_mail_gateway():
self.test_channel.message_post(
body="Test", partner_ids=self.test_partner.ids,
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_user_synchronize(self):
"""Archiving / deleting a user should automatically unsubscribe related partner from private channels"""