summaryrefslogtreecommitdiff
path: root/addons/crm_iap_lead
diff options
context:
space:
mode:
authorPierre Collinet (pic) <pic@odoo.com>2020-06-11 08:46:25 +0000
committerPierre Collinet (pic) <pic@odoo.com>2020-06-11 12:26:51 +0000
commit4c2db92aecc10103d2c8ef0269d342d20b61e979 (patch)
treebbaf594ebbffe94432a81ad22b3ff22db8994321 /addons/crm_iap_lead
parentf1c99a60fa175095a2b4b2a6270d866e3999e05d (diff)
[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>
Diffstat (limited to 'addons/crm_iap_lead')
-rw-r--r--addons/crm_iap_lead/models/crm_iap_lead_mining_request.py22
-rw-r--r--addons/crm_iap_lead/static/src/js/tours/crm_iap_lead.js41
-rw-r--r--addons/crm_iap_lead/views/crm_iap_lead_templates.xml3
-rw-r--r--addons/crm_iap_lead/views/crm_iap_lead_views.xml95
4 files changed, 100 insertions, 61 deletions
diff --git a/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py b/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py
index 6f30f596d2a..8cd41ebb3bd 100644
--- a/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py
+++ b/addons/crm_iap_lead/models/crm_iap_lead_mining_request.py
@@ -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:
diff --git a/addons/crm_iap_lead/static/src/js/tours/crm_iap_lead.js b/addons/crm_iap_lead/static/src/js/tours/crm_iap_lead.js
new file mode 100644
index 00000000000..577b6cd14d9
--- /dev/null
+++ b/addons/crm_iap_lead/static/src/js/tours/crm_iap_lead.js
@@ -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]');
+}
+});
+
+}); \ No newline at end of file
diff --git a/addons/crm_iap_lead/views/crm_iap_lead_templates.xml b/addons/crm_iap_lead/views/crm_iap_lead_templates.xml
index d6844a6a242..107a1140026 100644
--- a/addons/crm_iap_lead/views/crm_iap_lead_templates.xml
+++ b/addons/crm_iap_lead/views/crm_iap_lead_templates.xml
@@ -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> \ No newline at end of file
diff --git a/addons/crm_iap_lead/views/crm_iap_lead_views.xml b/addons/crm_iap_lead/views/crm_iap_lead_views.xml
index 5621f10109e..e1a967d71b2 100644
--- a/addons/crm_iap_lead/views/crm_iap_lead_views.xml
+++ b/addons/crm_iap_lead/views/crm_iap_lead_views.xml
@@ -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>
- </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>
+
+ <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>
+ </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>