summaryrefslogtreecommitdiff
path: root/addons/mail/models
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-05-29 17:34:43 +0200
committerChristophe Simonis <chs@odoo.com>2018-05-29 17:34:43 +0200
commitf36e6917bd73a56dc0c7468b4849920df4088154 (patch)
treeb63d02ae3e5ffc0815de009407363e0cf906f547 /addons/mail/models
parentbc0173c2d58ac26d80cb2f483a95c0c13b047dab (diff)
parent37eed7c509fb5846c89ef37046df4b3cab299719 (diff)
[MERGE] forward port branch saas-11.3 up to 37eed7c509f
Diffstat (limited to 'addons/mail/models')
-rw-r--r--addons/mail/models/ir_model.py6
-rw-r--r--addons/mail/models/mail_activity.py5
-rw-r--r--addons/mail/models/mail_message.py11
-rw-r--r--addons/mail/models/mail_thread.py25
-rw-r--r--addons/mail/models/res_users.py13
5 files changed, 40 insertions, 20 deletions
diff --git a/addons/mail/models/ir_model.py b/addons/mail/models/ir_model.py
index 04529610f0e..0b029f3e1a1 100644
--- a/addons/mail/models/ir_model.py
+++ b/addons/mail/models/ir_model.py
@@ -52,12 +52,6 @@ class IrModel(models.Model):
model_class._inherit = parents + ['mail.thread']
return model_class
- def unlink(self):
- # Delete followers for models that will be unlinked.
- query = "DELETE FROM mail_followers WHERE res_model IN %s"
- self.env.cr.execute(query, [tuple(self.mapped('model'))])
- return super(IrModel, self).unlink()
-
class IrModelField(models.Model):
_inherit = 'ir.model.fields'
diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py
index 81975b9826d..3dc7ef85330 100644
--- a/addons/mail/models/mail_activity.py
+++ b/addons/mail/models/mail_activity.py
@@ -89,7 +89,7 @@ class MailActivity(models.Model):
summary = fields.Char('Summary')
note = fields.Html('Note')
feedback = fields.Html('Feedback')
- date_deadline = fields.Date('Due Date', index=True, required=True, default=fields.Date.today)
+ date_deadline = fields.Date('Due Date', index=True, required=True, default=fields.Date.context_today)
automated = fields.Boolean(
'Automated activity', readonly=True,
help='Indicates this activity has been created automatically and not by any user.')
@@ -154,7 +154,8 @@ class MailActivity(models.Model):
@api.onchange('recommended_activity_type_id')
def _onchange_recommended_activity_type_id(self):
- self.activity_type_id = self.recommended_activity_type_id
+ if self.recommended_activity_type_id:
+ self.activity_type_id = self.recommended_activity_type_id
@api.multi
def _check_access(self, operation):
diff --git a/addons/mail/models/mail_message.py b/addons/mail/models/mail_message.py
index 1a69aaa229a..b42de71abcf 100644
--- a/addons/mail/models/mail_message.py
+++ b/addons/mail/models/mail_message.py
@@ -416,8 +416,17 @@ class Message(models.Model):
com_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_comment')
note_id = self.env['ir.model.data'].xmlid_to_res_id('mail.mt_note')
+ # fetch notification status
+ notif_dict = {}
+ notifs = self.env['mail.notification'].sudo().search([('mail_message_id', 'in', list(mid for mid in message_tree)), ('is_read', '=', False)])
+ for notif in notifs:
+ mid = notif.mail_message_id.id
+ if not notif_dict.get(mid):
+ notif_dict[mid] = {'partner_id': list()}
+ notif_dict[mid]['partner_id'].append(notif.res_partner_id.id)
+
for message in message_values:
- message['needaction_partner_ids'] = self.env['mail.notification'].sudo().search([('mail_message_id', '=', message['id']), ('is_read', '=', False)]).mapped('res_partner_id').ids
+ message['needaction_partner_ids'] = notif_dict.get(message['id'], dict()).get('partner_id', [])
message['is_note'] = message['subtype_id'] and subtypes_dict[message['subtype_id'][0]]['id'] == note_id
message['is_discussion'] = message['subtype_id'] and subtypes_dict[message['subtype_id'][0]]['id'] == com_id
message['is_notification'] = message['is_note'] and not message['model'] and not message['res_id']
diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py
index e247df26c8f..587009984cf 100644
--- a/addons/mail/models/mail_thread.py
+++ b/addons/mail/models/mail_thread.py
@@ -120,7 +120,8 @@ class MailThread(models.AbstractModel):
followers = self.env['mail.followers'].sudo().search([
('res_model', '=', self._name),
('partner_id', operator, operand)])
- return [('id', 'in', followers.mapped('res_id'))]
+ # using read() below is much faster than followers.mapped('res_id')
+ return [('id', 'in', [res['res_id'] for res in followers.read(['res_id'])])]
@api.model
def _search_follower_channels(self, operator, operand):
@@ -133,7 +134,8 @@ class MailThread(models.AbstractModel):
followers = self.env['mail.followers'].sudo().search([
('res_model', '=', self._name),
('channel_id', operator, operand)])
- return [('id', 'in', followers.mapped('res_id'))]
+ # using read() below is much faster than followers.mapped('res_id')
+ return [('id', 'in', [res['res_id'] for res in followers.read(['res_id'])])]
@api.multi
@api.depends('message_follower_ids')
@@ -143,7 +145,8 @@ class MailThread(models.AbstractModel):
('res_id', 'in', self.ids),
('partner_id', '=', self.env.user.partner_id.id),
])
- following_ids = followers.mapped('res_id')
+ # using read() below is much faster than followers.mapped('res_id')
+ following_ids = [res['res_id'] for res in followers.read(['res_id'])]
for record in self:
record.message_is_follower = record.id in following_ids
@@ -155,9 +158,11 @@ class MailThread(models.AbstractModel):
])
# Cases ('message_is_follower', '=', True) or ('message_is_follower', '!=', False)
if (operator == '=' and operand) or (operator == '!=' and not operand):
- return [('id', 'in', followers.mapped('res_id'))]
+ # using read() below is much faster than followers.mapped('res_id')
+ return [('id', 'in', [res['res_id'] for res in followers.read(['res_id'])])]
else:
- return [('id', 'not in', followers.mapped('res_id'))]
+ # using read() below is much faster than followers.mapped('res_id')
+ return [('id', 'not in', [res['res_id'] for res in followers.read(['res_id'])])]
@api.multi
def _get_message_unread(self):
@@ -1433,7 +1438,13 @@ class MailThread(models.AbstractModel):
located in tools. """
if not body:
return body, attachments
- root = lxml.html.fromstring(body)
+ try:
+ root = lxml.html.fromstring(body)
+ except ValueError:
+ # In case the email client sent XHTML, fromstring will fail because 'Unicode strings
+ # with encoding declaration are not supported'.
+ root = lxml.html.fromstring(body.encode('utf-8'))
+
postprocessed = False
to_remove = []
for node in root.iter():
@@ -1815,6 +1826,8 @@ class MailThread(models.AbstractModel):
continue
if isinstance(content, pycompat.text_type):
content = content.encode('utf-8')
+ elif content is None:
+ continue
data_attach = {
'name': name,
'datas': base64.b64encode(content),
diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py
index 2068e66c834..0d6ea26579c 100644
--- a/addons/mail/models/res_users.py
+++ b/addons/mail/models/res_users.py
@@ -75,16 +75,19 @@ class Users(models.Model):
def activity_user_count(self):
query = """SELECT m.id, count(*), act.res_model as model,
CASE
- WHEN now()::date - act.date_deadline::date = 0 Then 'today'
- WHEN now()::date - act.date_deadline::date > 0 Then 'overdue'
- WHEN now()::date - act.date_deadline::date < 0 Then 'planned'
+ WHEN %(today)s::date - act.date_deadline::date = 0 Then 'today'
+ WHEN %(today)s::date - act.date_deadline::date > 0 Then 'overdue'
+ WHEN %(today)s::date - act.date_deadline::date < 0 Then 'planned'
END AS states
FROM mail_activity AS act
JOIN ir_model AS m ON act.res_model_id = m.id
- WHERE user_id = %s
+ WHERE user_id = %(user_id)s
GROUP BY m.id, states, act.res_model;
"""
- self.env.cr.execute(query, [self.env.uid])
+ self.env.cr.execute(query, {
+ 'today': fields.Date.context_today(self),
+ 'user_id': self.env.uid,
+ })
activity_data = self.env.cr.dictfetchall()
model_ids = [a['id'] for a in activity_data]
model_names = {n[0]: n[1] for n in self.env['ir.model'].browse(model_ids).name_get()}