From 0ea4c3110a76d2b7f46aa1fd6b7976624dbb07d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 15 Sep 2022 11:58:09 +0000 Subject: [PATCH] [MOV] account, mail: properly locate attachments management on model PURPOSE Purpose of this task is to cleanup attachment management done in generic mail models overrides and move it in account as model overrides. SPECIFICATIONS Accounting holds code to handle attachments linked to their custom composer (``account.invoice.send``) that uses through inheritance the mail composer (``mail.compose.message``) that has a specific processing of attachments to link pending composer attachments to the right records. Indeed attachments linked to the composer are pending attachments, and are linked to the record when posting the message. This allows to know which attachments have been added by the user, have specific rules for access rights, ... However this code has been wrongly added directly at mixing level at odoo/odoo@bdcc0120048c38971ed723e12bccd0defca806c6. Instead ``_message_post_process_attachments`` method should always be called based on a record, allowing to locate the override at model level. Task-2792146 (Mail: Move model-dependent code from composer / template) Task-2710804 (Mail: Clean MailThread API) Part-of: odoo/odoo#106658 --- addons/account/models/__init__.py | 1 - addons/account/models/account_move.py | 18 +++++++++++++ addons/account/models/mail_thread.py | 30 ---------------------- addons/mail/wizard/mail_compose_message.py | 2 +- addons/mail_group/models/mail_group.py | 9 ++++--- addons/portal/controllers/mail.py | 15 ++++++----- 6 files changed, 33 insertions(+), 42 deletions(-) delete mode 100644 addons/account/models/mail_thread.py diff --git a/addons/account/models/__init__.py b/addons/account/models/__init__.py index 8b2f00c0176..7138d530511 100644 --- a/addons/account/models/__init__.py +++ b/addons/account/models/__init__.py @@ -33,5 +33,4 @@ from . import digest from . import res_users from . import ir_actions_report from . import res_currency -from . import mail_thread from . import account_report diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index 8d753ff75bc..8791cf0192d 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -3998,6 +3998,24 @@ class AccountMove(models.Model): render_context['subtitles'] = subtitles return render_context + def _message_post_process_attachments(self, attachments, attachment_ids, message_values): + """ This method extension ensures that, when using the "Send & Print" feature + if the user adds an attachment, the latter will be linked to the record. """ + self.ensure_one() + message_values['model'] = self._name + message_values['res_id'] = self.id + + if attachment_ids: + # taking advantage of cache looks better in this case, to check + filtered_attachment_ids = self.env['ir.attachment'].sudo().browse(attachment_ids).filtered( + lambda a: a.res_model == 'account.invoice.send' and a.create_uid.id == self._uid) + # link account.invoice.send attachments to mail.compose.message, so that it is then + # updated with respect to access rights records in base method + if filtered_attachment_ids: + filtered_attachment_ids.res_model = 'mail.compose.message' + + return super()._message_post_process_attachments(attachments, attachment_ids, message_values) + # ------------------------------------------------------------------------- # HOOKS # ------------------------------------------------------------------------- diff --git a/addons/account/models/mail_thread.py b/addons/account/models/mail_thread.py deleted file mode 100644 index 81ac0162bd8..00000000000 --- a/addons/account/models/mail_thread.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import models - -class MailThread(models.AbstractModel): - _inherit = 'mail.thread' - - def _message_post_process_attachments(self, attachments, attachment_ids, message_values): - """ This method extension ensures that, when using the "Send & Print" feature, if the user - adds an attachment, the latter will be linked to the record. - - # Task-2792146: will move to model-based method - """ - record = self.env.context.get('attached_to') - # link mail.compose.message attachments to attached_to - if record and record._name == 'account.move': - message_values['model'] = record._name - message_values['res_id'] = record.id - res = super()._message_post_process_attachments(attachments, attachment_ids, message_values) - # link account.invoice.send attachments to attached_to - model = message_values['model'] - res_id = message_values['res_id'] - att_ids = [att[1] for att in res.get('attachment_ids') or []] - if att_ids and model == 'account.move': - filtered_attachment_ids = self.env['ir.attachment'].sudo().browse(att_ids).filtered( - lambda a: a.res_model in ('account.invoice.send',) and a.create_uid.id == self._uid) - if filtered_attachment_ids: - filtered_attachment_ids.write({'res_model': model, 'res_id': res_id}) - return res diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 8b69f6a0f36..b3e82dfd4c4 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -433,7 +433,7 @@ class MailComposer(models.TransientModel): new_attach_id = self.env['ir.attachment'].browse(attach_id).copy({'res_model': self._name, 'res_id': self.id}) attachment_ids.append(new_attach_id.id) attachment_ids.reverse() - mail_values['attachment_ids'] = self.env['mail.thread'].with_context(attached_to=record)._message_post_process_attachments( + mail_values['attachment_ids'] = record._message_post_process_attachments( mail_values.pop('attachments', []), attachment_ids, {'model': 'mail.message', 'res_id': 0} diff --git a/addons/mail_group/models/mail_group.py b/addons/mail_group/models/mail_group.py index eb38c47b675..3a92f0ea377 100644 --- a/addons/mail_group/models/mail_group.py +++ b/addons/mail_group/models/mail_group.py @@ -306,10 +306,11 @@ class MailGroup(models.Model): if not values.get('message_id'): values['message_id'] = generate_tracking_message_id('%s-mail.group' % self.id) - attachments = kwargs.get('attachments') or [] - attachment_ids = kwargs.get('attachment_ids') or [] - attachement_values = Mailthread._message_post_process_attachments(attachments, attachment_ids, values) - values.update(attachement_values) + values.update(Mailthread._message_post_process_attachments( + kwargs.get('attachments') or [], + kwargs.get('attachment_ids') or [], + values + )) mail_message = Mailthread._message_create(values) diff --git a/addons/portal/controllers/mail.py b/addons/portal/controllers/mail.py index c11b12f7b0e..ad64aa6d629 100644 --- a/addons/portal/controllers/mail.py +++ b/addons/portal/controllers/mail.py @@ -153,12 +153,15 @@ class PortalChatter(http.Controller): result.update({'default_message_id': message.id}) if attachment_ids: - # sudo write the attachment to bypass the read access - # verification in mail message - record = request.env[res_model].browse(res_id) - message_values = {'res_id': res_id, 'model': res_model} - attachments = record._message_post_process_attachments([], attachment_ids, message_values) - + # _message_post_helper already checks for pid/hash/token -> use message + # environment to keep the sudo mode when activated + record = message.env[res_model].browse(res_id) + attachments = record._message_post_process_attachments( + [], attachment_ids, + {'res_id': res_id, 'model': res_model} + ) + # sudo write the attachment to bypass the read access verification in + # mail message if attachments.get('attachment_ids'): message.sudo().write(attachments)