From 71e6d7e510ff9d44fe8deb16f29d50b021709074 Mon Sep 17 00:00:00 2001
From: "Hubert Van de Walle (huvw)" <huvw@odoo.com>
Date: Fri, 15 Oct 2021 15:21:37 +0000
Subject: [PATCH] [FIX] web: basic_renderer: delay destroy after render when
 rerendering widget

Steps to follow

  Edit the account.move view (with studio for example)
  Set the lines readonly property to [["partner_id","=",False]]
  Create a new move
  Add a partner
  Add a product
  Remove the partner
  -> A traceback appears: widget.$el is undefined

Cause of the issue

  widget.$el is used after the widget has been destroyed

The fix was already present in 14.0 (3fd7b2009ec1f16c56c6d0ae87004011c90e204c)
but we still need to keep the test

opw-2557142

closes odoo/odoo#79066

X-original-commit: 0bfc05c2a48f8cc69292c2aed796128814eb6bc9
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
Signed-off-by: Hubert Van De Walle <huvw@odoo.com>
---
 addons/web/static/tests/views/form_tests.js | 54 +++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js
index 094d913f1265..ee683bbf6d37 100644
--- a/addons/web/static/tests/views/form_tests.js
+++ b/addons/web/static/tests/views/form_tests.js
@@ -1377,6 +1377,60 @@ QUnit.module('Views', {
         form.destroy();
     });
 
+    QUnit.test('readonly attrs on lines are re-evaluated on field change 2', async function (assert) {
+        assert.expect(4);
+
+        this.data.partner.records[0].product_ids = [37];
+        this.data.partner.records[0].trululu = false;
+        this.data.partner.onchanges = {
+            trululu(record) {
+                // when trululu changes, push another record in product_ids.
+                // only push a second record once.
+                if (record.product_ids.map(command => command[1]).includes(41)) {
+                    return;
+                }
+                // copy the list to force it as different from the original
+                record.product_ids = record.product_ids.slice();
+                record.product_ids.push([4,41,false]);
+            }
+        };
+
+        this.data.product.records[0].name = 'test';
+        // This one is necessary to have a valid, rendered widget
+        this.data.product.fields.int_field = { type:"integer", string: "intField" };
+
+        var form = await createView({
+            View: FormView,
+            model: 'partner',
+            data: this.data,
+            arch: `
+            <form>
+                <field name="trululu"/>
+                <field name="product_ids" attrs="{'readonly': [['trululu', '=', False]]}">
+                    <tree editable="top"><field name="int_field" widget="handle" /><field name="name"/></tree>
+                </field>
+            </form>
+            `,
+            res_id: 1,
+            viewOptions: {
+                mode: 'edit',
+            },
+        });
+
+        for (let value of [true, false, true, false]) {
+            if (value) {
+                await testUtils.fields.many2one.clickOpenDropdown('trululu')
+                await testUtils.fields.many2one.clickHighlightedItem('trululu')
+                assert.notOk($('.o_field_one2many[name="product_ids"]').hasClass("o_readonly_modifier"), 'lines should not be readonly')
+            } else {
+                await testUtils.fields.editAndTrigger(form.$('.o_field_many2one[name="trululu"] input'), '', ['keyup'])
+                assert.ok($('.o_field_one2many[name="product_ids"]').hasClass("o_readonly_modifier"), 'lines should be readonly')
+            }
+        }
+
+        form.destroy();
+    });
+
     QUnit.test('empty fields have o_form_empty class in readonly mode', async function (assert) {
         assert.expect(8);
 
-- 
GitLab