[FIX] web: correctly save many2manys inside one2manys
In a form view, if a one2many list view contained a many2many field (e.g. widget many2many_tags), the commands for the embedded many2many weren't generated for newly created one2many subrecords, so this field couldn't be saved.
This commit is contained in:
@@ -1718,6 +1718,8 @@ var BasicModel = AbstractModel.extend({
|
||||
} else if (type === 'many2one' && fieldName in changes) {
|
||||
var value = changes[fieldName];
|
||||
changes[fieldName] = value ? this.localData[value].res_id : false;
|
||||
} else if (changes[fieldName] === null) {
|
||||
changes[fieldName] = false;
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
@@ -1797,13 +1799,13 @@ var BasicModel = AbstractModel.extend({
|
||||
// the didChange variable keeps track of the fact that at
|
||||
// least one id was updated
|
||||
var didChange = false;
|
||||
var command, relRecord;
|
||||
var changes, command, relRecord;
|
||||
for (var i = 0; i < relIds.length; i++) {
|
||||
if (_.contains(keptIds, relIds[i])) {
|
||||
// this is an id that already existed
|
||||
relRecord = _.findWhere(relData, {res_id: relIds[i]});
|
||||
if (!_.isEmpty(relRecord._changes)) {
|
||||
var changes = this._generateChanges(relRecord);
|
||||
changes = this._generateChanges(relRecord);
|
||||
command = x2ManyCommands.update(relRecord.res_id, changes);
|
||||
didChange = true;
|
||||
} else {
|
||||
@@ -1813,8 +1815,8 @@ var BasicModel = AbstractModel.extend({
|
||||
} else if (_.contains(addedIds, relIds[i])) {
|
||||
// this is a new id
|
||||
relRecord = _.findWhere(relData, {res_id: relIds[i]});
|
||||
relRecord = this.get(relRecord.id, {raw: true});
|
||||
commands[fieldName].push(x2ManyCommands.create(_.omit(relRecord.data, 'id')));
|
||||
changes = this._generateChanges(relRecord);
|
||||
commands[fieldName].push(x2ManyCommands.create(changes));
|
||||
}
|
||||
}
|
||||
if (changesOnly && !didChange && addedIds.length === 0 && removedIds.length === 0) {
|
||||
|
||||
@@ -775,6 +775,13 @@ QUnit.module('Views', {
|
||||
this.params.res_id = undefined;
|
||||
this.params.type = 'record';
|
||||
|
||||
var o2mRecordParams = {
|
||||
fields: this.data.product.fields,
|
||||
fieldNames: ['name'],
|
||||
modelName: 'product',
|
||||
type: 'record',
|
||||
};
|
||||
|
||||
var model = createModel({
|
||||
Model: BasicModel,
|
||||
data: this.data,
|
||||
@@ -788,18 +795,15 @@ QUnit.module('Views', {
|
||||
});
|
||||
|
||||
model.load(this.params).then(function (resultID) {
|
||||
|
||||
var record = model.get(resultID);
|
||||
assert.strictEqual(record.data.product_ids.data.length, 0,
|
||||
"one2many should start with a list of length 0");
|
||||
|
||||
model.makeRecord('product', [{
|
||||
name: 'name',
|
||||
string: "Product Name",
|
||||
type: "char",
|
||||
value: "xpod"
|
||||
}
|
||||
]).then(function (relatedRecordID) {
|
||||
// make a default record for the related model
|
||||
model.load(o2mRecordParams).then(function (relatedRecordID) {
|
||||
// update the subrecord
|
||||
model.notifyChanges(relatedRecordID, {name: 'xpod'});
|
||||
// add the subrecord to the o2m of the main record
|
||||
model.notifyChanges(resultID, {
|
||||
product_ids: {operation: "ADD", id: relatedRecordID}
|
||||
});
|
||||
|
||||
@@ -2712,5 +2712,46 @@ QUnit.module('Views', {
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('many2manys inside one2manys are saved correctly', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form string="Partners">' +
|
||||
'<sheet>' +
|
||||
'<field name="p">' +
|
||||
'<tree editable="top">' +
|
||||
'<field name="timmy" widget="many2many_tags"/>' +
|
||||
'</tree>' +
|
||||
'</field>' +
|
||||
'</sheet>' +
|
||||
'</form>',
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'create') {
|
||||
var command = args.args[0].p;
|
||||
assert.deepEqual(command, [[0, false, {
|
||||
display_name: false,
|
||||
timmy: [[6, false, [12]]],
|
||||
}]], "the default partner_type_id should be equal to 12");
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
// add a o2m subrecord with a m2m tag
|
||||
form.$('.o_form_field_x2many_list_row_add a').click();
|
||||
form.$('.o_many2many_tags_cell').click();
|
||||
form.$('.o_form_field_many2one input').click();
|
||||
var $dropdown = form.$('.o_form_field_many2one input').autocomplete('widget');
|
||||
$dropdown.find('li:first()').click(); // select the first tag
|
||||
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user