From cf214ed7244207f1fd5d377ab69d85a6441ff665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Nov 2013 12:09:42 +0100 Subject: [PATCH] [FIX] mail: when generating pure email mass mailing we have to process attachments as well as attachment_ids in the values generated by the composer and the optional template. As this behavior is the same as the one already implemented for message_post, this feature has been moved into its dedicated method to be called by message_post or before calling mail_mail.create(). This also allows to have attachments in pure email mass mailing that are attached to mail.message, not to mail.compose.message model. When unlinking those emails, the attachments will be also removed, and not lost in the database anymore. bzr revid: tde@openerp.com-20131126110942-h8p0d9sbjtk0hwlu --- addons/mail/mail_thread.py | 57 +++++++++++++--------- addons/mail/wizard/mail_compose_message.py | 12 +++-- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 33d7f81024f..5d81d9c98f5 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1287,6 +1287,40 @@ class mail_thread(osv.AbstractModel): mail_message_obj.write(cr, SUPERUSER_ID, message_ids, {'author_id': partner_info['partner_id']}, context=context) return result + def _message_preprocess_attachments(self, cr, uid, attachments, attachment_ids, attach_model, attach_res_id, context=None): + """ Preprocess attachments for mail_thread.message_post() or mail_mail.create(). + + :param list attachments: list of attachment tuples in the form ``(name,content)``, + where content is NOT base64 encoded + :param list attachment_ids: a list of attachment ids, not in tomany command form + :param str attach_model: the model of the attachments parent record + :param integer attach_res_id: the id of the attachments parent record + """ + Attachment = self.pool['ir.attachment'] + m2m_attachment_ids = [] + if attachment_ids: + filtered_attachment_ids = Attachment.search(cr, SUPERUSER_ID, [ + ('res_model', '=', 'mail.compose.message'), + ('create_uid', '=', uid), + ('id', 'in', attachment_ids)], context=context) + if filtered_attachment_ids: + Attachment.write(cr, SUPERUSER_ID, filtered_attachment_ids, {'res_model': attach_model, 'res_id': attach_res_id}, context=context) + m2m_attachment_ids += [(4, id) for id in attachment_ids] + # Handle attachments parameter, that is a dictionary of attachments + for name, content in attachments: + if isinstance(content, unicode): + content = content.encode('utf-8') + data_attach = { + 'name': name, + 'datas': base64.b64encode(str(content)), + 'datas_fname': name, + 'description': name, + 'res_model': attach_model, + 'res_id': attach_res_id, + } + m2m_attachment_ids.append((0, 0, data_attach)) + return m2m_attachment_ids + def message_post(self, cr, uid, thread_id, body='', subject=None, type='notification', subtype=None, parent_id=False, attachments=None, context=None, content_subtype='html', **kwargs): @@ -1365,28 +1399,7 @@ class mail_thread(osv.AbstractModel): # 3. Attachments # - HACK TDE FIXME: Chatter: attachments linked to the document (not done JS-side), load the message - attachment_ids = kwargs.pop('attachment_ids', []) or [] # because we could receive None (some old code sends None) - if attachment_ids: - filtered_attachment_ids = ir_attachment.search(cr, SUPERUSER_ID, [ - ('res_model', '=', 'mail.compose.message'), - ('create_uid', '=', uid), - ('id', 'in', attachment_ids)], context=context) - if filtered_attachment_ids: - ir_attachment.write(cr, SUPERUSER_ID, filtered_attachment_ids, {'res_model': model, 'res_id': thread_id}, context=context) - attachment_ids = [(4, id) for id in attachment_ids] - # Handle attachments parameter, that is a dictionary of attachments - for name, content in attachments: - if isinstance(content, unicode): - content = content.encode('utf-8') - data_attach = { - 'name': name, - 'datas': base64.b64encode(str(content)), - 'datas_fname': name, - 'description': name, - 'res_model': model, - 'res_id': thread_id, - } - attachment_ids.append((0, 0, data_attach)) + attachment_ids = self._message_preprocess_attachments(cr, uid, attachments, kwargs.pop('attachment_ids', []), model, thread_id, context) # 4: mail.message.subtype subtype_id = False diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index 7c63dbd23fa..f9e3ff52f28 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -20,6 +20,7 @@ ############################################################################## import re + from openerp import tools from openerp import SUPERUSER_ID from openerp.osv import osv @@ -260,10 +261,13 @@ class mail_compose_message(osv.TransientModel): for res_id, mail_values in all_mail_values.iteritems(): if mass_mail_mode and not wizard.post: - # Attachments are still formatted as a list of ids, because message_post will process them - # We have to put them back as a m2m command if we want attachments to be sent - if mail_values.get('attachment_ids'): - mail_values['attachment_ids'] = [(4, id) for id in mail_values['attachment_ids']] + # process attachments and attachment_ids before sending values to mail_mail.Lcreat + m2m_attachment_ids = self.pool['mail.thread']._message_preprocess_attachments( + cr, uid, mail_values.pop('attachments', []), + mail_values.pop('attachment_ids', []), + 'mail.message', 0, + context=context) + mail_values['attachment_ids'] = m2m_attachment_ids self.pool.get('mail.mail').create(cr, uid, mail_values, context=context) else: subtype = 'mail.mt_comment'