[IMP] crm_iap_lead: improve onboarding tour of module crm_iap_lead
- Improve crm onboarding tour text messages and display - Modify CRMLeadMiningRequest to improve the Lead Generation Process Default value for lead_number changes from 10 to 3; Computed value for team_id : per default add the current user sale_team_id; Default value for user_id : per default add the current user; Default values for country_ids : Per default, add the country of the active company because it avoids a click and is usually correct; - Improve crm_iap_lead_mining_request_form Group fields by sections for more readability; Change string attribute of some fields; Change the position of the alert messages to the top of the form (as a ribbon); Change button string from Submit to Generate Leads to be more explicit; Task ID 2226563 Community PR #51587 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -12,6 +12,7 @@ _logger = logging.getLogger(__name__)
|
||||
DEFAULT_ENDPOINT = 'https://iap-services.odoo.com'
|
||||
|
||||
MAX_LEAD = 200
|
||||
|
||||
MAX_CONTACT = 5
|
||||
|
||||
CREDIT_PER_COMPANY = 1
|
||||
@@ -28,19 +29,25 @@ class CRMLeadMiningRequest(models.Model):
|
||||
else:
|
||||
return 'opportunity'
|
||||
|
||||
def _default_country_ids(self):
|
||||
return self.env.user.company_id.country_id
|
||||
|
||||
name = fields.Char(string='Request Number', required=True, readonly=True, default=lambda self: _('New'), copy=False)
|
||||
state = fields.Selection([('draft', 'Draft'), ('done', 'Done'), ('error', 'Error')], string='Status', required=True, default='draft')
|
||||
|
||||
# Request Data
|
||||
lead_number = fields.Integer(string='Number of Leads', required=True, default=10)
|
||||
lead_number = fields.Integer(string='Number of Leads', required=True, default=3)
|
||||
search_type = fields.Selection([('companies', 'Companies'), ('people', 'Companies and their Contacts')], string='Target', required=True, default='companies')
|
||||
error = fields.Text(string='Error', readonly=True)
|
||||
|
||||
# Lead / Opportunity Data
|
||||
|
||||
lead_type = fields.Selection([('lead', 'Leads'), ('opportunity', 'Opportunities')], string='Type', required=True, default=_default_lead_type)
|
||||
display_lead_label = fields.Char(compute='_compute_display_lead_label')
|
||||
team_id = fields.Many2one('crm.team', string='Sales Team', domain="[('use_opportunities', '=', True)]")
|
||||
user_id = fields.Many2one('res.users', string='Salesperson')
|
||||
team_id = fields.Many2one(
|
||||
'crm.team', string='Sales Team',
|
||||
domain="[('use_opportunities', '=', True)]", readonly=False, compute='_compute_team_id', store=True)
|
||||
user_id = fields.Many2one('res.users', string='Salesperson', default=lambda self: self.env.user)
|
||||
tag_ids = fields.Many2many('crm.tag', string='Tags')
|
||||
lead_ids = fields.One2many('crm.lead', 'lead_mining_request_id', string='Generated Lead / Opportunity')
|
||||
lead_count = fields.Integer(compute='_compute_lead_count', string='Number of Generated Leads')
|
||||
@@ -49,12 +56,12 @@ class CRMLeadMiningRequest(models.Model):
|
||||
filter_on_size = fields.Boolean(string='Filter on Size', default=False)
|
||||
company_size_min = fields.Integer(string='Size', default=1)
|
||||
company_size_max = fields.Integer(default=1000)
|
||||
country_ids = fields.Many2many('res.country', string='Countries')
|
||||
country_ids = fields.Many2many('res.country', string='Countries', default=_default_country_ids)
|
||||
state_ids = fields.Many2many('res.country.state', string='States')
|
||||
industry_ids = fields.Many2many('crm.iap.lead.industry', string='Industries')
|
||||
|
||||
# Contact Generation Filter
|
||||
contact_number = fields.Integer(string='Number of Contacts', default=1)
|
||||
contact_number = fields.Integer(string='Number of Contacts', default=10)
|
||||
contact_filter_type = fields.Selection([('role', 'Role'), ('seniority', 'Seniority')], string='Filter on', default='role')
|
||||
preferred_role_id = fields.Many2one('crm.iap.lead.role', string='Preferred Role')
|
||||
role_ids = fields.Many2many('crm.iap.lead.role', string='Other Roles')
|
||||
@@ -98,6 +105,11 @@ class CRMLeadMiningRequest(models.Model):
|
||||
for request in self:
|
||||
request.lead_count = mapped_data.get(request.id, 0)
|
||||
|
||||
@api.depends('user_id')
|
||||
def _compute_team_id(self):
|
||||
for record in self:
|
||||
record.team_id = record.user_id.sale_team_id
|
||||
|
||||
@api.onchange('lead_number')
|
||||
def _onchange_lead_number(self):
|
||||
if self.lead_number <= 0:
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
odoo.define('crm_iap_lead.generate_leads_steps', function (require) {
|
||||
"use strict";
|
||||
|
||||
var tour = require('web_tour.tour');
|
||||
var core = require('web.core');
|
||||
|
||||
require('crm.tour');
|
||||
var _t = core._t;
|
||||
|
||||
var DragOppToWonStepIndex = _.findIndex(tour.tours.crm_tour.steps, function (step) {
|
||||
return (step.id === 'drag_opportunity_to_won_step');
|
||||
});
|
||||
|
||||
tour.tours.crm_tour.steps.splice(DragOppToWonStepIndex + 1, 0, {
|
||||
/**
|
||||
* Add some steps between "Drag your opportunity to <b>Won</b> when you get
|
||||
* the deal. Congrats !" and "Let’s have a look at an Opportunity." to
|
||||
* include the steps related to the lead generation (crm_iap_lead).
|
||||
* This eases the on boarding for the Lead Generation process.
|
||||
*
|
||||
*/
|
||||
trigger: ".o_button_generate_leads",
|
||||
content: _t("Looking for more opportunities ?<br>Try the <b>Lead Generation</b> tool."),
|
||||
position: "bottom",
|
||||
run: function (actions) {
|
||||
actions.auto('.o_button_generate_leads');
|
||||
},
|
||||
}, {
|
||||
trigger: '.modal-body .o_industry',
|
||||
content: _t("Which Industry do you want to target?"),
|
||||
position: "right",
|
||||
}, {
|
||||
trigger: '.modal-footer button[name=action_submit]',
|
||||
content: _t("Now, just let the magic happen!"),
|
||||
position: "bottom",
|
||||
run: function (actions) {
|
||||
actions.auto('.modal-footer button[special=cancel]');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -3,6 +3,7 @@
|
||||
<template id="assets_backend" name="crm_iap_lead assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/crm_iap_lead/static/src/js/leads_tree_generate_leads.js"/>
|
||||
<script type="text/javascript" src="/crm_iap_lead/static/src/js/tours/crm_iap_lead.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
</odoo>
|
||||
@@ -6,25 +6,19 @@
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<button name="action_submit" type="object"
|
||||
string="Submit" states="draft"
|
||||
class="oe_highlight" invisible="context.get('is_modal')"/>
|
||||
<button name="action_submit" type="object"
|
||||
string="Retry" states="error"
|
||||
class="oe_highlight"/>
|
||||
<button name="action_submit" type="object" string="Submit" states="draft" class="oe_highlight" invisible="context.get('is_modal')"/>
|
||||
<button name="action_submit" type="object" string="Retry" states="error" class="oe_highlight"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,done" invisible="context.get('is_modal')"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_get_opportunity_action" class="oe_stat_button" type="object" icon="fa-handshake-o"
|
||||
attrs="{'invisible': ['|', ('lead_type', '!=', 'opportunity'), ('state', '!=' , 'done')]}">
|
||||
<button name="action_get_opportunity_action" class="oe_stat_button" type="object" icon="fa-handshake-o" attrs="{'invisible': ['|', ('lead_type', '!=', 'opportunity'), ('state', '!=' , 'done')]}">
|
||||
<div class="o_stat_info">
|
||||
<field name="lead_count"/>
|
||||
<span class="o_stat_text">Opportunities</span>
|
||||
</div>
|
||||
</button>
|
||||
<button name="action_get_lead_action" class="oe_stat_button" type="object" icon="fa-handshake-o" groups="crm.group_use_lead"
|
||||
attrs="{'invisible': ['|', ('lead_type', '!=', 'lead'), ('state', '!=' , 'done')]}">
|
||||
<button name="action_get_lead_action" class="oe_stat_button" type="object" icon="fa-handshake-o" groups="crm.group_use_lead" attrs="{'invisible': ['|', ('lead_type', '!=', 'lead'), ('state', '!=' , 'done')]}">
|
||||
<div class="o_stat_info">
|
||||
<field name="lead_count"/>
|
||||
<span class="o_stat_text">Leads</span>
|
||||
@@ -42,21 +36,24 @@
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<group>
|
||||
<group name="requests" string="Request">
|
||||
<field name="lead_number" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="search_type" widget="radio" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="error" attrs="{'invisible': [('state', '!=', 'error')]}"/>
|
||||
</group>
|
||||
<group name="lead_info" string="Lead Information">
|
||||
<field name="lead_type" groups="crm.group_use_lead" invisible="context.get('is_modal')" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="team_id" attrs="{'readonly': [('state', '!=', 'draft')]}" kanban_view_ref="%(sales_team.crm_team_view_kanban)s"/>
|
||||
<field name="user_id" attrs="{'readonly': [('state', '!=', 'draft')]}" domain="[('share', '=', False)]"/>
|
||||
<field name="tag_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
|
||||
<h2>What do you need ?</h2>
|
||||
|
||||
<group name="requests">
|
||||
<group>
|
||||
<div class="o_row">
|
||||
<field name="lead_number" attrs="{'readonly': [('state', '!=', 'draft')]}" nolabel="1" class="oe_inline col-md-2 pl-0"/>
|
||||
<field name="search_type" widget="selection" attrs="{'readonly': [('state', '!=', 'draft')]}" nolabel="1" class="oe_inline col-md-6"/>
|
||||
<field name="error" attrs="{'invisible': [('state', '!=', 'error')]}"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<group name="companies" string="Companies">
|
||||
<group name="companies">
|
||||
<field name="country_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}" required="True" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="state_ids" widget="many2many_tags" attrs="{'invisible': [('country_ids', '=', [])], 'readonly': [('state', '!=', 'draft')]}" domain="[('country_id', 'in', country_ids)]" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="industry_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}" options="{'no_create': True, 'no_open': True}" class="o_industry"/>
|
||||
<field name="filter_on_size" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<label for="company_size_min" attrs="{'invisible': [('filter_on_size', '=', False)]}"/>
|
||||
<div attrs="{'invisible': [('filter_on_size', '=', False)]}">
|
||||
@@ -66,44 +63,32 @@
|
||||
<field name="company_size_max" class="oe_inline col-sm-3" attrs="{'required': [('filter_on_size', '=', True)], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
employees
|
||||
</div>
|
||||
<field name="country_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}" required="True" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="state_ids" widget="many2many_tags" attrs="{'invisible': [('country_ids', '=', [])], 'readonly': [('state', '!=', 'draft')]}" domain="[('country_id', 'in', country_ids)]" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="industry_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}" options="{'no_create': True, 'no_open': True}"/>
|
||||
|
||||
</group>
|
||||
<group name="contacts" string="Contacts" attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
<field name="contact_number" attrs="{'readonly': [('state', '!=', 'draft')], 'required': [('search_type', '=', 'people')]}"/>
|
||||
<field name="contact_filter_type" widget="radio" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="preferred_role_id"
|
||||
options="{'no_create_edit': True, 'no_quick_create': True}"
|
||||
attrs="{'invisible': [('contact_filter_type','!=', 'role')], 'required': [('search_type', '=', 'people'), ('contact_filter_type', '=', 'role')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="role_ids" widget="many2many_tags"
|
||||
options="{'color_field': 'color', 'no_create_edit': True, 'no_quick_create': True}"
|
||||
attrs="{'invisible': ['|', ('preferred_role_id','=', False), ('contact_filter_type','!=', 'role')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="seniority_id" options="{'no_create_edit': True, 'no_quick_create': True}"
|
||||
attrs="{'invisible': [('contact_filter_type', '!=', 'seniority')], 'required': [('search_type', '=', 'people'), ('contact_filter_type', '=', 'seniority')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<group name="lead_info">
|
||||
<field name="lead_type" groups="crm.group_use_lead" invisible="context.get('is_modal')" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="team_id" no_create="1" no_open="1" attrs="{'readonly': [('state', '!=', 'draft')]}" kanban_view_ref="812"/>
|
||||
<field name="user_id" no_create="1" no_open="1" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="tag_ids" string="Default Tags" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="alert alert-info" role="alert">
|
||||
<field name="lead_credits"/>
|
||||
<br/>
|
||||
<span attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
<field name="lead_contacts_credits"/>
|
||||
<br/>
|
||||
<field name="lead_total_credits"/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<group name="contacts" attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
<div>
|
||||
<field name="contact_number" attrs="{'readonly': [('state', '!=', 'draft')], 'required': [('search_type', '=', 'people')]}" nolabel="1" class="col-md-1"/>
|
||||
<span class="col-md-6">Extra contacts per Company</span>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="alert alert-info" role="alert"
|
||||
attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
Make sure you know if you have to be GDPR compliant for storing personal data.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('search_type', '!=', 'people')]}">
|
||||
<group>
|
||||
<field name="contact_filter_type" widget="radio" attrs="{'readonly': [('state', '!=', 'draft')]}" options="{'horizontal': true}"/>
|
||||
<field name="preferred_role_id" options="{'no_create_edit': True, 'no_quick_create': True}" attrs="{'invisible': [('contact_filter_type','!=', 'role')], 'required': [('search_type', '=', 'people'), ('contact_filter_type', '=', 'role')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="role_ids" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True, 'no_quick_create': True}" attrs="{'invisible': ['|', ('preferred_role_id','=', False), ('contact_filter_type','!=', 'role')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="seniority_id" options="{'no_create_edit': True, 'no_quick_create': True}" attrs="{'invisible': [('contact_filter_type', '!=', 'seniority')], 'required': [('search_type', '=', 'people'), ('contact_filter_type', '=', 'seniority')], 'readonly': [('state', '!=', 'draft')]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Submit" name="action_submit" type="object" default_focus="1" class="btn-primary" invisible="not context.get('is_modal')"/>
|
||||
<button string="Generate Leads" name="action_submit" type="object" default_focus="1" class="btn-primary" invisible="not context.get('is_modal')"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel" invisible="not context.get('is_modal')"/>
|
||||
</footer>
|
||||
</sheet>
|
||||
|
||||
Reference in New Issue
Block a user