199 lines
9.7 KiB
Python
199 lines
9.7 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
import random
|
||
|
|
||
|
from odoo.addons.crm.tests.test_crm_lead_assignment import TestLeadAssignCommon
|
||
|
from odoo.tests.common import tagged
|
||
|
from odoo.tools import mute_logger
|
||
|
|
||
|
|
||
|
@tagged('lead_assign', 'crm_performance', 'post_install', '-at_install')
|
||
|
class TestLeadAssignPerf(TestLeadAssignCommon):
|
||
|
""" Test performances of lead assignment feature added in saas-14.2
|
||
|
|
||
|
Assign process is a random process: randomizing teams leads to searching,
|
||
|
assigning and de-duplicating leads in various order. As a lot of search
|
||
|
are implied during assign process query counters may vary from run to run.
|
||
|
"Heavy" performance test included here ranged from 6K to 6.3K queries. Either
|
||
|
we set high counters maximum which makes those tests less useful. Either we
|
||
|
avoid random if possible which is what we decided to do by setting the seed
|
||
|
of random in tests.
|
||
|
"""
|
||
|
|
||
|
@mute_logger('odoo.models.unlink', 'odoo.addons.crm.models.crm_team', 'odoo.addons.crm.models.crm_team_member')
|
||
|
def test_assign_perf_duplicates(self):
|
||
|
""" Test assign process with duplicates on partner. Allow to ensure notably
|
||
|
that de duplication is effectively performed. """
|
||
|
# fix the seed and avoid randomness
|
||
|
random.seed(1940)
|
||
|
|
||
|
leads = self._create_leads_batch(
|
||
|
lead_type='lead',
|
||
|
user_ids=[False],
|
||
|
partner_ids=[self.contact_1.id, self.contact_2.id, False, False, False],
|
||
|
count=200
|
||
|
)
|
||
|
# commit probability and related fields
|
||
|
leads.flush_recordset()
|
||
|
self.assertInitialData()
|
||
|
|
||
|
# assign probability to leads (bypass auto probability as purpose is not to test pls)
|
||
|
leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
|
||
|
for idx in range(0, 5):
|
||
|
sliced_leads = leads[idx:len(leads):5]
|
||
|
for lead in sliced_leads:
|
||
|
lead.probability = (idx + 1) * 10 * ((int(lead.priority) + 1) / 2)
|
||
|
# commit probability and related fields
|
||
|
leads.flush_recordset()
|
||
|
|
||
|
# randomness: at least 1 query
|
||
|
with self.with_user('user_sales_manager'):
|
||
|
self.env['res.users'].has_group('base.group_user') # warmup the cache to avoid inconsistency between community an enterprise
|
||
|
with self.assertQueryCount(user_sales_manager=1169): # crm 1160 / com 1165
|
||
|
self.env['crm.team'].browse(self.sales_teams.ids)._action_assign_leads(work_days=2)
|
||
|
|
||
|
# teams assign
|
||
|
leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
|
||
|
leads_st1 = leads.filtered_domain([('team_id', '=', self.sales_team_1.id)])
|
||
|
leads_stc = leads.filtered_domain([('team_id', '=', self.sales_team_convert.id)])
|
||
|
self.assertLessEqual(len(leads_st1), 128)
|
||
|
self.assertLessEqual(len(leads_stc), 96)
|
||
|
self.assertEqual(len(leads_st1) + len(leads_stc), len(leads)) # Make sure all lead are assigned
|
||
|
|
||
|
# salespersons assign
|
||
|
self.members.invalidate_model(['lead_month_count'])
|
||
|
self.assertMemberAssign(self.sales_team_1_m1, 11) # 45 max on 2 days (3) + compensation (8.4)
|
||
|
self.assertMemberAssign(self.sales_team_1_m2, 4) # 15 max on 2 days (1) + compensation (2.8)
|
||
|
self.assertMemberAssign(self.sales_team_1_m3, 4) # 15 max on 2 days (1) + compensation (2.8)
|
||
|
self.assertMemberAssign(self.sales_team_convert_m1, 8) # 30 max on 15 (2) + compensation (5.6)
|
||
|
self.assertMemberAssign(self.sales_team_convert_m2, 15) # 60 max on 15 (4) + compsantion (11.2)
|
||
|
|
||
|
@mute_logger('odoo.models.unlink', 'odoo.addons.crm.models.crm_team', 'odoo.addons.crm.models.crm_team_member')
|
||
|
def test_assign_perf_no_duplicates(self):
|
||
|
# fix the seed and avoid randomness
|
||
|
random.seed(1945)
|
||
|
|
||
|
leads = self._create_leads_batch(
|
||
|
lead_type='lead',
|
||
|
user_ids=[False],
|
||
|
partner_ids=[False],
|
||
|
count=100
|
||
|
)
|
||
|
# commit probability and related fields
|
||
|
leads.flush_recordset()
|
||
|
self.assertInitialData()
|
||
|
|
||
|
# assign probability to leads (bypass auto probability as purpose is not to test pls)
|
||
|
leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
|
||
|
for idx in range(0, 5):
|
||
|
sliced_leads = leads[idx:len(leads):5]
|
||
|
for lead in sliced_leads:
|
||
|
lead.probability = (idx + 1) * 10 * ((int(lead.priority) + 1) / 2)
|
||
|
# commit probability and related fields
|
||
|
leads.flush_recordset()
|
||
|
|
||
|
# randomness: at least 1 query
|
||
|
with self.with_user('user_sales_manager'):
|
||
|
with self.assertQueryCount(user_sales_manager=586): # crm 582
|
||
|
self.env['crm.team'].browse(self.sales_teams.ids)._action_assign_leads(work_days=2)
|
||
|
|
||
|
# teams assign
|
||
|
leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
|
||
|
leads_st1 = leads.filtered_domain([('team_id', '=', self.sales_team_1.id)])
|
||
|
leads_stc = leads.filtered_domain([('team_id', '=', self.sales_team_convert.id)])
|
||
|
self.assertEqual(len(leads_st1) + len(leads_stc), 100)
|
||
|
|
||
|
# salespersons assign
|
||
|
self.members.invalidate_model(['lead_month_count'])
|
||
|
self.assertMemberAssign(self.sales_team_1_m1, 11) # 45 max on 2 days (3) + compensation (8.4)
|
||
|
self.assertMemberAssign(self.sales_team_1_m2, 4) # 15 max on 2 days (1) + compensation (2.8)
|
||
|
self.assertMemberAssign(self.sales_team_1_m3, 4) # 15 max on 2 days (1) + compensation (2.8)
|
||
|
self.assertMemberAssign(self.sales_team_convert_m1, 8) # 30 max on 15 (2) + compensation (5.6)
|
||
|
self.assertMemberAssign(self.sales_team_convert_m2, 15) # 60 max on 15 (4) + compensation (11.2)
|
||
|
|
||
|
@mute_logger('odoo.models.unlink', 'odoo.addons.crm.models.crm_team', 'odoo.addons.crm.models.crm_team_member')
|
||
|
def test_assign_perf_populated(self):
|
||
|
""" Test assignment on a more high volume oriented test set in order to
|
||
|
have more insights on query counts. """
|
||
|
# fix the seed and avoid randomness
|
||
|
random.seed(1871)
|
||
|
|
||
|
# create leads enough to have interesting counters
|
||
|
_lead_count, _email_dup_count, _partner_count = 600, 50, 150
|
||
|
leads = self._create_leads_batch(
|
||
|
lead_type='lead',
|
||
|
user_ids=[False],
|
||
|
partner_count=_partner_count,
|
||
|
country_ids=[self.env.ref('base.be').id, self.env.ref('base.fr').id, False],
|
||
|
count=_lead_count,
|
||
|
email_dup_count=_email_dup_count)
|
||
|
# commit probability and related fields
|
||
|
leads.flush_recordset()
|
||
|
self.assertInitialData()
|
||
|
|
||
|
# assign for one month, aka a lot
|
||
|
self.env.ref('crm.ir_cron_crm_lead_assign').write({'interval_type': 'days', 'interval_number': 30})
|
||
|
# create a third team
|
||
|
sales_team_3 = self.env['crm.team'].create({
|
||
|
'name': 'Sales Team 3',
|
||
|
'sequence': 15,
|
||
|
'alias_name': False,
|
||
|
'use_leads': True,
|
||
|
'use_opportunities': True,
|
||
|
'company_id': False,
|
||
|
'user_id': False,
|
||
|
'assignment_domain': [('country_id', '!=', False)],
|
||
|
})
|
||
|
sales_team_3_m1 = self.env['crm.team.member'].create({
|
||
|
'user_id': self.user_sales_manager.id,
|
||
|
'crm_team_id': sales_team_3.id,
|
||
|
'assignment_max': 60,
|
||
|
'assignment_domain': False,
|
||
|
})
|
||
|
sales_team_3_m2 = self.env['crm.team.member'].create({
|
||
|
'user_id': self.user_sales_leads.id,
|
||
|
'crm_team_id': sales_team_3.id,
|
||
|
'assignment_max': 60,
|
||
|
'assignment_domain': False,
|
||
|
})
|
||
|
sales_team_3_m3 = self.env['crm.team.member'].create({
|
||
|
'user_id': self.user_sales_salesman.id,
|
||
|
'crm_team_id': sales_team_3.id,
|
||
|
'assignment_max': 15,
|
||
|
'assignment_domain': [('probability', '>=', 10)],
|
||
|
})
|
||
|
sales_teams = self.sales_teams | sales_team_3
|
||
|
self.assertEqual(sum(team.assignment_max for team in sales_teams), 300)
|
||
|
self.assertEqual(len(leads), 650)
|
||
|
|
||
|
# assign probability to leads (bypass auto probability as purpose is not to test pls)
|
||
|
leads = self.env['crm.lead'].search([('id', 'in', leads.ids)]) # ensure order
|
||
|
for idx in range(0, 5):
|
||
|
sliced_leads = leads[idx:len(leads):5]
|
||
|
for lead in sliced_leads:
|
||
|
lead.probability = (idx + 1) * 10 * ((int(lead.priority) + 1) / 2)
|
||
|
# commit probability and related fields
|
||
|
leads.flush_recordset()
|
||
|
|
||
|
# randomness: add 2 queries
|
||
|
with self.with_user('user_sales_manager'):
|
||
|
with self.assertQueryCount(user_sales_manager=6066): # crm 6048 / com 6052 / ent 6055
|
||
|
self.env['crm.team'].browse(sales_teams.ids)._action_assign_leads(work_days=30)
|
||
|
|
||
|
# teams assign
|
||
|
leads = self.env['crm.lead'].search([('id', 'in', leads.ids)])
|
||
|
self.assertEqual(leads.team_id, sales_teams)
|
||
|
self.assertEqual(leads.user_id, sales_teams.member_ids)
|
||
|
|
||
|
# salespersons assign
|
||
|
self.members.invalidate_model(['lead_month_count'])
|
||
|
self.assertMemberAssign(self.sales_team_1_m1, 45) # 45 max on one month
|
||
|
self.assertMemberAssign(self.sales_team_1_m2, 15) # 15 max on one month
|
||
|
self.assertMemberAssign(self.sales_team_1_m3, 15) # 15 max on one month
|
||
|
self.assertMemberAssign(self.sales_team_convert_m1, 30) # 30 max on one month
|
||
|
self.assertMemberAssign(self.sales_team_convert_m2, 60) # 60 max on one month
|
||
|
self.assertMemberAssign(sales_team_3_m1, 60) # 60 max on one month
|
||
|
self.assertMemberAssign(sales_team_3_m2, 60) # 60 max on one month
|
||
|
self.assertMemberAssign(sales_team_3_m3, 15) # 15 max on one month
|