[IMP] mail_message: partner_ids now holds only specific destination partners. Partner...
authorThibault Delavallée <tde@openerp.com>
Thu, 25 Oct 2012 11:30:48 +0000 (13:30 +0200)
committerThibault Delavallée <tde@openerp.com>
Thu, 25 Oct 2012 11:30:48 +0000 (13:30 +0200)
bzr revid: tde@openerp.com-20121025113048-5f1ob8ligqzb52gu

addons/email_template/tests/test_mail.py
addons/mail/mail_message.py
addons/mail/mail_thread.py
addons/mail/static/src/js/mail.js
addons/mail/tests/test_mail.py
addons/mail/tests/test_mail_access_rights.py

index 69afd5b..7af05f3 100644 (file)
@@ -165,11 +165,8 @@ class test_message_compose(test_mail.TestMailMockups):
         self.assertEqual(message_pigs.body, _body_html1, 'mail.message body on Pigs incorrect')
         self.assertEqual(message_bird.body, _body_html2, 'mail.message body on Bird incorrect')
         # Test: partner_ids: p_a_id (default) + 3 newly created partners
-        message_pigs_pids = [partner.id for partner in message_pigs.partner_ids]
-        message_bird_pids = [partner.id for partner in message_bird.partner_ids]
+        message_pigs_pids = [partner.id for partner in message_pigs.notified_partner_ids]
+        message_bird_pids = [partner.id for partner in message_bird.notified_partner_ids]
         partner_ids = self.res_partner.search(cr, uid, [('email', 'in', ['b@b.b', 'c@c.c', 'd@d.d'])])
-        self.assertEqual(len(message_pigs_pids), len(partner_ids), 'mail.message on pigs incorrect number of partner_ids')
-        self.assertEqual(set(message_pigs_pids), set(partner_ids), 'mail.message on pigs incorrect number of partner_ids')
-
-        self.assertEqual(len(message_bird_pids), len(partner_ids), 'mail.message on bird partner_ids incorrect')
-        self.assertEqual(set(message_bird_pids), set(partner_ids), 'mail.message on bird partner_ids incorrect')
+        self.assertEqual(set(message_pigs_pids), set(partner_ids), 'mail.message on pigs incorrect number of notified_partner_ids')
+        self.assertEqual(set(message_bird_pids), set(partner_ids), 'mail.message on bird notified_partner_ids incorrect')
index c6895c3..37b37ca 100644 (file)
@@ -115,8 +115,13 @@ class mail_message(osv.Model):
                         ], 'Type',
             help="Message type: email for email message, notification for system "\
                  "message, comment for other messages such as user replies"),
-        'author_id': fields.many2one('res.partner', 'Author', required=True),
-        'partner_ids': fields.many2many('res.partner', 'mail_notification', 'message_id', 'partner_id', 'Recipients'),
+        'from': fields.char('From',
+            help="Email address of the sender, to use if it does not match any partner."),
+        'author_id': fields.many2one('res.partner', 'Author',
+            help="Partner that did write the message. If not set, try to use the From field instead."),
+        'partner_ids': fields.many2many('res.partner', string='Recipients'),
+        'notified_partner_ids': fields.many2many('res.partner', 'mail_notification',
+            'message_id', 'partner_id', 'Recipients'),
         'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel',
             'message_id', 'attachment_id', 'Attachments'),
         'parent_id': fields.many2one('mail.message', 'Parent Message', select=True, ondelete='set null', help="Initial thread message."),
@@ -201,6 +206,9 @@ class mail_message(osv.Model):
         is_author = False
         if message['author_id']:
             is_author = message['author_id'][0] == self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=None)['partner_id'][0]
+            author_id = message['author_id']
+        elif message['from']:
+            author_id = (0, message['from'])
 
         has_voted = False
         if uid in message.get('vote_user_ids'):
@@ -210,9 +218,9 @@ class mail_message(osv.Model):
         if uid in message.get('favorite_user_ids'):
             is_favorite = True
 
-        is_private = False
+        is_private = True
         if message.get('model') and message.get('res_id'):
-            is_private = True
+            is_private = False
 
         try:
             attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, message['attachment_ids'], context=context)]
@@ -236,9 +244,8 @@ class mail_message(osv.Model):
             'record_name': message['record_name'],
             'subject': message['subject'],
             'date': message['date'],
-            'author_id': message['author_id'],
+            'author_id': author_id,
             'is_author': is_author,
-            # TDE note: is this useful ? to check
             'partner_ids': partner_ids,
             'ancestor_id': False,
             'vote_nb': len(message['vote_user_ids']),
@@ -463,11 +470,11 @@ class mail_message(osv.Model):
         author_ids, partner_ids, allowed_ids = set([]), set([]), set([])
         model_ids = {}
 
-        messages = super(mail_message, self).read(cr, uid, ids, ['author_id', 'model', 'res_id', 'partner_ids'], context=context)
+        messages = super(mail_message, self).read(cr, uid, ids, ['author_id', 'model', 'res_id', 'notified_partner_ids'], context=context)
         for message in messages:
             if message.get('author_id') and message.get('author_id')[0] == pid:
                 author_ids.add(message.get('id'))
-            elif pid in message.get('partner_ids'):
+            elif pid in message.get('notified_partner_ids'):
                 partner_ids.add(message.get('id'))
             elif message.get('model') and message.get('res_id'):
                 model_ids.setdefault(message.get('model'), {}).setdefault(message.get('res_id'), set()).add(message.get('id'))
@@ -615,40 +622,36 @@ class mail_message(osv.Model):
     # Messaging API
     #------------------------------------------------------
 
-    def _notify_followers(self, cr, uid, newid, message, context=None):
-        """ Add the related record followers to the destination partner_ids.
+    def _notify(self, cr, uid, newid, context=None):
+        """ Add the related record followers to the destination partner_ids if is not a private message.
+            Call mail_notification.notify to manage the email sending
         """
+        message = self.read(cr, uid, newid, ['model', 'res_id', 'author_id', 'subtype_id', 'partner_ids'], context=context)
+
         partners_to_notify = set([])
         # message has no subtype_id: pure log message -> no partners, no one notified
-        if not message.subtype_id:
-            message.write({'partner_ids': [5]})
+        if not message.get('subtype_id'):
             return True
         # all partner_ids of the mail.message have to be notified
-        if message.partner_ids:
-            partners_to_notify |= set(partner.id for partner in message.partner_ids)
+        if message.get('partner_ids'):
+            partners_to_notify |= set(message.get('partner_ids'))
         # all followers of the mail.message document have to be added as partners and notified
-        if message.model and message.res_id:
+        if message.get('model') and message.get('res_id'):
             fol_obj = self.pool.get("mail.followers")
-            fol_ids = fol_obj.search(cr, uid, [('res_model', '=', message.model), ('res_id', '=', message.res_id), ('subtype_ids', 'in', message.subtype_id.id)], context=context)
-            fol_objs = fol_obj.browse(cr, uid, fol_ids, context=context)
-            extra_notified = set(fol.partner_id.id for fol in fol_objs)
-            missing_notified = extra_notified - partners_to_notify
-            if missing_notified:
-                self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(4, p_id) for p_id in missing_notified]}, context=context)
-
-    def _notify(self, cr, uid, newid, context=None):
-        """ Add the related record followers to the destination partner_ids if is not a private message.
-            Call mail_notification.notify to manage the email sending
-        """
-        message = self.browse(cr, uid, newid, context=context)
-        if message.model and message.res_id:
-            self._notify_followers(cr, uid, newid, message, context=context)
-
+            fol_ids = fol_obj.search(cr, uid, [
+                ('res_model', '=', message.get('model')),
+                ('res_id', '=', message.get('res_id')),
+                ('subtype_ids', 'in', message.get('subtype_id')[0])
+                ], context=context)
+            fol_objs = fol_obj.read(cr, uid, fol_ids, ['partner_id'], context=context)
+            partners_to_notify |= set(fol['partner_id'][0] for fol in fol_objs)
         # add myself if I wrote on my wall, otherwise remove myself author
-        if ((message.model == "res.partner" and message.res_id == message.author_id.id)):
-            self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(4, message.author_id.id)]}, context=context)
+        if message.get('author_id') and message.get('model') == "res.partner" and message.get('res_id') == message.get('author_id')[0]:
+            partners_to_notify |= set([message.get('author_id')[0]])
         else:
-            self.write(cr, SUPERUSER_ID, [newid], {'partner_ids': [(3, message.author_id.id)]}, context=context)
+            partners_to_notify = partners_to_notify - set([message.get('author_id')[0]])
+        if partners_to_notify:
+            self.write(cr, SUPERUSER_ID, [newid], {'notified_partner_ids': [(4, p_id) for p_id in partners_to_notify]}, context=context)
 
         self.pool.get('mail.notification')._notify(cr, uid, newid, context=context)
 
index e88e817..2692049 100644 (file)
@@ -554,7 +554,10 @@ class mail_thread(osv.AbstractModel):
                                       ('file2', 'bytes')}
                     }
         """
-        msg_dict = {}
+        msg_dict = {
+            'type': 'email',
+            'subtype': 'mail.mt_comment',
+        }
         if not isinstance(message, Message):
             if isinstance(message, unicode):
                 # Warning: message_from_string doesn't always work correctly on unicode,
@@ -581,6 +584,8 @@ class mail_thread(osv.AbstractModel):
             author_ids = self._message_find_partners(cr, uid, message, ['From'], context=context)
             if author_ids:
                 msg_dict['author_id'] = author_ids[0]
+            else:
+                msg_dict['from'] = message.get('from')
         partner_ids = self._message_find_partners(cr, uid, message, ['From', 'To', 'Cc'], context=context)
         msg_dict['partner_ids'] = partner_ids
 
@@ -690,14 +695,14 @@ class mail_thread(osv.AbstractModel):
         return mail_message.create(cr, uid, values, context=context)
 
     def message_post_api(self, cr, uid, thread_id, body='', subject=False, type='notification',
-                        subtype=None, parent_id=False, attachment_ids=None, context=None):
+                        parent_id=False, attachment_ids=None, context=None):
         """ Wrapper on message_post, used only in Chatter (JS). The purpose is
             to handle attachments.
 
             # TDE FIXME: body is plaintext: convert it into html
         """
         new_message_id = self.message_post(cr, uid, thread_id=thread_id, body=body, subject=subject, type=type,
-                        subtype=subtype, parent_id=parent_id, context=context)
+                        subtype='mail.mt_comment', parent_id=parent_id, context=context)
 
         # HACK FIXME: Chatter: attachments linked to the document (not done JS-side), load the message
         if attachment_ids:
index b385e6b..0de1699 100644 (file)
@@ -339,7 +339,6 @@ openerp.mail = function(session) {
                         mail.ChatterUtils.get_text2html(body), 
                         false, 
                         'comment', 
-                        'mail.mt_comment',
                         this.context.default_parent_id, 
                         attachments,
                         this.parent_thread.context
index 8bfd5d4..d509200 100644 (file)
@@ -365,11 +365,11 @@ class test_mail(TestMailMockups):
             # the html2plaintext uses etree or beautiful soup, so the result may be slighly different
             # depending if you have installed beautiful soup.
             self.assertIn(sent_email['body_alternative'], _mail_bodyalt1 + '\nBert Tartopoils\n', 'sent_email body_alternative is incorrect')
-        # Test: mail_message: partner_ids = group followers
-        message_pids = set([partner.id for partner in message.partner_ids])
+        # Test: mail_message: notified_partner_ids = group followers
+        message_pids = set([partner.id for partner in message.notified_partner_ids])
         test_pids = set([p_b_id, p_c_id])
         self.assertEqual(test_pids, message_pids, 'mail.message partners incorrect')
-        # Test: notification linked to this message = group followers = partner_ids
+        # Test: notification linked to this message = group followers = notified_partner_ids
         notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.id)])
         notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
         self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
@@ -398,11 +398,11 @@ class test_mail(TestMailMockups):
             self.assertEqual(sent_email['subject'], _mail_subject, 'sent_email subject incorrect')
             self.assertIn(_mail_body2, sent_email['body'], 'sent_email body incorrect')
             self.assertIn(_mail_bodyalt2, sent_email['body_alternative'], 'sent_email body_alternative incorrect')
-        # Test: mail_message: partner_ids = group followers
-        message_pids = set([partner.id for partner in message.partner_ids])
+        # Test: mail_message: notified_partner_ids = group followers
+        message_pids = set([partner.id for partner in message.notified_partner_ids])
         test_pids = set([p_b_id, p_c_id, p_d_id])
         self.assertEqual(message_pids, test_pids, 'mail.message partners incorrect')
-        # Test: notifications linked to this message = group followers = partner_ids
+        # Test: notifications linked to this message = group followers = notified_partner_ids
         notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.id)])
         notif_pids = set([notif.partner_id.id for notif in self.mail_notification.browse(cr, uid, notif_ids)])
         self.assertEqual(notif_pids, test_pids, 'mail.message notification partners incorrect')
@@ -466,12 +466,12 @@ class test_mail(TestMailMockups):
         # Test: mail.message: subject, body inside pre
         self.assertEqual(message.subject,  False, 'mail.message incorrect subject')
         self.assertEqual(message.body, _msg_body, 'mail.message incorrect body')
-        # Test: mail.message: partner_ids = entries in mail.notification: group_pigs fans (a, b) + mail.compose.message partner_ids (c, d)
-        msg_pids = [partner.id for partner in message.partner_ids]
+        # Test: mail.message: notified_partner_ids = entries in mail.notification: group_pigs fans (a, b) + mail.compose.message partner_ids (c, d)
+        msg_pids = [partner.id for partner in message.notified_partner_ids]
         test_pids = [p_b_id, p_c_id, p_d_id]
         notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', message.id)])
         self.assertEqual(len(notif_ids), 3, 'mail.message: too much notifications created')
-        self.assertEqual(set(msg_pids), set(test_pids), 'mail.message partner_ids incorrect')
+        self.assertEqual(set(msg_pids), set(test_pids), 'mail.message notified_partner_ids incorrect')
 
         # ----------------------------------------
         # CASE2: reply to last comment with attachments
index bcf499d..7b90e07 100644 (file)
@@ -56,29 +56,32 @@ class test_mail_access_rights(test_mail.TestMailMockups):
         cr, uid, group_pigs_id = self.cr, self.uid, self.group_pigs_id
         partner_bert_id, partner_raoul_id = self.partner_bert_id, self.partner_raoul_id
         user_bert_id, user_raoul_id = self.user_bert_id, self.user_raoul_id
+        # Data: comment subtype for mail.message creation
+        ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'mail', 'mt_comment')
+        subtype_id = ref and ref[1] or False
 
         # Data: Birds group, private
         group_birds_id = self.mail_group.create(self.cr, self.uid, {'name': 'Birds', 'public': 'private'})
         # Data: raoul is member of Pigs
         self.mail_group.message_subscribe(cr, uid, [group_pigs_id], [partner_raoul_id])
         # Data: various author_ids, partner_ids, documents
-        msg_id1 = self.mail_message.create(cr, uid, {'subject': 'Test', 'body': 'A'})
-        msg_id2 = self.mail_message.create(cr, uid, {'subject': 'Test', 'body': 'A+B', 'partner_ids': [(6, 0, [partner_bert_id])]})
-        msg_id3 = self.mail_message.create(cr, uid, {'subject': 'Test', 'body': 'A Pigs', 'model': 'mail.group', 'res_id': group_pigs_id})
-        msg_id4 = self.mail_message.create(cr, uid, {'subject': 'Test', 'body': 'A+B Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_bert_id])]})
-        msg_id5 = self.mail_message.create(cr, uid, {'subject': 'Test', 'body': 'A+R Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_raoul_id])]})
-        msg_id6 = self.mail_message.create(cr, uid, {'subject': 'Test', 'body': 'A Birds', 'model': 'mail.group', 'res_id': group_birds_id})
-        msg_id7 = self.mail_message.create(cr, user_bert_id, {'subject': 'Test', 'body': 'B'})
-        msg_id8 = self.mail_message.create(cr, user_bert_id, {'subject': 'Test', 'body': 'B+R', 'partner_ids': [(6, 0, [partner_raoul_id])]})
+        msg_id1 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A', 'subtype_id': subtype_id})
+        msg_id2 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B', 'partner_ids': [(6, 0, [partner_bert_id])], 'subtype_id': subtype_id})
+        msg_id3 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'subtype_id': subtype_id})
+        msg_id4 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+B Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_bert_id])], 'subtype_id': subtype_id})
+        msg_id5 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A+R Pigs', 'model': 'mail.group', 'res_id': group_pigs_id, 'partner_ids': [(6, 0, [partner_raoul_id])], 'subtype_id': subtype_id})
+        msg_id6 = self.mail_message.create(cr, uid, {'subject': '_Test', 'body': 'A Birds', 'model': 'mail.group', 'res_id': group_birds_id, 'subtype_id': subtype_id})
+        msg_id7 = self.mail_message.create(cr, user_bert_id, {'subject': '_Test', 'body': 'B', 'subtype_id': subtype_id})
+        msg_id8 = self.mail_message.create(cr, user_bert_id, {'subject': '_Test', 'body': 'B+R', 'partner_ids': [(6, 0, [partner_raoul_id])], 'subtype_id': subtype_id})
 
         # Test: Bert: 2 messages that have Bert in partner_ids + 2 messages as author
-        msg_ids = self.mail_message.search(cr, user_bert_id, [('subject', 'like', 'Test')])
+        msg_ids = self.mail_message.search(cr, user_bert_id, [('subject', 'like', '_Test')])
         self.assertEqual(set([msg_id2, msg_id4, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed')
         # Test: Raoul: 3 messages on Pigs Raoul can read (employee can read group with default values), 0 on Birds (private group)
-        msg_ids = self.mail_message.search(cr, user_raoul_id, [('body', 'like', 'A')])
+        msg_ids = self.mail_message.search(cr, user_raoul_id, [('subject', 'like', '_Test'), ('body', 'like', 'A')])
         self.assertEqual(set([msg_id3, msg_id4, msg_id5]), set(msg_ids), 'mail_message search failed')
         # Test: Admin: all messages
-        msg_ids = self.mail_message.search(cr, uid, [('subject', 'like', 'Test')])
+        msg_ids = self.mail_message.search(cr, uid, [('subject', 'like', '_Test')])
         self.assertEqual(set([msg_id1, msg_id2, msg_id3, msg_id4, msg_id5, msg_id6, msg_id7, msg_id8]), set(msg_ids), 'mail_message search failed')
 
     def test_05_mail_message_read_access_rights(self):