[FIX] account_edi: Add missing 'extra_domain' + Fix tests l10n_be_edi

- allow to match a partner having 'BE0477472701' as vat but '477472701' inside the xml.
- code cleanup as suggested in the original PR

Introduced by https://github.com/odoo/odoo/pull/80266

closes odoo/odoo#81237

X-original-commit: 598bfedb540aa81676b957340255aafef85d2823
Signed-off-by: Olivier Colson <oco@odoo.com>
Signed-off-by: Laurent Smet <las@odoo.com>
This commit is contained in:
Laurent Smet
2021-12-10 15:28:57 +00:00
parent e80af1ce11
commit ed75307baf
3 changed files with 109 additions and 13 deletions
+87 -13
View File
@@ -455,21 +455,95 @@ class AccountEdiFormat(models.Model):
:param vat: The vat number of the partner.
:returns: A partner or an empty recordset if not found.
'''
domains = []
for value, dom in (
(name, [('name', 'ilike', name)]),
(phone, expression.OR([[('phone', '=', phone)], [('mobile', '=', phone)]])),
(mail, [('email', '=', mail)]),
(vat, [('vat', 'like', vat)]),
):
if value is not None:
domains.append(dom)
def search_with_vat(extra_domain):
if not vat:
return None
if domain:
domains.append(domain)
# Sometimes, the vat is specified with some whitespaces.
normalized_vat = vat.replace(' ', '')
country_prefix = None
domain = expression.OR(domains)
return self.env['res.partner'].search(domain, limit=1)
partner = self.env['res.partner'].search(extra_domain + [('vat', '=', normalized_vat)], limit=1)
# Try to remove the country code prefix from the vat.
if not partner and len(normalized_vat) > 2 and normalized_vat[:2].isalpha():
country_prefix = normalized_vat[:2]
normalized_vat = normalized_vat[2:]
partner = self.env['res.partner'].search(extra_domain + [
('vat', '=', normalized_vat),
('country_id.code', '=', country_prefix.lower()),
], limit=1)
# The country could be not specified on the partner.
if not partner:
partner = self.env['res.partner'].search(extra_domain + [
('vat', '=', normalized_vat),
('country_id', '=', False),
], limit=1)
# The vat could be a string of alphanumeric values without country code but with missing zeros at the
# beginning.
if not partner:
try:
vat_only_numeric = str(int(normalized_vat))
except ValueError:
vat_only_numeric = None
if vat_only_numeric:
query = self.env['res.partner']._where_calc(extra_domain + [('active', '=', True)])
tables, where_clause, where_params = query.get_sql()
if country_prefix:
vat_prefix_regex = f'({country_prefix})?'
else:
vat_prefix_regex = '([A-z]{2})?'
self._cr.execute(f'''
SELECT res_partner.id
FROM {tables}
WHERE {where_clause}
AND res_partner.vat ~ %s
LIMIT 1
''', where_params + ['^%s0*%s$' % (vat_prefix_regex, vat_only_numeric)])
partner_row = self._cr.fetchone()
if partner_row:
partner = self.env['res.partner'].browse(partner_row[0])
return partner
def search_with_phone_mail(extra_domain):
domains = []
if phone:
domains.append([('phone', '=', phone)])
domains.append([('mobile', '=', phone)])
if mail:
domains.append([('email', '=', mail)])
if not domains:
return None
domain = expression.OR(domains)
if extra_domain:
domain = expression.AND([domain, extra_domain])
return self.env['res.partner'].search(domain, limit=1)
def search_with_name(extra_domain):
if not name:
return None
return self.env['res.partner'].search([('name', 'ilike', name)] + extra_domain, limit=1)
def search_with_domain(extra_domain):
if not domain:
return None
return self.env['res.partner'].search(domain + extra_domain, limit=1)
for search_method in (search_with_vat, search_with_domain, search_with_phone_mail, search_with_name):
for extra_domain in ([('company_id', '=', self.env.company.id)], []):
partner = search_method(extra_domain)
if partner:
return partner
return self.env['res.partner']
def _retrieve_product(self, name=None, default_code=None, barcode=None):
'''Search all products and find one that matches one of the parameters.
+1
View File
@@ -3,3 +3,4 @@
from . import common
from . import test_edi
from . import test_import_vendor_bill
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestImportVendorBill(AccountTestInvoicingCommon):
def test_retrieve_partner(self):
def retrieve_partner(vat, import_vat):
self.partner_a.with_context(no_vat_validation=True).vat = vat
self.partner_a.flush()
return self.env['account.edi.format']._retrieve_partner(vat=import_vat)
self.assertEqual(self.partner_a, retrieve_partner('BE0477472701', 'BE0477472701'))
self.assertEqual(self.partner_a, retrieve_partner('BE0477472701', '0477472701'))
self.assertEqual(self.partner_a, retrieve_partner('BE0477472701', '477472701'))
self.assertEqual(self.partner_a, retrieve_partner('0477472701', 'BE0477472701'))
self.assertEqual(self.partner_a, retrieve_partner('477472701', 'BE0477472701'))
self.assertEqual(self.env['res.partner'], retrieve_partner('DE0477472701', 'BE0477472701'))