[FIX] web: allow x2many fields without relation_field

Have a field x2many without relation_field.

Before this commit, a server error was raised because, we send changes
for the non-existing field (relation_field).

Now, we only send to the server the changes for relation_field only if
they exist.

Note that, this commit will also add an exception on the server mock
onchange if we sent changes for non-existings fields.

Part of task~3179751

Part-of: odoo/odoo#114024
This commit is contained in:
Jorge Pinna Puissant
2023-07-24 20:17:56 +02:00
committed by Aaron Bohy
parent 2129d774a2
commit a41e5ff690
4 changed files with 48 additions and 4 deletions
@@ -34,7 +34,13 @@ QUnit.module("Fields", (hooks) => {
},
'sale.order.line': {
fields: {
product_template_id: {
order_id: {
string: "Order Reference",
type: "many2one",
relation: "sale.order",
relation_field: "order_line",
},
product_template_id: {
string: "Product",
type: "many2one",
relation: "product.template",
@@ -618,7 +618,7 @@ export class StaticList extends DataPoint {
async _createNewRecordDatapoint(params = {}) {
const changes = {};
if (!params.withoutParent) {
if (!params.withoutParent && this.config.relationField) {
changes[this.config.relationField] = this._parent._getChanges();
if (!this._parent.isNew) {
changes[this.config.relationField].id = this._parent.resId;
@@ -936,6 +936,14 @@ export class MockServer {
let serverValues = {};
const onchangeValues = {};
for (const fieldName in changes) {
if (!(fieldName in this.models[modelName].fields)) {
throw makeServerError({
type: "ValidationError",
message: `Field ${fieldName} does not exist`,
});
}
}
if (resId) {
serverValues = this.mockRead(modelName, [args[0], fieldsFromView], kwargs)[0];
} else if (firstOnChange) {
@@ -287,6 +287,30 @@ QUnit.module("Fields", (hooks) => {
}
);
QUnit.test("O2M field without relation_field", async function (assert) {
delete serverData.models.partner.fields.p.relation_field;
serverData.models.partner.records[0].p = [2, 4];
await makeView({
type: "form",
resModel: "partner",
serverData,
arch: `
<form>
<field name="p">
<tree>
<field name="foo" invisible="1"/>
<field name="display_name" />
</tree>
</field>
</form>`,
resId: 1,
});
await addRow(target, ".o_field_x2many_list");
assert.containsOnce(target, ".o_dialog");
});
QUnit.test(
"O2M List with pager, decoration and default_order: add and cancel adding",
async function (assert) {
@@ -12807,7 +12831,10 @@ QUnit.module("Fields", (hooks) => {
assert.strictEqual(target.querySelector("[name=int_field] input").value, "10");
assert.containsN(target, ".o_data_row", 2);
assert.deepEqual(getNodesTextContent(target.querySelectorAll(".o_data_cell")), ["first record", "second record"]);
assert.deepEqual(getNodesTextContent(target.querySelectorAll(".o_data_cell")), [
"first record",
"second record",
]);
assert.strictEqual(
target.querySelector(".o_x2m_control_panel .o_pager_counter").innerText,
"1-2 / 3"
@@ -12816,7 +12843,10 @@ QUnit.module("Fields", (hooks) => {
// trigger the onchange
await editInput(target, "[name=int_field] input", "16");
assert.containsN(target, ".o_data_row", 2);
assert.deepEqual(getNodesTextContent(target.querySelectorAll(".o_data_cell")), ["first record", "second record"]);
assert.deepEqual(getNodesTextContent(target.querySelectorAll(".o_data_cell")), [
"first record",
"second record",
]);
assert.containsNone(target, ".o_x2m_control_panel .o_pager");
});