From 70406c8bc9dd2d8c7db0d1f36e33f692d1da2219 Mon Sep 17 00:00:00 2001
From: Machac <machac@netgrif.com>
Date: Sun, 1 Jun 2025 22:19:01 +0200
Subject: [PATCH 1/6] [NAE-2119] Fix menuItem

- Added transformation methods `transformCaseFieldField` and `transformFilterFieldField` to `ElasticCaseMappingService`.
- Introduced new classes `CaseField` and `FilterField` in both `elastic` and `spring.elastic` domains.
- Updated `I18nField` to include `translations` using a `Map<String, String>` and annotated it appropriately for ElasticSearch.
- Enhanced `GetDataEvent` to handle null values safely in `getMessage`.
- Modified `User` domain to handle `tel` attribute when `attributes` is null.
- Fixed formatting of multiple methods for better readability.
- Updated `docker-compose.yml` to correct misplaced `networks` and `volumes` definition.
---
 application-engine/docker-compose.yml         | 15 ++--
 .../service/ElasticCaseMappingService.java    | 77 ++++++++++++++-----
 .../engine/objects/auth/domain/User.java      |  7 ++
 .../objects/elastic/domain/CaseField.java     | 15 ++++
 .../domain/FieldWithAllowedNetsField.java     | 24 ++++++
 .../objects/elastic/domain/FilterField.java   | 22 ++++++
 .../objects/elastic/domain/I18nField.java     |  5 +-
 .../event/events/data/GetDataEvent.java       |  5 +-
 .../spring/elastic/domain/CaseField.java      | 26 +++++++
 .../spring/elastic/domain/FilterField.java    | 32 ++++++++
 .../spring/elastic/domain/I18nField.java      | 11 ++-
 11 files changed, 207 insertions(+), 32 deletions(-)
 create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
 create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java
 create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java
 create mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java
 create mode 100644 nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java

diff --git a/application-engine/docker-compose.yml b/application-engine/docker-compose.yml
index 3e275c95c1..40842a1cf8 100644
--- a/application-engine/docker-compose.yml
+++ b/application-engine/docker-compose.yml
@@ -51,13 +51,6 @@ services:
       - MINIO_ROOT_USER=root
       - MINIO_ROOT_PASSWORD=password
       - MINIO_DEFAULT_BUCKETS=default
-networks:
-  minionetwork:
-    driver: bridge
-
-volumes:
-  minio_data:
-    driver: local
 
 #  kibana:
 #    image: docker.elastic.co/kibana/kibana:8.10.4
@@ -67,3 +60,11 @@ volumes:
 #      - docker-elastic
 #    ports:
 #      - "5601:5601"
+
+networks:
+  minionetwork:
+    driver: bridge
+
+volumes:
+  minio_data:
+    driver: local
\ No newline at end of file
diff --git a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
index ef8e93af15..fa6c8161bf 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
@@ -79,6 +79,10 @@ protected Optional<DataField> transformDataField(String fieldId, Case useCase) {
             return this.transformUserListField(caseField);
         } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) {
             return this.transformI18nField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) netField);
+        } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField) {
+            return this.transformCaseFieldField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField) netField);
+        } else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField) {
+            return this.transformFilterFieldField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField) netField);
         } else {
             String string = caseField.getValue().toString();
             if (string == null)
@@ -87,7 +91,8 @@ protected Optional<DataField> transformDataField(String fieldId, Case useCase) {
         }
     }
 
-    protected Optional<DataField> transformMultichoiceMapField(com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceMap, MultichoiceMapField netField) {
+    protected Optional<DataField> transformMultichoiceMapField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceMap, MultichoiceMapField netField) {
         Optional<Set> optValues = this.getMultichoiceValue(multichoiceMap, netField);
         if (!optValues.isPresent()) {
             return Optional.empty();
@@ -101,27 +106,44 @@ protected Optional<DataField> transformMultichoiceMapField(com.netgrif.applicati
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.MapField(values));
     }
 
-    protected Optional<DataField> transformI18nField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField netField) {
+    protected Optional<DataField> transformI18nField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField
+                     dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField netField) {
         Set<String> keys = ((I18nString) dataField.getValue()).getTranslations().keySet();
         Set<String> values = new HashSet<>(((I18nString) dataField.getValue()).getTranslations().values());
         values.add(((I18nString) dataField.getValue()).getDefaultValue());
-        return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.I18nField(keys, values));
+        return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.I18nField(keys, values, ((I18nString) dataField.getValue()).getTranslations()));
     }
 
-    protected Optional<DataField> transformEnumerationMapField(com.netgrif.application.engine.objects.workflow.domain.DataField enumMap, EnumerationMapField netField) {
+    protected Optional<DataField> transformCaseFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField netField) {
+        String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
+        String[] referencedCases = ((List<String>) dataField.getValue()).toArray(new String[0]);
+        return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.CaseField(referencedCases,allowedNets));
+    }
+
+    protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
+        String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
+        Map<String, Object> filterMetadata = dataField.getFilterMetadata();
+        return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata));
+    }
+
+    protected Optional<DataField> transformEnumerationMapField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField enumMap, EnumerationMapField netField) {
         Map<String, I18nString> options = this.getFieldOptions(enumMap, netField);
         String selectedKey = (String) enumMap.getValue();
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.MapField(new AbstractMap.SimpleEntry<>(selectedKey, collectTranslations(options.get(selectedKey)))));
     }
 
-    private Map<String, I18nString> getFieldOptions(com.netgrif.application.engine.objects.workflow.domain.DataField map, MapOptionsField<I18nString, ?> netField) {
+    private Map<String, I18nString> getFieldOptions
+            (com.netgrif.application.engine.objects.workflow.domain.DataField map, MapOptionsField<I18nString, ?> netField) {
         if (map.getOptions() != null) {
             return map.getOptions();
         }
         return netField.getOptions();
     }
 
-    protected Optional<DataField> transformMultichoiceField(com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceField, MultichoiceField netField) {
+    protected Optional<DataField> transformMultichoiceField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceField, MultichoiceField netField) {
         Optional<Set> optValues = this.getMultichoiceValue(multichoiceField, netField);
         if (!optValues.isPresent()) {
             return Optional.empty();
@@ -142,7 +164,8 @@ protected Optional<DataField> transformMultichoiceField(com.netgrif.application.
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(translations.toArray(new String[0])));
     }
 
-    private Optional<Set> getMultichoiceValue(com.netgrif.application.engine.objects.workflow.domain.DataField multichoice, Field netField) {
+    private Optional<Set> getMultichoiceValue(com.netgrif.application.engine.objects.workflow.domain.DataField
+                                                      multichoice, Field netField) {
         if (multichoice.getValue() instanceof Set) {
             return Optional.of((Set) multichoice.getValue());
         } else if (multichoice.getValue() instanceof Collection) {
@@ -157,7 +180,8 @@ private Optional<Set> getMultichoiceValue(com.netgrif.application.engine.objects
         }
     }
 
-    protected Optional<DataField> transformEnumerationField(com.netgrif.application.engine.objects.workflow.domain.DataField enumField) {
+    protected Optional<DataField> transformEnumerationField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField enumField) {
         Object value = enumField.getValue();
         if (value instanceof I18nString) {
             return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(this.collectTranslations((I18nString) value).toArray(new String[0])));
@@ -180,25 +204,29 @@ protected List<String> collectTranslations(I18nString i18nString) {
         return translations;
     }
 
-    protected Optional<DataField> transformNumberField(com.netgrif.application.engine.objects.workflow.domain.DataField numberField) {
+    protected Optional<DataField> transformNumberField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField numberField) {
         if (numberField.getValue() instanceof Integer) { //TODO: Refactor
             return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.NumberField(Double.parseDouble(numberField.getValue().toString())));
         }
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.NumberField((Double) numberField.getValue()));
     }
 
-    protected Optional<DataField> transformButtonField(com.netgrif.application.engine.objects.workflow.domain.DataField buttonField) {
+    protected Optional<DataField> transformButtonField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField buttonField) {
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.ButtonField((Integer) buttonField.getValue()));
     }
 
-    protected Optional<DataField> transformUserField(com.netgrif.application.engine.objects.workflow.domain.DataField userField) {
+    protected Optional<DataField> transformUserField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField userField) {
         UserFieldValue user = (UserFieldValue) userField.getValue();
         if (user == null)
             return Optional.empty();
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.UserField(this.transformUserValue(user)));
     }
 
-    protected Optional<DataField> transformUserListField(com.netgrif.application.engine.objects.workflow.domain.DataField userListField) {
+    protected Optional<DataField> transformUserListField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField userListField) {
         UserListFieldValue userListValue = (UserListFieldValue) userListField.getValue();
         UserField.UserMappingData[] userMappingData = userListValue.getUserValues().stream().map(this::transformUserListValue).toArray(UserField.UserMappingData[]::new);
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.UserListField(userMappingData));
@@ -224,7 +252,9 @@ private StringBuilder buildFullName(String name, String surname) {
         return fullName;
     }
 
-    protected Optional<DataField> transformDateField(com.netgrif.application.engine.objects.workflow.domain.DataField dateField, com.netgrif.application.engine.objects.petrinet.domain.dataset.DateField netField) {
+    protected Optional<DataField> transformDateField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField
+                     dateField, com.netgrif.application.engine.objects.petrinet.domain.dataset.DateField netField) {
         if (dateField.getValue() instanceof LocalDate) {
             LocalDate date = (LocalDate) dateField.getValue();
             return formatDateField(LocalDateTime.of(date, LocalTime.NOON));
@@ -239,7 +269,8 @@ protected Optional<DataField> transformDateField(com.netgrif.application.engine.
         }
     }
 
-    protected Optional<DataField> transformDateTimeField(com.netgrif.application.engine.objects.workflow.domain.DataField dateTimeField, DateTimeField netField) {
+    protected Optional<DataField> transformDateTimeField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField dateTimeField, DateTimeField netField) {
         if (dateTimeField.getValue() instanceof LocalDateTime) {
             return formatDateField((LocalDateTime) dateTimeField.getValue());
         } else if (dateTimeField.getValue() instanceof Date) {
@@ -252,7 +283,8 @@ protected Optional<DataField> transformDateTimeField(com.netgrif.application.eng
         }
     }
 
-    private LocalDateTime transformDateValueField(com.netgrif.application.engine.objects.workflow.domain.DataField dateValueField) {
+    private LocalDateTime transformDateValueField(com.netgrif.application.engine.objects.workflow.domain.DataField
+                                                          dateValueField) {
         return ((Date) dateValueField.getValue()).toInstant()
                 .atZone(ZoneId.systemDefault())
                 .toLocalDateTime();
@@ -264,26 +296,31 @@ private Optional<DataField> formatDateField(LocalDateTime date) {
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.DateField(date.format(DateTimeFormatter.BASIC_ISO_DATE), date));
     }
 
-    protected Optional<DataField> transformBooleanField(com.netgrif.application.engine.objects.workflow.domain.DataField booleanField) {
+    protected Optional<DataField> transformBooleanField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField booleanField) {
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.BooleanField((Boolean) booleanField.getValue()));
     }
 
-    protected Optional<DataField> transformTextField(com.netgrif.application.engine.objects.workflow.domain.DataField textField) {
+    protected Optional<DataField> transformTextField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField textField) {
         if (textField.getValue() == null) {
             return Optional.empty();
         }
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField((String) textField.getValue()));
     }
 
-    protected Optional<DataField> transformFileField(com.netgrif.application.engine.objects.workflow.domain.DataField fileField) {
+    protected Optional<DataField> transformFileField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField fileField) {
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FileField((FileFieldValue) fileField.getValue()));
     }
 
-    protected Optional<DataField> transformFileListField(com.netgrif.application.engine.objects.workflow.domain.DataField fileListField) {
+    protected Optional<DataField> transformFileListField
+            (com.netgrif.application.engine.objects.workflow.domain.DataField fileListField) {
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FileField(((FileListFieldValue) fileListField.getValue()).getNamesPaths().toArray(new FileFieldValue[0])));
     }
 
-    protected Optional<DataField> transformOtherFields(com.netgrif.application.engine.objects.workflow.domain.DataField otherField, Field netField) {
+    protected Optional<DataField> transformOtherFields
+            (com.netgrif.application.engine.objects.workflow.domain.DataField otherField, Field netField) {
         log.warn("Field of type " + netField.getClass().getCanonicalName() + " is not supported for indexation by default. Indexing the toString() representation of its value...");
         return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(otherField.getValue().toString()));
     }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java
index b419c48d53..8ce9efe2b4 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/auth/domain/User.java
@@ -341,6 +341,9 @@ public boolean validateRequiredAttributes() {
 
     @Override
     public String getTelNumber() {
+        if (attributes == null) {
+            return null;
+        }
         if (attributes.containsKey("tel")) {
             return (String) attributes.get("tel").getValue();
         }
@@ -349,9 +352,13 @@ public String getTelNumber() {
 
     @Override
     public void setTelNumber(String telNumber) {
+        if (attributes == null) {
+            attributes = new HashMap<>();
+        }
         if (attributes.containsKey("tel")) {
             ((Attribute<String>) attributes.get("tel")).setValue(telNumber);
         }
         attributes.put("tel", new Attribute<>(telNumber, false));
     }
+
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
new file mode 100644
index 0000000000..76c34dcbbc
--- /dev/null
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
@@ -0,0 +1,15 @@
+package com.netgrif.application.engine.objects.elastic.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public abstract class CaseField extends FieldWithAllowedNetsField {
+
+    public CaseField(String[] fullTextValue, String[] allowedNets) {
+        super(fullTextValue, allowedNets);
+    }
+}
\ No newline at end of file
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java
new file mode 100644
index 0000000000..6e8523c50c
--- /dev/null
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java
@@ -0,0 +1,24 @@
+package com.netgrif.application.engine.objects.elastic.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public abstract class FieldWithAllowedNetsField extends DataField {
+
+    public String[] allowedNets;
+
+    public FieldWithAllowedNetsField(String fullTextValue, String[] allowedNets) {
+        super(fullTextValue);
+        this.allowedNets = allowedNets;
+    }
+
+    public FieldWithAllowedNetsField(String[] fullTextValue, String[] allowedNets) {
+        super(fullTextValue);
+        this.allowedNets = allowedNets;
+    }
+}
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java
new file mode 100644
index 0000000000..30e8efa95c
--- /dev/null
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java
@@ -0,0 +1,22 @@
+package com.netgrif.application.engine.objects.elastic.domain;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public abstract class FilterField extends FieldWithAllowedNetsField {
+
+    public Map<String, Object> filterMetadata;
+
+    public FilterField(String fullTextValue, String[] allowedNets, Map<String, Object> filterMetadata) {
+        super(fullTextValue, allowedNets);
+        this.filterMetadata = filterMetadata != null ? filterMetadata : new HashMap<>();
+    }
+}
+
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
index dbad7aaf8e..2317a3de9c 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
@@ -4,6 +4,7 @@
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
+import java.util.Map;
 import java.util.Set;
 
 @Data
@@ -13,7 +14,9 @@ public abstract class I18nField extends TextField {
 
     public String[] keyValue;
 
-    public I18nField(Set<String> keys, Set<String> values) {
+    public Map<String, String> translations;
+
+    public I18nField(Set<String> keys, Set<String> values, Map<String, String> translations) {
         super(new String[0]);
         this.keyValue = keys.toArray(new String[0]);
         this.textValue = values.toArray(new String[0]);
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java
index 44a1093f56..73236cdda7 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/event/events/data/GetDataEvent.java
@@ -5,6 +5,7 @@
 import com.netgrif.application.engine.objects.workflow.domain.eventoutcomes.dataoutcomes.GetDataEventOutcome;
 import lombok.Getter;
 
+
 @Getter
 public class GetDataEvent extends DataEvent {
 
@@ -21,12 +22,12 @@ public GetDataEvent(GetDataEventOutcome eventOutcome, IUser user) {
     }
 
     public GetDataEvent(GetDataEventOutcome eventOutcome, EventPhase eventPhase, IUser user) {
-        super(eventOutcome,eventPhase, user);
+        super(eventOutcome, eventPhase, user);
         this.eventOutcome = eventOutcome;
     }
 
     @Override
     public String getMessage() {
-        return "GetDataEvent: GET [" + eventOutcome.getMessage().toString() + "]";
+        return "GetDataEvent: GET [" + (eventOutcome.getMessage() == null ? "NULL" : eventOutcome.getMessage().toString()) + "]";
     }
 }
diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java
new file mode 100644
index 0000000000..a91aca3d06
--- /dev/null
+++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/CaseField.java
@@ -0,0 +1,26 @@
+package com.netgrif.application.engine.adapter.spring.elastic.domain;
+
+import lombok.NoArgsConstructor;
+import org.springframework.data.elasticsearch.annotations.Field;
+
+import static org.springframework.data.elasticsearch.annotations.FieldType.Text;
+
+@NoArgsConstructor
+public class CaseField extends com.netgrif.application.engine.objects.elastic.domain.CaseField {
+
+    public CaseField(String[] values, String[] allowedNets) {
+        super(values, allowedNets);
+    }
+
+    @Override
+    @Field(type = Text)
+    public String[] getFulltextValue() {
+        return super.getFulltextValue();
+    }
+
+    @Field(type = Text)
+    public String[] getAllowedNets() {
+        return super.allowedNets;
+    }
+
+}
diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java
new file mode 100644
index 0000000000..e3322b1fe3
--- /dev/null
+++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/FilterField.java
@@ -0,0 +1,32 @@
+package com.netgrif.application.engine.adapter.spring.elastic.domain;
+
+import lombok.NoArgsConstructor;
+import org.springframework.data.elasticsearch.annotations.Field;
+
+import java.util.Map;
+
+import static org.springframework.data.elasticsearch.annotations.FieldType.*;
+
+@NoArgsConstructor
+public class FilterField extends com.netgrif.application.engine.objects.elastic.domain.FilterField {
+
+    public FilterField(String value, String[] allowedNets, Map<String, Object> filterMetadata) {
+        super(value, allowedNets, filterMetadata);
+    }
+
+    @Override
+    @Field(type = Text)
+    public String[] getFulltextValue() {
+        return super.getFulltextValue();
+    }
+
+    @Field(type = Text)
+    public String[] getAllowedNets() {
+        return super.allowedNets;
+    }
+
+    @Field(type = Flattened)
+    public Map<String, Object> getFilterMetadata() {
+        return super.filterMetadata;
+    }
+}
diff --git a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java
index a5212d4e0d..6e7345b559 100644
--- a/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java
+++ b/nae-spring-core-adapter/src/main/java/com/netgrif/application/engine/adapter/spring/elastic/domain/I18nField.java
@@ -3,15 +3,17 @@
 import lombok.NoArgsConstructor;
 import org.springframework.data.elasticsearch.annotations.Field;
 
+import java.util.Map;
 import java.util.Set;
 
+import static org.springframework.data.elasticsearch.annotations.FieldType.Flattened;
 import static org.springframework.data.elasticsearch.annotations.FieldType.Text;
 
 @NoArgsConstructor
 public class I18nField extends com.netgrif.application.engine.objects.elastic.domain.I18nField {
 
-    public I18nField(Set<String> keys, Set<String> values) {
-        super(keys, values);
+    public I18nField(Set<String> keys, Set<String> values, Map<String, String> translations) {
+        super(keys, values, translations);
     }
 
     @Override
@@ -24,4 +26,9 @@ public String[] getFulltextValue() {
     public String[] getKeyValue() {
         return super.getKeyValue();
     }
+
+    @Field(type = Flattened)
+    public Map<String,String> getTranslations() {
+        return super.getTranslations();
+    }
 }

From a5cccb522c295afc107cd0b00fb8a6e1882e8be3 Mon Sep 17 00:00:00 2001
From: renczesstefan <renczes.stefan@gmail.com>
Date: Mon, 2 Jun 2025 09:58:27 +0200
Subject: [PATCH 2/6] - capitalized filter type

---
 .../petrinet/domain/dataset/logic/action/ActionDelegate.groovy | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index 0e0a2a4cdc..c2d608ed34 100644
--- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -1,5 +1,6 @@
 package com.netgrif.application.engine.petrinet.domain.dataset.logic.action
 
+import com.mchange.v2.lang.StringUtils
 import com.netgrif.application.engine.AsyncRunner
 import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService
 import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase
@@ -1610,7 +1611,7 @@ class ActionDelegate {
         def setDataMap = [
                 (DefaultFiltersRunner.FILTER_TYPE_FIELD_ID)      : [
                         "type" : "enumeration_map",
-                        "value": type
+                        "value": type.capitalize()
                 ],
                 (DefaultFiltersRunner.FILTER_VISIBILITY_FIELD_ID): [
                         "type" : "enumeration_map",

From a1418a13f8d5b28ef8a0aefca2dbd535f583bb71 Mon Sep 17 00:00:00 2001
From: renczesstefan <renczes.stefan@gmail.com>
Date: Mon, 2 Jun 2025 10:48:07 +0200
Subject: [PATCH 3/6] - capitalized filter type

---
 .../petrinet/domain/dataset/logic/action/ActionDelegate.groovy | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index c2d608ed34..d1909a31f2 100644
--- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -1601,6 +1601,7 @@ class ActionDelegate {
     @NamedVariant
     Case createFilter(def title, String query, String type, List<String> allowedNets,
                       String icon, String visibility, def filterMetadata) {
+        type = type.capitalize();
         Case filterCase = createCase(FilterRunner.FILTER_PETRI_NET_IDENTIFIER, title as String)
         filterCase.setIcon(icon)
         filterCase.dataSet[DefaultFiltersRunner.FILTER_I18N_TITLE_FIELD_ID].value = (title instanceof I18nString) ? title : new I18nString(title as String)
@@ -1611,7 +1612,7 @@ class ActionDelegate {
         def setDataMap = [
                 (DefaultFiltersRunner.FILTER_TYPE_FIELD_ID)      : [
                         "type" : "enumeration_map",
-                        "value": type.capitalize()
+                        "value": type
                 ],
                 (DefaultFiltersRunner.FILTER_VISIBILITY_FIELD_ID): [
                         "type" : "enumeration_map",

From d3584fb6f03e2d624e918f2f0220aeea26e696cd Mon Sep 17 00:00:00 2001
From: renczesstefan <renczes.stefan@gmail.com>
Date: Mon, 2 Jun 2025 15:59:45 +0200
Subject: [PATCH 4/6] Add `getValue` method to various field classes and
 enhance field serialization

- Introduced a `getValue` method to multiple field classes (`MapField`, `DataField`, `UserField`, `CaseField`, `DateField`, and others) to standardize data retrieval from field objects.
- Created a new `ImmediateField` class for representing immediate data fields in `ElasticCase`.
- Updated `ElasticCase` to include handling for `immediateData` with proper mapping from `ImmediateField`.
- Refactored imports across the affected classes to use `java.util.*` and streamline code.
- Enhanced `FileField` with support for file paths and proper serialization via `getValue`.
- Updated various field structure definitions to ensure clarity and consistency in field data management.

This change improves maintainability and provides better support for advanced data retrieval and serialization of field objects.
---
 .../objects/elastic/domain/BooleanField.java  |  5 ++++
 .../objects/elastic/domain/ButtonField.java   |  5 ++++
 .../objects/elastic/domain/CaseField.java     |  8 ++++++
 .../objects/elastic/domain/DataField.java     |  4 +++
 .../objects/elastic/domain/DateField.java     |  5 ++++
 .../objects/elastic/domain/ElasticCase.java   | 10 ++++---
 .../domain/FieldWithAllowedNetsField.java     |  2 ++
 .../objects/elastic/domain/FileField.java     | 18 +++++++++++++
 .../objects/elastic/domain/FilterField.java   |  5 ++++
 .../objects/elastic/domain/I18nField.java     |  7 +++++
 .../objects/elastic/domain/MapField.java      | 15 ++++++++---
 .../objects/elastic/domain/NumberField.java   |  4 +++
 .../objects/elastic/domain/UserField.java     | 18 +++++++++++++
 .../domain/dataset/ImmediateField.java        | 27 +++++++++++++++++++
 14 files changed, 125 insertions(+), 8 deletions(-)
 create mode 100644 nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java

diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java
index 4f0ad10ad3..9e23aa144f 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/BooleanField.java
@@ -16,4 +16,9 @@ public BooleanField(Boolean value) {
         super(value.toString());
         this.booleanValue = value;
     }
+
+    @Override
+    public Object getValue() {
+        return booleanValue;
+    }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java
index dd1020e9dd..3564ddca34 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ButtonField.java
@@ -16,4 +16,9 @@ public ButtonField(Integer value) {
         super(value.toString());
         this.buttonValue = value;
     }
+
+    @Override
+    public Object getValue() {
+        return buttonValue;
+    }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
index 76c34dcbbc..b744625a33 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/CaseField.java
@@ -4,6 +4,9 @@
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
+import java.util.ArrayList;
+import java.util.List;
+
 @Data
 @NoArgsConstructor
 @EqualsAndHashCode(callSuper = true)
@@ -12,4 +15,9 @@ public abstract class CaseField extends FieldWithAllowedNetsField {
     public CaseField(String[] fullTextValue, String[] allowedNets) {
         super(fullTextValue, allowedNets);
     }
+
+    @Override
+    public Object getValue() {
+        return new ArrayList<>(List.of(fulltextValue));
+    }
 }
\ No newline at end of file
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
index 43daf7f114..744bc0f868 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
@@ -22,4 +22,8 @@ public abstract class DataField implements Serializable {
         this.fulltextValue = new String[1];
         this.fulltextValue[0] = fulltextValue;
     }
+
+    public Object getValue() {
+        return fulltextValue[0];
+    }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java
index 3fc15d4805..7d30aedcb0 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DateField.java
@@ -23,4 +23,9 @@ public DateField(String value, LocalDateTime dateTime) {
         this.dateValue = dateTime;
         this.timestampValue = Timestamp.valueOf(dateTime).getTime();
     }
+
+    @Override
+    public Object getValue() {
+        return dateValue;
+    }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
index dafdc9008d..f5c0d3246c 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/ElasticCase.java
@@ -5,6 +5,7 @@
 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
 import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
 import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.netgrif.application.engine.objects.petrinet.domain.dataset.ImmediateField;
 import com.netgrif.application.engine.objects.workflow.domain.Case;
 import com.netgrif.application.engine.objects.workflow.domain.TaskPair;
 import lombok.AllArgsConstructor;
@@ -16,10 +17,7 @@
 import java.io.Serializable;
 import java.sql.Timestamp;
 import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
 
@@ -63,6 +61,8 @@ public abstract class ElasticCase implements Serializable {
 
     private String authorEmail;
 
+    private List<ImmediateField> immediateData;
+
     private Map<String, DataField> dataSet;
 
     private Set<String> taskIds;
@@ -115,6 +115,7 @@ public ElasticCase(Case useCase) {
         tags = new HashMap<>(useCase.getTags());
 
         dataSet = new HashMap<>();
+        immediateData = useCase.getImmediateData().stream().map(ImmediateField::new).collect(Collectors.toList());
     }
 
     public void update(ElasticCase useCase) {
@@ -135,5 +136,6 @@ public void update(ElasticCase useCase) {
         tags = useCase.getTags();
 
         dataSet = useCase.getDataSet();
+        immediateData = useCase.getImmediateData();
     }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java
index 6e8523c50c..4194ba0f81 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FieldWithAllowedNetsField.java
@@ -4,6 +4,8 @@
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
+import java.util.List;
+
 
 @Data
 @NoArgsConstructor
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
index e4380cf7e8..875c574080 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FileField.java
@@ -6,20 +6,28 @@
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
+import java.util.Arrays;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
 @Data
 @NoArgsConstructor
 @EqualsAndHashCode(callSuper = true)
 public abstract class FileField extends DataField {
 
+    public String[] filePath;
+
     public String[] fileNameValue;
 
     public String[] fileExtensionValue;
 
     public FileField(FileFieldValue value) {
         super(value.getName());
+        this.filePath = new String[1];
         this.fileNameValue = new String[1];
         this.fileExtensionValue = new String[1];
         FileNameAndExtension extracted = this.extractFileExtensionFromName(value.getName());
+        this.filePath[0] = value.getPath();
         this.fileNameValue[0] = extracted.name;
         this.fileExtensionValue[0] = extracted.extension;
     }
@@ -36,6 +44,16 @@ public FileField(FileFieldValue[] values) {
         }
     }
 
+    @Override
+    public Object getValue() {
+        if (fileNameValue != null && fileNameValue.length == 1) {
+            return new FileFieldValue(fileNameValue[0] + "." + fileExtensionValue[0], filePath[0]);
+        } else if (fileNameValue != null && fileNameValue.length > 1) {
+            return IntStream.range(0, fileNameValue.length).mapToObj(i -> new FileFieldValue(fileNameValue[i] + "." + fileExtensionValue[i], filePath[i])).toList();
+        }
+        return null;
+    }
+
     private FileNameAndExtension extractFileExtensionFromName(String filename) {
         int index = filename.lastIndexOf('.');
         if (index > 0) {
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java
index 30e8efa95c..1a4a02bd58 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/FilterField.java
@@ -18,5 +18,10 @@ public FilterField(String fullTextValue, String[] allowedNets, Map<String, Objec
         super(fullTextValue, allowedNets);
         this.filterMetadata = filterMetadata != null ? filterMetadata : new HashMap<>();
     }
+
+    @Override
+    public Object getValue() {
+        return super.getValue();
+    }
 }
 
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
index 2317a3de9c..16614e4f0a 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
@@ -1,5 +1,6 @@
 package com.netgrif.application.engine.objects.elastic.domain;
 
+import com.netgrif.application.engine.objects.petrinet.domain.I18nString;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
@@ -20,5 +21,11 @@ public I18nField(Set<String> keys, Set<String> values, Map<String, String> trans
         super(new String[0]);
         this.keyValue = keys.toArray(new String[0]);
         this.textValue = values.toArray(new String[0]);
+        this.translations = translations;
+    }
+
+    @Override
+    public Object getValue() {
+        return new I18nString(textValue[0], translations);
     }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java
index fd9897fc5c..ad5e374b20 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/MapField.java
@@ -4,10 +4,8 @@
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 @Data
@@ -34,4 +32,13 @@ public MapField(List<Map.Entry<String, Collection<String>>> valuePairs) {
         this.textValue = values.toArray(new String[0]);
         this.fulltextValue = values.toArray(new String[0]);
     }
+
+    public Object getValue() {
+        if (keyValue != null && keyValue.length == 1) {
+            return keyValue[0];
+        } else if (keyValue != null && keyValue.length > 1) {
+            return new LinkedHashSet<>(Arrays.asList(keyValue));
+        }
+        return null;
+    }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java
index 7512c552b5..21cf944128 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/NumberField.java
@@ -16,4 +16,8 @@ public NumberField(Double value) {
         super(value.toString());
         this.numberValue = value;
     }
+
+    public Object getValue() {
+        return numberValue;
+    }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
index b93a10be6b..b56fd2ca37 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
@@ -1,10 +1,14 @@
 package com.netgrif.application.engine.objects.elastic.domain;
 
+import com.netgrif.application.engine.objects.petrinet.domain.dataset.FileFieldValue;
+import com.netgrif.application.engine.objects.petrinet.domain.dataset.UserFieldValue;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
 
+import java.util.stream.IntStream;
+
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
@@ -40,6 +44,20 @@ public UserField(UserMappingData[] values) {
         }
     }
 
+    @Override
+    public Object getValue() {
+        if (userIdValue != null && userIdValue.length == 1) {
+            String[] fullNameSplit = fullNameValue[0].split(" ");
+            return new UserFieldValue(userIdValue[0], fullNameSplit[0], fullNameSplit[1], emailValue[0]);
+        } else if (userIdValue != null && userIdValue.length > 1) {
+            return IntStream.range(0, userIdValue.length).mapToObj(i -> {
+                String[] fullNameSplit = fullNameValue[i].split(" ");
+                return new UserFieldValue(userIdValue[i], fullNameSplit[0], fullNameSplit[1], emailValue[i]);
+            }).toList();
+        }
+        return null;
+    }
+
     @AllArgsConstructor
     public static class UserMappingData {
         public String userId;
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java
new file mode 100644
index 0000000000..41b2282a11
--- /dev/null
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/petrinet/domain/dataset/ImmediateField.java
@@ -0,0 +1,27 @@
+package com.netgrif.application.engine.objects.petrinet.domain.dataset;
+
+import com.netgrif.application.engine.objects.petrinet.domain.I18nString;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+@Data
+public class ImmediateField implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private String stringId;
+    private I18nString name;
+    private FieldType type;
+
+    public ImmediateField() {
+    }
+
+    public ImmediateField(Field<?> field) {
+        this.stringId = field.getStringId();
+        this.name = field.getName();
+        this.type = field.getType();
+    }
+}

From 9796d46549e9441f5cf8ea51edbabeec022428e0 Mon Sep 17 00:00:00 2001
From: renczesstefan <renczes.stefan@gmail.com>
Date: Tue, 3 Jun 2025 14:48:36 +0200
Subject: [PATCH 5/6] Fix null check for userRealmId assignment in Task.java

- Corrects the condition to check if the user is null before accessing its realmId. Prevents potential NullPointerException when the user object is not initialized.
---
 .../application/engine/workflow/web/responsebodies/Task.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java
index 4115b62b7e..0731ed7923 100644
--- a/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java
+++ b/application-engine/src/main/java/com/netgrif/application/engine/workflow/web/responsebodies/Task.java
@@ -86,7 +86,7 @@ public Task(com.netgrif.application.engine.objects.workflow.domain.Task task, Lo
         this.caseTitle = task.getCaseTitle();
         this.priority = task.getPriority();
         this.userId = task.getUser() != null ? task.getUser().getStringId() : null;
-        this.userRealmId = task.getUserRealmId() != null ? task.getUser().getRealmId() : null;
+        this.userRealmId = task.getUser() != null ? task.getUser().getRealmId() : null;
         this.roles = task.getRoles();
         this.users = task.getUsers();
         this.startDate = task.getStartDate();

From 891b24b8e3f483ac6c3dc786cb2f0dd6688f913c Mon Sep 17 00:00:00 2001
From: renczesstefan <renczes.stefan@gmail.com>
Date: Thu, 5 Jun 2025 10:55:30 +0200
Subject: [PATCH 6/6] Fix null checks and improve error handling in field
 methods

Adjusted null and boundary checks in `getValue` methods to prevent runtime exceptions and ensure data integrity. Added validation for filter type in `ActionDelegate` to avoid illegal arguments and improved string handling for robustness.
---
 .../dataset/logic/action/ActionDelegate.groovy     |  9 ++++++---
 .../engine/objects/elastic/domain/DataField.java   |  2 +-
 .../engine/objects/elastic/domain/I18nField.java   |  5 ++++-
 .../engine/objects/elastic/domain/UserField.java   | 14 ++++++++++----
 4 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
index d1909a31f2..d90dc30fed 100644
--- a/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
+++ b/application-engine/src/main/groovy/com/netgrif/application/engine/petrinet/domain/dataset/logic/action/ActionDelegate.groovy
@@ -1,6 +1,6 @@
 package com.netgrif.application.engine.petrinet.domain.dataset.logic.action
 
-import com.mchange.v2.lang.StringUtils
+
 import com.netgrif.application.engine.AsyncRunner
 import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService
 import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase
@@ -32,6 +32,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.*
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.*
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.ChangedField
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.FieldBehavior
+import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.validation.DynamicValidation
 import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.validation.Validation
 import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole
@@ -60,7 +61,6 @@ import com.netgrif.application.engine.workflow.service.TaskService
 import com.netgrif.application.engine.workflow.service.interfaces.*
 import com.netgrif.application.engine.workflow.web.responsebodies.MessageResource
 import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference
-import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action;
 import com.querydsl.core.types.Predicate
 import groovy.transform.NamedVariant
 import org.bson.types.ObjectId
@@ -1601,7 +1601,10 @@ class ActionDelegate {
     @NamedVariant
     Case createFilter(def title, String query, String type, List<String> allowedNets,
                       String icon, String visibility, def filterMetadata) {
-        type = type.capitalize();
+        if (type == null || type.length() == 0) {
+            throw new IllegalArgumentException("Filter type cannot be null or empty");
+        }
+        type = type.toLowerCase().capitalize()
         Case filterCase = createCase(FilterRunner.FILTER_PETRI_NET_IDENTIFIER, title as String)
         filterCase.setIcon(icon)
         filterCase.dataSet[DefaultFiltersRunner.FILTER_I18N_TITLE_FIELD_ID].value = (title instanceof I18nString) ? title : new I18nString(title as String)
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
index 744bc0f868..7c054eee54 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/DataField.java
@@ -24,6 +24,6 @@ public abstract class DataField implements Serializable {
     }
 
     public Object getValue() {
-        return fulltextValue[0];
+        return (fulltextValue != null && fulltextValue.length > 0) ? fulltextValue[0] : null;
     }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
index 16614e4f0a..fa6b590f4c 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/I18nField.java
@@ -26,6 +26,9 @@ public I18nField(Set<String> keys, Set<String> values, Map<String, String> trans
 
     @Override
     public Object getValue() {
-        return new I18nString(textValue[0], translations);
+        if (textValue != null && textValue.length > 0) {
+            return new I18nString(textValue[0], translations);
+        }
+        return null;
     }
 }
diff --git a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
index b56fd2ca37..2e7acd3aca 100644
--- a/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
+++ b/nae-object-library/src/main/java/com/netgrif/application/engine/objects/elastic/domain/UserField.java
@@ -47,12 +47,18 @@ public UserField(UserMappingData[] values) {
     @Override
     public Object getValue() {
         if (userIdValue != null && userIdValue.length == 1) {
-            String[] fullNameSplit = fullNameValue[0].split(" ");
-            return new UserFieldValue(userIdValue[0], fullNameSplit[0], fullNameSplit[1], emailValue[0]);
+            String fullName = fullNameValue[0] != null ? fullNameValue[0] : "";
+            String[] fullNameSplit = fullName.split(" ", 2);
+            String firstName = fullNameSplit.length > 0 ? fullNameSplit[0] : "";
+            String lastName = fullNameSplit.length > 1 ? fullNameSplit[1] : "";
+            return new UserFieldValue(userIdValue[0], firstName, lastName, emailValue[0]);
         } else if (userIdValue != null && userIdValue.length > 1) {
             return IntStream.range(0, userIdValue.length).mapToObj(i -> {
-                String[] fullNameSplit = fullNameValue[i].split(" ");
-                return new UserFieldValue(userIdValue[i], fullNameSplit[0], fullNameSplit[1], emailValue[i]);
+                String fullName = fullNameValue[i] != null ? fullNameValue[i] : "";
+                String[] fullNameSplit = fullName.split(" ", 2);
+                String firstName = fullNameSplit.length > 0 ? fullNameSplit[0] : "";
+                String lastName = fullNameSplit.length > 1 ? fullNameSplit[1] : "";
+                return new UserFieldValue(userIdValue[i], firstName, lastName, emailValue[i]);
             }).toList();
         }
         return null;
