Initial commit: Sale packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:49 +02:00
commit 14e3d26998
6469 changed files with 2479670 additions and 0 deletions

View file

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import common
from . import test_sales_team
from . import test_sales_team_internals
from . import test_sales_team_membership

View file

@ -0,0 +1,143 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import TransactionCase
from odoo.addons.mail.tests.common import mail_new_test_user
from odoo.addons.base.tests.common import DISABLED_MAIL_CONTEXT
class SalesTeamCommon(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env['base'].with_context(**DISABLED_MAIL_CONTEXT).env
cls.group_sale_salesman = cls.env.ref('sales_team.group_sale_salesman')
cls.group_sale_manager = cls.env.ref('sales_team.group_sale_manager')
cls.sale_user = cls.env['res.users'].create({
'name': 'Test Salesman',
'login': 'salesman',
'password': 'salesman',
'email': 'default_user_salesman@example.com',
'signature': '--\nMark',
'notification_type': 'email',
'groups_id': [(6, 0, cls.group_sale_salesman.ids)],
})
cls.sale_manager = cls.env['res.users'].create({
'name': 'Test Sales Manager',
'login': 'salesmanager',
'password': 'salesmanager',
'email': 'default_user_salesmanager@example.com',
'signature': '--\nDamien',
'notification_type': 'email',
'groups_id': [(6, 0, cls.group_sale_manager.ids)],
})
cls.sale_team = cls.env['crm.team'].create({
'name': 'Test Sales Team',
})
# Disable other teams (demo data/existing data)
cls.env['crm.team'].search([
('id', '!=', cls.sale_team.id),
]).action_archive()
class TestSalesCommon(TransactionCase):
@classmethod
def setUpClass(cls):
super(TestSalesCommon, cls).setUpClass()
cls.env['ir.config_parameter'].set_param('sales_team.membership_multi', False)
# Salesmen organization
# ------------------------------------------------------------
# Role: M (team member) R (team manager)
# SALESMAN---------------sales_team_1
# admin------------------M-----------
# user_sales_manager-----R-----------
# user_sales_leads-------M-----------
# user_sales_salesman----/-----------
# Sales teams organization
# ------------------------------------------------------------
# SALESTEAM-----------SEQU-----COMPANY
# sales_team_1--------5--------False
# data----------------9999-----??
cls.company_main = cls.env.user.company_id
cls.user_admin = cls.env.ref('base.user_admin')
cls.user_sales_manager = mail_new_test_user(
cls.env, login='user_sales_manager',
name='Martin Sales Manager', email='crm_manager@test.example.com',
company_id=cls.company_main.id,
notification_type='inbox',
groups='sales_team.group_sale_manager,base.group_partner_manager',
)
cls.user_sales_leads = mail_new_test_user(
cls.env, login='user_sales_leads',
name='Laetitia Sales Leads', email='crm_leads@test.example.com',
company_id=cls.company_main.id,
notification_type='inbox',
groups='sales_team.group_sale_salesman_all_leads,base.group_partner_manager',
)
cls.user_sales_salesman = mail_new_test_user(
cls.env, login='user_sales_salesman',
name='Orteil Sales Own', email='crm_salesman@test.example.com',
company_id=cls.company_main.id,
notification_type='inbox',
groups='sales_team.group_sale_salesman',
)
cls.env['crm.team'].search([]).write({'sequence': 9999})
cls.sales_team_1 = cls.env['crm.team'].create({
'name': 'Test Sales Team',
'sequence': 5,
'company_id': False,
'user_id': cls.user_sales_manager.id,
})
cls.sales_team_1_m1 = cls.env['crm.team.member'].create({
'user_id': cls.user_sales_leads.id,
'crm_team_id': cls.sales_team_1.id,
})
cls.sales_team_1_m2 = cls.env['crm.team.member'].create({
'user_id': cls.user_admin.id,
'crm_team_id': cls.sales_team_1.id,
})
class TestSalesMC(TestSalesCommon):
""" Multi Company / Multi Sales Team environment """
@classmethod
def setUpClass(cls):
""" Teams / Company
* sales_team_1: False
* team_c2: company_2
* team_mc: company_main
"""
super(TestSalesMC, cls).setUpClass()
cls.company_2 = cls.env['res.company'].create({
'name': 'New Test Company',
'email': 'company.2@test.example.com',
'country_id': cls.env.ref('base.fr').id,
})
cls.team_c2 = cls.env['crm.team'].create({
'name': 'C2 Team1',
'sequence': 1,
'user_id': False,
'company_id': cls.company_2.id,
})
cls.team_mc = cls.env['crm.team'].create({
'name': 'MainCompany Team',
'user_id': cls.user_admin.id,
'sequence': 3,
'company_id': cls.company_main.id
})
# admin and sale manager belong to new company also
(cls.user_admin | cls.user_sales_manager).write({
'company_ids': [(4, cls.company_2.id)]
})

View file

@ -0,0 +1,232 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import exceptions
from odoo.tests import tagged, users
from odoo.addons.sales_team.tests.common import SalesTeamCommon, TestSalesCommon, TestSalesMC
class TestDefaultTeam(TestSalesCommon):
"""Tests to check if correct default team is found."""
@classmethod
def setUpClass(cls):
"""Set up data for default team tests."""
super(TestDefaultTeam, cls).setUpClass()
cls.env['ir.config_parameter'].set_param('sales_team.membership_multi', True)
# Salesmen organization
# ------------------------------------------------------------
# Role: M (team member) R (team manager)
# SALESMAN---------------sales_team_1---C2Team1---LowSequ---Team3
# admin------------------M-------------- --------- ---------
# user_sales_manager-----R-------------- --------- ---------R
# user_sales_leads-------M-------------- ---------M---------
# user_sales_salesman----/-------------- --------- ---------
# Sales teams organization
# ------------------------------------------------------------
# SALESTEAM-----------SEQU-----COMPANY
# LowSequence---------0--------False
# C2Team1-------------1--------C2
# Team3---------------3--------Main
# sales_team_1--------5--------False
# data----------------9999-----??
cls.company_2 = cls.env['res.company'].create({
'name': 'New Test Company',
'email': 'company.2@test.example.com',
'country_id': cls.env.ref('base.fr').id,
})
cls.team_c2 = cls.env['crm.team'].create({
'name': 'C2 Team1',
'sequence': 1,
'company_id': cls.company_2.id,
'user_id': False,
})
cls.team_sequence = cls.env['crm.team'].create({
'company_id': False,
'name': 'Team LowSequence',
'member_ids': [(4, cls.user_sales_leads.id)],
'sequence': 0,
'user_id': False,
})
cls.team_responsible = cls.env['crm.team'].create({
'company_id': cls.company_main.id,
'name': 'Team 3',
'user_id': cls.user_sales_manager.id,
'sequence': 3,
})
def test_default_team_fallback(self):
""" Test fallbacks when computing default team without any memberships:
domain, order """
self.sales_team_1.member_ids = [(5,)]
self.team_sequence.member_ids = [(5,)]
(self.sales_team_1 + self.team_sequence).flush_model()
self.assertFalse(self.env['crm.team.member'].search([('user_id', '=', self.user_sales_leads.id)]))
# default is better sequence matching company criterion
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_sequence)
# next one is team_responsible with sequence = 3 (team_c2 is in another company)
self.team_sequence.active = False
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_responsible)
self.user_sales_leads.write({
'company_ids': [(4, self.company_2.id)],
'company_id': self.company_2.id,
})
# multi company: switch company
self.user_sales_leads.write({
'company_id': self.company_2.id,
'company_ids': [(4, self.company_2.id)],
})
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_c2)
def test_default_team_member(self):
""" Test default team choice based on sequence, when having several
possible choices due to membership """
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_sequence)
self.team_sequence.member_ids = [(5,)]
self.team_sequence.flush_model()
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.sales_team_1)
# responsible with lower sequence better than member with higher sequence
self.team_responsible.user_id = self.user_sales_leads.id
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_responsible)
# in case of same sequence: take latest team
self.team_responsible.sequence = self.sales_team_1.sequence
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_responsible)
def test_default_team_wcontext(self):
""" Test default team choice when having a value in context """
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_sequence)
team = self.env['crm.team'].with_context(
default_team_id=self.sales_team_1.id
)._get_default_team_id()
self.assertEqual(
team, self.sales_team_1,
'SalesTeam: default takes over ordering when member / responsible'
)
# remove all memberships
self.sales_team_1.member_ids = [(5,)]
self.team_sequence.member_ids = [(5,)]
(self.sales_team_1 + self.team_sequence).flush_model()
self.assertFalse(self.env['crm.team.member'].search([('user_id', '=', self.user_sales_leads.id)]))
with self.with_user('user_sales_leads'):
team = self.env['crm.team']._get_default_team_id()
self.assertEqual(team, self.team_sequence)
team = self.env['crm.team'].with_context(
default_team_id=self.sales_team_1.id
)._get_default_team_id()
self.assertEqual(
team, self.sales_team_1,
'SalesTeam: default taken into account when no member / responsible'
)
class TestMultiCompany(TestSalesMC):
"""Tests to check multi company management with sales team and their
members. """
@users('user_sales_manager')
def test_team_members(self):
""" Test update of team users involving company check """
team_c2 = self.env['crm.team'].browse(self.team_c2.id)
team_c2.write({'name': 'Manager Update'})
self.assertEqual(team_c2.member_ids, self.env['res.users'])
# can add someone from same company
self.env.user.write({'company_id': self.company_2.id})
team_c2.write({'member_ids': [(4, self.env.user.id)]})
self.assertEqual(team_c2.member_ids, self.env.user)
# cannot add someone from another company
with self.assertRaises(exceptions.UserError):
team_c2.write({'member_ids': [(4, self.user_sales_salesman.id)]})
# reset members, change company
team_c2.write({'member_ids': [(5, 0)], 'company_id': self.company_main.id})
self.assertEqual(team_c2.member_ids, self.env['res.users'])
team_c2.write({'member_ids': [(4, self.user_sales_salesman.id)]})
self.assertEqual(team_c2.member_ids, self.user_sales_salesman)
# cannot change company as it breaks memberships mc check
with self.assertRaises(exceptions.UserError):
team_c2.write({'company_id': self.company_2.id})
@users('user_sales_manager')
def test_team_memberships(self):
""" Test update of team member involving company check """
team_c2 = self.env['crm.team'].browse(self.team_c2.id)
team_c2.write({'name': 'Manager Update'})
self.assertEqual(team_c2.member_ids, self.env['res.users'])
# can add someone from same company
self.env.user.write({'company_id': self.company_2.id})
team_c2.write({'crm_team_member_ids': [(0, 0, {'user_id': self.env.user.id})]})
self.assertEqual(team_c2.member_ids, self.env.user)
# cannot add someone from another company
with self.assertRaises(exceptions.UserError):
team_c2.write({'crm_team_member_ids': [(0, 0, {'user_id': self.user_sales_salesman.id})]})
# reset members, change company
team_c2.write({'member_ids': [(5, 0)], 'company_id': self.company_main.id})
self.assertEqual(team_c2.member_ids, self.env['res.users'])
team_c2.write({'crm_team_member_ids': [(0, 0, {'user_id': self.user_sales_salesman.id})]})
self.assertEqual(team_c2.member_ids, self.user_sales_salesman)
# cannot change company as it breaks memberships mc check
with self.assertRaises(exceptions.UserError):
team_c2.write({'company_id': self.company_2.id})
@tagged('post_install', '-at_install')
class TestAccessRights(SalesTeamCommon):
@users('salesmanager')
def test_access_sales_manager(self):
""" Test sales manager's access rights """
# Manager can create a Sales Team
india_channel = self.env['crm.team'].with_context(tracking_disable=True).create({
'name': 'India',
})
self.assertIn(
india_channel.id, self.env['crm.team'].search([]).ids,
'Sales manager should be able to create a Sales Team')
# Manager can edit a Sales Team
india_channel.write({'name': 'new_india'})
self.assertEqual(
india_channel.name, 'new_india',
'Sales manager should be able to edit a Sales Team')
# Manager can delete a Sales Team
india_channel.unlink()
self.assertNotIn(
india_channel.id, self.env['crm.team'].search([]).ids,
'Sales manager should be able to delete a Sales Team')

View file

@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import exceptions
from odoo.addons.mail.tests.common import mail_new_test_user
from odoo.addons.sales_team.tests.common import TestSalesMC
from odoo.tests.common import users, TransactionCase
from odoo.tools import mute_logger
class TestCornerCases(TransactionCase):
def setUp(self):
super(TestCornerCases, self).setUp()
self.user_sales_leads = mail_new_test_user(
self.env, login='user_sales_leads',
name='Laetitia Sales Leads', email='crm_leads@test.example.com',
company_id=self.env.user.company_id.id,
notification_type='inbox',
groups='sales_team.group_sale_salesman_all_leads,base.group_partner_manager',
)
self.sales_team_1 = self.env['crm.team'].create({
'name': 'Test Sales Team',
'sequence': 5,
'company_id': False,
'user_id': self.env.user.id,
})
def test_unicity(self):
""" Archived memberships should be removed when detecting duplicates.
Creating duplicates should raise unicity constraint.
Note: redoing the data set to avoid clashing with SavepointCase as
we expect a db-level assert """
sales_team_1_m1 = self.env['crm.team.member'].create({
'user_id': self.user_sales_leads.id,
'crm_team_id': self.sales_team_1.id,
})
sales_team_1_m1.write({'active': False})
sales_team_1_m1.flush_recordset()
sales_team_1_m2 = self.env['crm.team.member'].create({
'user_id': self.user_sales_leads.id,
'crm_team_id': self.sales_team_1.id,
})
found = self.env['crm.team.member'].search([
('user_id', '=', self.user_sales_leads.id),
('crm_team_id', '=', self.sales_team_1.id),
])
self.assertEqual(found, sales_team_1_m2)
with self.assertRaises(exceptions.UserError), mute_logger('odoo.sql_db'):
self.env['crm.team.member'].create({
'user_id': self.user_sales_leads.id,
'crm_team_id': self.sales_team_1.id,
})
def test_unicity_multicreate(self):
""" Test constraint works with creating duplicates in the same create
method. """
with self.assertRaises(exceptions.UserError), mute_logger('odoo.sql_db'):
self.env['crm.team.member'].create([
{'user_id': self.user_sales_leads.id, 'crm_team_id': self.sales_team_1.id},
{'user_id': self.user_sales_leads.id, 'crm_team_id': self.sales_team_1.id}
])
class TestSecurity(TestSalesMC):
@users('user_sales_leads')
def test_team_access(self):
sales_team = self.sales_team_1.with_user(self.env.user)
sales_team.read(['name'])
for member in sales_team.member_ids:
member.read(['name'])
with self.assertRaises(exceptions.AccessError):
sales_team.write({'name': 'Trolling'})
for membership in sales_team.crm_team_member_ids:
membership.read(['name'])
with self.assertRaises(exceptions.AccessError):
membership.write({'active': False})
with self.assertRaises(exceptions.AccessError):
sales_team.write({'member_ids': [(5, 0)]})
@users('user_sales_leads')
def test_team_multi_company(self):
self.sales_team_1.with_user(self.env.user).read(['name'])
with self.assertRaises(exceptions.AccessError):
self.team_c2.with_user(self.env.user).read(['name'])

View file

@ -0,0 +1,322 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import exceptions
from odoo.addons.sales_team.tests.common import TestSalesCommon
from odoo.tests.common import users
from odoo.tools import mute_logger
class TestMembership(TestSalesCommon):
"""Tests to ensure membership behavior """
@classmethod
def setUpClass(cls):
super(TestMembership, cls).setUpClass()
cls.new_team = cls.env['crm.team'].create({
'name': 'Test Specific',
'sequence': 10,
})
cls.env['ir.config_parameter'].set_param('sales_team.membership_multi', True)
@users('user_sales_manager')
def test_fields(self):
self.assertTrue(self.sales_team_1.with_user(self.env.user).is_membership_multi)
self.assertTrue(self.new_team.with_user(self.env.user).is_membership_multi)
self.env['ir.config_parameter'].sudo().set_param('sales_team.membership_multi', False)
self.assertFalse(self.sales_team_1.with_user(self.env.user).is_membership_multi)
self.assertFalse(self.new_team.with_user(self.env.user).is_membership_multi)
@users('user_sales_manager')
def test_members_mono(self):
""" Test mono mode using the user m2m relationship """
self.env['ir.config_parameter'].sudo().set_param('sales_team.membership_multi', False)
# ensure initial data
sales_team_1 = self.sales_team_1.with_user(self.env.user)
new_team = self.new_team.with_user(self.env.user)
self.assertEqual(sales_team_1.member_ids, self.user_sales_leads | self.user_admin)
# test various add / remove on computed m2m
self.assertEqual(new_team.member_ids, self.env['res.users'])
new_team.write({'member_ids': [(4, self.env.uid)]})
self.assertEqual(new_team.member_ids, self.env.user)
new_team.write({'member_ids': [(4, self.user_sales_leads.id)]})
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
new_team.write({'member_ids': [(3, self.user_sales_leads.id)]})
self.assertEqual(new_team.member_ids, self.env.user)
new_team.write({'member_ids': [(6, 0, (self.user_sales_leads | self.env.user).ids)]})
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
# archived memberships on sales_team_1 for user_sales_leads
self.assertEqual(sales_team_1.member_ids, self.user_admin)
# create a new user on the fly, just for testing
self.user_sales_manager.write({'groups_id': [(4, self.env.ref('base.group_system').id)]})
new_team.write({'member_ids': [(0, 0, {
'name': 'Marty OnTheMCFly',
'login': 'mcfly@test.example.com',
})]})
new_user = self.env['res.users'].search([('login', '=', 'mcfly@test.example.com')])
self.assertTrue(len(new_user))
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads | new_user)
self.user_sales_manager.write({'groups_id': [(3, self.env.ref('base.group_system').id)]})
self.env.flush_all()
memberships = self.env['crm.team.member'].with_context(active_test=False).search([('user_id', '=', self.user_sales_leads.id)])
self.assertEqual(len(memberships), 3) # subscribed twice to new_team + subscribed to sales_team_1
self.assertEqual(memberships.crm_team_id, sales_team_1 | new_team)
self.assertFalse(memberships.filtered(lambda m: m.crm_team_id == sales_team_1).active)
new_team_memberships = memberships.filtered(lambda m: m.crm_team_id == new_team)
self.assertEqual(len(new_team_memberships), 2) # subscribed, removed, then subscribed again
self.assertTrue(set(new_team_memberships.mapped('active')), set([False, True]))
# still avoid duplicated team / user entries
with self.assertRaises(exceptions.UserError):
self.env['crm.team.member'].create({'crm_team_id': new_team.id, 'user_id': new_user.id})
@users('user_sales_manager')
def test_members_multi(self):
# ensure initial data
sales_team_1 = self.sales_team_1.with_user(self.env.user)
new_team = self.new_team.with_user(self.env.user)
self.assertEqual(sales_team_1.member_ids, self.user_sales_leads | self.user_admin)
# test various add / remove on computed m2m
self.assertEqual(new_team.member_ids, self.env['res.users'])
new_team.write({'member_ids': [(4, self.env.uid), (4, self.user_sales_leads.id)]})
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
new_team.write({'member_ids': [(3, self.user_sales_leads.id)]})
self.assertEqual(new_team.member_ids, self.env.user)
new_team.write({'member_ids': [(6, 0, (self.user_sales_leads | self.env.user).ids)]})
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
# nothing changed on sales_team_1
self.assertEqual(sales_team_1.member_ids, self.user_sales_leads | self.user_admin)
# create a new user on the fly, just for testing
self.user_sales_manager.write({'groups_id': [(4, self.env.ref('base.group_system').id)]})
new_team.write({'member_ids': [(0, 0, {
'name': 'Marty OnTheMCFly',
'login': 'mcfly@test.example.com',
})]})
new_user = self.env['res.users'].search([('login', '=', 'mcfly@test.example.com')])
self.assertTrue(len(new_user))
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads | new_user)
self.user_sales_manager.write({'groups_id': [(3, self.env.ref('base.group_system').id)]})
self.env.flush_all()
# still avoid duplicated team / user entries
with self.assertRaises(exceptions.UserError):
self.env['crm.team.member'].create({'crm_team_id': new_team.id, 'user_id': new_user.id})
@users('user_sales_manager')
def test_memberships_mono(self):
""" Test mono mode: updating crm_team_member_ids field """
self.env['ir.config_parameter'].sudo().set_param('sales_team.membership_multi', False)
# ensure initial data
sales_team_1 = self.env['crm.team'].browse(self.sales_team_1.ids)
new_team = self.env['crm.team'].browse(self.new_team.ids)
self.assertEqual(sales_team_1.member_ids, self.user_sales_leads | self.user_admin)
# subscribe on new team (user_sales_leads will have two memberships -> old one deactivated)
self.assertEqual(new_team.member_ids, self.env['res.users'])
new_team.write({'crm_team_member_ids': [
(0, 0, {'user_id': self.user_sales_leads.id}),
(0, 0, {'user_id': self.uid}),
]})
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
self.assertEqual(sales_team_1.member_ids, self.user_admin)
self.env.flush_all()
memberships = self.env['crm.team.member'].with_context(active_test=False).search([('user_id', '=', self.user_sales_leads.id)])
self.assertEqual(memberships.crm_team_id, sales_team_1 | new_team)
self.assertFalse(memberships.filtered(lambda m: m.crm_team_id == sales_team_1).active)
self.assertTrue(memberships.filtered(lambda m: m.crm_team_id == new_team).active)
# subscribe user_sales_leads on old team -> old membership still archived and kept
sales_team_1.write({'crm_team_member_ids': [(0, 0, {'user_id': self.user_sales_leads.id})]})
memberships_new = self.env['crm.team.member'].with_context(active_test=False).search([('user_id', '=', self.user_sales_leads.id)])
self.assertTrue(memberships < memberships_new)
self.assertEqual(memberships.crm_team_id, sales_team_1 | new_team)
# old membership is still inactive, new membership is active
old_st_1 = memberships_new.filtered(lambda m: m.crm_team_id == sales_team_1 and m in memberships)
new_st_1 = memberships_new.filtered(lambda m: m.crm_team_id == sales_team_1 and m not in memberships)
new_nt = memberships_new.filtered(lambda m: m.crm_team_id == new_team)
self.assertFalse(old_st_1.active)
self.assertTrue(new_st_1.active)
self.assertFalse(new_nt.active)
# check members fields
self.assertEqual(new_team.member_ids, self.env.user)
self.assertEqual(sales_team_1.member_ids, self.user_admin | self.user_sales_leads)
# activate another team membership: previous team membership should be de activated
new_nt.toggle_active()
self.assertTrue(new_nt.active)
self.assertFalse(old_st_1.active)
self.assertFalse(new_st_1.active)
# activate another team membership: previous team membership should be de activated
old_st_1.toggle_active()
self.assertFalse(new_nt.active)
self.assertTrue(old_st_1.active)
self.assertFalse(new_st_1.active)
# try to activate duplicate memberships again, which should trigger issues
with self.assertRaises(exceptions.UserError):
new_st_1.toggle_active()
@users('user_sales_manager')
def test_memberships_multi(self):
# ensure initial data
sales_team_1 = self.env['crm.team'].browse(self.sales_team_1.ids)
new_team = self.env['crm.team'].browse(self.new_team.ids)
self.assertEqual(sales_team_1.member_ids, self.user_sales_leads | self.user_admin)
# subscribe on new team (user_sales_leads will have two memberships -> old one deactivated)
self.assertEqual(new_team.member_ids, self.env['res.users'])
new_team.write({'crm_team_member_ids': [
(0, 0, {'user_id': self.user_sales_leads.id}),
(0, 0, {'user_id': self.uid}),
]})
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
self.assertEqual(sales_team_1.member_ids, self.user_sales_leads | self.user_admin)
self.env.flush_all()
memberships = self.env['crm.team.member'].with_context(active_test=False).search([('user_id', '=', self.user_sales_leads.id)])
self.assertEqual(memberships.crm_team_id, sales_team_1 | new_team)
self.assertTrue(memberships.filtered(lambda m: m.crm_team_id == sales_team_1).active)
self.assertTrue(memberships.filtered(lambda m: m.crm_team_id == new_team).active)
# archive membership on sales_team_1 and try creating a new one
memberships.filtered(lambda m: m.crm_team_id == sales_team_1).write({'active': False})
# subscribe user_sales_leads on old team -> old membership still archived and kept
sales_team_1.write({'crm_team_member_ids': [(0, 0, {'user_id': self.user_sales_leads.id})]})
memberships_new = self.env['crm.team.member'].with_context(active_test=False).search([('user_id', '=', self.user_sales_leads.id)])
self.assertTrue(memberships < memberships_new)
self.assertEqual(memberships.crm_team_id, sales_team_1 | new_team)
# old membership is still inactive, new membership is active
old_st_1 = memberships_new.filtered(lambda m: m.crm_team_id == sales_team_1 and m in memberships)
new_st_1 = memberships_new.filtered(lambda m: m.crm_team_id == sales_team_1 and m not in memberships)
new_nt = memberships_new.filtered(lambda m: m.crm_team_id == new_team)
self.assertFalse(old_st_1.active)
self.assertTrue(new_st_1.active)
self.assertTrue(new_nt.active)
# check members fields
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
self.assertEqual(sales_team_1.member_ids, self.user_admin | self.user_sales_leads)
# try to activate duplicate memberships again, which should trigger issues
with self.assertRaises(exceptions.UserError):
old_st_1.toggle_active()
@users('user_sales_manager')
def test_memberships_sync(self):
sales_team_1 = self.env['crm.team'].browse(self.sales_team_1.ids)
new_team = self.env['crm.team'].browse(self.new_team.ids)
self.assertEqual(sales_team_1.member_ids, self.user_sales_leads | self.user_admin)
self.assertEqual(new_team.crm_team_member_ids, self.env['crm.team.member'])
self.assertEqual(new_team.crm_team_member_all_ids, self.env['crm.team.member'])
self.assertEqual(new_team.member_ids, self.env['res.users'])
# creating memberships correctly updates m2m without any refresh
new_member = self.env['crm.team.member'].create({
'user_id': self.env.user.id,
'crm_team_id': self.new_team.id,
})
self.assertEqual(new_team.crm_team_member_ids, new_member)
self.assertEqual(new_team.crm_team_member_all_ids, new_member)
self.assertEqual(new_team.member_ids, self.env.user)
# adding members correctly update o2m with right values
new_team.write({
'member_ids': [(4, self.user_sales_leads.id)]
})
added = self.env['crm.team.member'].search([('crm_team_id', '=', new_team.id), ('user_id', '=', self.user_sales_leads.id)])
self.assertEqual(new_team.crm_team_member_ids, new_member + added)
self.assertEqual(new_team.crm_team_member_all_ids, new_member + added)
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
# archiving membership correctly updates m2m and o2m
added.write({'active': False})
self.assertEqual(new_team.crm_team_member_ids, new_member)
self.assertEqual(new_team.crm_team_member_all_ids, new_member + added)
self.assertEqual(new_team.member_ids, self.env.user)
# reactivating correctly updates m2m and o2m
added.write({'active': True})
self.assertEqual(new_team.crm_team_member_ids, new_member + added)
self.assertEqual(new_team.crm_team_member_all_ids, new_member + added)
self.assertEqual(new_team.member_ids, self.env.user | self.user_sales_leads)
# archived are kept if duplicated on write
admin_original = self.env['crm.team.member'].search([
('crm_team_id', '=', sales_team_1.id),
('user_id', '=', self.user_admin.id)
])
self.assertTrue(bool(admin_original))
admin_archived = self.env['crm.team.member'].create({
'crm_team_id': new_team.id,
'user_id': self.user_admin.id,
'active': False,
})
admin_original.write({'crm_team_id': new_team.id})
# send to db as errors may pop at that step (like trying to set NULL on a m2o inverse of o2m)
self.env.flush_all()
self.assertTrue(self.user_admin in new_team.member_ids)
self.assertTrue(admin_original.active)
self.assertTrue(admin_archived.exists())
self.assertFalse(admin_archived.active)
# change team of membership should raise unicity constraint
with self.assertRaises(exceptions.UserError), mute_logger('odoo.sql_db'):
added.write({'crm_team_id': sales_team_1.id})
def test_sales_team_member_search(self):
""" when a search is triggered on the member_ids field in crm.team
it is currently returning the archived records also. this test will
ensure that the search wont return archived record.
this is to fix unwanted ORM behavior
"""
self.env['res.partner'].create({'name': 'Test Partner', 'team_id': self.new_team.id})
self.env['crm.team.member'].create({
'user_id': self.env.uid,
'crm_team_id': self.new_team.id,
'active': False,
})
partner_exists = self.env['res.partner'].search([
('team_id.member_ids', 'in', [self.env.uid])
])
self.assertFalse(partner_exists, msg="Partner should return empty as current user is removed from team")
def test_users_sale_team_id(self):
self.assertTrue(self.sales_team_1.sequence < self.new_team.sequence)
self.assertEqual(self.user_sales_leads.crm_team_ids, self.sales_team_1)
self.assertEqual(self.user_sales_leads.sale_team_id, self.sales_team_1)
# subscribe to new team -> default team is still the old one
self.new_team.write({
'member_ids': [(4, self.user_sales_leads.id)]
})
self.assertEqual(self.user_sales_leads.crm_team_ids, self.sales_team_1 | self.new_team)
self.assertEqual(self.user_sales_leads.sale_team_id, self.sales_team_1)
# archive membership to first team -> second one becomes default
self.sales_team_1_m1.write({'active': False})
self.assertEqual(self.user_sales_leads.crm_team_ids, self.new_team)
self.assertEqual(self.user_sales_leads.sale_team_id, self.new_team)
# activate membership to first team -> first one becomes default again
self.sales_team_1_m1.write({'active': True})
self.assertEqual(self.user_sales_leads.crm_team_ids, self.sales_team_1 | self.new_team)
self.assertEqual(self.user_sales_leads.sale_team_id, self.sales_team_1)
# keep only one membership -> default team
self.sales_team_1_m1.unlink()
self.assertEqual(self.user_sales_leads.crm_team_ids, self.new_team)
self.assertEqual(self.user_sales_leads.sale_team_id, self.new_team)