[ADD]: Multi branch and CRM.

This commit is contained in:
Kunjal 2018-01-16 18:21:36 +05:30
parent 06065498bc
commit cb7bf9524f
29 changed files with 643 additions and 25 deletions

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of flectra. See LICENSE file for full copyright and licensing details.
from . import models

View File

@ -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
<field name="branch_id" />
<field name="company_id" />
""",
'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
}

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<flectra>
<data noupdate="1">
<record id="data_branch_1" model="res.branch">
<field name="name">New York</field>
<field name="code">NY</field>
<field name="company_id" ref="base.main_company"/>
<field name="street">80 Broad St</field>
<field name="city">Scranton</field>
<field name="zip">10004</field>
<field name='country_id' ref='base.us'/>
<field name='state_id' ref='base.state_us_27'/>
<field name="phone">+1 485 123 8989</field>
</record>
<record id="data_branch_2" model="res.branch">
<field name="name">Washington</field>
<field name="code">WA</field>
<field name="company_id" ref="base.main_company"/>
<field name="street">2050 Bamako Place</field>
<field name="zip">DC 20521-7100</field>
<field name='country_id' ref='base.us'/>
<field name='state_id' ref='base.state_us_48'/>
<field name="phone">+1 555 123 8069</field>
</record>
<record id="data_branch_3" model="res.branch">
<field name="name">New Jersey</field>
<field name="code">NJ</field>
<field name="company_id" ref="base.main_company"/>
<field name="street">2711-2880 Nulla St.</field>
<field name="zip">NJ 20521-7100</field>
<field name='country_id' ref='base.us'/>
<field name='state_id' ref='base.state_us_48'/>
<field name="phone">(372) 587-2335</field>
</record>
<record id="base.user_root" model="res.users">
<field name="branch_ids" eval="[(6,0,[ref('data_branch_1'),])]"/>
<field name='default_branch_id' ref='data_branch_1'/>
</record>
</data>
</flectra>

View File

@ -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

View File

@ -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)

View File

@ -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)"
"]")

View File

@ -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

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<flectra noupdate="1">
<record id="branch_comp_rule" model="ir.rule">
<field name="name">Branch</field>
<field name="model_id" ref="model_res_branch"/>
<field name="global" eval="True"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
</record>
<record id="ir_rule_branch_allowed"
model="ir.rule">
<field name="model_id" ref="model_res_branch"/>
<field name="domain_force">['|', ('id','=',user.default_branch_id.id), ('id','in',[g.id for g in user.branch_ids])]
</field>
<field name="name">Allowed Branch</field>
<field name="global" eval="True"/>
</record>
</flectra>

View File

@ -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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_res_branch access_res_branch model_res_branch 1 1 1 0
3 access_ir_branch_company access_ir_branch_company model_ir_branch_company_mixin 1 1 1 0

View File

@ -0,0 +1 @@
from . import test_branch

View File

@ -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)

View File

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<flectra>
<record id="view_res_branch_form" model="ir.ui.view">
<field name="name">res.branch.form</field>
<field name="model">res.branch</field>
<field name="arch" type="xml">
<form string="Branch">
<sheet>
<div class="oe_button_box" name="button_box">
<button name="toggle_active" type="object"
class="oe_stat_button" icon="fa-archive">
<field name="active" widget="boolean_button"
options='{"terminology": "archive"}'/>
</button>
</div>
<group col="4">
<field name="name"/>
<field name="code"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="partner_id" readonly="1"/>
</group>
<group>
<group>
<label for="street" string="Address"/>
<div class="o_address_format">
<field name="street" placeholder="Street..." class="o_address_street"/>
<field name="street2" placeholder="Street 2..." class="o_address_street"/>
<field name="city" placeholder="City" class="o_address_city"/>
<field name="state_id" class="o_address_state" placeholder="State" options='{"no_open": True}'
context="{'country_id': country_id, 'zip': zip}"/>
<field name="zip" placeholder="ZIP" class="o_address_zip"/>
<field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True, "no_create": True}'/>
</div>
</group>
<group>
<field name="phone" widget="phone"/>
<field name="mobile" widget="phone"/>
<field name="email" widget="email" context="{'gravatar_image': True}"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_res_branch_tree" model="ir.ui.view">
<field name="name">res.branch.tree</field>
<field name="model">res.branch</field>
<field name="arch" type="xml">
<tree string="Branch">
<field name="code"/>
<field name="name"/>
<field name="company_id" groups="base.group_multi_company"/>
</tree>
</field>
</record>
<record id="view_res_branch_search" model="ir.ui.view">
<field name="name">res.branch.search</field>
<field name="model">res.branch</field>
<field name="arch" type="xml">
<search string="Search Branch">
<field name="name" string="Branch"/>
<field name="code" string="Code"/>
</search>
</field>
</record>
<record id="action_res_branch_tree" model="ir.actions.act_window">
<field name="name">Branches</field>
<field name="res_model">res.branch</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to start a new Branch.
</p>
</field>
</record>
<menuitem action="action_res_branch_tree"
id="menu_action_res_branch_tree"
parent="base.menu_users"/>
<record id="view_branch_users_form" model="ir.ui.view">
<field name="name">res.users.form.branch</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base.view_users_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@name='access_rights']/group[1]" position="replace">
<group>
<group string="Multi Companies" attrs="{'invisible': [('companies_count', '&lt;=', 1)]}">
<field string="Allowed Companies" name="company_ids" widget="many2many_tags"/>
<field string="Current Company" name="company_id" context="{'user_preference': 0}"/>
<field string="Companies count" name="companies_count" invisible="1"/>
</group>
<group string="Allowed Branches">
<field name="default_branch_id" domain="[('company_id','=',company_id)]"/>
<field name="branch_ids" widget="many2many_tags" domain="[('company_id','=',company_id)]"/>
</group>
</group>
</xpath>
</field>
</record>
</flectra>

View File

@ -3,7 +3,7 @@
{ {
'name': 'CRM', 'name': 'CRM',
'author': 'Odoo S.A', 'author' : 'Odoo S.A',
'version': '1.0', 'version': '1.0',
'category': 'Sales', 'category': 'Sales',
'sequence': 5, 'sequence': 5,

View File

@ -53,6 +53,7 @@
<field name="priority">1</field> <field name="priority">1</field>
<field name="team_id" ref="sales_team.team_sales_department"/> <field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
<field name="date_open" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/> <field name="date_open" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="stage_lead1"/> <field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/> <field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
@ -82,6 +83,7 @@
<field name="country_id" ref="base.fr"/> <field name="country_id" ref="base.fr"/>
<field name="city">Bordeaux</field> <field name="city">Bordeaux</field>
<field name="zip">33000</field> <field name="zip">33000</field>
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
<field name="street">Rue Ignasse Blanchoux 214/32</field> <field name="street">Rue Ignasse Blanchoux 214/32</field>
<field name="phone">+33 1 25 54 45 69</field> <field name="phone">+33 1 25 54 45 69</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/> <field name="tag_ids" eval="[(6, 0, [categ_oppor2])]"/>
@ -111,6 +113,7 @@
<field name="email_from">contact@thekompany.example.com</field> <field name="email_from">contact@thekompany.example.com</field>
<field name="country_id" ref="base.us"/> <field name="country_id" ref="base.us"/>
<field name="city">New York</field> <field name="city">New York</field>
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
<field name="zip">10001</field> <field name="zip">10001</field>
<field name="street">Lafayette Ave 450/12</field> <field name="street">Lafayette Ave 450/12</field>
<field name="phone">+1 555 754 3010</field> <field name="phone">+1 555 754 3010</field>
@ -133,6 +136,7 @@
<field name="email_from">hmc@yahoo.example.com</field> <field name="email_from">hmc@yahoo.example.com</field>
<field name="country_id" ref="base.uk"/> <field name="country_id" ref="base.uk"/>
<field name="city">Manchester</field> <field name="city">Manchester</field>
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
<field name="zip">03101</field> <field name="zip">03101</field>
<field name="street">United Street 68</field> <field name="street">United Street 68</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor5])]"/> <field name="tag_ids" eval="[(6, 0, [categ_oppor5])]"/>
@ -369,6 +373,7 @@ Andrew</p>]]></field>
<field name="partner_name">Rediff Mail</field> <field name="partner_name">Rediff Mail</field>
<field name="email_from">willmac@rediffmail.example.com</field> <field name="email_from">willmac@rediffmail.example.com</field>
<field name="country_id" ref="base.au"/> <field name="country_id" ref="base.au"/>
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
<field name="city">Melbourne</field> <field name="city">Melbourne</field>
<field name="street">Kensington Road 189</field> <field name="street">Kensington Road 189</field>
<field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/> <field name="tag_ids" eval="[(6, 0, [categ_oppor1])]"/>

View File

@ -50,7 +50,7 @@ class Lead(models.Model):
_name = "crm.lead" _name = "crm.lead"
_description = "Lead/Opportunity" _description = "Lead/Opportunity"
_order = "priority desc,activity_date_deadline,id desc" _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): def _default_probability(self):
stage_id = self._default_stage_id() stage_id = self._default_stage_id()

View File

@ -78,6 +78,7 @@ class Team(models.Model):
values['alias_defaults'] = defaults = safe_eval(self.alias_defaults or "{}") 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['type'] = 'lead' if has_group_use_lead and self.use_leads else 'opportunity'
defaults['team_id'] = self.id defaults['team_id'] = self.id
defaults['branch_id'] = self.branch_id and self.branch_id.id
return values return values
@api.onchange('use_leads', 'use_opportunities') @api.onchange('use_leads', 'use_opportunities')

View File

@ -84,6 +84,16 @@
<field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field> <field name="domain_force">['|',('user_id','=',user.id),('user_id','=',False)]</field>
<field name="groups" eval="[(4, ref('sales_team.group_sale_salesman'))]"/> <field name="groups" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
</record> </record>
<!-- Multi Branch rule -->
<record id="crm_lead_multi_branch_rule" model="ir.rule">
<field name="name">Lead multi-branch</field>
<field name="model_id" ref="model_crm_lead"/>
<field name="global" eval="True"/>
<field name="domain_force">['|', ('branch_id', '=', False), '|', ('branch_id', '=', user.default_branch_id.id),
('branch_id', 'in', user.branch_ids.ids)]
</field>
</record>
</data> </data>
</flectra> </flectra>

View File

@ -5,3 +5,4 @@ from . import test_new_lead_notification
from . import test_lead2opportunity from . import test_lead2opportunity
from . import test_crm_activity from . import test_crm_activity
from . import test_crm_ui from . import test_crm_ui
from . import test_crm_branch

View File

@ -33,11 +33,13 @@ class TestCrmCases(TransactionCase):
def setUp(self): def setUp(self):
super(TestCrmCases, self).setUp() 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 # Create a user as 'Crm Salesmanager' and added the `sales manager` group
self.crm_salemanager = self.env['res.users'].create({ self.crm_salemanager = self.env['res.users'].create({
'company_id': self.env.ref("base.main_company").id, '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", 'login': "csm",
'email': "crmmanager@yourcompany.com", 'email': "crmmanager@yourcompany.com",
'groups_id': [(6, 0, [self.ref('sales_team.group_sale_manager')])] '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 # Create a user as 'Crm Salesman' and added few groups
self.crm_salesman = self.env['res.users'].create({ self.crm_salesman = self.env['res.users'].create({
'company_id': self.env.ref("base.main_company").id, '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", 'login': "csu",
'email': "crmuser@yourcompany.com", '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])] 'groups_id': [(6, 0, [self.env.ref('sales_team.group_sale_salesman_all_leads').id, self.env.ref('base.group_partner_manager').id])]

View File

@ -34,10 +34,12 @@ class TestCrmMailActivity(TestCrmCases):
# I create an opportunity, as salesman # I create an opportunity, as salesman
self.partner_client = self.env.ref("base.res_partner_1") 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({ self.lead = self.env['crm.lead'].sudo(self.crm_salesman.id).create({
'name': 'Test Opp', 'name': 'Test Opp',
'type': 'opportunity', 'type': 'opportunity',
'partner_id': self.partner_client.id, 'partner_id': self.partner_client.id,
'branch_id': branch.id,
'team_id': self.env.ref("sales_team.team_sales_department").id, 'team_id': self.env.ref("sales_team.team_sales_department").id,
'user_id': self.crm_salesman.id, 'user_id': self.crm_salesman.id,
}) })

View File

@ -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))

View File

@ -25,8 +25,10 @@ class TestCRMLead(TestCrmCases):
def test_find_stage(self): def test_find_stage(self):
# I create a new lead # I create a new lead
branch = self.env.ref('base_branch_company.data_branch_1')
lead = self.env['crm.lead'].create({ lead = self.env['crm.lead'].create({
'type': "lead", 'type': "lead",
'branch_id': branch.id,
'name': "Test lead new", 'name': "Test lead new",
'partner_id': self.env.ref("base.res_partner_1").id, 'partner_id': self.env.ref("base.res_partner_1").id,
'description': "This is the description of the test new lead.", '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. # 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") default_stage_id = self.ref("crm.stage_lead1")
LeadSalesmanager = self.env['crm.lead'].sudo(self.crm_salemanager.id) LeadSalesmanager = self.env['crm.lead'].sudo(self.crm_salemanager.id)
branch = self.env.ref('base_branch_company.data_branch_2')
# TEST CASE 1 # TEST CASE 1
test_crm_opp_01 = LeadSalesmanager.create({ test_crm_opp_01 = LeadSalesmanager.create({
'type': 'opportunity', 'type': 'opportunity',
'name': 'Test opportunity 1', 'name': 'Test opportunity 1',
'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_3").id, 'partner_id': self.env.ref("base.res_partner_3").id,
'stage_id': default_stage_id, 'stage_id': default_stage_id,
'description': 'This is the description of the test opp 1.' 'description': 'This is the description of the test opp 1.'
@ -91,7 +94,7 @@ class TestCRMLead(TestCrmCases):
'type': 'lead', 'type': 'lead',
'name': 'Test lead first', 'name': 'Test lead first',
'partner_id': self.env.ref("base.res_partner_1").id, '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.' 'description': 'This is the description of the test lead first.'
}) })
@ -99,7 +102,7 @@ class TestCRMLead(TestCrmCases):
'type': 'lead', 'type': 'lead',
'name': 'Test lead second', 'name': 'Test lead second',
'partner_id': self.env.ref("base.res_partner_1").id, '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.' '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) # I want to test leads merge. Start by creating two leads (with the same partner)
test_crm_lead_03 = LeadSalesmanager.create({ test_crm_lead_03 = LeadSalesmanager.create({
'type': 'lead', 'type': 'lead',
'name': 'Test lead 3', 'name': 'Test lead 3', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_1").id, 'partner_id': self.env.ref("base.res_partner_1").id,
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })
test_crm_lead_04 = LeadSalesmanager.create({ test_crm_lead_04 = LeadSalesmanager.create({
'type': 'lead', 'type': 'lead',
'name': 'Test lead 4', 'name': 'Test lead 4', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_1").id, 'partner_id': self.env.ref("base.res_partner_1").id,
'stage_id': default_stage_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). # I want to test opps merge. Start by creating two opportunities (with the same partner).
test_crm_opp_02 = LeadSalesmanager.create({ test_crm_opp_02 = LeadSalesmanager.create({
'type': 'opportunity', 'type': 'opportunity',
'name': 'Test opportunity 2', 'name': 'Test opportunity 2', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_3").id, 'partner_id': self.env.ref("base.res_partner_3").id,
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })
test_crm_opp_03 = LeadSalesmanager.create({ test_crm_opp_03 = LeadSalesmanager.create({
'type': 'opportunity', 'type': 'opportunity',
'name': 'Test opportunity 3', 'name': 'Test opportunity 3', 'branch_id': branch.id,
'partner_id': self.env.ref("base.res_partner_3").id, 'partner_id': self.env.ref("base.res_partner_3").id,
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })

View File

@ -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é') 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. # 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({ 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)], 'user_ids': [(6, 0, self.env.ref('base.user_root').ids)],
'team_id': self.env.ref("sales_team.team_sales_department").id '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'] CrmLead2OpportunityPartnerMass = self.env['crm.lead2opportunity.partner.mass']
LeadSaleman = self.env['crm.lead'].sudo(self.crm_salesman.id) LeadSaleman = self.env['crm.lead'].sudo(self.crm_salesman.id)
default_stage_id = self.ref("crm.stage_lead1") 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). # 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({ 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', 'login': 'tua@example.com',
'new_password': 'tua' 'new_password': 'tua'
}) })
test_res_user_02 = self.env['res.users'].create({ 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', 'login': 'tub@example.com',
'new_password': 'tub' 'new_password': 'tub'
}) })
test_res_user_03 = self.env['res.users'].create({ 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', 'login': 'tuc@example.com',
'new_password': 'tuc' 'new_password': 'tuc'
}) })
test_res_user_04 = self.env['res.users'].create({ 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', 'login': 'tud@example.com',
'new_password': 'tud' 'new_password': 'tud'
}) })
@ -99,36 +100,36 @@ class TestLead2opportunity2win(TestCrmCases):
# Salesman also creates lead so giving access rights of salesman. # Salesman also creates lead so giving access rights of salesman.
test_crm_lead_01 = LeadSaleman.create({ test_crm_lead_01 = LeadSaleman.create({
'type': 'lead', 'type': 'lead',
'name': 'Test lead 1', 'name': 'Test lead 1', 'branch_id': branch.id,
'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>', 'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>',
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })
test_crm_lead_02 = LeadSaleman.create({ test_crm_lead_02 = LeadSaleman.create({
'type': 'lead', 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 2', 'name': 'Test lead 2',
'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>', 'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>',
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })
test_crm_lead_03 = LeadSaleman.create({ test_crm_lead_03 = LeadSaleman.create({
'type': 'lead', 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 3', 'name': 'Test lead 3',
'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>', 'email_from': 'Raoul Grosbedon <raoul@grosbedon.fr>',
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })
test_crm_lead_04 = LeadSaleman.create({ test_crm_lead_04 = LeadSaleman.create({
'type': 'lead', 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 4', 'name': 'Test lead 4',
'email_from': 'Fabrice Lepoilu', 'email_from': 'Fabrice Lepoilu',
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })
test_crm_lead_05 = LeadSaleman.create({ test_crm_lead_05 = LeadSaleman.create({
'type': 'lead', 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 5', 'name': 'Test lead 5',
'email_from': 'Fabrice Lepoilu', 'email_from': 'Fabrice Lepoilu',
'stage_id': default_stage_id 'stage_id': default_stage_id
}) })
test_crm_lead_06 = LeadSaleman.create({ test_crm_lead_06 = LeadSaleman.create({
'type': 'lead', 'type': 'lead', 'branch_id': branch.id,
'name': 'Test lead 6', 'name': 'Test lead 6',
'email_from': 'Agrolait SuperSeed SA', 'email_from': 'Agrolait SuperSeed SA',
'stage_id': default_stage_id 'stage_id': default_stage_id

View File

@ -16,6 +16,7 @@ class NewLeadNotification(TestCrm):
# Imitate what happens in the controller when somebody creates a new # Imitate what happens in the controller when somebody creates a new
# lead from the website form # 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({ lead = self.env["crm.lead"].with_context(mail_create_nosubscribe=True).sudo().create({
"contact_name": "Somebody", "contact_name": "Somebody",
"description": "Some question", "description": "Some question",
@ -23,6 +24,7 @@ class NewLeadNotification(TestCrm):
"name": "Some subject", "name": "Some subject",
"partner_name": "Some company", "partner_name": "Some company",
"team_id": self.sales_team_1.id, "team_id": self.sales_team_1.id,
"branch_id": branch.id,
"phone": "+0000000000" "phone": "+0000000000"
}) })
# partner and channel should be auto subscribed # partner and channel should be auto subscribed

View File

@ -89,6 +89,7 @@
<field name="user_id" domain="[('share', '=', False)]" <field name="user_id" domain="[('share', '=', False)]"
context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'sales_team.group_sale_salesman_all_leads'], 'team_id': team_id}"/> context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'sales_team.group_sale_salesman_all_leads'], 'team_id': team_id}"/>
<field name="team_id" widget="selection" domain="[('use_leads','=',True)]"/> <field name="team_id" widget="selection" domain="[('use_leads','=',True)]"/>
<field name="branch_id" options="{'no_create': True, 'no_create_edit': True}"/>
<field name="type" invisible="1"/> <field name="type" invisible="1"/>
</group> </group>
<group> <group>
@ -492,6 +493,7 @@
<group> <group>
<field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'sales_team.group_sale_salesman_all_leads'], 'team_id': team_id}" domain="[('share', '=', False)]"/> <field name="user_id" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'sales_team.group_sale_salesman_all_leads'], 'team_id': team_id}" domain="[('share', '=', False)]"/>
<field name="team_id" widget="selection"/> <field name="team_id" widget="selection"/>
<field name="branch_id" options="{'no_create': True, 'no_create_edit': True}"/>
</group> </group>
<group> <group>
<field name="priority" widget="priority"/> <field name="priority" widget="priority"/>
@ -650,6 +652,7 @@
<filter string="Sales Channel" context="{'group_by':'team_id'}"/> <filter string="Sales Channel" context="{'group_by':'team_id'}"/>
<filter string="Country" context="{'group_by':'country_id'}" /> <filter string="Country" context="{'group_by':'country_id'}" />
<filter string="Company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/> <filter string="Company" context="{'group_by':'company_id'}" groups="base.group_multi_company"/>
<filter string="Branch" context="{'group_by':'branch_id'}"/>
<filter name="stage" string="Stage" context="{'group_by':'stage_id'}"/> <filter name="stage" string="Stage" context="{'group_by':'stage_id'}"/>
<filter string="Campaign" domain="[]" context="{'group_by':'campaign_id'}"/> <filter string="Campaign" domain="[]" context="{'group_by':'campaign_id'}"/>
<filter string="Medium" domain="[]" context="{'group_by':'medium_id'}"/> <filter string="Medium" domain="[]" context="{'group_by':'medium_id'}"/>

View File

@ -8,14 +8,14 @@ from dateutil.relativedelta import relativedelta
import json import json
from flectra import api, fields, models, _ from flectra import api, fields, models, _
from flectra.exceptions import UserError from flectra.exceptions import UserError, ValidationError
from flectra.release import version from flectra.release import version
from flectra.tools import DEFAULT_SERVER_DATE_FORMAT as DF from flectra.tools import DEFAULT_SERVER_DATE_FORMAT as DF
class CrmTeam(models.Model): class CrmTeam(models.Model):
_name = "crm.team" _name = "crm.team"
_inherit = ['mail.thread'] _inherit = ['mail.thread', 'ir.branch.company.mixin']
_description = "Sales Channel" _description = "Sales Channel"
_order = "name" _order = "name"
@ -81,6 +81,18 @@ class CrmTeam(models.Model):
('year', 'Last Year'), ('year', 'Last Year'),
], string='Scale', default='month', help="The time period this channel's dashboard graph will consider.") ], 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') @api.depends('dashboard_graph_group', 'dashboard_graph_model', 'dashboard_graph_period')
def _compute_dashboard_graph(self): def _compute_dashboard_graph(self):
for team in self.filtered('dashboard_graph_model'): for team in self.filtered('dashboard_graph_model'):

View File

@ -40,6 +40,13 @@
<field eval="[(6,0,[ref('base.group_system')])]" name="groups_id"/> <field eval="[(6,0,[ref('base.group_system')])]" name="groups_id"/>
</record> </record>
<record model="ir.rule" id="crm_team_multi_branch_rule">
<field name="name">CRM Team multi-branch</field>
<field name="model_id" ref="sales_team.model_crm_team"/>
<field name="global" eval="True"/>
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
</record>
<data noupdate="1"> <data noupdate="1">
<record id="base.default_user" model="res.users"> <record id="base.default_user" model="res.users">
<field name="groups_id" eval="[(4,ref('sales_team.group_sale_manager'))]"/> <field name="groups_id" eval="[(4,ref('sales_team.group_sale_manager'))]"/>

View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import test_branch_crm_team

View File

@ -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))