From 516f22c398758dbcc1241919a023b095b26a6a7a Mon Sep 17 00:00:00 2001
From: Nans Lefebvre <len@odoo.com>
Date: Wed, 15 May 2019 09:31:43 +0000
Subject: [PATCH] [FIX] mail: remove previous attachments when changing
 template

Open a mail.compose.message wizard.
Select a template that generates an attachment.
Reselect it. A second attachment has been generated.
Can be repeated ad infinitum.

At template onchange, the template is rendered to overwrite the composers values
This includes the attachments.
Let L1 be the list of attachments generated by the template.
When _convert_to_write(values) is called with {'attachment_ids': L1},
it gets self.attachments_ids = L2, and generates a [(6, 0, L1 + L2)] command.
As a result attachments are only added,
the previous ones need to be removed manually.

Since c6d718f, the semantics of _convert_to_write changed.
Before, it always returned an empty list for new records (without an id).
In other words, wa always had L2 == [].
As a result we need to adapt the wizard to keep its old behaviour.

To solve it we bypass the _convert_to_write for 'attachment_ids' and directly
generate the 6 command with the list of ids L1 generated by the template.
We only do this for templates that add attachments to keep the templates
composable (a template only overwrites the values it defines).
Unfortunately, we don't have any way to know which attachments have been added
manually, so we can't preserve these (which was the old behaviour anyway).

opw 1997430
opw 1987169
opw 1998115
opw 1998782

closes odoo/odoo#33387

Signed-off-by: Nans Lefebvre (len) <len@odoo.com>
---
 addons/mail/wizard/mail_compose_message.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index d0903fd2d407..f6a48dcd4b07 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -350,6 +350,7 @@ class MailComposer(models.TransientModel):
             - normal mode: return rendered values
             /!\ for x2many field, this onchange return command instead of ids
         """
+        attachment_ids = []
         if template_id and composition_mode == 'mass_mail':
             template = self.env['mail.template'].browse(template_id)
             fields = ['subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id']
@@ -375,7 +376,7 @@ class MailComposer(models.TransientModel):
                     'res_id': 0,
                     'type': 'binary',  # override default_type from context, possibly meant for another model!
                 }
-                values.setdefault('attachment_ids', list()).append(Attachment.create(data_attach).id)
+                attachment_ids.append(Attachment.create(data_attach).id)
         else:
             default_values = self.with_context(default_composition_mode=composition_mode, default_model=model, default_res_id=res_id).default_get(['composition_mode', 'model', 'res_id', 'parent_id', 'partner_ids', 'subject', 'body', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'])
             values = dict((key, default_values[key]) for key in ['subject', 'body', 'partner_ids', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'] if key in default_values)
@@ -388,6 +389,8 @@ class MailComposer(models.TransientModel):
         # this force the complete replacement of x2many field with
         # command and is compatible with onchange api.v7
         values = self._convert_to_write(values)
+        if attachment_ids:
+            values.update(attachment_ids=[(6, 0, attachment_ids)])
 
         return {'value': values}
 
-- 
GitLab