diff --git a/addons/crm/tests/common.py b/addons/crm/tests/common.py index bc463a0068f..fa2c77a2307 100644 --- a/addons/crm/tests/common.py +++ b/addons/crm/tests/common.py @@ -1,7 +1,10 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from unittest.mock import patch + from odoo.addons.mail.tests.common import MailCase, mail_new_test_user +from odoo.fields import Datetime from odoo.tests.common import SavepointCase INCOMING_EMAIL = """Return-Path: {return_path} @@ -88,18 +91,24 @@ class TestCrmCommon(MailCase, SavepointCase): }) cls.stage_team1_won = cls.env['crm.stage'].create({ 'name': 'Won', + 'sequence': 70, 'team_id': cls.sales_team_1.id, 'is_won': True, - 'sequence': 70, }) cls.stage_gen_1 = cls.env['crm.stage'].create({ 'name': 'Generic stage', 'sequence': 3, 'team_id': False, }) + cls.stage_gen_won = cls.env['crm.stage'].create({ + 'name': 'Generic Won', + 'sequence': 30, + 'team_id': False, + 'is_won': True, + }) cls.lead_1 = cls.env['crm.lead'].create({ - 'name': 'Club Office Furnitures', + 'name': 'Nibbler Spacecraft Request', 'type': 'lead', 'user_id': cls.user_sales_leads.id, 'team_id': cls.sales_team_1.id, @@ -119,6 +128,8 @@ class TestCrmCommon(MailCase, SavepointCase): cls.contact_1 = cls.env['res.partner'].create({ 'name': 'Philip J Fry', 'email': 'philip.j.fry@test.example.com', + 'mobile': '+1 202 555 0122', + 'phone': False, 'parent_id': cls.contact_company_1.id, 'is_company': False, 'street': 'Actually the sewers', @@ -136,3 +147,137 @@ class TestCrmCommon(MailCase, SavepointCase): 'country_id': cls.env.ref('base.us').id, 'zip': '97648', }) + + def _create_duplicates(self, lead, count=2): + leads = self.env['crm.lead'] + for x in range(count): + leads |= self.env['crm.lead'].create({ + 'name': 'Dup-%02d-%s' % (x+1, lead.name), + 'type': 'lead', + 'user_id': False, + 'team_id': lead.team_id.id, + 'contact_name': 'Duplicate %02d of %s' % (x+1, lead.contact_name), + 'email_from': lead.email_from, + }) + return leads + + +class TestLeadConvertCommon(TestCrmCommon): + + @classmethod + def setUpClass(cls): + super(TestLeadConvertCommon, cls).setUpClass() + # Sales Team organization + # Role: M (team member) R (team manager) + # SALESMAN---------------sales_team_1-----sales_team_convert + # admin------------------M----------------/ + # user_sales_manager-----R----------------R + # user_sales_leads-------M----------------/ + # user_sales_salesman----/----------------M + + # Stages Team organization + # Name-------------------ST-------------------Sequ + # stage_team1_1----------sales_team_1---------1 + # stage_team1_2----------sales_team_1---------5 + # stage_team1_won--------sales_team_1---------70 + # stage_gen_1------------/--------------------3 + # stage_gen_won----------/--------------------30 + # stage_team_convert_1---sales_team_convert---1 + + cls.sales_team_convert = cls.env['crm.team'].create({ + 'name': 'Convert Sales Team', + 'alias_name': False, + 'use_leads': True, + 'use_opportunities': True, + 'company_id': False, + 'user_id': cls.user_sales_manager.id, + 'member_ids': [(4, cls.user_sales_salesman.id)], + }) + cls.stage_team_convert_1 = cls.env['crm.stage'].create({ + 'name': 'New', + 'sequence': 1, + 'team_id': cls.sales_team_convert.id, + }) + + cls.lead_1.write({'date_open': Datetime.from_string('2020-01-15 11:30:00')}) + + cls.crm_lead_dt_patcher = patch('odoo.addons.crm.models.crm_lead.fields.Datetime', wraps=Datetime) + cls.crm_lead_dt_mock = cls.crm_lead_dt_patcher.start() + + @classmethod + def tearDownClass(cls): + cls.crm_lead_dt_patcher.stop() + super(TestLeadConvertCommon, cls).tearDownClass() + + +class TestLeadConvertMassCommon(TestLeadConvertCommon): + + @classmethod + def setUpClass(cls): + super(TestLeadConvertMassCommon, cls).setUpClass() + # Sales Team organization + # Role: M (team member) R (team manager) + # SALESMAN-------------------sales_team_1-----sales_team_convert + # admin----------------------M----------------/ + # user_sales_manager---------R----------------R + # user_sales_leads-----------M----------------/ + # user_sales_leads_convert---/----------------M <-- NEW + # user_sales_salesman--------/----------------M + + cls.user_sales_leads_convert = mail_new_test_user( + cls.env, login='user_sales_leads_convert', + name='Lucien Sales Leads Convert', email='crm_leads_2@test.example.com', + company_id=cls.env.ref("base.main_company").id, + notification_type='inbox', + groups='sales_team.group_sale_salesman_all_leads,base.group_partner_manager,crm.group_use_lead', + ) + cls.sales_team_convert.write({ + 'member_ids': [(4, cls.user_sales_leads_convert.id)] + }) + + cls.lead_w_partner = cls.env['crm.lead'].create({ + 'name': 'New1', + 'type': 'lead', + 'probability': 10, + 'user_id': cls.user_sales_manager.id, + 'stage_id': False, + 'partner_id': cls.contact_1.id, + }) + cls.lead_w_partner_company = cls.env['crm.lead'].create({ + 'name': 'New1', + 'type': 'lead', + 'probability': 15, + 'user_id': cls.user_sales_manager.id, + 'stage_id': cls.stage_team1_1.id, + 'partner_id': cls.contact_company_1.id, + 'contact_name': 'Hermes Conrad', + 'email_from': 'hermes.conrad@test.example.com', + }) + cls.lead_w_contact = cls.env['crm.lead'].create({ + 'name': 'LeadContact', + 'type': 'lead', + 'probability': 15, + 'contact_name': 'TestContact', + 'user_id': cls.user_sales_salesman.id, + 'stage_id': cls.stage_gen_1.id, + }) + cls.lead_w_email = cls.env['crm.lead'].create({ + 'name': 'LeadEmailAsContact', + 'type': 'lead', + 'probability': 15, + 'email_from': 'contact.email@test.example.com', + 'user_id': cls.user_sales_salesman.id, + 'stage_id': cls.stage_gen_1.id, + }) + cls.lead_w_email_lost = cls.env['crm.lead'].create({ + 'name': 'Lost', + 'type': 'lead', + 'probability': 15, + 'email_from': 'strange.from@test.example.com', + 'user_id': cls.user_sales_leads.id, + 'stage_id': cls.stage_team1_2.id, + 'active': False, + }) + for l in (cls.lead_w_partner | cls.lead_w_partner_company | cls.lead_w_contact | cls.lead_w_email | cls.lead_w_email_lost): + l._onchange_user_id() + l.flush() diff --git a/addons/crm/tests/test_crm_lead.py b/addons/crm/tests/test_crm_lead.py index 80b32bea315..bf7933df43e 100644 --- a/addons/crm/tests/test_crm_lead.py +++ b/addons/crm/tests/test_crm_lead.py @@ -41,7 +41,7 @@ class TestCRMLead(TestCrmCommon): lead.action_set_won() self.assertEqual(lead.probability, 100.0) - self.assertEqual(lead.stage_id, self.stage_team1_won) + self.assertEqual(lead.stage_id, self.stage_gen_won) # generic won stage has lower sequence than team won stage @users('user_sales_manager') def test_crm_team_alias(self): diff --git a/addons/crm/tests/test_crm_lead_convert.py b/addons/crm/tests/test_crm_lead_convert.py index c4f85fd6f1e..ec587d10c4f 100644 --- a/addons/crm/tests/test_crm_lead_convert.py +++ b/addons/crm/tests/test_crm_lead_convert.py @@ -1,67 +1,98 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from unittest.mock import patch - -from odoo.addons.crm.tests.common import TestCrmCommon +from odoo.addons.crm.tests import common as crm_common from odoo.fields import Datetime from odoo.tests.common import tagged, users @tagged('lead_manage') -class TestLeadConvertCommon(TestCrmCommon): +class TestLeadConvert(crm_common.TestLeadConvertCommon): @classmethod def setUpClass(cls): - super(TestLeadConvertCommon, cls).setUpClass() - - cls.sales_team_convert = cls.env['crm.team'].create({ - 'name': 'Convert Sales Team', - 'alias_name': False, - 'use_leads': True, - 'use_opportunities': True, - 'company_id': False, - 'user_id': cls.user_sales_manager.id, - 'member_ids': [(4, cls.user_sales_salesman.id)], - }) - cls.lead_1.write({'date_open': Datetime.from_string('2020-01-15 11:30:00')}) - - cls.crm_lead_dt_patcher = patch('odoo.addons.crm.models.crm_lead.fields.Datetime', wraps=Datetime) - cls.crm_lead_dt_mock = cls.crm_lead_dt_patcher.start() - - @classmethod - def tearDownClass(cls): - cls.crm_lead_dt_patcher.stop() - super(TestLeadConvertCommon, cls).tearDownClass() - - def create_duplicates(self): - self.lead_1_dup1 = self.env['crm.lead'].create({ - 'name': 'Duplicate1', - 'type': 'lead', - 'user_id': False, - 'team_id': self.lead_1.team_id.id, - 'contact_name': 'Amy Wong Duplicate', - 'email_from': self.lead_1.email_from, - }) - self.lead_1_dup2 = self.env['crm.lead'].create({ - 'name': 'Duplicate2', - 'type': 'lead', - 'user_id': False, - 'team_id': self.lead_1.team_id.id, - 'contact_name': 'Amy Wong Duplicate Two', - 'email_from': self.lead_1.email_from, - }) - - -class TestLeadConvert(TestLeadConvertCommon): + super(TestLeadConvert, cls).setUpClass() + date = Datetime.from_string('2020-01-20 16:00:00') + cls.crm_lead_dt_mock.now.return_value = date @users('user_sales_manager') - def test_lead_convert_convert(self): - date = Datetime.from_string('2020-01-20 16:00:00') - self.crm_lead_dt_mock.now.return_value = date + def test_lead_convert_base(self): + """ Test base method ``convert_opportunity`` or crm.lead model """ + lead = self.lead_1.with_user(self.env.user) + lead.write({ + 'phone': '123456789', + }) + self.assertEqual(lead.team_id, self.sales_team_1) + self.assertEqual(lead.stage_id, self.stage_team1_1) + self.assertEqual(lead.email_from, 'amy.wong@test.example.com') + lead.convert_opportunity(self.contact_2.id) + self.assertEqual(lead.type, 'opportunity') + self.assertEqual(lead.partner_id, self.contact_2) + self.assertEqual(lead.email_from, self.contact_2.email) + self.assertEqual(lead.mobile, self.contact_2.mobile) + self.assertEqual(lead.phone, '123456789') + self.assertEqual(lead.team_id, self.sales_team_1) + self.assertEqual(lead.stage_id, self.stage_team1_1) + + @users('user_sales_manager') + def test_lead_convert_base_corner_cases(self): + """ Test base method ``convert_opportunity`` or crm.lead model with corner + cases: inactive, won, stage update, ... """ + # inactive leads are not converted + lead = self.lead_1.with_user(self.env.user) + lead.action_archive() + self.assertFalse(lead.active) + lead.convert_opportunity(self.contact_2.id) + + self.assertEqual(lead.type, 'lead') + self.assertEqual(lead.partner_id, self.env['res.partner']) + + lead.action_unarchive() + self.assertTrue(lead.active) + + # won leads are not converted + lead.action_set_won() + # TDE FIXME: set won does not take into account sales team when fetching a won stage + # self.assertEqual(lead.stage_id, self.stage_team1_won) + self.assertEqual(lead.stage_id, self.stage_gen_won) + self.assertEqual(lead.probability, 100) + + lead.convert_opportunity(self.contact_2.id) + self.assertEqual(lead.type, 'lead') + self.assertEqual(lead.partner_id, self.env['res.partner']) + + @users('user_sales_manager') + def test_lead_convert_base_w_salesmen(self): + """ Test base method ``convert_opportunity`` while forcing salesmen, as it + should also force sales team """ + lead = self.lead_1.with_user(self.env.user) + self.assertEqual(lead.team_id, self.sales_team_1) + lead.convert_opportunity(False, user_ids=self.user_sales_salesman.ids) + self.assertEqual(lead.user_id, self.user_sales_salesman) + self.assertEqual(lead.team_id, self.sales_team_convert) + # TDE FIXME: convert does not recompute stage based on updated team of assigned user + # self.assertEqual(lead.stage_id, self.stage_team_convert_1) + + @users('user_sales_manager') + def test_lead_convert_base_w_team(self): + """ Test base method ``convert_opportunity`` while forcing team """ + lead = self.lead_1.with_user(self.env.user) + lead.convert_opportunity(False, team_id=self.sales_team_convert.id) + self.assertEqual(lead.team_id, self.sales_team_convert) + self.assertEqual(lead.user_id, self.user_sales_leads) + # TDE FIXME: convert does not recompute stage based on team + # self.assertEqual(lead.stage_id, self.stage_team_convert_1) + + @users('user_sales_manager') + def test_lead_convert_internals(self): + """ Test internals of convert wizard """ + # ensure initial data to avoid spaghetti test update afterwards self.assertFalse(self.lead_1.date_conversion) self.assertEqual(self.lead_1.date_open, Datetime.from_string('2020-01-15 11:30:00')) + self.assertEqual(self.lead_1.user_id, self.user_sales_leads) + self.assertEqual(self.lead_1.team_id, self.sales_team_1) + self.assertEqual(self.lead_1.stage_id, self.stage_team1_1) convert = self.env['crm.lead2opportunity.partner'].with_context({ 'active_model': 'crm.lead', @@ -83,16 +114,57 @@ class TestLeadConvert(TestLeadConvertCommon): self.assertEqual(convert.team_id, self.sales_team_convert) convert.action_apply() + # convert test self.assertEqual(self.lead_1.type, 'opportunity') + self.assertEqual(self.lead_1.user_id, self.user_sales_salesman) + self.assertEqual(self.lead_1.team_id, self.sales_team_convert) + # TDE FIXME: stage is linked to the old sales team and is not updated when converting, could be improved + # self.assertEqual(self.lead_1.stage_id, self.stage_gen_1) + # partner creation test + new_partner = self.lead_1.partner_id + self.assertEqual(new_partner.name, 'Amy Wong') + self.assertEqual(new_partner.email, 'amy.wong@test.example.com') @users('user_sales_manager') - def test_lead_convert_merge(self): - self.create_duplicates() + def test_lead_convert_action_exist(self): + """ Test specific use case of 'exist' action in conver wizard """ + self.lead_1.write({'partner_id': self.contact_1.id}) + + convert = self.env['crm.lead2opportunity.partner'].with_context({ + 'active_model': 'crm.lead', + 'active_id': self.lead_1.id, + 'active_ids': self.lead_1.ids, + }).create({}) + self.assertEqual(convert.action, 'exist') + convert.action_apply() + self.assertEqual(self.lead_1.type, 'opportunity') + self.assertEqual(self.lead_1.partner_id, self.contact_1) + + @users('user_sales_manager') + def test_lead_convert_action_nothing(self): + """ Test specific use case of 'nothing' action in conver wizard """ + self.lead_1.write({'contact_name': False}) + + convert = self.env['crm.lead2opportunity.partner'].with_context({ + 'active_model': 'crm.lead', + 'active_id': self.lead_1.id, + 'active_ids': self.lead_1.ids, + }).create({}) + self.assertEqual(convert.action, 'nothing') + convert.action_apply() + self.assertEqual(self.lead_1.type, 'opportunity') + self.assertEqual(self.lead_1.user_id, self.user_sales_leads) + self.assertEqual(self.lead_1.team_id, self.sales_team_1) + self.assertEqual(self.lead_1.stage_id, self.stage_team1_1) + self.assertEqual(self.lead_1.partner_id, self.env['res.partner']) + + @users('user_sales_manager') + def test_lead_merge(self): + """ Test convert wizard working in merge mode """ date = Datetime.from_string('2020-01-20 16:00:00') self.crm_lead_dt_mock.now.return_value = date - self.assertFalse(self.lead_1.date_conversion) - self.assertEqual(self.lead_1.date_open, Datetime.from_string('2020-01-15 11:30:00')) + leads = self._create_duplicates(self.lead_1) convert = self.env['crm.lead2opportunity.partner'].with_context({ 'active_model': 'crm.lead', @@ -101,7 +173,7 @@ class TestLeadConvert(TestLeadConvertCommon): }).create({}) # test internals of convert wizard - self.assertEqual(convert.opportunity_ids, self.lead_1 | self.lead_1_dup1 | self.lead_1_dup2) + self.assertEqual(convert.opportunity_ids, self.lead_1 | leads) self.assertEqual(convert.user_id, self.lead_1.user_id) self.assertEqual(convert.team_id, self.lead_1.team_id) self.assertFalse(convert.partner_id) @@ -116,171 +188,159 @@ class TestLeadConvert(TestLeadConvertCommon): convert.action_apply() self.assertEqual(self.lead_1.type, 'opportunity') + +@tagged('lead_manage') +class TestLeadConvertBatch(crm_common.TestLeadConvertMassCommon): + @users('user_sales_manager') - def test_lead_convert_various(self): - self.lead_1.write({'contact_name': False}) + def test_lead_convert_batch_internals(self): + """ Test internals of convert wizard, working in batch mode """ + date = Datetime.from_string('2020-01-20 16:00:00') + self.crm_lead_dt_mock.now.return_value = date + + lead_w_partner = self.lead_w_partner + self.assertEqual(lead_w_partner.user_id, self.user_sales_manager) + self.assertEqual(lead_w_partner.team_id, self.sales_team_1) + self.assertEqual(lead_w_partner.stage_id, self.env['crm.stage']) + lead_w_contact = self.lead_w_contact + self.assertEqual(lead_w_contact.user_id, self.user_sales_salesman) + self.assertEqual(lead_w_contact.team_id, self.sales_team_convert) + self.assertEqual(lead_w_contact.stage_id, self.stage_gen_1) + lead_w_email_lost = self.lead_w_email_lost + self.assertEqual(lead_w_email_lost.user_id, self.user_sales_leads) + self.assertEqual(lead_w_email_lost.team_id, self.sales_team_1) + self.assertEqual(lead_w_email_lost.stage_id, self.stage_team1_2) + lead_w_email_lost.action_set_lost() + self.assertEqual(lead_w_email_lost.active, False) convert = self.env['crm.lead2opportunity.partner'].with_context({ 'active_model': 'crm.lead', 'active_id': self.lead_1.id, + 'active_ids': (self.lead_1 | lead_w_partner | lead_w_contact | lead_w_email_lost).ids, }).create({}) - self.assertEqual(convert.action, 'nothing') - self.lead_1.write({'partner_id': self.contact_1.id}) + # test internals of convert wizard + # self.assertEqual(convert.lead_id, self.lead_1) + self.assertEqual(convert.user_id, self.lead_1.user_id) + self.assertEqual(convert.team_id, self.lead_1.team_id) + self.assertFalse(convert.partner_id) + self.assertEqual(convert.name, 'convert') + self.assertEqual(convert.action, 'create') - convert = self.env['crm.lead2opportunity.partner'].with_context({ + convert.action_apply() + self.assertEqual(convert.user_id, self.user_sales_leads) + self.assertEqual(convert.team_id, self.sales_team_1) + # lost leads are not converted (see crm_lead.convert_opportunity()) + self.assertFalse(lead_w_email_lost.active) + self.assertFalse(lead_w_email_lost.date_conversion) + self.assertEqual(lead_w_email_lost.partner_id, self.env['res.partner']) + self.assertEqual(lead_w_email_lost.stage_id, self.stage_team1_2) # did not change + # other leads are converted into opportunities + for opp in (self.lead_1 | lead_w_partner | lead_w_contact): + # team management update: opportunity linked to chosen wizard values + self.assertEqual(opp.type, 'opportunity') + self.assertTrue(opp.active) + self.assertEqual(opp.user_id, convert.user_id) + self.assertEqual(opp.team_id, convert.team_id) + # dates update: convert set them to now + self.assertEqual(opp.date_open, date) + self.assertEqual(opp.date_conversion, date) + # stage update (depends on previous value) + if opp == self.lead_1: + self.assertEqual(opp.stage_id, self.stage_team1_1) # did not change + elif opp == lead_w_partner: + self.assertEqual(opp.stage_id, self.stage_team1_1) # is set to default stage of sales_team_1 + elif opp == lead_w_contact: + self.assertEqual(opp.stage_id, self.stage_gen_1) # did not change + else: + self.assertFalse(True) + + +@tagged('lead_manage') +class TestLeadConvertMass(crm_common.TestLeadConvertMassCommon): + + @classmethod + def setUpClass(cls): + super(TestLeadConvertMass, cls).setUpClass() + + cls.leads = cls.lead_1 + cls.lead_w_partner + cls.lead_w_email_lost + # reset some assigned users to test salesmen assign + (cls.lead_w_partner | cls.lead_w_email_lost).write({ + 'user_id': False + }) + + cls.assign_users = cls.user_sales_manager + cls.user_sales_leads_convert + cls.user_sales_salesman + + @users('user_sales_manager') + def test_mass_convert_internals(self): + """ Test internals mass converted in convert mode, without duplicate management """ + leads = self.leads + + mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({ 'active_model': 'crm.lead', - 'active_id': self.lead_1.id, - }).create({}) - self.assertEqual(convert.action, 'exist') - - -class TestLeadConvertMass(TestLeadConvertCommon): - - def test_lead2opportunity2win(self): - """ Tests for Test Lead 2 opportunity 2 win """ - default_stage_id = self.stage_gen_1.id - - crm_case_2 = self.env['crm.lead'].create({ - 'name': 'Design Software', - 'type': 'lead', - }) - crm_case_3 = self.env['crm.lead'].create({ - 'name': 'Pricing for 25 desks', - 'type': 'lead', - }) - crm_case_13 = self.env['crm.lead'].create({ - 'name': 'Quote for 600 Chairs', - 'type': 'opportunity', - 'contact_name': 'Will McEncroe', - }) - - # In order to test the conversion of a lead into a opportunity, - # I set lead to open stage. - crm_case_3.write({'stage_id': default_stage_id}) - - # I check if the lead stage is "Open". - # self.assertEqual(crm_case_3.stage_id.sequence, 1, 'Lead stage is Open') - - # Giving access rights of salesman to convert the lead into opportunity. - # I convert lead into opportunity for exiting customer. - crm_case_3.with_user(self.user_sales_manager).convert_opportunity(self.contact_2.id) - - # I check details of converted opportunity. - self.assertEqual(crm_case_3.type, 'opportunity', 'Lead is not converted to opportunity!') - self.assertEqual(crm_case_3.partner_id.id, self.contact_2.id, 'Partner mismatch!') - self.assertEqual(crm_case_3.stage_id.id, default_stage_id, 'Stage of opportunity is incorrect!') - - # I convert mass lead into opportunity customer. - mass = self.env['crm.lead2opportunity.partner.mass'].with_user(self.user_sales_manager).with_context({ - 'active_model': 'crm.lead', - 'active_ids': [crm_case_13.id, crm_case_2.id], - 'active_id': crm_case_13.id} - ).create({ - 'user_ids': [(6, 0, self.env.ref('base.user_root').ids)], - 'team_id': self.env.ref("sales_team.team_sales_department").id - }) - mass.with_user(self.user_sales_manager).mass_convert() - - # Now I check first lead converted on opportunity. - self.assertEqual(crm_case_13.name, "Quote for 600 Chairs", "Opportunity name not correct") - self.assertEqual(crm_case_13.type, 'opportunity', "Lead is not converted to opportunity!") - expected_partner = "Will McEncroe" - self.assertEqual(crm_case_13.partner_id.name, expected_partner, "Partner mismatch! %s vs %s" % (crm_case_13.partner_id.name, expected_partner)) - self.assertEqual(crm_case_13.stage_id.id, default_stage_id, "Stage of probability is incorrect!") - - # Then check for second lead converted on opportunity. - self.assertEqual(crm_case_2.name, "Design Software", "Opportunity name not correct") - self.assertEqual(crm_case_2.type, "opportunity", "Lead is not converted to opportunity!") - self.assertEqual(crm_case_2.stage_id.id, default_stage_id, "Stage of probability is incorrect!") - - # I loose the second opportunity - crm_case_2.action_set_lost() - - # I check details of the opportunity after the loose - self.assertEqual(crm_case_2.probability, 0.0, "Revenue probability should be 0.0!") - - def test_lead2opportunity_assign_salesmen(self): - """ Tests for Test Lead2opportunity Assign Salesmen """ - LeadSaleman = self.env['crm.lead'].with_user(self.user_sales_manager) - default_stage_id = self.stage_gen_1.id - - # During a lead to opp conversion, salesmen should be assigned to leads following the round-robin method. Start by creating 4 salesmen (A to D) and 6 leads (1 to 6). - test_res_user_01 = self.env['res.users'].create({ - 'name': 'Test user A', - 'login': 'tua@example.com', - }) - test_res_user_02 = self.env['res.users'].create({ - 'name': 'Test user B', - 'login': 'tub@example.com', - }) - test_res_user_03 = self.env['res.users'].create({ - 'name': 'Test user C', - 'login': 'tuc@example.com', - }) - test_res_user_04 = self.env['res.users'].create({ - 'name': 'Test user D', - 'login': 'tud@example.com', - }) - - # Salesman also creates lead so giving access rights of salesman. - test_crm_lead_01 = LeadSaleman.create({ - 'type': 'lead', - 'name': 'Test lead 1', - 'email_from': 'Raoul Grosbedon ', - 'stage_id': default_stage_id - }) - test_crm_lead_02 = LeadSaleman.create({ - 'type': 'lead', - 'name': 'Test lead 2', - 'email_from': 'Raoul Grosbedon ', - 'stage_id': default_stage_id - }) - test_crm_lead_03 = LeadSaleman.create({ - 'type': 'lead', - 'name': 'Test lead 3', - 'email_from': 'Raoul Grosbedon ', - 'stage_id': default_stage_id - }) - test_crm_lead_04 = LeadSaleman.create({ - 'type': 'lead', - 'name': 'Test lead 4', - 'email_from': 'Fabrice Lepoilu', - 'stage_id': default_stage_id - }) - test_crm_lead_05 = LeadSaleman.create({ - 'type': 'lead', - 'name': 'Test lead 5', - 'email_from': 'Fabrice Lepoilu', - 'stage_id': default_stage_id - }) - test_crm_lead_06 = LeadSaleman.create({ - 'type': 'lead', - 'name': 'Test lead 6', - 'email_from': 'Agrolait SuperSeed SA', - 'stage_id': default_stage_id - }) - - lead_ids = [test_crm_lead_01.id, test_crm_lead_02.id, test_crm_lead_03.id, test_crm_lead_04.id, test_crm_lead_05.id, test_crm_lead_06.id] - salesmen_ids = [test_res_user_01.id, test_res_user_02.id, test_res_user_03.id, test_res_user_04.id] - - # Salesman create a mass convert wizard and convert all the leads. - mass = self.env['crm.lead2opportunity.partner.mass'].with_user(self.user_sales_manager).with_context({ - 'active_model': 'crm.lead', - 'active_ids': lead_ids, - 'active_id': test_crm_lead_01.id} - ).create({ - 'user_ids': [(6, 0, salesmen_ids)], - 'team_id': self.env.ref("sales_team.team_sales_department").id, + 'active_ids': leads.ids, + 'active_id': leads.ids[0] + }).create({ 'deduplicate': False, - 'force_assignation': True + 'user_id': self.user_sales_salesman.id, + 'force_assignation': False, }) - mass.with_user(self.user_sales_manager).mass_convert() + mass_convert.onchange_action() + mass_convert._onchange_user() - # The leads should now be opps with a salesman and a salesteam. Also, salesmen should have been assigned following a round-robin method. - opps = self.env['crm.lead'].with_user(self.user_sales_manager).browse(lead_ids) - i = 0 - for opp in opps: - self.assertEqual(opp.type, 'opportunity', 'Type mismatch: this should be an opp, not a lead') - self.assertEqual(opp.user_id.id, salesmen_ids[i], 'Salesman mismatch: expected salesman %r, got %r' % (salesmen_ids[i], opp.user_id.id)) - i = i + 1 if (i < len(salesmen_ids) - 1) else 0 + # default values + self.assertEqual(mass_convert.name, 'convert') + self.assertEqual(mass_convert.action, 'each_exist_or_create') + # depending on options + self.assertEqual(mass_convert.partner_id, self.env['res.partner']) + self.assertEqual(mass_convert.deduplicate, False) + self.assertEqual(mass_convert.user_id, self.user_sales_salesman) + self.assertEqual(mass_convert.team_id, self.sales_team_convert) + + mass_convert.mass_convert() + for lead in self.lead_1 | self.lead_w_partner: + self.assertEqual(lead.type, 'opportunity') + if lead == self.lead_w_partner: + self.assertEqual(lead.user_id, self.env['res.users']) # user_id is bypassed + self.assertEqual(lead.partner_id, self.contact_1) + elif lead == self.lead_1: + self.assertEqual(lead.user_id, self.user_sales_leads) # existing value not forced + new_partner = lead.partner_id + self.assertEqual(new_partner.name, 'Amy Wong') + self.assertEqual(new_partner.email, 'amy.wong@test.example.com') + + # test unforced assignation + mass_convert.write({ + 'user_ids': self.user_sales_salesman.ids, + }) + mass_convert.mass_convert() + self.assertEqual(self.lead_w_partner.user_id, self.user_sales_salesman) + self.assertEqual(self.lead_1.user_id, self.user_sales_leads) # existing value not forced + + # lost leads are untouched + self.assertEqual(self.lead_w_email_lost.type, 'lead') + self.assertFalse(self.lead_w_email_lost.active) + self.assertFalse(self.lead_w_email_lost.date_conversion) + # TDE FIXME: partner creation is done even on lost leads because not checked in wizard + # self.assertEqual(self.lead_w_email_lost.partner_id, self.env['res.partner']) + + def test_mass_convert_w_salesmen(self): + leads = self.leads + + mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({ + 'active_model': 'crm.lead', + 'active_ids': leads.ids, + 'active_id': leads.ids[0] + }).create({ + 'deduplicate': False, + 'user_ids': self.assign_users.ids, + 'force_assignation': True, + }) + + # TDE FIXME: what happens if we mix people from different sales team ? currently nothing, to check + mass_convert.mass_convert() + + for idx, lead in enumerate(self.leads - self.lead_w_email_lost): + self.assertEqual(lead.type, 'opportunity') + assigned_user = self.assign_users[idx % len(self.assign_users)] + self.assertEqual(lead.user_id, assigned_user)