From 9a01a2953fa8e8c257568cdcf03f177bf79db35a Mon Sep 17 00:00:00 2001 From: Nicolas Seinlet Date: Wed, 5 May 2021 08:34:49 +0000 Subject: [PATCH] [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) --- .../im_livechat/models/im_livechat_channel.py | 2 +- .../im_livechat/views/mail_channel_views.xml | 2 +- addons/mail/models/mail_thread.py | 30 +++++++++++++++---- .../website_crm_livechat/models/crm_lead.py | 2 +- addons/website_livechat/models/website.py | 2 +- .../views/website_visitor_views.xml | 2 +- 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/addons/im_livechat/models/im_livechat_channel.py b/addons/im_livechat/models/im_livechat_channel.py index 4119b0d7652..dafc9040423 100644 --- a/addons/im_livechat/models/im_livechat_channel.py +++ b/addons/im_livechat/models/im_livechat_channel.py @@ -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) diff --git a/addons/im_livechat/views/mail_channel_views.xml b/addons/im_livechat/views/mail_channel_views.xml index b3245a8e270..a17845c4533 100644 --- a/addons/im_livechat/views/mail_channel_views.xml +++ b/addons/im_livechat/views/mail_channel_views.xml @@ -129,7 +129,7 @@ Sessions mail.channel tree,form - [('livechat_channel_id', 'in', [active_id]), ('message_ids', '!=', False)] + [('livechat_channel_id', 'in', [active_id]), ('has_message', '=', True)] { 'search_default_livechat_channel_id': [active_id], 'default_livechat_channel_id': active_id, diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 19271082b7d..7f7276b6b23 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -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) diff --git a/addons/website_crm_livechat/models/crm_lead.py b/addons/website_crm_livechat/models/crm_lead.py index 9751c5bdb97..f218ab087a6 100644 --- a/addons/website_crm_livechat/models/crm_lead.py +++ b/addons/website_crm_livechat/models/crm_lead.py @@ -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 diff --git a/addons/website_livechat/models/website.py b/addons/website_livechat/models/website.py index 95874357ecb..6bfe620a094 100644 --- a/addons/website_livechat/models/website.py +++ b/addons/website_livechat/models/website.py @@ -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 { diff --git a/addons/website_livechat/views/website_visitor_views.xml b/addons/website_livechat/views/website_visitor_views.xml index 1787d1fdd21..d22b55decfa 100644 --- a/addons/website_livechat/views/website_visitor_views.xml +++ b/addons/website_livechat/views/website_visitor_views.xml @@ -5,7 +5,7 @@ mail.channel tree,form - [('livechat_visitor_id', '=', active_id), ('message_ids', '!=', False)] + [('livechat_visitor_id', '=', active_id), ('has_message', '=', True)] { 'search_default_livechat_visitor_id': [active_id], 'default_livechat_visitor_id': active_id,