], '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