From 41ca7536e02093211b65342afd3fb44ed25c1c09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Nov 2013 10:56:32 +0100 Subject: [PATCH 1/6] [FIX] mail: when performing pure email mass mailing attachments were not formatted as a m2m command but a list of ids. This is now fixed. bzr revid: tde@openerp.com-20131126095632-txuy00xc1cmqjqcn --- addons/mail/wizard/mail_compose_message.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index f129e5bf0f9..7c63dbd23fa 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -260,6 +260,10 @@ 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']] self.pool.get('mail.mail').create(cr, uid, mail_values, context=context) else: subtype = 'mail.mt_comment' From 6f322004cc4c5ea886231fb18c17cc9310802f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Nov 2013 12:07:42 +0100 Subject: [PATCH 2/6] [FIX] email_template: when generating reports in batch, update the values for all res_ids, not only the last one of the current template. bzr revid: tde@openerp.com-20131126110742-aecac7r0zyappo0a --- addons/email_template/email_template.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index efa1387435a..ab95613c283 100644 --- a/addons/email_template/email_template.py +++ b/addons/email_template/email_template.py @@ -369,7 +369,7 @@ class email_template(osv.osv): attachment_ids=[attach.id for attach in template.attachment_ids], ) - # Add report in attachments + # Add report in attachments: generate once for all template_res_ids if template.report_template: for res_id in template_res_ids: attachments = [] @@ -388,7 +388,8 @@ class email_template(osv.osv): report_name += ext attachments.append((report_name, result)) - values['attachments'] = attachments + for res_id in template_res_ids: + results[res_id]['attachments'] = attachments return results 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 3/6] [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' From 974675bcbf3235b48fbe8c98267677f4929003d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Nov 2013 13:03:36 +0100 Subject: [PATCH 4/6] [FIX] mail: attachments encoding issue: posting process waits not encoded attachments: email_template encodes them. So de-encoding is necessary. bzr revid: tde@openerp.com-20131126120336-5lcp9ii7z9lru5vr --- addons/mail/wizard/mail_compose_message.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index f9e3ff52f28..d7d5ae9bae1 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -19,6 +19,7 @@ # ############################################################################## +import base64 import re from openerp import tools @@ -261,7 +262,6 @@ class mail_compose_message(osv.TransientModel): for res_id, mail_values in all_mail_values.iteritems(): if mass_mail_mode and not wizard.post: - # 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', []), @@ -306,7 +306,12 @@ class mail_compose_message(osv.TransientModel): if mass_mail_mode and wizard.model: email_dict = rendered_values[res_id] mail_values['partner_ids'] += email_dict.pop('partner_ids', []) - mail_values['attachments'] = email_dict.pop('attachments', []) + # process attachments and attachment_ids before sending values to mail_mail.create() + attachments = [] + if email_dict.get('attachments'): + for name, enc_cont in email_dict.pop('attachments'): + attachments.append((name, base64.b64decode(enc_cont))) + mail_values['attachments'] = attachments attachment_ids = [] for attach_id in mail_values.pop('attachment_ids'): new_attach_id = self.pool.get('ir.attachment').copy(cr, uid, attach_id, {'res_model': self._name, 'res_id': wizard.id}, context=context) From f2c23488c3a29416582cdcd9c2ec993025c20e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Nov 2013 13:08:43 +0100 Subject: [PATCH 5/6] [FIX] email_template: fixing to have the correct report suppose to correctly fix. So, fix the fix to fix it bzr revid: tde@openerp.com-20131126120843-gt8vdhl3yn61vd8r --- addons/email_template/email_template.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index ab95613c283..6e19b1eb8aa 100644 --- a/addons/email_template/email_template.py +++ b/addons/email_template/email_template.py @@ -387,9 +387,7 @@ class email_template(osv.osv): if not report_name.endswith(ext): report_name += ext attachments.append((report_name, result)) - - for res_id in template_res_ids: - results[res_id]['attachments'] = attachments + results[res_id]['attachments'] = attachments return results From 4468d522836bcb1f70311942ab9b7ba5de33dc69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Tue, 26 Nov 2013 13:16:49 +0100 Subject: [PATCH 6/6] [DOC] mail: cleaned a comment bzr revid: tde@openerp.com-20131126121649-nywrh4hc1mcpwleh --- addons/mail/wizard/mail_compose_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index d7d5ae9bae1..833811c07a1 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -306,7 +306,7 @@ class mail_compose_message(osv.TransientModel): if mass_mail_mode and wizard.model: email_dict = rendered_values[res_id] mail_values['partner_ids'] += email_dict.pop('partner_ids', []) - # process attachments and attachment_ids before sending values to mail_mail.create() + # process attachments: should not be encoded before being processed by message_post / mail_mail create attachments = [] if email_dict.get('attachments'): for name, enc_cont in email_dict.pop('attachments'):