summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2018-09-21 11:23:31 +0200
committerThibault Delavallée <tde@odoo.com>2018-09-21 11:23:31 +0200
commit68b2a8c5357e2ad2c867bce236c04f339b71e205 (patch)
tree8150357526f91a58d4c1aba0f6bf086c71c7cd24 /addons
parentda03aa31386d50e7f8a5853daabf29ce75e7eaf8 (diff)
parent22e33a7a3d57e1fac63585703ff4cd3a39d4b3e1 (diff)
[MERGE] crm: enforce lost / restore / won flow instead of active / inactive
Leads should not be active / inactive. Purpose of this merge is to use lost / restore flow and hide all active-based filters and buttons. See separate commits for more details. This merge is linked to task ID 1880051 and closes PR #26977 .
Diffstat (limited to 'addons')
-rw-r--r--addons/crm/models/crm_lead.py18
-rw-r--r--addons/crm/report/crm_opportunity_report_views.xml3
-rw-r--r--addons/crm/views/crm_lead_views.xml37
-rw-r--r--addons/crm_project/views/crm_lead_views.xml2
-rw-r--r--addons/sale_crm/views/crm_lead_views.xml3
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_column.js1
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_view.js1
-rw-r--r--addons/web/static/src/xml/kanban.xml2
-rw-r--r--addons/web/static/tests/views/kanban_tests.js71
9 files changed, 107 insertions, 31 deletions
diff --git a/addons/crm/models/crm_lead.py b/addons/crm/models/crm_lead.py
index a68cc5ae48d..b6829a25708 100644
--- a/addons/crm/models/crm_lead.py
+++ b/addons/crm/models/crm_lead.py
@@ -66,7 +66,7 @@ class Lead(models.Model):
name = fields.Char('Opportunity', required=True, index=True)
partner_id = fields.Many2one('res.partner', string='Customer', track_visibility='onchange', track_sequence=1, index=True,
help="Linked partner (optional). Usually created when converting the lead.")
- active = fields.Boolean('Active', default=True)
+ active = fields.Boolean('Active', default=True, track_visibility=True)
date_action_last = fields.Datetime('Last Action', readonly=True)
email_from = fields.Char('Email', help="Email address of the contact", track_visibility='onchange', track_sequence=4, index=True)
website = fields.Char('Website', index=True, help="Website of the contact")
@@ -355,14 +355,6 @@ class Lead(models.Model):
return self.write({'probability': 0, 'active': False})
@api.multi
- def action_set_active(self):
- return self.write({'active': True})
-
- @api.multi
- def action_set_unactive(self):
- return self.write({'active': False})
-
- @api.multi
def action_set_won(self):
""" Won semantic: probability = 100 (active untouched) """
for lead in self:
@@ -459,6 +451,14 @@ class Lead(models.Model):
'context': {'default_type': 'opportunity'}
}
+ def toggle_active(self):
+ """ When re-activating leads and opportunities set their probability
+ to the default stage one. """
+ res = super(Lead, self).toggle_active()
+ for lead in self.filtered(lambda lead: lead.active and lead.stage_id.probability):
+ lead.probability = lead.stage_id.probability
+ return res
+
# ----------------------------------------
# Business Methods
# ----------------------------------------
diff --git a/addons/crm/report/crm_opportunity_report_views.xml b/addons/crm/report/crm_opportunity_report_views.xml
index 07329f850bb..d263b5bc8b0 100644
--- a/addons/crm/report/crm_opportunity_report_views.xml
+++ b/addons/crm/report/crm_opportunity_report_views.xml
@@ -75,9 +75,6 @@
<filter string="Creation Date" name="filter_create_date" date="create_date"/>
<filter string="Expected Closing" name="filter_date_deadline" date="date_deadline"/>
<filter string="Date Closed" name="date_closed_filter" date="date_closed"/>
- <separator/>
- <filter string="Current" name="current" domain="[('active', '=', True)]"/>
- <filter string="Archived" name="archived" domain="[('active', '=', False)]"/>
<group expand="0" string="Extended Filters">
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
<field name="stage_id" widget="selection" domain="['|', ('team_id', '=', False), ('team_id', '=', 'team_id')]"/>
diff --git a/addons/crm/views/crm_lead_views.xml b/addons/crm/views/crm_lead_views.xml
index 5813b5a7378..f4a5ba6ca19 100644
--- a/addons/crm/views/crm_lead_views.xml
+++ b/addons/crm/views/crm_lead_views.xml
@@ -45,14 +45,21 @@
<header>
<button name="%(crm.action_crm_lead2opportunity_partner)d" string="Convert to Opportunity" type="action"
help="Convert to Opportunity" class="oe_highlight" attrs="{'invisible': [('type', '=', 'opportunity')]}"/>
+ <button name="toggle_active"
+ string="Restore"
+ type="object"
+ attrs="{'invisible': ['|', ('probability', '&gt;', 0), ('active', '=', True)]}"/>
+ <button name="action_set_lost"
+ string="Mark as Lost"
+ type="object"
+ attrs="{'invisible': ['&amp;', ('probability', '=', 0), ('active', '=', False)]}"/>
</header>
<sheet>
+ <field name="active" invisible="1"/>
<div class="oe_button_box" name="button_box">
- <button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
- <field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
- </button>
</div>
- <div class="badge badge-success float-right" attrs="{'invisible': [('probability', '&lt;', 100)]}">Won</div>
+ <div class="badge-pill badge-danger float-right" attrs="{'invisible': ['|', ('probability', '&gt;', 0), ('active', '=', True)]}">Lost</div>
+ <div class="badge-pill badge-success float-right" attrs="{'invisible': [('probability', '&lt;', 100)]}">Won</div>
<div class="oe_title">
<label for="name" class="oe_edit_only" string="Lead"/>
<h1><field name="name" placeholder="Describe the lead..."/></h1>
@@ -169,7 +176,7 @@
<field name="model">crm.lead</field>
<field name="priority" eval="100"/>
<field name="arch" type="xml">
- <kanban class="o_kanban_mobile">
+ <kanban class="o_kanban_mobile" archivable="false">
<field name="name"/>
<field name="contact_name"/>
<field name="priority"/>
@@ -306,7 +313,8 @@
<field name="model">crm.lead</field>
<field name="priority" eval="1"/>
<field name="arch" type="xml">
- <kanban default_group_by="stage_id" class="o_kanban_small_column o_opportunity_kanban" on_create="quick_create" quick_create_view="crm.quick_create_opportunity_form">
+ <kanban default_group_by="stage_id" class="o_kanban_small_column o_opportunity_kanban" on_create="quick_create" quick_create_view="crm.quick_create_opportunity_form"
+ archivable="false">
<field name="stage_id" options='{"group_by_tooltip": {"requirements": "Description", "legend_priority": "Use of stars"}}'/>
<field name="color"/>
<field name="priority"/>
@@ -335,8 +343,6 @@
<div class="dropdown-menu" role="menu">
<t t-if="widget.editable"><a role="menuitem" type="edit" class="dropdown-item">Edit</a></t>
<t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t>
- <a t-if="! record.active.value" role="menuitem" name="action_set_active" type="object" class="dropdown-item">Restore</a>
- <a t-if="record.active.value" role="menuitem" name="action_set_unactive" type="object" class="dropdown-item">Archive</a>
<ul class="oe_kanban_colorpicker" data-field="color"/>
</div>
</div>
@@ -400,7 +406,7 @@
<filter string="Won" name="won"
domain="[('probability', '=', 100)]"/>
<filter string="Lost" name="lost"
- domain="[('probability', '=', 0), ('active', '=', False)]"/>
+ domain="['&amp;', ('probability', '=', 0), ('active', '=', False)]"/>
<group expand="0" string="Group By">
<filter string="Salesperson" name="salesperson" context="{'group_by':'user_id'}"/>
<filter string="Sales Channel" name="saleschannel" context="{'group_by':'team_id'}"/>
@@ -439,12 +445,17 @@
type="action" class="oe_highlight"
context="{'default_lead_id': active_id}"
attrs="{'invisible': [('active', '=', False),('probability', '&lt;', 100)]}"/>
+ <button name="toggle_active"
+ string="Restore"
+ type="object"
+ attrs="{'invisible': ['|', ('probability', '&gt;', 0), ('active', '=', True)]}"/>
<field name="stage_id" widget="statusbar"
options="{'clickable': '1', 'fold_field': 'fold'}"
domain="['|', ('team_id', '=', team_id), ('team_id', '=', False)]"
attrs="{'invisible': [('active', '=', False)]}"/>
</header>
<sheet>
+ <field name="active" invisible="1"/>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" type="object"
context="{'partner_id': partner_id}"
@@ -455,13 +466,9 @@
<span class="o_stat_text" attrs="{'invisible': [('meeting_count', '&gt;', 1)]}"> Meeting</span>
</div>
</button>
- <button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive"
- attrs="{'invisible': [('active', '=', True), ('probability', '&lt;', 100)]}">
- <field name="active" widget="boolean_button" options='{"terminology": "archive"}'/>
- </button>
</div>
- <div class="badge badge-danger float-right" attrs="{'invisible': ['|', ('probability', '&gt;', 0), ('active', '=', True)]}">Lost</div>
- <div class="badge badge-success float-right" attrs="{'invisible': [('probability', '&lt;', 100)]}">Won</div>
+ <div class="badge-pill badge-danger float-right" attrs="{'invisible': ['|', ('probability', '&gt;', 0), ('active', '=', True)]}">Lost</div>
+ <div class="badge-pill badge-success float-right" attrs="{'invisible': [('probability', '&lt;', 100)]}">Won</div>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name" placeholder="e.g. Product Pricing"/></h1>
diff --git a/addons/crm_project/views/crm_lead_views.xml b/addons/crm_project/views/crm_lead_views.xml
index 874c9afb997..530f5160f74 100644
--- a/addons/crm_project/views/crm_lead_views.xml
+++ b/addons/crm_project/views/crm_lead_views.xml
@@ -7,7 +7,7 @@
<field name="model">crm.lead</field>
<field name="inherit_id" ref="crm.crm_case_form_view_leads" />
<field name="arch" type="xml">
- <xpath expr="//button[@name='toggle_active']" position="before">
+ <xpath expr="//div[@name='button_box']" position="inside">
<button class="oe_stat_button" type="action" name="%(crm_lead_convert2task_action)d" icon="fa-bug" help="Convert to Task">
<div class="o_field_widget o_stat_info">
<span class="o_stat_text">Convert To</span>
diff --git a/addons/sale_crm/views/crm_lead_views.xml b/addons/sale_crm/views/crm_lead_views.xml
index 5efb023bfd3..8cf8fd91386 100644
--- a/addons/sale_crm/views/crm_lead_views.xml
+++ b/addons/sale_crm/views/crm_lead_views.xml
@@ -8,6 +8,7 @@
<field name="arch" type="xml">
<xpath expr="//button[@name='action_set_won_rainbowman']" position="before">
<button string="New Quotation" name="%(sale_action_quotations_new)d" type="action" class="oe_highlight"
+ attrs="{'invisible': ['&amp;', ('probability', '=', 0), ('active', '=', False)]}"
context="{'search_default_partner_id': partner_id,
'default_partner_id': partner_id,
'default_team_id': team_id,
@@ -16,7 +17,7 @@
'default_origin': name,
'default_source_id': source_id}"/>
</xpath>
- <button name="toggle_active" position="before">
+ <button name="action_schedule_meeting" position="after">
<button class="oe_stat_button" type="action"
name="%(sale_action_quotations)d" icon="fa-pencil-square-o"
context="{'default_partner_id': partner_id, 'search_default_draft': 1}">
diff --git a/addons/web/static/src/js/views/kanban/kanban_column.js b/addons/web/static/src/js/views/kanban/kanban_column.js
index 6fea1c36d32..ef75caca8c0 100644
--- a/addons/web/static/src/js/views/kanban/kanban_column.js
+++ b/addons/web/static/src/js/views/kanban/kanban_column.js
@@ -53,6 +53,7 @@ var KanbanColumn = Widget.extend({
this.grouped_by_m2o = options.grouped_by_m2o;
this.editable = options.editable;
this.deletable = options.deletable;
+ this.archivable = options.archivable;
this.draggable = options.draggable;
this.KanbanRecord = options.KanbanRecord || KanbanRecord; // the KanbanRecord class to use
this.records_editable = options.records_editable;
diff --git a/addons/web/static/src/js/views/kanban/kanban_view.js b/addons/web/static/src/js/views/kanban/kanban_view.js
index 99be6175da3..791e3664668 100644
--- a/addons/web/static/src/js/views/kanban/kanban_view.js
+++ b/addons/web/static/src/js/views/kanban/kanban_view.js
@@ -61,6 +61,7 @@ var KanbanView = BasicView.extend({
this.rendererParams.column_options = {
editable: activeActions.group_edit,
deletable: activeActions.group_delete,
+ archivable: this.arch.attrs.archivable ? JSON.parse(this.arch.attrs.archivable) : true,
group_creatable: activeActions.group_create && !config.device.isMobile,
quick_create: params.isQuickCreateEnabled || this._isQuickCreateEnabled(),
quickCreateView: this.arch.attrs.quick_create_view || null,
diff --git a/addons/web/static/src/xml/kanban.xml b/addons/web/static/src/xml/kanban.xml
index adc213999f2..b91b8844752 100644
--- a/addons/web/static/src/xml/kanban.xml
+++ b/addons/web/static/src/xml/kanban.xml
@@ -23,7 +23,7 @@
<a t-if="widget.editable and widget.id" role="menuitem" class="dropdown-item o_column_edit" href="#">Edit Stage</a>
<a t-if="widget.deletable and widget.id" role="menuitem" class="dropdown-item o_column_delete" href="#">Delete</a>
</t>
- <t t-if="widget.has_active_field">
+ <t t-if="widget.has_active_field and widget.archivable">
<a href="#" class="dropdown-item o_column_archive_records">Archive All</a>
<a href="#" class="dropdown-item o_column_unarchive_records">Unarchive All</a>
</t>
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js
index c967b42a332..1fbe683187d 100644
--- a/addons/web/static/tests/views/kanban_tests.js
+++ b/addons/web/static/tests/views/kanban_tests.js
@@ -148,7 +148,7 @@ QUnit.module('Views', {
kanban.destroy();
});
- QUnit.test('basic grouped rendering with active field', function (assert) {
+ QUnit.test('basic grouped rendering with active field (archivable by default)', function (assert) {
assert.expect(9);
// add active field on partner model and make all records active
@@ -193,6 +193,75 @@ QUnit.module('Views', {
kanban.destroy();
});
+ QUnit.test('basic grouped rendering with active field and archive enabled (archivable true)', function (assert) {
+ assert.expect(7);
+
+ // add active field on partner model and make all records active
+ this.data.partner.fields.active = {string: 'Active', type: 'char', default: true};
+
+ var envIDs = [1, 2, 3, 4]; // the ids that should be in the environment during this test
+ var kanban = createView({
+ View: KanbanView,
+ model: 'partner',
+ data: this.data,
+ arch: '<kanban class="o_kanban_test" archivable="true">' +
+ '<field name="active"/>' +
+ '<field name="bar"/>' +
+ '<templates><t t-name="kanban-box">' +
+ '<div><field name="foo"/></div>' +
+ '</t></templates></kanban>',
+ groupBy: ['bar'],
+ });
+
+ // check archive/restore all actions in kanban header's config dropdown
+ assert.ok(kanban.$('.o_kanban_header:first .o_kanban_config .o_column_archive_records').length, "should be able to archive all the records");
+ assert.ok(kanban.$('.o_kanban_header:first .o_kanban_config .o_column_unarchive_records').length, "should be able to restore all the records");
+
+ // archive the records of the first column
+ assert.strictEqual(kanban.$('.o_kanban_group:last .o_kanban_record').length, 3,
+ "last column should contain 3 records");
+ envIDs = [4];
+ kanban.$('.o_kanban_group:last .o_column_archive_records').click(); // Click on 'Archive All'
+ assert.ok($('.modal').length, 'a confirm modal should be displayed');
+ $('.modal-footer .btn-secondary').click(); // Click on 'Cancel'
+ assert.strictEqual(kanban.$('.o_kanban_group:last .o_kanban_record').length, 3, "still last column should contain 3 records");
+ kanban.$('.o_kanban_group:last .o_column_archive_records').click();
+ assert.ok($('.modal').length, 'a confirm modal should be displayed');
+ $('.modal-footer .btn-primary').click(); // Click on 'Ok'
+ assert.strictEqual(kanban.$('.o_kanban_group:last .o_kanban_record').length, 0, "last column should not contain any records");
+ kanban.destroy();
+ });
+
+ QUnit.test('basic grouped rendering with active field and hidden archive buttons (archivable false)', function (assert) {
+ assert.expect(2);
+
+ // add active field on partner model and make all records active
+ this.data.partner.fields.active = {string: 'Active', type: 'char', default: true};
+
+ var envIDs = [1, 2, 3, 4]; // the ids that should be in the environment during this test
+ var kanban = createView({
+ View: KanbanView,
+ model: 'partner',
+ data: this.data,
+ arch: '<kanban class="o_kanban_test" archivable="false">' +
+ '<field name="active"/>' +
+ '<field name="bar"/>' +
+ '<templates><t t-name="kanban-box">' +
+ '<div><field name="foo"/></div>' +
+ '</t></templates></kanban>',
+ groupBy: ['bar'],
+ });
+
+ // check archive/restore all actions in kanban header's config dropdown
+ assert.strictEqual(
+ kanban.$('.o_kanban_header:first .o_kanban_config .o_column_archive_records').length, 0,
+ "should not be able to archive all the records");
+ assert.strictEqual(
+ kanban.$('.o_kanban_header:first .o_kanban_config .o_column_unarchive_records').length, 0,
+ "should not be able to restore all the records");
+ kanban.destroy();
+ });
+
QUnit.test('pager should be hidden in grouped mode', function (assert) {
assert.expect(1);