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

arnold 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 a04aa4536 FINERACT-1693: Fix null handling of datatables
a04aa4536 is described below

commit a04aa45368343d64af49bb7b2ae931925f5381b2
Author: Adam Saghy <[email protected]>
AuthorDate: Thu Sep 1 20:20:21 2022 +0200

    FINERACT-1693: Fix null handling of datatables
---
 .../service/ReadWriteNonCoreDataServiceImpl.java   |   6 +-
 .../integrationtests/DatatableIntegrationTest.java | 125 +++++++++++++++++++++
 2 files changed, 129 insertions(+), 2 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
index eb857450e..bd7eac706 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java
@@ -1540,7 +1540,7 @@ public class ReadWriteNonCoreDataServiceImpl implements 
ReadWriteNonCoreDataServ
             final String key = pColumnHeader.getColumnName();
             if (affectedColumns.containsKey(key)) {
                 pValue = String.valueOf(affectedColumns.get(key));
-                if (StringUtils.isEmpty(pValue)) {
+                if (StringUtils.isEmpty(pValue) || 
"null".equalsIgnoreCase(pValue)) {
                     pValueWrite = "null";
                 } else {
                     if ("bit".equalsIgnoreCase(pColumnHeader.getColumnType())) 
{
@@ -1605,7 +1605,7 @@ public class ReadWriteNonCoreDataServiceImpl implements 
ReadWriteNonCoreDataServ
         for (final String key : affectedColumns.keySet()) {
             pValue = String.valueOf(affectedColumns.get(key));
 
-            if (StringUtils.isEmpty(pValue)) {
+            if (StringUtils.isEmpty(pValue) || 
"null".equalsIgnoreCase(pValue)) {
                 pValueWrite = "null";
             } else {
                 pValueWrite = singleQuote + 
this.genericDataService.replace(pValue, singleQuote, singleQuote + singleQuote) 
+ singleQuote;
@@ -1860,6 +1860,8 @@ public class ReadWriteNonCoreDataServiceImpl implements 
ReadWriteNonCoreDataServ
                             dataValidationErrors);
                 }
             }
+        } else {
+            paramValue = null;
         }
         return paramValue;
     }
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DatatableIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DatatableIntegrationTest.java
index 6299fbb7e..4019b06fb 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DatatableIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DatatableIntegrationTest.java
@@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
@@ -255,6 +256,130 @@ public class DatatableIntegrationTest {
         assertEquals(datatableName, deletedDataTableName, "ERROR IN DELETING 
THE DATATABLE");
     }
 
+    @Test
+    public void validateInsertNullValues() {
+        // Fetch / Create TST code
+        HashMap<String, Object> codeResponse = 
CodeHelper.getCodeByName(this.requestSpec, this.responseSpec, "TST_TST_TST");
+
+        // creating datatable for client entity
+        final HashMap<String, Object> columnMap = new HashMap<>();
+        final List<HashMap<String, Object>> datatableColumnsList = new 
ArrayList<>();
+        columnMap.put("datatableName", 
Utils.randomNameGenerator(LOAN_APP_TABLE_NAME + "_", 5));
+        columnMap.put("apptableName", LOAN_APP_TABLE_NAME);
+        columnMap.put("entitySubType", "");
+        columnMap.put("multiRow", true);
+        DatatableHelper.addDatatableColumns(datatableColumnsList, 
"itsABoolean", "Boolean", false, null, null);
+        DatatableHelper.addDatatableColumns(datatableColumnsList, "itsADate", 
"Date", false, null, null);
+        DatatableHelper.addDatatableColumns(datatableColumnsList, 
"itsADatetime", "Datetime", false, null, null);
+        DatatableHelper.addDatatableColumns(datatableColumnsList, 
"itsADecimal", "Decimal", false, null, null);
+        DatatableHelper.addDatatableColumns(datatableColumnsList, 
"itsADropdown", "Dropdown", false, null, "TST_TST_TST");
+        DatatableHelper.addDatatableColumns(datatableColumnsList, 
"itsANumber", "Number", false, null, null);
+        DatatableHelper.addDatatableColumns(datatableColumnsList, 
"itsAString", "String", false, 10, null);
+        DatatableHelper.addDatatableColumns(datatableColumnsList, "itsAText", 
"Text", false, null, null);
+        columnMap.put("columns", datatableColumnsList);
+        String datatabelRequestJsonString = new Gson().toJson(columnMap);
+        LOG.info("map : {}", datatabelRequestJsonString);
+
+        HashMap<String, Object> datatableResponse = 
this.datatableHelper.createDatatable(datatabelRequestJsonString, "");
+        String datatableName = (String) 
datatableResponse.get("resourceIdentifier");
+        DatatableHelper.verifyDatatableCreatedOnServer(this.requestSpec, 
this.responseSpec, datatableName);
+
+        // try to create with the same name
+        ResponseSpecification responseSpecError400 = new 
ResponseSpecBuilder().expectStatusCode(400).build();
+        this.datatableHelper = new DatatableHelper(this.requestSpec, 
responseSpecError400);
+        HashMap<String, Object> response = 
this.datatableHelper.createDatatable(datatabelRequestJsonString, "");
+        assertEquals("validation.msg.validation.errors.exist", ((Map) 
response).get("userMessageGlobalisationCode"));
+        this.datatableHelper = new DatatableHelper(this.requestSpec, 
this.responseSpec);
+
+        // creating client with datatables
+        final Integer clientID = 
ClientHelper.createClientAsPerson(requestSpec, responseSpec);
+        final Integer loanProductID = 
createLoanProductWithPeriodicAccrualAccountingEnabled();
+        final Integer loanID = applyForLoanApplication(clientID, 
loanProductID);
+
+        // creating new client datatable entry
+        final boolean genericResultSet = true;
+
+        HashMap<String, Object> datatableEntryMap = new HashMap<>();
+        datatableEntryMap.put("itsABoolean", null);
+        datatableEntryMap.put("itsADate", null);
+        datatableEntryMap.put("itsADatetime", null);
+        datatableEntryMap.put("itsADecimal", null);
+        datatableEntryMap.put("TST_TST_TST_cd_itsADropdown", null);
+        datatableEntryMap.put("itsANumber", null);
+        datatableEntryMap.put("itsAString", null);
+        datatableEntryMap.put("itsAText", null);
+
+        datatableEntryMap.put("locale", "en");
+        datatableEntryMap.put("dateFormat", "yyyy-MM-dd");
+
+        String datatableEntryRequestJsonString = new 
GsonBuilder().serializeNulls().create().toJson(datatableEntryMap);
+        LOG.info("map : {}", datatableEntryRequestJsonString);
+
+        HashMap<String, Object> datatableEntryResponseFirst = 
this.datatableHelper.createDatatableEntry(datatableName, loanID,
+                genericResultSet, datatableEntryRequestJsonString);
+
+        datatableEntryMap = new HashMap<>();
+        datatableEntryMap.put("itsABoolean", "");
+        datatableEntryMap.put("itsADate", "");
+        datatableEntryMap.put("itsADatetime", "");
+        datatableEntryMap.put("itsADecimal", "");
+        datatableEntryMap.put("TST_TST_TST_cd_itsADropdown", "");
+        datatableEntryMap.put("itsANumber", "");
+        datatableEntryMap.put("itsAString", "");
+        datatableEntryMap.put("itsAText", "");
+
+        datatableEntryMap.put("locale", "en");
+        datatableEntryMap.put("dateFormat", "yyyy-MM-dd");
+
+        datatableEntryRequestJsonString = new 
GsonBuilder().serializeNulls().create().toJson(datatableEntryMap);
+        HashMap<String, Object> datatableEntryResponseSecond = 
this.datatableHelper.createDatatableEntry(datatableName, loanID,
+                genericResultSet, datatableEntryRequestJsonString);
+        assertNotNull(datatableEntryResponseFirst.get("resourceId"), "ERROR IN 
CREATING THE ENTITY DATATABLE RECORD");
+        assertNotNull(datatableEntryResponseSecond.get("resourceId"), "ERROR 
IN CREATING THE ENTITY DATATABLE RECORD");
+
+        // Read the Datatable entry generated with genericResultSet in true 
(default)
+        HashMap<String, Object> items = 
this.datatableHelper.readDatatableEntry(datatableName, loanID, 
genericResultSet, null, "");
+        assertNotNull(items);
+        assertEquals(2, ((List) items.get("data")).size());
+
+        assertEquals("id", ((Map) ((List) 
items.get("columnHeaders")).get(0)).get("columnName"));
+        assertEquals(1, ((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(0));
+        assertEquals("loan_id", ((Map) ((List) 
items.get("columnHeaders")).get(1)).get("columnName"));
+        assertEquals(loanID, ((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(1));
+        assertEquals("itsABoolean", ((Map) ((List) 
items.get("columnHeaders")).get(2)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(2));
+        assertEquals("itsADate", ((Map) ((List) 
items.get("columnHeaders")).get(3)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(3));
+        assertEquals("itsADatetime", ((Map) ((List) 
items.get("columnHeaders")).get(4)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(4));
+        assertEquals("itsADecimal", ((Map) ((List) 
items.get("columnHeaders")).get(5)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(5));
+        assertEquals("TST_TST_TST_cd_itsADropdown", ((Map) ((List) 
items.get("columnHeaders")).get(6)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(6));
+        assertEquals("itsANumber", ((Map) ((List) 
items.get("columnHeaders")).get(7)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(7));
+        assertEquals("itsAString", ((Map) ((List) 
items.get("columnHeaders")).get(8)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(8));
+        assertEquals("itsAText", ((Map) ((List) 
items.get("columnHeaders")).get(9)).get("columnName"));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(0)).get("row")).get(9));
+
+        assertEquals(2, ((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(0));
+        assertEquals(loanID, ((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(1));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(2));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(3));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(4));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(5));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(6));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(7));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(8));
+        assertNull(((List) ((Map) ((List) 
items.get("data")).get(1)).get("row")).get(9));
+
+        HashMap<String, Object> updatedDatatableEntryResponse = 
this.datatableHelper.updateDatatableEntry(datatableName, loanID, 1, false,
+                datatableEntryRequestJsonString);
+
+        assertEquals(null, updatedDatatableEntryResponse.get("changes"));
+    }
+
     @Test
     public void validateReadDatatableMultirow() {
         // Fetch / Create TST code

Reply via email to