From a41e5ff690ecf617136ede8cb27cbf39c31e1fa8 Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Tue, 18 Jul 2023 06:50:28 +0000 Subject: [PATCH] [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 --- .../static/tests/sale_product_field_tests.js | 8 ++++- .../src/model/relational_model/static_list.js | 2 +- .../web/static/tests/helpers/mock_server.js | 8 +++++ .../views/fields/one2many_field_tests.js | 34 +++++++++++++++++-- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/addons/sale/static/tests/sale_product_field_tests.js b/addons/sale/static/tests/sale_product_field_tests.js index 4dee19722ac..630c4c4682e 100644 --- a/addons/sale/static/tests/sale_product_field_tests.js +++ b/addons/sale/static/tests/sale_product_field_tests.js @@ -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", diff --git a/addons/web/static/src/model/relational_model/static_list.js b/addons/web/static/src/model/relational_model/static_list.js index 4f35965d826..3e9cf0dbc1d 100644 --- a/addons/web/static/src/model/relational_model/static_list.js +++ b/addons/web/static/src/model/relational_model/static_list.js @@ -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; diff --git a/addons/web/static/tests/helpers/mock_server.js b/addons/web/static/tests/helpers/mock_server.js index 83d96f69a32..df1f2cca40a 100644 --- a/addons/web/static/tests/helpers/mock_server.js +++ b/addons/web/static/tests/helpers/mock_server.js @@ -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) { diff --git a/addons/web/static/tests/views/fields/one2many_field_tests.js b/addons/web/static/tests/views/fields/one2many_field_tests.js index e24ec35a9ec..ad16c4b408d 100644 --- a/addons/web/static/tests/views/fields/one2many_field_tests.js +++ b/addons/web/static/tests/views/fields/one2many_field_tests.js @@ -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: ` +
+ + + + + + +
`, + 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"); });