diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py index e4f444e1340..88bd6ae321d 100644 --- a/addons/mail/models/mail_message.py +++ b/addons/mail/models/mail_message.py @@ -467,6 +467,7 @@ class Message(models.Model): - if author_id == pid, uid is the author, OR - uid belongs to a notified channel, OR - uid is in the specified recipients, OR + - uid has a notification on the message, OR - uid have read access to the related document is model, res_id - otherwise: remove the id """ @@ -494,17 +495,22 @@ class Message(models.Model): # check read access rights before checking the actual rules on the given ids super(Message, self.sudo(access_rights_uid or self._uid)).check_access_rights('read') - self._cr.execute("""SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, partner_rel.res_partner_id, channel_partner.channel_id as channel_id + self._cr.execute(""" + SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, + COALESCE(partner_rel.res_partner_id, needaction_rel.res_partner_id), + channel_partner.channel_id as channel_id FROM "%s" m LEFT JOIN "mail_message_res_partner_rel" partner_rel - ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = (%%s) + ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = %%(pid)s + LEFT JOIN "mail_message_res_partner_needaction_rel" needaction_rel + ON needaction_rel.mail_message_id = m.id AND needaction_rel.res_partner_id = %%(pid)s LEFT JOIN "mail_message_mail_channel_rel" channel_rel ON channel_rel.mail_message_id = m.id LEFT JOIN "mail_channel" channel ON channel.id = channel_rel.mail_channel_id LEFT JOIN "mail_channel_partner" channel_partner - ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = (%%s) - WHERE m.id = ANY (%%s)""" % self._table, (pid, pid, ids,)) + ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = %%(pid)s + WHERE m.id = ANY (%%(ids)s)""" % self._table, dict(pid=pid, ids=ids)) for id, rmod, rid, author_id, partner_id, channel_id in self._cr.fetchall(): if author_id == pid: author_ids.add(id) @@ -532,6 +538,7 @@ class Message(models.Model): - read: if - author_id == pid, uid is the author OR - uid is in the recipients (partner_ids) OR + - uid has been notified (needaction) OR - uid is member of a listern channel (channel_ids.partner_ids) OR - uid have read access to the related document if model, res_id - otherwise: raise @@ -582,17 +589,22 @@ class Message(models.Model): message_values = dict((res_id, {}) for res_id in self.ids) if operation in ['read', 'write']: - self._cr.execute("""SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, m.parent_id, partner_rel.res_partner_id, channel_partner.channel_id as channel_id + self._cr.execute(""" + SELECT DISTINCT m.id, m.model, m.res_id, m.author_id, m.parent_id, + COALESCE(partner_rel.res_partner_id, needaction_rel.res_partner_id), + channel_partner.channel_id as channel_id FROM "%s" m LEFT JOIN "mail_message_res_partner_rel" partner_rel - ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = (%%s) + ON partner_rel.mail_message_id = m.id AND partner_rel.res_partner_id = %%(pid)s + LEFT JOIN "mail_message_res_partner_needaction_rel" needaction_rel + ON needaction_rel.mail_message_id = m.id AND needaction_rel.res_partner_id = %%(pid)s LEFT JOIN "mail_message_mail_channel_rel" channel_rel ON channel_rel.mail_message_id = m.id LEFT JOIN "mail_channel" channel ON channel.id = channel_rel.mail_channel_id LEFT JOIN "mail_channel_partner" channel_partner - ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = (%%s) - WHERE m.id = ANY (%%s)""" % self._table, (self.env.user.partner_id.id, self.env.user.partner_id.id, self.ids,)) + ON channel_partner.channel_id = channel.id AND channel_partner.partner_id = %%(pid)s + WHERE m.id = ANY (%%(ids)s)""" % self._table, dict(pid=self.env.user.partner_id.id, ids=self.ids)) for mid, rmod, rid, author_id, parent_id, partner_id, channel_id in self._cr.fetchall(): message_values[mid] = { 'model': rmod, diff --git a/addons/mail/tests/test_mail_features.py b/addons/mail/tests/test_mail_features.py index 2064b907765..4460bd69bc0 100644 --- a/addons/mail/tests/test_mail_features.py +++ b/addons/mail/tests/test_mail_features.py @@ -37,6 +37,45 @@ class TestMailFeatures(TestMail): @mute_logger('openerp.addons.mail.models.mail_mail') def test_mark_all_as_read(self): + emp_partner = self.user_employee.partner_id.sudo(self.user_employee.id) + + group_private = self.env['mail.channel'].with_context({ + 'mail_create_nolog': True, + 'mail_create_nosubscribe': True, + 'mail_channel_noautofollow': True, + }).create({ + 'name': 'Private', + 'description': 'Private James R.', + 'public': 'private', + 'alias_name': 'private', + 'alias_contact': 'followers'} + ).with_context({'mail_create_nosubscribe': False}) + + # mark all as read clear needactions + group_private.message_post(body='Test', message_type='comment', subtype='mail.mt_comment', partner_ids=[emp_partner.id]) + emp_partner.env['mail.message'].mark_all_as_read(channel_ids=[], domain=[]) + na_count = emp_partner.get_needaction_count() + self.assertEqual(na_count, 0, "mark all as read should conclude all needactions") + + # mark all as read also clear inaccessible needactions + new_msg = group_private.message_post(body='Zest', message_type='comment', subtype='mail.mt_comment', partner_ids=[emp_partner.id]) + needaction_accessible = len(emp_partner.env['mail.message'].search([['needaction', '=', True]])) + self.assertEqual(needaction_accessible, 1, "a new message to a partner is readable to that partner") + + new_msg.sudo().partner_ids = self.env['res.partner'] + emp_partner.env['mail.message'].search([['needaction', '=', True]]) + needaction_length = len(emp_partner.env['mail.message'].search([['needaction', '=', True]])) + self.assertEqual(needaction_length, 1, "message should still be readable when notified") + + na_count = emp_partner.get_needaction_count() + self.assertEqual(na_count, 1, "message not accessible is currently still counted") + + emp_partner.env['mail.message'].mark_all_as_read(channel_ids=[], domain=[]) + na_count = emp_partner.get_needaction_count() + self.assertEqual(na_count, 0, "mark all read should conclude all needactions even inacessible ones") + + @mute_logger('openerp.addons.mail.models.mail_mail') + def test_mark_all_as_read_share(self): portal_partner = self.user_portal.partner_id.sudo(self.user_portal.id) # mark all as read clear needactions @@ -52,7 +91,7 @@ class TestMailFeatures(TestMail): new_msg.sudo().partner_ids = self.env['res.partner'] needaction_length = len(portal_partner.env['mail.message'].search([['needaction', '=', True]])) - self.assertEqual(needaction_length, 0, "removing access of a message make it not readable") + self.assertEqual(needaction_length, 1, "message should still be readable when notified") na_count = portal_partner.get_needaction_count() self.assertEqual(na_count, 1, "message not accessible is currently still counted")