From 9cf42366b288359dad90035750b577be7096cfe4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Sun, 21 Feb 2021 18:25:05 +0100
Subject: [PATCH] forms: apply locked fields after a block row is added
 (#51314)

---
 tests/form_pages/test_block.py | 34 ++++++++++++++++++++++++++++++++++
 wcs/forms/root.py              | 26 +++++++++++++-------------
 2 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/tests/form_pages/test_block.py b/tests/form_pages/test_block.py
index 8707f09c3..735ae4536 100644
--- a/tests/form_pages/test_block.py
+++ b/tests/form_pages/test_block.py
@@ -1367,3 +1367,37 @@ def test_block_used_in_later_prefill(pub, blocks_feature):
     resp.form['f1$element2$f123'] = '1'
     resp = resp.form.submit('submit')  # -> 2nd page
     assert resp.form['f3'].value == '9'
+
+
+def test_block_add_and_locked_field(pub, blocks_feature):
+    FormDef.wipe()
+    BlockDef.wipe()
+
+    block = BlockDef()
+    block.name = 'foobar'
+    block.fields = [
+        fields.StringField(id='123', required=True, label='Amount', type='string', varname='amount'),
+    ]
+    block.store()
+
+    formdef = FormDef()
+    formdef.name = 'form title'
+    formdef.fields = [
+        fields.BlockField(id='1', label='test', type='block:foobar', varname='data', max_items=3),
+        fields.StringField(id='2', label='foo', prefill={'type': 'string', 'value': 'Foo', 'locked': True}),
+    ]
+    formdef.store()
+
+    app = get_app(pub)
+    resp = app.get(formdef.get_url())
+    assert resp.form['f2'].value == 'Foo'
+    assert 'readonly' in resp.form['f2'].attrs
+    resp.form['f1$element0$f123'] = 'a'
+    resp = resp.form.submit('f1$add_element')
+    assert resp.form['f2'].value == 'Foo'
+    assert 'readonly' in resp.form['f2'].attrs
+    resp.form['f1$element1$f123'] = 'b'
+    resp = resp.form.submit('f1$add_element')
+    resp.form['f1$element2$f123'] = 'c'
+    resp = resp.form.submit('submit')  # -> validation page
+    resp = resp.form.submit('submit')  # -> submit
diff --git a/wcs/forms/root.py b/wcs/forms/root.py
index a944f3f4e..e487a1cd6 100644
--- a/wcs/forms/root.py
+++ b/wcs/forms/root.py
@@ -360,15 +360,6 @@ class FormPage(Directory, FormTemplateMixin):
             prefilled = False
             locked = False
 
-            if add_button_clicked:
-                if not block:
-                    # do not replay filling fields that are not part of a block
-                    continue
-                if widget and widget.value:
-                    # do not alter subwidget values that may not yet have been
-                    # "commited" to data when an "add row" button is clicked
-                    continue
-
             if field.prefill:
                 prefill_user = get_request().user
                 if get_request().is_in_backoffice():
@@ -379,6 +370,19 @@ class FormPage(Directory, FormTemplateMixin):
                 # "live prefill", regardless of existing data.
                 widget.prefill_attributes = field.get_prefill_attributes()
 
+            if widget and locked:
+                widget.readonly = 'readonly'
+                widget.attrs['readonly'] = 'readonly'
+
+            if add_button_clicked:
+                if not block:
+                    # do not replay filling fields that are not part of a block
+                    continue
+                if widget and widget.value:
+                    # do not alter subwidget values that may not yet have been
+                    # "commited" to data when an "add row" button is clicked
+                    continue
+
             should_prefill = bool(field.prefill)
 
             has_current_value = False
@@ -450,10 +454,6 @@ class FormPage(Directory, FormTemplateMixin):
                     # page).
                     widget.set_error(get_selection_error_text())
 
-                if locked:
-                    widget.readonly = 'readonly'
-                    widget.attrs['readonly'] = 'readonly'
-
                 had_prefill = True
         return had_prefill
 
-- 
2.30.1

