[IMP] crm,sale,*: Improve UX

This commit improves the ux in CRM by changing a few things:
  - Restore the use_leads and use_quotations fields
    along with their features as they were in 12.0.
  - Hide the email alias if use_upportunities and use_leads
    are unchecked.
  - Show a link to the general settings instead of the alias_domain
    if no alias_domain has been configured.
  - fixes the "unassigned lead(s)" link so that
    it redirects the user to the actually unassigned leads

Task: #1962182
PR: #32372
This commit is contained in:
qmo-odoo
2019-07-30 11:46:30 +00:00
parent 2fe6274bd7
commit 0d2be38333
12 changed files with 81 additions and 57 deletions
+4
View File
@@ -10,5 +10,9 @@
<field name="alias_user_id" ref="base.user_admin"/>
<field name="company_id" eval="False"/>
</record>
<record id="sales_team.crm_team_1" model="crm.team">
<field name="use_leads">True</field>
</record>
</data>
</odoo>
+12 -10
View File
@@ -12,8 +12,10 @@ class Team(models.Model):
_name = 'crm.team'
_inherit = ['mail.alias.mixin', 'crm.team']
_description = 'Sales Team'
use_opportunities = fields.Boolean('Manage a pipeline', default=True, 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.")
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', default=True, 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',
@@ -76,10 +78,10 @@ class Team(models.Model):
for team in self:
team.overdue_opportunities_count = counts.get(team.id, 0)
team.overdue_opportunities_amount = amounts.get(team.id, 0)
@api.onchange('use_opportunities')
def _onchange_opportunities(self):
if not self.use_opportunities:
@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
def get_alias_model_name(self, vals):
@@ -89,13 +91,13 @@ class Team(models.Model):
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 else 'opportunity'
defaults['type'] = 'lead' if has_group_use_lead and self.use_leads else 'opportunity'
defaults['team_id'] = self.id
return values
return values
def write(self, vals):
result = super(Team, self).write(vals)
if 'alias_defaults' in 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
@@ -130,7 +132,7 @@ class Team(models.Model):
if self.use_opportunities:
return self.env.ref('crm.crm_case_form_view_salesteams_opportunity').read()[0]
return super(Team,self).action_primary_channel_button()
def _graph_get_model(self):
if self.use_opportunities:
return 'crm.lead'
+4 -2
View File
@@ -134,7 +134,7 @@
<group>
<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}"/>
<field name="team_id" widget="selection"/>
<field name="team_id" widget="selection" domain="[('use_leads','=',True)]"/>
<field name="type" invisible="1"/>
</group>
<group>
@@ -456,6 +456,8 @@
name="assigned_to_me"
domain="[('user_id', '=', uid)]"
help="Leads that are assigned to me"/>
<filter string="Unassigned Leads" name="unassigned_leads"
domain="[('user_id','=', False), ('type', '=', 'lead')]" help="No salesperson"/>
<separator />
<filter string="Lost Leads" name="lost"
domain="['&amp;', ('probability', '=', 0), ('active', '=', False)]"/>
@@ -624,7 +626,7 @@
<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="team_id" widget="selection"/>
<field name="team_id" widget="selection" domain="[('use_opportunities', '=', True)]"/>
</group>
<group>
<field name="lost_reason" attrs="{'invisible': [('active', '=', True)]}"/>
+42 -31
View File
@@ -97,36 +97,42 @@
</record>
<record id="sales_team_form_view_in_crm" model="ir.ui.view">
<field name="name">crm.team.form.inherit</field>
<field name="model">crm.team</field>
<field name="inherit_id" ref="sales_team.crm_team_view_form"/>
<field name="priority">12</field>
<field name="arch" type="xml">
<xpath expr="//div[@name='options_active']" position="inside">
<div name="opportunities" class="o_row" invisible="1">
<field name="name">crm.team.form.inherit</field>
<field name="model">crm.team</field>
<field name="inherit_id" ref="sales_team.crm_team_view_form"/>
<field name="priority">12</field>
<field name="arch" type="xml">
<xpath expr="//div[@name='options_active']" position="inside">
<div class="o_row">
<span name="opportunities">
<field name="use_opportunities"/>
<label for="use_opportunities"/>
</span>
<span class="o_row" groups="crm.group_use_lead">
<field name="use_leads"/>
<label for="use_leads" string="Leads"/>
</span>
</div>
</xpath>
<xpath expr="//field[@name='user_id']" position="after">
<label for="alias_name" string="Email Alias"
attrs="{'invisible': [('use_leads', '=', False),('use_opportunities', '=', False)]}"/>
<div class="oe_inline" name="alias_def"
attrs="{'invisible': [('use_leads', '=', False),('use_opportunities', '=', False)]}">
<field name="alias_id" class="oe_read_only oe_inline"
string="Email Alias" required="0"/>
<div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;" >
<field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
<button icon="fa-arrow-right" type="action" name="%(base_setup.action_general_configuration)d" string="Configure domain name" class="btn-link" attrs="{'invisible': [('alias_domain', '!=', False)]}"/>
</div>
</xpath>
<xpath expr="//field[@name='user_id']" position="after">
<label for="alias_name" string="Email Alias"
attrs="{'invisible': [('use_opportunities', '=', False)]}"/>
<div class="oe_inline" name="alias_def"
attrs="{'invisible': [('use_opportunities', '=', False)]}">
<field name="alias_id" class="oe_read_only oe_inline"
string="Email Alias" required="0"/>
<div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;" >
<field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
</div>
</div>
<field name="alias_contact" class="oe_inline"
string="Accept Emails From"
attrs="{'invisible': [('use_opportunities', '=', False)]}"/>
<field name="alias_user_id" string="Assign to"/>
</xpath>
</field>
</record>
</div>
<field name="alias_contact" class="oe_inline"
string="Accept Emails From"
attrs="{'invisible': [('use_leads', '=', False), ('use_opportunities', '=', False)]}"/>
<field name="alias_user_id" string="Assign to"/>
</xpath>
</field>
</record>
<!-- Case Teams Action -->
<record id="action_crm_tag_kanban_view_salesteams_oppor11" model="ir.actions.act_window.view">
@@ -173,6 +179,10 @@
<field name="search_view_id" ref="crm.view_crm_case_opportunities_filter"/>
</record>
<record id="sales_team.crm_team_salesteams_pipelines_act" model="ir.actions.act_window">
<field name="domain">[('use_opportunities', '=', True)]</field>
</record>
<record id="crm_team_salesteams_view_kanban" model="ir.ui.view">
<field name="name">crm.team.kanban</field>
<field name="model">crm.team</field>
@@ -184,10 +194,11 @@
<field name="alias_name"/>
<field name="alias_domain"/>
<field name="use_opportunities"/>
<field name="use_leads"/>
</xpath>
<xpath expr="//div[hasclass('o_primary')]" position="after">
<div t-if="record.alias_name.value and record.alias_domain.value">
<div t-if="record.use_leads.raw_value and record.alias_name.value and record.alias_domain.value">
<small t-translation="off"><i class="fa fa-envelope-o" aria-label="Leads" title="Leads" role="img"></i>&amp;nbsp; <field name="alias_id"/></small>
</div>
</xpath>
@@ -195,7 +206,7 @@
<xpath expr="//t[@name='first_options']" position="after">
<div class="row" t-if="record.unassigned_leads_count.raw_value">
<div class="col-8">
<a name="%(crm_case_form_view_salesteams_lead)d" type="action" context="{'search_default_unassigned': True}">
<a name="%(crm_case_form_view_salesteams_lead)d" type="action" context="{'search_default_unassigned_leads': 1}">
<field name="unassigned_leads_count"/>
<t t-if="record.unassigned_leads_count.raw_value == 1">Unassigned Lead</t>
<t t-else="">Unassigned Leads</t>
@@ -229,7 +240,7 @@
</xpath>
<xpath expr="//div[hasclass('o_kanban_manage_view')]" position="inside">
<div groups="crm.group_use_lead">
<div t-if="record.use_leads.raw_value" groups="crm.group_use_lead">
<a name="%(crm_case_form_view_salesteams_lead)d" type="action">
Leads
</a>
@@ -250,7 +261,7 @@
</xpath>
<xpath expr="//div[hasclass('o_kanban_manage_reports')]" position="inside">
<div groups="crm.group_use_lead">
<div t-if="record.use_leads.raw_value" groups="crm.group_use_lead">
<a name="%(action_report_crm_lead_salesteam)d" type="action">
Leads
</a>
@@ -30,14 +30,12 @@
<field name="generate_lead_from_alias"/>
</div>
<div class="o_setting_right_pane">
<label for="generate_lead_from_alias" string="Manual Assignation of Incoming Emails"/>
<label for="generate_lead_from_alias" string="Email Alias"/>
<div class="text-muted">
Generate leads from incoming emails and assign them
to a Sales Team manually
Incoming emails create leads
</div>
<div class="content-group" attrs="{'invisible': [('generate_lead_from_alias','=',False)]}">
<div class="mt16">
<label for="crm_alias_prefix" string="Alias" class="o_light_label"/>
<field name="crm_alias_prefix" class="oe_inline"
attrs="{'required': [('generate_lead_from_alias', '=', True)]}"/>
<label for="alias_domain" string="@"/>
+2
View File
@@ -12,10 +12,12 @@
</record>
<record model="crm.team" id="sales_team.team_sales_department">
<field name="use_quotations" eval="True"/>
<field name="invoiced_target">250000</field>
</record>
<record model="crm.team" id="sales_team.crm_team_1">
<field name="use_quotations" eval="True"/>
<field name="invoiced_target">40000</field>
</record>
+3 -2
View File
@@ -9,6 +9,7 @@ from odoo import api, fields, models, _
class CrmTeam(models.Model):
_inherit = 'crm.team'
use_quotations = fields.Boolean(string='Quotations', help="Check this box if you send quotations to your customers rather than confirming orders straight away.")
invoiced = fields.Integer(
compute='_compute_invoiced',
string='Invoiced This Month', readonly=True,
@@ -58,7 +59,7 @@ class CrmTeam(models.Model):
('team_id', 'in', self.ids),
('invoice_status','=','to invoice'),
], ['team_id'], ['team_id'])
data_map = {datum['team_id'][0]: datum['team_id_count'] for datum in sale_order_data }
data_map = {datum['team_id'][0]: datum['team_id_count'] for datum in sale_order_data}
for team in self:
team.sales_to_invoice_count = data_map.get(team.id,0.0)
@@ -124,6 +125,6 @@ class CrmTeam(models.Model):
if self._context.get('in_sales_app'):
return self.env.ref('sale.action_order_report_so_salesteam').read()[0]
return super(CrmTeam, self).action_primary_channel_button()
def update_invoiced_target(self, value):
return self.write({'invoiced_target': round(float(value or 0))})
+8 -2
View File
@@ -6,6 +6,11 @@
<field name="priority">9</field>
<field name="inherit_id" ref="sales_team.crm_team_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@name='options_active']" position="inside">
<div class="o_row" style="display:inherit">
<field name="use_quotations"/><label for="use_quotations"/>
</div>
</xpath>
<xpath expr="//field[@name='user_id']" position="after">
<field name="invoiced_target"/>
</xpath>
@@ -48,6 +53,7 @@
<field name="arch" type="xml">
<data>
<xpath expr="//templates" position="before">
<field name="use_quotations"/>
<field name="invoiced_target"/>
</xpath>
@@ -87,7 +93,7 @@
</xpath>
<xpath expr="//div[hasclass('o_kanban_manage_view')]" position="inside">
<div>
<div t-if="record.use_quotations.raw_value">
<a name="%(action_quotations_salesteams)d" type="action" class="o_quotation_view_button">Quotations</a>
</div>
<div>
@@ -99,7 +105,7 @@
</xpath>
<xpath expr="//div[hasclass('o_kanban_manage_new')]" position="inside">
<div>
<div t-if="record.use_quotations.raw_value">
<a name="%(action_quotation_form)d" type="action">
Quotation
</a>
+1 -4
View File
@@ -6,7 +6,7 @@
<field name="inherit_id" ref="crm.sales_team_form_view_in_crm"/>
<field name="arch" type="xml">
<data>
<xpath expr="//div[@name='opportunities']" position="attributes">
<xpath expr="//span[@name='opportunities']" position="attributes">
<attribute name="invisible" value="0"/>
</xpath>
</data>
@@ -17,7 +17,4 @@
<field name="context">{'in_sales_app': True}</field>
</record>
<record id="sales_team.crm_team_salesteams_pipelines_act" model="ir.actions.act_window">
<field name="domain">[('use_opportunities', '=', True)]</field>
</record>
</odoo>
+1 -1
View File
@@ -24,7 +24,7 @@ class Website(models.Model):
def _get_crm_default_team_domain(self):
if not self.env.user.has_group('crm.group_use_lead'):
return [('use_opportunities', '=', True)]
return []
return [('use_leads', '=', True)]
crm_default_team_id = fields.Many2one(
'crm.team', string='Default Sales Teams',
@@ -9,7 +9,7 @@ class ResConfigSettings(models.TransientModel):
def _get_crm_default_team_domain(self):
if not self.env.user.has_group('crm.group_use_lead'):
return [('use_opportunities', '=', True)]
return []
return [('use_leads', '=', True)]
crm_default_team_id = fields.Many2one(
'crm.team', string='Default Sales Team', related='website_id.crm_default_team_id', readonly=False,
@@ -118,6 +118,7 @@ class TestPartnerLeadPortal(TestCrmCases):
# Sales Team of crm_salesman
self.team = self.env['crm.team'].with_context(mail_notrack=True).create({
'name': 'Test Team FOR THE WIN',
'use_leads': True,
'member_ids': [(6, 0, [self.crm_salesman.id])],
})