[IMP] mail, im_livechat: inline sql instead of long id list

using inselect operator to inline sql in the search method and avoid ORM
to fetch multiple useless messages to check if there's one

closes odoo/odoo#70410

X-original-commit: 505c7b0946689d3ac1ac4dd2f59cf4d535c36cbb
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Nicolas Seinlet
2021-05-05 12:40:29 +00:00
parent c4f9d83c25
commit 9a01a2953f
6 changed files with 30 additions and 10 deletions
@@ -76,7 +76,7 @@ class ImLivechatChannel(models.Model):
def _compute_nbr_channel(self):
data = self.env['mail.channel'].read_group([
('livechat_channel_id', 'in', self._ids),
('message_ids', '!=', False)], ['__count'], ['livechat_channel_id'], lazy=False)
('has_message', '=', True)], ['__count'], ['livechat_channel_id'], lazy=False)
channel_count = {x['livechat_channel_id'][0]: x['__count'] for x in data}
for record in self:
record.nbr_channel = channel_count.get(record.id, 0)
@@ -129,7 +129,7 @@
<field name="name">Sessions</field>
<field name="res_model">mail.channel</field>
<field name="view_mode">tree,form</field>
<field name="domain">[('livechat_channel_id', 'in', [active_id]), ('message_ids', '!=', False)]</field>
<field name="domain">[('livechat_channel_id', 'in', [active_id]), ('has_message', '=', True)]</field>
<field name="context">{
'search_default_livechat_channel_id': [active_id],
'default_livechat_channel_id': active_id,
+25 -5
View File
@@ -88,6 +88,7 @@ class MailThread(models.AbstractModel):
message_ids = fields.One2many(
'mail.message', 'res_id', string='Messages',
domain=lambda self: [('message_type', '!=', 'user_notification')], auto_join=True)
has_message = fields.Boolean(compute="_compute_has_message", search="_search_has_message", store=False)
message_unread = fields.Boolean(
'Unread Messages', compute='_get_message_unread',
help="If checked, new messages require your attention.")
@@ -154,6 +155,25 @@ class MailThread(models.AbstractModel):
# 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'])])]
def _compute_has_message(self):
self.flush()
self.env.cr.execute("""
SELECT distinct res_id
FROM mail_message mm
WHERE res_id = any(%s)
AND mm.model=%s
""", [self.ids, self._name])
channel_ids = [r[0] for r in self.env.cr.fetchall()]
for record in self:
record.has_message = record.id in channel_ids
def _search_has_message(self, operator, value):
if (operator == '=' and value is True) or (operator == '!=' and value is False):
operator_new = 'inselect'
else:
operator_new = 'not inselect'
return [('id', operator_new, ("SELECT distinct res_id FROM mail_message WHERE model=%s", [self._name]))]
def _get_message_unread(self):
partner_id = self.env.user.partner_id.id
res = dict.fromkeys(self.ids, 0)
@@ -888,7 +908,7 @@ class MailThread(models.AbstractModel):
# 0. Handle bounce: verify whether this is a bounced email and use it to collect bounce data and update notifications for customers
# Bounce regex: typical form of bounce is bounce_alias+128-crm.lead-34@domain
# group(1) = the mail ID; group(2) = the model (if any); group(3) = the record ID
# group(1) = the mail ID; group(2) = the model (if any); group(3) = the record ID
# Bounce message (not alias)
# See http://datatracker.ietf.org/doc/rfc3462/?include_text=1
# As all MTA does not respect this RFC (googlemail is one of them),
@@ -1655,7 +1675,7 @@ class MailThread(models.AbstractModel):
m2m_attachment_ids += [Command.link(id) for id in attachment_ids]
# Handle attachments parameter, that is a dictionary of attachments
if attachments: # generate
if attachments: # generate
cids_in_body = set()
names_in_body = set()
cid_list = []
@@ -1925,7 +1945,7 @@ class MailThread(models.AbstractModel):
def message_notify(self, *,
partner_ids=False, parent_id=False, model=False, res_id=False,
author_id=None, email_from=None, body='', subject=False, **kwargs):
""" Shortcut allowing to notify partners of messages that shouldn't be
""" Shortcut allowing to notify partners of messages that shouldn't be
displayed on a document. It pushes notifications on inbox or by email depending
on the user configuration, like other notifications. """
if self:
@@ -2480,7 +2500,7 @@ class MailThread(models.AbstractModel):
'button_access': {'title': 'View Simple Chatter Model',
'url': '/mail/view?model=mail.test.simple&res_id=1497'},
'has_button_access': False,
'recipients': [4, 5, 6]
'recipients': [4, 5, 6]
},
{
'actions': [],
@@ -2706,7 +2726,7 @@ class MailThread(models.AbstractModel):
new_partner_subtypes = dict()
# return data related to auto subscription based on subtype matching (aka:
# return data related to auto subscription based on subtype matching (aka:
# default task subtypes or subtypes from project triggering task subtypes)
updated_relation = dict()
child_ids, def_ids, all_int_ids, parent, relation = self.env['mail.message.subtype']._get_auto_subscription_subtypes(self._name)
@@ -17,5 +17,5 @@ class Lead(models.Model):
def action_redirect_to_livechat_sessions(self):
visitors = self.visitor_ids
action = self.env["ir.actions.actions"]._for_xml_id("website_livechat.website_visitor_livechat_session_action")
action['domain'] = [('livechat_visitor_id', 'in', visitors.ids), ('message_ids', '!=', False)]
action['domain'] = [('livechat_visitor_id', 'in', visitors.ids), ('has_message', '=', True)]
return action
+1 -1
View File
@@ -41,7 +41,7 @@ class Website(models.Model):
('livechat_visitor_id', '=', visitor.id),
('livechat_channel_id', '=', self.channel_id.id),
('livechat_active', '=', True),
('message_ids', '!=', False)
('has_message', '=', True)
], order='create_date desc', limit=1)
if chat_request_channel:
return {
@@ -5,7 +5,7 @@
<field name="res_model">mail.channel</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="im_livechat.mail_channel_view_tree"/>
<field name="domain">[('livechat_visitor_id', '=', active_id), ('message_ids', '!=', False)]</field>
<field name="domain">[('livechat_visitor_id', '=', active_id), ('has_message', '=', True)]</field>
<field name="context">{
'search_default_livechat_visitor_id': [active_id],
'default_livechat_visitor_id': active_id,