diff --git a/addons/account/tests/test_account_move_send.py b/addons/account/tests/test_account_move_send.py index 7b3f7493b0a..9174deb39c3 100644 --- a/addons/account/tests/test_account_move_send.py +++ b/addons/account/tests/test_account_move_send.py @@ -527,6 +527,15 @@ class TestAccountMoveSend(TestAccountMoveSendCommon): ]) self.assertEqual(len(invoice_attachments), 1) + # Only one PDF linked to the invoice. + invoice_attachments = self.env['ir.attachment'].search([ + ('name', '=', pdf_report.name), + ('res_model', '=', invoice._name), + ('res_id', '=', invoice.id), + ('res_field', '=', False), + ]) + self.assertFalse(invoice_attachments) + def test_invoice_multi(self): invoice1 = self.init_invoice("out_invoice", partner=self.partner_a, amounts=[1000], post=True) invoice2 = self.init_invoice("out_invoice", partner=self.partner_b, amounts=[1000], post=True) @@ -653,13 +662,20 @@ class TestAccountMoveSend(TestAccountMoveSendCommon): # Send. wizard.action_send_and_print() message = self._get_mail_message(invoice) - self.assertRecordValues(message, [{ - 'attachment_ids': [ - manual_attachment.id, - invoice.invoice_pdf_report_id.id, - extra_attachment2.id, - ], - }]) + self.assertRecordValues(message.attachment_ids.sorted('name'), [ + { + 'name': invoice.invoice_pdf_report_id.name, + 'datas': invoice.invoice_pdf_report_id.datas, + }, + { + 'name': extra_attachment2.name, + 'datas': extra_attachment2.datas, + }, + { + 'name': manual_attachment.name, + 'datas': manual_attachment.datas, + }, + ]) # Resend. wizard = self.create_send_and_print(invoice) @@ -679,12 +695,31 @@ class TestAccountMoveSend(TestAccountMoveSendCommon): # Send. wizard.action_send_and_print() message = self._get_mail_message(invoice) - self.assertRecordValues(message, [{ - 'attachment_ids': [ - invoice.invoice_pdf_report_id.id, - extra_attachment2.id, - ], - }]) + self.assertRecordValues(message.attachment_ids.sorted('name'), [ + { + 'name': invoice.invoice_pdf_report_id.name, + 'datas': invoice.invoice_pdf_report_id.datas, + }, + { + 'name': extra_attachment2.name, + 'datas': extra_attachment2.datas, + }, + ]) + + # Manually remove the attachment and check the mail's attachments are not removed. + invoice_pdf_report_name = invoice.invoice_pdf_report_id.name + invoice_pdf_report_datas = invoice.invoice_pdf_report_id.datas + invoice.invoice_pdf_report_id.unlink() + self.assertRecordValues(message.attachment_ids.sorted('name'), [ + { + 'name': invoice_pdf_report_name, + 'datas': invoice_pdf_report_datas, + }, + { + 'name': extra_attachment2.name, + 'datas': extra_attachment2.datas, + }, + ]) def test_proforma_pdf(self): invoice = self.init_invoice("out_invoice", amounts=[1000], post=True) diff --git a/addons/account/wizard/account_move_send.py b/addons/account/wizard/account_move_send.py index f980135edf6..cdfa66e9bf6 100644 --- a/addons/account/wizard/account_move_send.py +++ b/addons/account/wizard/account_move_send.py @@ -404,7 +404,7 @@ class AccountMoveSend(models.Model): partner_ids = kwargs.get('partner_ids', []) mail_template = self.mail_template_id - move\ + new_message = move\ .with_context( no_new_invoice=True, mail_notify_author=self.env.user.partner_id.id in partner_ids, @@ -421,6 +421,12 @@ class AccountMoveSend(models.Model): }, ) + # Prevent duplicated attachments linked to the invoice. + new_message.attachment_ids.write({ + 'res_model': new_message._name, + 'res_id': new_message.id, + }) + def _get_mail_params(self, move): self.ensure_one() @@ -429,17 +435,25 @@ class AccountMoveSend(models.Model): # We must ensure the newly created PDF are added. At this point, the PDF has been generated but not added # to 'mail_attachments_widget'. - attachment_ids = list(set([ - x['id'] - for x in self.mail_attachments_widget + self._get_invoice_extra_attachments_data(self.move_ids) - if not x.get('placeholder') - ])) + seen_attachment_ids = set() + for attachment_data in self._get_invoice_extra_attachments_data(self.move_ids) + self.mail_attachments_widget: + try: + attachment_id = int(attachment_data['id']) + except ValueError: + continue + + seen_attachment_ids.add(attachment_id) + + mail_attachments = [ + (attachment.name, attachment.raw) + for attachment in self.env['ir.attachment'].browse(list(seen_attachment_ids)) + ] return { 'body': self.mail_body, 'subject': self.mail_subject, 'partner_ids': self.mail_partner_ids.ids, - 'attachment_ids': attachment_ids, + 'attachments': mail_attachments, } def _send_mails(self, moves_data): @@ -454,7 +468,8 @@ class AccountMoveSend(models.Model): continue if move_data.get('proforma_pdf_attachment'): - mail_params['attachment_ids'].append(move_data['proforma_pdf_attachment'].id) + attachment = move_data['proforma_pdf_attachment'] + mail_params['attachments'].append((attachment.name, attachment.raw)) mail_lang = form.mail_lang email_from = form._get_mail_default_field_value_from_template(mail_template, mail_lang, move, 'email_from')