[FIX] account: fix single bill creation with PDF and XML from alias
Steps to reproduce: - Install Accounting - Configure an Email alias for Vendor Bills journal - Send an email to the alias with an PDF containing an embedded EDI XML and the EDI XML corresponding to the PDF as attachments Issue: - 2 bills are created (one with the PDF as attachment and one with the XML), instead of one with both PDF and XML as attachments - The PDF with the embedded XML is linked to the invoice created by the attached XML file and not the embedded one - The embedded XML is decoded before the attached XML file. Cause: The order in which the documents are decoded. opw-3604697 closes odoo/odoo#144243 Signed-off-by: Laurent Smet (las) <las@odoo.com>
This commit is contained in:
@@ -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']
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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", '<test></test>')
|
||||
embedded_files = self.env['ir.attachment']._decode_edi_xml(xml_filename, '<test></test>')
|
||||
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})
|
||||
|
||||
Reference in New Issue
Block a user