summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYannick Tivisse <yti@odoo.com>2019-07-02 10:41:19 +0200
committerYannick Tivisse <yti@odoo.com>2019-07-12 13:01:36 +0200
commitf896afcc8a54eae3efcdf034e3fd256942f7fa78 (patch)
treef971a366144eacbdcdb77e74650ddaea75dce4d7
parentba0308923030c2dcafa1a1577742fa5233d71a04 (diff)
[FIX] web: Call 'toggle_active' instead of 'write'
Purpose ======= Currently when clicking on 'Archive' or 'Unarchive' on the list view, we write directly on the record {'active': False}, instead of calling toggle_active. Missing that way implementation of numerous business cases. Example - Archive a record --> archive its next activities - (Un)Archive a user --> (Un)Archive its partner - (Un)Archive a product variant --> (Un)Archive its template if there is only one variant - Archive an employee --> Open a wizard to choose an exit plan + describe the departure reason - Archive a route --> Archive its procurement rules - ... Specification ============= - Call toggle_active instead of write when calling toggleActive in the web client. - On the other hand, use actionArchive and actionUnarchive to apply the toggle action on the related records only.
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js54
-rw-r--r--addons/web/static/src/js/views/form/form_controller.js12
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_controller.js3
-rw-r--r--addons/web/static/src/js/views/list/list_controller.js12
-rw-r--r--addons/web/static/tests/views/kanban_model_tests.js9
-rw-r--r--addons/web/static/tests/views/kanban_tests.js56
-rw-r--r--addons/web/static/tests/views/list_tests.js6
-rw-r--r--odoo/models.py15
8 files changed, 154 insertions, 13 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index 60c2f6a3314..311b0ee6947 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -1176,7 +1176,7 @@ var BasicModel = AbstractModel.extend({
* @param {string} parentID id of the parent resource to reload
* @returns {Promise<string>} resolves to the parent id
*/
- toggleActive: function (recordIDs, value, parentID) {
+ toggleActive: function (recordIDs, parentID) {
var self = this;
var parent = this.localData[parentID];
var resIDs = _.map(recordIDs, function (recordID) {
@@ -1184,8 +1184,56 @@ var BasicModel = AbstractModel.extend({
});
return this._rpc({
model: parent.model,
- method: 'write',
- args: [resIDs, { active: value }],
+ method: 'toggle_active',
+ args: [resIDs],
+ })
+ .then(function () {
+ // optionally clear the DataManager's cache
+ self._invalidateCache(parent);
+ return self.reload(parentID);
+ });
+ },
+ /**
+ * Archive the given records
+ *
+ * @param {Array} recordIDs local ids of the records to (un)archive
+ * @param {string} parentID id of the parent resource to reload
+ * @returns {Promise<string>} resolves to the parent id
+ */
+ actionArchive: function (recordIDs, parentID) {
+ var self = this;
+ var parent = this.localData[parentID];
+ var resIDs = _.map(recordIDs, function (recordID) {
+ return self.localData[recordID].res_id;
+ });
+ return this._rpc({
+ model: parent.model,
+ method: 'action_archive',
+ args: [resIDs],
+ })
+ .then(function () {
+ // optionally clear the DataManager's cache
+ self._invalidateCache(parent);
+ return self.reload(parentID);
+ });
+ },
+ /**
+ * Unarchive the given records
+ *
+ * @param {Array} recordIDs local ids of the records to (un)archive
+ * @param {string} parentID id of the parent resource to reload
+ * @returns {Promise<string>} resolves to the parent id
+ */
+ actionUnarchive: function (recordIDs, parentID) {
+ var self = this;
+ var parent = this.localData[parentID];
+ var resIDs = _.map(recordIDs, function (recordID) {
+ return self.localData[recordID].res_id;
+ });
+ return this._rpc({
+ model: parent.model,
+ method: 'action_unarchive',
+ args: [resIDs],
})
.then(function () {
// optionally clear the DataManager's cache
diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js
index 67d1a6aa130..b3a65cc2bde 100644
--- a/addons/web/static/src/js/views/form/form_controller.js
+++ b/addons/web/static/src/js/views/form/form_controller.js
@@ -293,9 +293,15 @@ var FormController = BasicController.extend({
if (ids.length === 0) {
return Promise.resolve();
}
- return this.model
- .toggleActive(ids, !archive, this.handle)
- .then(this.update.bind(this, {}, {reload: false}));
+ if (archive) {
+ return this.model
+ .actionArchive(ids, this.handle)
+ .then(this.update.bind(this, {}, {reload: false}));
+ } else {
+ return this.model
+ .actionUnarchive(ids, this.handle)
+ .then(this.update.bind(this, {}, {reload: false}));
+ }
},
/**
diff --git a/addons/web/static/src/js/views/kanban/kanban_controller.js b/addons/web/static/src/js/views/kanban/kanban_controller.js
index 4ea823ed062..bf39906b8e5 100644
--- a/addons/web/static/src/js/views/kanban/kanban_controller.js
+++ b/addons/web/static/src/js/views/kanban/kanban_controller.js
@@ -569,12 +569,11 @@ var KanbanController = BasicController.extend({
*/
_onToggleActiveRecords: function (ev) {
var self = this;
- var active = !ev.data.archive;
var column = ev.target;
var recordIds = _.pluck(column.records, 'db_id');
if (recordIds.length) {
this.model
- .toggleActive(recordIds, active, column.db_id)
+ .toggleActive(recordIds, column.db_id)
.then(function (dbID) {
var data = self.model.get(dbID);
self.renderer.updateColumn(dbID, data);
diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js
index ffeef454716..bbc1a2cd6ba 100644
--- a/addons/web/static/src/js/views/list/list_controller.js
+++ b/addons/web/static/src/js/views/list/list_controller.js
@@ -265,9 +265,15 @@ var ListController = BasicController.extend({
if (ids.length === 0) {
return Promise.resolve();
}
- return this.model
- .toggleActive(ids, !archive, this.handle)
- .then(this.update.bind(this, {}, {reload: false}));
+ if (archive) {
+ return this.model
+ .actionArchive(ids, this.handle)
+ .then(this.update.bind(this, {}, {reload: false}));
+ } else {
+ return this.model
+ .actionUnarchive(ids, this.handle)
+ .then(this.update.bind(this, {}, {reload: false}));
+ }
},
/**
* Assign on the buttons create additionnal behavior to facilitate the work of the users doing input only using the keyboard
diff --git a/addons/web/static/tests/views/kanban_model_tests.js b/addons/web/static/tests/views/kanban_model_tests.js
index 39b601d9a51..81deca04968 100644
--- a/addons/web/static/tests/views/kanban_model_tests.js
+++ b/addons/web/static/tests/views/kanban_model_tests.js
@@ -135,6 +135,13 @@ QUnit.module('Views', {
var model = createModel({
Model: KanbanModel,
data: this.data,
+ mockRPC: function (route, args) {
+ if (route === '/web/dataset/call_kw/partner/action_archive') {
+ this.data.partner.records[0].active = false;
+ return Promise.resolve();
+ }
+ return this._super.apply(this, arguments);
+ },
});
var params = _.extend(this.params, {
@@ -151,7 +158,7 @@ QUnit.module('Views', {
// archive the column 'xphone'
var recordIDs = _.pluck(xphoneGroup.data, 'id');
- await model.toggleActive(recordIDs, false, xphoneGroup.id);
+ await model.actionArchive(recordIDs, xphoneGroup.id);
state = model.get(resultID);
xphoneGroup = _.findWhere(state.data, {res_id: 37});
assert.strictEqual(xphoneGroup.count, 0, 'xphone group has no record anymore');
diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js
index 7284caeae21..d3ff979de8b 100644
--- a/addons/web/static/tests/views/kanban_tests.js
+++ b/addons/web/static/tests/views/kanban_tests.js
@@ -176,6 +176,20 @@ QUnit.module('Views', {
'<div><field name="foo"/></div>' +
'</t></templates></kanban>',
groupBy: ['bar'],
+ mockRPC: function (route, args) {
+ if (route === '/web/dataset/call_kw/partner/toggle_active') {
+ var partnerIDS = args.args[0];
+ var records = this.data.partner.records
+ _.each(partnerIDS, function(partnerID) {
+ _.find(records, function (record) {
+ return record.id === partnerID;
+ }).active = false;
+ })
+ this.data.partner.records[0].active;
+ return Promise.resolve();
+ }
+ return this._super.apply(this, arguments);
+ },
});
// check archive/restore all actions in kanban header's config dropdown
@@ -219,6 +233,20 @@ QUnit.module('Views', {
'<div><field name="foo"/></div>' +
'</t></templates></kanban>',
groupBy: ['bar'],
+ mockRPC: function (route, args) {
+ if (route === '/web/dataset/call_kw/partner/toggle_active') {
+ var partnerIDS = args.args[0];
+ var records = this.data.partner.records
+ _.each(partnerIDS, function(partnerID) {
+ _.find(records, function (record) {
+ return record.id === partnerID;
+ }).active = false;
+ })
+ this.data.partner.records[0].active;
+ return Promise.resolve();
+ }
+ return this._super.apply(this, arguments);
+ },
});
// check archive/restore all actions in kanban header's config dropdown
@@ -4747,6 +4775,20 @@ QUnit.module('Views', {
'</t></templates>' +
'</kanban>',
groupBy: ['bar'],
+ mockRPC: function (route, args) {
+ if (route === '/web/dataset/call_kw/partner/toggle_active') {
+ var partnerIDS = args.args[0];
+ var records = this.data.partner.records
+ _.each(partnerIDS, function(partnerID) {
+ _.find(records, function (record) {
+ return record.id === partnerID;
+ }).active = false;
+ })
+ this.data.partner.records[0].active;
+ return Promise.resolve();
+ }
+ return this._super.apply(this, arguments);
+ },
});
assert.strictEqual(kanban.$('.o_kanban_group:eq(1) .o_kanban_counter_side').text(), "36",
@@ -4790,6 +4832,20 @@ QUnit.module('Views', {
'</t></templates>' +
'</kanban>',
groupBy: ['bar'],
+ mockRPC: function (route, args) {
+ if (route === '/web/dataset/call_kw/partner/toggle_active') {
+ var partnerIDS = args.args[0];
+ var records = this.data.partner.records
+ _.each(partnerIDS, function(partnerID) {
+ _.find(records, function (record) {
+ return record.id === partnerID;
+ }).active = false;
+ })
+ this.data.partner.records[0].active;
+ return Promise.resolve();
+ }
+ return this._super.apply(this, arguments);
+ },
});
assert.deepEqual(kanban.exportState().resIds, [1, 2, 3, 4]);
diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js
index 797aaea016b..2e6969bab48 100644
--- a/addons/web/static/tests/views/list_tests.js
+++ b/addons/web/static/tests/views/list_tests.js
@@ -1473,6 +1473,10 @@ QUnit.module('Views', {
arch: '<tree><field name="foo"/></tree>',
mockRPC: function (route) {
assert.step(route);
+ if (route === '/web/dataset/call_kw/foo/action_archive') {
+ this.data.foo.records[0].active = false;
+ return Promise.resolve();
+ }
return this._super.apply(this, arguments);
},
});
@@ -1496,7 +1500,7 @@ QUnit.module('Views', {
assert.strictEqual($('.modal').length, 1, 'a confirm modal should be displayed');
await testUtils.dom.click($('.modal-footer .btn-primary'));
assert.containsN(list, 'tbody td.o_list_record_selector', 3, "should have 3 records");
- assert.verifySteps(['/web/dataset/call_kw/foo/write', '/web/dataset/search_read']);
+ assert.verifySteps(['/web/dataset/call_kw/foo/action_archive', '/web/dataset/search_read']);
list.destroy();
});
diff --git a/odoo/models.py b/odoo/models.py
index e23120f36d9..0ab45f403d1 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -4671,6 +4671,21 @@ Fields:
for record in self:
record.active = not record.active
+ def action_archive(self):
+ """
+ Set active=False on a recordset, by calling toggle_active to take the
+ corresponding actions according to the model
+ """
+ return self.filtered(lambda record: record.active).toggle_active()
+
+ @api.multi
+ def action_unarchive(self):
+ """
+ Set active=True on a recordset, by calling toggle_active to take the
+ corresponding actions according to the model
+ """
+ return self.filtered(lambda record: not record.active).toggle_active()
+
def _register_hook(self):
""" stuff to do right after the registry is built """
pass