[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@bdcc012004. 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
This commit is contained in:
Thibault Delavallée
2022-11-28 15:52:58 +01:00
parent f1bb452ce4
commit 0ea4c3110a
6 changed files with 33 additions and 42 deletions
-1
View File
@@ -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
+18
View File
@@ -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
# -------------------------------------------------------------------------
-30
View File
@@ -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
+1 -1
View File
@@ -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}
+5 -4
View File
@@ -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)
+9 -6
View File
@@ -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)