[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.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user