[FIX] mail: prioritize partners with matching company in email lookup
Versions -------- - 16.0+ Steps ----- 1. Have two companies with helpdesk teams; 2. create a contact associated with company 1; 3. create a contact associated with company 2 w/ the same email address; 4. from this address, send an email to team 2 to create a ticket. Issue ----- Ticket is created using company 1's contact. Cause ----- When searching for partners associated with an email address, it only looks at the first one. Solution -------- Expanding on e1d50a404516d5b32bf01508423c5a1c880cb304 which prioritized the current user, further prioritize based on companies matching the records passed to `_mail_find_partner_from_email`, avoiding potential access rights errors in multi-company environments. Also fixes a bug in account_move where `_mail_find_partner_from_email` was called with an `extra_domain` argument in the wrong position. opw-3705199 closes odoo/odoo#159108 X-original-commit: 60dd5348179c9bdcc78e4ad46bd9b768a6e3ea21 Signed-off-by: Levi Siuzdak <sile@odoo.com>
This commit is contained in:
@@ -4636,11 +4636,11 @@ class AccountMove(models.Model):
|
||||
|
||||
# Search for partners in copy.
|
||||
cc_mail_addresses = email_split(msg_dict.get('cc', ''))
|
||||
followers = [partner for partner in self._mail_find_partner_from_emails(cc_mail_addresses, extra_domain) if partner]
|
||||
followers = [partner for partner in self._mail_find_partner_from_emails(cc_mail_addresses, extra_domain=extra_domain) if partner]
|
||||
|
||||
# Search for partner that sent the mail.
|
||||
from_mail_addresses = email_split(msg_dict.get('from', ''))
|
||||
senders = partners = [partner for partner in self._mail_find_partner_from_emails(from_mail_addresses, extra_domain) if partner]
|
||||
senders = partners = [partner for partner in self._mail_find_partner_from_emails(from_mail_addresses, extra_domain=extra_domain) if partner]
|
||||
|
||||
# Search for partners using the user.
|
||||
if not senders:
|
||||
@@ -4653,7 +4653,7 @@ class AccountMove(models.Model):
|
||||
body_mail_addresses = set(email_re.findall(msg_dict.get('body')))
|
||||
partners = [
|
||||
partner
|
||||
for partner in self._mail_find_partner_from_emails(body_mail_addresses, extra_domain)
|
||||
for partner in self._mail_find_partner_from_emails(body_mail_addresses, extra_domain=extra_domain)
|
||||
if not is_internal_partner(partner) and partner.company_id.id in (False, company.id)
|
||||
]
|
||||
# Little hack: Inject the mail's subject in the body.
|
||||
|
||||
@@ -1957,10 +1957,20 @@ class MailThread(models.AbstractModel):
|
||||
|
||||
partners = self._mail_search_on_partner(remaining, extra_domain=extra_domain)
|
||||
done_partners += [partner for partner in partners]
|
||||
remaining = [email for email in normalized_emails if email not in [partner.email_normalized for partner in done_partners]]
|
||||
|
||||
# prioritize current user if exists in list
|
||||
done_partners.sort(key=lambda p: self.env.user.partner_id != p)
|
||||
# prioritize current user if exists in list, and partners with matching company ids
|
||||
if company_fname := records and records._mail_get_company_field():
|
||||
def sort_key(p):
|
||||
return (
|
||||
self.env.user.partner_id == p, # prioritize user
|
||||
p.company_id in records[company_fname], # then partner associated w/ records
|
||||
not p.company_id, # else pick partner w/out company_id
|
||||
)
|
||||
else:
|
||||
def sort_key(p):
|
||||
return (self.env.user.partner_id == p, not p.company_id)
|
||||
|
||||
done_partners.sort(key=sort_key, reverse=True) # reverse because False < True
|
||||
|
||||
# iterate and keep ordering
|
||||
partners = []
|
||||
|
||||
@@ -151,6 +151,34 @@ class TestMailTools(MailCommon):
|
||||
found = self.env['res.partner']._mail_find_partner_from_emails([self.env.user.partner_id.email_formatted])
|
||||
self.assertEqual(found, [self.env.user.partner_id])
|
||||
|
||||
def test_mail_find_partner_from_emails_multicompany(self):
|
||||
""" Test _mail_find_partner_from_emails when dealing with records in
|
||||
a multicompany environment, returning a partner record with matching
|
||||
company_id. """
|
||||
Partner = self.env['res.partner']
|
||||
self.test_partner.company_id = self.company_2
|
||||
|
||||
test_partner_no_company = self.test_partner.copy({'company_id': False})
|
||||
test_partner_company_2 = self.test_partner
|
||||
test_partner_company_3 = test_partner_no_company.copy({'company_id': self.company_3.id})
|
||||
records = [
|
||||
None,
|
||||
*Partner.create([
|
||||
{'name': 'Company 2 contact', 'company_id': self.company_2.id},
|
||||
{'name': 'Company 3 contact', 'company_id': self.company_3.id},
|
||||
{'name': 'No restrictions', 'company_id': False},
|
||||
])
|
||||
]
|
||||
expected_partners = [
|
||||
(test_partner_no_company, "W/out reference record, prefer non-specific partner."),
|
||||
(test_partner_company_2, "Prefer same company as reference record."),
|
||||
(test_partner_company_3, "Prefer same company as reference record."),
|
||||
(test_partner_no_company, "Prefer non-specific partner for non-specific records."),
|
||||
]
|
||||
for record, (expected_partner, msg) in zip(records, expected_partners):
|
||||
found = Partner._mail_find_partner_from_emails([self._test_email], records=record)
|
||||
self.assertEqual(found, [expected_partner], msg)
|
||||
|
||||
|
||||
@tagged('mail_tools', 'mail_init')
|
||||
class TestMailUtils(MailCommon):
|
||||
|
||||
Reference in New Issue
Block a user