[FW][FIX] crm: compute no team lead probability based on all lead

Before this commit, leads without any team_id set had their automated
proabbility computed based on the subset of all leads without team id.
Unless wrongly configured or strange pipeline use, all leads end up with
a team_id set. Therefore subset of leads without team is not really a
good set used to estimate probability of new leads.

After this commit, a lead with no team_id set yet will have its
automated probability computed based on the entire lead set.

Task-2526926
PR odoo/odoo#70270

X-original-commit: be1a55b305057803a67ec2b016e51325c992586f
Co-authored-by: David Beguin <dbe@odoo.com>
Co-authored-by: Thibault François <tfr@odoo.com>
This commit is contained in:
Thibault Francois
2021-06-11 15:44:54 +00:00
committed by Thibault Delavallée
co-authored by David Beguin Thibault François
parent e123aa2f30
commit da361f03fe
2 changed files with 40 additions and 10 deletions
+9 -9
View File
@@ -1909,19 +1909,17 @@ class Lead(models.Model):
# get all team_ids from frequencies
frequency_teams = frequencies.mapped('team_id')
frequency_team_ids = [0] + [team.id for team in frequency_teams]
frequency_team_ids = [team.id for team in frequency_teams]
# 1. Compute each variable value count individually
# regroup each variable to be able to compute their own probabilities
# As all the variable does not enter into account (as we reject unset values in the process)
# each value probability must be computed only with their own variable related total count
# special case: for lead for which team_id is not in frequency table,
# special case: for lead for which team_id is not in frequency table or lead with no team_id,
# we consider all the records, independently from team_id (this is why we add a result[-1])
result = dict((team_id, dict((field, dict(won_total=0, lost_total=0)) for field in leads_fields)) for team_id in frequency_team_ids)
result[-1] = dict((field, dict(won_total=0, lost_total=0)) for field in leads_fields)
for frequency in frequencies:
team_result = result[frequency.team_id.id if frequency.team_id else 0]
field = frequency['variable']
value = frequency['value']
@@ -1930,9 +1928,11 @@ class Lead(models.Model):
if field == 'tag_id' and (frequency['won_count'] + frequency['lost_count']) < 50:
continue
team_result[field][value] = {'won': frequency['won_count'], 'lost': frequency['lost_count']}
team_result[field]['won_total'] += frequency['won_count']
team_result[field]['lost_total'] += frequency['lost_count']
if frequency.team_id:
team_result = result[frequency.team_id.id]
team_result[field][value] = {'won': frequency['won_count'], 'lost': frequency['lost_count']}
team_result[field]['won_total'] += frequency['won_count']
team_result[field]['lost_total'] += frequency['lost_count']
if value not in result[-1][field]:
result[-1][field][value] = {'won': 0, 'lost': 0}
@@ -1960,8 +1960,8 @@ class Lead(models.Model):
lead_probabilities[lead_id] = 100
continue
lead_team_id = lead_values['team_id'] if lead_values['team_id'] else 0 # team_id = None -> Convert to 0
lead_team_id = lead_team_id if lead_team_id in result else -1 # team_id not in frequency Table -> convert to -1
# team_id not in frequency Table -> convert to -1
lead_team_id = lead_values['team_id'] if lead_values['team_id'] in result else -1
if lead_team_id != save_team_id:
save_team_id = lead_team_id
team_won = result[save_team_id]['team_won']
+31 -1
View File
@@ -109,7 +109,7 @@ class TestCRMPLS(TransactionCase):
country_ids = self.env['res.country'].search([], limit=3).ids
stage_ids = self.env['crm.stage'].search([], limit=3).ids
won_stage_id = self.env['crm.stage'].search([('is_won', '=', True)], limit=1).id
team_ids = self.env['crm.team'].create([{'name': 'Team Test 1'}, {'name': 'Team Test 2'}]).ids
team_ids = self.env['crm.team'].create([{'name': 'Team Test 1'}, {'name': 'Team Test 2'}, {'name': 'Team Test 3'}]).ids
# create bunch of lost and won crm_lead
leads_to_create = []
# for team 1
@@ -132,8 +132,22 @@ class TestCRMPLS(TransactionCase):
leads_to_create.append(
self._get_lead_values(team_ids[1], 'team_2_%s' % str(9), country_ids[1], state_ids[0], state_values[1], state_values[0], source_ids[1], stage_ids[1]))
# for leads with no team
leads_to_create.append(
self._get_lead_values(False, 'no_team_%s' % str(10), country_ids[1], state_ids[1], state_values[2], state_values[0], source_ids[1], stage_ids[2]))
leads_to_create.append(
self._get_lead_values(False, 'no_team_%s' % str(11), country_ids[0], state_ids[1], state_values[1], state_values[1], source_ids[0], stage_ids[0]))
leads_to_create.append(
self._get_lead_values(False, 'no_team_%s' % str(12), country_ids[1], state_ids[2], state_values[0], state_values[1], source_ids[2], stage_ids[0]))
leads_to_create.append(
self._get_lead_values(False, 'no_team_%s' % str(13), country_ids[0], state_ids[1], state_values[2], state_values[0], source_ids[2], stage_ids[1]))
leads = Lead.create(leads_to_create)
# assign team 3 to all leads with no teams (also take data into account).
leads_with_no_team = self.env['crm.lead'].sudo().search([('team_id', '=', False)])
leads_with_no_team.write({'team_id': team_ids[2]})
# Set the PLS config
self.env['ir.config_parameter'].sudo().set_param("crm.pls_start_date", "2000-01-01")
self.env['ir.config_parameter'].sudo().set_param("crm.pls_fields", "country_id,state_id,email_state,phone_state,source_id,tag_ids")
@@ -147,6 +161,10 @@ class TestCRMPLS(TransactionCase):
leads[5].action_set_lost()
leads[6].action_set_lost()
leads[7].action_set_won()
# Leads with no team
leads[10].action_set_won()
leads[11].action_set_lost()
leads[12].action_set_lost()
# A. Test Full Rebuild
# rebuild frequencies table and recompute automated_probability for all leads.
@@ -157,6 +175,18 @@ class TestCRMPLS(TransactionCase):
self.assertEqual(tools.float_compare(leads[3].automated_probability, 33.49, 2), 0)
self.assertEqual(tools.float_compare(leads[8].automated_probability, 7.74, 2), 0)
lead_13_team_3_proba = leads[13].automated_probability
self.assertEqual(tools.float_compare(lead_13_team_3_proba, 35.09, 2), 0)
# Probability for Lead with no teams should be based on all the leads no matter their team.
# De-assign team 3 and rebuilt frequency table and recompute.
# Proba should be different as "no team" is not considered as a separated team.
leads_with_no_team.write({'team_id': False})
Lead._cron_update_automated_probabilities()
leads.invalidate_cache()
lead_13_no_team_proba = leads[13].automated_probability
self.assertTrue(lead_13_team_3_proba != leads[13].automated_probability, "Probability for leads with no team should be different than if they where in their own team.")
self.assertEqual(tools.float_compare(lead_13_no_team_proba, 36.65, 2), 0)
# Test frequencies
lead_4_stage_0_freq = LeadScoringFrequency.search([('team_id', '=', leads[4].team_id.id), ('variable', '=', 'stage_id'), ('value', '=', stage_ids[0])])