From ce3798e6ca2f06b40d7897ced9091e96cbd9ce7a Mon Sep 17 00:00:00 2001 From: Adrien Widart Date: Wed, 13 Apr 2022 10:44:06 +0000 Subject: [PATCH] [FIX] web: remove default_ from parent record When having a subview for a 2many field, if an onchange is triggered for that field, the default values of the parent are still in the request context. To reproduce the issue: (Need helpdesk_repair. Use demo data) 1. Helpdesk > Configuration > Helpdesk Teams, edit "Customer Care": - Enable "Repairs" 2. Create a storable and tracked-by-usn product P 3. Update the on-hand quantity: - 1 x P with serial S 4. Helpdesk > Customer Care (Tickets), create a ticket: - Product: P - Lot/Serial number: S 5. Click on Repair and save the repair order R 6. Edit R and add a line in "Parts" Error: on the new line, both Product and Lot/Serial fields are already filled with values P and S, which does not make sens On step 5, when clicking on Repair, the form views of a repair order is loaded with a specific context: https://github.com/odoo/enterprise/blob/deef3c967d43862edf02dbcfc461fb89b064731e/helpdesk_repair/views/helpdesk_views.xml#L31-L34 Therefore, when editing the form and trying to add a new line in Parts, an onchange is triggered but the default values are not removed from the context. As a result, since the model `repair.line` also has two fields called `product_id` and `lot_id`, the default values of the parent (`repair.order`) are used. When computing the context of a subview, the default values of the parent should be removed. OPW-2752436 closes odoo/odoo#89366 X-original-commit: db7423a97fd812fe6df95296fd7a6ca18854933b Signed-off-by: Aaron Bohy (aab) Signed-off-by: Adrien Widart --- .../src/legacy/js/views/basic/basic_model.js | 11 ++++-- .../static/tests/legacy/views/form_tests.js | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/legacy/js/views/basic/basic_model.js b/addons/web/static/src/legacy/js/views/basic/basic_model.js index 53a2d156c56..dc6856fa50c 100644 --- a/addons/web/static/src/legacy/js/views/basic/basic_model.js +++ b/addons/web/static/src/legacy/js/views/basic/basic_model.js @@ -1505,11 +1505,11 @@ var BasicModel = AbstractModel.extend({ var makeDefaultRecords = []; if (additionalContexts){ _.each(additionalContexts, function (context) { - params.context = self._getContext(list, {additionalContext: context}); + params.context = self._getContext(list, {additionalContext: context, sanitize_default_values: true}); makeDefaultRecords.push(self._makeDefaultRecord(list.model, params)); }); } else { - params.context = self._getContext(list); + params.context = self._getContext(list, {sanitize_default_values: true}); makeDefaultRecords.push(self._makeDefaultRecord(list.model, params)); } @@ -3489,7 +3489,12 @@ var BasicModel = AbstractModel.extend({ context.set_eval_context(this._getEvalContext(element)); if (options.full || !(options.fieldName || options.additionalContext)) { - context.add(element.context); + var context_to_add = options.sanitize_default_values ? + _.omit(element.context, function (val, key) { + return _.str.startsWith(key, 'default_'); + }) + : element.context; + context.add(context_to_add); } if (options.fieldName) { var viewType = options.viewType || element.viewType; diff --git a/addons/web/static/tests/legacy/views/form_tests.js b/addons/web/static/tests/legacy/views/form_tests.js index 4ae3bc493a4..654e932099b 100644 --- a/addons/web/static/tests/legacy/views/form_tests.js +++ b/addons/web/static/tests/legacy/views/form_tests.js @@ -2648,6 +2648,44 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('remove default value in subviews', async function (assert) { + assert.expect(2); + + this.data.product.onchanges = {} + this.data.product.onchanges.name = function () {}; + + var form = await createView({ + View: FormView, + model: 'partner', + data: this.data, + viewOptions: { + context: {default_state: "ab"} + }, + arch: '
' + + '' + + '' + + '' + + '' + + '' + + '
', + mockRPC: function (route, args) { + if (route === "/web/dataset/call_kw/partner/onchange") { + assert.deepEqual(args.kwargs.context, { + default_state: 'ab', + }) + } + else if (route === "/web/dataset/call_kw/product/onchange") { + assert.deepEqual(args.kwargs.context, { + default_product_uom_qty: 68, + }) + } + return this._super.apply(this, arguments); + }, + }); + await testUtils.dom.click(form.$('.o_field_x2many_list_row_add a')); + form.destroy(); + }); + QUnit.test('reference field in one2many list', async function (assert) { assert.expect(1);