diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm
index 696e06622..686834944 100644
--- a/api-docs/apiLive.htm
+++ b/api-docs/apiLive.htm
@@ -292,6 +292,22 @@
|
|
+
+ | Client Address |
+ client/{clientId}/addresses |
+ Create an address for a Client |
+ List all Addresses for a Client |
+ Update an address for a Client |
+ |
+
+
+ | Entity Field Configuration |
+ fieldconfiguration/{entity} |
+ td>
+ List all configuration for a entity |
+ |
+ |
+
| Client Identifiers |
clients/{clientId}/identifiers |
@@ -1024,7 +1040,7 @@
|
|
-
+
|
accounts/share/{accountId}?command=activate |
@@ -1057,7 +1073,7 @@
|
|
-
+
|
accounts/share/{accountId}?command=rejectadditionalshares |
@@ -1066,7 +1082,7 @@
|
|
-
+
|
accounts/share/{accountId}?command=redeemshares |
@@ -1075,12 +1091,12 @@
|
|
-
+
-
+
POST https://Domain Name/api/v1/accounts/share/{shareAccountId}?command=close
@@ -22629,7 +23216,7 @@ Request Body:
{
-
+
"resourceId":5,
"changes":{
"status":{
@@ -22648,7 +23235,7 @@ Request Body:
"note":"close note"
}
}
-
+
@@ -22659,7 +23246,7 @@ Request Body:
Apply additional shares on a share account
requestedDate is requsted date of share purchase
requestedShares is number of shares to be purchase
-
+
Mandatory Fields |
@@ -22669,7 +23256,7 @@ Request Body:
-
+
POST https://Domain Name/api/v1/accounts/share/{shareAccountId}?command=applyadditionalshares
@@ -22685,10 +23272,10 @@ Request Body:
{
-
+
"resourceId":5,
}
-
+
@@ -22698,7 +23285,7 @@ Request Body:
Approve additional shares request on a share account
requestedShares is Share purchase transaction ids
-
+
Mandatory Fields |
@@ -22708,7 +23295,7 @@ Request Body:
-
+
POST https://Domain Name/api/v1/accounts/share/{shareAccountId}?command=approveadditionalshares
@@ -22723,10 +23310,10 @@ Request Body:
{
-
+
"resourceId":5,
}
-
+
@@ -22736,7 +23323,7 @@ Request Body:
Reject additional shares request on a share account
requestedShares is Share purchase transaction ids
-
+
Mandatory Fields |
@@ -22746,7 +23333,7 @@ Request Body:
-
+
POST https://Domain Name/api/v1/accounts/share/{shareAccountId}?command=rejectadditionalshares
@@ -22759,10 +23346,10 @@ Request Body:
{
-
+
"resourceId":5,
}
-
+
@@ -22774,7 +23361,7 @@ Request Body:
Results redeem some/all shares from share account.
requestedDate is requsted date of shares redeem
requestedShares is number of shares to be redeemed
-
+
Mandatory Fields |
@@ -22784,7 +23371,7 @@ Request Body:
-
+
POST https://Domain Name/api/v1/accounts/share/{shareAccountId}?command=redeemshares
@@ -22800,10 +23387,10 @@ Request Body:
{
-
+
"resourceId":5,
}
-
+
@@ -22814,7 +23401,7 @@ Request Body:
List share applications/accounts
Example Requests:
shareaccount
-
+
GET https://Domain Name/api/v1/accounts/share
@@ -22829,7 +23416,7 @@ Request Body:
"clientName": "Client Name",
"productId": 1,
"productName": "Share Product Name",
-
+
"status": {
"id": 100,
"code": "shareAccountStatusType.submitted.and.pending.approval",
@@ -22862,7 +23449,7 @@ Request Body:
"purchasedPrice": 5
}
],
-
+
"summary": {
"currency": {
"code": "USD",
@@ -22884,7 +23471,7 @@ Request Body:
Retrieve a share application/account:
-
+
Example Requests :
shareaccount/1
@@ -23271,7 +23858,7 @@ No Request Body:
{
-
+
"resourceId": 1,
"changes": {
"dateFormat": "dd MMMM yyyy",
@@ -23283,7 +23870,7 @@ No Request Body:
-
+
@@ -23388,7 +23975,7 @@ No Request Body:
| overdraftLimit |
| Optional: If provided, sets the maximum allowed overdraft amount for a savings account e.g. 5,000 else set the limit as zero |
-
+
| withHoldTax |
| Optional: If tax group provided at product level, will allow to Enable or disable withhold tax on interest posting for savings account |
@@ -24476,8 +25063,8 @@ No Request Body:
-
-
+
+
@@ -27062,7 +27649,7 @@ No Request Body:
| withHoldTax |
| Optional: If tax group provided at product level, will allow to Enable or disable withhold tax on interest posting for savings account |
-
+
@@ -39552,7 +40139,7 @@ No Request Body:
-
+
@@ -39716,7 +40303,7 @@ No Request Body:
4,
11],
"taxComponentHistories": [{
-
+
}]
},
{
@@ -39737,9 +40324,9 @@ No Request Body:
4,
11],
"taxComponentHistories": [{
-
+
}]
- }]
+ }]
@@ -39777,7 +40364,7 @@ No Request Body:
4,
11],
"taxComponentHistories": [{
-
+
}]
}
@@ -39940,7 +40527,7 @@ No Request Body:
"startDate": "11 April 2016"
}],
"dateFormat": "dd MMMM yyyy"
- }
+ }
{
@@ -39992,7 +40579,7 @@ No Request Body:
4,
11]
}]
- }]
+ }]
@@ -43002,8 +43589,8 @@ Request Body:
-
-
+
+
@@ -44201,7 +44788,7 @@ No Request Body:
-
+
POST https://DomainName/api/v1/self/beneficiaries/tpt
@@ -44216,7 +44803,7 @@ Request Body:
"accountNumber": "0000001",
"accountType": 1,
"transferLimit": 1000
-
+
}
@@ -44235,7 +44822,7 @@ Request Body:
Example Requests:
/self/beneficiaries/tpt
-
+
GET https://DomainName/api/v1/self/beneficiaries/tpt
@@ -44295,7 +44882,7 @@ Content-Type: application/json
-
+
PUT https://DomainName/api/v1/self/beneficiaries/tpt/{beneficiaryId}
@@ -44306,7 +44893,7 @@ Request Body:
{
"name": "beneficiary nick name",
"transferLimit": 1000
-
+
}
@@ -44329,7 +44916,7 @@ Request Body:
Example Requests:
/self/beneficiaries/tpt/{beneficiaryId}
-
+
DELETE https://DomainName/api/v1/self/beneficiaries/tpt/{beneficiaryId}
@@ -44593,6 +45180,7 @@ No Request Body:
|
|
+
| Client Identifiers |
clients/{clientId}/identifiers |
@@ -46298,7 +46886,7 @@ No Request Body:
|
|
-
+
|
shareproducts/template |
diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
index 3b26e1df1..dea6a9e42 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java
@@ -41,12 +41,31 @@ public class CommandWrapperBuilder {
private String transactionId;
private Long productId;
private Long templateId;
+
public CommandWrapper build() {
return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, this.actionName,
- this.entityName, this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId, this.templateId);
+ this.entityName, this.entityId, this.subentityId, this.href, this.json, this.transactionId, this.productId,
+ this.templateId);
}
-
+
+ public CommandWrapperBuilder addClientAddress(final long clientId,final long addressTypeId) {
+ this.actionName = "CREATE";
+ this.entityName = "ADDRESS";
+ this.entityId = addressTypeId;
+ this.href = "/clients/"+clientId+"/addresses";
+ this.clientId=clientId;
+ return this;
+ }
+
+ public CommandWrapperBuilder updateClientAddress(final long clientId) {
+ this.actionName = "UPDATE";
+ this.entityName = "ADDRESS";
+ this.href = "/clients/"+clientId+"/addresses";
+ this.clientId=clientId;
+ return this;
+ }
+
public CommandWrapperBuilder withLoanId(final Long withLoanId) {
this.loanId = withLoanId;
return this;
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java
index 7b3a0ab72..40aede7d2 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/data/GlobalConfigurationPropertyData.java
@@ -60,4 +60,34 @@ public class GlobalConfigurationPropertyData {
this.description = description;
this.trapDoor = isTrapDoor;
}
+
+ public String getName() {
+ return this.name;
+ }
+
+ public boolean isEnabled() {
+ return this.enabled;
+ }
+
+ public Long getValue() {
+ return this.value;
+ }
+
+ public Date getDateValue() {
+ return this.dateValue;
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ public boolean isTrapDoor() {
+ return this.trapDoor;
+ }
+
+
}
\ No newline at end of file
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformService.java
index 27a734920..2c9c9c11a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformService.java
@@ -24,6 +24,8 @@ import org.apache.fineract.infrastructure.configuration.data.GlobalConfiguration
public interface ConfigurationReadPlatformService {
GlobalConfigurationPropertyData retrieveGlobalConfiguration(Long configId);
+
+ GlobalConfigurationPropertyData retrieveGlobalConfiguration(String name);
GlobalConfigurationData retrieveGlobalConfiguration(boolean survey);
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java
index 80c704739..ab7f30f23 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/ConfigurationReadPlatformServiceImpl.java
@@ -66,6 +66,21 @@ public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPl
return new GlobalConfigurationData(globalConfiguration);
}
+
+
+
+ @Override
+ public GlobalConfigurationPropertyData retrieveGlobalConfiguration(String name) {
+
+ this.context.authenticatedUser();
+
+ final String sql = "SELECT c.id, c.name, c.enabled, c.value, c.date_value, c.description, c.is_trap_door FROM "
+ + "c_configuration c where c.name=? order by c.id";
+ final GlobalConfigurationPropertyData globalConfiguration = this.jdbcTemplate.queryForObject(sql, this.rm,
+ new Object[] { name });
+
+ return globalConfiguration;
+ }
@Override
public GlobalConfigurationPropertyData retrieveGlobalConfiguration(Long configId) {
@@ -80,6 +95,7 @@ public class ConfigurationReadPlatformServiceImpl implements ConfigurationReadPl
return globalConfiguration;
}
+
private static final class GlobalConfigurationRowMapper implements RowMapper {
@Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/api/EntityFieldConfigurationApiResources.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/api/EntityFieldConfigurationApiResources.java
new file mode 100644
index 000000000..838e419fe
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/api/EntityFieldConfigurationApiResources.java
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.api;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.fineract.commands.domain.CommandWrapper;
+import org.apache.fineract.commands.service.CommandWrapperBuilder;
+import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
+import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
+import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
+import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
+import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.apache.fineract.portfolio.address.data.AddressData;
+import org.apache.fineract.portfolio.address.data.FieldConfigurationData;
+import org.apache.fineract.portfolio.address.service.AddressReadPlatformServiceImpl;
+import org.apache.fineract.portfolio.address.service.FieldConfigurationReadPlatformService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+@Path("/fieldconfiguration/{entity}")
+@Component
+@Scope("singleton")
+public class EntityFieldConfigurationApiResources {
+
+ private final Set RESPONSE_DATA_PARAMETERS = new HashSet<>(Arrays.asList("clientAddressId", "client_id",
+ "address_id", "address_type_id", "isActive", "fieldConfigurationId", "entity", "table", "field",
+ "is_enabled", "is_mandatory", "validation_regex"));
+ private final String resourceNameForPermissions = "Address";
+ private final PlatformSecurityContext context;
+ private final DefaultToApiJsonSerializer toApiJsonSerializer;
+ private final FieldConfigurationReadPlatformService readPlatformServicefld;
+ private final DefaultToApiJsonSerializer toApiJsonSerializerfld;
+ private final ApiRequestParameterHelper apiRequestParameterHelper;
+ private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
+
+ @Autowired
+ public EntityFieldConfigurationApiResources(final PlatformSecurityContext context,
+ final DefaultToApiJsonSerializer toApiJsonSerializer,
+ final FieldConfigurationReadPlatformService readPlatformServicefld,
+ final DefaultToApiJsonSerializer toApiJsonSerializerfld,
+ final ApiRequestParameterHelper apiRequestParameterHelper,
+ final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
+ this.context = context;
+ this.toApiJsonSerializer = toApiJsonSerializer;
+ this.readPlatformServicefld = readPlatformServicefld;
+ this.toApiJsonSerializerfld = toApiJsonSerializerfld;
+ this.apiRequestParameterHelper = apiRequestParameterHelper;
+ this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
+ }
+
+ @GET
+ @Consumes({ MediaType.APPLICATION_JSON })
+ @Produces({ MediaType.APPLICATION_JSON })
+ public String getAddresses(@PathParam("entity") final String entityname, @Context final UriInfo uriInfo) {
+ this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions);
+
+ final Collection fldconfig = this.readPlatformServicefld
+ .retrieveFieldConfiguration(entityname);
+
+ final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper
+ .process(uriInfo.getQueryParameters());
+ return this.toApiJsonSerializerfld.serialize(settings, fldconfig, this.RESPONSE_DATA_PARAMETERS);
+
+ }
+
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/AddressData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/AddressData.java
new file mode 100644
index 000000000..8601b46a9
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/AddressData.java
@@ -0,0 +1,188 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.data;
+
+import java.math.BigDecimal;
+import java.util.Collection;
+import java.util.Date;
+
+import org.apache.fineract.infrastructure.codes.data.CodeValueData;
+
+public class AddressData {
+ private final Long client_id;
+
+ private final String addressType;
+
+ private final Long addressId;
+
+ private final Long addressTypeId;
+
+ private final Boolean isActive;
+
+ private final String street;
+
+ private final String addressLine1;
+
+ private final String addressLine2;
+
+ private final String addressLine3;
+
+ private final String townVillage;
+
+ private final String city;
+
+ private final String countyDistrict;
+
+ private final Long stateProvinceId;
+
+ private final String countryName;
+
+ private final String stateName;
+
+ private final Long countryId;
+
+ private final String postalCode;
+
+ private final BigDecimal latitude;
+
+ private final BigDecimal longitude;
+
+ private final String createdBy;
+
+ private final Date createdOn;
+
+ private final String updatedBy;
+
+ private final Date updatedOn;
+
+ // template holder
+ private final Collection countryIdOptions;
+ private final Collection stateProvinceIdOptions;
+ private final Collection addressTypeIdOptions;
+
+ private AddressData(final String addressType, final Long client_id, final Long addressId, final Long addressTypeId,
+ final Boolean is_active, final String street, final String addressLine1, final String addressLine2,
+ final String addressLine3, final String townVillage, final String city, final String countyDistrict,
+ final Long stateProvinceId, final Long countryId, final String stateName, final String countryName,
+ final String postalCode, final BigDecimal latitude, final BigDecimal longitude, final String createdBy,
+ final Date createdOn, final String updatedBy, final Date updatedOn,
+ final Collection countryIdOptions, final Collection stateProvinceIdOptions,
+ final Collection addressTypeIdOptions) {
+ this.addressType = addressType;
+ this.client_id = client_id;
+ this.addressId = addressId;
+ this.addressTypeId = addressTypeId;
+ this.isActive = is_active;
+ this.street = street;
+ this.addressLine1 = addressLine1;
+ this.addressLine2 = addressLine2;
+ this.addressLine3 = addressLine3;
+ this.townVillage = townVillage;
+ this.city = city;
+ this.countyDistrict = countyDistrict;
+ this.stateProvinceId = stateProvinceId;
+ this.countryId = countryId;
+ this.stateName = stateName;
+ this.countryName = countryName;
+ this.postalCode = postalCode;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.createdBy = createdBy;
+ this.createdOn = createdOn;
+ this.updatedBy = updatedBy;
+ this.updatedOn = updatedOn;
+ this.countryIdOptions = countryIdOptions;
+ this.stateProvinceIdOptions = stateProvinceIdOptions;
+ this.addressTypeIdOptions = addressTypeIdOptions;
+ }
+
+ public static AddressData instance(final String addressType, final Long client_id, final Long addressId,
+ final Long addressTypeId, final Boolean is_active, final String street, final String addressLine1,
+ final String addressLine2, final String addressLine3, final String townVillage, final String city,
+ final String countyDistrict, final Long stateProvinceId, final Long countryId, final String stateName,
+ final String countryName, final String postalCode, final BigDecimal latitude, final BigDecimal longitude,
+ final String createdBy, final Date createdOn, final String updatedBy, final Date updatedOn) {
+
+ return new AddressData(addressType, client_id, addressId, addressTypeId, is_active, street, addressLine1,
+ addressLine2, addressLine3, townVillage, city, countyDistrict, stateProvinceId, countryId,
+ stateName, countryName, postalCode, latitude, longitude, createdBy, createdOn, updatedBy,
+ updatedOn, null, null, null);
+ }
+
+ public static AddressData instance1(final Long addressId, final String street, final String addressLine1,
+ final String addressLine2, final String addressLine3, final String townVillage, final String city,
+ final String countyDistrict, final Long stateProvinceId, final Long countryId, final String postalCode,
+ final BigDecimal latitude, final BigDecimal longitude, final String createdBy, final Date createdOn,
+ final String updatedBy, final Date updatedOn) {
+ return new AddressData(null, null, addressId, null, false, street, addressLine1, addressLine2,
+ addressLine3, townVillage, city, countyDistrict, stateProvinceId, countryId, null, null,
+ postalCode, latitude, longitude, createdBy, createdOn, updatedBy, updatedOn, null, null, null);
+ }
+
+ public static AddressData template(final Collection countryIdOptions,
+ final Collection stateProvinceIdOptions,
+ final Collection addressTypeIdOptions) {
+ final Long client_idtemp = null;
+
+ final Long addressIdtemp = null;
+
+ final Long addressTypeIdtemp = null;
+
+ final Boolean is_activetemp = null;
+
+ final String streettemp = null;
+
+ final String addressLine1temp = null;
+
+ final String addressLine2temp = null;
+
+ final String addressLine3temp = null;
+
+ final String townVillagetemp = null;
+
+ final String citytemp = null;
+
+ final String countyDistricttemp = null;
+
+ final Long stateProvinceIdtemp = null;
+
+ final Long countryIdtemp = null;
+
+ final String postalCodetemp = null;
+
+ final BigDecimal latitudetemp = null;
+
+ final BigDecimal longitudetemp = null;
+
+ final String createdBytemp = null;
+
+ final Date createdOntemp = null;
+
+ final String updatedBytemp = null;
+
+ final Date updatedOntemp = null;
+
+ return new AddressData(null, client_idtemp, addressIdtemp, addressTypeIdtemp, is_activetemp, streettemp,
+ addressLine1temp, addressLine2temp, addressLine3temp, townVillagetemp, citytemp,
+ countyDistricttemp, stateProvinceIdtemp, countryIdtemp, null, null, postalCodetemp, latitudetemp,
+ longitudetemp, createdBytemp, createdOntemp, updatedBytemp, updatedOntemp, countryIdOptions,
+ stateProvinceIdOptions, addressTypeIdOptions);
+ }
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/ClientAddressData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/ClientAddressData.java
new file mode 100644
index 000000000..dc55e0538
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/ClientAddressData.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.data;
+
+public class ClientAddressData {
+
+ private final long clientAddressId;
+
+ private final long client_id;
+
+ private final long address_id;
+
+ private final long address_type_id;
+
+ private final boolean isActive;
+
+ private ClientAddressData(final long clientAddressId, final long client_id, final long address_id,
+ final long address_type_id, final boolean isActive) {
+ this.clientAddressId = clientAddressId;
+ this.client_id = client_id;
+ this.address_id = address_id;
+ this.address_type_id = address_type_id;
+ this.isActive = isActive;
+ }
+
+ public static ClientAddressData instance(final long clientAddressId, final long client_id, final long address_id,
+ final long address_type_id, final boolean isActive) {
+ return new ClientAddressData(clientAddressId, client_id, address_id, address_type_id, isActive);
+ }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/FieldConfigurationData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/FieldConfigurationData.java
new file mode 100644
index 000000000..ae0495d0a
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/data/FieldConfigurationData.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.data;
+
+public class FieldConfigurationData {
+ private final long fieldConfigurationId;
+
+ private final String entity;
+
+ private final String subentity;
+
+ private final String field;
+
+ private final boolean is_enabled;
+
+ private final boolean is_mandatory;
+
+ private final String validation_regex;
+
+ private FieldConfigurationData(final long fieldConfigurationId, final String entity, final String subentity,
+ final String field, final boolean is_enabled, final boolean is_mandatory, final String validation_regex) {
+ this.fieldConfigurationId = fieldConfigurationId;
+ this.entity = entity;
+ this.subentity = subentity;
+ this.field = field;
+ this.is_enabled = is_enabled;
+ this.is_mandatory = is_mandatory;
+ this.validation_regex = validation_regex;
+ }
+
+ public static FieldConfigurationData instance(final long fieldConfigurationId, final String entity,
+ final String subentity, final String field, final boolean is_enabled, final boolean is_mandatory,
+ final String validation_regex) {
+ return new FieldConfigurationData(fieldConfigurationId, entity, subentity, field, is_enabled, is_mandatory,
+ validation_regex);
+ }
+
+ public long getFieldConfigurationId() {
+ return this.fieldConfigurationId;
+ }
+
+ public String getEntity() {
+ return this.entity;
+ }
+
+ public String getSubEntity() {
+ return this.subentity;
+ }
+
+ public String getField() {
+ return this.field;
+ }
+
+ public boolean isIs_enabled() {
+ return this.is_enabled;
+ }
+
+ public boolean isIs_mandatory() {
+ return this.is_mandatory;
+ }
+
+ public String getValidation_regex() {
+ return this.validation_regex;
+ }
+
+}
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
new file mode 100644
index 000000000..6143a5b81
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java
@@ -0,0 +1,393 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+import org.apache.fineract.infrastructure.codes.domain.CodeValue;
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.apache.fineract.portfolio.client.domain.ClientAddress;
+import org.joda.time.LocalDate;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.springframework.data.jpa.domain.AbstractPersistable;
+
+import com.google.gson.JsonObject;
+
+@Entity
+@Table(name = "m_address")
+public class Address extends AbstractPersistable {
+
+ /*
+ * @OneToMany(mappedBy = "address", cascade = CascadeType.ALL) private
+ * List clientaddress = new ArrayList<>();
+ */
+
+ @OneToMany(mappedBy = "address", cascade = CascadeType.ALL)
+ private Set clientaddress;
+
+ @Column(name = "street")
+ private String street;
+
+ @Column(name = "address_line_1")
+ private String addressLine1;
+
+ @Column(name = "address_line_2")
+ private String addressLine2;
+
+ @Column(name = "address_line_3")
+ private String addressLine3;
+
+ @Column(name = "town_village")
+ private String townVillage;
+
+ @Column(name = "city")
+ private String city;
+
+ @Column(name = "county_district")
+ private String countyDistrict;
+
+ @ManyToOne
+ @JoinColumn(name = "state_province_id")
+ private CodeValue stateProvince;
+
+ @ManyToOne
+ @JoinColumn(name = "country_id")
+ private CodeValue country;
+
+ @Column(name = "postal_code")
+ private String postalCode;
+
+ @Column(name = "latitude")
+ private BigDecimal latitude;
+
+ @Column(name = "longitude")
+ private BigDecimal longitude;
+
+ @Column(name = "created_by")
+ private String createdBy;
+
+ @Column(name = "created_on")
+ private Date createdOn;
+
+ @Column(name = "updated_by")
+ private String updatedBy;
+
+ @Column(name = "updated_on")
+ private Date updatedOn;
+
+ private Address(final String street, final String addressLine1, final String addressLine2,
+ final String addressLine3, final String townVillage, final String city, final String countyDistrict,
+ final CodeValue stateProvince, final CodeValue country, final String postalCode, final BigDecimal latitude,
+ final BigDecimal longitude, final String createdBy, final LocalDate createdOn, final String updatedBy,
+ final LocalDate updatedOn) {
+ this.street = street;
+ this.addressLine1 = addressLine1;
+ this.addressLine2 = addressLine2;
+ this.addressLine3 = addressLine3;
+ this.townVillage = townVillage;
+ this.city = city;
+ this.countyDistrict = countyDistrict;
+ this.stateProvince = stateProvince;
+ this.country = country;
+ this.postalCode = postalCode;
+ this.latitude = latitude;
+ this.longitude = longitude;
+ this.createdBy = createdBy;
+ //this.createdOn = createdOn;
+ this.updatedBy = updatedBy;
+ //this.updatedOn = updatedOn;
+
+ if (createdOn != null) {
+ this.createdOn = createdOn.toDate();
+
+ }
+
+ if (updatedOn != null) {
+ this.updatedOn = updatedOn.toDate();
+ }
+
+ }
+
+ public Address() {
+
+ }
+
+ public static Address fromJson(final JsonCommand command, final CodeValue stateProvince, final CodeValue country) {
+
+ final String street = command.stringValueOfParameterNamed("street");
+
+ final String addressLine1 = command.stringValueOfParameterNamed("addressLine1");
+
+ final String addressLine2 = command.stringValueOfParameterNamed("addressLine2");
+
+ final String addressLine3 = command.stringValueOfParameterNamed("addressLine3");
+
+ final String townVillage = command.stringValueOfParameterNamed("townVillage");
+
+ final String city = command.stringValueOfParameterNamed("city");
+
+ final String countyDistrict = command.stringValueOfParameterNamed("countyDistrict");
+
+ final String postalCode = command.stringValueOfParameterNamed("postalCode");
+
+ final BigDecimal latitude = command.bigDecimalValueOfParameterNamed("latitude");
+
+ final BigDecimal longitude = command.bigDecimalValueOfParameterNamed("longitude");
+
+ final String createdBy = command.stringValueOfParameterNamed("createdBy");
+
+ final LocalDate createdOn = command.localDateValueOfParameterNamed("createdOn");
+
+ final String updatedBy = command.stringValueOfParameterNamed("updatedBy");
+
+ final LocalDate updatedOn = command.localDateValueOfParameterNamed("updatedOn");
+
+
+
+ return new Address(street, addressLine1, addressLine2, addressLine3, townVillage, city, countyDistrict,
+ stateProvince, country, postalCode, latitude, longitude, createdBy, createdOn, updatedBy, updatedOn);
+ }
+
+ public static Address fromJsonObject(final JsonObject jsonObject, final CodeValue state_province,
+ final CodeValue country) {
+ String street = "";
+ String addressLine1 = "";
+ String addressLine2 = "";
+ String addressLine3 = "";
+ String townVillage = "";
+ String city = "";
+ String countyDistrict = "";
+ String postalCode = "";
+ 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")) {
+ addressLine1 = jsonObject.get("addressLine1").getAsString();
+ }
+ if (jsonObject.has("addressLine2")) {
+
+ addressLine2 = jsonObject.get("addressLine2").getAsString();
+ }
+ if (jsonObject.has("addressLine3")) {
+ addressLine3 = jsonObject.get("addressLine3").getAsString();
+ }
+ if (jsonObject.has("townVillage")) {
+ townVillage = jsonObject.get("townVillage").getAsString();
+ }
+ if (jsonObject.has("city")) {
+ city = jsonObject.get("city").getAsString();
+ }
+ if (jsonObject.has("countyDistrict")) {
+ countyDistrict = jsonObject.get("countyDistrict").getAsString();
+ }
+ if (jsonObject.has("postalCode")) {
+
+ postalCode = jsonObject.get("postalCode").getAsString();
+ }
+ if (jsonObject.has("latitude")) {
+
+ latitude = jsonObject.get("latitude").getAsBigDecimal();
+ }
+ if (jsonObject.has("longitude")) {
+
+ longitude = jsonObject.get("longitude").getAsBigDecimal();
+ }
+
+ if (jsonObject.has("createdBy")) {
+ createdBy = jsonObject.get("createdBy").getAsString();
+ }
+ if (jsonObject.has("createdOn")) {
+ String createdOn = jsonObject.get("createdOn").getAsString();
+ DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
+ createdOnDate = LocalDate.parse(createdOn, formatter);
+
+ }
+ if (jsonObject.has("updatedBy")) {
+ updatedBy = jsonObject.get("updatedBy").getAsString();
+ }
+ if (jsonObject.has("updatedOn")) {
+ String updatedOn = jsonObject.get("updatedOn").getAsString();
+ DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
+ updatedOnDate = LocalDate.parse(updatedOn, formatter);
+ }
+
+ return new Address(street, addressLine1, addressLine2, addressLine3, townVillage, city, countyDistrict,
+ state_province, country, postalCode, latitude, longitude, createdBy, createdOnDate, updatedBy,
+ updatedOnDate);
+ }
+
+ public Set getClientaddress() {
+ return this.clientaddress;
+ }
+
+ public void setClientaddress(Set clientaddress) {
+ this.clientaddress = clientaddress;
+ }
+
+ public String getStreet() {
+ return this.street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getAddressLine1() {
+ return this.addressLine1;
+ }
+
+ public void setAddressLine1(String addressLine1) {
+ this.addressLine1 = addressLine1;
+ }
+
+ public String getAddressLine2() {
+ return this.addressLine2;
+ }
+
+ public void setAddressLine2(String addressLine2) {
+ this.addressLine2 = addressLine2;
+ }
+
+ public String getAddressLine3() {
+ return this.addressLine3;
+ }
+
+ public void setAddressLine3(String addressLine3) {
+ this.addressLine3 = addressLine3;
+ }
+
+ public String getTownVillage() {
+ return this.townVillage;
+ }
+
+ public void setTownVillage(String townVillage) {
+ this.townVillage = townVillage;
+ }
+
+ public String getCity() {
+ return this.city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCountyDistrict() {
+ return this.countyDistrict;
+ }
+
+ public void setCountyDistrict(String countyDistrict) {
+ this.countyDistrict = countyDistrict;
+ }
+
+ public CodeValue getStateProvince() {
+ return this.stateProvince;
+ }
+
+ public void setStateProvince(CodeValue stateProvince) {
+ this.stateProvince = stateProvince;
+ }
+
+ public CodeValue getCountry() {
+ return this.country;
+ }
+
+ public void setCountry(CodeValue country) {
+ this.country = country;
+ }
+
+ public String getPostalCode() {
+ return this.postalCode;
+ }
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public BigDecimal getLatitude() {
+ return this.latitude;
+ }
+
+ public void setLatitude(BigDecimal latitude) {
+ this.latitude = latitude;
+ }
+
+ public BigDecimal getLongitude() {
+ return this.longitude;
+ }
+
+ public void setLongitude(BigDecimal longitude) {
+ this.longitude = longitude;
+ }
+
+ public String getCreatedBy() {
+ return this.createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public Date getCreatedOn() {
+ return this.createdOn;
+ }
+
+ public void setCreatedOn(LocalDate createdOn) {
+ this.createdOn = createdOn.toDate();
+ }
+
+ public String getUpdatedBy() {
+ return this.updatedBy;
+ }
+
+ public void setUpdatedBy(String updatedBy) {
+ this.updatedBy = updatedBy;
+ }
+
+ public Date getUpdatedOn() {
+ return this.updatedOn;
+ }
+
+ public void setUpdatedOn(LocalDate updatedOn) {
+ this.updatedOn = updatedOn.toDate();;
+ }
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/AddressRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/AddressRepository.java
new file mode 100644
index 000000000..40870020f
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/AddressRepository.java
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.domain;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+public interface AddressRepository extends JpaRepository, JpaSpecificationExecutor {
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfiguration.java
new file mode 100644
index 000000000..8afcb93c4
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfiguration.java
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.domain;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import org.springframework.data.jpa.domain.AbstractPersistable;
+
+@Entity
+@Table(name = "m_field_configuration")
+public class FieldConfiguration extends AbstractPersistable {
+
+ private String entity;
+
+ private String table;
+
+ private String field;
+
+ private boolean is_enabled;
+
+ public FieldConfiguration() {
+
+ }
+
+ private FieldConfiguration(final String entity, final String table, final String field, final boolean is_enabled) {
+ this.entity = entity;
+ this.table = table;
+ this.field = field;
+ this.is_enabled = is_enabled;
+
+ }
+
+ private static FieldConfiguration fromJson(final JsonCommand command) {
+ final String entity = command.stringValueOfParameterNamed("entity");
+ final String table = command.stringValueOfParameterNamed("table");
+ final String field = command.stringValueOfParameterNamed("field");
+ final boolean is_enabled = command.booleanPrimitiveValueOfParameterNamed("implementationKey");
+
+ return new FieldConfiguration(entity, table, field, is_enabled);
+ }
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfigurationRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfigurationRepository.java
new file mode 100644
index 000000000..070373c74
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfigurationRepository.java
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.domain;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+
+public interface FieldConfigurationRepository
+ extends JpaRepository, JpaSpecificationExecutor {
+
+}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/exception/AddressNotFoundException.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/exception/AddressNotFoundException.java
new file mode 100644
index 000000000..99351925a
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/exception/AddressNotFoundException.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.exception;
+
+import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
+
+public class AddressNotFoundException extends AbstractPlatformResourceNotFoundException {
+
+ public AddressNotFoundException(final long clientId) {
+ super("error.msg.address.client.Identifier.not.found",
+ "Client with client ID `" + clientId + "` is not mapped with any address", clientId);
+ }
+
+ public AddressNotFoundException(final long clientId, final long addressTypeId) {
+ super("error.msg.address.client.addresstype.not.found",
+ "Client with client ID`" + clientId + "` does not have address" + " type with id", addressTypeId);
+ }
+}
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
new file mode 100644
index 000000000..dd054e1ec
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/serialization/AddressCommandFromApiJsonDeserializer.java
@@ -0,0 +1,272 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.portfolio.address.serialization;
+
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
+import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+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;
+
+import com.google.gson.JsonElement;
+import com.google.gson.reflect.TypeToken;
+
+@Component
+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);
+ }
+
+ public void validateForCreate(final String json, final boolean fromNewClient) {
+ validate(json, fromNewClient);
+ }
+
+ public void validate(final String json, final boolean fromNewClient) {
+ if (StringUtils.isBlank(json)) {
+ throw new InvalidJsonException();
+ }
+
+ final Type typeOfMap = new TypeToken