diff --git a/addons/mail/models/discuss/discuss_channel.py b/addons/mail/models/discuss/discuss_channel.py index b5b1260fd75..1410c86037e 100644 --- a/addons/mail/models/discuss/discuss_channel.py +++ b/addons/mail/models/discuss/discuss_channel.py @@ -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' diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 2467daa741d..18ad7864f7d 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -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 - # and send the and the notifications + # and send the , and the 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): diff --git a/addons/test_mail_full/tests/test_web_push.py b/addons/test_mail_full/tests/test_web_push.py index 24474c126e4..23fa04916ad 100644 --- a/addons/test_mail_full/tests/test_web_push.py +++ b/addons/test_mail_full/tests/test_web_push.py @@ -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