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

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new ab8bb930ec FINERACT-2333: Batch API - Support date format: from array 
to string
ab8bb930ec is described below

commit ab8bb930ec932715ce44d57022baad5615d5c78f
Author: Adam Saghy <[email protected]>
AuthorDate: Mon Jul 21 20:15:49 2025 +0200

    FINERACT-2333: Batch API - Support date format: from array to string
---
 .../fineract/batch/service/ResolutionHelper.java   | 31 +++++---
 .../batch/service/ResolutionHelperTest.java        | 90 ++++++++++++++++++++++
 2 files changed, 110 insertions(+), 11 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
 
b/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
index 332041706e..672f7927c4 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/batch/service/ResolutionHelper.java
@@ -25,6 +25,8 @@ import com.google.gson.JsonObject;
 import com.google.gson.JsonPrimitive;
 import com.jayway.jsonpath.JsonPath;
 import com.jayway.jsonpath.ReadContext;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -134,7 +136,7 @@ public class ResolutionHelper {
             // parameter
             for (Map.Entry<String, JsonElement> element : 
jsonRequestBody.entrySet()) {
                 final String key = element.getKey();
-                final JsonElement value = 
resolveDependentVariables(element.getValue(), responseCtx);
+                final JsonElement value = 
resolveDependentVariables(element.getValue(), requestBody, responseCtx);
                 jsonResultBody.add(key, value);
             }
             // Set the body after dependency resolution
@@ -163,44 +165,51 @@ public class ResolutionHelper {
         return request;
     }
 
-    private JsonElement resolveDependentVariables(final JsonElement 
jsonElement, final ReadContext responseCtx) {
+    private JsonElement resolveDependentVariables(final JsonElement 
jsonElement, final String requestBody, final ReadContext responseCtx) {
         JsonElement value;
         if (jsonElement.isJsonObject()) {
             final JsonObject jsObject = jsonElement.getAsJsonObject();
-            value = processJsonObject(jsObject, responseCtx);
+            value = processJsonObject(jsObject, requestBody, responseCtx);
         } else if (jsonElement.isJsonArray()) {
             final JsonArray jsElementArray = jsonElement.getAsJsonArray();
-            value = processJsonArray(jsElementArray, responseCtx);
+            value = processJsonArray(jsElementArray, requestBody, responseCtx);
         } else if (jsonElement.isJsonNull()) {
             // No further processing of null values
             value = jsonElement;
         } else {
-            value = processJsonPrimitive(jsonElement, responseCtx);
+            value = processJsonPrimitive(jsonElement, requestBody, 
responseCtx);
         }
         return value;
     }
 
-    private JsonElement processJsonObject(final JsonObject jsObject, final 
ReadContext responseCtx) {
+    private JsonElement processJsonObject(final JsonObject jsObject, final 
String requestBody, final ReadContext responseCtx) {
         JsonObject valueObj = new JsonObject();
         for (Map.Entry<String, JsonElement> element : jsObject.entrySet()) {
-            valueObj.add(element.getKey(), 
resolveDependentVariables(element.getValue(), responseCtx));
+            valueObj.add(element.getKey(), 
resolveDependentVariables(element.getValue(), requestBody, responseCtx));
         }
         return valueObj;
     }
 
-    private JsonArray processJsonArray(final JsonArray elementArray, final 
ReadContext responseCtx) {
+    private JsonArray processJsonArray(final JsonArray elementArray, final 
String requestBody, final ReadContext responseCtx) {
         JsonArray valueArr = new JsonArray();
         for (JsonElement element : elementArray) {
-            valueArr.add(resolveDependentVariables(element, responseCtx));
+            valueArr.add(resolveDependentVariables(element, requestBody, 
responseCtx));
         }
         return valueArr;
     }
 
-    private JsonElement processJsonPrimitive(final JsonElement element, final 
ReadContext responseCtx) {
+    private JsonElement processJsonPrimitive(final JsonElement element, final 
String requestBody, final ReadContext responseCtx) {
         JsonElement value = element;
         if (element instanceof JsonPrimitive) {
             String paramVal = element.getAsString();
-            if (paramVal.contains("$.")) {
+            if (paramVal.contains("$[ARRAYDATE]")) {
+                String resolvableParamVal = paramVal.replace("$[ARRAYDATE]", 
"$");
+                final String resParamValue = 
responseCtx.read(resolvableParamVal).toString();
+                JsonArray date = (JsonArray) 
this.fromJsonHelper.parse(resParamValue);
+                String dateFormat = JsonPath.read(requestBody, "$.dateFormat");
+                return new 
JsonPrimitive(DateTimeFormatter.ofPattern(dateFormat)
+                        .format(LocalDate.of(date.get(0).getAsInt(), 
date.get(1).getAsInt(), date.get(2).getAsInt())));
+            } else if (paramVal.contains("$.")) {
                 // Get the value of the parameter from parent response
                 final String resParamValue = 
responseCtx.read(paramVal).toString();
                 value = this.fromJsonHelper.parse(resParamValue);
diff --git 
a/fineract-core/src/test/java/org/apache/fineract/batch/service/ResolutionHelperTest.java
 
b/fineract-core/src/test/java/org/apache/fineract/batch/service/ResolutionHelperTest.java
index 1a735b9d6f..fcccb567d1 100644
--- 
a/fineract-core/src/test/java/org/apache/fineract/batch/service/ResolutionHelperTest.java
+++ 
b/fineract-core/src/test/java/org/apache/fineract/batch/service/ResolutionHelperTest.java
@@ -21,6 +21,7 @@ package org.apache.fineract.batch.service;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -104,4 +105,93 @@ public class ResolutionHelperTest {
         
assertEquals("{\"key1\":\"value1\",\"key2\":{\"subKey\":false},\"key3\":[1,2,3],\"key4\":null}",
 resolvedRequest.getBody());
         assertEquals("/resource/id", resolvedRequest.getRelativeUrl());
     }
+
+    @Test
+    void testResolveRequestWithArrayDateParameter() {
+        // Test resolving a JSON primitive with array date format
+        BatchRequest batchRequest = new BatchRequest();
+        batchRequest
+                .setBody("{\"dateFormat\":\"dd MMMM 
yyyy\",\"startDate\":\"$[ARRAYDATE].dates[0]\",\"endDate\":\"$[ARRAYDATE].dates[1]\"}");
+        batchRequest.setRelativeUrl("/resource/endpoint");
+
+        BatchResponse parentResponse = new BatchResponse();
+        parentResponse.setBody("{\"dates\":[[2023,5,15],[2023,6,15]]}");
+
+        // Mock the response context
+        ReadContext readContext = mock(ReadContext.class);
+        when(readContext.read("$.dates[0]")).thenReturn(new int[] { 2023, 5, 
15 });
+        when(readContext.read("$.dates[1]")).thenReturn(new int[] { 2023, 6, 
15 });
+
+        BatchRequest resolvedRequest = 
resolutionHelper.resolveRequest(batchRequest, parentResponse);
+        assertNotNull(resolvedRequest);
+
+        // Check for possible date formats
+        String body = resolvedRequest.getBody();
+        assertTrue(body.contains("\"startDate\":\"15 May 2023\"") || 
body.contains("\"startDate\":\"15 May, 2023\"")
+                || body.contains("\"startDate\":\"15 May. 2023\"") || 
body.contains("\"startDate\":\"May 15, 2023\""));
+        assertTrue(body.contains("\"endDate\":\"15 June 2023\"") || 
body.contains("\"endDate\":\"15 June, 2023\"")
+                || body.contains("\"endDate\":\"15 Jun. 2023\"") || 
body.contains("\"endDate\":\"June 15, 2023\""));
+    }
+
+    @Test
+    void testResolveRequestWithNestedJsonPrimitives() {
+        // Test resolving nested JSON primitives
+        BatchRequest batchRequest = new BatchRequest();
+        
batchRequest.setBody("{\"nested\":{\"key1\":\"$.value1\",\"key2\":123,\"key3\":true,\"key4\":null}}");
+        batchRequest.setRelativeUrl("/resource/endpoint");
+
+        BatchResponse parentResponse = new BatchResponse();
+        parentResponse.setBody("{\"value1\":\"resolvedValue\"}");
+
+        // Mock the response context
+        ReadContext readContext = mock(ReadContext.class);
+        when(readContext.read("$.value1")).thenReturn("resolvedValue");
+
+        BatchRequest resolvedRequest = 
resolutionHelper.resolveRequest(batchRequest, parentResponse);
+        assertNotNull(resolvedRequest);
+        
assertEquals("{\"nested\":{\"key1\":\"resolvedValue\",\"key2\":123,\"key3\":true,\"key4\":null}}",
 resolvedRequest.getBody());
+    }
+
+    @Test
+    void testResolveRequestWithPrimitiveTypes() {
+        // Test resolving different primitive types
+        BatchRequest batchRequest = new BatchRequest();
+        
batchRequest.setBody("{\"string\":\"text\",\"number\":123.45,\"boolean\":true,\"nullValue\":null}");
+        batchRequest.setRelativeUrl("/resource/endpoint");
+
+        BatchResponse parentResponse = new BatchResponse();
+        parentResponse.setBody("{}"); // Empty response as we're not using any 
references
+
+        BatchRequest resolvedRequest = 
resolutionHelper.resolveRequest(batchRequest, parentResponse);
+        assertNotNull(resolvedRequest);
+
+        // The JSON might be reordered, so we need to check for existence of 
each key-value pair
+        String body = resolvedRequest.getBody();
+        assertTrue(body.contains("\"string\":\"text\""));
+        assertTrue(body.contains("\"number\":123.45"));
+        assertTrue(body.contains("\"boolean\":true"));
+        assertTrue(body.contains("\"nullValue\":null"));
+    }
+
+    @Test
+    void testResolveRequestWithComplexReferencePath() {
+        // Test resolving with complex reference paths
+        BatchRequest batchRequest = new BatchRequest();
+        batchRequest.setBody("{\"user\": {\"name\": 
\"$.userData.name\",\"age\": \"$.userData.age\"}}");
+        batchRequest.setRelativeUrl("/users/$.userData.id");
+
+        BatchResponse parentResponse = new BatchResponse();
+        parentResponse.setBody("{\"userData\":{\"id\": 42,\"name\": 
\"John\",\"age\": 30}}");
+
+        // Mock the response context
+        ReadContext readContext = mock(ReadContext.class);
+        when(readContext.read("$.userData.name")).thenReturn("John");
+        when(readContext.read("$.userData.age")).thenReturn(30);
+        when(readContext.read("$.userData.id")).thenReturn(42);
+
+        BatchRequest resolvedRequest = 
resolutionHelper.resolveRequest(batchRequest, parentResponse);
+        assertNotNull(resolvedRequest);
+        assertEquals("{\"user\":{\"name\":\"John\",\"age\":30}}", 
resolvedRequest.getBody());
+        assertEquals("/users/42", resolvedRequest.getRelativeUrl());
+    }
 }

Reply via email to