You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ar...@apache.org on 2022/04/26 11:48:31 UTC

[fineract] branch develop updated: FINERACT-1593: Bugfixes for Client Address creation

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 9d212ba47 FINERACT-1593: Bugfixes for Client Address creation
9d212ba47 is described below

commit 9d212ba471c528519129bb387adcada0b1560c7b
Author: Arnold Galovics <ga...@gmail.com>
AuthorDate: Mon Apr 25 22:28:41 2022 +0200

    FINERACT-1593: Bugfixes for Client Address creation
---
 fineract-client/build.gradle                       |   2 +-
 .../java/org/apache/fineract/client/util/JSON.java |   7 +-
 .../api/GlobalConfigurationApiResource.java        |  18 ++
 .../fineract/portfolio/address/domain/Address.java |   3 -
 .../AddressCommandFromApiJsonDeserializer.java     |  10 +-
 .../service/AddressWritePlatformServiceImpl.java   | 130 ++++++--------
 .../client/api/ClientAddressApiResources.java      |   2 +
 .../api/ClientAddressApiResourcesSwagger.java      |   2 +
 .../portfolio/client/api/ClientsApiResource.java   |  26 +--
 .../client/api/ClientsApiResourceSwagger.java      |  32 ++++
 integration-tests/dependencies.gradle              |   3 +
 .../fineract/integrationtests/ClientTest.java      | 163 +++++++++++++-----
 .../integrationtests/common/ClientHelper.java      | 186 +++++++++++++--------
 .../common/GlobalConfigurationHelper.java          |  66 +++++---
 .../fineract/integrationtests/common/Utils.java    |  10 ++
 .../integrationtests/common/system/CodeHelper.java |  30 ++++
 16 files changed, 433 insertions(+), 257 deletions(-)

diff --git a/fineract-client/build.gradle b/fineract-client/build.gradle
index dd32ac445..c0307931b 100644
--- a/fineract-client/build.gradle
+++ b/fineract-client/build.gradle
@@ -91,7 +91,7 @@ licenseFormatMain.dependsOn buildTypescriptAngularSdk
 compileJava.dependsOn licenseFormatMain
 
 // TODO: @vidakovic we could provide even more client libs in different languages (Go, Ruby, Swift etc.)
-compileJava.dependsOn buildJavaSdk, spotlessJavaApply, buildTypescriptAngularSdk, spotlessMiscApply
+compileJava.dependsOn buildJavaSdk, buildTypescriptAngularSdk, spotlessMiscApply
 
 java {
     // keep this at Java 8, not 17; see https://issues.apache.org/jira/browse/FINERACT-1214
diff --git a/fineract-client/src/main/java/org/apache/fineract/client/util/JSON.java b/fineract-client/src/main/java/org/apache/fineract/client/util/JSON.java
index c1751bc63..de7611f16 100644
--- a/fineract-client/src/main/java/org/apache/fineract/client/util/JSON.java
+++ b/fineract-client/src/main/java/org/apache/fineract/client/util/JSON.java
@@ -43,9 +43,8 @@ import retrofit2.converter.gson.GsonConverterFactory;
 
 // This class was originally generated by OpenAPI Generator (https://openapi-generator.tech),
 // but then had to be manually edited by Michael Vorburger.ch to fix https://issues.apache.org/jira/browse/FINERACT-1220.
-// It is intentionally NOT public, as it's considered an "implementation detail".
 // The original JSON class is deleted during the build (see FINERACT-1231).
-class JSON {
+public class JSON {
 
     private final Gson gson;
     private final DateTypeAdapter dateTypeAdapter = new DateTypeAdapter();
@@ -53,14 +52,14 @@ class JSON {
     private final OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter();
     private final LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter();
 
-    JSON() {
+    public JSON() {
         gson = new GsonFireBuilder().createGsonBuilder().registerTypeAdapter(Date.class, dateTypeAdapter)
                 .registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter)
                 .registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter)
                 .registerTypeAdapter(LocalDate.class, localDateTypeAdapter).create();
     }
 
-    Gson getGson() {
+    public Gson getGson() {
         return gson;
     }
 
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiResource.java
index f2d27987a..7d6fc0778 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationApiResource.java
@@ -134,6 +134,24 @@ public class GlobalConfigurationApiResource {
         return this.propertyDataJsonSerializer.serialize(settings, configurationData, RESPONSE_DATA_PARAMETERS);
     }
 
+    @GET
+    @Path("name/{name}")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Operation(summary = "Retrieve Global Configuration", description = "Returns a global enable/disable configuration.\n" + "\n"
+            + "Example Requests:\n" + "\n" + "configurations/name/Enable-Address")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = GlobalConfigurationPropertyData.class))) })
+    public String retrieveOneByName(@PathParam("name") @Parameter(description = "name") final String name, @Context final UriInfo uriInfo) {
+
+        this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+        final GlobalConfigurationPropertyData configurationData = this.readPlatformService.retrieveGlobalConfiguration(name);
+
+        final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
+        return this.propertyDataJsonSerializer.serialize(settings, configurationData, RESPONSE_DATA_PARAMETERS);
+    }
+
     @PUT
     @Path("{configId}")
     @Consumes({ MediaType.APPLICATION_JSON })
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java
index 7d8f4347b..bfb897523 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java
@@ -24,7 +24,6 @@ import java.time.LocalDate;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.Date;
-import java.util.Locale;
 import java.util.Set;
 import javax.persistence.CascadeType;
 import javax.persistence.Column;
@@ -182,14 +181,12 @@ public class Address extends AbstractPersistableCustom {
         BigDecimal latitude = BigDecimal.ZERO;
         BigDecimal longitude = BigDecimal.ZERO;
         String createdBy = "";
-        Locale locale = Locale.ENGLISH;
         String updatedBy = "";
         LocalDate updatedOnDate = null;
         LocalDate createdOnDate = null;
 
         if (jsonObject.has("street")) {
             street = jsonObject.get("street").getAsString();
-
         }
 
         if (jsonObject.has("addressLine1")) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/serialization/AddressCommandFromApiJsonDeserializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/serialization/AddressCommandFromApiJsonDeserializer.java
index 39eef97e5..8ed7301b0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/serialization/AddressCommandFromApiJsonDeserializer.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/serialization/AddressCommandFromApiJsonDeserializer.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
 import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
@@ -34,22 +35,15 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.portfolio.address.data.FieldConfigurationData;
 import org.apache.fineract.portfolio.address.service.FieldConfigurationReadPlatformService;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
+@RequiredArgsConstructor
 public class AddressCommandFromApiJsonDeserializer {
 
     private final FromJsonHelper fromApiJsonHelper;
     private final FieldConfigurationReadPlatformService readservice;
 
-    @Autowired
-    public AddressCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper,
-            final FieldConfigurationReadPlatformService readservice) {
-        this.fromApiJsonHelper = fromApiJsonHelper;
-        this.readservice = readservice;
-    }
-
     public void validateForUpdate(final String json) {
         validate(json, false);
     }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressWritePlatformServiceImpl.java
index b9d052b0d..f0ec83ef0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/service/AddressWritePlatformServiceImpl.java
@@ -22,6 +22,7 @@ import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import lombok.RequiredArgsConstructor;
 import org.apache.fineract.infrastructure.codes.domain.CodeValue;
 import org.apache.fineract.infrastructure.codes.domain.CodeValueRepository;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
@@ -38,10 +39,10 @@ import org.apache.fineract.portfolio.client.domain.ClientAddress;
 import org.apache.fineract.portfolio.client.domain.ClientAddressRepository;
 import org.apache.fineract.portfolio.client.domain.ClientAddressRepositoryWrapper;
 import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 @Service
+@RequiredArgsConstructor
 public class AddressWritePlatformServiceImpl implements AddressWritePlatformService {
 
     private final PlatformSecurityContext context;
@@ -52,112 +53,77 @@ public class AddressWritePlatformServiceImpl implements AddressWritePlatformServ
     private final ClientAddressRepositoryWrapper clientAddressRepositoryWrapper;
     private final AddressCommandFromApiJsonDeserializer fromApiJsonDeserializer;
 
-    @Autowired
-    public AddressWritePlatformServiceImpl(final PlatformSecurityContext context, final CodeValueRepository codeValueRepository,
-            final ClientAddressRepository clientAddressRepository, final ClientRepositoryWrapper clientRepositoryWrapper,
-            final AddressRepository addressRepository, final ClientAddressRepositoryWrapper clientAddressRepositoryWrapper,
-            final AddressCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
-        this.context = context;
-        this.codeValueRepository = codeValueRepository;
-        this.clientAddressRepository = clientAddressRepository;
-        this.clientRepositoryWrapper = clientRepositoryWrapper;
-        this.addressRepository = addressRepository;
-        this.clientAddressRepositoryWrapper = clientAddressRepositoryWrapper;
-        this.fromApiJsonDeserializer = fromApiJsonDeserializer;
-
-    }
-
     @Override
     public CommandProcessingResult addClientAddress(final Long clientId, final Long addressTypeId, final JsonCommand command) {
-        CodeValue stateIdobj = null;
-        CodeValue countryIdObj = null;
-        long stateId;
-        long countryId;
-
-        this.context.authenticatedUser();
-        this.fromApiJsonDeserializer.validateForCreate(command.json(), true);
-
-        if (command.longValueOfParameterNamed("stateProvinceId") != null) {
-            stateId = command.longValueOfParameterNamed("stateProvinceId");
-            stateIdobj = this.codeValueRepository.getById(stateId);
-        }
-
-        if (command.longValueOfParameterNamed("countryId") != null) {
-            countryId = command.longValueOfParameterNamed("countryId");
-            countryIdObj = this.codeValueRepository.getById(countryId);
-        }
-
-        final CodeValue addressTypeIdObj = this.codeValueRepository.getById(addressTypeId);
+        JsonObject jsonObject = command.parsedJson().getAsJsonObject();
+        context.authenticatedUser();
+        fromApiJsonDeserializer.validateForCreate(jsonObject.toString(), false);
 
-        final Address add = Address.fromJson(command, stateIdobj, countryIdObj);
-        add.setCreatedOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
-        add.setUpdatedOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
-        this.addressRepository.save(add);
-        final Long addressid = add.getId();
-        final Address addobj = this.addressRepository.getById(addressid);
+        final CodeValue addressTypeIdCodeValue = codeValueRepository.getById(addressTypeId);
+        final Client client = clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
 
-        final Client client = this.clientRepositoryWrapper.findOneWithNotFoundDetection(clientId);
-        final boolean isActive = command.booleanPrimitiveValueOfParameterNamed("isActive");
+        final Address address = createAddress(jsonObject);
+        addressRepository.save(address);
 
-        final ClientAddress clientAddressobj = ClientAddress.fromJson(isActive, client, addobj, addressTypeIdObj);
-        this.clientAddressRepository.saveAndFlush(clientAddressobj);
+        final ClientAddress clientAddress = createClientAddress(client, jsonObject, addressTypeIdCodeValue, address);
+        clientAddressRepository.saveAndFlush(clientAddress);
 
-        return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(clientAddressobj.getId()).build();
+        return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(clientAddress.getId()).build();
     }
 
-    // following method is used for adding multiple addresses while creating new
-    // client
-
     @Override
     public CommandProcessingResult addNewClientAddress(final Client client, final JsonCommand command) {
-        CodeValue stateIdobj = null;
-        CodeValue countryIdObj = null;
-        long stateId;
-        long countryId;
-        ClientAddress clientAddressobj = new ClientAddress();
+        ClientAddress clientAddress = new ClientAddress();
         final JsonArray addressArray = command.arrayOfParameterNamed("address");
 
         if (addressArray != null) {
             for (int i = 0; i < addressArray.size(); i++) {
                 final JsonObject jsonObject = addressArray.get(i).getAsJsonObject();
 
-                // validate every address
-                this.fromApiJsonDeserializer.validateForCreate(jsonObject.toString(), true);
+                fromApiJsonDeserializer.validateForCreate(jsonObject.toString(), true);
 
-                if (jsonObject.get("stateProvinceId") != null) {
-                    stateId = jsonObject.get("stateProvinceId").getAsLong();
-                    stateIdobj = this.codeValueRepository.getById(stateId);
-                }
+                final long addressTypeId = jsonObject.get("addressTypeId").getAsLong();
+                final CodeValue addressTypeIdCodeValue = codeValueRepository.getById(addressTypeId);
 
-                if (jsonObject.get("countryId") != null) {
-                    countryId = jsonObject.get("countryId").getAsLong();
-                    countryIdObj = this.codeValueRepository.getById(countryId);
-                }
+                final Address address = createAddress(jsonObject);
+                addressRepository.save(address);
 
-                final long addressTypeId = jsonObject.get("addressTypeId").getAsLong();
-                final CodeValue addressTypeIdObj = this.codeValueRepository.getById(addressTypeId);
+                clientAddress = createClientAddress(client, jsonObject, addressTypeIdCodeValue, address);
+                clientAddressRepository.saveAndFlush(clientAddress);
 
-                final Address add = Address.fromJsonObject(jsonObject, stateIdobj, countryIdObj);
-                add.setCreatedOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
-                add.setUpdatedOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
-                this.addressRepository.save(add);
-                final Long addressid = add.getId();
-                final Address addobj = this.addressRepository.getById(addressid);
+            }
+        }
 
-                // final boolean isActive =
-                // jsonObject.get("isActive").getAsBoolean();
-                boolean isActive = false;
-                if (jsonObject.get("isActive") != null) {
-                    isActive = jsonObject.get("isActive").getAsBoolean();
-                }
+        // This is confusing because only the last client address id is returned
+        // TODO: clean this up
+        return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(clientAddress.getId()).build();
+    }
+
+    private ClientAddress createClientAddress(Client client, JsonObject jsonObject, CodeValue addressTypeIdCodeValue, Address address) {
+        boolean clientAddressIsActive = false;
+        if (jsonObject.get("isActive") != null) {
+            clientAddressIsActive = jsonObject.get("isActive").getAsBoolean();
+        }
+        return ClientAddress.fromJson(clientAddressIsActive, client, address, addressTypeIdCodeValue);
+    }
 
-                clientAddressobj = ClientAddress.fromJson(isActive, client, addobj, addressTypeIdObj);
-                this.clientAddressRepository.saveAndFlush(clientAddressobj);
+    private Address createAddress(JsonObject jsonObject) {
+        CodeValue stateIdCodeValue = null;
+        if (jsonObject.get("stateProvinceId") != null) {
+            long stateId = jsonObject.get("stateProvinceId").getAsLong();
+            stateIdCodeValue = codeValueRepository.getById(stateId);
+        }
 
-            }
+        CodeValue countryIdCodeValue = null;
+        if (jsonObject.get("countryId") != null) {
+            long countryId = jsonObject.get("countryId").getAsLong();
+            countryIdCodeValue = codeValueRepository.getById(countryId);
         }
 
-        return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(clientAddressobj.getId()).build();
+        final Address address = Address.fromJsonObject(jsonObject, stateIdCodeValue, countryIdCodeValue);
+        address.setCreatedOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
+        address.setUpdatedOn(LocalDate.now(DateUtils.getDateTimeZoneOfTenant()));
+        return address;
     }
 
     @Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResources.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResources.java
index 75c8976bc..b6db99ea0 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResources.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResources.java
@@ -133,6 +133,8 @@ public class ClientAddressApiResources {
 
         this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
 
+        // TODO: This is quite a confusing implementation with all these checks
+        // These have to be considered as filtering criterias instead
         if (addressTypeId == 0 && status == null) {
             address = this.readPlatformService.retrieveAllClientAddress(clientid);
         } else if (addressTypeId != 0 && status == null) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResourcesSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResourcesSwagger.java
index cd71c6dbb..177fcd272 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResourcesSwagger.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientAddressApiResourcesSwagger.java
@@ -49,6 +49,8 @@ final class ClientAddressApiResourcesSwagger {
         public Integer countryId;
         @Schema(example = "400064")
         public Long postalCode;
+        @Schema(example = "true")
+        public Boolean isActive;
     }
 
     @Schema(description = "PostClientClientIdAddressesResponse")
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java
index ad7efc181..10127b802 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResource.java
@@ -48,6 +48,7 @@ import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+import lombok.RequiredArgsConstructor;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.commands.domain.CommandWrapper;
 import org.apache.fineract.commands.service.CommandWrapperBuilder;
@@ -74,7 +75,6 @@ import org.apache.fineract.portfolio.savings.data.SavingsAccountData;
 import org.apache.fineract.portfolio.savings.service.SavingsAccountReadPlatformService;
 import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
 import org.glassfish.jersey.media.multipart.FormDataParam;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -83,6 +83,7 @@ import org.springframework.stereotype.Component;
 @Scope("singleton")
 @Tag(name = "Client", description = "Clients are people and businesses that have applied (or may apply) to an MFI for loans.\n" + "\n"
         + "Clients can be created in Pending or straight into Active state.")
+@RequiredArgsConstructor
 public class ClientsApiResource {
 
     private final PlatformSecurityContext context;
@@ -97,29 +98,6 @@ public class ClientsApiResource {
     private final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService;
     private final GuarantorReadPlatformService guarantorReadPlatformService;
 
-    @Autowired
-    public ClientsApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
-            final ToApiJsonSerializer<ClientData> toApiJsonSerializer,
-            final ToApiJsonSerializer<AccountSummaryCollectionData> clientAccountSummaryToApiJsonSerializer,
-            final ApiRequestParameterHelper apiRequestParameterHelper,
-            final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
-            final AccountDetailsReadPlatformService accountDetailsReadPlatformService,
-            final SavingsAccountReadPlatformService savingsAccountReadPlatformService,
-            final BulkImportWorkbookPopulatorService bulkImportWorkbookPopulatorService,
-            final BulkImportWorkbookService bulkImportWorkbookService, final GuarantorReadPlatformService guarantorReadPlatformService) {
-        this.context = context;
-        this.clientReadPlatformService = readPlatformService;
-        this.toApiJsonSerializer = toApiJsonSerializer;
-        this.clientAccountSummaryToApiJsonSerializer = clientAccountSummaryToApiJsonSerializer;
-        this.apiRequestParameterHelper = apiRequestParameterHelper;
-        this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
-        this.accountDetailsReadPlatformService = accountDetailsReadPlatformService;
-        this.savingsAccountReadPlatformService = savingsAccountReadPlatformService;
-        this.bulkImportWorkbookPopulatorService = bulkImportWorkbookPopulatorService;
-        this.bulkImportWorkbookService = bulkImportWorkbookService;
-        this.guarantorReadPlatformService = guarantorReadPlatformService;
-    }
-
     @GET
     @Path("template")
     @Consumes({ MediaType.APPLICATION_JSON })
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java
index 8bf03e027..4c9fce88a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/api/ClientsApiResourceSwagger.java
@@ -266,12 +266,42 @@ final class ClientsApiResourceSwagger {
 
         }
 
+        static final class PostClientsAddressRequest {
+
+            @Schema(example = "Ipca")
+            public String street;
+            @Schema(example = "Kandivali")
+            public String addressLine1;
+            @Schema(example = "plot47")
+            public String addressLine2;
+            @Schema(example = "charkop")
+            public String addressLine3;
+            @Schema(example = "Mumbai")
+            public String city;
+            @Schema(example = "800")
+            public Integer stateProvinceId;
+            @Schema(example = "802")
+            public Integer countryId;
+            @Schema(example = "400064")
+            public Long postalCode;
+            @Schema(example = "1")
+            public Long addressTypeId;
+            @Schema(example = "true")
+            public Boolean isActive;
+        }
+
         @Schema(example = "1")
         public Integer officeId;
         @Schema(example = "1")
         public Integer legalFormId;
         @Schema(example = "Client of group")
         public String fullname;
+        @Schema(example = "Client_FirstName")
+        public String firstname;
+        @Schema(example = "123")
+        public String externalId;
+        @Schema(example = "Client_LastName")
+        public String lastname;
         @Schema(example = "1")
         public Integer groupId;
         @Schema(example = "dd MMMM yyyy")
@@ -284,6 +314,8 @@ final class ClientsApiResourceSwagger {
         public String activationDate;
         @Schema(description = "List of PostClientsDatatable")
         public List<PostClientsDatatable> datatables;
+        @Schema(description = "Address requests")
+        public List<PostClientsAddressRequest> address;
 
     }
 
diff --git a/integration-tests/dependencies.gradle b/integration-tests/dependencies.gradle
index 759a5e0a6..da8ed8507 100644
--- a/integration-tests/dependencies.gradle
+++ b/integration-tests/dependencies.gradle
@@ -38,4 +38,7 @@ dependencies {
         exclude group: 'org.apache.sling'
         exclude group: 'com.sun.xml.bind'
     }
+
+    testCompileOnly 'org.projectlombok:lombok'
+    testAnnotationProcessor 'org.projectlombok:lombok'
 }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientTest.java
index 6f2622d40..5ffabbd27 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.integrationtests;
 
+import static org.apache.fineract.integrationtests.client.IntegrationTest.assertThat;
 import static org.junit.jupiter.api.Assertions.assertNotEquals;
 
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@@ -29,122 +30,133 @@ import io.restassured.specification.ResponseSpecification;
 import java.security.SecureRandom;
 import java.util.HashMap;
 import java.util.List;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.fineract.client.models.GetClientClientIdAddressesResponse;
+import org.apache.fineract.client.models.GlobalConfigurationPropertyData;
+import org.apache.fineract.client.models.PostClientClientIdAddressesRequest;
+import org.apache.fineract.client.models.PostClientClientIdAddressesResponse;
+import org.apache.fineract.client.models.PostClientsAddressRequest;
+import org.apache.fineract.client.models.PostClientsRequest;
 import org.apache.fineract.integrationtests.common.ClientHelper;
+import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
 import org.apache.fineract.integrationtests.common.Utils;
+import org.apache.fineract.integrationtests.common.system.CodeHelper;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 public class ClientTest {
 
+    private static final SecureRandom rand = new SecureRandom();
+
     private ResponseSpecification responseSpec;
     private RequestSpecification requestSpec;
     private ClientHelper clientHelper;
-    private static final SecureRandom rand = new SecureRandom();
 
     @BeforeEach
     public void setup() {
         Utils.initializeRESTAssured();
-        this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
-        this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
-        this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
-        this.clientHelper = new ClientHelper(this.requestSpec, this.responseSpec);
+        requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build();
+        requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+        responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
+        clientHelper = new ClientHelper(requestSpec, responseSpec);
+    }
+
+    @AfterEach
+    public void tearDown() {
+        GlobalConfigurationHelper.resetAllDefaultGlobalConfigurations(requestSpec, responseSpec);
+        GlobalConfigurationHelper.verifyAllDefaultGlobalConfigurations(requestSpec, responseSpec);
     }
 
     @Test
     public void testClientStatus() {
-
-        final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec);
-        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientId);
-        // Assertions.assertNotNull(clientId);
+        final Integer clientId = ClientHelper.createClient(requestSpec, responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(requestSpec, responseSpec, clientId);
 
         HashMap<String, Object> status = ClientHelper.getClientStatus(requestSpec, responseSpec, String.valueOf(clientId));
         ClientStatusChecker.verifyClientIsActive(status);
 
-        HashMap<String, Object> clientStatusHashMap = this.clientHelper.closeClient(clientId);
+        HashMap<String, Object> clientStatusHashMap = clientHelper.closeClient(clientId);
         ClientStatusChecker.verifyClientClosed(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.reactivateClient(clientId);
+        clientStatusHashMap = clientHelper.reactivateClient(clientId);
         ClientStatusChecker.verifyClientPending(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.rejectClient(clientId);
+        clientStatusHashMap = clientHelper.rejectClient(clientId);
         ClientStatusChecker.verifyClientRejected(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.activateClient(clientId);
+        clientStatusHashMap = clientHelper.activateClient(clientId);
         ClientStatusChecker.verifyClientActiavted(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.closeClient(clientId);
+        clientStatusHashMap = clientHelper.closeClient(clientId);
         ClientStatusChecker.verifyClientClosed(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.reactivateClient(clientId);
+        clientStatusHashMap = clientHelper.reactivateClient(clientId);
         ClientStatusChecker.verifyClientPending(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.withdrawClient(clientId);
+        clientStatusHashMap = clientHelper.withdrawClient(clientId);
         ClientStatusChecker.verifyClientWithdrawn(clientStatusHashMap);
 
     }
 
     @Test
     public void testClientAsPersonStatus() {
-
-        final Integer clientId = ClientHelper.createClientAsPerson(this.requestSpec, this.responseSpec);
-        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientId);
-        // Assertions.assertNotNull(clientId);
+        final Integer clientId = ClientHelper.createClientAsPerson(requestSpec, responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(requestSpec, responseSpec, clientId);
 
         HashMap<String, Object> status = ClientHelper.getClientStatus(requestSpec, responseSpec, String.valueOf(clientId));
         ClientStatusChecker.verifyClientIsActive(status);
 
-        HashMap<String, Object> clientStatusHashMap = this.clientHelper.closeClient(clientId);
+        HashMap<String, Object> clientStatusHashMap = clientHelper.closeClient(clientId);
         ClientStatusChecker.verifyClientClosed(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.reactivateClient(clientId);
+        clientStatusHashMap = clientHelper.reactivateClient(clientId);
         ClientStatusChecker.verifyClientPending(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.rejectClient(clientId);
+        clientStatusHashMap = clientHelper.rejectClient(clientId);
         ClientStatusChecker.verifyClientRejected(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.activateClient(clientId);
+        clientStatusHashMap = clientHelper.activateClient(clientId);
         ClientStatusChecker.verifyClientActiavted(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.closeClient(clientId);
+        clientStatusHashMap = clientHelper.closeClient(clientId);
         ClientStatusChecker.verifyClientClosed(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.reactivateClient(clientId);
+        clientStatusHashMap = clientHelper.reactivateClient(clientId);
         ClientStatusChecker.verifyClientPending(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.withdrawClient(clientId);
+        clientStatusHashMap = clientHelper.withdrawClient(clientId);
         ClientStatusChecker.verifyClientWithdrawn(clientStatusHashMap);
 
     }
 
     @Test
     public void testClientAsEntityStatus() {
-
-        final Integer clientId = ClientHelper.createClientAsEntity(this.requestSpec, this.responseSpec);
-        ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientId);
-        // Assertions.assertNotNull(clientId);
+        final Integer clientId = ClientHelper.createClientAsEntity(requestSpec, responseSpec);
+        ClientHelper.verifyClientCreatedOnServer(requestSpec, responseSpec, clientId);
 
         HashMap<String, Object> status = ClientHelper.getClientStatus(requestSpec, responseSpec, String.valueOf(clientId));
         ClientStatusChecker.verifyClientIsActive(status);
 
-        HashMap<String, Object> clientStatusHashMap = this.clientHelper.closeClient(clientId);
+        HashMap<String, Object> clientStatusHashMap = clientHelper.closeClient(clientId);
         ClientStatusChecker.verifyClientClosed(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.reactivateClient(clientId);
+        clientStatusHashMap = clientHelper.reactivateClient(clientId);
         ClientStatusChecker.verifyClientPending(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.rejectClient(clientId);
+        clientStatusHashMap = clientHelper.rejectClient(clientId);
         ClientStatusChecker.verifyClientRejected(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.activateClient(clientId);
+        clientStatusHashMap = clientHelper.activateClient(clientId);
         ClientStatusChecker.verifyClientActiavted(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.closeClient(clientId);
+        clientStatusHashMap = clientHelper.closeClient(clientId);
         ClientStatusChecker.verifyClientClosed(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.reactivateClient(clientId);
+        clientStatusHashMap = clientHelper.reactivateClient(clientId);
         ClientStatusChecker.verifyClientPending(clientStatusHashMap);
 
-        clientStatusHashMap = this.clientHelper.withdrawClient(clientId);
+        clientStatusHashMap = clientHelper.withdrawClient(clientId);
         ClientStatusChecker.verifyClientWithdrawn(clientStatusHashMap);
 
     }
@@ -157,11 +169,11 @@ public class ClientTest {
 
         // Add a few clients to the server and activate a random amount of them
         for (int i = 0; i < 15; i++) {
-            final Integer clientId = ClientHelper.createClientAsEntity(this.requestSpec, this.responseSpec);
+            final Integer clientId = ClientHelper.createClientAsEntity(requestSpec, responseSpec);
             if (rand.nextInt(10) % 2 == 0) {
                 // Takes Client to pending status
-                this.clientHelper.closeClient(clientId);
-                this.clientHelper.reactivateClient(clientId);
+                clientHelper.closeClient(clientId);
+                clientHelper.reactivateClient(clientId);
             }
             // Other clients stay in Active status
         }
@@ -182,4 +194,73 @@ public class ClientTest {
         }
     }
 
+    @Test
+    public void testClientAddressCreationWorks() {
+        // given
+        GlobalConfigurationPropertyData addressEnabledConfig = GlobalConfigurationHelper.getGlobalConfigurationByName(requestSpec,
+                responseSpec, "Enable-Address");
+        Long configId = addressEnabledConfig.getId();
+
+        GlobalConfigurationHelper.updateEnabledFlagForGlobalConfiguration(requestSpec, responseSpec, configId, true);
+        GlobalConfigurationPropertyData updatedAddressEnabledConfig = GlobalConfigurationHelper.getGlobalConfigurationByName(requestSpec,
+                responseSpec, "Enable-Address");
+        boolean isAddressEnabled = BooleanUtils.toBoolean(updatedAddressEnabledConfig.getEnabled());
+        assertThat(isAddressEnabled).isTrue();
+
+        Integer addressTypeId = CodeHelper.createAddressTypeCodeValue(requestSpec, responseSpec,
+                Utils.randomNameGenerator("Residential address", 4), 0);
+        Integer countryId = CodeHelper.createCountryCodeValue(requestSpec, responseSpec, Utils.randomNameGenerator("Hungary", 4), 0);
+        Integer stateId = CodeHelper.createStateCodeValue(requestSpec, responseSpec, Utils.randomNameGenerator("Budapest", 4), 0);
+        String city = "Budapest";
+        boolean addressIsActive = true;
+        long postalCode = 1000L;
+
+        // when
+        PostClientsAddressRequest addressRequest = new PostClientsAddressRequest().postalCode(postalCode).city(city).countryId(countryId)
+                .stateProvinceId(stateId).addressTypeId(addressTypeId.longValue()).isActive(addressIsActive);
+        PostClientsRequest request = ClientHelper.defaultClientCreationRequest().address(List.of(addressRequest));
+        final Integer clientId = ClientHelper.createClient(requestSpec, responseSpec, request);
+
+        // then
+        ClientHelper.verifyClientCreatedOnServer(requestSpec, responseSpec, clientId);
+        List<GetClientClientIdAddressesResponse> clientAddresses = ClientHelper.getClientAddresses(requestSpec, responseSpec, clientId);
+        GetClientClientIdAddressesResponse addressResponse = clientAddresses.get(0);
+        assertThat(addressResponse.getCity()).isEqualTo(city);
+        assertThat(addressResponse.getCountryId()).isEqualTo(countryId);
+        assertThat(addressResponse.getStateProvinceId()).isEqualTo(stateId);
+        assertThat(addressResponse.getAddressTypeId()).isEqualTo(addressTypeId);
+        assertThat(addressResponse.getIsActive()).isEqualTo(addressIsActive);
+        assertThat(addressResponse.getPostalCode()).isEqualTo(postalCode);
+    }
+
+    @Test
+    public void testClientAddressCreationWorksAfterClientIsCreated() {
+        // given
+        Integer addressTypeId = CodeHelper.createAddressTypeCodeValue(requestSpec, responseSpec,
+                Utils.randomNameGenerator("Residential address", 4), 0);
+        Integer countryId = CodeHelper.createCountryCodeValue(requestSpec, responseSpec, Utils.randomNameGenerator("Hungary", 4), 0);
+        Integer stateId = CodeHelper.createStateCodeValue(requestSpec, responseSpec, Utils.randomNameGenerator("Budapest", 4), 0);
+        String city = "Budapest";
+        boolean addressIsActive = true;
+        long postalCode = 1000L;
+
+        PostClientsRequest clientRequest = ClientHelper.defaultClientCreationRequest();
+        final Integer clientId = ClientHelper.createClient(requestSpec, responseSpec, clientRequest);
+        // when
+        PostClientClientIdAddressesRequest request = new PostClientClientIdAddressesRequest().postalCode(postalCode).city(city)
+                .countryId(countryId).stateProvinceId(stateId).isActive(addressIsActive);
+        PostClientClientIdAddressesResponse response = ClientHelper.createClientAddress(requestSpec, responseSpec, clientId.longValue(),
+                addressTypeId, request);
+        // then
+        assertThat(response.getResourceId()).isNotNull();
+        List<GetClientClientIdAddressesResponse> clientAddresses = ClientHelper.getClientAddresses(requestSpec, responseSpec, clientId);
+        GetClientClientIdAddressesResponse addressResponse = clientAddresses.get(0);
+        assertThat(addressResponse.getCity()).isEqualTo(city);
+        assertThat(addressResponse.getCountryId()).isEqualTo(countryId);
+        assertThat(addressResponse.getStateProvinceId()).isEqualTo(stateId);
+        assertThat(addressResponse.getAddressTypeId()).isEqualTo(addressTypeId);
+        assertThat(addressResponse.getIsActive()).isEqualTo(addressIsActive);
+        assertThat(addressResponse.getPostalCode()).isEqualTo(postalCode);
+    }
+
 }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java
index 8fce44e78..1d1c9c40f 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ClientHelper.java
@@ -20,6 +20,7 @@ package org.apache.fineract.integrationtests.common;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
+import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
 import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
@@ -33,19 +34,23 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.client.models.GetClientClientIdAddressesResponse;
+import org.apache.fineract.client.models.GetClientsClientIdResponse;
+import org.apache.fineract.client.models.PostClientClientIdAddressesRequest;
+import org.apache.fineract.client.models.PostClientClientIdAddressesResponse;
+import org.apache.fineract.client.models.PostClientsRequest;
+import org.apache.fineract.client.util.JSON;
 import org.apache.fineract.infrastructure.bulkimport.data.GlobalEntityType;
 import org.apache.fineract.integrationtests.common.system.CodeHelper;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.Workbook;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+@Slf4j
+@RequiredArgsConstructor
 public class ClientHelper {
 
-    private static final Logger LOG = LoggerFactory.getLogger(ClientHelper.class);
-    private final RequestSpecification requestSpec;
-    private final ResponseSpecification responseSpec;
-
     private static final String CREATE_CLIENT_URL = "/fineract-provider/api/v1/clients?" + Utils.TENANT_IDENTIFIER;
     private static final String CLIENT_URL = "/fineract-provider/api/v1/clients";
     private static final String CLOSE_CLIENT_COMMAND = "close";
@@ -67,9 +72,16 @@ public class ClientHelper {
     public static final String DATE_FORMAT = "dd MMMM yyyy";
     public static final String DATE_TIME_FORMAT = "dd MMMM yyyy HH:mm";
 
-    public ClientHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
-        this.requestSpec = requestSpec;
-        this.responseSpec = responseSpec;
+    private static final Gson GSON = new JSON().getGson();
+
+    private final RequestSpecification requestSpec;
+    private final ResponseSpecification responseSpec;
+
+    public static Integer createClient(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            PostClientsRequest request) {
+        log.info("---------------------------------CREATING A CLIENT---------------------------------------------");
+        String requestBody = GSON.toJson(request);
+        return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, requestBody, "clientId");
     }
 
     public static Integer createClient(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
@@ -83,11 +95,21 @@ public class ClientHelper {
 
     public static Integer createClient(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String activationDate, final String officeId) {
-        LOG.info("---------------------------------CREATING A CLIENT---------------------------------------------");
+        log.info("---------------------------------CREATING A CLIENT---------------------------------------------");
         return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, getTestClientAsJSON(activationDate, officeId),
                 "clientId");
     }
 
+    public static PostClientClientIdAddressesResponse createClientAddress(final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec, long clientId, long addressTypeId, PostClientClientIdAddressesRequest request) {
+        final String CREATE_CLIENT_ADDRESS_URL = "/fineract-provider/api/v1/client/" + clientId + "/addresses?type=" + addressTypeId + "&"
+                + Utils.TENANT_IDENTIFIER;
+        log.info("---------------------------------CREATING A CLIENT ADDRESS ---------------------------------------------");
+        String requestBody = GSON.toJson(request);
+        String response = Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_ADDRESS_URL, requestBody);
+        return GSON.fromJson(response, PostClientClientIdAddressesResponse.class);
+    }
+
     public static Integer createClientPending(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
         return createClientPending(requestSpec, responseSpec, "04 March 2014");
     }
@@ -99,20 +121,20 @@ public class ClientHelper {
 
     public static Integer createClientPending(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String submittedOnDate, final String officeId) {
-        LOG.info("---------------------------------CREATING A CLIENT IN PENDING---------------------------------------------");
+        log.info("---------------------------------CREATING A CLIENT IN PENDING---------------------------------------------");
         return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, getTestClientAsJSONPending(submittedOnDate, officeId),
                 "clientId");
     }
 
     public Object createClientPendingWithError(final String jsonAttributeToGetBack) {
-        LOG.info("---------------------------------CREATING A CLIENT IN PENDING WITH ERROR---------------------------------------------");
+        log.info("---------------------------------CREATING A CLIENT IN PENDING WITH ERROR---------------------------------------------");
         return Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_CLIENT_URL,
                 getTestClientAsJSONPending("04 March 2014", "1"), jsonAttributeToGetBack);
     }
 
     public static Integer createClientPendingWithDatatable(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String registeredTableName) {
-        LOG.info("-------------------------- CREATING A CLIENT IN PENDING WITH DATATABLES --------------------------------");
+        log.info("-------------------------- CREATING A CLIENT IN PENDING WITH DATATABLES --------------------------------");
         return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL,
                 getTestPendingClientWithDatatableAsJson(registeredTableName), "clientId");
     }
@@ -129,7 +151,7 @@ public class ClientHelper {
     public static Integer createClientAsPerson(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String activationDate, final String officeId) {
 
-        LOG.info(
+        log.info(
                 "---------------------------------CREATING A CLIENT NON PERSON(ORGANISATION)---------------------------------------------");
         return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL, getTestPersonClientAsJSON(activationDate, officeId),
                 "clientId");
@@ -151,7 +173,7 @@ public class ClientHelper {
         Integer soleProprietorCodeValueId = (Integer) CodeHelper.retrieveOrCreateCodeValue(constitutionCodeId, requestSpec, responseSpec)
                 .get("id");
 
-        LOG.info(
+        log.info(
                 "---------------------------------CREATING A CLIENT NON PERSON(ORGANISATION)---------------------------------------------");
         return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL,
                 getTestEntityClientAsJSON(activationDate, officeId, soleProprietorCodeValueId), "clientId");
@@ -161,7 +183,7 @@ public class ClientHelper {
             final Integer clientType, String jsonAttributeToGetBack) {
         final String activationDate = "04 March 2011";
         final String officeId = "1";
-        LOG.info(
+        log.info(
                 "---------------------------------CREATING A CLIENT BASED ON ACCOUNT PREFERENCE---------------------------------------------");
         return Utils.performServerPost(requestSpec, responseSpec, CREATE_CLIENT_URL,
                 getTestClientWithClientTypeAsJSON(activationDate, officeId, clientType.toString()), jsonAttributeToGetBack);
@@ -172,7 +194,7 @@ public class ClientHelper {
         final String CLIENT_ASSIGN_STAFF_URL = "/fineract-provider/api/v1/clients/" + clientId + "?" + Utils.TENANT_IDENTIFIER
                 + "&command=assignStaff";
 
-        LOG.info("---------------------------------CREATING A CLIENT---------------------------------------------");
+        log.info("---------------------------------CREATING A CLIENT---------------------------------------------");
         return Utils.performServerPost(requestSpec, responseSpec, CLIENT_ASSIGN_STAFF_URL, assignStaffToClientAsJson(staffId), "changes");
     }
 
@@ -192,8 +214,8 @@ public class ClientHelper {
         map.put("locale", "en");
         map.put("active", "true");
         map.put("activationDate", dateOfJoining);
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+        log.info("map :  {}", map);
+        return GSON.toJson(map);
     }
 
     public static String getTestClientAsJSONPending(final String submittedOnDate, final String officeId) {
@@ -207,8 +229,8 @@ public class ClientHelper {
         map.put("locale", "en");
         map.put("active", "false");
         map.put("submittedOnDate", submittedOnDate);
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+        log.info("map :  {}", map);
+        return GSON.toJson(map);
     }
 
     public static String getTestPendingClientWithDatatableAsJson(final String registeredTableName) {
@@ -223,7 +245,7 @@ public class ClientHelper {
         map.put("active", "false");
         map.put("submittedOnDate", "04 March 2014");
         String requestJson = getTestDatatableAsJson(map, registeredTableName);
-        LOG.info("map : {}", requestJson);
+        log.info("map : {}", requestJson);
         return requestJson;
     }
 
@@ -241,7 +263,7 @@ public class ClientHelper {
         datatableMap.put("data", dataMap);
         datatablesListMap.add(datatableMap);
         map.put("datatables", datatablesListMap);
-        return new Gson().toJson(map);
+        return GSON.toJson(map);
     }
 
     public static String getTestPersonClientAsJSON(final String dateOfJoining, final String officeId) {
@@ -255,8 +277,8 @@ public class ClientHelper {
         map.put("activationDate", dateOfJoining);
         map.put("legalFormId", 1);
 
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+        log.info("map :  {}", map);
+        return GSON.toJson(map);
     }
 
     public static String getTestEntityClientAsJSON(final String dateOfJoining, final String officeId,
@@ -275,8 +297,8 @@ public class ClientHelper {
         clientNonPersonMap.put("constitutionId", soleProprietorCodeValueId);
         map.put("clientNonPersonDetails", clientNonPersonMap);
 
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+        log.info("map :  {}", map);
+        return GSON.toJson(map);
     }
 
     public static String getTestClientWithClientTypeAsJSON(final String dateOfJoining, final String officeId, final String clientType) {
@@ -291,31 +313,44 @@ public class ClientHelper {
         map.put("active", "true");
         map.put("activationDate", dateOfJoining);
         map.put("clientTypeId", clientType);
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+        log.info("map :  {}", map);
+        return GSON.toJson(map);
     }
 
     public static String assignStaffToClientAsJson(final String staffId) {
         final HashMap<String, String> map = new HashMap<>();
         map.put("staffId", staffId);
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+        log.info("map :  {}", map);
+        return GSON.toJson(map);
     }
 
     public static void verifyClientCreatedOnServer(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
-            final Integer generatedClientID) {
-        LOG.info("------------------------------CHECK CLIENT DETAILS------------------------------------\n");
-        final String CLIENT_URL = "/fineract-provider/api/v1/clients/" + generatedClientID + "?" + Utils.TENANT_IDENTIFIER;
+            final Integer clientId) {
+        log.info("------------------------------CHECK CLIENT DETAILS------------------------------------\n");
+        final String CLIENT_URL = "/fineract-provider/api/v1/clients/" + clientId + "?" + Utils.TENANT_IDENTIFIER;
         final Integer responseClientID = Utils.performServerGet(requestSpec, responseSpec, CLIENT_URL, "id");
-        assertEquals(generatedClientID, responseClientID, "ERROR IN CREATING THE CLIENT");
+        assertEquals(clientId, responseClientID, "ERROR IN CREATING THE CLIENT");
+    }
+
+    public static GetClientsClientIdResponse getClient(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final int clientId) {
+        String clientResponseStr = (String) getClient(requestSpec, responseSpec, Integer.toString(clientId), null);
+        return GSON.fromJson(clientResponseStr, GetClientsClientIdResponse.class);
+    }
+
+    public static List<GetClientClientIdAddressesResponse> getClientAddresses(final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec, final int clientId) {
+        final String GET_CLIENT_ADDRESSES_URL = "/fineract-provider/api/v1/client/" + clientId + "/addresses?" + Utils.TENANT_IDENTIFIER;
+        log.info("---------------------------------GET A CLIENT'S ADDRESSES ---------------------------------------------");
+        String clientResponseStr = Utils.performServerGet(requestSpec, responseSpec, GET_CLIENT_ADDRESSES_URL);
+        return GSON.fromJson(clientResponseStr, new TypeToken<List<GetClientClientIdAddressesResponse>>() {}.getType());
     }
 
     public static Object getClient(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final String clientId,
             final String jsonReturn) {
         final String GET_CLIENT_URL = "/fineract-provider/api/v1/clients/" + clientId + "?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("---------------------------------GET A CLIENT---------------------------------------------");
+        log.info("---------------------------------GET A CLIENT---------------------------------------------");
         return Utils.performServerGet(requestSpec, responseSpec, GET_CLIENT_URL, jsonReturn);
-
     }
 
     /* Client status is a map.So adding SuppressWarnings */
@@ -346,8 +381,8 @@ public class ClientHelper {
         map.put("dateFormat", CommonConstants.DATE_FORMAT);
         map.put("closureDate", CREATED_DATE_PLUS_ONE);
 
-        String clientJson = new Gson().toJson(map);
-        LOG.info(clientJson);
+        String clientJson = GSON.toJson(map);
+        log.info(clientJson);
         return clientJson;
 
     }
@@ -357,8 +392,8 @@ public class ClientHelper {
         map.put("locale", CommonConstants.LOCALE);
         map.put("dateFormat", CommonConstants.DATE_FORMAT);
         map.put("reactivationDate", CREATED_DATE_PLUS_ONE);
-        String clientJson = new Gson().toJson(map);
-        LOG.info(clientJson);
+        String clientJson = GSON.toJson(map);
+        log.info(clientJson);
         return clientJson;
 
     }
@@ -368,8 +403,8 @@ public class ClientHelper {
         map.put("locale", CommonConstants.LOCALE);
         map.put("dateFormat", CommonConstants.DATE_FORMAT);
         map.put("reopenedDate", date);
-        String clientJson = new Gson().toJson(map);
-        LOG.info(clientJson);
+        String clientJson = GSON.toJson(map);
+        log.info(clientJson);
         return clientJson;
 
     }
@@ -379,8 +414,8 @@ public class ClientHelper {
         map.put("locale", CommonConstants.LOCALE);
         map.put("dateFormat", CommonConstants.DATE_FORMAT);
         map.put("reopenedDate", date);
-        String clientJson = new Gson().toJson(map);
-        LOG.info(clientJson);
+        String clientJson = GSON.toJson(map);
+        log.info(clientJson);
         return clientJson;
 
     }
@@ -401,8 +436,8 @@ public class ClientHelper {
         map.put("dateFormat", CommonConstants.DATE_FORMAT);
         map.put("rejectionDate", CREATED_DATE_PLUS_ONE);
         map.put("rejectionReasonId", rejectionReasonId.toString());
-        String clientJson = new Gson().toJson(map);
-        LOG.info(clientJson);
+        String clientJson = GSON.toJson(map);
+        log.info(clientJson);
         return clientJson;
 
     }
@@ -412,8 +447,8 @@ public class ClientHelper {
         map.put("locale", CommonConstants.LOCALE);
         map.put("dateFormat", CommonConstants.DATE_FORMAT);
         map.put("activationDate", date);
-        String clientJson = new Gson().toJson(map);
-        LOG.info(clientJson);
+        String clientJson = GSON.toJson(map);
+        log.info(clientJson);
         return clientJson;
     }
 
@@ -433,8 +468,8 @@ public class ClientHelper {
         map.put("dateFormat", CommonConstants.DATE_FORMAT);
         map.put("withdrawalDate", CREATED_DATE_PLUS_ONE);
         map.put("withdrawalReasonId", withdrawalReasonId.toString());
-        String clientJson = new Gson().toJson(map);
-        LOG.info(clientJson);
+        String clientJson = GSON.toJson(map);
+        log.info(clientJson);
         return clientJson;
 
     }
@@ -446,7 +481,7 @@ public class ClientHelper {
         map.put("dueDate", dueDate);
         map.put("chargeId", chargeId);
         map.put("amount", "200");
-        String json = new Gson().toJson(map);
+        String json = GSON.toJson(map);
         return json;
     }
 
@@ -456,8 +491,8 @@ public class ClientHelper {
         map.put("dateFormat", DATE_FORMAT);
         map.put("transactionDate", date);
         map.put("amount", amount);
-        String json = new Gson().toJson(map);
-        LOG.info("{}", json);
+        String json = GSON.toJson(map);
+        log.info("{}", json);
         return json;
     }
 
@@ -466,34 +501,34 @@ public class ClientHelper {
         map.put("locale", "en_GB");
         map.put("amount", amount);
         map.put("clientChargeId", clientChargeId);
-        String json = new Gson().toJson(map);
-        LOG.info("{}", json);
+        String json = GSON.toJson(map);
+        log.info("{}", json);
         return json;
     }
 
     public HashMap<String, Object> closeClient(final Integer clientId) {
-        LOG.info("--------------------------------- CLOSE CLIENT -------------------------------");
+        log.info("--------------------------------- CLOSE CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(CLOSE_CLIENT_COMMAND, clientId), getCloseClientAsJSON(), clientId);
     }
 
     public HashMap<String, Object> reactivateClient(final Integer clientId) {
-        LOG.info("--------------------------------- REACTIVATE CLIENT -------------------------------");
+        log.info("--------------------------------- REACTIVATE CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(REACTIVATE_CLIENT_COMMAND, clientId), getReactivateClientAsJSON(), clientId);
     }
 
     public HashMap<String, Object> rejectClient(final Integer clientId) {
-        LOG.info("--------------------------------- REJECT CLIENT -------------------------------");
+        log.info("--------------------------------- REJECT CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(REJECT_CLIENT_COMMAND, clientId), getRejectClientAsJSON(), clientId);
     }
 
     public HashMap<String, Object> activateClient(final Integer clientId) {
-        LOG.info("--------------------------------- ACTIVATE CLIENT -------------------------------");
+        log.info("--------------------------------- ACTIVATE CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(ACTIVATE_CLIENT_COMMAND, clientId),
                 getActivateClientAsJSON(CREATED_DATE_PLUS_ONE), clientId);
     }
 
     public HashMap<String, Object> withdrawClient(final Integer clientId) {
-        LOG.info("--------------------------------- WITHDRAWN CLIENT -------------------------------");
+        log.info("--------------------------------- WITHDRAWN CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(WITHDRAW_CLIENT_COMMAND, clientId), getWithdrawClientAsJSON(), clientId);
     }
 
@@ -502,39 +537,39 @@ public class ClientHelper {
     }
 
     public HashMap<String, Object> undoReject(final Integer clientId) {
-        LOG.info("--------------------------------- UNDO REJECT CLIENT -------------------------------");
+        log.info("--------------------------------- UNDO REJECT CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(UNDOREJECT_CLIENT_COMMAND, clientId),
                 getUndoRejectClientAsJSON(CREATED_DATE_PLUS_TWO), clientId);
     }
 
     public HashMap<String, Object> undoWithdrawn(final Integer clientId) {
-        LOG.info("--------------------------------- UNDO WITHDRAWN CLIENT -------------------------------");
+        log.info("--------------------------------- UNDO WITHDRAWN CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(UNDOWITHDRAWN_CLIENT_COMMAND, clientId),
                 getUndoWithdrawnClientAsJSON(CREATED_DATE_PLUS_TWO), clientId);
     }
 
     public ArrayList<HashMap<String, Object>> undoRejectedclient(final Integer clientId, final String jsonAttributeToGetBack,
             final String rejectedDate) {
-        LOG.info("----------------------------------UNDO REJECT CLIENT ----------------------------------");
+        log.info("----------------------------------UNDO REJECT CLIENT ----------------------------------");
         return performClientActionsWithValidationErrors(createClientOperationURL(UNDOREJECT_CLIENT_COMMAND, clientId),
                 getUndoRejectClientAsJSON(rejectedDate), jsonAttributeToGetBack);
     }
 
     public ArrayList<HashMap<String, Object>> undoWithdrawclient(final Integer clientId, final String jsonAttributeToGetBack,
             final String rejectedDate) {
-        LOG.info("----------------------------------UNDO WITHDRAW CLIENT ----------------------------------");
+        log.info("----------------------------------UNDO WITHDRAW CLIENT ----------------------------------");
         return performClientActionsWithValidationErrors(createClientOperationURL(UNDOWITHDRAWN_CLIENT_COMMAND, clientId),
                 getUndoWithdrawnClientAsJSON(rejectedDate), jsonAttributeToGetBack);
     }
 
     public ArrayList<HashMap<String, Object>> activateClient(final Integer clientId, final String jsonAttributeToGetBack) {
-        LOG.info("--------------------------------- ACTIVATE CLIENT -------------------------------");
+        log.info("--------------------------------- ACTIVATE CLIENT -------------------------------");
         return performClientActionsWithValidationErrors(createClientOperationURL(ACTIVATE_CLIENT_COMMAND, clientId),
                 getActivateClientAsJSON(CREATED_DATE_PLUS_ONE), jsonAttributeToGetBack);
     }
 
     public HashMap<String, Object> activateClientWithDiffDateOption(final Integer clientId, final String activationDate) {
-        LOG.info("--------------------------------- ACTIVATE CLIENT -------------------------------");
+        log.info("--------------------------------- ACTIVATE CLIENT -------------------------------");
         return performClientActions(createClientOperationURL(ACTIVATE_CLIENT_COMMAND, clientId), getActivateClientAsJSON(activationDate),
                 clientId);
     }
@@ -553,7 +588,7 @@ public class ClientHelper {
 
     public static Integer addChargesForClient(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final Integer clientId, final String request) {
-        LOG.info("--------------------------------- ADD CHARGES FOR Client --------------------------------");
+        log.info("--------------------------------- ADD CHARGES FOR Client --------------------------------");
         final String ADD_CHARGES_URL = "/fineract-provider/api/v1/clients/" + clientId + "/charges?" + Utils.TENANT_IDENTIFIER;
         final HashMap<?, ?> response = Utils.performServerPost(requestSpec, responseSpec, ADD_CHARGES_URL, request, "");
         return (Integer) response.get("resourceId");
@@ -561,7 +596,7 @@ public class ClientHelper {
 
     public static String payChargesForClients(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final Integer clientId, final Integer clientChargeId, final String json) {
-        LOG.info("--------------------------------- PAY CHARGES FOR CLIENT --------------------------------");
+        log.info("--------------------------------- PAY CHARGES FOR CLIENT --------------------------------");
         final String CHARGES_URL = "/fineract-provider/api/v1/clients/" + clientId + "/charges/" + clientChargeId + "?command=paycharge&"
                 + Utils.TENANT_IDENTIFIER;
         final HashMap<?, ?> response = Utils.performServerPost(requestSpec, responseSpec, CHARGES_URL, json, "");
@@ -570,7 +605,7 @@ public class ClientHelper {
 
     public static String waiveChargesForClients(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final Integer clientId, final Integer clientChargeId, final String json) {
-        LOG.info("--------------------------------- WAIVE CHARGES FOR CLIENT --------------------------------");
+        log.info("--------------------------------- WAIVE CHARGES FOR CLIENT --------------------------------");
         final String CHARGES_URL = "/fineract-provider/api/v1/clients/" + clientId + "/charges/" + clientChargeId + "?command=waive&"
                 + Utils.TENANT_IDENTIFIER;
 
@@ -580,7 +615,7 @@ public class ClientHelper {
 
     public static Integer revertClientChargeTransaction(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String clientId, String clientChargeId) {
-        LOG.info("---------------------------------UNDO TRANSACTION---------------------------------------------");
+        log.info("---------------------------------UNDO TRANSACTION---------------------------------------------");
         final String CHARGES_URL = "/fineract-provider/api/v1/clients/" + clientId + "/transactions/" + clientChargeId + "?command=undo&"
                 + Utils.TENANT_IDENTIFIER;
 
@@ -591,7 +626,7 @@ public class ClientHelper {
 
     public static Object getClientCharge(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String clientId, final String clientChargeId) {
-        LOG.info("---------------------------------GET CLIENT CHARGE---------------------------------------------");
+        log.info("---------------------------------GET CLIENT CHARGE---------------------------------------------");
         final String CHARGES_URL = "/fineract-provider/api/v1/clients/" + clientId + "/charges/" + clientChargeId + "?"
                 + Utils.TENANT_IDENTIFIER;
         return Utils.performServerGet(requestSpec, responseSpec, CHARGES_URL, "amountOutstanding");
@@ -599,7 +634,7 @@ public class ClientHelper {
 
     public static Boolean getClientTransactions(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String clientId, final String transactionId) {
-        LOG.info("---------------------------------GET CLIENT CHARGE TRANSACTIONS---------------------------------------------");
+        log.info("---------------------------------GET CLIENT CHARGE TRANSACTIONS---------------------------------------------");
         final String CHARGES_URL = "/fineract-provider/api/v1/clients/" + clientId + "/transactions/" + transactionId + "?"
                 + Utils.TENANT_IDENTIFIER;
         return Utils.performServerGet(requestSpec, responseSpec, CHARGES_URL, "reversed");
@@ -636,4 +671,9 @@ public class ClientHelper {
         return (List) responseClients.get("pageItems");
     }
 
+    public static PostClientsRequest defaultClientCreationRequest() {
+        return new PostClientsRequest().officeId(1).legalFormId(LEGALFORM_ID_PERSON)
+                .firstname(Utils.randomNameGenerator("Client_FirstName_", 5)).lastname(Utils.randomNameGenerator("Client_LastName_", 5))
+                .externalId(randomIDGenerator("ID_", 7)).dateFormat(DATE_FORMAT).locale("en").active(true).activationDate("04 March 2011");
+    }
 }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java
index a58551a9f..1499b61aa 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.java
@@ -23,26 +23,25 @@ import io.restassured.specification.RequestSpecification;
 import io.restassured.specification.ResponseSpecification;
 import java.util.ArrayList;
 import java.util.HashMap;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.client.models.GlobalConfigurationPropertyData;
+import org.apache.fineract.client.util.JSON;
 import org.junit.jupiter.api.Assertions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({ "unused", "rawtypes" })
+@Slf4j
+@RequiredArgsConstructor
 public class GlobalConfigurationHelper {
 
-    private static final Logger LOG = LoggerFactory.getLogger(GlobalConfigurationHelper.class);
+    private static final Gson GSON = new JSON().getGson();
     private final RequestSpecification requestSpec;
     private final ResponseSpecification responseSpec;
 
-    public GlobalConfigurationHelper(final RequestSpecification requestSpec, final ResponseSpecification responseSpec) {
-        this.requestSpec = requestSpec;
-        this.responseSpec = responseSpec;
-    }
-
     public static ArrayList<HashMap> getAllGlobalConfigurations(final RequestSpecification requestSpec,
             final ResponseSpecification responseSpec) {
         final String GET_ALL_GLOBAL_CONFIG_URL = "/fineract-provider/api/v1/configurations?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("------------------------ RETRIEVING ALL GLOBAL CONFIGURATIONS -------------------------");
+        log.info("------------------------ RETRIEVING ALL GLOBAL CONFIGURATIONS -------------------------");
         final HashMap<String, ArrayList<HashMap>> response = Utils.performServerGet(requestSpec, responseSpec, GET_ALL_GLOBAL_CONFIG_URL,
                 "");
         return response.get("globalConfiguration");
@@ -51,10 +50,20 @@ public class GlobalConfigurationHelper {
     public static HashMap getGlobalConfigurationById(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String configId) {
         final String GET_GLOBAL_CONFIG_BY_ID_URL = "/fineract-provider/api/v1/configurations/" + configId + "?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("------------------------ RETRIEVING GLOBAL CONFIGURATION BY ID -------------------------");
+        log.info("------------------------ RETRIEVING GLOBAL CONFIGURATION BY ID -------------------------");
         return Utils.performServerGet(requestSpec, responseSpec, GET_GLOBAL_CONFIG_BY_ID_URL, "");
     }
 
+    public static GlobalConfigurationPropertyData getGlobalConfigurationByName(final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec, final String name) {
+        final String GET_GLOBAL_CONFIG_BY_NAME_URL = "/fineract-provider/api/v1/configurations/name/" + name + "?"
+                + Utils.TENANT_IDENTIFIER;
+        log.info("------------------------ RETRIEVING GLOBAL CONFIGURATION BY NAME -------------------------");
+        String response = Utils.performServerGet(requestSpec, responseSpec, GET_GLOBAL_CONFIG_BY_NAME_URL);
+        return GSON.fromJson(response, GlobalConfigurationPropertyData.class);
+    }
+
+    // TODO: This is quite a bad pattern and adds a lot of time to individual test executions
     public static void resetAllDefaultGlobalConfigurations(final RequestSpecification requestSpec,
             final ResponseSpecification responseSpec) {
 
@@ -437,15 +446,30 @@ public class GlobalConfigurationHelper {
     public static Integer updateValueForGlobalConfiguration(final RequestSpecification requestSpec,
             final ResponseSpecification responseSpec, final String configId, final String value) {
         final String GLOBAL_CONFIG_UPDATE_URL = "/fineract-provider/api/v1/configurations/" + configId + "?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("---------------------------------UPDATE VALUE FOR GLOBAL CONFIG---------------------------------------------");
+        log.info("---------------------------------UPDATE VALUE FOR GLOBAL CONFIG---------------------------------------------");
         return Utils.performServerPut(requestSpec, responseSpec, GLOBAL_CONFIG_UPDATE_URL, updateGlobalConfigUpdateValueAsJSON(value),
                 "resourceId");
     }
 
+    public static Integer updateValueForGlobalConfiguration(final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec, final String configId, final int value) {
+        return updateValueForGlobalConfiguration(requestSpec, responseSpec, configId, Integer.toString(value));
+    }
+
     public static Integer updateEnabledFlagForGlobalConfiguration(final RequestSpecification requestSpec,
-            final ResponseSpecification responseSpec, final String configId, final Boolean enabled) {
+            final ResponseSpecification responseSpec, final long configId, final boolean enabled) {
         final String GLOBAL_CONFIG_UPDATE_URL = "/fineract-provider/api/v1/configurations/" + configId + "?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("---------------------------------UPDATE GLOBAL CONFIG FOR ENABLED FLAG---------------------------------------------");
+        log.info("---------------------------------UPDATE GLOBAL CONFIG FOR ENABLED FLAG---------------------------------------------");
+        return Utils.performServerPut(requestSpec, responseSpec, GLOBAL_CONFIG_UPDATE_URL,
+                updateGlobalConfigUpdateEnabledFlagAsJSON(enabled), "resourceId");
+    }
+
+    // Deprecated because it's using configId as a String
+    @Deprecated
+    public static Integer updateEnabledFlagForGlobalConfiguration(final RequestSpecification requestSpec,
+            final ResponseSpecification responseSpec, final String configId, final boolean enabled) {
+        final String GLOBAL_CONFIG_UPDATE_URL = "/fineract-provider/api/v1/configurations/" + configId + "?" + Utils.TENANT_IDENTIFIER;
+        log.info("---------------------------------UPDATE GLOBAL CONFIG FOR ENABLED FLAG---------------------------------------------");
         return Utils.performServerPut(requestSpec, responseSpec, GLOBAL_CONFIG_UPDATE_URL,
                 updateGlobalConfigUpdateEnabledFlagAsJSON(enabled), "resourceId");
     }
@@ -453,7 +477,7 @@ public class GlobalConfigurationHelper {
     public static ArrayList getGlobalConfigurationIsCacheEnabled(final RequestSpecification requestSpec,
             final ResponseSpecification responseSpec) {
         final String GET_IS_CACHE_GLOBAL_CONFIG_URL = "/fineract-provider/api/v1/caches?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("------------------------ RETRIEVING IS CACHE ENABLED GLOBAL CONFIGURATION -------------------------");
+        log.info("------------------------ RETRIEVING IS CACHE ENABLED GLOBAL CONFIGURATION -------------------------");
         final ArrayList<HashMap> response = Utils.performServerGet(requestSpec, responseSpec, GET_IS_CACHE_GLOBAL_CONFIG_URL, "");
         return response;
     }
@@ -461,7 +485,7 @@ public class GlobalConfigurationHelper {
     public static HashMap updateIsCacheEnabledForGlobalConfiguration(final RequestSpecification requestSpec,
             final ResponseSpecification responseSpec, final String cacheType) {
         final String IS_CACHE_GLOBAL_CONFIG_UPDATE_URL = "/fineract-provider/api/v1/caches?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("------------------UPDATE GLOBAL CONFIG FOR IS CACHE ENABLED----------------------");
+        log.info("------------------UPDATE GLOBAL CONFIG FOR IS CACHE ENABLED----------------------");
         return Utils.performServerPut(requestSpec, responseSpec, IS_CACHE_GLOBAL_CONFIG_UPDATE_URL,
                 updateIsCacheEnabledGlobalConfigUpdateAsJSON(cacheType), "changes");
     }
@@ -470,7 +494,7 @@ public class GlobalConfigurationHelper {
             final ResponseSpecification responseSpec, final Integer configId, final String value, final String enabled,
             final String jsonAttributeToGetBack) {
         final String UPDATE_URL = "/fineract-provider/api/v1/configurations/" + configId + "?" + Utils.TENANT_IDENTIFIER;
-        LOG.info("------------------UPDATE GLOBAL CONFIG FOR FORCE PASSWORD RESET DAYS----------------------");
+        log.info("------------------UPDATE GLOBAL CONFIG FOR FORCE PASSWORD RESET DAYS----------------------");
         return Utils.performServerPut(requestSpec, responseSpec, UPDATE_URL, updatePasswordResetDaysGlobalConfigAsJSON(value, enabled),
                 jsonAttributeToGetBack);
     }
@@ -478,8 +502,8 @@ public class GlobalConfigurationHelper {
     public static String updateGlobalConfigUpdateValueAsJSON(final String value) {
         final HashMap<String, String> map = new HashMap<>();
         map.put("value", value);
-        LOG.info("map :  {}", map);
-        return new Gson().toJson(map);
+        log.info("map :  {}", map);
+        return GSON.toJson(map);
     }
 
     public static String updatePasswordResetDaysGlobalConfigAsJSON(final String value, final String enabled) {
@@ -488,21 +512,21 @@ public class GlobalConfigurationHelper {
             map.put("value", value);
         }
         map.put("enabled", enabled);
-        LOG.info("map :  {}", map);
+        log.info("map :  {}", map);
         return new Gson().toJson(map);
     }
 
     public static String updateGlobalConfigUpdateEnabledFlagAsJSON(final Boolean enabled) {
         final HashMap<String, Boolean> map = new HashMap<String, Boolean>();
         map.put("enabled", enabled);
-        LOG.info("map :  {}", map);
+        log.info("map :  {}", map);
         return new Gson().toJson(map);
     }
 
     public static String updateIsCacheEnabledGlobalConfigUpdateAsJSON(final String cacheType) {
         final HashMap<String, String> map = new HashMap<>();
         map.put("cacheType", cacheType);
-        LOG.info("map :  {}", map);
+        log.info("map :  {}", map);
         return new Gson().toJson(map);
     }
 
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java
index 6cf4542a4..4f6bef4a0 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/Utils.java
@@ -138,6 +138,11 @@ public final class Utils {
         }
     }
 
+    public static String performServerGet(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final String url) {
+        return performServerGet(requestSpec, responseSpec, url, null);
+    }
+
     public static <T> T performServerGet(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String getURL, final String jsonAttributeToGetBack) {
         final String json = given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().get(getURL).andReturn().asString();
@@ -157,6 +162,11 @@ public final class Utils {
         return given().spec(requestSpec).expect().spec(responseSpec).log().ifError().when().get(getURL).andReturn().asByteArray();
     }
 
+    public static String performServerPost(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final String postURL, final String jsonBodyToSend) {
+        return performServerPost(requestSpec, responseSpec, postURL, jsonBodyToSend, null);
+    }
+
     public static <T> T performServerPost(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final String postURL, final String jsonBodyToSend, final String jsonAttributeToGetBack) {
         final String json = given().spec(requestSpec).body(jsonBodyToSend).expect().spec(responseSpec).log().ifError().when().post(postURL)
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/system/CodeHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/system/CodeHelper.java
index d0b6db232..507b8c7d7 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/system/CodeHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/system/CodeHelper.java
@@ -31,6 +31,10 @@ import org.apache.fineract.integrationtests.common.Utils;
 
 public final class CodeHelper {
 
+    private static final String COUNTRY_CODE_NAME = "COUNTRY";
+    private static final String STATE_CODE_NAME = "STATE";
+    private static final String ADDRESS_TYPE_CODE_NAME = "ADDRESS_TYPE";
+
     private CodeHelper() {
 
     }
@@ -150,6 +154,32 @@ public final class CodeHelper {
 
     }
 
+    public static Integer createAddressTypeCodeValue(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final String addressTypeName, final Integer position) {
+        HashMap<String, Object> code = getCodeByName(requestSpec, responseSpec, ADDRESS_TYPE_CODE_NAME);
+        Integer countryCode = (Integer) code.get("id");
+        return createCodeValue(requestSpec, responseSpec, countryCode, addressTypeName, position);
+    }
+
+    public static Integer createStateCodeValue(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final String stateName, final Integer position) {
+        HashMap<String, Object> code = getCodeByName(requestSpec, responseSpec, STATE_CODE_NAME);
+        Integer countryCode = (Integer) code.get("id");
+        return createCodeValue(requestSpec, responseSpec, countryCode, stateName, position);
+    }
+
+    public static Integer createCountryCodeValue(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final String countryName, final Integer position) {
+        HashMap<String, Object> code = getCodeByName(requestSpec, responseSpec, COUNTRY_CODE_NAME);
+        Integer countryCode = (Integer) code.get("id");
+        return createCodeValue(requestSpec, responseSpec, countryCode, countryName, position);
+    }
+
+    public static Integer createCodeValue(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
+            final Integer codeId, final String codeValueName, final Integer position) {
+        return (Integer) createCodeValue(requestSpec, responseSpec, codeId, codeValueName, position, SUBRESPONSE_ID_ATTRIBUTE_NAME);
+    }
+
     public static Object createCodeValue(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
             final Integer codeId, final String codeValueName, final Integer position, final String jsonAttributeToGetback) {
         String description = null;