[MERGE] trunk
authorFabien Pinckaers <fp@openerp.com>
Wed, 15 Aug 2012 18:57:13 +0000 (20:57 +0200)
committerFabien Pinckaers <fp@openerp.com>
Wed, 15 Aug 2012 18:57:13 +0000 (20:57 +0200)
bzr revid: fp@openerp.com-20120815185713-82zylb0yqqgs008y

1  2 
addons/mail/__init__.py
addons/mail/mail_message.py
addons/mail/mail_thread.py
addons/mail/res_partner.py
addons/mail/res_users.py
addons/mail/wizard/mail_compose_message.py
addons/purchase/purchase.py
addons/purchase/purchase_view.xml
addons/sale/sale.py

@@@ -25,8 -24,9 +25,8 @@@ import mail_mai
  import mail_thread
  import mail_group
  import mail_subscription
- import res_users
 -import ir_needaction
  import res_partner
+ import res_users
  import report
  import wizard
  import res_config
@@@ -90,20 -208,28 +93,19 @@@ 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"),
 -        'partner_id': fields.many2one('res.partner', 'Related partner',
 -            help="Deprecated field. Use partner_ids instead."),
 +
 +        # partner_id should be renamed into author_id, user_id removed
 +        'author_id': fields.many2one('res.partner', 'Author', required=True),
 +
 +        # this is redundant with notifications ? Yes
          'partner_ids': fields.many2many('res.partner',
-             'mail_message_destination_partner_rel',
+             'mail_message_res_partner_rel',
              'message_id', 'partner_id', 'Destination partners',
              help="When sending emails through the social network composition wizard"\
                   "you may choose to send a copy of the mail to partners."),
 -        'user_id': fields.many2one('res.users', 'Related User', readonly=1),
 -        'attachment_ids': fields.many2many('ir.attachment', 'message_attachment_rel',
 -            'message_id', 'attachment_id', 'Attachments'),
 -        'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing mail server', readonly=1),
 -        'state': fields.selection([
 -                        ('outgoing', 'Outgoing'),
 -                        ('sent', 'Sent'),
 -                        ('received', 'Received'),
 -                        ('exception', 'Delivery Failed'),
 -                        ('cancel', 'Cancelled'),
 -                        ], 'Status', readonly=True),
 -        'auto_delete': fields.boolean('Auto Delete',
 -            help="Permanently delete this email after sending it, to save space"),
 -        'original': fields.binary('Original', readonly=1,
 -            help="Original version of the message, as it was sent on the network"),
 +        'attachment_ids': fields.one2many('ir.attachment', 'res_id', 'Attachments'
 +            domain=[('res_model','=','mail.message')]),
 +
          'parent_id': fields.many2one('mail.message', 'Parent Message',
              select=True, ondelete='set null',
              help="Parent message, used for displaying as threads with hierarchy"),
          self.check(cr, uid, ids, 'unlink', context=context)
          return super(mail_message, self).unlink(cr, uid, ids, context)
  
-     # FP Note: to be simplified, mail.message fields only, not mail.mail
 -    def schedule_with_attach(self, cr, uid, email_from, email_to, subject, body, model=False, type='email',
 -                             email_cc=None, email_bcc=None, reply_to=False, partner_ids=None, attachments=None,
 -                             message_id=False, references=False, res_id=False, content_subtype='plain',
 -                             headers=None, mail_server_id=False, auto_delete=False, context=None):
 -        """ Schedule sending a new email message, to be sent the next time the
 -            mail scheduler runs, or the next time :meth:`process_email_queue` is
 -            called explicitly.
 -
 -            :param string email_from: sender email address
 -            :param list email_to: list of recipient addresses (to be joined with commas) 
 -            :param string subject: email subject (no pre-encoding/quoting necessary)
 -            :param string body: email body, according to the ``content_subtype`` 
 -                (by default, plaintext). If html content_subtype is used, the
 -                message will be automatically converted to plaintext and wrapped
 -                in multipart/alternative.
 -            :param list email_cc: optional list of string values for CC header
 -                (to be joined with commas)
 -            :param list email_bcc: optional list of string values for BCC header
 -                (to be joined with commas)
 -            :param string model: optional model name of the document this mail
 -                is related to (this will also be used to generate a tracking id,
 -                used to match any response related to the same document)
 -            :param int res_id: optional resource identifier this mail is related
 -                to (this will also be used to generate a tracking id, used to
 -                match any response related to the same document)
 -            :param string reply_to: optional value of Reply-To header
 -            :param partner_ids: destination partner_ids
 -            :param string content_subtype: optional mime content_subtype for
 -                the text body (usually 'plain' or 'html'), must match the format
 -                of the ``body`` parameter. Default is 'plain', making the content
 -                part of the mail "text/plain".
 -            :param dict attachments: map of filename to filecontents, where
 -                filecontents is a string containing the bytes of the attachment
 -            :param dict headers: optional map of headers to set on the outgoing
 -                mail (may override the other headers, including Subject,
 -                Reply-To, Message-Id, etc.)
 -            :param int mail_server_id: optional id of the preferred outgoing
 -                mail server for this mail
 -            :param bool auto_delete: optional flag to turn on auto-deletion of
 -                the message after it has been successfully sent (default to False)
 -        """
 -        if context is None:
 -            context = {}
 -        if attachments is None:
 -            attachments = {}
 -        if partner_ids is None:
 -            partner_ids = []
 -        attachment_obj = self.pool.get('ir.attachment')
 -        for param in (email_to, email_cc, email_bcc):
 -            if param and not isinstance(param, list):
 -                param = [param]
 -        msg_vals = {
 -                'subject': subject,
 -                'date': fields.datetime.now(),
 -                'user_id': uid,
 -                'model': model,
 -                'res_id': res_id,
 -                'type': type,
 -                'body_text': body if content_subtype != 'html' else False,
 -                'body_html': body if content_subtype == 'html' else False,
 -                'email_from': email_from,
 -                'email_to': email_to and ','.join(email_to) or '',
 -                'email_cc': email_cc and ','.join(email_cc) or '',
 -                'email_bcc': email_bcc and ','.join(email_bcc) or '',
 -                'partner_ids': partner_ids,
 -                'reply_to': reply_to,
 -                'message_id': message_id,
 -                'references': references,
 -                'content_subtype': content_subtype,
 -                'headers': headers, # serialize the dict on the fly
 -                'mail_server_id': mail_server_id,
 -                'state': 'outgoing',
 -                'auto_delete': auto_delete
 -            }
 -        email_msg_id = self.create(cr, uid, msg_vals, context)
 -        attachment_ids = []
 -        for attachment in attachments:
 -            fname, fcontent = attachment
 -            attachment_data = {
 -                    'name': fname,
 -                    'datas_fname': fname,
 -                    'datas': fcontent and fcontent.encode('base64'),
 -                    'res_model': self._name,
 -                    'res_id': email_msg_id,
 -            }
 -            if context.has_key('default_type'):
 -                del context['default_type']
 -            attachment_ids.append(attachment_obj.create(cr, uid, attachment_data, context))
 -        if attachment_ids:
 -            self.write(cr, uid, email_msg_id, { 'attachment_ids': [(6, 0, attachment_ids)]}, context=context)
 -        return email_msg_id
 -
 -    def mark_outgoing(self, cr, uid, ids, context=None):
 -        return self.write(cr, uid, ids, {'state':'outgoing'}, context=context)
 -
 -    def cancel(self, cr, uid, ids, context=None):
 -        return self.write(cr, uid, ids, {'state':'cancel'}, context=context)
 -
 -    def process_email_queue(self, cr, uid, ids=None, context=None):
 -        """Send immediately queued messages, committing after each
 -           message is sent - this is not transactional and should
 -           not be called during another transaction!
 -
 -           :param list ids: optional list of emails ids to send. If passed
 -                            no search is performed, and these ids are used
 -                            instead.
 -           :param dict context: if a 'filters' key is present in context,
 -                                this value will be used as an additional
 -                                filter to further restrict the outgoing
 -                                messages to send (by default all 'outgoing'
 -                                messages are sent).
 -        """
 -        if context is None:
 -            context = {}
 -        if not ids:
 -            filters = ['&', ('state', '=', 'outgoing'), ('type', '=', 'email')]
 -            if 'filters' in context:
 -                filters.extend(context['filters'])
 -            ids = self.search(cr, uid, filters, context=context)
 -        res = None
 -        try:
 -            # Force auto-commit - this is meant to be called by
 -            # the scheduler, and we can't allow rolling back the status
 -            # of previously sent emails!
 -            res = self.send(cr, uid, ids, auto_commit=True, context=context)
 -        except Exception:
 -            _logger.exception("Failed processing mail queue")
 -        return res
 -
      def parse_message(self, message, save_original=False, context=None):
          """Parses a string or email.message.Message representing an
             RFC-2822 email, and returns a generic dict holding the
Simple merge
@@@ -29,20 -28,20 +28,29 @@@ class res_partner_mail(osv.Model)
  
      def message_search_get_domain(self, cr, uid, ids, context=None):
          """ Override of message_search_get_domain for partner discussion page.
-             The purpose is to add messages directly sent to the partner.
+             The purpose is to add messages directly sent to the partner. It also
+             adds messages pushed to the related user, if any, using @login.
          """
          initial_domain = super(res_partner_mail, self).message_search_get_domain(cr, uid, ids, context=context)
-         if self._name == 'res.partner': # to avoid models inheriting from res.partner
-             search_domain = ['|'] + initial_domain + ['|', ('partner_id', 'in', ids), ('partner_ids', 'in', ids)]
+         # to avoid models inheriting from res.partner
+         if self._name != 'res.partner':
+             return initial_domain
+         # add message linked to the partner
+         search_domain = ['|'] + initial_domain + ['|', ('partner_id', 'in', ids), ('partner_ids', 'in', ids)]
+         # if partner is linked to a user: find @login
+         res_users_obj = self.pool.get('res.users')
+         user_ids = res_users_obj.search(cr, uid, [('partner_id', 'in', ids)], context=context)
+         for user in res_users_obj.browse(cr, uid, user_ids, context=context):
+             search_domain = ['|'] + search_domain + ['|', ('body_text', 'like', '@%s' % (user.login)), ('body_html', 'like', '@%s' % (user.login))]
          return search_domain
 +    _columns = {
 +        'notification_email_pref': fields.selection([
 +            ('all', 'All feeds'),
 +            ('comment', 'Comments and emails'),
 +            ('none', 'Never')
 +            ], 'Receive Feeds by Email', required=True,
 +            help="Choose in which case you want to receive an email when you "\
 +                  "receive new feeds."),
 +    }
  
  # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@@ -37,11 -37,18 +37,11 @@@ class res_users(osv.Model)
      _name = 'res.users'
      _inherit = ['res.users']
      _inherits = {'mail.alias': 'alias_id'}
-     
      _columns = {
 -        'notification_email_pref': fields.selection([
 -            ('all', 'All Feeds'),
 -            ('to_me', 'Only send directly to me'),
 -            ('none', 'Never')
 -            ], 'Receive Feeds by Email', required=True,
 -            help="Choose in which case you want to receive an email when you "\
 -                 "receive new feeds."),
          'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True, 
-                                     help="Email address internally associated with this user. Incoming emails will appear "
-                                          "in the user's notifications."),
+             help="Email address internally associated with this user. Incoming "\
+                  "emails will appear in the user's notifications."),
      }
      
      _defaults = {
Simple merge
Simple merge
Simple merge