From b08afa34758298f1f68c8bc0da006a8f1270e846 Mon Sep 17 00:00:00 2001 From: Krzysztof Magusiak Date: Mon, 22 Mar 2021 10:25:58 +0000 Subject: [PATCH] [FIX] web: can update one2many with custom field widget One might design a custom field widget to display/interact with a one2many field. Before this commit, if this field widget triggered a field_changed event to update a related record, it crashed, because the code assumed that there was a view associated with the field. Closes #68276 opw~2468238 closes odoo/odoo#68309 X-original-commit: 3826a2645b94e0f62c719814c4dbe4cc6502e1f2 Signed-off-by: Lucas Perais (lpe) Signed-off-by: Aaron Bohy (aab) Co-authored-by: Aaron Bohy --- .../static/src/js/views/basic/basic_model.js | 4 +- .../relational_fields/field_one2many_tests.js | 71 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js index 4b86e45636e..31fd50ce2bc 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -2053,7 +2053,9 @@ var BasicModel = AbstractModel.extend({ case 'UPDATE': list._changes.push({operation: 'UPDATE', id: command.id}); if (command.data) { - defs.push(this._applyChange(command.id, command.data, { viewType: view.type })); + defs.push(this._applyChange(command.id, command.data, { + viewType: view && view.type, + })); } break; case 'FORGET': diff --git a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js index 425efbee5a9..b4e8c65fd0c 100644 --- a/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js +++ b/addons/web/static/tests/fields/relational_fields/field_one2many_tests.js @@ -9764,6 +9764,77 @@ QUnit.module('fields', {}, function () { form.destroy(); }); + + QUnit.test('update a one2many from a custom field widget', async function (assert) { + // In this test, we define a custom field widget to render/update a one2many + // field. For the update part, we ensure that updating primitive fields of a sub + // record works. There is no guarantee that updating a relational field on the sub + // record would work. Deleting a sub record works as well. However, creating sub + // records isn't supported. There are obviously a lot of limitations, but the code + // hasn't been designed to support all this. This test simply encodes what can be + // done, and this comment explains what can't (and won't be implemented in stable + // versions). + assert.expect(3); + + this.data.partner.records[0].p = [1, 2]; + const MyRelationalField = AbstractField.extend({ + events: { + 'click .update': '_onUpdate', + 'click .delete': '_onDelete', + }, + async _render() { + const records = await this._rpc({ + method: 'read', + model: 'partner', + args: [this.value.res_ids], + }); + this.$el.text(records.map(r => `${r.display_name}/${r.int_field}`).join(', ')); + this.$el.append($('