details:   https://code.tryton.org/tryton/commit/ccc9209a41cc
branch:    default
user:      Nicolas Évrard <[email protected]>
date:      Sat Oct 31 14:25:54 2026 +0100
description:
        Validate readonly x2Many field even when they're readonly

        Closes #15181
diffstat:

 sao/src/model.js                                   |  8 +++++---
 tryton/tryton/gui/window/view_form/model/record.py |  9 ++++++---
 2 files changed, 11 insertions(+), 6 deletions(-)

diffs (50 lines):

diff -r bf2f5a9b28e2 -r ccc9209a41cc sao/src/model.js
--- a/sao/src/model.js  Wed Oct 28 17:49:25 2026 +0100
+++ b/sao/src/model.js  Sat Oct 31 14:25:54 2026 +0100
@@ -1329,17 +1329,19 @@
                 return values[0].rec_name;
             });
         },
-        validate: function(fields, softvalidation, pre_validate) {
+        validate: function(field_names, softvalidation, pre_validate) {
             var result = true;
             for (var fname in this.model.fields) {
                 var field = this.model.fields[fname];
-                if (fields && !~fields.indexOf(fname)) {
+                if (field_names && !~field_names.indexOf(fname)) {
                     continue;
                 }
                 if (!this.get_loaded([fname])) {
                     continue;
                 }
-                if (field.description.readonly) {
+                if (field.description.readonly &&
+                    !((field instanceof Sao.field.One2Many) ||
+                        (field instanceof Sao.field.Many2Many))) {
                     continue;
                 }
                 if ([this.group.exclude_field, 
this.group.parent_name].includes(fname)) {
diff -r bf2f5a9b28e2 -r ccc9209a41cc 
tryton/tryton/gui/window/view_form/model/record.py
--- a/tryton/tryton/gui/window/view_form/model/record.py        Wed Oct 28 
17:49:25 2026 +0100
+++ b/tryton/tryton/gui/window/view_form/model/record.py        Sat Oct 31 
14:25:54 2026 +0100
@@ -439,14 +439,17 @@
         except RPCException:
             return ''
 
-    def validate(self, fields=None, softvalidation=False, pre_validate=None):
+    def validate(
+            self, field_names=None, softvalidation=False, pre_validate=None):
         res = True
         for field_name, field in list(self.group.fields.items()):
-            if fields is not None and field_name not in fields:
+            if field_names is not None and field_name not in field_names:
                 continue
             if not self.get_loaded([field_name]):
                 continue
-            if field.attrs.get('readonly'):
+            if (field.attrs.get('readonly')
+                    and not isinstance(
+                        field, (fields.O2MField, fields.M2MField))):
                 continue
             if field_name in {
                     self.group.exclude_field, self.group.parent_name}:

Reply via email to