[FIX] web: evaluate inner x2many context after onchange

Commit [1] recently restricted the context sent to read records
and related records (m2o, x2m) in form views (see commit message
for details). It restricted the context in too many cases though.
For instance, open an existing record (or create a new one) with
an x2many, and add a line in that x2many. If there is an inner
x2many inside, and there're records in that inner x2many by
default, the context sent to read those records does not need to
be restricted, as this is not part of the (initial) read of the
whole form view.

To reproduce the issue, create a new invoice, add a line: the
default tax's name isn't correct ("15% (Sales)" instead of "15%").

[1] fa11f330b8

closes odoo/odoo#115552

X-original-commit: 81c619113fed0b70c2bb69e016b18e1f93ce5983
Signed-off-by: Géry Debongnie <ged@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Aaron Bohy
2023-03-17 07:14:29 +01:00
parent 3a982de28e
commit 2b43835741
2 changed files with 62 additions and 7 deletions
@@ -3128,7 +3128,7 @@ var BasicModel = AbstractModel.extend({
});
record.data[fieldName] = list.id;
if (!fieldInfo.__no_fetch) {
var def = self._readUngroupedList(list).then(function () {
var def = self._readUngroupedList(list, { withoutRecordData: true }).then(function () {
return Promise.all([
self._fetchX2ManysBatched(list),
self._fetchReferencesBatched(list)
@@ -4762,7 +4762,7 @@ var BasicModel = AbstractModel.extend({
* @param {string[]} fieldNames to check and read if missing
* @returns {Promise<Object>}
*/
_readMissingFields: function (list, resIDs, fieldNames) {
_readMissingFields: function (list, resIDs, fieldNames, withoutRecordData) {
var self = this;
var missingIDs = [];
@@ -4783,7 +4783,7 @@ var BasicModel = AbstractModel.extend({
var def;
if (missingIDs.length && fieldNames.length) {
def = self._performRPC({
context: list.getContext({ withoutRecordData: true }),
context: list.getContext({ withoutRecordData: !!withoutRecordData }),
fieldNames: fieldNames,
ids: missingIDs,
method: 'read',
@@ -4989,7 +4989,8 @@ var BasicModel = AbstractModel.extend({
* @param {Object} list a valid resource object
* @returns {Promise<Object>} resolves to the fetched list object
*/
_readUngroupedList: function (list) {
_readUngroupedList: function (list, options) {
options = options || {};
var self = this;
var def = Promise.resolve();
@@ -5001,7 +5002,7 @@ var BasicModel = AbstractModel.extend({
if (list.res_ids.length > list.limit && list.orderedBy.length) {
if (!list.orderedResIDs) {
var fieldNames = _.pluck(list.orderedBy, 'name');
def = this._readMissingFields(list, _.filter(list.res_ids, _.isNumber), fieldNames);
def = this._readMissingFields(list, _.filter(list.res_ids, _.isNumber), fieldNames, options.withoutRecordData);
}
def.then(function () {
self._sortList(list);
@@ -5034,7 +5035,7 @@ var BasicModel = AbstractModel.extend({
resIDs.push(resId);
}
}
return self._readMissingFields(list, resIDs, fieldNames).then(function () {
return self._readMissingFields(list, resIDs, fieldNames, options.withoutRecordData).then(function () {
if (list.res_ids.length <= list.limit) {
self._sortList(list);
} else {
@@ -7440,7 +7440,7 @@ QUnit.module("Fields", (hooks) => {
arch: `
<form>
<field name="foo"/>
<field name="timmy" context="{'key': parent.foo, 'key2': 'hello'}">
<field name="timmy" context="{'key': foo, 'key2': 'hello'}">
<tree editable="top">
<field name="display_name"/>
</tree>
@@ -7491,6 +7491,60 @@ QUnit.module("Fields", (hooks) => {
await clickSave(target);
});
QUnit.test("contexts of nested x2manys are correctly sent (add line)", async function (assert) {
assert.expect(2);
serverData.models.partner.fields.timmy.default = [12];
patchWithCleanup(session, { user_context: { someKey: "some value" } });
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<field name="foo"/>
<field name="p">
<tree editable="top">
<field name="display_name"/>
<field name="timmy" context="{'key': parent.foo, 'key2': 'hello'}" widget="many2many_tags"/>
</tree>
</field>
</form>`,
mockRPC(route, args) {
if (args.method === "onchange") {
assert.deepEqual(
args.kwargs.context,
{
active_field: 2,
someKey: "some value",
uid: 7,
},
"onchange context"
);
}
if (args.method === "read" && args.model === "partner_type") {
assert.deepEqual(
args.kwargs.context,
{
active_field: 2,
key: "yop",
key2: "hello",
someKey: "some value",
uid: 7,
},
"read timmy context"
);
}
},
resId: 1,
context: { active_field: 2 },
});
await click(target.querySelector(".o_field_x2many_list_row_add a"));
});
QUnit.test("resetting invisible one2manys", async function (assert) {
serverData.models.partner.records[0].turtles = [];
serverData.models.partner.onchanges.foo = function (obj) {