[MERGE] Revisions 8997 ... 8999 of 7.0 branch.
authorThibault Delavallée <tde@openerp.com>
Fri, 26 Apr 2013 13:27:21 +0000 (15:27 +0200)
committerThibault Delavallée <tde@openerp.com>
Fri, 26 Apr 2013 13:27:21 +0000 (15:27 +0200)
bzr revid: tde@openerp.com-20130426132721-02lkoc41fms9ve1k

1  2 
addons/mail/mail_mail.py
addons/mail/mail_thread.py
addons/mail/static/src/js/mail.js
addons/mail/tests/test_mail_gateway.py

@@@ -240,12 -194,42 +264,17 @@@ class mail_mail(osv.Model)
              :param browse_record partner: specific recipient partner
          """
          body = mail.body_html
 +
 +        # add footer
 +        body_footer = self.send_get_mail_body_footer(cr, uid, mail, partner=partner, context=context)
 +        body = tools.append_content_to_html(body, body_footer, plaintext=False, container_tag='div')
++
+         # generate footer
+         link = self._get_partner_access_link(cr, uid, mail, partner, context=context)
+         if link:
+             body = tools.append_content_to_html(body, link, plaintext=False, container_tag='div')
          return body
  
 -    def send_get_mail_reply_to(self, cr, uid, mail, partner=None, context=None):
 -        """ Return a specific ir_email reply_to.
 -
 -            :param browse_record mail: mail.mail browse_record
 -            :param browse_record partner: specific recipient partner
 -        """
 -        if mail.reply_to:
 -            return mail.reply_to
 -        email_reply_to = False
 -
 -        # if model and res_id: try to use ``message_get_reply_to`` that returns the document alias
 -        if mail.model and mail.res_id and hasattr(self.pool.get(mail.model), 'message_get_reply_to'):
 -            email_reply_to = self.pool.get(mail.model).message_get_reply_to(cr, uid, [mail.res_id], context=context)[0]
 -        # no alias reply_to -> reply_to will be the email_from, only the email part
 -        if not email_reply_to and mail.email_from:
 -            emails = tools.email_split(mail.email_from)
 -            if emails:
 -                email_reply_to = emails[0]
 -
 -        # format 'Document name <email_address>'
 -        if email_reply_to and mail.model and mail.res_id:
 -            document_name = self.pool.get(mail.model).name_get(cr, SUPERUSER_ID, [mail.res_id], context=context)[0]
 -            if document_name:
 -                # sanitize document name
 -                sanitized_doc_name = re.sub(r'[^\w+.]+', '-', document_name[1])
 -                # generate reply to
 -                email_reply_to = _('"Followers of %s" <%s>') % (sanitized_doc_name, email_reply_to)
 -
 -        return email_reply_to
 -
      def send_get_email_dict(self, cr, uid, mail, partner=None, context=None):
          """ Return a dictionary for specific email values, depending on a
              partner, or generic to the whole recipients given by mail.email_to.
@@@ -429,26 -389,54 +429,75 @@@ class mail_thread(osv.AbstractModel)
              return [('message_unread', '=', True)]
          return []
  
 +    def _garbage_collect_attachments(self, cr, uid, context=None):
 +        """ Garbage collect lost mail attachments. Those are attachments
 +            - linked to res_model 'mail.compose.message', the composer wizard
 +            - with res_id 0, because they were created outside of an existing
 +                wizard (typically user input through Chatter or reports
 +                created on-the-fly by the templates)
 +            - unused since at least one day (create_date and write_date)
 +        """
 +        limit_date = datetime.datetime.utcnow() - datetime.timedelta(days=1)
 +        limit_date_str = datetime.datetime.strftime(limit_date, tools.DEFAULT_SERVER_DATETIME_FORMAT)
 +        ir_attachment_obj = self.pool.get('ir.attachment')
 +        attach_ids = ir_attachment_obj.search(cr, uid, [
 +                            ('res_model', '=', 'mail.compose.message'),
 +                            ('res_id', '=', 0),
 +                            ('create_date', '<', limit_date_str),
 +                            ('write_date', '<', limit_date_str),
 +                            ], context=context)
 +        ir_attachment_obj.unlink(cr, uid, attach_ids, context=context)
 +        return True
 +
+     def message_redirect_get_inbox_action_xml_id(self, cr, uid, context=None):
+         """ When redirecting towards the Inbox, choose which action xml_id has
+             to be fetched. This method is meant to be inherited, at least in portal
+             because portal users have a different Inbox action than classic users. """
+         return ('mail', 'action_mail_inbox_feeds')
+     def message_redirect_action(self, cr, uid, context=None):
+         """ For a given message, return an action that either
+             - opens the form view of the related document if model, res_id, and
+               read access to the document
+             - opens the Inbox with a default search on the conversation if model,
+               res_id
+             - opens the Inbox with context propagated
++
+         """
+         if context is None:
+             context = {}
+         # default action is the Inbox action
+         self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
+         act_model, act_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, *self.message_redirect_get_inbox_action_xml_id(cr, uid, context=context))
+         action = self.pool.get(act_model).read(cr, uid, act_id, [])
+         # if msg_id specified: try to redirect to the document or fallback on the Inbox
+         msg_id = context.get('params', {}).get('message_id')
+         if not msg_id:
+             return action
+         msg = self.pool.get('mail.message').browse(cr, uid, msg_id, context=context)
+         if msg.model and msg.res_id and self.pool.get(msg.model).check_access_rights(cr, uid, 'read', raise_exception=False):
+             try:
+                 self.pool.get(msg.model).check_access_rule(cr, uid, [msg.res_id], 'read', context=context)
+                 action = {
+                     'type': 'ir.actions.act_window',
+                     'res_model': msg.model,
+                     'view_type': 'form',
+                     'view_mode': 'form',
+                     'views': [(msg.res_id, 'form')],
+                     'target': 'current',
+                     'res_id': msg.res_id,
+                 }
+             except osv.except_osv:
+                 action.update({
+                     'context': {
+                         'search_default_model': msg.model,
+                         'search_default_res_id': msg.res_id,
+                     }
+                 })
+         return action
      #------------------------------------------------------
      # Email specific
      #------------------------------------------------------
Simple merge
@@@ -83,47 -84,8 +84,48 @@@ Sylvi
  
  class TestMailgateway(TestMailBase):
  
 +    def test_00_partner_find_from_email(self):
 +        """ Tests designed for partner fetch based on emails. """
 +        cr, uid, user_raoul, group_pigs = self.cr, self.uid, self.user_raoul, self.group_pigs
 +
 +        # --------------------------------------------------
 +        # Data creation
 +        # --------------------------------------------------
 +        # 1 - Partner ARaoul
 +        p_a_id = self.res_partner.create(cr, uid, {'name': 'ARaoul', 'email': 'test@test.fr'})
 +
 +        # --------------------------------------------------
 +        # CASE1: without object
 +        # --------------------------------------------------
 +
 +        # Do: find partner with email -> first partner should be found
 +        partner_info = self.mail_thread.message_find_partner_from_emails(cr, uid, None, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
 +        self.assertEqual(partner_info['full_name'], 'Maybe Raoul <test@test.fr>',
 +                        'mail_thread: message_find_partner_from_emails did not handle email')
 +        self.assertEqual(partner_info['partner_id'], p_a_id,
 +                        'mail_thread: message_find_partner_from_emails wrong partner found')
 +
 +        # Data: add some data about partners
 +        # 2 - User BRaoul
 +        p_b_id = self.res_partner.create(cr, uid, {'name': 'BRaoul', 'email': 'test@test.fr', 'user_ids': [(4, user_raoul.id)]})
 +
 +        # Do: find partner with email -> first user should be found
 +        partner_info = self.mail_thread.message_find_partner_from_emails(cr, uid, None, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
 +        self.assertEqual(partner_info['partner_id'], p_b_id,
 +                        'mail_thread: message_find_partner_from_emails wrong partner found')
 +
 +        # --------------------------------------------------
 +        # CASE1: with object
 +        # --------------------------------------------------
 +
 +        # Do: find partner in group where there is a follower with the email -> should be taken
 +        self.mail_group.message_subscribe(cr, uid, [group_pigs.id], [p_b_id])
 +        partner_info = self.mail_group.message_find_partner_from_emails(cr, uid, group_pigs.id, ['Maybe Raoul <test@test.fr>'], link_mail=False)[0]
 +        self.assertEqual(partner_info['partner_id'], p_b_id,
 +                        'mail_thread: message_find_partner_from_emails wrong partner found')
 +
+     @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
 -    def test_00_message_process(self):
 +    def test_10_message_process(self):
          """ Testing incoming emails processing. """
          cr, uid, user_raoul = self.cr, self.uid, self.user_raoul
  
          self.assertEqual(msg.body, '<pre>\nPlease call me as soon as possible this afternoon!\n\n--\nSylvie\n</pre>',
                              'message_process: plaintext incoming email incorrectly parsed')
  
+     @mute_logger('openerp.addons.mail.mail_thread', 'openerp.osv.orm')
 -    def test_10_thread_parent_resolution(self):
 +    def test_20_thread_parent_resolution(self):
          """ Testing parent/child relationships are correctly established when processing incoming mails """
          cr, uid = self.cr, self.uid