[FW][FIX] mail: fix various web.push issues

PURPOSE

Provide fixes for web push notifications implementation in mail, especially
it has been moved in standard mail in 17.0 .

FIXES

Fix override of recipients computation: add missing keys to match standard
structure

Fix 'notify_by_web_push' being called two times in discuss channels

Fix web push recipients being computed at wrong place: should be done in
a clean override of '_notify_recipients'

Fix access issue when sending push notifications in public channels

Task-3695571
Related to Task-3669738 (Mail: Web Push Models Rename and Fixes)

closes odoo/odoo#150011

Related: odoo/enterprise#54647
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Odoo's Mergebot
2024-01-22 15:56:54 +00:00
committed by Odoo Online
3 changed files with 58 additions and 39 deletions
+36 -36
View File
@@ -484,21 +484,19 @@ class Channel(models.Model):
# notify only user input (comment or incoming / outgoing emails)
if message_type not in ('comment', 'email', 'email_outgoing'):
return []
# notify only mailing lists or if mentioning recipients
if not pids:
return []
email_from = tools.email_normalize(msg_vals.get('email_from') or message.email_from)
author_id = msg_vals.get('author_id') or message.author_id.id
recipients_data = []
if pids:
email_from = tools.email_normalize(msg_vals.get('email_from') or message.email_from)
author_id = msg_vals.get('author_id') or message.author_id.id
self.env['res.partner'].flush_model(['active', 'email', 'partner_share'])
self.env['res.users'].flush_model(['notification_type', 'partner_id'])
sql_query = """
SELECT DISTINCT ON (partner.id) partner.id,
partner.lang,
partner.partner_share,
users.notification_type
COALESCE(users.notification_type, 'email') as notif,
COALESCE(users.share, FALSE) as ushare
FROM res_partner partner
LEFT JOIN res_users users on partner.id = users.partner_id
WHERE partner.active IS TRUE
@@ -508,17 +506,43 @@ class Channel(models.Model):
sql_query,
(email_from or '', list(pids), [author_id] if author_id else [], )
)
for partner_id, partner_share, notif in self._cr.fetchall():
for partner_id, lang, partner_share, notif, ushare 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': [],
'id': partner_id,
'is_follower': False,
'lang': lang,
'notif': notif,
'share': partner_share,
'type': 'user' if not partner_share and notif else 'customer',
'uid': False,
'ushare': ushare,
})
if self.is_chat or self.channel_type == "group":
already_in_ids = [r['id'] for r in recipients_data]
recipients_data += [
{
'active': partner.active,
'groups': [],
'id': partner.id,
'is_follower': False,
'lang': partner.lang,
'notif': 'web_push',
'share': partner.partner_share,
'type': 'customer',
'uid': False,
'ushare': False,
} for partner in self.sudo().channel_member_ids.filtered(
lambda member: (
not member.mute_until_dt and
member.partner_id.id not in already_in_ids
)
).partner_id
]
return recipients_data
def _notify_get_recipients_groups(self, message, model_description, msg_vals=None):
@@ -550,8 +574,6 @@ class Channel(models.Model):
]
# sudo: bus.bus - sending on safe channel (discuss.channel)
self.env["bus.bus"].sudo()._sendmany(bus_notifications)
if self.is_chat or self.channel_type == "group":
self._notify_thread_by_web_push(message, rdata, msg_vals, **kwargs)
return rdata
def _message_receive_bounce(self, email, partner):
@@ -1265,28 +1287,6 @@ class Channel(models.Model):
self._send_transient_message(self.env.user.partner_id, msg)
def _notify_thread_by_web_push(self, message, recipients_data, msg_vals=False, **kwargs):
""" Specifically handle channel members. """
chat_channels = self.filtered(lambda channel: channel.channel_type == 'chat')
if chat_channels:
# modify rdata only for calling super. Do not deep copy as we only
# add data into list but we do not modify item content
channel_rdata = recipients_data.copy()
channel_rdata += [
{'id': partner.id,
'share': partner.partner_share,
'active': partner.active,
'notif': 'web_push',
'type': 'customer',
'groups': [],
}
for partner in chat_channels.channel_member_ids.filtered(lambda member: not member.mute_until_dt).partner_id
]
else:
channel_rdata = recipients_data
return super()._notify_thread_by_web_push(message, channel_rdata, msg_vals=msg_vals, **kwargs)
def _notify_by_web_push_prepare_payload(self, message, msg_vals=False):
payload = super()._notify_by_web_push_prepare_payload(message, msg_vals=msg_vals)
payload['options']['data']['action'] = 'mail.action_discuss'
+21 -2
View File
@@ -2947,6 +2947,25 @@ class MailThread(models.AbstractModel):
'subtitles',
}
@api.model
def _is_notification_scheduled(self, notify_cheduled_date):
""" Helper to check if notification are about to be scheduled. Eases
overrides.
:param notify_scheduled_date: value of 'scheduled_date' given in
notification parameters: arbitrary datetime (as a date, datetime or
a string), may be void. See 'MailMail._parse_scheduled_datetime()';
:return bool: True if a valid datetime has been found and is in the
future; False otherwise.
"""
if notify_cheduled_date:
parsed_datetime = self.env['mail.mail']._parse_scheduled_datetime(notify_cheduled_date)
notify_cheduled_date = parsed_datetime.replace(tzinfo=None) if parsed_datetime else False
return (
notify_cheduled_date and notify_cheduled_date > datetime.datetime.utcnow()
)
def _raise_for_invalid_parameters(self, parameter_names, forbidden_names=None, restricting_names=None):
""" Helper to warn about invalid parameters (or fields).
@@ -3061,11 +3080,11 @@ class MailThread(models.AbstractModel):
})
else:
# generate immediately the <mail.notification>
# and send the <mail.mail> and the <bus.bus> notifications
# and send the <mail.mail>, <mail.push> and the <bus.bus> notifications
self._notify_thread_by_inbox(message, recipients_data, msg_vals=msg_vals, **kwargs)
self._notify_thread_by_email(message, recipients_data, msg_vals=msg_vals, **kwargs)
self._notify_thread_by_web_push(message, recipients_data, msg_vals, **kwargs)
self._notify_thread_by_web_push(message, recipients_data, msg_vals, **kwargs)
return recipients_data
def _notify_thread_by_inbox(self, message, recipients_data, msg_vals=False, **kwargs):
+1 -1
View File
@@ -16,7 +16,7 @@ from unittest.mock import patch
from types import SimpleNamespace
@tagged('post_install', '-at_install')
@tagged('post_install', '-at_install', 'mail_push')
class TestWebPushNotification(SMSCommon):
@classmethod