# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

import random

from ast import literal_eval
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from unittest.mock import patch

from odoo import fields
from odoo.addons.crm.tests.common import TestLeadConvertCommon
from odoo.tests.common import tagged
from odoo.tools import mute_logger
from odoo.fields import Datetime


class TestLeadAssignCommon(TestLeadConvertCommon):

    @classmethod
    def setUpClass(cls):
        super(TestLeadAssignCommon, cls).setUpClass()
        cls._switch_to_multi_membership()
        cls._switch_to_auto_assign()

        # don't mess with existing teams, deactivate them to make tests repeatable
        cls.sales_teams = cls.sales_team_1 + cls.sales_team_convert
        cls.members = cls.sales_team_1_m1 + cls.sales_team_1_m2 + cls.sales_team_1_m3 + cls.sales_team_convert_m1 + cls.sales_team_convert_m2
        cls.env['crm.team'].search([('id', 'not in', cls.sales_teams.ids)]).write({'active': False})

        # don't mess with existing leads, unlink those assigned to users used here to make tests
        # repeatable (archive is not sufficient because of lost leads)

        with mute_logger('odoo.models.unlink'):
            cls.env['crm.lead'].with_context(active_test=False).search(['|', ('team_id', '=', False), ('user_id', 'in', cls.sales_teams.member_ids.ids)]).unlink()
        cls.bundle_size = 50
        cls.env['ir.config_parameter'].set_param('crm.assignment.commit.bundle', '%s' % cls.bundle_size)
        cls.env['ir.config_parameter'].set_param('crm.assignment.delay', '0')

    def assertInitialData(self):
        self.assertEqual(self.sales_team_1.assignment_max, 75)
        self.assertEqual(self.sales_team_convert.assignment_max, 90)

        # ensure domains
        self.assertEqual(self.sales_team_1.assignment_domain, False)
        self.assertEqual(self.sales_team_1_m1.assignment_domain, False)
        self.assertEqual(self.sales_team_1_m2.assignment_domain, "[('probability', '>=', 10)]")
        self.assertEqual(self.sales_team_1_m3.assignment_domain, "[('probability', '>=', 20)]")

        self.assertEqual(self.sales_team_convert.assignment_domain, "[('priority', 'in', ['1', '2', '3'])]")
        self.assertEqual(self.sales_team_convert_m1.assignment_domain, "[('probability', '>=', 20)]")
        self.assertEqual(self.sales_team_convert_m2.assignment_domain, False)

        # start afresh
        self.assertEqual(self.sales_team_1_m1.lead_month_count, 0)
        self.assertEqual(self.sales_team_1_m2.lead_month_count, 0)
        self.assertEqual(self.sales_team_1_m3.lead_month_count, 0)
        self.assertEqual(self.sales_team_convert_m1.lead_month_count, 0)
        self.assertEqual(self.sales_team_convert_m2.lead_month_count, 0)


@tagged('lead_assign')
class TestLeadAssign(TestLeadAssignCommon):
    """ Test lead assignment feature added in saas-14.2 """

    def test_assign_configuration(self):
        now_patch = datetime(2020, 11, 2, 10, 0, 0)

        with patch.object(fields.Datetime, 'now', return_value=now_patch):
            config = self.env['res.config.settings'].create({
                'crm_use_auto_assignment': True,
                'crm_auto_assignment_action': 'auto',
                'crm_auto_assignment_interval_number': 19,
                'crm_auto_assignment_interval_type': 'hours'
            })
            config._onchange_crm_auto_assignment_run_datetime()
            config.execute()
            self.assertTrue(self.assign_cron.active)
            self.assertEqual(self.assign_cron.nextcall, datetime(2020, 11, 2, 10, 0, 0) + relativedelta(hours=19))

            config.write({
                'crm_auto_assignment_interval_number': 2,
                'crm_auto_assignment_interval_type': 'days'
            })
            config._onchange_crm_auto_assignment_run_datetime()
            config.execute()
            self.assertTrue(self.assign_cron.active)
            self.assertEqual(self.assign_cron.nextcall, datetime(2020, 11, 2, 10, 0, 0) + relativedelta(days=2))

            config.write({
                'crm_auto_assignment_run_datetime': fields.Datetime.to_string(datetime(2020, 11, 1, 10, 0, 0)),
            })
            config.execute()
            self.assertTrue(self.assign_cron.active)
            self.assertEqual(self.assign_cron.nextcall, datetime(2020, 11, 1, 10, 0, 0))

            config.write({
                'crm_auto_assignment_action': 'manual',
            })
            config.execute()
            self.assertFalse(self.assign_cron.active)
            self.assertEqual(self.assign_cron.nextcall, datetime(2020, 11, 1, 10, 0, 0))

            config.write({
                'crm_use_auto_assignment': False,
                'crm_auto_assignment_action': 'auto',
            })
            config.execute()
            self.assertFalse(self.assign_cron.active)
            self.assertEqual(self.assign_cron.nextcall, datetime(2020, 11, 1, 10, 0, 0))

    def test_assign_count(self):
        """ Test number of assigned leads when dealing with some existing data (leads
        or opportunities) as well as with opt-out management. """
        leads = self._create_leads_batch(
            lead_type='lead',
            user_ids=[False],
            partner_ids=[False, False, False, self.contact_1.id],
            probabilities=[30],
            count=8,
            suffix='Initial',
        )
        # commit probability and related fields
        leads.flush_recordset()
        self.assertInitialData()

        # archived members should not be taken into account
        self.sales_team_1_m1.action_archive()
        # assignment_max = 0 means opt_out
        self.sales_team_1_m2.assignment_max = 0

        # 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, lead in enumerate(leads):
            lead.probability = idx * 10
        # commit probability and related fields
        leads.flush_recordset()
        self.assertEqual(leads[0].probability, 0)

        # create exiting leads for user_sales_salesman (sales_team_1_m3, sales_team_convert_m1)
        existing_leads = self._create_leads_batch(
            lead_type='lead', user_ids=[self.user_sales_salesman.id],
            probabilities=[10],
            count=14,
            suffix='Existing')
        self.assertEqual(existing_leads.team_id, self.sales_team_1, "Team should have lower sequence")
        existing_leads[0].action_set_lost()  # lost
        existing_leads[1].probability = 100  # not won as stage is not won.
        existing_leads[2].probability = 0  # not lost as active
        existing_leads.flush_recordset()

        self.members.invalidate_model(['lead_month_count'])
        self.assertEqual(self.sales_team_1_m3.lead_month_count, 14)
        self.assertEqual(self.sales_team_convert_m1.lead_month_count, 0)

        # re-assign existing leads, check monthly count is updated
        existing_leads[-2:]._handle_salesmen_assignment(user_ids=self.user_sales_manager.ids)
        # commit probability and related fields
        leads.flush_recordset()
        self.members.invalidate_model(['lead_month_count'])
        self.assertEqual(self.sales_team_1_m3.lead_month_count, 12)

        # sales_team_1_m2 is opt-out (new field in 14.3) -> even with max, no lead assigned
        self.sales_team_1_m2.update({'assignment_max': 45, 'assignment_optout': True})
        self.sales_team_1_m3.update({'assignment_max': 45})
        with self.with_user('user_sales_manager'):
            teams_data, members_data = self.sales_team_1._action_assign_leads(force_quota=True)

        Leads = self.env['crm.lead']

        self.assertEqual(
            sorted(Leads.browse(teams_data[self.sales_team_1]['assigned']).mapped('name')),
            ['TestLeadInitial_0000', 'TestLeadInitial_0001', 'TestLeadInitial_0002',
             'TestLeadInitial_0004', 'TestLeadInitial_0005', 'TestLeadInitial_0006']
        )
        self.assertEqual(
            Leads.browse(teams_data[self.sales_team_1]['merged']).mapped('name'),
            ['TestLeadInitial_0003']
        )

        # TestLeadInitial_0007 has same partner as TestLeadInitial_0003
        self.assertEqual(len(teams_data[self.sales_team_1]['duplicates']), 1)

        # TestLeadInitial_0005 had a 0 auto_proba when its proba was set to 0.
        # Therefore, it is auto_proba. At this point, its proba is 9x.xx %, and it is selected.
        # These are the two leads with the highest probabilities, as they are sorted before assignment.
        self.assertEqual(
            sorted(members_data[self.sales_team_1_m3]['assigned'].mapped('name')),
            ['TestLeadInitial_0000', 'TestLeadInitial_0005']
        )

        # salespersons assign
        self.members.invalidate_model(['lead_month_count'])
        self.assertEqual(self.sales_team_1_m1.lead_month_count, 0)  # archived do not get leads
        self.assertEqual(self.sales_team_1_m2.lead_month_count, 0)  # opt-out through assignment_max = 0
        self.assertEqual(self.sales_team_1_m3.lead_month_count, 14)  # ignore actual quota (round(45/30) => +2) + existing 12

        with self.with_user('user_sales_manager'):
            self.env['crm.team'].browse(self.sales_team_1.ids)._action_assign_leads(force_quota=True)

        # salespersons assign
        self.members.invalidate_model(['lead_month_count'])
        self.assertEqual(self.sales_team_1_m1.lead_month_count, 0)  # archived do not get leads
        self.assertEqual(self.sales_team_1_m2.lead_month_count, 0)  # opt-out through assignment_max = 0
        self.assertEqual(self.sales_team_1_m3.lead_month_count, 16)  # ignore actual quota (round(45/30) => +2) + existing 14 and not capped anymore

    @mute_logger('odoo.models.unlink')
    def test_assign_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()

        with self.with_user('user_sales_manager'):
            self.env['crm.team'].browse(self.sales_teams.ids)._action_assign_leads()

        # teams assign
        leads = self.env['crm.lead'].search([('id', 'in', leads.ids)])  # ensure order
        self.assertEqual(len(leads), 122)
        leads_st1 = leads.filtered_domain([('team_id', '=', self.sales_team_1.id)])
        leads_stc = leads.filtered_domain([('team_id', '=', self.sales_team_convert.id)])

        # check random globally assigned enough leads to team
        self.assertEqual(len(leads_st1), 76)
        self.assertEqual(len(leads_stc), 46)
        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', 'lead_day_count'])
        self.assertMemberAssign(self.sales_team_1_m1, 2)  # 45 max on one month -> 2 daily
        self.assertMemberAssign(self.sales_team_1_m2, 1)  # 15 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_1_m3, 1)  # 15 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_convert_m1, 1)  # 30 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_convert_m2, 2)  # 60 max on one month -> 2 daily

        # teams assign: everything should be done due to duplicates
        leads = self.env['crm.lead'].search([('id', 'in', leads.ids)])  # ensure order
        self.assertEqual(len(leads.filtered_domain([('team_id', '=', False)])), 0)

        # deduplicate should have removed all duplicated linked to contact_1 and contact_2
        new_assigned_leads_wpartner = self.env['crm.lead'].search([
            ('partner_id', 'in', (self.contact_1 | self.contact_2).ids),
            ('id', 'in', leads.ids)
        ])
        self.assertEqual(len(new_assigned_leads_wpartner), 2)

    @mute_logger('odoo.models.unlink')
    def test_assign_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=150
        )
        # 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()

        with self.with_user('user_sales_manager'):
            self.env['crm.team'].browse(self.sales_teams.ids)._action_assign_leads()

        # 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), 150)

        # check random globally assigned enough leads to team
        self.assertEqual(len(leads_st1), 104)
        self.assertEqual(len(leads_stc), 46)
        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', 'lead_day_count'])
        self.assertMemberAssign(self.sales_team_1_m1, 2)  # 45 max on one month -> 2 daily
        self.assertMemberAssign(self.sales_team_1_m2, 1)  # 15 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_1_m3, 1)  # 15 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_convert_m1, 1)  # 30 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_convert_m2, 2)  # 60 max on one month -> 2 daily

    @mute_logger('odoo.models.unlink')
    def test_assign_populated(self):
        """ Test assignment on a more high volume oriented test set in order to
        test more real life use cases. """
        # fix the seed and avoid randomness
        random.seed(1871)

        # create leads enough to assign one month of work
        _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()

        with self.with_user('user_sales_manager'):
            self.env['crm.team'].browse(sales_teams.ids)._action_assign_leads()

        # 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)
        self.assertEqual(len(leads), 600)

        # check random globally assigned enough leads to team
        leads_st1 = leads.filtered_domain([('team_id', '=', self.sales_team_1.id)])
        leads_st2 = leads.filtered_domain([('team_id', '=', self.sales_team_convert.id)])
        leads_st3 = leads.filtered_domain([('team_id', '=', sales_team_3.id)])
        self.assertEqual(len(leads_st1), 170)
        self.assertEqual(len(leads_st2), 116)
        self.assertEqual(len(leads_st3), 314)

        # salespersons assign
        self.members.invalidate_model(['lead_month_count', 'lead_day_count'])
        self.assertMemberAssign(self.sales_team_1_m1, 2)  # 45 max on one month -> 2 daily
        self.assertMemberAssign(self.sales_team_1_m2, 1)  # 15 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_1_m3, 1)  # 15 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_convert_m1, 1)  # 30 max on one month -> 1 daily
        self.assertMemberAssign(self.sales_team_convert_m2, 2)  # 60 max on one month -> 2 daily
        self.assertMemberAssign(sales_team_3_m1, 2)  # 60 max on one month -> 2 daily
        self.assertMemberAssign(sales_team_3_m2, 2)  # 60 max on one month -> 2 daily
        self.assertMemberAssign(sales_team_3_m3, 1)  # 15 max on one month -> 1 daily

    def test_assign_preferred_domain(self):
        """ Test preferred domain use """
        random.seed(1914)
        preferred_tag = self.env['crm.tag'].create({'name': 'preferred'})

        leads = self._create_leads_batch(
            lead_type='lead',
            user_ids=[False],
            count=11,
        )
        leads[:8].write({'tag_ids': [(6, 0, preferred_tag.ids)]})
        # commit probability and related fields
        leads.flush_recordset()
        self.assertInitialData()
        test_sales_team = self.env['crm.team'].create({
            'name': 'Sales Team 5',
            'sequence': 15,
            'alias_name': False,
            'use_leads': True,
            'use_opportunities': True,
            'company_id': False,
            'user_id': False,
        })
        test_sales_team_m1 = self.env['crm.team.member'].create({
            'user_id': self.user_sales_manager.id,
            'crm_team_id': test_sales_team.id,
            'assignment_max': 150,
            'assignment_domain': False,
            'assignment_domain_preferred': "[('tag_ids', 'in', %s)]" % preferred_tag.ids,
        })
        test_sales_team_m2 = self.env['crm.team.member'].create({
            'user_id': self.user_sales_leads.id,
            'crm_team_id': test_sales_team.id,
            'assignment_max': 150,
            'assignment_domain': False,
            'assignment_domain_preferred': False,
        })
        test_sales_team_m3 = self.env['crm.team.member'].create({
            'user_id': self.user_sales_salesman.id,
            'crm_team_id': test_sales_team.id,
            'assignment_max': 150,
            'assignment_domain': False,
            'assignment_domain_preferred': False,
        })

        test_sales_team._action_assign_leads()

        member_leads = self.env['crm.lead'].search([
            ('user_id', '=', test_sales_team_m1.user_id.id),
            ('team_id', '=', test_sales_team_m1.crm_team_id.id),
            ('date_open', '>=', Datetime.now() - timedelta(hours=24)),
        ])
        self.assertEqual(
                member_leads.filtered_domain(literal_eval(test_sales_team_m1.assignment_domain_preferred)),
                member_leads
            )
        self.assertMemberAssign(test_sales_team_m1, 5)
        self.assertMemberAssign(test_sales_team_m2, 3)
        self.assertMemberAssign(test_sales_team_m3, 3)

    def test_assign_quota(self):
        """ Test quota computation """
        self.assertInitialData()

        # quota computation without existing leads
        self.assertEqual(
            self.sales_team_1_m1._get_assignment_quota(),
            2,
            "Assignment quota: 45 max -> 2 daily (round(45/30))"
        )

        # create exiting leads for user_sales_leads (sales_team_1_m1)
        existing_leads = self._create_leads_batch(
            lead_type='lead', user_ids=[self.user_sales_leads.id],
            probabilities=[10],
            count=30)
        self.assertEqual(existing_leads.team_id, self.sales_team_1, "Team should have lower sequence")
        existing_leads.flush_recordset()

        self.sales_team_1_m1.invalidate_model(['lead_month_count', 'lead_day_count'])
        self.assertEqual(self.sales_team_1_m1.lead_month_count, 30)
        self.assertEqual(self.sales_team_1_m1.lead_day_count, 30)

        # quota computation with existing leads
        self.assertEqual(
            self.sales_team_1_m1._get_assignment_quota(),
            -28,
            "Assignment quota: 45 max -> 2 daily ; 30 daily lead already assign -> 2 - 30 -> -28"
        )
        self.assertEqual(
            self.sales_team_1_m1._get_assignment_quota(True),
            2,
            "Assignment quota: 45 max ignoring existing daily lead -> 2"
        )

    def test_assign_specific_won_lost(self):
        """ Test leads taken into account in assign process: won, lost, stage
        configuration. """
        leads = self._create_leads_batch(
            lead_type='lead',
            user_ids=[False],
            partner_ids=[False, False, False, self.contact_1.id],
            probabilities=[30],
            count=6
        )
        leads[0].stage_id = self.stage_gen_won.id  # is won -> should not be taken into account
        leads[1].stage_id = False
        leads[2].update({'stage_id': False, 'probability': 0})
        leads[3].update({'stage_id': False, 'probability': False})
        leads[4].active = False  # is lost -> should not be taken into account
        leads[5].update({'team_id': self.sales_team_convert.id, 'user_id': self.user_sales_manager.id})  # assigned lead should not be re-assigned

        # commit probability and related fields
        leads.flush_recordset()

        self.sales_team_1.crm_team_member_ids.write({'assignment_max': 45})
        with self.with_user('user_sales_manager'):
            self.env['crm.team'].browse(self.sales_team_1.ids)._action_assign_leads()

        self.assertEqual(leads[0].team_id, self.env['crm.team'], 'Won lead should not be assigned')
        self.assertEqual(leads[0].user_id, self.env['res.users'], 'Won lead should not be assigned')
        for lead in leads[1:4]:
            self.assertIn(lead.user_id, self.sales_team_1.member_ids)
            self.assertEqual(lead.team_id, self.sales_team_1)
        self.assertEqual(leads[4].team_id, self.env['crm.team'], 'Lost lead should not be assigned')
        self.assertEqual(leads[4].user_id, self.env['res.users'], 'Lost lead should not be assigned')
        self.assertEqual(leads[5].team_id, self.sales_team_convert, 'Assigned lead should not be reassigned')
        self.assertEqual(leads[5].user_id, self.user_sales_manager, 'Assigned lead should not be reassigned')

    def test_assign_team_and_salesperson_on_duplicate_lead(self):
        """Ensure leads duplicated from an existing lead are assigned correctly."""
        duplicate_lead = self.env['crm.lead'].create({
            'name': 'Test Lead',
            'type': 'opportunity',
            'probability': 15,
            'partner_id': self.contact_1.id,
            'team_id': False,
            'user_id': False,
        }).copy()
        self.assertFalse(duplicate_lead.date_open)

        sales_team = self.sales_team_1
        sales_team.assignment_domain = [('user_id', '=', False)]
        with self.with_user('user_sales_manager'):
            sales_team._action_assign_leads()

        self.assertEqual(duplicate_lead.team_id, sales_team)
        self.assertTrue(duplicate_lead.user_id)

    @mute_logger('odoo.models.unlink')
    def test_merge_assign_keep_master_team(self):
        """ Check existing opportunity keep its team and salesman when merged with a new lead """
        sales_team_dupe = self.env['crm.team'].create({
            'name': 'Sales Team Dupe',
            'sequence': 15,
            'alias_name': False,
            'use_leads': True,
            'use_opportunities': True,
            'company_id': False,
            'user_id': False,
            'assignment_domain': "[]",
        })
        self.env['crm.team.member'].create({
            'user_id': self.user_sales_salesman.id,
            'crm_team_id': sales_team_dupe.id,
            'assignment_max': 10,
            'assignment_domain': "[]",
        })

        master_opp = self.env['crm.lead'].create({
            'name': 'Master',
            'type': 'opportunity',
            'probability': 50,
            'partner_id': self.contact_1.id,
            'team_id': self.sales_team_1.id,
            'user_id': self.user_sales_manager.id,
        })
        dupe_lead = self.env['crm.lead'].create({
            'name': 'Dupe',
            'type': 'lead',
            'email_from': 'Duplicate Email <%s>' % master_opp.email_normalized,
            'probability': 10,
            'team_id': False,
            'user_id': False,
        })

        sales_team_dupe._action_assign_leads()
        self.assertFalse(dupe_lead.exists())
        self.assertEqual(master_opp.team_id, self.sales_team_1, 'Opportunity: should keep its sales team')
        self.assertEqual(master_opp.user_id, self.user_sales_manager, 'Opportunity: should keep its salesman')

    def test_no_assign_if_exceed_max_assign(self):
        """ Test no leads being assigned to any team member if weights list sums to 0"""

        leads = self._create_leads_batch(
            lead_type='lead',
            user_ids=[False],
            count=1
        )

        sales_team_4 = self.env['crm.team'].create({
            'name': 'Sales Team 4',
            'sequence': 15,
            'use_leads': True,
        })
        sales_team_4_m1 = self.env['crm.team.member'].create({
            'user_id': self.user_sales_salesman.id,
            'crm_team_id': sales_team_4.id,
            'assignment_max': 30,
        })

        sales_team_4_m1.lead_month_count = 30
        sales_team_4_m1.lead_day_count = 2
        leads.team_id = sales_team_4.id

        members_data = sales_team_4._assign_and_convert_leads()
        self.assertFalse(members_data,
            "If team member has lead count greater than max assign,then do not assign any more")
