From ca2995e88a870b4271faa9244fd86948431412f4 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 Signed-off-by: Lucas Perais (lpe) Co-authored-by: Aaron Bohy --- .../static/src/js/views/basic/basic_model.js | 4 +- .../relational_fields/field_one2many_tests.js | 72 +++++++++++++++++++ 2 files changed, 75 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 87322631b4f9f..870df2ec2901e 100644 --- a/addons/web/static/src/js/views/basic/basic_model.js +++ b/addons/web/static/src/js/views/basic/basic_model.js @@ -1948,7 +1948,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 1ef36fea36750..4ab16985f2b57 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 @@ -3,6 +3,7 @@ odoo.define('web.field_one_to_many_tests', function (require) { var AbstractField = require('web.AbstractField'); var AbstractStorageService = require('web.AbstractStorageService'); +var fieldRegistry = require('web.field_registry'); var FormView = require('web.FormView'); var KanbanRecord = require('web.KanbanRecord'); var ListRenderer = require('web.ListRenderer'); @@ -9242,6 +9243,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($('