Master utm promenade amdi

Purpose
=======
Give users a better experience while using the utm campaign module.
Add placeholders to the link tracker module.

Specifications
==============
* Allow to archive a campaign and add the Archived filter.
* Change campaign kanban icons to buttons to ease the access to the
related views. It's not necessary to open the record anymore.
* Add a filter called "My Campaigns" filtering on the current user_id.
* Add a groupby Tags.
* In the list view:
      - Change the column name from "Campaign Name" to "Name"
      - Add bold on the stage field.
      - Add the avatar widget to the Responsible field.
* For the edit stage modal:
      - Make the dialog smaller.
      - Only display the name field.
      - Add a placeholder to the name field.
* Add placeholders to the Mediums and Sources tree views in the link_tracker module.

Task-3240966

closes odoo/odoo#116230

Related: odoo/enterprise#39213
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
This commit is contained in:
Odoo's Mergebot
2023-04-19 11:01:00 +02:00
committed by GitHub
10 changed files with 87 additions and 29 deletions
+15 -6
View File
@@ -8,12 +8,21 @@
<xpath expr="//field[@name='user_id']" position="after">
<field name="use_leads"/>
</xpath>
<xpath expr="//div[@id='utm_statistics']" position="inside">
<div class="me-3"
groups="sales_team.group_sale_salesman"
t-att-title="record.use_leads.raw_value ? 'Leads' : 'Opportunities'">
<i class="fa fa-star text-muted"></i> <small class="fw-bold"><field name="crm_lead_count"/></small>
</div>
<xpath expr="//div[hasclass('oe_kanban_bottom_left')]" position="inside">
<t t-if="record.use_leads.raw_value">
<t t-set="crm_lead_count_label">Leads</t>
</t>
<t t-else="">
<t t-set="crm_lead_count_label">Opportunities</t>
</t>
<a t-if="record.crm_lead_count" href="#" t-att-title="crm_lead_count_label" role="button"
groups="sales_team.group_sale_salesman" data-type="object" data-name="action_redirect_to_leads_opportunities"
class="oe_kanban_action oe_kanban_action_a btn-outline-primary rounded-pill me-1 order-3">
<span class="badge">
<i class="fa fa-fw fa-star" t-att-aria-label="crm_lead_count_label" role="img"/>
<field name="crm_lead_count"/>
</span>
</a>
</xpath>
</field>
</record>
@@ -22,12 +22,16 @@
<xpath expr="//field[@name='stage_id']" position="after">
<field name="click_count"/>
</xpath>
<xpath expr="//div[@id='utm_statistics']" position="inside">
<div class="me-3" title="Clicks">
<i class="fa fa-mouse-pointer text-muted"></i> <small class="fw-bold" t-esc="record.click_count.raw_value" />
</div>
<xpath expr="//div[hasclass('oe_kanban_bottom_left')]" position="inside">
<a t-if="record.click_count" href="#" title="Clicks" role="button"
data-type="action" data-name="%(link_tracker_action_campaign)d"
class="oe_kanban_action oe_kanban_action_a btn-outline-primary rounded-pill me-1 order-4">
<span class="badge">
<i class="fa fa-fw fa-mouse-pointer" aria-label="Clicks" role="img"/>
<t t-out="record.click_count.raw_value"/>
</span>
</a>
</xpath>
</field>
</record>
</odoo>
+16 -9
View File
@@ -6,16 +6,23 @@
<field name="model">utm.campaign</field>
<field name="inherit_id" ref="utm.utm_campaign_view_kanban"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='utm_statistics']" position="inside">
<div class="me-3" title="Revenues" groups="sales_team.group_sale_salesman">
<field name="currency_id" invisible="True"/>
<small class="fw-bold">
<xpath expr="//div[hasclass('oe_kanban_bottom_left')]" position="inside">
<a t-if="record.invoiced_amount" href="#" title="Revenues" role="button"
groups="sales_team.group_sale_salesman" data-type="object" data-name="action_redirect_to_invoiced"
class="oe_kanban_action oe_kanban_action_a btn-outline-primary rounded-pill me-1 order-1">
<span class="badge">
<field name="currency_id" invisible="True"/>
<field name="invoiced_amount" widget="monetary" options="{'currency_field': 'currency_id'}"/>
</small>
</div>
<div class="me-3" title="Quotations" groups="sales_team.group_sale_salesman">
<i class="fa fa-money text-muted"></i> <small class="fw-bold"><field name="quotation_count"/></small>
</div>
</span>
</a>
<a t-if="record.quotation_count" href="#" title="Quotations" role="button"
groups="sales_team.group_sale_salesman" data-type="object" data-name="action_redirect_to_quotations"
class="oe_kanban_action oe_kanban_action_a btn-outline-primary rounded-pill me-1 order-2">
<span class="badge">
<i class="fa fa-fw fa-money me-1" aria-label="Quotations" role="img"/>
<field name="quotation_count"/>
</span>
</a>
</xpath>
</field>
</record>
+2 -1
View File
@@ -9,6 +9,7 @@ class UtmCampaign(models.Model):
_description = 'UTM Campaign'
_rec_name = 'title'
active = fields.Boolean('Active', default=True)
name = fields.Char(string='Campaign Identifier', required=True, compute='_compute_name',
store=True, readonly=False, precompute=True, translate=False)
title = fields.Char(string='Campaign Name', required=True, translate=True)
@@ -19,7 +20,7 @@ class UtmCampaign(models.Model):
stage_id = fields.Many2one(
'utm.stage', string='Stage', ondelete='restrict', required=True,
default=lambda self: self.env['utm.stage'].search([], limit=1),
group_expand='_group_expand_stage_ids')
copy=False, group_expand='_group_expand_stage_ids')
tag_ids = fields.Many2many(
'utm.tag', 'utm_tag_rel',
'tag_id', 'campaign_id', string='Tags')
+1 -1
View File
@@ -62,7 +62,7 @@ class UtmMixin(models.AbstractModel):
"""Based on the model name and on the name of the record, retrieve the corresponding record or create it."""
Model = self.env[model_name]
record = Model.search([('name', '=', name)], limit=1)
record = Model.with_context(active_test=False).search([('name', '=', name)], limit=1)
if not record:
# No record found, create a new one
+8
View File
@@ -21,6 +21,14 @@ class TestUtm(TestUTMCommon):
self.assertNotIn(source_4, source_1 | source_2)
self.assertEqual(source_4.name, 'Source 3')
def test_find_or_create_with_archived_record(self):
archived_campaign = self.env['utm.campaign'].create([{
'active': False,
'name': 'Archived Campaign',
}])
campaign = self.env['utm.mixin']._find_or_create_record('utm.campaign', 'Archived Campaign')
self.assertEqual(archived_campaign, campaign, "An archived record must be found instead of re-created.")
def test_name_generation(self):
"""Test that the name is always unique.
+18 -5
View File
@@ -9,11 +9,17 @@
<field name="tag_ids"/>
<field name="user_id"/>
<field name="is_auto_campaign"/>
<filter string="My Campaigns" name="filter_assigned_to_me" domain="[('user_id', '=', uid)]"
help="Campaigns that are assigned to me"/>
<separator/>
<filter string="Archived" name="filter_inactive" domain="[('active', '=', False)]"/>
<group expand="0" string="Group By">
<filter string="Stage" name="group_stage_id"
context="{'group_by': 'stage_id'}"/>
<filter string="Responsible" name="group_user_id"
context="{'group_by': 'user_id'}"/>
<filter string="Tags" name="group_tags_id"
context="{'group_by': 'tag_ids'}"/>
</group>
</search>
</field>
@@ -30,7 +36,9 @@
<sheet>
<div class="oe_button_box d-flex justify-content-end" name="button_box">
</div>
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<group id="top-group">
<field name="active" invisible="1"/>
<field class="text-break" name="title" string="Campaign Name" placeholder="e.g. Black Friday"/>
<field name="name" invisible="1"/>
<field name="user_id" widget="many2one_avatar_user" domain="[('share', '=', False)]"/>
@@ -48,10 +56,10 @@
<field name="model">utm.campaign</field>
<field name="arch" type="xml">
<tree string="UTM Campaigns" multi_edit="1" sample="1">
<field name="title" readonly="1"/>
<field name="title" string="Name" readonly="1"/>
<field name="name" invisible="1"/>
<field name="user_id"/>
<field name="stage_id"/>
<field name="user_id" widget="many2one_avatar_user"/>
<field name="stage_id" decoration-bf="1"/>
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color'}"/>
</tree>
</field>
@@ -67,7 +75,7 @@
<field name="name" invisible="1"/>
<field class="o_text_overflow" name="title" string="Campaign Name" placeholder="e.g. Black Friday"/>
<field name="user_id" widget="many2one_avatar_user" domain="[('share', '=', False)]"/>
<field name="tag_ids" widget="many2many_tags" options="{'color_field': 'color', 'no_create_edit': True}"/>
<field name="tag_ids" widget="many2many_tags" class="o_field_highlight" options="{'color_field': 'color', 'no_create_edit': True}"/>
</group>
</form>
</field>
@@ -81,6 +89,7 @@
<field name='color'/>
<field name='user_id'/>
<field name="stage_id"/>
<field name='active'/>
<templates>
<t t-name="kanban-menu">
<t t-if="widget.editable">
@@ -89,6 +98,10 @@
<t t-if="widget.deletable">
<a role="menuitem" type="delete" class="dropdown-item">Delete</a>
</t>
<a role="menuitem" class="dropdown-item o_kanban_mailing_active" name="toggle_active" type="object">
<t t-if="record.active.raw_value">Archive</t>
<t t-else="">Restore</t>
</a>
<div role="separator" class="dropdown-divider"/>
<ul class="oe_kanban_colorpicker" data-field="color"/>
</t>
@@ -105,7 +118,7 @@
<ul id="o_utm_actions" class="list-group list-group-horizontal my-0"/>
</div>
<div class="o_kanban_record_bottom h5 mt-2 mb-0">
<div id="utm_statistics" class="d-flex flex-grow-1 text-600 mt-1"/>
<div class="oe_kanban_bottom_left py-auto"/>
<div class="oe_kanban_bottom_right">
<field name="user_id" widget="many2one_avatar_user"/>
</div>
+1 -1
View File
@@ -5,7 +5,7 @@
<field name="model">utm.medium</field>
<field name="arch" type="xml">
<tree string="Mediums" editable="bottom" sample="1">
<field name="name"/>
<field name="name" placeholder='e.g. "Email"'/>
<field name="active" invisible="1"/>
</tree>
</field>
+1 -1
View File
@@ -5,7 +5,7 @@
<field name="model">utm.source</field>
<field name="arch" type="xml">
<tree string="Source" editable="bottom" sample="1">
<field name="name"/>
<field name="name" placeholder='e.g. "Christmas Mailing"'/>
</tree>
</field>
</record>
+16
View File
@@ -22,6 +22,22 @@
</field>
</record>
<record id="utm_stage_view_form" model="ir.ui.view">
<field name="name">utm.stage.view.form</field>
<field name="model">utm.stage</field>
<field name="arch" type="xml">
<form string="Stages">
<sheet>
<group>
<group>
<field name="name" placeholder='e.g. "Brainstorming"'/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<record id="action_view_utm_stage" model="ir.actions.act_window">
<field name="name">UTM Stages</field>
<field name="res_model">utm.stage</field>