From cb7bf9524f829698966465dc62a669e672b82546 Mon Sep 17 00:00:00 2001
From: Kunjal
Date: Tue, 16 Jan 2018 18:21:36 +0530
Subject: [PATCH] [ADD]: Multi branch and CRM.
---
addons/base_branch_company/__init__.py | 4 +
addons/base_branch_company/__manifest__.py | 35 ++++++
.../base_branch_company/demo/branch_demo.xml | 42 +++++++
addons/base_branch_company/models/__init__.py | 8 ++
.../models/ir_branch_company.py | 15 +++
.../base_branch_company/models/res_branch.py | 105 +++++++++++++++++
.../base_branch_company/models/res_partner.py | 22 ++++
.../security/branch_security.xml | 20 ++++
.../security/ir.model.access.csv | 3 +
addons/base_branch_company/tests/__init__.py | 1 +
.../base_branch_company/tests/test_branch.py | 80 +++++++++++++
.../views/res_branch_view.xml | 106 ++++++++++++++++++
addons/crm/__manifest__.py | 2 +-
addons/crm/data/crm_lead_demo.xml | 5 +
addons/crm/models/crm_lead.py | 2 +-
addons/crm/models/crm_team.py | 1 +
addons/crm/security/crm_security.xml | 10 ++
addons/crm/tests/__init__.py | 1 +
addons/crm/tests/common.py | 9 +-
addons/crm/tests/test_crm_activity.py | 2 +
addons/crm/tests/test_crm_branch.py | 68 +++++++++++
addons/crm/tests/test_crm_lead.py | 17 +--
addons/crm/tests/test_lead2opportunity.py | 23 ++--
.../crm/tests/test_new_lead_notification.py | 2 +
addons/crm/views/crm_lead_views.xml | 3 +
addons/sales_team/models/crm_team.py | 16 ++-
.../security/sales_team_security.xml | 7 ++
addons/sales_team/tests/__init__.py | 3 +
.../sales_team/tests/test_branch_crm_team.py | 56 +++++++++
29 files changed, 643 insertions(+), 25 deletions(-)
create mode 100644 addons/base_branch_company/__init__.py
create mode 100644 addons/base_branch_company/__manifest__.py
create mode 100644 addons/base_branch_company/demo/branch_demo.xml
create mode 100644 addons/base_branch_company/models/__init__.py
create mode 100644 addons/base_branch_company/models/ir_branch_company.py
create mode 100644 addons/base_branch_company/models/res_branch.py
create mode 100644 addons/base_branch_company/models/res_partner.py
create mode 100644 addons/base_branch_company/security/branch_security.xml
create mode 100644 addons/base_branch_company/security/ir.model.access.csv
create mode 100644 addons/base_branch_company/tests/__init__.py
create mode 100644 addons/base_branch_company/tests/test_branch.py
create mode 100644 addons/base_branch_company/views/res_branch_view.xml
create mode 100644 addons/crm/tests/test_crm_branch.py
create mode 100644 addons/sales_team/tests/__init__.py
create mode 100644 addons/sales_team/tests/test_branch_crm_team.py
diff --git a/addons/base_branch_company/__init__.py b/addons/base_branch_company/__init__.py
new file mode 100644
index 00000000..6a64595a
--- /dev/null
+++ b/addons/base_branch_company/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of flectra. See LICENSE file for full copyright and licensing details.
+
+from . import models
diff --git a/addons/base_branch_company/__manifest__.py b/addons/base_branch_company/__manifest__.py
new file mode 100644
index 00000000..4774f7fa
--- /dev/null
+++ b/addons/base_branch_company/__manifest__.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+# Part of flectra. See LICENSE file for full copyright and licensing details.
+
+{
+ 'name': 'Branch & Company Mixin',
+ 'version': '1.0',
+ 'category': 'Discuss',
+ 'author': ['Flectra'],
+ 'sequence': 25,
+ 'summary': 'Include Branch & Company support',
+ 'description': """
+Branch & Company
+================
+
+Main Features
+-------------
+* Include Branch & Company in all objects
+* Just need to inherit ir.branch.company.mixin in your object
+* And in your xml file add below 2 lines in your Views
+
+
+""",
+ 'website': '',
+ 'depends': ['base'],
+ 'data': [
+ 'security/branch_security.xml',
+ 'security/ir.model.access.csv',
+ 'views/res_branch_view.xml',
+ ],
+ 'demo': [
+ 'demo/branch_demo.xml',
+ ],
+ 'installable': True,
+ 'auto_install': True
+}
diff --git a/addons/base_branch_company/demo/branch_demo.xml b/addons/base_branch_company/demo/branch_demo.xml
new file mode 100644
index 00000000..e71453f1
--- /dev/null
+++ b/addons/base_branch_company/demo/branch_demo.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ New York
+ NY
+
+ 80 Broad St
+ Scranton
+ 10004
+
+
+ +1 485 123 8989
+
+
+ Washington
+ WA
+
+ 2050 Bamako Place
+ DC 20521-7100
+
+
+ +1 555 123 8069
+
+
+ New Jersey
+ NJ
+
+ 2711-2880 Nulla St.
+ NJ 20521-7100
+
+
+ (372) 587-2335
+
+
+
+
+
+
+
diff --git a/addons/base_branch_company/models/__init__.py b/addons/base_branch_company/models/__init__.py
new file mode 100644
index 00000000..ee7e30da
--- /dev/null
+++ b/addons/base_branch_company/models/__init__.py
@@ -0,0 +1,8 @@
+# -*- coding: utf-8 -*-
+# Part of flectra. See LICENSE file for full copyright and licensing details.
+
+
+from . import res_branch
+from . import ir_branch_company
+from . import res_partner
+
diff --git a/addons/base_branch_company/models/ir_branch_company.py b/addons/base_branch_company/models/ir_branch_company.py
new file mode 100644
index 00000000..7b355b2b
--- /dev/null
+++ b/addons/base_branch_company/models/ir_branch_company.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+# Part of flectra. See LICENSE file for full copyright and licensing details.
+
+from flectra import fields, models
+
+
+class IrBranchCompanyMixin(models.AbstractModel):
+ _name = "ir.branch.company.mixin"
+
+ branch_id = fields.Many2one(
+ 'res.branch', 'Branch', ondelete="restrict",
+ default=lambda self: self.env.user.default_branch_id)
+ company_id = fields.Many2one(
+ 'res.company', 'Company', ondelete="restrict",
+ default=lambda self: self.env.user.company_id)
diff --git a/addons/base_branch_company/models/res_branch.py b/addons/base_branch_company/models/res_branch.py
new file mode 100644
index 00000000..31335a74
--- /dev/null
+++ b/addons/base_branch_company/models/res_branch.py
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+
+from flectra import api, fields, models
+
+
+class Company(models.Model):
+ _name = "res.company"
+ _inherit = ["res.company"]
+
+ branch_id = fields.Many2one('res.branch', 'Branch', ondelete="restrict")
+
+ @api.model
+ def create(self, vals):
+ branch = self.env['res.branch'].create({
+ 'name': vals['name'],
+ 'code': vals['name'],
+ })
+ vals['branch_id'] = branch.id
+ self.clear_caches()
+ company = super(Company, self).create(vals)
+ branch.write({'partner_id': company.partner_id.id,
+ 'company_id': company.id})
+ return company
+
+class ResBranch(models.Model):
+ _name = "res.branch"
+
+ name = fields.Char(string='Name', required=True)
+ code = fields.Char(string='Code', required=True)
+ active = fields.Boolean(string='Active', default=True)
+ partner_id = fields.Many2one('res.partner', string='Partner',
+ ondelete='restrict')
+ company_id = fields.Many2one(
+ 'res.company', string="Company",
+ default=lambda self: self.env.user.company_id, required=True)
+ street = fields.Char()
+ street2 = fields.Char()
+ zip = fields.Char(change_default=True)
+ city = fields.Char()
+ state_id = fields.Many2one("res.country.state", string='State',
+ ondelete='restrict')
+ country_id = fields.Many2one('res.country', string='Country',
+ ondelete='restrict')
+ email = fields.Char()
+ phone = fields.Char()
+ mobile = fields.Char()
+
+ _sql_constraints = [('branch_code_company_uniq', 'unique (code,company_id)',
+ 'The branch code must be unique per company!')]
+
+ @api.model
+ def create(self, vals):
+ if not vals.get('partner_id', False):
+ partner_id = self.env['res.partner'].create({'name': vals['name']})
+ vals.update({'partner_id': partner_id.id})
+ res = super(ResBranch, self).create(vals)
+ vals.pop("name", None)
+ vals.pop("code", None)
+ vals.pop("partner_id", None)
+ vals.update({'branch_id': res.id})
+ res.partner_id.write(vals)
+ return res
+
+ @api.multi
+ def write(self, vals):
+ res = super(ResBranch, self).write(vals)
+ vals.pop("name", None)
+ vals.pop("code", None)
+ vals.pop("company_id", None)
+ vals.pop("partner_id", None)
+ ctx = self.env.context.copy()
+ if 'branch' not in ctx:
+ self.partner_id.write(vals)
+ return res
+
+
+class Users(models.Model):
+
+ _inherit = "res.users"
+
+ @api.model
+ def branch_default_get(self, user):
+ if not user:
+ user = self._uid
+ branch_id = self.env['res.users'].browse(user).default_branch_id
+ if not branch_id:
+ branch_id = \
+ self.env['res.users'].browse(user).company_id.branch_id
+ return branch_id
+
+ @api.model
+ def _get_default_branch(self):
+ return self.branch_default_get(self._uid)
+
+ branch_ids = fields.Many2many('res.branch',
+ 'res_branch_users_rel',
+ 'user_id',
+ 'branch_id',
+ 'Branches')
+ default_branch_id = fields.Many2one('res.branch', 'Default branch',
+ default=_get_default_branch,
+ domain="[('company_id','=',company_id)"
+ "]")
+
+
diff --git a/addons/base_branch_company/models/res_partner.py b/addons/base_branch_company/models/res_partner.py
new file mode 100644
index 00000000..932be8c8
--- /dev/null
+++ b/addons/base_branch_company/models/res_partner.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+from flectra import api, fields, models
+
+class Partner(models.Model):
+ _name = "res.partner"
+ _inherit = ["res.partner", "ir.branch.company.mixin"]
+
+ @api.multi
+ def write(self, vals):
+ field_list = ['street', 'street2', 'zip', 'city', 'state_id',
+ 'country_id', 'email', 'phone', 'mobile']
+ branch_vals = dict((f, vals[f]) for f in field_list if f in vals)
+ if branch_vals and self.branch_id:
+ ctx = self.env.context.copy()
+ ctx.update({'branch': True})
+ self.branch_id.with_context(ctx).write(branch_vals)
+ result = super(Partner, self).write(vals)
+ return result
+
+
+
diff --git a/addons/base_branch_company/security/branch_security.xml b/addons/base_branch_company/security/branch_security.xml
new file mode 100644
index 00000000..c35a3964
--- /dev/null
+++ b/addons/base_branch_company/security/branch_security.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ Branch
+
+
+ ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]
+
+
+
+
+ ['|', ('id','=',user.default_branch_id.id), ('id','in',[g.id for g in user.branch_ids])]
+
+ Allowed Branch
+
+
+
+
diff --git a/addons/base_branch_company/security/ir.model.access.csv b/addons/base_branch_company/security/ir.model.access.csv
new file mode 100644
index 00000000..9759f6d0
--- /dev/null
+++ b/addons/base_branch_company/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_res_branch,access_res_branch,model_res_branch,,1,1,1,0
+access_ir_branch_company,access_ir_branch_company,model_ir_branch_company_mixin,,1,1,1,0
\ No newline at end of file
diff --git a/addons/base_branch_company/tests/__init__.py b/addons/base_branch_company/tests/__init__.py
new file mode 100644
index 00000000..f6fb8a09
--- /dev/null
+++ b/addons/base_branch_company/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_branch
diff --git a/addons/base_branch_company/tests/test_branch.py b/addons/base_branch_company/tests/test_branch.py
new file mode 100644
index 00000000..5677d353
--- /dev/null
+++ b/addons/base_branch_company/tests/test_branch.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+# Part of Flectra. See LICENSE file for full copyright and licensing details.
+
+from flectra.tests.common import TransactionCase
+import logging
+_logger = logging.getLogger(__name__)
+
+class TestMultiBranch(TransactionCase):
+ def setUp(self):
+ super(TestMultiBranch, self).setUp()
+ self.partner_obj = self.env['res.partner']
+ self.main_company = self.env.ref('base.main_company')
+
+ self.branch0 = self.env.ref('base_branch_company.data_branch_1')
+ self.branch1 = self.env.ref('base_branch_company.data_branch_2')
+
+ self.user_1 = self.create_user(self.main_company, 'user_1', self.branch0,
+ [self.branch0, self.branch1])
+ self.user_2 = self.create_user(self.main_company, 'user_2', self.branch1,
+ [self.branch1])
+
+ self.model_id = \
+ self.env['ir.model'].search([('model', '=', 'res.partner')])
+ self.record_rules = self.env['ir.rule'].create({
+ 'name': 'Partner',
+ 'model_id': self.model_id.id,
+ 'domain_force':
+ "['|',('branch_id','=', False),'|', "
+ "('branch_id','=',user.default_branch_id.id), "
+ "('branch_id','in', [b.id for b in user.branch_ids] )]"
+ })
+ self.branch_partner0 = self.partner_obj.create({
+ 'name': 'Test Partner0',
+ 'email': 'test@123.example.com',
+ 'branch_id': self.branch0.id
+ })
+
+ self.env = self.env(user=self.user_1)
+ self.branch_partner1 = self.partner_obj.create({
+ 'name': 'Test Partner1',
+ 'email': 'test@123.example.com',
+ 'branch_id': self.branch0.id
+ })
+
+ def create_user(self, main_company, user_name, branch_id, branch_ids):
+ data = {
+ 'company_ids': [(4, main_company.id)],
+ 'branch_ids': [(4, branch_id.id) for branch_id in branch_ids],
+ 'company_id': main_company.id,
+ 'default_branch_id': branch_id.id,
+ 'login': user_name,
+ 'name': 'Test User',
+ 'password': '123',
+ 'email': 'testuser@yourcompany.com',
+
+ }
+ user_obj = self.env['res.users'].create(data)
+ return user_obj
+
+
+ def test_user_authentication(self):
+ partner = self.partner_obj.sudo(self.user_1.id).search(
+ [('id', '=', self.branch_partner1.id),
+ ('branch_id', '=', self.branch0.id)])
+ self.assertNotEqual(partner.ids, [], 'Test User have access to '
+ 'Branch %s' % self.branch0.name)
+
+ partner = self.partner_obj.sudo(self.user_2.id).search(
+ [('id', '=', self.branch_partner0.id),
+ ('branch_id', '=', self.branch0.id)])
+ self.assertEqual(partner.ids, [],
+ 'Test User should not have access to '
+ 'Branch %s' % self.branch0.name)
+
+
+
+
+
+
+
diff --git a/addons/base_branch_company/views/res_branch_view.xml b/addons/base_branch_company/views/res_branch_view.xml
new file mode 100644
index 00000000..0f792d3a
--- /dev/null
+++ b/addons/base_branch_company/views/res_branch_view.xml
@@ -0,0 +1,106 @@
+
+
+
+ res.branch.form
+ res.branch
+
+
+
+
+
+
+ res.branch.tree
+ res.branch
+
+
+
+
+
+
+
+
+
+ res.branch.search
+ res.branch
+
+
+
+
+
+
+
+
+
+ Branches
+ res.branch
+ form
+ tree,form
+
+
+ Click to start a new Branch.
+
+
+
+
+
+
+
+
+ res.users.form.branch
+ res.users
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/crm/__manifest__.py b/addons/crm/__manifest__.py
index 41f4c57e..4204bd98 100644
--- a/addons/crm/__manifest__.py
+++ b/addons/crm/__manifest__.py
@@ -3,7 +3,7 @@
{
'name': 'CRM',
- 'author': 'Odoo S.A',
+ 'author' : 'Odoo S.A',
'version': '1.0',
'category': 'Sales',
'sequence': 5,
diff --git a/addons/crm/data/crm_lead_demo.xml b/addons/crm/data/crm_lead_demo.xml
index 6bacd14c..9e35c74e 100644
--- a/addons/crm/data/crm_lead_demo.xml
+++ b/addons/crm/data/crm_lead_demo.xml
@@ -53,6 +53,7 @@
1
+
@@ -82,6 +83,7 @@
Bordeaux
33000
+
Rue Ignasse Blanchoux 214/32
+33 1 25 54 45 69
@@ -111,6 +113,7 @@
contact@thekompany.example.com
New York
+
10001
Lafayette Ave 450/12
+1 555 754 3010
@@ -133,6 +136,7 @@
hmc@yahoo.example.com
Manchester
+
03101
United Street 68
@@ -369,6 +373,7 @@ Andrew
]]>
Rediff Mail
willmac@rediffmail.example.com
+
Melbourne
Kensington Road 189
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py
index 52d0a1ee..4f866fef 100644
--- a/addons/crm/models/crm_lead.py
+++ b/addons/crm/models/crm_lead.py
@@ -50,7 +50,7 @@ class Lead(models.Model):
_name = "crm.lead"
_description = "Lead/Opportunity"
_order = "priority desc,activity_date_deadline,id desc"
- _inherit = ['mail.thread', 'mail.activity.mixin', 'utm.mixin', 'format.address.mixin']
+ _inherit = ['mail.thread', 'mail.activity.mixin', 'utm.mixin', 'format.address.mixin', 'ir.branch.company.mixin']
def _default_probability(self):
stage_id = self._default_stage_id()
diff --git a/addons/crm/models/crm_team.py b/addons/crm/models/crm_team.py
index 353e99c1..b5793902 100644
--- a/addons/crm/models/crm_team.py
+++ b/addons/crm/models/crm_team.py
@@ -78,6 +78,7 @@ class Team(models.Model):
values['alias_defaults'] = defaults = safe_eval(self.alias_defaults or "{}")
defaults['type'] = 'lead' if has_group_use_lead and self.use_leads else 'opportunity'
defaults['team_id'] = self.id
+ defaults['branch_id'] = self.branch_id and self.branch_id.id
return values
@api.onchange('use_leads', 'use_opportunities')
diff --git a/addons/crm/security/crm_security.xml b/addons/crm/security/crm_security.xml
index 37de86be..c46aff15 100644
--- a/addons/crm/security/crm_security.xml
+++ b/addons/crm/security/crm_security.xml
@@ -84,6 +84,16 @@
['|',('user_id','=',user.id),('user_id','=',False)]
+
+
+
+ Lead multi-branch
+
+
+ ['|', ('branch_id', '=', False), '|', ('branch_id', '=', user.default_branch_id.id),
+ ('branch_id', 'in', user.branch_ids.ids)]
+
+
diff --git a/addons/crm/tests/__init__.py b/addons/crm/tests/__init__.py
index f6f7d9a8..0b9831b2 100644
--- a/addons/crm/tests/__init__.py
+++ b/addons/crm/tests/__init__.py
@@ -5,3 +5,4 @@ from . import test_new_lead_notification
from . import test_lead2opportunity
from . import test_crm_activity
from . import test_crm_ui
+from . import test_crm_branch
diff --git a/addons/crm/tests/common.py b/addons/crm/tests/common.py
index ba29e67f..35d9eaa7 100644
--- a/addons/crm/tests/common.py
+++ b/addons/crm/tests/common.py
@@ -33,11 +33,13 @@ class TestCrmCases(TransactionCase):
def setUp(self):
super(TestCrmCases, self).setUp()
-
+ branch0 = self.env.ref('base_branch_company.data_branch_1')
+ branch = self.env.ref('base_branch_company.data_branch_2')
# Create a user as 'Crm Salesmanager' and added the `sales manager` group
self.crm_salemanager = self.env['res.users'].create({
'company_id': self.env.ref("base.main_company").id,
- 'name': "Crm Sales manager",
+ 'name': "Crm Sales manager", 'default_branch_id': branch.id,
+ 'branch_ids': [(4, branch_id.id) for branch_id in [branch0, branch]],
'login': "csm",
'email': "crmmanager@yourcompany.com",
'groups_id': [(6, 0, [self.ref('sales_team.group_sale_manager')])]
@@ -46,7 +48,8 @@ class TestCrmCases(TransactionCase):
# Create a user as 'Crm Salesman' and added few groups
self.crm_salesman = self.env['res.users'].create({
'company_id': self.env.ref("base.main_company").id,
- 'name': "Crm Salesman",
+ 'name': "Crm Salesman", 'default_branch_id': branch.id,
+ 'branch_ids': [(4, branch_id.id) for branch_id in [branch0, branch]],
'login': "csu",
'email': "crmuser@yourcompany.com",
'groups_id': [(6, 0, [self.env.ref('sales_team.group_sale_salesman_all_leads').id, self.env.ref('base.group_partner_manager').id])]
diff --git a/addons/crm/tests/test_crm_activity.py b/addons/crm/tests/test_crm_activity.py
index 046c9e6f..3e2639b9 100644
--- a/addons/crm/tests/test_crm_activity.py
+++ b/addons/crm/tests/test_crm_activity.py
@@ -34,10 +34,12 @@ class TestCrmMailActivity(TestCrmCases):
# I create an opportunity, as salesman
self.partner_client = self.env.ref("base.res_partner_1")
+ branch = self.env.ref('base_branch_company.data_branch_2')
self.lead = self.env['crm.lead'].sudo(self.crm_salesman.id).create({
'name': 'Test Opp',
'type': 'opportunity',
'partner_id': self.partner_client.id,
+ 'branch_id': branch.id,
'team_id': self.env.ref("sales_team.team_sales_department").id,
'user_id': self.crm_salesman.id,
})
diff --git a/addons/crm/tests/test_crm_branch.py b/addons/crm/tests/test_crm_branch.py
new file mode 100644
index 00000000..9770929d
--- /dev/null
+++ b/addons/crm/tests/test_crm_branch.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+from flectra.tests import common
+
+
+class TestCrmBranch(common.TransactionCase):
+
+ def setUp(self):
+ super(TestCrmBranch, self).setUp()
+
+ self.branch_1 = self.env.ref('base_branch_company.data_branch_1')
+ self.branch_2 = self.env.ref('base_branch_company.data_branch_2')
+ self.model_crm = self.env['crm.lead']
+ self.sale_user_group = self.env.ref('sales_team.group_sale_manager')
+ self.main_company = self.env.ref('base.main_company')
+ self.crm_user_group = self.env.ref('base.group_user')
+
+ self.user_1 = self.create_crm_user(self.main_company, self.branch_1, [self.branch_1],'user_1', [self.sale_user_group,
+ self.crm_user_group])
+ self.user_2 = self.create_crm_user(self.main_company, self.branch_2, [self.branch_2], 'user_2', [self.sale_user_group,
+ self.crm_user_group])
+ self.team1=self.env.ref('sales_team.team_sales_department')
+ self.team1.write({'branch_id': self.branch_1.id, 'user_id': self.user_1.id})
+ self.team2 = self.env.ref('sales_team.crm_team_1')
+ self.team2.write({'branch_id': self.branch_2.id, 'user_id': self.user_2.id})
+
+ self.lead_1 = self.lead_create(self.branch_1, self.team1, self.user_1.id)
+ self.lead_2 = self.lead_create(self.branch_2, self.team2, self.user_2.id)
+
+ def create_crm_user(self, main_company, branch, branch_ids, login_user, groups):
+ groups = [group.id for group in groups]
+ user_obj = self.env['res.users'].create({
+ 'company_id': main_company.id,
+ 'branch_ids': [(4, branch_id.id) for branch_id in branch_ids],
+ 'default_branch_id': branch.id,
+ 'company_ids': [(4, main_company.id)],
+ 'groups_id': [(6, 0, groups)],
+ 'login': login_user,
+ 'name': 'CRM Test ' + login_user,
+ 'email': 'demo@yourcompany.com',
+ 'password': '123',
+ })
+ return user_obj
+
+
+ def lead_create(self, branch_id, team_id, user_id, ):
+ lead_name = 'CRM LEAD '
+ lead = self.model_crm.create({
+ 'user_id': user_id,
+ 'team_id': team_id.id,
+ 'name': lead_name + branch_id.name,
+ 'branch_id': branch_id.id,
+ })
+ return lead
+
+ def test_lead_authentication(self):
+ lead_ids = self.model_crm.sudo(self.user_2.id).search(
+ [('branch_id', '=', self.branch_1.id), ('id', '=', self.lead_1.id)])
+ self.assertEqual(lead_ids.ids, [], ('%s should not have'
+ ' access to %s')
+ % (self.user_2.name, self.branch_1.name))
+
+ def test_team_branch(self):
+ lead = self.lead_create(self.branch_2, self.team2, self.user_2.id )
+ self.assertEqual(
+ lead.branch_id, self.branch_2, ('%s lead '
+ 'should have %s as branch')
+ % (self.user_2.name,
+ self.branch_2.name))
diff --git a/addons/crm/tests/test_crm_lead.py b/addons/crm/tests/test_crm_lead.py
index 0455db4e..941aaa65 100644
--- a/addons/crm/tests/test_crm_lead.py
+++ b/addons/crm/tests/test_crm_lead.py
@@ -25,8 +25,10 @@ class TestCRMLead(TestCrmCases):
def test_find_stage(self):
# I create a new lead
+ branch = self.env.ref('base_branch_company.data_branch_1')
lead = self.env['crm.lead'].create({
'type': "lead",
+ 'branch_id': branch.id,
'name': "Test lead new",
'partner_id': self.env.ref("base.res_partner_1").id,
'description': "This is the description of the test new lead.",
@@ -77,11 +79,12 @@ class TestCRMLead(TestCrmCases):
# During a mixed merge (involving leads and opps), data should be handled a certain way following their type (m2o, m2m, text, ...) Start by creating two leads and an opp and giving the rights of Sales manager.
default_stage_id = self.ref("crm.stage_lead1")
LeadSalesmanager = self.env['crm.lead'].sudo(self.crm_salemanager.id)
-
+ branch = self.env.ref('base_branch_company.data_branch_2')
# TEST CASE 1
test_crm_opp_01 = LeadSalesmanager.create({
'type': 'opportunity',
'name': 'Test opportunity 1',
+ 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_3").id,
'stage_id': default_stage_id,
'description': 'This is the description of the test opp 1.'
@@ -91,7 +94,7 @@ class TestCRMLead(TestCrmCases):
'type': 'lead',
'name': 'Test lead first',
'partner_id': self.env.ref("base.res_partner_1").id,
- 'stage_id': default_stage_id,
+ 'stage_id': default_stage_id, 'branch_id': branch.id,
'description': 'This is the description of the test lead first.'
})
@@ -99,7 +102,7 @@ class TestCRMLead(TestCrmCases):
'type': 'lead',
'name': 'Test lead second',
'partner_id': self.env.ref("base.res_partner_1").id,
- 'stage_id': default_stage_id,
+ 'stage_id': default_stage_id, 'branch_id': branch.id,
'description': 'This is the description of the test lead second.'
})
@@ -124,14 +127,14 @@ class TestCRMLead(TestCrmCases):
# I want to test leads merge. Start by creating two leads (with the same partner)
test_crm_lead_03 = LeadSalesmanager.create({
'type': 'lead',
- 'name': 'Test lead 3',
+ 'name': 'Test lead 3', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_1").id,
'stage_id': default_stage_id
})
test_crm_lead_04 = LeadSalesmanager.create({
'type': 'lead',
- 'name': 'Test lead 4',
+ 'name': 'Test lead 4', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_1").id,
'stage_id': default_stage_id
})
@@ -154,14 +157,14 @@ class TestCRMLead(TestCrmCases):
# I want to test opps merge. Start by creating two opportunities (with the same partner).
test_crm_opp_02 = LeadSalesmanager.create({
'type': 'opportunity',
- 'name': 'Test opportunity 2',
+ 'name': 'Test opportunity 2', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_3").id,
'stage_id': default_stage_id
})
test_crm_opp_03 = LeadSalesmanager.create({
'type': 'opportunity',
- 'name': 'Test opportunity 3',
+ 'name': 'Test opportunity 3', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_3").id,
'stage_id': default_stage_id
})
diff --git a/addons/crm/tests/test_lead2opportunity.py b/addons/crm/tests/test_lead2opportunity.py
index 861444b3..4f587470 100644
--- a/addons/crm/tests/test_lead2opportunity.py
+++ b/addons/crm/tests/test_lead2opportunity.py
@@ -38,6 +38,7 @@ class TestLead2opportunity2win(TestCrmCases):
crm_case_3.message_post(subject='Test note', body='Détails envoyés par le client sur le FAX pour la qualité')
# I convert mass lead into opportunity customer.
+ branch = self.env.ref('base_branch_company.data_branch_1')
mass = CrmLead2OpportunityPartnerMass.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
@@ -73,25 +74,25 @@ class TestLead2opportunity2win(TestCrmCases):
CrmLead2OpportunityPartnerMass = self.env['crm.lead2opportunity.partner.mass']
LeadSaleman = self.env['crm.lead'].sudo(self.crm_salesman.id)
default_stage_id = self.ref("crm.stage_lead1")
-
+ branch = self.env.ref('base_branch_company.data_branch_2')
# 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',
+ 'name': 'Test user A', 'default_branch_id': branch.id,
'login': 'tua@example.com',
'new_password': 'tua'
})
test_res_user_02 = self.env['res.users'].create({
- 'name': 'Test user B',
+ 'name': 'Test user B', 'default_branch_id': branch.id,
'login': 'tub@example.com',
'new_password': 'tub'
})
test_res_user_03 = self.env['res.users'].create({
- 'name': 'Test user C',
+ 'name': 'Test user C', 'default_branch_id': branch.id,
'login': 'tuc@example.com',
'new_password': 'tuc'
})
test_res_user_04 = self.env['res.users'].create({
- 'name': 'Test user D',
+ 'name': 'Test user D', 'default_branch_id': branch.id,
'login': 'tud@example.com',
'new_password': 'tud'
})
@@ -99,36 +100,36 @@ class TestLead2opportunity2win(TestCrmCases):
# Salesman also creates lead so giving access rights of salesman.
test_crm_lead_01 = LeadSaleman.create({
'type': 'lead',
- 'name': 'Test lead 1',
+ 'name': 'Test lead 1', 'branch_id': branch.id,
'email_from': 'Raoul Grosbedon ',
'stage_id': default_stage_id
})
test_crm_lead_02 = LeadSaleman.create({
- 'type': 'lead',
+ 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 2',
'email_from': 'Raoul Grosbedon ',
'stage_id': default_stage_id
})
test_crm_lead_03 = LeadSaleman.create({
- 'type': 'lead',
+ 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 3',
'email_from': 'Raoul Grosbedon ',
'stage_id': default_stage_id
})
test_crm_lead_04 = LeadSaleman.create({
- 'type': 'lead',
+ 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 4',
'email_from': 'Fabrice Lepoilu',
'stage_id': default_stage_id
})
test_crm_lead_05 = LeadSaleman.create({
- 'type': 'lead',
+ 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 5',
'email_from': 'Fabrice Lepoilu',
'stage_id': default_stage_id
})
test_crm_lead_06 = LeadSaleman.create({
- 'type': 'lead',
+ 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 6',
'email_from': 'Agrolait SuperSeed SA',
'stage_id': default_stage_id
diff --git a/addons/crm/tests/test_new_lead_notification.py b/addons/crm/tests/test_new_lead_notification.py
index db1d018a..796ec7c2 100644
--- a/addons/crm/tests/test_new_lead_notification.py
+++ b/addons/crm/tests/test_new_lead_notification.py
@@ -16,6 +16,7 @@ class NewLeadNotification(TestCrm):
# Imitate what happens in the controller when somebody creates a new
# lead from the website form
+ branch = self.env.ref('base_branch_company.data_branch_1')
lead = self.env["crm.lead"].with_context(mail_create_nosubscribe=True).sudo().create({
"contact_name": "Somebody",
"description": "Some question",
@@ -23,6 +24,7 @@ class NewLeadNotification(TestCrm):
"name": "Some subject",
"partner_name": "Some company",
"team_id": self.sales_team_1.id,
+ "branch_id": branch.id,
"phone": "+0000000000"
})
# partner and channel should be auto subscribed
diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml
index 3a8a3275..3edfb58b 100644
--- a/addons/crm/views/crm_lead_views.xml
+++ b/addons/crm/views/crm_lead_views.xml
@@ -89,6 +89,7 @@
+
@@ -492,6 +493,7 @@
+
@@ -650,6 +652,7 @@
+
diff --git a/addons/sales_team/models/crm_team.py b/addons/sales_team/models/crm_team.py
index fc3c9600..c44ee16a 100644
--- a/addons/sales_team/models/crm_team.py
+++ b/addons/sales_team/models/crm_team.py
@@ -8,14 +8,14 @@ from dateutil.relativedelta import relativedelta
import json
from flectra import api, fields, models, _
-from flectra.exceptions import UserError
+from flectra.exceptions import UserError, ValidationError
from flectra.release import version
from flectra.tools import DEFAULT_SERVER_DATE_FORMAT as DF
class CrmTeam(models.Model):
_name = "crm.team"
- _inherit = ['mail.thread']
+ _inherit = ['mail.thread', 'ir.branch.company.mixin']
_description = "Sales Channel"
_order = "name"
@@ -81,6 +81,18 @@ class CrmTeam(models.Model):
('year', 'Last Year'),
], string='Scale', default='month', help="The time period this channel's dashboard graph will consider.")
+ @api.constrains('company_id', 'branch_id')
+ def _check_company_branch(self):
+ for record in self:
+ if record.company_id and record.company_id != record.branch_id.company_id:
+ raise ValidationError(
+ _('Configuration Error of Company:\n'
+ 'The Company (%s) in the Team and '
+ 'the Company (%s) of Branch must '
+ 'be the same company!') % (record.company_id.name,
+ record.branch_id.company_id.name)
+ )
+
@api.depends('dashboard_graph_group', 'dashboard_graph_model', 'dashboard_graph_period')
def _compute_dashboard_graph(self):
for team in self.filtered('dashboard_graph_model'):
diff --git a/addons/sales_team/security/sales_team_security.xml b/addons/sales_team/security/sales_team_security.xml
index 5e776de4..11802bd0 100644
--- a/addons/sales_team/security/sales_team_security.xml
+++ b/addons/sales_team/security/sales_team_security.xml
@@ -40,6 +40,13 @@
+
+ CRM Team multi-branch
+
+
+ ['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]
+
+
diff --git a/addons/sales_team/tests/__init__.py b/addons/sales_team/tests/__init__.py
new file mode 100644
index 00000000..a265991d
--- /dev/null
+++ b/addons/sales_team/tests/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import test_branch_crm_team
diff --git a/addons/sales_team/tests/test_branch_crm_team.py b/addons/sales_team/tests/test_branch_crm_team.py
new file mode 100644
index 00000000..d3c9b900
--- /dev/null
+++ b/addons/sales_team/tests/test_branch_crm_team.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+
+from flectra.tests import common
+
+
+class TestBranchSaleTeam(common.TransactionCase):
+
+ def setUp(self):
+ super(TestBranchSaleTeam, self).setUp()
+
+ self.main_company = self.env.ref('base.main_company')
+ self.sale_user_group = self.env.ref('sales_team.group_sale_manager')
+ self.manager_user_group = self.env.ref('sales_team.group_sale_manager')
+ self.branch_1 = self.env.ref('base_branch_company.data_branch_1')
+ self.branch_3 = self.env.ref('base_branch_company.data_branch_3')
+ self.user_id_1 = self.create_sale_team_user(self.main_company, 'user_1', self.branch_1,
+ [self.branch_1, self.branch_3],
+ [self.sale_user_group, self.manager_user_group])
+ self.user_id_2 = self.create_sale_team_user(self.main_company, 'user_2', self.branch_3,
+ [self.branch_3],
+ [self.sale_user_group, self.manager_user_group])
+ self.sales_team_1 = self.crm_team_create('CRM Team User 1', self.user_id_1, self.branch_1)
+ self.sales_team_2 = self.crm_team_create('CRM Team User 2', self.user_id_2, self.branch_3)
+
+ def create_sale_team_user(self, main_company, user_name, branch_id, branch_ids, groups):
+ group_ids = [grp.id for grp in groups]
+ data = {
+ 'company_ids': [(4, main_company.id)],
+ 'branch_ids': [(4, ou.id) for ou in branch_ids],
+ 'company_id': main_company.id,
+ 'groups_id': [(6, 0, group_ids)],
+ 'default_branch_id': branch_id.id,
+ 'login': user_name,
+ 'name': 'Ron Sales User',
+ 'password': '123',
+ 'email': 'ron@yourcompany.com',
+ }
+ user_obj = self.env['res.users'].create(data)
+ return user_obj
+
+ def crm_team_create(self, team_name, user_id, branch_id):
+ crm_id = self.env['crm.team'].sudo(user_id.id).create({'name': team_name,
+ 'branch_id': branch_id.id})
+ return crm_id
+
+ def get_crm_team(self, user_id, sales_team_1, branch_id):
+ crm_team = self.env['crm.team'].sudo(user_id.id).search(
+ [('id', '=', sales_team_1.id),
+ ('branch_id', '=', branch_id.id)])
+ return crm_team
+
+ def test_user_authentication_2(self):
+ crm_team = self.get_crm_team(self.user_id_1, self.sales_team_1, self.branch_3)
+ self.assertEqual(crm_team.ids, [], ('%s should not have '
+ 'access to Branch %s') % (
+ self.user_id_1.name, self.branch_1.name))