[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:
@@ -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,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'
|
||||
|
||||
@@ -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="['&', ('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)]}"/>
|
||||
|
||||
@@ -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>&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="@"/>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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))})
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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])],
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user