Files
odoo_source/addons/crm/models/crm_team.py
T
Nimesh Jethva 71820dbc20 [IMP]crm_*, sale_*: Improvement in model description
Purpose of this commit is to give description more "business oriented"
because those descriptions appears in Odoo Studio which is supposed to be used by end users, not only by developers.

Related Task ID : 37311
2018-09-21 11:45:14 +02:00

226 lines
11 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.exceptions import ValidationError
class Team(models.Model):
_name = 'crm.team'
_inherit = ['mail.alias.mixin', 'crm.team']
_description = 'Sales Channels'
use_leads = fields.Boolean('Leads', help="Check this box to filter and qualify incoming requests as leads before converting them into opportunities and assigning them to a salesperson.")
use_opportunities = fields.Boolean('Pipeline', help="Check this box to manage a presales process with opportunities.")
alias_id = fields.Many2one('mail.alias', string='Alias', ondelete="restrict", required=True, help="The email address associated with this channel. New emails received will automatically create new leads assigned to the channel.")
unassigned_leads_count = fields.Integer(
compute='_compute_unassigned_leads_count',
string='Unassigned Leads', readonly=True)
opportunities_count = fields.Integer(
compute='_compute_opportunities',
string='Number of open opportunities', readonly=True)
opportunities_amount = fields.Integer(
compute='_compute_opportunities',
string='Opportunities Revenues', readonly=True)
dashboard_graph_model = fields.Selection(selection_add=[('crm.lead', 'Pipeline')])
dashboard_graph_period_pipeline = fields.Selection([
('week', 'Within a Week'),
('month', 'Within a Month'),
('year', 'Within a Year'),
], string='Expected to Close', help="The time period this channel's dashboard graph will consider.",
compute="_compute_dashboard_graph_period_pipeline", inverse="_inverse_dashboard_graph_period_pipeline")
dashboard_graph_group_pipeline = fields.Selection([
('day', 'Expected Closing Day'),
('week', 'Expected Closing Week'),
('month', 'Expected Closing Month'),
('user', 'Salesperson'),
('stage', 'Stage'),
], string='Grouping Method', default='day', help="How this channel's dashboard graph will group the results.")
def _compute_unassigned_leads_count(self):
leads_data = self.env['crm.lead'].read_group([
('team_id', 'in', self.ids),
('type', '=', 'lead'),
('user_id', '=', False),
], ['team_id'], ['team_id'])
counts = {datum['team_id'][0]: datum['team_id_count'] for datum in leads_data}
for team in self:
team.unassigned_leads_count = counts.get(team.id, 0)
def _compute_opportunities(self):
opportunity_data = self.env['crm.lead'].read_group([
('team_id', 'in', self.ids),
('probability', '<', 100),
('type', '=', 'opportunity'),
], ['planned_revenue', 'probability', 'team_id'], ['team_id'])
counts = {datum['team_id'][0]: datum['team_id_count'] for datum in opportunity_data}
amounts = {datum['team_id'][0]: (datum['planned_revenue'] * datum['probability'] / 100) for datum in opportunity_data}
for team in self:
team.opportunities_count = counts.get(team.id, 0)
team.opportunities_amount = amounts.get(team.id, 0)
def _compute_dashboard_graph_period_pipeline(self):
for channel in self:
channel.dashboard_graph_period_pipeline = channel.dashboard_graph_period
def _inverse_dashboard_graph_period_pipeline(self):
for channel in self.filtered(lambda ch: ch.dashboard_graph_model == 'crm.lead'):
channel.dashboard_graph_period = channel.dashboard_graph_period_pipeline
def get_alias_model_name(self, vals):
return 'crm.lead'
def get_alias_values(self):
has_group_use_lead = self.env.user.has_group('crm.group_use_lead')
values = super(Team, self).get_alias_values()
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
return values
@api.onchange('use_leads', 'use_opportunities')
def _onchange_use_leads_opportunities(self):
if not self.use_leads and not self.use_opportunities:
self.alias_name = False
if not self.use_opportunities and self.use_leads:
self.use_leads = False
@api.onchange('team_type')
def _onchange_team_type(self):
if self.team_type == 'sales':
self.use_opportunities = True
self.use_leads = lambda self: self.user_has_groups('crm.group_use_lead')
self.dashboard_graph_model = 'crm.lead'
else:
self.use_opportunities = False
self.use_leads = False
return super(Team, self)._onchange_team_type()
@api.onchange('dashboard_graph_model')
def _onchange_dashboard_graph_model(self):
if self.dashboard_graph_model == 'crm.lead':
self.dashboard_graph_period_pipeline = self.dashboard_graph_period
self.dashboard_graph_group_pipeline = self.dashboard_graph_group
else:
self.dashboard_graph_period = self.dashboard_graph_period_pipeline
if not self.dashboard_graph_group:
self.dashboard_graph_group = self._fields['dashboard_graph_group'].default(self)
@api.onchange('dashboard_graph_group_pipeline')
def _onchange_dashboard_graph_group_pipeline(self):
if self.dashboard_graph_group_pipeline == 'stage':
self.dashboard_graph_group = False
else:
self.dashboard_graph_group = self.dashboard_graph_group_pipeline
@api.constrains('dashboard_graph_model', 'use_opportunities')
def _check_graph_model(self):
if not self.use_opportunities and self.dashboard_graph_model == 'crm.lead':
raise ValidationError(_("You have to enable the Pipeline on your Sales Team to be able to set it as a content for the graph"))
@api.multi
def write(self, vals):
result = super(Team, self).write(vals)
if 'use_leads' in vals or 'alias_defaults' in vals:
for team in self:
team.alias_id.write(team.get_alias_values())
return result
#TODO JEM : refactor this stuff with xml action, proper customization,
@api.model
def action_your_pipeline(self):
action = self.env.ref('crm.crm_lead_opportunities_tree_view').read()[0]
user_team_id = self.env.user.sale_team_id.id
if not user_team_id:
user_team_id = self.search([], limit=1).id
action['help'] = _("""<p class='o_view_nocontent_smiling_face'>Add new opportunities</p><p>
Looks like you are not a member of a Sales Team. You should add yourself
as a member of one of the Sales Team.
</p>""")
if user_team_id:
action['help'] += "<p>As you don't belong to any Sales Team, Odoo opens the first one by default.</p>"
action_context = safe_eval(action['context'], {'uid': self.env.uid})
if user_team_id:
action_context['default_team_id'] = user_team_id
action['context'] = action_context
return action
def _compute_dashboard_button_name(self):
opportunity_teams = self.filtered('use_opportunities')
opportunity_teams.update({'dashboard_button_name': _("Pipeline")})
super(Team, self - opportunity_teams)._compute_dashboard_button_name()
def action_primary_channel_button(self):
if self.use_opportunities:
action = self.env.ref('crm.crm_case_form_view_salesteams_opportunity').read()[0]
return action
return super(Team, self).action_primary_channel_button()
def _graph_get_dates(self, today):
""" return a coherent start and end date for the dashboard graph according to the graph settings.
"""
if self.dashboard_graph_model == 'crm.lead':
if self.dashboard_graph_group == 'month':
start_date = today.replace(day=1)
elif self.dashboard_graph_group == 'week':
start_date = today - relativedelta(days=today.isocalendar()[2] - 1)
else:
start_date = today
if self.dashboard_graph_period == 'week':
end_date = today + relativedelta(weeks=1)
elif self.dashboard_graph_period == 'year':
end_date = today + relativedelta(years=1)
else:
end_date = today + relativedelta(months=1)
# we take the end of the preceding month/week/day if we group by month/week/day
# (to avoid having twice the same month/week/day from different years/month/week)
if self.dashboard_graph_group == 'month':
end_date = end_date.replace(day=1) - relativedelta(days=1)
elif self.dashboard_graph_group == 'week':
end_date -= relativedelta(days=end_date.isocalendar()[2])
else:
end_date -= relativedelta(days=1)
return [start_date, end_date]
return super(Team, self)._graph_get_dates(today)
def _get_graph(self):
graph_datas = super(Team, self)._get_graph()
if self.dashboard_graph_model == 'crm.lead' and self.dashboard_graph_group_pipeline == 'stage':
stage_ids = [d['label'] for d in graph_datas[0]['values'] if d['label'] is not None]
stage_data = self.env['crm.stage'].browse(stage_ids).read(['sequence', 'name'])
stage_data = {d['id']: {'name': d['name'], 'sequence': d['sequence']} for d in stage_data}
# use "Undefined" stage for unset stage records
stage_data[None] = {'name': _('Undefined'), 'sequence': -1}
graph_datas[0]['values'] = sorted(graph_datas[0]['values'], key=lambda el: stage_data[el['label']]['sequence'])
for gdata in graph_datas[0]['values']:
gdata['label'] = stage_data[gdata['label']]['name']
return graph_datas
def _graph_date_column(self):
if self.dashboard_graph_model == 'crm.lead':
return 'date_deadline'
return super(Team, self)._graph_date_column()
def _graph_x_query(self):
if self.dashboard_graph_model == 'crm.lead' and self.dashboard_graph_group_pipeline == 'stage':
return 'stage_id'
return super(Team, self)._graph_x_query()
def _graph_y_query(self):
if self.dashboard_graph_model == 'crm.lead':
return 'SUM(expected_revenue)'
return super(Team, self)._graph_y_query()
def _graph_title_and_key(self):
if self.dashboard_graph_model == 'crm.lead':
return ['', _('Pipeline: Expected Revenue')] # no more title
return super(Team, self)._graph_title_and_key()