From 33d7ea6fb8198f741cc13765b2f60c820f54ae66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 19 Aug 2022 12:34:20 +0000 Subject: [PATCH] [PRF] mail: improve performance of closing activities MailActivity model has an ``_action_done`` method that is quite heavily used and overridden. It notably posts messages, create next activities but also has some specific behavior depending on category. Purpose of this commit is to improve code of this method to avoid useless queries, improve performance, and rethink the computation with batch in mind. Task-2883589 (Activity performance and cleaning) Part-of: odoo/odoo#93682 --- addons/calendar/models/mail_activity.py | 6 +-- addons/mail/models/mail_activity.py | 66 +++++++++++++------------ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/addons/calendar/models/mail_activity.py b/addons/calendar/models/mail_activity.py index 4ceed29cc11..cd921cda669 100644 --- a/addons/calendar/models/mail_activity.py +++ b/addons/calendar/models/mail_activity.py @@ -24,17 +24,15 @@ class MailActivity(models.Model): return action def _action_done(self, feedback=False, attachment_ids=False): - events = self.mapped('calendar_event_id') - messages, activities = super(MailActivity, self)._action_done(feedback=feedback, attachment_ids=attachment_ids) if feedback: - for event in events: + for event in self.calendar_event_id: description = event.description description = '%s
%s' % ( description if not tools.is_html_empty(description) else '', _('Feedback: %(feedback)s', feedback=tools.plaintext2html(feedback)) if feedback else '', ) event.write({'description': description}) - return messages, activities + return super(MailActivity, self)._action_done(feedback=feedback, attachment_ids=attachment_ids) def unlink_w_meeting(self): events = self.mapped('calendar_event_id') diff --git a/addons/mail/models/mail_activity.py b/addons/mail/models/mail_activity.py index d0488b30088..f5904c772a3 100644 --- a/addons/mail/models/mail_activity.py +++ b/addons/mail/models/mail_activity.py @@ -557,40 +557,44 @@ class MailActivity(models.Model): activity_id = attachment['res_id'] activity_attachments[activity_id].append(attachment['id']) - for activity in self: - # extract value to generate next activities - if activity.chaining_type == 'trigger': - vals = activity.with_context(activity_previous_deadline=activity.date_deadline)._prepare_next_activity_values() - next_activities_values.append(vals) + for model, activity_data in self._classify_by_model().items(): + records = self.env[model].browse(activity_data['record_ids']) + for record, activity in zip(records, activity_data['activities']): + # extract value to generate next activities + if activity.chaining_type == 'trigger': + vals = activity.with_context(activity_previous_deadline=activity.date_deadline)._prepare_next_activity_values() + next_activities_values.append(vals) - # post message on activity, before deleting it - record = self.env[activity.res_model].browse(activity.res_id) - record.message_post_with_view( - 'mail.message_activity_done', - values={ - 'activity': activity, - 'feedback': feedback, - 'display_assignee': activity.user_id != self.env.user - }, - subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_activities'), - mail_activity_type_id=activity.activity_type_id.id, - attachment_ids=[Command.link(attachment_id) for attachment_id in attachment_ids] if attachment_ids else [], - ) + # post message on activity, before deleting it + _, activity_message = record.message_post_with_view( + 'mail.message_activity_done', + values={ + 'activity': activity, + 'feedback': feedback, + 'display_assignee': activity.user_id != self.env.user + }, + subtype_id=self.env['ir.model.data']._xmlid_to_res_id('mail.mt_activities'), + mail_activity_type_id=activity.activity_type_id.id, + attachment_ids=[Command.link(attachment_id) for attachment_id in attachment_ids] if attachment_ids else [], + ) - # Moving the attachments in the message - # TODO: Fix void res_id on attachment when you create an activity with an image - # directly, see route /web_editor/attachment/add - activity_message = record.message_ids[0] - message_attachments = self.env['ir.attachment'].browse(activity_attachments[activity.id]) - if message_attachments: - message_attachments.write({ - 'res_id': activity_message.id, - 'res_model': activity_message._name, - }) - activity_message.attachment_ids = message_attachments - messages += activity_message + # Moving the attachments in the message + # TODO: Fix void res_id on attachment when you create an activity with an image + # directly, see route /web_editor/attachment/add + if activity_attachments[activity.id]: + message_attachments = self.env['ir.attachment'].browse(activity_attachments[activity.id]) + if message_attachments: + message_attachments.write({ + 'res_id': activity_message.id, + 'res_model': activity_message._name, + }) + activity_message.attachment_ids = message_attachments + messages += activity_message + + next_activities = self.env['mail.activity'] + if next_activities_values: + next_activities = self.env['mail.activity'].create(next_activities_values) - next_activities = self.env['mail.activity'].create(next_activities_values) self.unlink() # will unlink activity, dont access `self` after that return messages, next_activities