From 92cebe3d782ab080ff0ab15b66da9e689e9483a2 Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Thu, 29 Feb 2024 19:05:05 +0000 Subject: [PATCH] [FIX] account: Do not select wrong partner sharing same name with another MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a single database, you could have two partners who are called John Doe. Before this commit, any statement line where the partner_name was set with 'John Doe' would return the last one being created, due to the _order attribute on res.partner model, even if the statement line was generated from a payment of the other 'John Doe' (ie first one created). With this commit, we ensure that the wrong partner is not selected, in case we cannot differentiate one from the other. closes odoo/odoo#157754 X-original-commit: 421a0ae53de8c947d68fb1c22066d4d73c1ce9b7 Related: odoo/enterprise#58699 Signed-off-by: Laurent Smet (las) Signed-off-by: William André (wan) --- addons/account/models/partner.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/addons/account/models/partner.py b/addons/account/models/partner.py index 76bfbefb84a..9ea6f902f7f 100644 --- a/addons/account/models/partner.py +++ b/addons/account/models/partner.py @@ -793,21 +793,21 @@ class ResPartner(models.Model): normalized_vat = vat.replace(' ', '') country_prefix = re.match('^[a-zA-Z]{2}|^', vat).group() - partner = self.env['res.partner'].search(extra_domain + [('vat', 'in', (normalized_vat, vat))], limit=1) + partner = self.env['res.partner'].search(extra_domain + [('vat', 'in', (normalized_vat, vat))], limit=2) # Try to remove the country code prefix from the vat. if not partner and country_prefix: partner = self.env['res.partner'].search(extra_domain + [ ('vat', 'in', (normalized_vat[2:], vat[2:])), ('country_id.code', '=', country_prefix.upper()), - ], limit=1) + ], limit=2) # The country could be not specified on the partner. if not partner: partner = self.env['res.partner'].search(extra_domain + [ ('vat', 'in', (normalized_vat[2:], vat[2:])), ('country_id', '=', False), - ], limit=1) + ], limit=2) # The vat could be a string of alphanumeric values without country code but with missing zeros at the # beginning. @@ -822,13 +822,13 @@ class ResPartner(models.Model): vat_prefix_regex = f'({country_prefix})?' else: vat_prefix_regex = '([A-z]{2})?' - query = self.env['res.partner']._search(extra_domain + [('active', '=', True)], limit=1) + query = self.env['res.partner']._search(extra_domain + [('active', '=', True)], limit=2) query.add_where("res_partner.vat ~ %s", ['^%s0*%s$' % (vat_prefix_regex, vat_only_numeric)]) query_str, params = query.select() self._cr.execute(query_str, params) - partner_row = self._cr.fetchone() - if partner_row: - partner = self.env['res.partner'].browse(partner_row[0]) + partner_rows = self._cr.fetchall() or [] + if len(partner_rows) == 1: + partner = self.env['res.partner'].browse(partner_rows[0][0]) return partner @@ -847,13 +847,13 @@ class ResPartner(models.Model): domain = expression.OR(domains) if extra_domain: domain = expression.AND([domain, extra_domain]) - return self.env['res.partner'].search(domain, limit=1) + return self.env['res.partner'].search(domain, limit=2) @api.model def _retrieve_partner_with_name(self, name, extra_domain): if not name: return None - return self.env['res.partner'].search([('name', 'ilike', name)] + extra_domain, limit=1) + return self.env['res.partner'].search([('name', 'ilike', name)] + extra_domain, limit=2) def _retrieve_partner(self, name=None, phone=None, mail=None, vat=None, domain=None, company=None): '''Search all partners and find one that matches one of the parameters. @@ -882,9 +882,9 @@ class ResPartner(models.Model): company = company or self.env.company for search_method in (search_with_vat, search_with_domain, search_with_phone_mail, search_with_name): - for extra_domain in (self.env['res.partner']._check_company_domain(company), []): + for extra_domain in ([*self.env['res.partner']._check_company_domain(company), ('company_id', '!=', False)], []): partner = search_method(extra_domain) - if partner: + if partner and len(partner) == 1: return partner return self.env['res.partner']