[IMP] crm: stage management update 42

Stages are now shared by default between sales team. As the sales flow should
be quite the same whatever the sales team, stages are now shared and not
sales team dependant.

The possibility of customizing the flow by adding stages specific to a sales
team still exist. Stages have a team_id field that can be set in the stage
form, in configuration. However this is not the default behavior. A stage
is either common to all sales team, either specific to only one sales team.
This is why there is no team_ids field anymore, only team_id.

Moreover leads do not use stage anymore. A lead is either alive or archived.
The type field on stages is then removed, as all stages are now used in
opportunities only.

A small hack has been introduced in crm_stage default_get. Indeed when going
from the pipeline, creating a stage with a sales team in context should not
create a stage for the current sales team only. Therefore unless specified
in the context, default_team_id is discarded in the default get context.
This commit is contained in:
Thibault Delavallée
2015-11-30 15:30:54 +01:00
parent cf8a59c250
commit d025251c7e
14 changed files with 76 additions and 257 deletions
-1
View File
@@ -80,7 +80,6 @@ Dashboard for CRM will include:
'crm_mail_template_data.xml'
],
'demo': [
'data/crm_stage_demo.xml',
'crm_demo.xml',
'crm_lead_demo.xml',
'data/crm_action_demo.xml',
+10 -40
View File
@@ -72,14 +72,6 @@ class crm_lead(format_address, osv.osv):
team_id = self.pool['crm.team']._get_default_team_id(cr, SUPERUSER_ID, context=context, user_id=uid)
return self.stage_find(cr, uid, [], team_id, [('fold', '=', False)], context=context)
def _resolve_type_from_context(self, cr, uid, context=None):
""" Returns the type (lead or opportunity) from the type context
key. Returns None if it cannot be resolved.
"""
if context is None:
context = {}
return context.get('default_type')
def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
access_rights_uid = access_rights_uid or uid
stage_obj = self.pool.get('crm.stage')
@@ -91,17 +83,11 @@ class crm_lead(format_address, osv.osv):
# - ('id', 'in', 'ids'): add columns that should be present
# - OR ('fold', '=', False): add default columns that are not folded
# - OR ('team_ids', '=', team_id), ('fold', '=', False) if team_id: add team columns that are not folded
search_domain = []
team_id = context and context.get('default_team_id') or False
if team_id:
search_domain += ['|', ('team_ids', '=', team_id)]
search_domain += [('id', 'in', ids)]
search_domain = ['|', ('id', 'in', ids), '|', ('team_id', '=', False), ('team_id', '=', team_id)]
else:
search_domain += [('id', 'in', ids)]
# retrieve type from the context (if set: choose 'type' or 'both')
type = self._resolve_type_from_context(cr, uid, context=context)
if type:
search_domain += ['|', ('type', '=', type), ('type', '=', 'both')]
search_domain = ['|', ('id', 'in', ids), ('team_id', '=', False)]
# perform search
stage_ids = stage_obj._search(cr, uid, search_domain, order=order, access_rights_uid=access_rights_uid, context=context)
result = stage_obj.name_get(cr, access_rights_uid, stage_ids, context=context)
@@ -206,7 +192,7 @@ class crm_lead(format_address, osv.osv):
'priority': fields.selection(crm_stage.AVAILABLE_PRIORITIES, 'Rating', select=True),
'date_closed': fields.datetime('Closed', readonly=True, copy=False),
'stage_id': fields.many2one('crm.stage', 'Stage', track_visibility='onchange', select=True,
domain="['&', ('team_ids', '=', team_id), '|', ('type', '=', type), ('type', '=', 'both')]"),
domain="['|', ('team_id', '=', False), ('team_id', '=', team_id)]"),
'user_id': fields.many2one('res.users', 'Salesperson', select=True, track_visibility='onchange'),
'referred': fields.char('Referred By'),
'date_open': fields.datetime('Assigned', readonly=True),
@@ -320,32 +306,20 @@ class crm_lead(format_address, osv.osv):
cases = self.browse(cr, uid, cases, context=context)
if context is None:
context = {}
# check whether we should try to add a condition on type
avoid_add_type_term = any([term for term in domain if len(term) == 3 if term[0] == 'type'])
# collect all team_ids
team_ids = set()
types = ['both']
if not cases and context.get('default_type'):
ctx_type = context.get('default_type')
types += [ctx_type]
if team_id:
team_ids.add(team_id)
for lead in cases:
if lead.team_id:
team_ids.add(lead.team_id.id)
if lead.type not in types:
types.append(lead.type)
# OR all team_ids
search_domain = []
if team_ids:
search_domain += [('|')] * (len(team_ids) - 1)
for team_id in team_ids:
search_domain.append(('team_ids', '=', team_id))
# AND with cases types
if not avoid_add_type_term:
search_domain.append(('type', 'in', types))
search_domain = ['|', ('team_id', '=', False), ('team_id', 'in', list(team_ids))]
else:
search_domain = [('team_id', '=', False)]
# AND with the domain in parameter
search_domain += list(domain)
search_domain = ['&'] + list(domain) + search_domain
# perform search, return the first found
stage_ids = self.pool.get('crm.stage').search(cr, uid, search_domain, order=order, limit=1, context=context)
if stage_ids:
@@ -628,7 +602,7 @@ class crm_lead(format_address, osv.osv):
# Check if the stage is in the stages of the sales team. If not, assign the stage with the lowest sequence
if merged_data.get('team_id'):
team_stage_ids = self.pool.get('crm.stage').search(cr, uid, [('team_ids', 'in', merged_data['team_id']), ('type', 'in', [merged_data.get('type'), 'both'])], order='sequence', context=context)
team_stage_ids = self.pool.get('crm.stage').search(cr, uid, [('team_id', '=', merged_data['team_id'])], order='sequence', context=context)
if merged_data.get('stage_id') not in team_stage_ids:
merged_data['stage_id'] = team_stage_ids and team_stage_ids[0] or False
# Write merged data into first opportunity
@@ -640,10 +614,6 @@ class crm_lead(format_address, osv.osv):
return highest.id
def _convert_opportunity_data(self, cr, uid, lead, customer, team_id=False, context=None):
crm_stage = self.pool.get('crm.stage')
contact_id = False
if customer:
contact_id = self.pool.get('res.partner').address_get(cr, uid, [customer.id])['contact']
if not team_id:
team_id = lead.team_id and lead.team_id.id or False
val = {
@@ -657,8 +627,8 @@ class crm_lead(format_address, osv.osv):
'phone': customer and customer.phone or lead.phone,
'date_conversion': fields.datetime.now(),
}
if not lead.stage_id or lead.stage_id.type=='lead':
val['stage_id'] = self.stage_find(cr, uid, [lead], team_id, [('type', 'in', ('opportunity', 'both'))], context=context)
if not lead.stage_id:
val['stage_id'] = self.stage_find(cr, uid, [lead], team_id, [], context=context)
return val
def convert_opportunity(self, cr, uid, ids, partner_id, user_ids=False, team_id=False, context=None):
+15 -15
View File
@@ -127,7 +127,7 @@
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="date_open" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm_stage_2_1"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_google_adwords"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
@@ -148,7 +148,7 @@
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="date_open" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="stage_id" ref="crm_stage_2_1"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_banner"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
@@ -170,7 +170,7 @@
<field name="priority">2</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="crm_stage_2_1"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="description"></field>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
@@ -208,7 +208,7 @@ Contact: +1 813 494 5005</p>]]></field>
<field name="priority">2</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="crm_stage_2_1"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
@@ -303,7 +303,7 @@ ESM Expert<br />]]></field>
<field name="priority">2</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm_stage_2_1"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
@@ -337,7 +337,7 @@ Andrew</p>]]></field>
<field name="priority">2</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="crm_stage_2_1"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_direct"/>
<field name="source_id" ref="utm.utm_source_mailing"/>
@@ -415,7 +415,7 @@ Andrew</p>]]></field>
<field name="title_action">Send Catalogue by Email</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.crm_stage_2_1"/>
<field name="stage_id" ref="crm.stage_lead1"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
@@ -555,7 +555,7 @@ Andrew</p>]]></field>
<field name="title_action">Send price list regarding our interventions</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.crm_stage_2_2"/>
<field name="stage_id" ref="crm.stage_lead2"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
@@ -590,7 +590,7 @@ Andrew</p>]]></field>
<field name="title_action">Call to define real needs about training</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.crm_stage_2_2"/>
<field name="stage_id" ref="crm.stage_lead2"/>
<field eval="1" name="active"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
@@ -702,7 +702,7 @@ Andrew</p>]]></field>
<field name="next_activity_id" ref="crm_activity_data_email"/>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.crm_stage_2_2"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_services"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
@@ -720,7 +720,7 @@ Andrew</p>]]></field>
<field name="date_action" eval="(DateTime.today() + relativedelta(days=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.crm_stage_2_3"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="campaign_id" ref="utm.utm_campaign_fall_drive"/>
<field name="medium_id" ref="utm.utm_medium_direct"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
@@ -740,7 +740,7 @@ Andrew</p>]]></field>
<field name="date_action" eval="(DateTime.today() + relativedelta(days=2)).strftime('%Y-%m-%d %H:%M')"/>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.crm_stage_2_3"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_services"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
@@ -766,7 +766,7 @@ Andrew</p>]]></field>
<field name="title_action">Conf call with technical service</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_services"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
@@ -791,7 +791,7 @@ Andrew</p>]]></field>
<field name="title_action">Send Catalogue by Email</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.crm_stage_2_3"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
@@ -817,7 +817,7 @@ Andrew</p>]]></field>
<field name="title_action">Send Catalogue by Email</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field name="stage_id" ref="crm.stage_lead3"/>
</record>
<!-- Call Function to set some opportunities as Won -->
+1 -40
View File
@@ -1,41 +1,6 @@
<?xml version="1.0"?>
<openerp>
<data>
<!--
CRM CASE STAGE
-->
<!-- Stage Search view -->
<record id="crm_lead_stage_search" model="ir.ui.view">
<field name="name">Stage - Search</field>
<field name="model">crm.stage</field>
<field name="arch" type="xml">
<search string="Stage Search">
<field name="name"/>
<field name="type"/>
<field name="sequence"/>
<field name="probability"/>
</search>
</field>
</record>
<!-- Stage Form view -->
<record id="crm_lead_stage_act" model="ir.actions.act_window">
<field name="name">Stages</field>
<field name="res_model">crm.stage</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm.crm_stage_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to set a new stage in your lead/opportunity pipeline.
</p><p>
Stages will allow salespersons to easily track how a specific
lead or opportunity is positioned in the sales cycle.
</p>
</field>
</record>
<menuitem action="crm_lead_stage_act" id="menu_crm_lead_stage_act" name="Stages" sequence="0" parent="base.menu_crm_config_lead" groups="base.group_no_one"/>
<!--
LEADS/OPPORTUNITIES CATEGORIES
-->
@@ -106,10 +71,6 @@
<header>
<button name="%(crm.action_crm_lead2opportunity_partner)d" string="Convert to Opportunity" type="action"
help="Convert to Opportunity" class="oe_highlight"/>
<field name="stage_id" widget="statusbar" clickable="True"
domain="['&amp;', ('team_ids', '=', team_id), '|', ('type', '=', type), ('type', '=', 'both')]"
options="{'fold_field': 'fold'}"
on_change="onchange_stage_id(stage_id)"/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
@@ -400,7 +361,7 @@
attrs="{'invisible': [('active', '=', False)]}"/>
<field name="stage_id" widget="statusbar" clickable="True"
options="{'fold_field': 'fold'}"
domain="['&amp;', ('team_ids', '=', team_id), '|', ('type', '=', type), ('type', '=', 'both')]"
domain="['|', ('team_id', '=', team_id), ('team_id', '=', False)]"
attrs="{'invisible': [('active', '=', False)]}"/>
</header>
<sheet>
+9 -10
View File
@@ -22,32 +22,31 @@ class crm_stage(osv.Model):
_rec_name = 'name'
_order = "sequence"
def _default_team_ids(self, cr, uid, context=None):
return context.get('default_team_id') and [(6, 0, [context['default_team_id']])] or False
_columns = {
'name': fields.char('Stage Name', required=True, translate=True),
'sequence': fields.integer('Sequence', help="Used to order stages. Lower is better."),
'probability': fields.float('Probability (%)', required=True, help="This percentage depicts the default/average probability of the Case for this stage to be a success"),
'on_change': fields.boolean('Change Probability Automatically', help="Setting this stage will change the probability automatically on the opportunity."),
'requirements': fields.text('Requirements', help="Enter here the internal requirements for this stage (ex: Offer sent to customer). It will appear as a tooltip over the stage's name."),
'team_ids': fields.many2many('crm.team', 'crm_team_stage_rel', 'stage_id', 'team_id', string='Teams',
help="Link between stages and sales teams. When set, this limitate the current stage to the selected sales teams."),
'team_id': fields.many2one('crm.team', 'Team',
ondelete='set null',
help='Specific team that uses this stage. Other teams will not ne able to see or use this stage.'),
'legend_priority': fields.text(
'Priority Management Explanation', translate=True,
help='Explanation text to help users using the star and priority mechanism on stages or issues that are in this stage.'),
'fold': fields.boolean('Folded in Pipeline',
help='This stage is folded in the kanban view when '
'there are no records in that stage to display.'),
'type': fields.selection([('lead', 'Lead'), ('opportunity', 'Opportunity'), ('both', 'Both')],
string='Type', required=True,
help="This field is used to distinguish stages related to Leads from stages related to Opportunities, or to specify stages available for both types."),
}
_defaults = {
'sequence': 1,
'probability': 10.0,
'team_ids': _default_team_ids,
'fold': False,
'type': 'both',
}
def default_get(self, cr, uid, fields, context=None):
if context and context.get('default_team_id') and not context.get('crm_team_mono', False):
context = dict(context)
context.pop('default_team_id')
return super(crm_stage, self).default_get(cr, uid, fields, context=context)
+29 -6
View File
@@ -1,5 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="crm_lead_stage_search" model="ir.ui.view">
<field name="name">Stage - Search</field>
<field name="model">crm.stage</field>
<field name="arch" type="xml">
<search string="Stage Search">
<field name="name"/>
<field name="sequence"/>
<field name="probability"/>
<field name="team_id"/>
</search>
</field>
</record>
<record model="ir.ui.view" id="crm_stage_tree">
<field name="name">crm.stage.tree</field>
<field name="model">crm.stage</field>
@@ -8,7 +22,7 @@
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="probability"/>
<field name="type"/>
<field name="team_id"/>
</tree>
</field>
</record>
@@ -22,7 +36,7 @@
<group>
<group>
<field name="name"/>
<field name="type"/>
<field name="team_id"/>
<field name="fold"/>
</group>
<group>
@@ -32,16 +46,25 @@
</group>
<separator string="Requirements"/>
<field name="requirements" nolabel="1"/>
<field name="team_ids" invisible="1"/>
</form>
</field>
</record>
<!-- CRM Stage Action -->
<record id="crm_stage_act" model="ir.actions.act_window">
<record id="crm_stage_action" model="ir.actions.act_window">
<field name="name">Stages</field>
<field name="res_model">crm.stage</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_stage_tree"/>
<field name="view_id" ref="crm.crm_stage_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to set a new stage in your opportunity pipeline.
</p><p>
Stages allow salespersons to easily track how a specific opportunity
is positioned in the sales cycle.
</p>
</field>
</record>
<menuitem action="crm_stage_action" id="menu_crm_lead_stage_act" name="Stages" sequence="0" parent="base.menu_crm_config_lead" groups="base.group_no_one"/>
</odoo>
+3 -12
View File
@@ -5,33 +5,24 @@
<field name="probability">10</field>
<field name="on_change">1</field>
<field name="sequence">1</field>
<field name="type">both</field>
</record>
<record model="crm.stage" id="stage_lead2">
<field name="name">Qualified</field>
<field name="probability">30</field>
<field name="on_change">1</field>
<field name="sequence">1</field>
<field name="type">opportunity</field>
<field name="sequence">2</field>
</record>
<record model="crm.stage" id="stage_lead3">
<field name="name">Proposition</field>
<field name="probability">70</field>
<field name="on_change">1</field>
<field name="sequence">1</field>
<field name="type">opportunity</field>
<field name="sequence">3</field>
</record>
<record model="crm.stage" id="stage_lead5">
<record model="crm.stage" id="stage_lead4">
<field name="name">Won</field>
<field name="fold" eval="True"/>
<field name="probability">100</field>
<field name="on_change">1</field>
<field name="sequence">70</field>
<field name="type">opportunity</field>
</record>
<!-- Update data sales team with default stages -->
<record model="crm.team" id="sales_team.team_sales_department">
<field name="stage_ids" eval="[(4, ref('stage_lead1')), (4, ref('stage_lead2')), (4, ref('stage_lead3')), (4, ref('stage_lead5'))]"/>
</record>
</odoo>
-70
View File
@@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- Crm stages -->
<record model="crm.stage" id="stage_lead2">
<field name="name">Qualification</field>
<field name="probability">20</field>
<field name="on_change">1</field>
<field name="sequence">40</field>
<field name="type">opportunity</field>
</record>
<record model="crm.stage" id="stage_lead3">
<field name="name">Proposition</field>
<field name="probability">40</field>
<field name="on_change">1</field>
<field name="sequence">50</field>
<field name="type">opportunity</field>
</record>
<record model="crm.stage" id="stage_lead4">
<field name="name">Negotiation</field>
<field name="probability">60</field>
<field name="on_change">1</field>
<field name="sequence">60</field>
<field name="type">opportunity</field>
</record>
<record model="crm.stage" id="crm_stage_2_1">
<field name="name">New</field>
<field name="probability">10</field>
<field name="on_change">1</field>
<field name="sequence">1</field>
<field name="type">both</field>
</record>
<record model="crm.stage" id="crm_stage_2_2">
<field name="name">Qualification</field>
<field name="probability">20</field>
<field name="on_change">1</field>
<field name="sequence">40</field>
<field name="type">opportunity</field>
</record>
<record model="crm.stage" id="crm_stage_2_3">
<field name="name">Negotiation</field>
<field name="probability">60</field>
<field name="on_change">1</field>
<field name="sequence">60</field>
<field name="type">opportunity</field>
</record>
<record model="crm.stage" id="crm_stage_2_4">
<field name="name">Won</field>
<field name="fold" eval="True"/>
<field name="probability">100</field>
<field name="on_change">1</field>
<field name="sequence">70</field>
<field name="type">opportunity</field>
</record>
<record model="crm.team" id="sales_team.team_sales_department">
<field name="stage_ids" eval="[(4, ref('stage_lead2')), (4, ref('stage_lead3')),
(4, ref('stage_lead4'))]"/>
</record>
<record model="crm.team" id="sales_team.crm_team_1">
<field name="stage_ids" eval="[(4, ref('crm_stage_2_1')),
(4, ref('crm_stage_2_2')),
(4, ref('crm_stage_2_3')),
(4, ref('crm_stage_2_4'))]"/>
</record>
</data>
</odoo>
+1 -1
View File
@@ -35,7 +35,7 @@ class crm_opportunity_report(osv.Model):
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"),
'total_revenue': fields.float('Total Revenue',digits=(16,2),readonly=True),
'expected_revenue': fields.float('Expected Revenue', digits=(16,2),readonly=True),
'stage_id': fields.many2one ('crm.stage', 'Stage', readonly=True, domain="[('team_ids', '=', team_id)]"),
'stage_id': fields.many2one ('crm.stage', 'Stage', readonly=True, domain="['|', ('team_id', '=', False), ('team_id', '=', team_id)]"),
'stage_name': fields.char('Stage Name', readonly=True),
'partner_id': fields.many2one('res.partner', 'Partner' , readonly=True),
'company_id': fields.many2one('res.company', 'Company', readonly=True),
@@ -114,13 +114,13 @@
<filter string="Archived" name="archived" domain="[('active', '=', False)]"/>
<group expand="0" string="Extended Filters">
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<field name="stage_id" domain="[('team_ids', '=', 'team_id')]" />
<field name="stage_id" domain="['|', ('team_id', '=', False), ('team_id', '=', 'team_id')]"/>
<field name="campaign_id"/>
<field name="medium_id"/>
<field name="source_id"/>
<field name="company_id" groups="base.group_multi_company"/>
<separator orientation="vertical"/>
<field name="stage_id" widget="selection" domain="[('team_ids', '=', 'team_id')]" />
<field name="stage_id" widget="selection" domain="['|', ('team_id', '=', False), ('team_id', '=', 'team_id')]"/>
<field name="campaign_id" widget="selection"/>
<field name="medium_id" widget="selection"/>
<field name="source_id" widget="selection"/>
-45
View File
@@ -9,52 +9,8 @@ class crm_team(osv.Model):
_inherit = 'crm.team'
_inherits = {'mail.alias': 'alias_id'}
def _get_default_stage_ids(self, cr, uid, context=None):
return [
(0, 0, {
'name': _('Incoming'),
'sequence': 1,
'probability': 10.0,
'on_change': True,
'fold': False,
'type': 'both',
}),
(0, 0, {
'name': _('Qualified'),
'sequence': 2,
'probability': 30.0,
'on_change': True,
'fold': False,
'type': 'opportunity',
}),
(0, 0, {
'name': _('Proposal'),
'sequence': 3,
'probability': 70.0,
'on_change': True,
'fold': False,
'type': 'opportunity',
}),
(0, 0, {
'name': _('Negotiation'),
'sequence': 4,
'probability': 85.0,
'on_change': True,
'fold': False,
'type': 'opportunity',
}),
(0, 0, {
'name': _('Won'),
'sequence': 50,
'probability': 100.0,
'on_change': True,
'fold': True,
'type': 'both',
})]
_columns = {
'resource_calendar_id': fields.many2one('resource.calendar', "Working Time", help="Used to compute open days"),
'stage_ids': fields.many2many('crm.stage', 'crm_team_stage_rel', 'team_id', 'stage_id', 'Stages'),
'use_leads': fields.boolean('Leads',
help="The first contact you get with a potential customer is a lead you qualify before converting it into a real business opportunity. Check this box to manage leads in this sales team."),
'use_opportunities': fields.boolean('Opportunities', help="Check this box to manage opportunities in this sales team."),
@@ -67,7 +23,6 @@ class crm_team(osv.Model):
'crm.lead', self._columns['alias_id'], 'name', alias_prefix='Lead+', alias_defaults={}, context=context)
_defaults = {
'stage_ids': _get_default_stage_ids,
'use_opportunities': True,
}
-6
View File
@@ -96,12 +96,6 @@
<label for="use_opportunities"/>
</div>
</xpath>
<xpath expr="//page[@name='members']" position="after">
<page string="Stages" groups="base.group_no_one">
<separator string="Select Stages for this Sales Team"/>
<field name="stage_ids"/>
</page>
</xpath>
<xpath expr="//field[@name='code']" position="after">
<label for="alias_name" string="Email Alias"
groups="base.group_no_one"
+6 -7
View File
@@ -7,18 +7,17 @@
partner_id: base.res_partner_1
description: This is the description of the test new lead.
team_id: sales_team.team_sales_department
-
I check default stage of lead.
-
!python {model: crm.lead}: |
stage = self.pool.get('crm.stage').search_read(cr, uid, [('team_ids', '=', ref('sales_team.team_sales_department'))], ['id'], context=context)[0]
lead = self.browse(cr, uid, ref('test_crm_lead_new'))
assert lead.stage_id.id == stage['id'], "Default stage of lead is incorrect!"
-
I change type from lead to opportunity.
-
!python {model: crm.lead}: |
self.convert_opportunity(cr, uid ,[ref("test_crm_lead_new")], ref("base.res_partner_2"))
-
I check default stage of opportunity.
-
!python {model: crm.lead}: |
lead = self.browse(cr, uid, ref('test_crm_lead_new'))
assert lead.stage_id.sequence <= 1, "Default stage of lead is incorrect!"
-
Now I change the stage of opportunity to won.
-
@@ -5,13 +5,11 @@
<field name="name">Assigned</field>
<field eval="10" name="probability"/>
<field eval="12" name="sequence"/>
<field name="type">lead</field>
</record>
<record model="crm.stage" id="stage_portal_lead_recycle">
<field name="name">To Recycle</field>
<field eval="5" name="probability"/>
<field eval="11" name="sequence"/>
<field name="type">lead</field>
</record>
<record id="email_template_lead_forward_mail" model="mail.template">
<field name="name">Lead Mass Mail</field>