summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2018-01-03 12:39:08 +0100
committerThibault Delavallée <tde@odoo.com>2018-01-11 11:52:37 +0100
commitcdfe479e2e92b8bfc4e4d5bb32c1db8ad5c431d6 (patch)
tree76b793c56dc98bed3c8fcafc7ecf1a9fa7daf036 /addons
parent782154da11975b9db4620d7d39df3b567f3abcdc (diff)
[MOV] mail: reorder a bit mail thread methods by category
As this class has grown a lot some methods have been put a bit anywhere in the file. To prepare future improvements it is easier to regroup them a bit. remove_accent from mail_alias is also moved to tools in order to separate tools from business or class specific code.
Diffstat (limited to 'addons')
-rw-r--r--addons/mail/models/mail_alias.py13
-rw-r--r--addons/mail/models/mail_thread.py234
2 files changed, 116 insertions, 131 deletions
diff --git a/addons/mail/models/mail_alias.py b/addons/mail/models/mail_alias.py
index dc09f3be13b..2594d3162e0 100644
--- a/addons/mail/models/mail_alias.py
+++ b/addons/mail/models/mail_alias.py
@@ -3,26 +3,15 @@
import logging
import re
-import unicodedata
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
-from odoo.tools import ustr
+from odoo.tools import remove_accents
from odoo.tools.safe_eval import safe_eval
_logger = logging.getLogger(__name__)
-# Inspired by http://stackoverflow.com/questions/517923
-def remove_accents(input_str):
- """Suboptimal-but-better-than-nothing way to replace accented
- latin letters by an ASCII equivalent. Will obviously change the
- meaning of input_str and work only for some cases"""
- input_str = ustr(input_str)
- nkfd_form = unicodedata.normalize('NFKD', input_str)
- return u''.join([c for c in nkfd_form if not unicodedata.combining(c)])
-
-
class Alias(models.Model):
"""A Mail Alias is a mapping of an email address with a given Odoo Document
model. It is used by Odoo's mail gateway when processing incoming emails
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index 1131f1fe570..b0e15d1a106 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -298,10 +298,6 @@ class MailThread(models.AbstractModel):
# avoid tracking multiple temporary changes during copy
return super(MailThread, self.with_context(mail_notrack=True)).copy_data(default=default)
- # ------------------------------------------------------
- # Technical methods (to clean / move to controllers ?)
- # ------------------------------------------------------
-
@api.model
def get_empty_list_help(self, help):
""" Override of BaseModel.get_empty_list_help() to generate an help message
@@ -373,6 +369,89 @@ class MailThread(models.AbstractModel):
return res
# ------------------------------------------------------
+ # Technical methods / wrappers / tools
+ # ------------------------------------------------------
+
+ @api.model
+ def _garbage_collect_attachments(self):
+ """ 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)
+ self.env['ir.attachment'].search([
+ ('res_model', '=', 'mail.compose.message'),
+ ('res_id', '=', 0),
+ ('create_date', '<', limit_date_str),
+ ('write_date', '<', limit_date_str)]
+ ).unlink()
+ return True
+
+ @api.model
+ def check_mail_message_access(self, res_ids, operation, model_name=None):
+ """ mail.message check permission rules for related document. This method is
+ meant to be inherited in order to implement addons-specific behavior.
+ A common behavior would be to allow creating messages when having read
+ access rule on the document, for portal document such as issues. """
+ if model_name:
+ DocModel = self.env[model_name]
+ else:
+ DocModel = self
+ if hasattr(DocModel, '_mail_post_access'):
+ create_allow = DocModel._mail_post_access
+ else:
+ create_allow = 'write'
+
+ if operation in ['write', 'unlink']:
+ check_operation = 'write'
+ elif operation == 'create' and create_allow in ['create', 'read', 'write', 'unlink']:
+ check_operation = create_allow
+ elif operation == 'create':
+ check_operation = 'write'
+ else:
+ check_operation = operation
+
+ DocModel.check_access_rights(check_operation)
+ DocModel.browse(res_ids).check_access_rule(check_operation)
+
+ @api.multi
+ def message_change_thread(self, new_thread):
+ """
+ Transfer the list of the mail thread messages from an model to another
+
+ :param id : the old res_id of the mail.message
+ :param new_res_id : the new res_id of the mail.message
+ :param new_model : the name of the new model of the mail.message
+
+ Example : my_lead.message_change_thread(my_project_task)
+ will transfer the context of the thread of my_lead to my_project_task
+ """
+ self.ensure_one()
+ # get the subtype of the comment Message
+ subtype_comment = self.env.ref('mail.mt_comment')
+
+ # get the ids of the comment and not-comment of the thread
+ # TDE check: sudo on mail.message, to be sure all messages are moved ?
+ MailMessage = self.env['mail.message']
+ msg_comment = MailMessage.search([
+ ('model', '=', self._name),
+ ('res_id', '=', self.id),
+ ('subtype_id', '=', subtype_comment.id)])
+ msg_not_comment = MailMessage.search([
+ ('model', '=', self._name),
+ ('res_id', '=', self.id),
+ ('subtype_id', '!=', subtype_comment.id)])
+
+ # update the messages
+ msg_comment.write({"res_id": new_thread.id, "model": new_thread._name})
+ msg_not_comment.write({"res_id": new_thread.id, "model": new_thread._name, "subtype_id": None})
+ return True
+
+ # ------------------------------------------------------
# Automatic log / Tracking
# ------------------------------------------------------
@@ -504,55 +583,9 @@ class MailThread(models.AbstractModel):
return True
- #------------------------------------------------------
- # mail.message wrappers and tools
- #------------------------------------------------------
-
- @api.model
- def _garbage_collect_attachments(self):
- """ 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)
- self.env['ir.attachment'].search([
- ('res_model', '=', 'mail.compose.message'),
- ('res_id', '=', 0),
- ('create_date', '<', limit_date_str),
- ('write_date', '<', limit_date_str)]
- ).unlink()
- return True
-
- @api.model
- def check_mail_message_access(self, res_ids, operation, model_name=None):
- """ mail.message check permission rules for related document. This method is
- meant to be inherited in order to implement addons-specific behavior.
- A common behavior would be to allow creating messages when having read
- access rule on the document, for portal document such as issues. """
- if model_name:
- DocModel = self.env[model_name]
- else:
- DocModel = self
- if hasattr(DocModel, '_mail_post_access'):
- create_allow = DocModel._mail_post_access
- else:
- create_allow = 'write'
-
- if operation in ['write', 'unlink']:
- check_operation = 'write'
- elif operation == 'create' and create_allow in ['create', 'read', 'write', 'unlink']:
- check_operation = create_allow
- elif operation == 'create':
- check_operation = 'write'
- else:
- check_operation = operation
-
- DocModel.check_access_rights(check_operation)
- DocModel.browse(res_ids).check_access_rule(check_operation)
+ # ------------------------------------------------------
+ # Email Notification
+ # ------------------------------------------------------
@api.model
def _generate_notification_token(self, base_link, params):
@@ -706,32 +739,6 @@ class MailThread(models.AbstractModel):
return result
- # ------------------------------------------------------
- # Email specific
- # ------------------------------------------------------
-
- @api.multi
- def message_get_default_recipients(self, res_model=None, res_ids=None):
- if res_model and res_ids:
- if hasattr(self.env[res_model], 'message_get_default_recipients'):
- return self.env[res_model].browse(res_ids).message_get_default_recipients()
- records = self.env[res_model].sudo().browse(res_ids)
- else:
- records = self.sudo()
- res = {}
- for record in records:
- recipient_ids, email_to, email_cc = set(), False, False
- if 'partner_id' in self._fields and record.partner_id:
- recipient_ids.add(record.partner_id.id)
- elif 'email_from' in self._fields and record.email_from:
- email_to = record.email_from
- elif 'partner_email' in self._fields and record.partner_email:
- email_to = record.partner_email
- elif 'email' in self._fields:
- email_to = record.email
- res[record.id] = {'partner_ids': list(recipient_ids), 'email_to': email_to, 'email_cc': email_cc}
- return res
-
@api.model
def message_get_reply_to(self, res_ids, default=None):
""" Returns the preferred reply-to email address that is basically the
@@ -1550,9 +1557,31 @@ class MailThread(models.AbstractModel):
msg_dict['body'], msg_dict['attachments'] = self._message_extract_payload(message, save_original=save_original)
return msg_dict
- #------------------------------------------------------
- # Note specific
- #------------------------------------------------------
+ # ------------------------------------------------------
+ # Recipient management
+ # ------------------------------------------------------
+
+ @api.multi
+ def message_get_default_recipients(self, res_model=None, res_ids=None):
+ if res_model and res_ids:
+ if hasattr(self.env[res_model], 'message_get_default_recipients'):
+ return self.env[res_model].browse(res_ids).message_get_default_recipients()
+ records = self.env[res_model].sudo().browse(res_ids)
+ else:
+ records = self.sudo()
+ res = {}
+ for record in records:
+ recipient_ids, email_to, email_cc = set(), False, False
+ if 'partner_id' in self._fields and record.partner_id:
+ recipient_ids.add(record.partner_id.id)
+ elif 'email_from' in self._fields and record.email_from:
+ email_to = record.email_from
+ elif 'partner_email' in self._fields and record.partner_email:
+ email_to = record.partner_email
+ elif 'email' in self._fields:
+ email_to = record.email
+ res[record.id] = {'partner_ids': list(recipient_ids), 'email_to': email_to, 'email_cc': email_cc}
+ return res
@api.multi
def _message_add_suggested_recipient(self, result, partner=None, email=None, reason=''):
@@ -1689,6 +1718,10 @@ class MailThread(models.AbstractModel):
]).write({'author_id': partner_info['partner_id']})
return result
+ # ------------------------------------------------------
+ # Post / Send message API
+ # ------------------------------------------------------
+
def _message_post_process_attachments(self, attachments, attachment_ids, message_data):
""" Preprocess attachments for mail_thread.message_post() or mail_mail.create().
@@ -2148,40 +2181,3 @@ class MailThread(models.AbstractModel):
self._message_auto_subscribe_notify(user_pids)
return True
-
- # ------------------------------------------------------
- # Thread management
- # ------------------------------------------------------
-
- @api.multi
- def message_change_thread(self, new_thread):
- """
- Transfer the list of the mail thread messages from an model to another
-
- :param id : the old res_id of the mail.message
- :param new_res_id : the new res_id of the mail.message
- :param new_model : the name of the new model of the mail.message
-
- Example : my_lead.message_change_thread(my_project_task)
- will transfer the context of the thread of my_lead to my_project_task
- """
- self.ensure_one()
- # get the subtype of the comment Message
- subtype_comment = self.env.ref('mail.mt_comment')
-
- # get the ids of the comment and not-comment of the thread
- # TDE check: sudo on mail.message, to be sure all messages are moved ?
- MailMessage = self.env['mail.message']
- msg_comment = MailMessage.search([
- ('model', '=', self._name),
- ('res_id', '=', self.id),
- ('subtype_id', '=', subtype_comment.id)])
- msg_not_comment = MailMessage.search([
- ('model', '=', self._name),
- ('res_id', '=', self.id),
- ('subtype_id', '!=', subtype_comment.id)])
-
- # update the messages
- msg_comment.write({"res_id": new_thread.id, "model": new_thread._name})
- msg_not_comment.write({"res_id": new_thread.id, "model": new_thread._name, "subtype_id": None})
- return True