diff options
| author | Pierre Collinet (pic) <pic@odoo.com> | 2020-06-11 08:45:42 +0000 |
|---|---|---|
| committer | Pierre Collinet (pic) <pic@odoo.com> | 2020-06-11 12:26:45 +0000 |
| commit | f1c99a60fa175095a2b4b2a6270d866e3999e05d (patch) | |
| tree | 762049280ba63bae2ea143f599a0397f536669a5 | |
| parent | 87f49b0616d67ea00e4e15db81459ed33310abec (diff) | |
[IMP] crm: improve onboarding tour of module CRM
Add an autocomplete for opportunity name. If no name is set when a customer is
selected set the name partner_id.name's Opportunity
Change help title and subtitle to be more explicit. Change title from "Create
an opportunity in your pipeline" to "Create opportunities to keep an eye on
all your ongoing sales talks." Concerning subtitle, if a valid
and active email alias is found : Emails sent to ALIAS@address automatically
create opportunities.
Improve crm onboarding tour text messages and display.
Change menuitem from Teams to Team Pipelines to be more explicit. Update
the corresponding act_window name in the sales_team module.
Make the "schedule an activity" button bigger (100% of the div) and highlight
the entire Schedule button box.
Update test tours accordingly. Since quick create opportunity form is updated
the tests were failing. Reason is a trigger on input:first trying to detect
the field "name". This is not the case after this commit's changes.
Task ID 2226563
Community PR #51587
| -rw-r--r-- | addons/crm/models/crm_lead.py | 15 | ||||
| -rw-r--r-- | addons/crm/static/src/js/tours/crm.js | 98 | ||||
| -rw-r--r-- | addons/crm/views/assets.xml | 7 | ||||
| -rw-r--r-- | addons/crm/views/crm_lead_views.xml | 13 | ||||
| -rw-r--r-- | addons/crm/views/crm_menu_views.xml | 2 | ||||
| -rw-r--r-- | addons/mail/static/src/xml/web_kanban_activity.xml | 8 | ||||
| -rw-r--r-- | addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml | 2 | ||||
| -rw-r--r-- | addons/sales_team/views/crm_team_views.xml | 2 | ||||
| -rw-r--r-- | odoo/addons/test_main_flows/static/tests/tours/main_flow.js | 6 |
9 files changed, 78 insertions, 75 deletions
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py index 8b4a5214e6a..fb9ceca963a 100644 --- a/addons/crm/models/crm_lead.py +++ b/addons/crm/models/crm_lead.py @@ -67,7 +67,9 @@ class Lead(models.Model): _primary_email = 'email_from' # Description - name = fields.Char('Opportunity', index=True, required=True) + name = fields.Char( + 'Opportunity', index=True, required=True, + compute='_compute_name', readonly=False, store=True) user_id = fields.Many2one('res.users', string='Salesperson', index=True, tracking=True, default=lambda self: self.env.user) user_email = fields.Char('User Email', related='user_id.email', readonly=True) user_login = fields.Char('User Login', related='user_id.login', readonly=True) @@ -240,6 +242,12 @@ class Lead(models.Model): lead.day_close = abs((date_close - date_create).days) @api.depends('partner_id') + def _compute_name(self): + for lead in self: + if not lead.name and lead.partner_id and lead.partner_id.name: + lead.name = _("%s's opportunity") % lead.partner_id.name + + @api.depends('partner_id') def _compute_partner_id_values(self): """ compute the new values when partner_id has changed """ for lead in self: @@ -387,6 +395,7 @@ class Lead(models.Model): partner_name = partner.parent_id.name if not partner_name and partner.is_company: partner_name = partner.name + return { 'partner_name': partner_name, 'contact_name': partner.name if not partner.is_company else False, @@ -1077,7 +1086,7 @@ class Lead(models.Model): if self._context.get('default_type') == 'lead': help_title = _('Create a new lead') else: - help_title = _('Create an opportunity in your pipeline') + help_title = _('Create opportunities to keep an eye on all your ongoing sales talks.') alias_record = self.env['mail.alias'].search([ ('alias_name', '!=', False), ('alias_name', '!=', ''), @@ -1088,7 +1097,7 @@ class Lead(models.Model): if alias_record and alias_record.alias_domain and alias_record.alias_name: email = '%s@%s' % (alias_record.alias_name, alias_record.alias_domain) email_link = "<a href='mailto:%s'>%s</a>" % (email, email) - sub_title = _('or send an email to %s') % (email_link) + sub_title = _('Emails sent to %s automatically create opportunities.') % (email_link) return '<p class="o_view_nocontent_smiling_face">%s</p><p class="oe_view_nocontent_alias">%s</p>' % (help_title, sub_title) # ------------------------------------------------------------ diff --git a/addons/crm/static/src/js/tours/crm.js b/addons/crm/static/src/js/tours/crm.js index f0a5813de14..f491f44b0f1 100644 --- a/addons/crm/static/src/js/tours/crm.js +++ b/addons/crm/static/src/js/tours/crm.js @@ -8,93 +8,89 @@ var _t = core._t; tour.register('crm_tour', { url: "/web", + rainbowManMessage: _t("Congrats, best of luck catching such big fish! :)"), }, [tour.stepUtils.showAppsMenuItem(), { trigger: '.o_app[data-menu-xmlid="crm.crm_menu_root"]', - content: _t("Ready to boost your sales? Your <b>Pipeline</b> can be found here, under the <b>CRM</b> app."), - position: 'right', - edition: 'community' + content: _t('Ready to boost your sales? Let\'s have a look at your <b>Pipeline</b>.'), + position: 'bottom', + edition: 'community', }, { trigger: '.o_app[data-menu-xmlid="crm.crm_menu_root"]', - content: _t("Ready to boost your sales? Your <b>Pipeline</b> can be found here, under the <b>CRM</b> app."), + content: _t('Ready to boost your sales? Let\'s have a look at your <b>Pipeline</b>.'), position: 'bottom', edition: 'enterprise', }, { - trigger: ".o-kanban-button-new", + trigger: '.o-kanban-button-new', extra_trigger: '.o_opportunity_kanban', - content: _t("Click here to <b>create your first opportunity</b> and add it to your pipeline."), - position: "bottom", + content: _t("<b>Create your first opportunity.</b>"), + position: 'bottom', }, { - trigger: ".o_kanban_quick_create input:first", - content: _t("<b>Choose a name</b> for your opportunity, example: <i>'Need a new website'</i>"), + trigger: ".o_kanban_quick_create .o_field_widget[name='partner_id']", + content: _t('Look for a Contact or create a new one.<br><i>Tip : Did you know you can search by VAT Number as well?</i>'), position: "right", + run: function (actions) { + actions.text("Brandon Freeman", this.$anchor.find("input")); + }, +}, { + trigger: ".o_kanban_quick_create .o_field_widget[name='name']", + auto: true, +}, { + trigger: '.o_kanban_quick_create .o_field_monetary[name="planned_revenue"]', + content: _t("Define here the Expected Revenue of this Opportunity."), + position: 'right', }, { trigger: ".o_kanban_quick_create .o_kanban_add", - content: _t("Click here to <b>add your opportunity</b>."), + content: _t("Now, <b>add your Opportunity</b> to your Pipeline."), position: "bottom", }, { - trigger: ".o_opportunity_kanban .o_kanban_group:first-child .o_kanban_record:last-child", + trigger: ".o_opportunity_kanban .o_kanban_group:first-child .o_kanban_record:last-child .oe_kanban_content", + extra_trigger: ".o_opportunity_kanban", content: _t("<b>Drag & drop opportunities</b> between columns as you progress in your sales cycle."), - position: "right", + position: "bottom", run: "drag_and_drop .o_opportunity_kanban .o_kanban_group:eq(2) ", }, { trigger: ".o_kanban_record:not(.o_updating) .o_activity_color_default", extra_trigger: ".o_opportunity_kanban", - content: _t("This opportunity has <b>no activity planned</b>."), - position: "bottom" + content: _t("Looks like nothing is planned. :(<br><br><i>Tip : Schedule activities to keep track of everything you have to do!</i>"), + position: "bottom", }, { trigger: ".o_schedule_activity", extra_trigger: ".o_opportunity_kanban", - content: _t("Let's schedule an activity."), - position: "bottom" + content: _t("Let's <b>Schedule an Activity.</b>"), + position: "bottom", + width: 200, }, { - trigger: '.modal-body .o_field_many2one', - extra_trigger: ".o_opportunity_kanban", - content: _t("Choose an activity type.<br/>You can customize them in the general settings."), + trigger: '.modal-footer button[name="action_close_dialog"]', + content: _t("All set. Let’s <b>Schedule</b> it."), position: "bottom", run: function (actions) { actions.auto('.modal-footer button[special=cancel]'); }, }, { + id: "drag_opportunity_to_won_step", + trigger: ".o_opportunity_kanban .o_kanban_record:last-child", + content: _t("Drag your opportunity to <b>Won</b> when you get the deal. Congrats !"), + position: "bottom", + run: "drag_and_drop .o_opportunity_kanban .o_kanban_group:eq(3) ", +}, { trigger: ".o_kanban_record", extra_trigger: ".o_opportunity_kanban", - content: _t("Click on the opportunity to zoom in."), - position: "bottom", + content: _t("Let’s have a look at an Opportunity."), + position: "right", run: function (actions) { - actions.auto(".o_kanban_record .oe_kanban_action[data-type=edit]"); + actions.auto(".o_kanban_record"); }, }, { - trigger: ".o_lead_opportunity_form .o_chatter_button_new_message", - content: _t('<p><b>Send messages</b> to your prospect and get replies automatically attached to this opportunity.</p><p class="mb0">Type <i>\'@\'</i> to mention people - it\'s like cc-ing on emails.</p>'), - position: "bottom" -}, { - trigger: ".breadcrumb-item:not(.active):last", - extra_trigger: '.o_lead_opportunity_form', - content: _t("Use the breadcrumbs to <b>go back to your sales pipeline</b>."), + trigger: ".o_lead_opportunity_form .o_statusbar_status", + content: _t("This bar also allows you to switch stage."), position: "bottom" -}, tour.stepUtils.toggleHomeMenu(), tour.stepUtils.showAppsMenuItem(), { - trigger: '.o_app[data-menu-xmlid="base.menu_administration"]', - content: _t("Configuration options are available in the Settings app."), - position: "bottom", - edition: 'community' }, { - trigger: '.o_app[data-menu-xmlid="base.menu_administration"]', - content: _t("Configuration options are available in the Settings app."), + trigger: ".breadcrumb-item:not(.active):first", + content: _t("Click on the breadcrumb to go back to the Pipeline."), position: "bottom", - edition: 'enterprise' -}, { - trigger: "div#invite_users .o_user_emails", - content: _t("<b>Invite coworkers</b> via email.<br/><i>Enter one email per line.</i>"), - position: "right" -}, tour.stepUtils.toggleHomeMenu(), tour.stepUtils.showAppsMenuItem(), { - trigger: '.o_app[data-menu-xmlid="crm.crm_menu_root"]', - content: _t("Good job! You completed the tour of the CRM app."), - position: 'right', - edition: 'community' -}, { - trigger: '.o_app[data-menu-xmlid="crm.crm_menu_root"]', - content: _t("Good job! You completed the tour of the CRM app."), - position: 'bottom', - edition: 'enterprise' + run: function (actions) { + actions.auto(".breadcrumb-item:not(.active):last"); + } }]); }); diff --git a/addons/crm/views/assets.xml b/addons/crm/views/assets.xml index a06748512c5..e3edab1eee4 100644 --- a/addons/crm/views/assets.xml +++ b/addons/crm/views/assets.xml @@ -1,14 +1,9 @@ <?xml version="1.0" encoding="utf-8"?> <odoo> - <template id="assets_tests" name="CRM Assets Tests" inherit_id="web.assets_tests"> - <xpath expr="." position="inside"> - <script type="text/javascript" src="/crm/static/src/js/tours/crm.js"></script> - </xpath> - </template> - <template id="assets_backend" name="CRM assets backend" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> <script type="text/javascript" src="/crm/static/src/js/systray_activity_menu.js"/> + <script type="text/javascript" src="/crm/static/src/js/tours/crm.js"></script> </xpath> </template> </odoo> diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml index 14deef605e7..8f473228e5a 100644 --- a/addons/crm/views/crm_lead_views.xml +++ b/addons/crm/views/crm_lead_views.xml @@ -401,12 +401,16 @@ <field name="arch" type="xml"> <form> <group> - <field name="name"/> - <field name="partner_id" widget="res_partner_many2one" context="{'res_partner_search_mode': 'customer', 'show_vat': True}"/> - <field name="planned_revenue" widget="monetary" options="{'currency_field': 'company_currency'}"/> + <field name="partner_id" widget="res_partner_many2one" context="{'res_partner_search_mode': 'customer', 'show_vat': True}" string='Organization / Contact'/> + <field name="name" placeholder="e.g. Product Pricing" /> + <field name="email_from" string="Email" /> + <field name="phone" string="Phone" /> + <div class="o_row"> + <field name="planned_revenue" class="oe_inline mr-5" widget="monetary" options="{'currency_field': 'company_currency'}"/> + <field name="priority" class="oe_inline" nolabel="1" widget="priority"/> + </div> <field name="company_currency" invisible="1"/> <field name="company_id" invisible="1"/> - <field name="priority" nolabel="1" widget="priority"/> <field name="partner_name" invisible="1"/> <field name="contact_name" invisible="1"/> <field name="country_id" invisible="1"/> @@ -415,7 +419,6 @@ <field name="street" invisible="1"/> <field name="street2" invisible="1"/> <field name="zip" invisible="1"/> - <field name="phone" invisible="1"/> <field name="mobile" invisible="1"/> <field name="website" invisible="1"/> <field name="function" invisible="1"/> diff --git a/addons/crm/views/crm_menu_views.xml b/addons/crm/views/crm_menu_views.xml index e679fb8f122..e5df3a6f4a0 100644 --- a/addons/crm/views/crm_menu_views.xml +++ b/addons/crm/views/crm_menu_views.xml @@ -26,7 +26,7 @@ sequence="1"/> <menuitem id="sales_team_menu_team_pipeline" - name="Team Pipelines" + name="Teams" parent="crm_menu_sales" action="sales_team.crm_team_salesteams_pipelines_act" groups="sales_team.group_sale_manager" diff --git a/addons/mail/static/src/xml/web_kanban_activity.xml b/addons/mail/static/src/xml/web_kanban_activity.xml index 5b3491ea50c..e6d82e3773f 100644 --- a/addons/mail/static/src/xml/web_kanban_activity.xml +++ b/addons/mail/static/src/xml/web_kanban_activity.xml @@ -25,7 +25,7 @@ <t t-name="mail.KanbanActivityDropdown"> <span role="menuitem" t-if="_.isEmpty(records)" class="dropdown-item-text text-center o_no_activity"> - No activities planned. + <i>Schedule activities to help you get things done.</i> </span> <div t-else="" aria-haspopup="true" role="menu" class="o_activity_log_container dropdown-item bg-100 p-0"> <ul class="o_activity_log list-group list-group-flush mb-2" role="menu"> @@ -50,9 +50,9 @@ </t> </ul> </div> - <div class="dropdown-divider mt-0"/> - <div role="menuitem" class="o_schedule_activity dropdown-header py-1 text-center"> - <button class="btn btn-secondary mb-1"> + <div class="dropdown-divider m-0"/> + <div role="menuitem" class="o_schedule_activity dropdown-header p-0 text-center"> + <button class="btn btn-secondary btn-block p-3"> <i class="fa fa-plus fa-fw"></i><strong>Schedule an activity</strong> </button> </div> diff --git a/addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml b/addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml index f435040ff51..385eb52e73e 100644 --- a/addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml +++ b/addons/sale_crm/wizard/crm_opportunity_to_quotation_views.xml @@ -11,7 +11,7 @@ <field name="lead_id" invisible="1"/> </group> </group> - <group> + <group attrs="{'invisible': [('action','!=','exist')], 'required':[('action', '=','exist')]}"> <group> <field name="partner_id" attrs="{'invisible': [('action','!=','exist')], 'required':[('action', '=','exist')]}"/> </group> diff --git a/addons/sales_team/views/crm_team_views.xml b/addons/sales_team/views/crm_team_views.xml index 7fadf58c4b3..c1ad38e17ef 100644 --- a/addons/sales_team/views/crm_team_views.xml +++ b/addons/sales_team/views/crm_team_views.xml @@ -209,7 +209,7 @@ </record> <record id="crm_team_salesteams_pipelines_act" model="ir.actions.act_window"> - <field name="name">Team Pipelines</field> + <field name="name">Teams</field> <field name="res_model">crm.team</field> <field name="view_mode">kanban,form</field> <field name="view_id" ref="crm_team_salesteams_search"/> diff --git a/odoo/addons/test_main_flows/static/tests/tours/main_flow.js b/odoo/addons/test_main_flows/static/tests/tours/main_flow.js index b7f8faa7e03..bb8f09fff9a 100644 --- a/odoo/addons/test_main_flows/static/tests/tours/main_flow.js +++ b/odoo/addons/test_main_flows/static/tests/tours/main_flow.js @@ -439,7 +439,7 @@ tour.stepUtils.autoExpandMoreButtons('.o_form_readonly'), content: _t("Click here to <b>create your first opportunity</b> and add it to your pipeline."), position: "bottom" }, { - trigger: ".o_kanban_quick_create input:first", + trigger: ".o_kanban_quick_create input[name='name']", content: _t("<b>Choose a name</b> for your opportunity."), position: "right", run: "text the_flow.opportunity", @@ -463,7 +463,7 @@ tour.stepUtils.autoExpandMoreButtons('.o_form_readonly'), }, { mobile: true, trigger: '.o_field_widget[name=name] input', - extra_trigger: ".modal:not(.o_inactive_modal) .modal-title:contains('Customer')", + extra_trigger: ".modal:not(.o_inactive_modal) .modal-title:contains('Organization / Contact')", content: _t('Let\'s enter the name.'), position: 'left', run: 'text the_flow.customer', @@ -474,7 +474,7 @@ tour.stepUtils.autoExpandMoreButtons('.o_form_readonly'), }, { mobile: true, trigger: ".modal-footer .btn-primary:contains('Save')", - extra_trigger: ".modal:not(.o_inactive_modal) .modal-title:contains('Customer')", + extra_trigger: ".modal:not(.o_inactive_modal) .modal-title:contains('Organization / Contact')", content: _t('Save'), position: 'right', }, { |
