@@ -965,4 +965,90 @@ private Integer createLoanProductWithPeriodicAccrualAccountingEnabled() {
965965 return this .loanTransactionHelper .getLoanProductId (loanProductJSON );
966966 }
967967
968+ @ Test
969+ public void testDropNullColumnWithData () {
970+ // Create datatable for client entity
971+ final HashMap <String , Object > columnMap = new HashMap <>();
972+ final List <HashMap <String , Object >> datatableColumnsList = new ArrayList <>();
973+ columnMap .put ("datatableName" , Utils .uniqueRandomStringGenerator (CLIENT_APP_TABLE_NAME + "_" , 5 ));
974+ columnMap .put ("apptableName" , CLIENT_APP_TABLE_NAME );
975+ columnMap .put ("entitySubType" , CLIENT_PERSON_SUBTYPE_NAME );
976+ columnMap .put ("multiRow" , false );
977+
978+ // Add columns: one that will have data and one that will be NULL
979+ addDatatableColumn (datatableColumnsList , "columnWithData" , "String" , false , 50 , null );
980+ addDatatableColumn (datatableColumnsList , "columnWithNull" , "String" , false , 50 , null );
981+ columnMap .put ("columns" , datatableColumnsList );
982+
983+ String datatableRequestJsonString = new Gson ().toJson (columnMap );
984+ LOG .info ("Creating datatable: {}" , datatableRequestJsonString );
985+
986+ HashMap <String , Object > datatableResponse = this .datatableHelper .createDatatable (datatableRequestJsonString , "" );
987+ String datatableName = (String ) datatableResponse .get ("resourceIdentifier" );
988+ assertNotNull (datatableName );
989+ DatatableHelper .verifyDatatableCreatedOnServer (this .requestSpec , this .responseSpec , datatableName );
990+
991+ // Create a client
992+ final Integer clientId = ClientHelper .createClientAsPerson (requestSpec , responseSpec );
993+
994+ // Create a datatable entry with data in one column and NULL in the other
995+ final HashMap <String , Object > datatableEntryMap = new HashMap <>();
996+ datatableEntryMap .put ("columnWithData" , "TestValue" );
997+ // columnWithNull is intentionally not set, so it will be NULL
998+ datatableEntryMap .put ("locale" , "en" );
999+
1000+ String datatableEntryRequestJsonString = new Gson ().toJson (datatableEntryMap );
1001+ LOG .info ("Creating datatable entry: {}" , datatableEntryRequestJsonString );
1002+
1003+ final boolean genericResultSet = true ;
1004+ HashMap <String , Object > datatableEntryResponse = this .datatableHelper .createDatatableEntry (datatableName , clientId ,
1005+ genericResultSet , datatableEntryRequestJsonString );
1006+ assertNotNull (datatableEntryResponse .get ("resourceId" ), "ERROR IN CREATING THE ENTITY DATATABLE RECORD" );
1007+ assertEquals (clientId , datatableEntryResponse .get ("resourceId" ));
1008+
1009+ // Verify column count before drop
1010+ GetDataTablesResponse dataTableBeforeDrop = datatableHelper .getDataTableDetails (datatableName );
1011+ List <ResultsetColumnHeaderData > columnHeadersBeforeDrop = dataTableBeforeDrop .getColumnHeaderData ();
1012+ // Should have 5 columns before drop: client_id, columnWithData, columnWithNull, created_at, updated_at
1013+ // Note: Datatables automatically add audit columns (created_at, updated_at)
1014+ assertEquals (5 , columnHeadersBeforeDrop .size (), "Should have 5 columns before dropping columnWithNull" );
1015+
1016+ // Now try to drop the NULL column - this should succeed with the fix
1017+ HashMap <String , Object > updateMap = new HashMap <>();
1018+ updateMap .put ("apptableName" , CLIENT_APP_TABLE_NAME );
1019+ updateMap .put ("entitySubType" , CLIENT_PERSON_SUBTYPE_NAME );
1020+ List <Map <String , Object >> dropColumnsList = Collections .singletonList (Collections .singletonMap ("name" , "columnWithNull" ));
1021+ updateMap .put ("dropColumns" , dropColumnsList );
1022+
1023+ String updateRequestJsonString = new Gson ().toJson (updateMap );
1024+ LOG .info ("Dropping NULL column: {}" , updateRequestJsonString );
1025+
1026+ PutDataTablesResponse updateResponse = this .datatableHelper .updateDatatable (datatableName , updateRequestJsonString );
1027+ assertNotNull (updateResponse );
1028+ assertEquals (datatableName , updateResponse .getResourceIdentifier ());
1029+
1030+ // Verify the column was dropped
1031+ GetDataTablesResponse dataTable = datatableHelper .getDataTableDetails (datatableName );
1032+ List <ResultsetColumnHeaderData > columnHeaders = dataTable .getColumnHeaderData ();
1033+ // Should have 4 columns after drop: client_id, columnWithData, created_at, updated_at (columnWithNull should be
1034+ // dropped)
1035+ assertEquals (4 , columnHeaders .size (), "Should have 4 columns after dropping columnWithNull" );
1036+ boolean hasColumnWithData = false ;
1037+ boolean hasColumnWithNull = false ;
1038+ for (ResultsetColumnHeaderData header : columnHeaders ) {
1039+ if ("columnWithData" .equals (header .getColumnName ())) {
1040+ hasColumnWithData = true ;
1041+ }
1042+ if ("columnWithNull" .equals (header .getColumnName ())) {
1043+ hasColumnWithNull = true ;
1044+ }
1045+ }
1046+ assertTrue (hasColumnWithData , "columnWithData should still exist" );
1047+ assertFalse (hasColumnWithNull , "columnWithNull should have been dropped" );
1048+
1049+ // Clean up
1050+ this .datatableHelper .deleteDatatableEntries (datatableName , clientId , "clientId" );
1051+ this .datatableHelper .deleteDatatable (datatableName );
1052+ }
1053+
9681054}
0 commit comments