[FIX] account_edi_ubl_cii: import customer when uploading an invoice
Previously, it was only possible to upload a bill, so the partner_id was read from the vendor in the imported file. Now, it is also possible to upload a file to create an invoice, so we need to be able to decode the customer in the imported file. opw-3072989 closes odoo/odoo#106942 X-original-commit: c52cde5405dcc5f3e48fea9b380a93d4a56467b5 Signed-off-by: Laurent Smet <las@odoo.com> Signed-off-by: Julien Van Roy <juvr@odoo.com>
This commit is contained in:
@@ -82,27 +82,23 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_common.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_cii_facturx.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py:0
|
||||
#, python-format
|
||||
msgid "Could not retrieve the %s."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_common.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_common.py:0
|
||||
#, python-format
|
||||
msgid "Could not retrieve the tax: %s %% for line '%s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_cii_facturx.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_common.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Could not retrieve the unit of measure for line with label '%s'. Did you "
|
||||
"install the inventory app and enabled the 'Units of Measure' option ?"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_cii_facturx.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py:0
|
||||
#, python-format
|
||||
msgid "Could not retrieve the vendor."
|
||||
msgid "Could not retrieve the unit of measure for line with label '%s'."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
@@ -380,6 +376,13 @@ msgid ""
|
||||
" code (BT-151)."
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_cii_facturx.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py:0
|
||||
#, python-format
|
||||
msgid "customer"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
#: model_terms:ir.ui.view,arch_db:account_edi_ubl_cii.account_invoice_pdfa_3_facturx_metadata
|
||||
msgid "external"
|
||||
@@ -409,3 +412,10 @@ msgstr ""
|
||||
#: model_terms:ir.ui.view,arch_db:account_edi_ubl_cii.account_invoice_pdfa_3_facturx_metadata
|
||||
msgid "urn:factur-x:pdfa:CrossIndustryDocument:invoice:1p0#"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_edi_ubl_cii
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_cii_facturx.py:0
|
||||
#: code:addons/account_edi_ubl_cii/models/account_edi_xml_ubl_20.py:0
|
||||
#, python-format
|
||||
msgid "vendor"
|
||||
msgstr ""
|
||||
|
||||
@@ -216,14 +216,14 @@ class AccountEdiXmlCII(models.AbstractModel):
|
||||
|
||||
# ==== partner_id ====
|
||||
|
||||
partner_type = invoice.journal_id.type == journal.type and 'SellerTradeParty' or 'BuyerTradeParty'
|
||||
partner_type = invoice.journal_id.type == 'purchase' and 'SellerTradeParty' or 'BuyerTradeParty'
|
||||
invoice.partner_id = self.env['account.edi.format']._retrieve_partner(
|
||||
name=_find_value(f"//ram:{partner_type}/ram:Name"),
|
||||
mail=_find_value(f"//ram:{partner_type}//ram:URIID[@schemeID='SMTP']"),
|
||||
vat=_find_value(f"//ram:{partner_type}/ram:SpecifiedTaxRegistration/ram:ID"),
|
||||
)
|
||||
if not invoice.partner_id:
|
||||
logs.append(_("Could not retrieve the vendor."))
|
||||
logs.append(_("Could not retrieve the %s.", _("customer") if invoice.is_sale_document() else _("vendor")))
|
||||
|
||||
# ==== currency_id ====
|
||||
|
||||
|
||||
@@ -465,12 +465,12 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
|
||||
partner = self._import_retrieve_info_from_map(
|
||||
tree,
|
||||
self._import_retrieve_partner_map(journal),
|
||||
self._import_retrieve_partner_map(self.env.company, journal.type),
|
||||
)
|
||||
if partner:
|
||||
invoice.partner_id = partner
|
||||
else:
|
||||
logs.append(_("Could not retrieve the vendor."))
|
||||
logs.append(_("Could not retrieve the %s.", _("customer") if invoice.is_sale_document() else _("vendor")))
|
||||
|
||||
# ==== currency_id ====
|
||||
|
||||
@@ -615,23 +615,24 @@ class AccountEdiXmlUBL20(models.AbstractModel):
|
||||
return 'refund', 1
|
||||
return None, None
|
||||
|
||||
def _import_retrieve_partner_map(self, company):
|
||||
def _import_retrieve_partner_map(self, company, move_type='purchase'):
|
||||
role = "Customer" if move_type == 'sale' else "Supplier"
|
||||
|
||||
def with_vat(tree, extra_domain):
|
||||
vat_node = tree.find('.//{*}AccountingSupplierParty/{*}Party//{*}CompanyID')
|
||||
vat_node = tree.find(f'.//{{*}}Accounting{role}Party/{{*}}Party//{{*}}CompanyID')
|
||||
vat = None if vat_node is None else vat_node.text
|
||||
return self.env['account.edi.format']._retrieve_partner_with_vat(vat, extra_domain)
|
||||
|
||||
def with_phone_mail(tree, extra_domain):
|
||||
phone_node = tree.find('.//{*}AccountingSupplierParty/{*}Party//{*}Telephone')
|
||||
mail_node = tree.find('.//{*}AccountingSupplierParty/{*}Party//{*}ElectronicMail')
|
||||
phone_node = tree.find(f'.//{{*}}Accounting{role}Party/{{*}}Party//{{*}}Telephone')
|
||||
mail_node = tree.find(f'.//{{*}}Accounting{role}Party/{{*}}Party//{{*}}ElectronicMail')
|
||||
|
||||
phone = None if phone_node is None else phone_node.text
|
||||
mail = None if mail_node is None else mail_node.text
|
||||
return self.env['account.edi.format']._retrieve_partner_with_phone_mail(phone, mail, extra_domain)
|
||||
|
||||
def with_name(tree, extra_domain):
|
||||
name_node = tree.find('.//{*}AccountingSupplierParty/{*}Party//{*}Name')
|
||||
name_node = tree.find(f'.//{{*}}Accounting{role}Party/{{*}}Party//{{*}}Name')
|
||||
name = None if name_node is None else name_node.text
|
||||
return self.env['account.edi.format']._retrieve_partner_with_name(name, extra_domain)
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class TestUBLCommon(AccountEdiTestCommon):
|
||||
def assert_same_invoice(self, invoice1, invoice2, **invoice_kwargs):
|
||||
self.assertEqual(len(invoice1.invoice_line_ids), len(invoice2.invoice_line_ids))
|
||||
self.assertRecordValues(invoice2, [{
|
||||
'partner_id': invoice1.company_id.partner_id.id,
|
||||
'partner_id': invoice1.partner_id.id,
|
||||
'invoice_date': fields.Date.from_string(invoice1.date),
|
||||
'currency_id': invoice1.currency_id.id,
|
||||
'amount_untaxed': invoice1.amount_untaxed,
|
||||
@@ -74,6 +74,7 @@ class TestUBLCommon(AccountEdiTestCommon):
|
||||
Create an account.move directly from an xml file, asserts the invoice obtained is the same as the expected
|
||||
invoice.
|
||||
"""
|
||||
# /!\ use the same journal as the invoice's one to import the attachment !
|
||||
invoice.journal_id.create_document_from_attachment(attachment.ids)
|
||||
new_invoice = self.env['account.move'].search([], order='id desc', limit=1)
|
||||
|
||||
@@ -194,6 +195,41 @@ class TestUBLCommon(AccountEdiTestCommon):
|
||||
|
||||
return attachment
|
||||
|
||||
def _test_import_partner(self, edi_code, filename):
|
||||
"""
|
||||
Given an invoice where partner_1 is the vendor and partner_2 is the customer with an EDI attachment.
|
||||
* Uploading the attachment as an invoice should create an invoice with the buyer = partner_2.
|
||||
* Uploading the attachment as a vendor bill should create a bill with the vendor = partner_1.
|
||||
"""
|
||||
invoice = self._generate_move(
|
||||
seller=self.partner_1,
|
||||
buyer=self.partner_2,
|
||||
move_type='out_invoice',
|
||||
invoice_line_ids=[{'product_id': self.product_a.id}],
|
||||
)
|
||||
edi_attachment = invoice.edi_document_ids.filtered(
|
||||
lambda doc: doc.edi_format_id.code == edi_code).attachment_id
|
||||
self.assertEqual(edi_attachment.name, filename)
|
||||
edi_etree = self.get_xml_tree_from_string(edi_attachment.raw)
|
||||
|
||||
# Import attachment as an invoice
|
||||
new_invoice = self.edi_format._create_invoice_from_xml_tree(
|
||||
filename='test_filename',
|
||||
tree=edi_etree,
|
||||
journal=self.env['account.journal'].search(
|
||||
[('type', '=', 'sale'), ('company_id', '=', self.env.company.id)], limit=1)
|
||||
)
|
||||
self.assertEqual(self.partner_2, new_invoice.partner_id)
|
||||
|
||||
# Import attachment as a vendor bill
|
||||
new_invoice = self.edi_format._create_invoice_from_xml_tree(
|
||||
filename='test_filename',
|
||||
tree=edi_etree,
|
||||
journal=self.env['account.journal'].search(
|
||||
[('type', '=', 'purchase'), ('company_id', '=', self.env.company.id)], limit=1)
|
||||
)
|
||||
self.assertEqual(self.partner_1, new_invoice.partner_id)
|
||||
|
||||
def _test_encoding_in_attachment(self, edi_code, filename):
|
||||
"""
|
||||
Generate an invoice, assert that the tag '<?xml version='1.0' encoding='UTF-8'?>' is present in the attachment
|
||||
|
||||
@@ -292,6 +292,9 @@ class TestCIIFR(TestUBLCommon):
|
||||
# Test import
|
||||
####################################################
|
||||
|
||||
def test_import_partner_facturx(self):
|
||||
self._test_import_partner('facturx_1_0_05', 'factur-x.xml')
|
||||
|
||||
def test_import_tax_included(self):
|
||||
"""
|
||||
Tests whether the tax included / tax excluded are correctly decoded when
|
||||
|
||||
@@ -220,6 +220,9 @@ class TestUBLBE(TestUBLCommon):
|
||||
# Test import
|
||||
####################################################
|
||||
|
||||
def test_import_partner_ubl(self):
|
||||
self._test_import_partner('ubl_bis3', 'INV_2017_00002_ubl_bis3.xml')
|
||||
|
||||
def test_import_export_invoice_xml(self):
|
||||
"""
|
||||
Test whether the elements only specific to ubl_be are correctly exported
|
||||
|
||||
Reference in New Issue
Block a user