[FIX] web: BasicModel: send correct context
... when reading and writing on a record (especially inside lists). Before this rev., the context sent when reading a record, and when writing records inside lists (editable list views) wasn't correct. This caused an issue in Sales > Products (variant activated) > open a product with variants > click on variant prices > edit the prices of a variant: the value wasn't saved correctly (because the inverse function requires 'active_id' to be in the context and it wasn't the case).
This commit is contained in:
@@ -1546,7 +1546,7 @@ var BasicModel = AbstractModel.extend({
|
||||
model: record.model,
|
||||
method: 'read',
|
||||
args: [[record.res_id], fieldNames],
|
||||
context: _.extend({}, record.context, {bin_size: true}),
|
||||
context: _.extend({}, record.getContext(), {bin_size: true}),
|
||||
})
|
||||
.then(function (result) {
|
||||
if (result.length === 0) {
|
||||
@@ -2505,8 +2505,13 @@ var BasicModel = AbstractModel.extend({
|
||||
continue;
|
||||
}
|
||||
if (field.type === 'one2many' || field.type === 'many2many') {
|
||||
relDataPoint = this._applyX2ManyOperations(this.localData[context[fieldName]]);
|
||||
var ids = relDataPoint.res_ids.slice(0);
|
||||
var ids;
|
||||
if (!context[fieldName] || _.isArray(context[fieldName])) { // no dataPoint created yet
|
||||
ids = context[fieldName] || [];
|
||||
} else {
|
||||
relDataPoint = this._applyX2ManyOperations(this.localData[context[fieldName]]);
|
||||
ids = relDataPoint.res_ids.slice(0);
|
||||
}
|
||||
if (!forDomain) {
|
||||
// when sent to the server, the x2manys values must be a list
|
||||
// of commands in a context, but the list of ids in a domain
|
||||
@@ -3159,7 +3164,7 @@ var BasicModel = AbstractModel.extend({
|
||||
model: list.model,
|
||||
method: 'read',
|
||||
args: [missingIds, fieldNames],
|
||||
context: {} // FIXME
|
||||
context: list.getContext(),
|
||||
});
|
||||
} else {
|
||||
def = $.when(_.map(missingIds, function (id) {
|
||||
@@ -3177,6 +3182,7 @@ var BasicModel = AbstractModel.extend({
|
||||
dataPoint = self.localData[list._cache[id]];
|
||||
} else {
|
||||
dataPoint = self._makeDataPoint({
|
||||
context: list.context,
|
||||
data: _.findWhere(records, {id: id}),
|
||||
fieldsInfo: list.fieldsInfo,
|
||||
fields: list.fields,
|
||||
@@ -3233,7 +3239,7 @@ var BasicModel = AbstractModel.extend({
|
||||
route: '/web/dataset/search_read',
|
||||
model: list.model,
|
||||
fields: fieldNames,
|
||||
context: list.context,
|
||||
context: list.getContext(),
|
||||
domain: list.domain || [],
|
||||
limit: list.limit,
|
||||
offset: list.loadMoreOffset + list.offset,
|
||||
@@ -3244,6 +3250,7 @@ var BasicModel = AbstractModel.extend({
|
||||
var ids = _.pluck(result.records, 'id');
|
||||
var data = _.map(result.records, function (record) {
|
||||
var dataPoint = self._makeDataPoint({
|
||||
context: list.context,
|
||||
data: record,
|
||||
fields: list.fields,
|
||||
fieldsInfo: list.fieldsInfo,
|
||||
|
||||
@@ -4658,6 +4658,61 @@ QUnit.module('relational_fields', {
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('editable list: contexts are correctly sent', function (assert) {
|
||||
assert.expect(5);
|
||||
|
||||
this.data.partner.records[0].timmy = [12];
|
||||
var form = createView({
|
||||
View: FormView,
|
||||
model: 'partner',
|
||||
data: this.data,
|
||||
arch: '<form>' +
|
||||
'<field name="foo"/>' +
|
||||
'<field name="timmy" context="{\'key\': parent.foo}">' +
|
||||
'<tree editable="top">' +
|
||||
'<field name="display_name"/>' +
|
||||
'</tree>' +
|
||||
'</field>' +
|
||||
'</form>',
|
||||
mockRPC: function (route, args) {
|
||||
if (args.method === 'read' && args.model === 'partner') {
|
||||
assert.deepEqual(args.kwargs.context, {
|
||||
active_field: 2,
|
||||
bin_size: true,
|
||||
someKey: 'some value',
|
||||
}, "sent context should be correct");
|
||||
}
|
||||
if (args.method === 'read' && args.model === 'partner_type') {
|
||||
assert.deepEqual(args.kwargs.context, {
|
||||
key: 'yop',
|
||||
someKey: 'some value',
|
||||
}, "sent context should be correct");
|
||||
}
|
||||
if (args.method === 'write') {
|
||||
assert.deepEqual(args.kwargs.context, {
|
||||
active_field: 2,
|
||||
someKey: 'some value',
|
||||
}, "sent context should be correct");
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
session: {
|
||||
user_context: {someKey: 'some value'},
|
||||
},
|
||||
viewOptions: {
|
||||
mode: 'edit',
|
||||
context: {active_field: 2},
|
||||
},
|
||||
res_id: 1,
|
||||
});
|
||||
|
||||
form.$('.o_data_cell:first').click();
|
||||
form.$('.o_field_widget[name=display_name]').val('abc').trigger('input');
|
||||
form.$buttons.find('.o_form_button_save').click();
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('FieldMany2Many');
|
||||
|
||||
QUnit.test('many2many kanban: edition', function (assert) {
|
||||
|
||||
@@ -72,9 +72,15 @@ QUnit.module('Views', {
|
||||
Model: BasicModel,
|
||||
data: this.data,
|
||||
mockRPC: function (route, args) {
|
||||
assert.strictEqual(args.kwargs.context.active_field, 2,
|
||||
"should have sent the correct context");
|
||||
assert.deepEqual(args.kwargs.context, {
|
||||
active_field: 2,
|
||||
bin_size: true,
|
||||
someKey: 'some value',
|
||||
}, "should have sent the correct context");
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
session: {
|
||||
user_context: {someKey: 'some value'},
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1790,9 +1796,23 @@ QUnit.module('Views', {
|
||||
|
||||
this.data.partner.records[0].product_ids = [37, 41];
|
||||
this.params.fieldNames = Object.keys(this.data.partner.fields);
|
||||
this.params.fieldsInfo = {
|
||||
form: {
|
||||
qux: {
|
||||
context: "{'category': category, 'product_ids': product_ids}",
|
||||
domain: "[['id', 'in', category], ['id', 'in', product_ids]]",
|
||||
relatedFields: this.data.partner.fields,
|
||||
},
|
||||
category: {
|
||||
relatedFields: this.data.partner_type.fields,
|
||||
},
|
||||
product_ids: {
|
||||
relatedFields: this.data.product.fields,
|
||||
},
|
||||
},
|
||||
};
|
||||
this.params.viewType = 'form';
|
||||
this.params.res_id = 1;
|
||||
this.params.context = "{'category': category, 'product_ids': product_ids}";
|
||||
this.params.domain = "[['id', 'in', category], ['id', 'in', product_ids]]";
|
||||
|
||||
var model = createModel({
|
||||
Model: BasicModel,
|
||||
@@ -1801,8 +1821,8 @@ QUnit.module('Views', {
|
||||
|
||||
model.load(this.params).then(function (resultID) {
|
||||
var record = model.get(resultID);
|
||||
var context = record.getContext();
|
||||
var domain = record.getDomain();
|
||||
var context = record.getContext({fieldName: 'qux'});
|
||||
var domain = record.getDomain({fieldName: 'qux'});
|
||||
|
||||
assert.deepEqual(context, {
|
||||
category: [12],
|
||||
|
||||
@@ -2,6 +2,7 @@ odoo.define('web.list_tests', function (require) {
|
||||
"use strict";
|
||||
|
||||
var config = require('web.config');
|
||||
var FormView = require('web.FormView');
|
||||
var ListView = require('web.ListView');
|
||||
var testUtils = require('web.test_utils');
|
||||
|
||||
@@ -2430,6 +2431,41 @@ QUnit.module('Views', {
|
||||
list.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('editable list view: contexts are correctly sent', function (assert) {
|
||||
assert.expect(6);
|
||||
|
||||
var list = createView({
|
||||
View: ListView,
|
||||
model: 'foo',
|
||||
data: this.data,
|
||||
arch: '<tree editable="top">' +
|
||||
'<field name="foo"/>' +
|
||||
'</tree>',
|
||||
mockRPC: function (route, args) {
|
||||
var context;
|
||||
if (route === '/web/dataset/search_read') {
|
||||
context = args.context;
|
||||
} else {
|
||||
context = args.kwargs.context;
|
||||
}
|
||||
assert.strictEqual(context.active_field, 2, "context should be correct");
|
||||
assert.strictEqual(context.someKey, 'some value', "context should be correct");
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
session: {
|
||||
user_context: {someKey: 'some value'},
|
||||
},
|
||||
viewOptions: {
|
||||
context: {active_field: 2},
|
||||
},
|
||||
});
|
||||
|
||||
list.$('.o_data_cell:first').click();
|
||||
list.$('.o_field_widget[name=foo]').val('abc').trigger('input');
|
||||
list.$buttons.find('.o_list_button_save').click();
|
||||
|
||||
list.destroy();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user