[IMP] account_edi_ubl_cii: handles UBL files with namespaces per line

Backporting: 1e24b151c6ad0023769b5a561690cb62bcda1d8a

When importing a UBL file, Odoo expects the UBL specific namespaces to
be in the root element of the file. This is not always the case as these
namespaces could exist in every element in the file. When a file is
formatted this way, Odoo cannot extract the necessary data from it
because it is missing the necessary namespaces. To cover this case we
use the lxml.etree.Element.find function instead, and pass in the UBL
specific namespaces to successfully extract the data.

task-3657563
opw-3839398

closes odoo/odoo#161959

X-original-commit: 2845db5966bae3d6f81b6007980053f4ecb00a03
Signed-off-by: Wala Gauthier (gawa) <gawa@odoo.com>
Signed-off-by: Julien Van Roy (juvr) <juvr@odoo.com>
This commit is contained in:
AllePilli
2024-04-17 06:41:22 +00:00
committed by Julien Van Roy
parent b278241a71
commit 529419957f
2 changed files with 16 additions and 7 deletions
@@ -118,9 +118,9 @@ class AccountEdiCommon(models.AbstractModel):
return UOM_TO_UNECE_CODE.get(xmlid[line.product_uom_id.id], 'C62')
return 'C62'
def _find_value(self, xpath, tree):
def _find_value(self, xpath, tree, nsmap=False):
# avoid 'TypeError: empty namespace prefix is not supported in XPath'
nsmap = {k: v for k, v in tree.nsmap.items() if k is not None}
nsmap = nsmap or {k: v for k, v in tree.nsmap.items() if k is not None}
return find_xml_value(xpath, tree, nsmap)
# -------------------------------------------------------------------------
@@ -5,12 +5,21 @@ from lxml import etree
from odoo import models, _
from odoo.tools import html2plaintext, cleanup_xml_node
UBL_NAMESPACES = {
'cbc': "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
'cac': "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
}
class AccountEdiXmlUBL20(models.AbstractModel):
_name = "account.edi.xml.ubl_20"
_inherit = 'account.edi.common'
_description = "UBL 2.0"
def _find_value(self, xpath, tree, nsmap=False):
# EXTENDS account.edi.common
return super()._find_value(xpath, tree, UBL_NAMESPACES)
# -------------------------------------------------------------------------
# EXPORT
# -------------------------------------------------------------------------
@@ -600,11 +609,11 @@ class AccountEdiXmlUBL20(models.AbstractModel):
# ==== partner_id ====
role = "Customer" if invoice.journal_id.type == 'sale' else "Supplier"
vat = self._find_value(f'//cac:Accounting{role}Party/cac:Party//cbc:CompanyID[string-length(text()) > 5]', tree)
phone = self._find_value(f'//cac:Accounting{role}Party/cac:Party//cbc:Telephone', tree)
mail = self._find_value(f'//cac:Accounting{role}Party/cac:Party//cbc:ElectronicMail', tree)
name = self._find_value(f'//cac:Accounting{role}Party/cac:Party//cbc:Name', tree)
country_code = self._find_value(f'//cac:Accounting{role}Party/cac:Party//cac:Country//cbc:IdentificationCode', tree)
vat = self._find_value(f'.//cac:Accounting{role}Party/cac:Party//cbc:CompanyID[string-length(text()) > 5]', tree)
phone = self._find_value(f'.//cac:Accounting{role}Party/cac:Party//cbc:Telephone', tree)
mail = self._find_value(f'.//cac:Accounting{role}Party/cac:Party//cbc:ElectronicMail', tree)
name = self._find_value(f'.//cac:Accounting{role}Party/cac:Party//cbc:Name', tree)
country_code = self._find_value(f'.//cac:Accounting{role}Party/cac:Party//cac:Country//cbc:IdentificationCode', tree)
self._import_retrieve_and_fill_partner(invoice, name=name, phone=phone, mail=mail, vat=vat, country_code=country_code)
# ==== currency_id ====