summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authormgh-odoo <mgh@odoo.com>2019-07-31 12:51:10 +0000
committerAlexandre Kühn <aku@odoo.com>2020-02-05 09:59:52 +0000
commit4da64b3f3c8dff88d8e0e01c65374590cc0bf4f7 (patch)
treecfc7d9b87178feffb10dc2a9fea563fcb6c4f186 /addons
parent474643b1c1341d8f5956e7a18bfde14ff0e9d662 (diff)
[IMP] mail: email channels duplicated notifications
This commit prevents sending a notification within Odoo when a message is posted from a mailing channel to a user whose notification management preference is set to "Handle by Emails". Task-ID 2033302 closes odoo/odoo#36000 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/mail/models/ir_http.py1
-rw-r--r--addons/mail/models/mail_thread.py33
-rw-r--r--addons/mail/static/src/js/services/mail_notification_manager.js11
-rw-r--r--addons/test_mail/tests/test_mail_channel.py1
-rw-r--r--addons/test_mail/tests/test_performance.py2
5 files changed, 35 insertions, 13 deletions
diff --git a/addons/mail/models/ir_http.py b/addons/mail/models/ir_http.py
index 76643f6e735..7285b3447b0 100644
--- a/addons/mail/models/ir_http.py
+++ b/addons/mail/models/ir_http.py
@@ -13,4 +13,5 @@ class IrHttp(models.AbstractModel):
result = super(IrHttp, self).session_info()
if self.env.user.has_group('base.group_user'):
result['out_of_office_message'] = user.out_of_office_message
+ result['notification_type'] = user.notification_type
return result
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index afaa5cbed1b..7cc1484bd5c 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -2178,7 +2178,17 @@ class MailThread(models.AbstractModel):
for partner_id in inbox_pids:
bus_notifications.append([(self._cr.dbname, 'ir.needaction', partner_id), dict(message_format_values)])
if channel_ids:
- bus_notifications += self.env['mail.channel'].sudo().browse(channel_ids)._channel_message_notifications(message, message_format_values)
+ channels = self.env['mail.channel'].sudo().browse(channel_ids)
+ bus_notifications += channels._channel_message_notifications(message, message_format_values)
+ # Message from mailing channel should not make a notification in Odoo for users
+ # with notification "Handled by Email", but web client should receive the message.
+ # To do so, message is still sent from longpolling, but channel is marked as read
+ # in order to remove notification.
+ for channel in channels.filtered(lambda c: c.email_send):
+ users = channel.channel_partner_ids.mapped('user_ids')
+ for user in users.filtered(lambda u: u.notification_type == 'email'):
+ channel.with_user(user).channel_seen()
+
if bus_notifications:
self.env['bus.bus'].sudo().sendmany(bus_notifications)
@@ -2433,18 +2443,23 @@ class MailThread(models.AbstractModel):
# here : (searching all partners linked to channels with notif email if email is not the author one)
# TDE FIXME: use email_sanitized
email_from = msg_vals.get('email_from') or message.email_from
+ email_from = self.env['res.partner']._parse_partner_name(email_from)[1]
exept_partner = [r['id'] for r in recipient_data['partners']]
if author_id:
exept_partner.append(author_id)
- new_pids = self.env['res.partner'].sudo().search([
- ('id', 'not in', exept_partner),
- ('channel_ids', 'in', email_cids),
- ('email', 'not in', [email_from]),
- ])
- for partner in new_pids:
- # caution: side effect, if user has notif type inbox, will receive en email anyway?
+ sql_query = """ select distinct on (p.id) p.id from res_partner p
+ left join mail_channel_partner mcp on p.id = mcp.partner_id
+ left join mail_channel c on c.id = mcp.channel_id
+ left join res_users u on p.id = u.partner_id
+ where (u.notification_type != 'inbox' or u.id is null)
+ and (p.email != ANY(%s) or p.email is null)
+ and c.id = ANY(%s)
+ and p.id != ANY(%s)"""
+
+ self.env.cr.execute(sql_query, (([email_from], ), (email_cids, ), (exept_partner, )))
+ 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
- recipient_data['partners'].append({'id': partner.id, 'share': True, 'active': True, 'notif': 'email', 'type': 'channel_email', 'groups': []})
+ recipient_data['partners'].append({'id': partner_id[0], 'share': True, 'active': True, 'notif': 'email', 'type': 'channel_email', 'groups': []})
return recipient_data
diff --git a/addons/mail/static/src/js/services/mail_notification_manager.js b/addons/mail/static/src/js/services/mail_notification_manager.js
index 9cef9742747..ba9230eb32b 100644
--- a/addons/mail/static/src/js/services/mail_notification_manager.js
+++ b/addons/mail/static/src/js/services/mail_notification_manager.js
@@ -97,9 +97,14 @@ MailManager.include({
_handleChannelMessageNotification: function (messageData) {
var self = this;
var def;
- var channelAlreadyInCache = true;
+ let notify = true;
if (messageData.channel_ids.length === 1) {
- channelAlreadyInCache = !!this.getChannel(messageData.channel_ids[0]);
+ const channel = this.getChannel(messageData.channel_ids[0]);
+ // Message from mailing channel should not make a notification in Odoo for users
+ // with notification "Handled by Email", but web client should receive the message.
+ // Channel has been marked as read server-side in this case, so it should not display
+ // a notification by incrementing the unread counter.
+ notify = channel && (!channel.isMassMailing() || session.notification_type !== 'email');
def = this.joinChannel(messageData.channel_ids[0], { autoswitch: false });
} else {
def = Promise.resolve();
@@ -109,7 +114,7 @@ MailManager.include({
// its unread counter has just been fetched
return self.addMessage(messageData, {
showNotification: true,
- incrementUnread: channelAlreadyInCache
+ incrementUnread: notify,
});
});
},
diff --git a/addons/test_mail/tests/test_mail_channel.py b/addons/test_mail/tests/test_mail_channel.py
index 2e3c7c2cb4b..e14fd727eae 100644
--- a/addons/test_mail/tests/test_mail_channel.py
+++ b/addons/test_mail/tests/test_mail_channel.py
@@ -161,6 +161,7 @@ class TestChannelFeatures(TestMailCommon):
""" Posting a message on a mailing list should send one email to all recipients """
self.env['ir.config_parameter'].set_param('mail.catchall.domain', 'schlouby.fr')
self.test_channel.write({'email_send': True})
+ self.user_employee.write({'notification_type': 'email'})
# Subscribe an user without email. We shouldn't try to send email to them.
nomail = self.env['res.users'].create({
diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py
index 31c93f4a0fa..79058b69b6a 100644
--- a/addons/test_mail/tests/test_performance.py
+++ b/addons/test_mail/tests/test_performance.py
@@ -817,7 +817,7 @@ class TestMailHeavyPerformancePost(BaseMailPerformance):
]
self.attachements = self.env['ir.attachment'].with_user(self.env.user).create(self.vals)
attachement_ids = self.attachements.ids
- with self.assertQueryCount(emp=92):
+ with self.assertQueryCount(emp=98):
self.cr.sql_log = self.warm and self.cr.sql_log_count
record.with_context({}).message_post(
body='<p>Test body <img src="cid:cid1"> <img src="cid:cid2"></p>',