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:
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user