diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index d0a9d1d98cb..92685ed167a 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -3100,7 +3100,7 @@ class AccountMove(models.Model):
def add_file_data_results(file_data, invoice):
passed_file_data_list.append(file_data)
- attachment = file_data.get('attachment')
+ attachment = file_data.get('attachment') or file_data.get('originator_pdf')
if attachment:
if attachments_by_invoice[attachment]:
attachments_by_invoice[attachment] |= invoice
@@ -3123,8 +3123,8 @@ class AccountMove(models.Model):
close_file(file_data)
continue
- # When receiving an xml plus a pdf, since both are representing the same invoice, both needs
- # to be linked to the same invoice.
+ # When receiving multiple files, if they have a different type, we supposed they are all linked
+ # to the same invoice.
if (
passed_file_data_list
and passed_file_data_list[-1]['filename'] != file_data['filename']
diff --git a/addons/account/models/ir_attachment.py b/addons/account/models/ir_attachment.py
index bbb3fd50c14..8e1c43fa366 100644
--- a/addons/account/models/ir_attachment.py
+++ b/addons/account/models/ir_attachment.py
@@ -46,7 +46,6 @@ class IrAttachment(models.Model):
'attachment': self,
'filename': filename,
'content': content,
- 'attachment': self,
'xml_tree': xml_tree,
'sort_weight': 10,
'type': 'xml',
@@ -69,7 +68,11 @@ class IrAttachment(models.Model):
to_process = []
try:
for xml_name, xml_content in pdf_reader.getAttachments():
- to_process.extend(self.env['ir.attachment']._decode_edi_xml(xml_name, xml_content))
+ embedded_files = self.env['ir.attachment']._decode_edi_xml(xml_name, xml_content)
+ for file_data in embedded_files:
+ file_data['sort_weight'] += 1
+ file_data['originator_pdf'] = self
+ to_process.extend(embedded_files)
except (NotImplementedError, StructError, PdfReadError) as e:
_logger.warning("Unable to access the attachments of %s. Tried to decrypt it, but %s.", filename, e)
diff --git a/addons/account/tests/test_account_incoming_supplier_invoice.py b/addons/account/tests/test_account_incoming_supplier_invoice.py
index b417563680f..ba15f3f32ce 100644
--- a/addons/account/tests/test_account_incoming_supplier_invoice.py
+++ b/addons/account/tests/test_account_incoming_supplier_invoice.py
@@ -56,27 +56,41 @@ class TestAccountIncomingSupplierInvoice(AccountTestInvoicingCommon):
@contextmanager
def with_success_decoder(self, omit=None):
+ decoded_files = set()
+
def get_edi_decoder(_record, file_data, new=False):
- return lambda *args, **kwargs: not omit or file_data['attachment'].name not in omit
+
+ def decoder(*args, **kwargs):
+ return not omit or file_data['attachment'].name not in omit
+
+ if decoder():
+ decoded_files.add(file_data['filename'])
+ return decoder
with patch.object(type(self.env['account.move']), '_get_edi_decoder', get_edi_decoder):
- yield
+ yield decoded_files
@contextmanager
def with_simulated_embedded_xml(self, pdf):
super_decode_edi_pdf = type(self.env['ir.attachment'])._decode_edi_pdf
+ xml_filename = f"{pdf.name}_xml"
def decode_edi_pdf(record, filename, content):
results = super_decode_edi_pdf(record, filename, content)
if filename == pdf.name:
- results += pdf._decode_edi_xml(f"{pdf.name}_xml", '')
+ embedded_files = self.env['ir.attachment']._decode_edi_xml(xml_filename, '')
+ for file_data in embedded_files:
+ file_data['sort_weight'] += 1
+ file_data['originator_pdf'] = pdf
+ results += embedded_files
return results
with patch.object(type(self.env['ir.attachment']), '_decode_edi_pdf', decode_edi_pdf):
- yield
+ yield xml_filename
def _assert_extend_with_attachments(self, expected_values, new=False):
attachments = self.env['ir.attachment'].browse([x.id for x in expected_values])
+ nb_moves_before = self.env['account.move'].search_count([('company_id', '=', self.env.company.id)])
results = self.env['account.move']\
.with_context(default_move_type='out_invoice', default_journal_id=self.company_data['default_journal_sale'].id)\
._extend_with_attachments(attachments, new=new)
@@ -92,6 +106,9 @@ class TestAccountIncomingSupplierInvoice(AccountTestInvoicingCommon):
self.assertEqual(current_values, {k.name: v for k, v in expected_values.items()})
+ nb_moves_after = self.env['account.move'].search_count([('company_id', '=', self.env.company.id)])
+ self.assertEqual(nb_moves_before + invoice_number, nb_moves_after)
+
def test_supplier_invoice_mailed_from_supplier(self):
message_parsed = {
'message_id': 'message-id-dead-beef',
@@ -182,17 +199,42 @@ class TestAccountIncomingSupplierInvoice(AccountTestInvoicingCommon):
gif2 = self._create_dummy_gif_attachment()
xml1 = self._create_dummy_xml_attachment()
xml2 = self._create_dummy_xml_attachment()
- with self.with_success_decoder():
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({pdf1: 1, pdf2: 1}, new=False)
+ self.assertEqual(decoded_files, {pdf1.name})
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({pdf1: 1, pdf2: 2}, new=True)
+ self.assertEqual(decoded_files, {pdf1.name, pdf2.name})
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({pdf1: 1, pdf2: 1, gif1: 1, gif2: 1}, new=False)
+ self.assertEqual(decoded_files, {pdf1.name})
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({pdf1: 1, pdf2: 2, gif1: 3, gif2: 4}, new=True)
+ self.assertEqual(decoded_files, {pdf1.name, pdf2.name, gif1.name, gif2.name})
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({pdf1: 1, xml1: 1}, new=False)
+ self.assertEqual(decoded_files, {xml1.name})
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({pdf1: 1, xml1: 1}, new=True)
+ self.assertEqual(decoded_files, {xml1.name})
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({xml1: 1, xml2: 1}, new=False)
+ self.assertEqual(decoded_files, {xml1.name})
+ with self.with_success_decoder() as decoded_files:
self._assert_extend_with_attachments({xml1: 1, xml2: 2}, new=True)
- with self.with_success_decoder(omit={pdf1.name}):
+ self.assertEqual(decoded_files, {xml1.name, xml2.name})
+ with self.with_success_decoder(omit={pdf1.name}) as decoded_files:
self._assert_extend_with_attachments({pdf1: 1, pdf2: 2}, new=True)
- with self.with_success_decoder(), self.with_simulated_embedded_xml(pdf1):
+ self.assertEqual(decoded_files, {pdf2.name})
+ with self.with_success_decoder() as decoded_files, self.with_simulated_embedded_xml(pdf1) as xml_filename:
self._assert_extend_with_attachments({pdf1: 1, pdf2: 1}, new=False)
+ self.assertEqual(decoded_files, {xml_filename})
+ with self.with_success_decoder() as decoded_files, self.with_simulated_embedded_xml(pdf1) as xml_filename:
self._assert_extend_with_attachments({pdf1: 1, pdf2: 2}, new=True)
+ self.assertEqual(decoded_files, {xml_filename, pdf2.name})
+ with self.with_success_decoder() as decoded_files, self.with_simulated_embedded_xml(pdf1):
+ self._assert_extend_with_attachments({pdf1: 1, xml1: 1}, new=False)
+ self.assertEqual(decoded_files, {xml1.name})
+ with self.with_success_decoder() as decoded_files, self.with_simulated_embedded_xml(pdf1):
+ self._assert_extend_with_attachments({pdf1: 1, xml1: 1}, new=True)
+ self.assertEqual(decoded_files, {xml1.name})