diff --git a/addons/email_template/email_template.py b/addons/email_template/email_template.py index efa1387435a..6e19b1eb8aa 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 = [] @@ -387,8 +387,7 @@ class email_template(osv.osv): if not report_name.endswith(ext): report_name += ext attachments.append((report_name, result)) - - values['attachments'] = attachments + results[res_id]['attachments'] = attachments return results diff --git a/addons/mail/mail_thread.py b/addons/mail/mail_thread.py index 865d92abe6d..85d8ffca264 100644 --- a/addons/mail/mail_thread.py +++ b/addons/mail/mail_thread.py @@ -1294,6 +1294,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): @@ -1372,28 +1406,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 f129e5bf0f9..833811c07a1 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -19,7 +19,9 @@ # ############################################################################## +import base64 import re + from openerp import tools from openerp import SUPERUSER_ID from openerp.osv import osv @@ -260,6 +262,12 @@ class mail_compose_message(osv.TransientModel): for res_id, mail_values in all_mail_values.iteritems(): if mass_mail_mode and not wizard.post: + 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' @@ -298,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: 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'): + 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)