[FIX] web: generate proper x2many commands in some cases

When creating a new record with a non empty default value for a one2many
field, we did send the command 0 (for each one2many line) instead of the
command 1 (update).  This was a pretty big problem, because then the
server would try to create a line with possibly incomplete data.

For example, it was not possible to create expense sheets: go to expense
menu, select one expense in the list view, click on the action menu
'submit to manager', this opens a form view with a one2many with the
selected expense, then save.  Before this commit, this would lead to a
server error.
This commit is contained in:
Géry Debongnie
2017-10-17 18:21:47 +02:00
parent a1e15b9fce
commit d365a289d4
2 changed files with 27 additions and 6 deletions
@@ -875,7 +875,10 @@ var BasicModel = AbstractModel.extend({
// id never changes, and should not be written
delete record._changes.id;
}
var changes = self._generateChanges(record, {viewType: options.viewType});
var changes = self._generateChanges(record, {viewType: options.viewType, changesOnly: method !== 'create'});
// id field should never be written/changed
delete changes.id;
if (method === 'create') {
var fieldNames = record.getFieldNames();
@@ -2438,7 +2441,7 @@ var BasicModel = AbstractModel.extend({
changes = _.extend({}, record.data, record._changes);
} else {
changes = _.extend({}, record._changes);
};
}
var withReadonly = options.withReadonly || false;
var commands = this._generateX2ManyCommands(record, {
changesOnly: 'changesOnly' in options ? options.changesOnly : true,
@@ -2475,6 +2478,7 @@ var BasicModel = AbstractModel.extend({
changes[fieldName] = false;
}
}
return changes;
},
/**
@@ -2621,7 +2625,13 @@ var BasicModel = AbstractModel.extend({
// this is a new id
relRecord = _.findWhere(relRecordAdded, {res_id: list.res_ids[i]});
changes = this._generateChanges(relRecord, options);
commands[fieldName].push(x2ManyCommands.create(changes));
if ('id' in changes) {
var id = changes.id;
delete changes.id;
commands[fieldName].push(x2ManyCommands.update(id, changes));
} else {
commands[fieldName].push(x2ManyCommands.create(changes));
}
}
}
if (options.changesOnly && !didChange && addedIds.length === 0 && removedIds.length === 0) {
@@ -1062,14 +1062,14 @@ QUnit.module('relational_fields', {
});
QUnit.test('list in form: default_get with x2many create and onchange', function (assert) {
assert.expect(1);
assert.expect(2);
this.data.partner.onchanges.turtles = function (obj) {
assert.deepEqual(
obj.turtles,
[
[0, false, {turtle_foo: 'blip', id: 2}],
[0, false, {turtle_foo: 'kawa', id: 3}]
[1, 2, {turtle_foo: 'blip'}],
[1, 3, {turtle_foo: 'kawa'}]
],
"should have properly created the x2many command list");
};
@@ -1092,10 +1092,21 @@ QUnit.module('relational_fields', {
if (args.method === 'default_get') {
return $.when({turtles: [[6, 0, [2,3]]]});
}
if (args.method === 'create') {
// it would be even better if we did not send the current
// unchanged state with the command 1, but this seems more
// difficult.
assert.deepEqual(args.args[0].turtles, [
[1, 2, {turtle_foo: 'blip'}],
[1, 3, {turtle_foo: 'kawa'}]
], 'should send proper commands to create method');
}
return this._super.apply(this, arguments);
},
});
form.$buttons.find('.o_form_button_save').click();
form.destroy();
});