You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by nm...@apache.org on 2025/07/31 09:04:20 UTC

(ofbiz-framework) branch trunk updated: Improved: Add ('in', 'not-in') operator for seca condition (OFBIZ-13281)

This is an automated email from the ASF dual-hosted git repository.

nmalin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new b2b2d4da8b Improved: Add ('in', 'not-in') operator for seca condition (OFBIZ-13281)
b2b2d4da8b is described below

commit b2b2d4da8bc9be7261d939da47269e7350fa4ee1
Author: Nicolas Malin <ni...@nereide.fr>
AuthorDate: Thu Jul 31 11:02:12 2025 +0200

    Improved: Add ('in', 'not-in') operator for seca condition (OFBIZ-13281)
    
    When you create a seca to follow a status evolution, and you need to run a service on two status value, currently you define twice the seca :
    
    ****
        <eca service="setInvoiceStatus" event="return">
            <condition field-name="statusId" operator="equals" value="INVOICE_READY"/>
            <action service="runSomething" mode="async" run-as-user="system"/>
        </eca>
        <eca service="setInvoiceStatus" event="return">
            <condition field-name="statusId" operator="equals" value="INVOICE_RECEIVED"/>
            <action service="runSomething" mode="async" run-as-user="system"/>
        </eca>
    ****
    
    A simple improve will optimize this with an in (or not_in) operator already present on the framework.
    
    ****
       <eca service="setInvoiceStatus" event="return">
            <condition field-name="statusId" operator="in" value="INVOICE_READY,INVOICE_RECEIVED"/>
            <action service="runSomething" mode="async" run-as-user="system"/>
        </eca>
    ****
---
 .../java/org/apache/ofbiz/base/util/ObjectType.java | 21 +++++++++++++++++++++
 framework/common/servicedef/secas_test.xml          |  4 ++++
 framework/service/dtd/service-eca.xsd               |  2 ++
 .../ofbiz/service/test/ServiceEngineTests.java      | 13 +++++++++++++
 4 files changed, 40 insertions(+)

diff --git a/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java b/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java
index 3090723e31..01641ce9a4 100644
--- a/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java
+++ b/framework/base/src/main/java/org/apache/ofbiz/base/util/ObjectType.java
@@ -429,6 +429,27 @@ public class ObjectType {
             Collection<?> col1 = (Collection<?>) value1;
             return col1.contains(convertedValue2) ? Boolean.TRUE : Boolean.FALSE;
         }
+        if (List.of("in", "not-in").contains(operator)) {
+            Boolean isPresent = null;
+            if (value2 instanceof Collection<?>) {
+                isPresent = ((Collection<?>) value2).contains(value1);
+            }
+            if (value2 instanceof String str2) {
+                String delim = str2.contains("|") ? "|"
+                            : str2.contains(",") ? ","
+                            : null;
+
+                isPresent = (delim != null)
+                        ? StringUtil.split(str2, delim).contains(String.valueOf(value1))
+                        : str2.contains(String.valueOf(value1));
+            }
+            if (isPresent != null) {
+                return "not-in".equals(operator) != isPresent;
+            }
+            messages.add("ERROR: Could not analyze the given list with operator "
+                    + operator + " the right element need to be a list or string with | or ,");
+            return Boolean.FALSE;
+        }
 
         Object convertedValue1 = null;
         try {
diff --git a/framework/common/servicedef/secas_test.xml b/framework/common/servicedef/secas_test.xml
index 24969da10f..1b14d9d82d 100644
--- a/framework/common/servicedef/secas_test.xml
+++ b/framework/common/servicedef/secas_test.xml
@@ -24,6 +24,10 @@ under the License.
         <condition field-name="message" operator="equals" value="auto"/>
         <set field-name="message" value="set message to auto message"/>
     </eca>
+    <eca service="ping" event="invoke">
+        <condition field-name="message" operator="in" value="present,in"/>
+        <set field-name="message" value="set message to condition in message"/>
+    </eca>
     <eca service="testCommit" event="global-commit">
         <action service="testScv" mode="sync"/>
     </eca>
diff --git a/framework/service/dtd/service-eca.xsd b/framework/service/dtd/service-eca.xsd
index cc2f058eff..24ad862f7e 100644
--- a/framework/service/dtd/service-eca.xsd
+++ b/framework/service/dtd/service-eca.xsd
@@ -154,6 +154,8 @@ under the License.
                     <xs:enumeration value="is-empty"/>
                     <xs:enumeration value="is-not-empty"/>
                     <xs:enumeration value="contains"/>
+                    <xs:enumeration value="in"/>
+                    <xs:enumeration value="not-in"/>
                 </xs:restriction>
             </xs:simpleType>
         </xs:attribute>
diff --git a/framework/service/src/main/java/org/apache/ofbiz/service/test/ServiceEngineTests.java b/framework/service/src/main/java/org/apache/ofbiz/service/test/ServiceEngineTests.java
index 2cd8f40354..6c2ebebe52 100644
--- a/framework/service/src/main/java/org/apache/ofbiz/service/test/ServiceEngineTests.java
+++ b/framework/service/src/main/java/org/apache/ofbiz/service/test/ServiceEngineTests.java
@@ -47,6 +47,19 @@ public class ServiceEngineTests extends OFBizTestCase {
         assertEquals("Service result success", ModelService.RESPOND_SUCCESS, result.get(ModelService.RESPONSE_MESSAGE));
     }
 
+    /**
+     * Test a seca with condition in
+     * @throws Exception the exception
+     */
+    public void testConditionSecaInInvocation() throws Exception {
+        Map<String, Object> result = getDispatcher().runSync("ping", UtilMisc.toMap("message", "present"));
+        assertEquals("set message to condition in message", result.get("message"));
+        result = getDispatcher().runSync("ping", UtilMisc.toMap("message", "in"));
+        assertEquals("set message to condition in message", result.get("message"));
+        result = getDispatcher().runSync("ping", UtilMisc.toMap("message", "other"));
+        assertEquals("other", result.get("message"));
+    }
+
     /**
      * Test a basic clojure invocation
      * @throws Exception the exception