summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstd-odoo <std@odoo.com>2021-01-26 14:11:57 +0000
committerstd-odoo <std@odoo.com>2021-05-26 07:36:03 +0000
commit123dce518a0ea44725c55a0719ea45f6d603ff66 (patch)
treee367d52c07aae36b295bbd6e58d544674478a579
parentcb996aefb4aeeac9c41359ead523d52c66d21e29 (diff)
[REV] mail: fix a traceback when sending a message in a "email channel"
Bug === Since 4da64b3f3c8dff88d8e0e01c65374590cc0bf4f7 , if multiple users of different companies are in the same channel, and if the type of the channel is "email", a traceback is raised when sending a message. Technical ========= "with_user" drop the SU flag and is not enough to bypass the multi company ACLs. Moreover, we do not want to send a "channel_seen" bus notifications and we can mark the message as seen on the JS side directly. Changes ======= So now, the traceback is not raised anymore in that case, and the message is marked as seen if the receiver has the web client open. But, if the receiver has not the web client open, when he will login, the message will not be marked as seen. This can be improved but at the moment we just want to revert the fix that cause the traceback and fix the issue in most cases. Task 2427790 closes odoo/odoo#65185 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
-rw-r--r--addons/mail/models/mail_thread.py9
-rw-r--r--addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js4
-rw-r--r--addons/test_mail/tests/test_mail_channel.py67
-rw-r--r--addons/test_mail/tests/test_performance.py2
4 files changed, 73 insertions, 9 deletions
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index 6e0f725ae41..3064c391a91 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -2176,14 +2176,6 @@ class MailThread(models.AbstractModel):
if channel_ids:
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(message.id)
if bus_notifications:
self.env['bus.bus'].sudo().sendmany(bus_notifications)
@@ -2464,6 +2456,7 @@ class MailThread(models.AbstractModel):
exept_partner = [r['id'] for r in recipient_data['partners']]
if author_id:
exept_partner.append(author_id)
+
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
diff --git a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js
index f1ce13bec21..a42ede1c6ae 100644
--- a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js
+++ b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js
@@ -241,6 +241,10 @@ function factory(dependencies) {
channel.mass_mailing &&
this.env.session.notification_type === 'email'
) {
+ this._handleNotificationChannelSeen(channelId, {
+ last_message_id: messageData.id,
+ partner_id: this.env.messaging.currentPartner.id,
+ });
return;
}
// In all other cases: update counter and notify if necessary
diff --git a/addons/test_mail/tests/test_mail_channel.py b/addons/test_mail/tests/test_mail_channel.py
index 239e76ccb41..e33570277e9 100644
--- a/addons/test_mail/tests/test_mail_channel.py
+++ b/addons/test_mail/tests/test_mail_channel.py
@@ -349,6 +349,73 @@ class TestChannelFeatures(TestMailCommon):
initial_channel_info = self.env['mail.channel'].with_user(test_user_1).with_context(allowed_company_ids=company_A.ids).channel_get(test_user_2.partner_id.ids)
self.assertTrue(initial_channel_info, 'should be able to chat with multi company user')
+ def test_multi_company_message_post_notifications(self):
+ company_1 = self.company_admin
+ company_2 = self.env['res.company'].create({'name': 'Company 2'})
+
+ # Company 1 and notification_type == "inbox"
+ user_1 = self.user_employee
+
+ # Company 1 and notification_type == "email"
+ user_2 = self.user_admin
+ user_2.notification_type = 'email'
+
+ user_3 = mail_new_test_user(
+ self.env, login='user3', email='user3@example.com', groups='base.group_user',
+ company_id=company_2.id, company_ids=[(6, 0, company_2.ids)],
+ name='user3', notification_type='inbox')
+
+ user_4 = mail_new_test_user(
+ self.env, login='user4', email='user4@example.com', groups='base.group_user',
+ company_id=company_2.id, company_ids=[(6, 0, company_2.ids)],
+ name='user4', notification_type='email')
+
+ partner_without_user = self.env['res.partner'].create({
+ 'name': 'Partner',
+ 'email': 'partner_test_123@example.com',
+ })
+ mail_channel = self.env['mail.channel'].with_user(user_1).create({
+ 'name': 'Channel',
+ 'channel_partner_ids': [
+ (4, user_1.partner_id.id),
+ (4, user_2.partner_id.id),
+ (4, user_3.partner_id.id),
+ (4, user_4.partner_id.id),
+ (4, partner_without_user.id),
+ ],
+ 'email_send': True,
+ })
+
+ mail_channel.invalidate_cache()
+ (user_1 | user_2 | user_3 | user_4).invalidate_cache()
+
+ with self.mock_mail_gateway():
+ mail_channel.with_user(user_1).with_company(company_1).message_post(
+ body='Test body message 1337',
+ channel_ids=mail_channel.ids,
+ )
+
+ self.assertSentEmail(user_1.partner_id, [user_2.partner_id])
+ self.assertSentEmail(user_1.partner_id, [user_4.partner_id])
+ self.assertEqual(len(self._mails), 3, 'Should have send only 3 emails to user 2, user 4 and the partner')
+
+ self.assertBusNotifications([(self.cr.dbname, 'mail.channel', mail_channel.id)])
+
+ # Should not create mail notifications for user 1 & 3
+ self.assertFalse(self.env['mail.notification'].search([('res_partner_id', '=', user_1.partner_id.id)]))
+ self.assertFalse(self.env['mail.notification'].search([('res_partner_id', '=', user_3.partner_id.id)]))
+
+ # Should create mail notifications for user 2 & 4
+ self.assertTrue(self.env['mail.notification'].search([('res_partner_id', '=', user_2.partner_id.id)]))
+ self.assertTrue(self.env['mail.notification'].search([('res_partner_id', '=', user_4.partner_id.id)]))
+
+ # Check that we did not send a "channel_seen" notifications
+ # for the users which receive the notifications by email
+ notification_seen_user_2 = self.env['bus.bus'].search([('create_uid', '=', user_2.id)])
+ self.assertFalse(notification_seen_user_2, 'Should not have sent a notification as user 2')
+ notification_seen_user_4 = self.env['bus.bus'].search([('create_uid', '=', user_4.id)])
+ self.assertFalse(notification_seen_user_4, 'Should not have sent a notification as user 4')
+
@tagged('moderation', 'mail_channel')
class TestChannelModeration(TestMailCommon):
diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py
index 658e353a81e..6862160acea 100644
--- a/addons/test_mail/tests/test_performance.py
+++ b/addons/test_mail/tests/test_performance.py
@@ -998,7 +998,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=82):
+ with self.assertQueryCount(emp=80):
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>',