19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:30:53 +01:00
parent dc68f80d3f
commit 7221b9ac46
610 changed files with 135477 additions and 161677 deletions

View file

@ -2,227 +2,226 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.crm.tests.common import TestCrmCommon
from odoo.addons.iap.tools import iap_tools
from odoo.tests.common import tagged, users
@tagged('lead_manage')
class TestLeadConvert(TestCrmCommon):
@tagged('lead_internals')
class TestCRMLead(TestCrmCommon):
@users('user_sales_manager')
def test_potential_duplicates(self):
company = self.env['res.partner'].create({
'name': 'My company',
'email': 'mycompany@company.com',
'is_company': True,
'street': '57th Street',
@classmethod
def setUpClass(cls):
super().setUpClass()
# To avoid magic phone sanitization
cls.env.company.country_id = cls.env.ref('base.us')
cls.emails_provider_generic = {
('robert.poilvert@gmail.com', 'robert.poilvert@gmail.com'),
('fp@odoo.com', 'fp@odoo.com'),
('fp.alias@mail.odoo.com', 'fp.alias@mail.odoo.com'),
}
cls.emails_provider_company = {
('robert.poilvert@mycompany.com', 'mycompany.com'),
('fp@subdomain.odoo.com', 'subdomain.odoo.com'),
}
# customer data
country_us_id = cls.env.ref('base.us').id
cls.test_company = cls.env['res.partner'].create({
'city': 'New New York',
'country_id': self.env.ref('base.us').id,
'country_id': country_us_id,
'email': 'test.company@another.email.company.com',
'is_company': True,
'name': 'My company',
'street': '57th Street',
'zip': '12345',
})
cls.test_partners = cls.env['res.partner'].create([
{
'city': 'New York',
'country_id': country_us_id,
'email': 'dave@another.email.company.com',
'is_company': False,
'name': 'Dave',
'phone': '+1 202 000 0123',
'parent_id': cls.test_company.id,
'street': 'Pearl street',
'zip': '12345',
},
{
'city': 'New York',
'country_id': country_us_id,
'email': 'eve@another.email.company.com',
'is_company': False,
'name': 'Eve',
'parent_id': cls.test_company.id,
'phone': '+1 202 000 3210',
'street': 'Wall street',
'zip': '12345',
}
])
partner_1 = self.env['res.partner'].create({
'name': 'Dave',
'email': 'dave@odoo.com',
'mobile': '+1 202 555 0123',
'phone': False,
'parent_id': company.id,
'is_company': False,
'street': 'Pearl street',
'city': 'California',
'country_id': self.env.ref('base.us').id,
'zip': '95826',
})
partner_2 = self.env['res.partner'].create({
'name': 'Eve',
'email': 'eve@odoo.com',
'mobile': '+1 202 555 3210',
'phone': False,
'parent_id': company.id,
'is_company': False,
'street': 'Wall street',
'city': 'New York',
'country_id': self.env.ref('base.us').id,
'zip': '54321',
})
lead_1 = self.env['crm.lead'].create({
'name': 'Lead 1',
# base leads on which duplicate detection is performed
cls.lead_generic = cls.env['crm.lead'].create({
'country_id': country_us_id,
'email_from': 'FP@odoo.com',
'name': 'Generic 1',
'partner_id': cls.test_partners[0].id,
'phone': '+1 202 555 0123',
'type': 'lead',
'partner_name': 'Alice',
'email_from': 'alice@odoo.com',
})
lead_2 = self.env['crm.lead'].create({
'name': 'Opportunity 1',
'type': 'opportunity',
'email_from': 'alice@odoo.com',
})
lead_3 = self.env['crm.lead'].create({
'name': 'Opportunity 2',
'type': 'opportunity',
'email_from': 'alice@odoo.com',
})
lead_4 = self.env['crm.lead'].create({
'name': 'Lead 2',
'type': 'lead',
'partner_name': 'Alice Doe'
})
lead_5 = self.env['crm.lead'].create({
'name': 'Opportunity 3',
'type': 'opportunity',
'partner_name': 'Alice Doe'
})
lead_6 = self.env['crm.lead'].create({
'name': 'Opportunity 4',
'type': 'opportunity',
'partner_name': 'Bob Doe'
})
lead_7 = self.env['crm.lead'].create({
'name': 'Opportunity 5',
'type': 'opportunity',
'partner_name': 'Bob Doe',
'email_from': 'bob@odoo.com',
})
lead_8 = self.env['crm.lead'].create({
'name': 'Opportunity 6',
'type': 'opportunity',
'email_from': 'bob@mymail.com',
})
lead_9 = self.env['crm.lead'].create({
'name': 'Opportunity 7',
'type': 'opportunity',
'email_from': 'alice@mymail.com',
})
lead_10 = self.env['crm.lead'].create({
'name': 'Opportunity 8',
'type': 'opportunity',
'probability': 0,
'active': False,
'email_from': 'alice@mymail.com',
})
lead_11 = self.env['crm.lead'].create({
'name': 'Opportunity 9',
'type': 'opportunity',
'contact_name': 'charlie'
})
lead_12 = self.env['crm.lead'].create({
'name': 'Opportunity 10',
'type': 'opportunity',
'contact_name': 'Charlie Chapelin',
})
lead_13 = self.env['crm.lead'].create({
'name': 'Opportunity 8',
'type': 'opportunity',
'partner_id': partner_1.id
})
lead_14 = self.env['crm.lead'].create({
'name': 'Lead 3',
'type': 'lead',
'partner_id': partner_2.id
})
self.assertEqual(lead_1 + lead_2 + lead_3, lead_1.duplicate_lead_ids)
self.assertEqual(lead_1 + lead_2 + lead_3, lead_2.duplicate_lead_ids)
self.assertEqual(lead_1 + lead_2 + lead_3, lead_3.duplicate_lead_ids)
self.assertEqual(lead_4 + lead_5, lead_4.duplicate_lead_ids)
self.assertEqual(lead_4 + lead_5, lead_5.duplicate_lead_ids)
self.assertEqual(lead_6 + lead_7, lead_6.duplicate_lead_ids)
self.assertEqual(lead_6 + lead_7, lead_7.duplicate_lead_ids)
self.assertEqual(lead_8 + lead_9 + lead_10, lead_8.duplicate_lead_ids)
self.assertEqual(lead_8 + lead_9 + lead_10, lead_9.duplicate_lead_ids)
self.assertEqual(lead_8 + lead_9 + lead_10, lead_10.duplicate_lead_ids)
self.assertEqual(lead_11 + lead_12, lead_11.duplicate_lead_ids)
self.assertEqual(lead_12, lead_12.duplicate_lead_ids)
self.assertEqual(lead_13 + lead_14, lead_13.duplicate_lead_ids)
self.assertEqual(lead_13 + lead_14, lead_14.duplicate_lead_ids)
@users('user_sales_manager')
def test_potential_duplicates_with_phone(self):
customer = self.env['res.partner'].create({
'email': 'customer1@duplicate.example.com',
'mobile': '+32485001122',
'name': 'Customer1',
'phone': '(803)-456-6126',
})
base_lead = self.env['crm.lead'].create({
'name': 'Base Lead',
'partner_id': customer.id,
cls.lead_company = cls.env['crm.lead'].create({
'country_id': country_us_id,
'email_from': 'floppy@MYCOMPANY.com',
'partner_id': False,
'name': 'CompanyMail 1',
'phone': '+1 202 666 4567',
'type': 'lead',
})
self.assertEqual(base_lead.contact_name, customer.name)
self.assertEqual(base_lead.mobile, customer.mobile)
self.assertFalse(base_lead.partner_name)
self.assertEqual(base_lead.phone, customer.phone)
# duplicates
cls.lead_generic_email_dupes = cls.env['crm.lead'].create([
# email based: normalized version used for email domain criterion
{
'email_from': '"Fabulous Fab" <fp@ODOO.COM>',
'name': 'Dupe1 of fp@odoo.com (same email)',
'type': 'lead',
},
{
'email_from': 'FP@odoo.com',
'name': 'Dupe2 of fp@odoo.com (same email)',
'type': 'lead',
},
# phone_sanitized based
{
'email_from': 'not.fp@not.odoo.com',
'name': 'Dupe3 of fp@odoo.com (same phone sanitized)',
'phone': '+1 202 555 0123',
'type': 'lead',
},
{
'email_from': 'not.fp@not.odoo.com',
'phone': '+1 202 555 0123',
'name': 'Dupe4 of fp@odoo.com (same phone sanitized)',
'type': 'lead',
},
# same commercial entity
{
'name': 'Dupe5 of fp@odoo.com (same commercial entity)',
'partner_id': cls.test_partners[1].id,
},
{
'name': 'Dupe6 of fp@odoo.com (same commercial entity)',
'partner_id': cls.test_company.id,
}
])
cls.lead_generic_email_notdupes = cls.env['crm.lead'].create([
# email: check for exact match
{
'email_from': 'not.fp@odoo.com',
'name': 'NotADupe1',
'type': 'lead',
},
])
cls.lead_company_email_dupes = cls.env['crm.lead'].create([
# email based: normalized version used for email domain criterion
{
'email_from': '"The Other Fabulous Fab" <fp@mycompany.COM>',
'name': 'Dupe1 of mycompany@mycompany.com (same company)',
'type': 'lead',
},
{
'email_from': '"Same Email" <floppy@mycompany.com>',
'name': 'Dupe2 of mycompany@mycompany.com (same company)',
'type': 'lead',
},
# phone_sanitized based
{
'email_from': 'not.floppy@not.mycompany.com',
'name': 'Dupe3 of fp@odoo.com (same phone sanitized)',
'phone': '+1 202 666 4567',
'type': 'lead',
},
{
'email_from': 'not.floppy@not.mycompany.com',
'phone': '+1 202 666 4567',
'name': 'Dupe4 of fp@odoo.com (same phone sanitized)',
'type': 'lead',
},
])
cls.lead_company_email_notdupes = cls.env['crm.lead'].create([
# email: check same company
{
'email_from': 'floppy@zboing.MYCOMPANY.com',
'name': 'NotADupe2',
'type': 'lead',
},
])
dup1_1 = self.env['crm.lead'].create({
'name': 'Base Lead Dup1',
'type': 'lead',
'phone': '456-6126', # shorter version of base_lead
'mobile': ' ', # empty string shouldn't crash Odoo
'partner_name': 'Partner Name 1',
})
dup1_2 = self.env['crm.lead'].create({
'name': 'Base Lead Dup2',
'mobile': '8034566126',
'partner_name': 'Partner Name 2',
'type': 'lead',
})
dup1_3 = self.env['crm.lead'].create({
'name': 'Base Lead Dup3',
'partner_name': 'Partner Name 3',
'phone': '(803)-456-6126',
'type': 'lead',
})
dup1_4 = self.env['crm.lead'].create({
'mobile': '0032485001122',
# 'mobile': '0485001122', # note: does not work
'name': 'Base Lead Dup4',
'partner_name': 'Partner Name 4',
'phone': False,
'type': 'lead',
})
def test_assert_initial_values(self):
""" Just be sure of initial value for those tests """
lead_generic = self.lead_generic.with_env(self.env)
self.assertEqual(lead_generic.phone_sanitized, '+12025550123')
self.assertEqual(lead_generic.email_domain_criterion, 'fp@odoo.com')
self.assertEqual(lead_generic.email_normalized, 'fp@odoo.com')
expected = base_lead + dup1_2 + dup1_3 + dup1_4 # dup1_1 is shorter than lead -> not a dupe
self.assertEqual(
base_lead.duplicate_lead_ids, expected,
'CRM: missing %s, extra %s' % ((expected - base_lead.duplicate_lead_ids).mapped('name'), (base_lead.duplicate_lead_ids - expected).mapped('name'))
)
expected = base_lead + dup1_1 + dup1_2 + dup1_3 # dup1_4 has mobile of customer, but no link with dup1_1
self.assertEqual(
dup1_1.duplicate_lead_ids, expected,
'CRM: missing %s, extra %s' % ((expected - dup1_1.duplicate_lead_ids).mapped('name'), (dup1_1.duplicate_lead_ids - expected).mapped('name'))
)
lead_company = self.lead_company.with_env(self.env)
self.assertEqual(lead_company.phone_sanitized, '+12026664567')
self.assertEqual(lead_company.email_domain_criterion, '@mycompany.com')
self.assertEqual(lead_company.email_normalized, 'floppy@mycompany.com')
@users('user_sales_manager')
def test_potential_duplicates_with_invalid_email(self):
lead_1 = self.env['crm.lead'].create({
'name': 'Lead 1',
'type': 'lead',
'email_from': 'mail"1@mymail.com'
})
lead_2 = self.env['crm.lead'].create({
'name': 'Opportunity 1',
'type': 'opportunity',
'email_from': 'mail2@mymail.com'
})
lead_3 = self.env['crm.lead'].create({
'name': 'Opportunity 2',
'type': 'lead',
'email_from': 'odoo.com'
})
lead_4 = self.env['crm.lead'].create({
'name': 'Opportunity 3',
'type': 'opportunity',
'email_from': 'odoo.com'
})
lead_5 = self.env['crm.lead'].create({
'name': 'Opportunity 3',
'type': 'opportunity',
'email_from': 'myodoo.com'
})
@users('user_sales_leads')
def test_crm_lead_duplicates_fetch(self):
""" Test heuristic to find duplicates of a given lead. """
# generic provider-based email
lead_generic = self.lead_generic.with_env(self.env)
self.assertEqual(lead_1 + lead_2, lead_1.duplicate_lead_ids)
self.assertEqual(lead_1 + lead_2, lead_2.duplicate_lead_ids)
self.assertEqual(lead_3 + lead_4 + lead_5, lead_3.duplicate_lead_ids)
self.assertEqual(lead_3 + lead_4 + lead_5, lead_4.duplicate_lead_ids)
self.assertEqual(lead_5, lead_5.duplicate_lead_ids)
self.assertEqual(lead_generic.duplicate_lead_ids,
lead_generic + self.lead_generic_email_dupes,
'Duplicates: exact email matching (+ self)')
# company-based email
lead_company = self.lead_company.with_env(self.env)
self.assertEqual(lead_company.duplicate_lead_ids,
lead_company + self.lead_company_email_dupes,
'Duplicates: exact email matching (+ self)')
@users('user_sales_leads')
def test_crm_lead_email_domain_criterion(self):
""" Test computed field 'email_domain_criterion' used notably to fetch
duplicates. """
for test_email, provider in self.emails_provider_generic:
with self.subTest(test_email=test_email, provider=provider):
lead = self.env['crm.lead'].create({
'email_from': test_email,
'name': test_email,
})
self.assertEqual(lead.email_domain_criterion, provider)
for test_email, provider in self.emails_provider_company:
with self.subTest(test_email=test_email, provider=provider):
lead = self.env['crm.lead'].create({
'email_from': test_email,
'name': test_email,
})
self.assertEqual(lead.email_domain_criterion, f'@{provider}',)
@users('user_sales_leads')
def test_iap_tools(self):
""" Test iap tools specifically """
for test_email, provider in self.emails_provider_generic:
with self.subTest(test_email=test_email, provider=provider):
self.assertEqual(
iap_tools.mail_prepare_for_domain_search(test_email),
test_email,
'As provider is a generic one, complete email should be returned for a company-based mail search'
)
for test_email, provider in self.emails_provider_company:
with self.subTest(test_email=test_email, provider=provider):
self.assertEqual(
iap_tools.mail_prepare_for_domain_search(test_email),
f'@{provider}',
'As provider is a company one, only the domain part should be returned for a company-based mail search'
)