[FIX] web: create with m2o use the field context

Before this commit, in a list view, the context set on a m2o field
is not used when you edit the field to create a new record.

How:
- Go to a list view with a m2o field containing a context
    <field name="m2o" context={"test":1}/>
- Edit the field the m2o field
- Click on "Create ..."

Before this commit:
The name_create method call does not contain the context defined
on the <field/>

After this commit:
The call to the name_create method contains the context defined
on the <field/>

closes odoo/odoo#100987

X-original-commit: dd1e7fab585ed5a691456632c20097ce443d9d69
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
FrancoisGe
2022-09-23 14:37:04 +02:00
parent 30ad9ac2eb
commit 2edec16782
2 changed files with 73 additions and 20 deletions
+35 -20
View File
@@ -80,6 +80,31 @@ function orderByToString(orderBy) {
return orderBy.map((o) => `${o.name} ${o.asc ? "ASC" : "DESC"}`).join(", ");
}
/**
* @param {RawContext} rawContext
* @param {Context} defaultContext
* @returns {Context}
*/
function processRawContext(rawContext, defaultContext) {
const contexts = [];
if (!rawContext) {
return Object.assign({}, defaultContext);
}
contexts.push({ ...defaultContext, ...rawContext.make() });
while (rawContext.parent) {
rawContext = rawContext.parent;
const context = rawContext.make();
for (const key in context) {
if (key.startsWith("default_")) {
delete context[key];
}
}
contexts.push(context);
}
return Object.assign({}, ...contexts.reverse());
}
/**
* FIXME: don't know where this function should be:
* - on a dataPoint: don't want to make it accessible everywhere (e.g. in Fields)
@@ -255,25 +280,7 @@ class DataPoint {
// -------------------------------------------------------------------------
get context() {
const contexts = [];
let rawContext = this.rawContext;
if (!rawContext) {
return Object.assign({}, this.defaultContext);
}
contexts.push({ ...this.defaultContext, ...rawContext.make() });
while (rawContext.parent) {
rawContext = rawContext.parent;
const context = rawContext.make();
for (const key in context) {
if (key.startsWith("default_")) {
delete context[key];
}
}
contexts.push(context);
}
return Object.assign({}, ...contexts.reverse());
return processRawContext(this.rawContext, this.defaultContext);
}
get fieldNames() {
@@ -999,7 +1006,15 @@ export class Record extends DataPoint {
if (!id && label) {
// only display_name given -> do a name_create
const res = await this.model.orm.call(relation, "name_create", [label], {
context: this.context,
context: processRawContext({
parent: this.rawContext,
make: () => {
return makeContext(
[this.activeFields[fieldName].context],
this.evalContext
);
},
}),
});
// Check if a record is really created. Models without defined
// _rec_name cannot create record based on name_create.
@@ -713,6 +713,44 @@ QUnit.module("Fields", (hooks) => {
}
);
QUnit.test(
"many2ones in list views: create a new record with a context",
async function (assert) {
await makeView({
type: "list",
resModel: "partner",
serverData,
arch: `
<tree editable="top">
<field name="user_id" context="{'default_test': 1, 'test':2 }" />
</tree>`,
context: {
default_yop: 3,
yop: 4,
},
mockRPC(route, args) {
const { method, model, kwargs } = args;
if (method === "name_create" && model === "user") {
const { context } = kwargs;
assert.step(method);
assert.strictEqual(context.default_test, 1);
assert.strictEqual(context.test, 2);
assert.notOk("default_yop" in context);
assert.strictEqual(context.yop, 4);
}
},
});
await click(target.querySelectorAll(".o_data_cell")[0]);
const input = target.querySelector(".o_field_widget[name=user_id] input");
await editInput(input, null, "yy");
await click(target, ".o_field_widget[name=user_id] input");
await selectDropdownItem(target, "user_id", 'Create "yy"');
assert.verifySteps(["name_create"]);
}
);
QUnit.test(
"onchanges on many2ones trigger when editing record in form view",
async function (assert) {