From f40a598addfea345f6c7687b64c5936a559946ca Mon Sep 17 00:00:00 2001 From: madhukar Date: Thu, 9 Aug 2012 20:51:35 +0530 Subject: [PATCH] Deposit Product Creation, Retrieving --- .../api/DepositProductsApiResource.java | 139 ++++++++++++++ .../api/commands/DepositProductCommand.java | 170 ++++++++++++++++++ .../platform/api/data/DepositProductData.java | 124 +++++++++++++ .../api/data/DepositProductLookup.java | 37 ++++ .../ApiDataConversionService.java | 8 +- .../ApiDataConversionServiceImpl.java | 85 +++++++++ .../deposit/domain/DepositProduct.java | 118 ++++++++++++ .../domain/DepositProductRelatedDetail.java | 168 +++++++++++++++++ .../domain/DepositProductRepository.java | 10 ++ .../DepositProductCommandValidator.java | 89 +++++++++ .../DepositProductReadPlatformService.java | 18 ++ ...DepositProductReadPlatformServiceImpl.java | 123 +++++++++++++ .../DepositProductWritePlatformService.java | 18 ++ ...WritePlatformServiceJpaRepositoryImpl.java | 78 ++++++++ .../DepositProductNotFoundException.java | 13 ++ .../src/test/resources/META-INF/context.xml | 2 +- 16 files changed, 1198 insertions(+), 2 deletions(-) create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositProductCommand.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductLookup.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProduct.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRelatedDetail.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRepository.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductCommandValidator.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformServiceImpl.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java create mode 100644 mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductNotFoundException.java diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java new file mode 100644 index 000000000..656f4124f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java @@ -0,0 +1,139 @@ +package org.mifosng.platform.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.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +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.Response; +import javax.ws.rs.core.UriInfo; + +import org.mifosng.platform.api.commands.DepositProductCommand; +import org.mifosng.platform.api.data.DepositProductData; +import org.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.api.infrastructure.ApiDataConversionService; +import org.mifosng.platform.api.infrastructure.ApiParameterHelper; +import org.mifosng.platform.depositproduct.service.DepositProductReadPlatformService; +import org.mifosng.platform.depositproduct.service.DepositProductWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/depositproducts") +@Component +@Scope("singleton") +public class DepositProductsApiResource { + + @Autowired + private DepositProductReadPlatformService depositProductReadPlatformService; + + @Autowired + private DepositProductWritePlatformService depositProductWritePlatformService; + + @Autowired + private ApiDataConversionService apiDataConversionService; + + @POST + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + public Response createDepositProduct(final String jsonRequestBody){ + + final DepositProductCommand command=this.apiDataConversionService.convertJsonToDepositProductCommand(null, jsonRequestBody); + + EntityIdentifier entityIdentifier=this.depositProductWritePlatformService.createDepositProduct(command); + + return Response.ok().entity(entityIdentifier).build(); + + } + + @PUT + @Path("{productId}") + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + public Response updateDepositProduct(@PathParam("productId") final Long productId, final String jsonRequestBody){ + + final DepositProductCommand command=this.apiDataConversionService.convertJsonToDepositProductCommand(productId, jsonRequestBody); + EntityIdentifier entityIdentifier=this.depositProductWritePlatformService.updateDepositProduct(command); + return Response.ok().entity(entityIdentifier).build(); + } + + @DELETE + @Path("{productId}") + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + public Response deleteDepositProduct(@PathParam("productId") final Long productId) { + + this.depositProductWritePlatformService.deleteDepositProduct(productId); + + return Response.ok(new EntityIdentifier(productId)).build(); + } + + @GET + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + public String retrieveAllDepositProducts(@Context final UriInfo uriInfo){ + Set typicalResponseParameters = new HashSet(Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn", + "currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance")); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + Collection products=this.depositProductReadPlatformService.retrieveAllDepositProducts(); + return this.apiDataConversionService.convertDepositProductDataToJson(prettyPrint, responseParameters, products.toArray(new DepositProductData[products.size()])); + } + + @GET + @Path("{productId}") + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + public String retrieveDepositProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo){ + Set typicalResponseParameters = new HashSet(Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn", + "currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance")); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); + if (template) { + responseParameters.addAll(Arrays.asList("currencyOptions")); + } + DepositProductData productData = this.depositProductReadPlatformService.retrieveDepositProductData(productId); + return this.apiDataConversionService.convertDepositProductDataToJson(prettyPrint, responseParameters, productData); + } + + @GET + @Path("template") + @Consumes({MediaType.APPLICATION_JSON}) + @Produces({MediaType.APPLICATION_JSON}) + public String retrieveNewDepositProductDetails(@Context final UriInfo uriInfo) { + + Set typicalResponseParameters = new HashSet( + Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn","currencyCode","digitsAfterDecimal", "currencyOptions","minimumBalance","maximumBalance")); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + DepositProductData depositProduct = this.depositProductReadPlatformService.retrieveNewDepositProductDetails(); + + return this.apiDataConversionService.convertDepositProductDataToJson(prettyPrint, responseParameters, depositProduct); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositProductCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositProductCommand.java new file mode 100644 index 000000000..2312cfadf --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositProductCommand.java @@ -0,0 +1,170 @@ +package org.mifosng.platform.api.commands; + +import java.math.BigDecimal; +import java.util.Set; + +public class DepositProductCommand { + + private final Long id; + private final String name; + private final String description; + + private final String currencyCode; + private final Integer digitsAfterDecimal; + + private final BigDecimal minimumBalance; + private final BigDecimal maximumBalance; + + private final Integer tenureMonths; + private final BigDecimal maturityDefaultInterestRate; + private final BigDecimal maturityMinInterestRate; + private final BigDecimal maturityMaxInterestRate; + private final Boolean canRenew; + private final Boolean canPreClose; + private final BigDecimal preClosureInterestRate; + + private final Set modifiedParameters; + + public DepositProductCommand(final Set modifiedParameters, + final Long id, final String name, final String description, + final String currencyCode, final Integer digitsAfterDecimal, + final BigDecimal minimumBalance, final BigDecimal maximumBalance, + final Integer tenureMonths, final BigDecimal maturityDefaultInterestRate, + final BigDecimal maturityMinInterestRate, final BigDecimal maturityMaxInterestRate, + final Boolean canRenew, final Boolean canPreClose, final BigDecimal preClosureInterestRate ) { + this.id = id; + this.name = name; + this.description = description; + + this.currencyCode = currencyCode; + this.digitsAfterDecimal = digitsAfterDecimal; + + this.minimumBalance=minimumBalance; + this.maximumBalance=maximumBalance; + + this.tenureMonths=tenureMonths; + this.maturityDefaultInterestRate = maturityDefaultInterestRate; + this.maturityMinInterestRate = maturityMinInterestRate; + this.maturityMaxInterestRate = maturityMaxInterestRate; + this.preClosureInterestRate = preClosureInterestRate; + + this.canRenew = canRenew; + this.canPreClose = canPreClose; + + this.modifiedParameters = modifiedParameters; + + } + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public Integer getDigitsAfterDecimal() { + return digitsAfterDecimal; + } + + public BigDecimal getMinimumBalance() { + return minimumBalance; + } + + public BigDecimal getMaximumBalance() { + return maximumBalance; + } + + public Integer getTenureMonths() { + return tenureMonths; + } + + public BigDecimal getMaturityDefaultInterestRate() { + return maturityDefaultInterestRate; + } + + public BigDecimal getMaturityMinInterestRate() { + return maturityMinInterestRate; + } + + public BigDecimal getMaturityMaxInterestRate() { + return maturityMaxInterestRate; + } + + public Boolean getCanRenew() { + return canRenew; + } + + public Boolean getCanPreClose() { + return canPreClose; + } + + public BigDecimal getPreClosureInterestRate() { + return preClosureInterestRate; + } + + public boolean isNameChanged() { + return this.modifiedParameters.contains("name"); + } + + public boolean isDescriptionChanged() { + return this.modifiedParameters.contains("description"); + } + + public boolean isCurrencyCodeChanged() { + return this.modifiedParameters.contains("currencyCode"); + } + + public boolean isDigitsAfterDecimalChanged() { + return this.modifiedParameters.contains("digitsAfterDecimal"); + } + + public boolean isInterestRateChanged() { + return this.modifiedParameters.contains("interestRate"); + } + + public boolean isMinimumBalanceChanged(){ + return this.modifiedParameters.contains("minimumBalance"); + } + + public boolean isMaximumBalanceChanged(){ + return this.modifiedParameters.contains("maximumBalance"); + } + + public boolean isTenureMonthsChanged() { + return this.modifiedParameters.contains("tenureMonths"); + } + + public boolean isMaturityDefaultInterestRateChanged() { + return this.modifiedParameters.contains("maturityDefaultInterestRate"); + } + + public boolean isMaturityMinInterestRateChanged() { + return this.modifiedParameters.contains("maturityMinInterestRate"); + } + + public boolean isMaturityMaxInterestRateChanged() { + return this.modifiedParameters.contains("maturityMaxInterestRate"); + } + + public boolean isCanRenewChanged() { + return this.modifiedParameters.contains("canRenew"); + } + + public boolean isCanPreCloseChanged() { + return this.modifiedParameters.contains("canPreClose"); + } + + public boolean isPreClosureInterestRateChanged() { + return this.modifiedParameters.contains("preClosureInterestRate"); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java new file mode 100644 index 000000000..1d6cc14ca --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java @@ -0,0 +1,124 @@ +package org.mifosng.platform.api.data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.joda.time.DateTime; + +public class DepositProductData implements Serializable { + + private Long id; + private String name; + private String description; + private String currencyCode; + private Integer digitsAfterDecimal; + + private BigDecimal minimumBalance = BigDecimal.ZERO; + private BigDecimal maximumBalance = BigDecimal.ZERO; + + private DateTime createdOn; + private DateTime lastModifedOn; + + private List currencyOptions = new ArrayList(); + + public DepositProductData() { + // TODO Auto-generated constructor stub + } + + public DepositProductData(DateTime createdOn, DateTime lastModifedOn, Long id,String name, String description, String currencyCode, Integer digitsAfterDecimal,BigDecimal minimumBalance,BigDecimal maximumBalance) { + + this.createdOn=createdOn; + this.lastModifedOn=lastModifedOn; + this.id=id; + this.name=name; + this.description=description; + this.currencyCode=currencyCode; + this.digitsAfterDecimal=digitsAfterDecimal; + this.minimumBalance=minimumBalance; + this.maximumBalance=maximumBalance; + + } + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public void setCurrencyCode(String currencyCode) { + this.currencyCode = currencyCode; + } + + public Integer getDigitsAfterDecimal() { + return digitsAfterDecimal; + } + + public void setDigitsAfterDecimal(Integer digitsAfterDecimal) { + this.digitsAfterDecimal = digitsAfterDecimal; + } + + public BigDecimal getMinimumBalance() { + return minimumBalance; + } + + public void setMinimumBalance(BigDecimal minimumBalance) { + this.minimumBalance = minimumBalance; + } + + public BigDecimal getMaximumBalance() { + return maximumBalance; + } + + public void setMaximumBalance(BigDecimal maximumBalance) { + this.maximumBalance = maximumBalance; + } + + public DateTime getCreatedOn() { + return createdOn; + } + + public void setCreatedOn(DateTime createdOn) { + this.createdOn = createdOn; + } + + public DateTime getLastModifedOn() { + return lastModifedOn; + } + + public void setLastModifedOn(DateTime lastModifedOn) { + this.lastModifedOn = lastModifedOn; + } + + public List getCurrencyOptions() { + return currencyOptions; + } + + public void setCurrencyOptions(List currencyOptions) { + this.currencyOptions = currencyOptions; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductLookup.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductLookup.java new file mode 100644 index 000000000..fa1e360bb --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductLookup.java @@ -0,0 +1,37 @@ +package org.mifosng.platform.api.data; + +import java.io.Serializable; + +public class DepositProductLookup implements Serializable { + + private Long id; + private String name; + + public DepositProductLookup() { + // TODO Auto-generated constructor stub + } + + public DepositProductLookup(Long id, String name) { + this.id = id; + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java index 4b0ec19d7..de97253ed 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionService.java @@ -5,6 +5,7 @@ import java.util.Set; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.ClientCommand; +import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.api.commands.LoanProductCommand; @@ -23,6 +24,7 @@ import org.mifosng.platform.api.data.AuthenticatedUserData; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData; import org.mifosng.platform.api.data.ConfigurationData; +import org.mifosng.platform.api.data.DepositProductData; import org.mifosng.platform.api.data.FundData; import org.mifosng.platform.api.data.GenericResultsetData; import org.mifosng.platform.api.data.GroupData; @@ -61,7 +63,9 @@ public interface ApiDataConversionService { String convertLoanProductDataToJson(boolean prettyPrint, Set responseParameters, LoanProductData... products); - String convertSavingProductDataToJson(boolean prettyPrint, Set responseParameters, SavingProductData... products); + String convertSavingProductDataToJson(boolean prettyPrint, Set responseParameters, SavingProductData... products); + + String convertDepositProductDataToJson(boolean prettyPrint, Set responseParameters, DepositProductData... products); String convertNewLoanDataToJson(boolean prettyPrint, Set responseParameters, NewLoanData newLoanData); @@ -93,6 +97,8 @@ public interface ApiDataConversionService { LoanProductCommand convertJsonToLoanProductCommand(Long resourceIdentifier, String json); SavingProductCommand convertJsonToSavingProductCommand(Long resourceIdentifier, String json); + + DepositProductCommand convertJsonToDepositProductCommand(Long resourceIdentifier, String json); ClientCommand convertJsonToClientCommand(Long resourceIdentifier, String jsonRequestBody); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java index b6c78f6fe..459ad3cff 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java @@ -21,6 +21,7 @@ import org.joda.time.format.DateTimeFormat; import org.mifosng.platform.api.commands.AdjustLoanTransactionCommand; import org.mifosng.platform.api.commands.BranchMoneyTransferCommand; import org.mifosng.platform.api.commands.ClientCommand; +import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosng.platform.api.commands.FundCommand; import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.api.commands.LoanProductCommand; @@ -40,6 +41,7 @@ import org.mifosng.platform.api.data.AuthenticatedUserData; import org.mifosng.platform.api.data.ClientData; import org.mifosng.platform.api.data.ClientLoanAccountSummaryCollectionData; import org.mifosng.platform.api.data.ConfigurationData; +import org.mifosng.platform.api.data.DepositProductData; import org.mifosng.platform.api.data.FundData; import org.mifosng.platform.api.data.GenericResultsetData; import org.mifosng.platform.api.data.GroupData; @@ -1179,6 +1181,22 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { return paramValue; } + private Boolean extractBooleanParameter(final String paramName, final Map requestMap, final Set modifiedParameters) { + Boolean paramValue = null; + String paramValueAsString = null; + if (requestMap.containsKey(paramName)) { + paramValueAsString = (String) requestMap.get(paramName); + + if (paramValueAsString != null) { + paramValueAsString = paramValueAsString.trim(); + } + + paramValue = Boolean.valueOf(paramValueAsString); + modifiedParameters.add(paramName); + } + return paramValue; + } + private Long extractLongParameter(final String paramName, final Map requestMap, final Set modifiedParameters) { Long paramValue = null; if (requestMap.containsKey(paramName)) { @@ -1499,4 +1517,71 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { return json; } + + @Override + public DepositProductCommand convertJsonToDepositProductCommand(Long resourceIdentifier, String json) { + + if (StringUtils.isBlank(json)) { + throw new InvalidJsonException(); + } + + Type typeOfMap = new TypeToken>() {}.getType(); + Map requestMap = gsonConverter.fromJson(json, typeOfMap); + + Set supportedParams = new HashSet(Arrays.asList("name","description","currencyCode", "digitsAfterDecimal","locale","minimumBalance","maximumBalance","tenureMonths","maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate","canRenew","canPreClose","preClosureInterestRate")); + checkForUnsupportedParameters(requestMap, supportedParams); + Set modifiedParameters = new HashSet(); + String name = extractStringParameter("name", requestMap,modifiedParameters); + String description = extractStringParameter("description", requestMap,modifiedParameters); + String currencyCode=extractStringParameter("currencyCode", requestMap,modifiedParameters); + Integer digitsAfterDecimalValue = extractIntegerParameter("digitsAfterDecimal", requestMap, modifiedParameters); + BigDecimal minimumBalance=extractBigDecimalParameter("minimumBalance", requestMap, modifiedParameters); + BigDecimal maximumBalance=extractBigDecimalParameter("maximumBalance", requestMap, modifiedParameters); + + Integer tenureMonths = extractIntegerParameter("tenureMonths", requestMap, modifiedParameters); + BigDecimal maturityDefaultInterestRate = extractBigDecimalParameter("maturityDefaultInterestRate", requestMap, modifiedParameters); + BigDecimal maturityMinInterestRate = extractBigDecimalParameter("maturityMinInterestRate", requestMap, modifiedParameters); + BigDecimal maturityMaxInterestRate = extractBigDecimalParameter("maturityMaxInterestRate", requestMap, modifiedParameters); + Boolean canRenew = extractBooleanParameter("canRenew", requestMap, modifiedParameters); + Boolean canPreClose = extractBooleanParameter("canPreClose", requestMap, modifiedParameters); + BigDecimal preClosureInterestRate = extractBigDecimalParameter("preClosureInterestRate", requestMap, modifiedParameters); + + + return new DepositProductCommand(modifiedParameters, resourceIdentifier, name, description, currencyCode, digitsAfterDecimalValue, minimumBalance,maximumBalance, + tenureMonths, maturityDefaultInterestRate, maturityMinInterestRate, maturityMaxInterestRate, canRenew, canPreClose, preClosureInterestRate); + } + + @Override + public String convertDepositProductDataToJson(boolean prettyPrint, + Set responseParameters, DepositProductData... products) { + + Set supportedParameters = new HashSet( + Arrays.asList("id", "name", "description","createdOn", "lastModifedOn","currencyCode","digitsAfterDecimal", "currencyOptions", "minimumBalance","maximumBalance")); + final Set parameterNamesToSkip = new HashSet(); + if (!responseParameters.isEmpty()) { + if (!supportedParameters.containsAll(responseParameters)) { + throw new UnsupportedParameterException(new ArrayList(responseParameters)); + } + + parameterNamesToSkip.addAll(supportedParameters); + parameterNamesToSkip.removeAll(responseParameters); + } + ExclusionStrategy strategy = new ParameterListExclusionStrategy(parameterNamesToSkip); + GsonBuilder builder = new GsonBuilder().addSerializationExclusionStrategy(strategy); + builder.registerTypeAdapter(LocalDate.class, new JodaLocalDateAdapter()); + builder.registerTypeAdapter(DateTime.class, new JodaDateTimeAdapter()); + if (prettyPrint) { + builder.setPrettyPrinting(); + } + Gson gsonDeserializer = builder.create(); + + String json = ""; + if (products != null && products.length == 1) { + json = gsonDeserializer.toJson(products[0]); + } else { + json = gsonDeserializer.toJson(products); + } + + return json; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProduct.java b/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProduct.java new file mode 100644 index 000000000..aa60f2b1d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProduct.java @@ -0,0 +1,118 @@ +package org.mifosng.platform.deposit.domain; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Table; + +import org.apache.commons.lang.StringUtils; +import org.mifosng.platform.api.commands.DepositProductCommand; +import org.mifosng.platform.currency.domain.MonetaryCurrency; +import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosng.platform.user.domain.AppUser; + +@Entity +@Table(name = "portfolio_product_deposit") +public class DepositProduct extends AbstractAuditableCustom { + + @Column(name = "name", nullable = false) + private String name; + + @Column(name = "description") + private String description; + + @Column(name = "is_deleted", nullable=false) + private boolean deleted = false; + + @Embedded + DepositProductRelatedDetail depositProductRelatedDetail; + + protected DepositProduct(){ + this.name = null; + this.description = null; + depositProductRelatedDetail=null; + } + + public DepositProduct(final String name, final String description, final MonetaryCurrency currency, final BigDecimal minimumBalance,final BigDecimal maximumBalance, + final Integer tenureMonths,final BigDecimal maturityDefaultInterestRate, final BigDecimal maturityMinInterestRate, BigDecimal maturityMaxInterestRate, Boolean canRenew, + Boolean canPreClose, BigDecimal preClosureInterestRate ){ + this.name = name.trim(); + if (StringUtils.isNotBlank(description)) { + this.description = description.trim(); + } else { + this.description = null; + } + this.depositProductRelatedDetail= new DepositProductRelatedDetail(currency, minimumBalance, maximumBalance, tenureMonths, maturityDefaultInterestRate, maturityMinInterestRate, maturityMaxInterestRate, canRenew, canPreClose, preClosureInterestRate); + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + public MonetaryCurrency getCurrency() { + return this.depositProductRelatedDetail.getCurrency(); + } + + public BigDecimal getMinimumBalance(){ + return this.depositProductRelatedDetail.getMinimumBalance(); + } + + public BigDecimal getMaximumBalance(){ + return this.depositProductRelatedDetail.getMaximumBalance(); + } + + public Integer getTenureMonths(){ + return this.depositProductRelatedDetail.getTenureMonths(); + } + + public BigDecimal getMaturityDefaultInterestRate() { + return this.depositProductRelatedDetail.getMaturityDefaultInterestRate(); + } + + public BigDecimal getMaturityMinInterestRate() { + return this.depositProductRelatedDetail.getMaturityMinInterestRate(); + } + + public BigDecimal getMaturityMaxInterestRate() { + return this.depositProductRelatedDetail.getMaturityMaxInterestRate(); + } + + public Boolean getCanRenew() { + return this.depositProductRelatedDetail.getCanRenew(); + } + + public Boolean getCanPreClose() { + return this.depositProductRelatedDetail.getCanPreClose(); + } + + public BigDecimal getPreClosureInterestRate() { + return this.depositProductRelatedDetail.getPreClosureInterestRate(); + } + + public boolean isDeleted() { + return deleted; + } + + public void delete() { + this.deleted = true; + } + + public void update(DepositProductCommand command){ + + if (command.isNameChanged()) { + this.name = command.getName(); + } + + if (command.isDescriptionChanged()) { + this.description = command.getDescription(); + } + + this.depositProductRelatedDetail.update(command); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRelatedDetail.java b/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRelatedDetail.java new file mode 100644 index 000000000..ed52e8b50 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRelatedDetail.java @@ -0,0 +1,168 @@ +package org.mifosng.platform.deposit.domain; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.Embedded; + +import org.mifosng.platform.api.commands.DepositProductCommand; +import org.mifosng.platform.currency.domain.MonetaryCurrency; + + @Embeddable + public class DepositProductRelatedDetail { + + @Embedded + private MonetaryCurrency currency; + + @Column(name = "minimum_balance", scale = 6, precision = 19, nullable = false) + private BigDecimal minimumBalance; + + @Column(name = "maximum_balance", scale = 6, precision = 19, nullable = false) + private BigDecimal maximumBalance; + + @Column(name = "tenure_months", nullable=false) + private Integer tenureMonths; + + @Column(name = "maturity_default_interest_rate", scale = 6, precision = 19, nullable = false) + private BigDecimal maturityDefaultInterestRate; + + @Column(name = "maturity_min_interest_rate", scale = 6, precision = 19, nullable = false) + private BigDecimal maturityMinInterestRate; + + @Column(name = "maturity_max_interest_rate", scale = 6, precision = 19, nullable = false) + private BigDecimal maturityMaxInterestRate; + + @Column(name = "can_renew", nullable=false) + private Boolean canRenew; + + @Column(name = "can_pre_close", nullable=false) + private Boolean canPreClose; + + @Column(name = "pre_closure_interest_rate", scale = 6, precision = 19, nullable = false) + private BigDecimal preClosureInterestRate; + + public DepositProductRelatedDetail() { + this.maximumBalance = null; + this.minimumBalance = null; + this.tenureMonths = null; + this.maturityDefaultInterestRate = null; + this.maturityMinInterestRate = null; + this.maturityMaxInterestRate = null; + this.canRenew = null; + this.canPreClose = null; + this.preClosureInterestRate = null; + } + + public DepositProductRelatedDetail(final MonetaryCurrency currency, final BigDecimal minimumBalance,final BigDecimal maximumBalance, final Integer tenureMonths, + final BigDecimal maturityDefaultInterestRate, final BigDecimal maturityMinInterestRate, BigDecimal maturityMaxInterestRate, Boolean canRenew, Boolean canPreClose, BigDecimal preClosureInterestRate){ + + this.currency=currency; + this.minimumBalance=minimumBalance; + this.maximumBalance=maximumBalance; + + this.tenureMonths = tenureMonths; + this.maturityDefaultInterestRate = maturityDefaultInterestRate; + this.maturityMinInterestRate = maturityMinInterestRate; + this.maturityMaxInterestRate = maturityMaxInterestRate; + this.canRenew = canRenew; + this.canPreClose = canPreClose; + this.preClosureInterestRate = preClosureInterestRate; + } + + + public MonetaryCurrency getCurrency() { + return this.currency.copy(); + } + + public BigDecimal getMinimumBalance(){ + return BigDecimal.valueOf(Double.valueOf(this.minimumBalance.stripTrailingZeros().toString())); + } + + public BigDecimal getMaximumBalance(){ + return BigDecimal.valueOf(Double.valueOf(this.maximumBalance.stripTrailingZeros().toString())); + } + + public Integer getTenureMonths() { + return this.tenureMonths; + } + + public BigDecimal getMaturityDefaultInterestRate() { + return BigDecimal.valueOf(Double.valueOf(this.maturityDefaultInterestRate.stripTrailingZeros().toString())); + } + + public BigDecimal getMaturityMinInterestRate() { + return BigDecimal.valueOf(Double.valueOf(this.maturityMinInterestRate.stripTrailingZeros().toString())); + } + + public BigDecimal getMaturityMaxInterestRate() { + return BigDecimal.valueOf(Double.valueOf(this.maturityMaxInterestRate.stripTrailingZeros().toString())); + } + + public Boolean getCanRenew() { + return this.canRenew; + } + + public Boolean getCanPreClose() { + return this.canPreClose; + } + + public BigDecimal getPreClosureInterestRate() { + return BigDecimal.valueOf(Double.valueOf(this.preClosureInterestRate.stripTrailingZeros().toString())); + } + + public void update(DepositProductCommand command){ + + Integer digitsAfterDecimalChanged = this.currency.getDigitsAfterDecimal(); + if (command.isDigitsAfterDecimalChanged()) { + digitsAfterDecimalChanged = command.getDigitsAfterDecimal(); + } + + String currencyCodeChanged = this.currency.getCode(); + if (command.isCurrencyCodeChanged()) { + currencyCodeChanged = command.getCurrencyCode(); + } + + if (command.isDigitsAfterDecimalChanged() || command.isCurrencyCodeChanged()) { + this.currency = new MonetaryCurrency(currencyCodeChanged, digitsAfterDecimalChanged); + } + + if(command.isMinimumBalanceChanged()){ + this.minimumBalance=command.getMinimumBalance(); + } + + if(command.isMaximumBalanceChanged()){ + this.maximumBalance=command.getMaximumBalance(); + } + + if(command.isTenureMonthsChanged()){ + this.tenureMonths=command.getTenureMonths(); + } + + if (command.isMaturityDefaultInterestRateChanged()) { + this.maturityDefaultInterestRate=command.getMaturityDefaultInterestRate(); + } + + if(command.isMaturityMaxInterestRateChanged()){ + this.maturityMaxInterestRate=command.getMaturityMaxInterestRate(); + } + + if (command.isMaturityMinInterestRateChanged()) { + this.maturityMinInterestRate=command.getMaturityMinInterestRate(); + } + + if (command.isCanRenewChanged()) { + this.canRenew=command.getCanRenew(); + } + + if (command.isCanPreCloseChanged()) { + this.canPreClose=command.getCanPreClose(); + } + + if (command.isPreClosureInterestRateChanged()) { + this.preClosureInterestRate=command.getPreClosureInterestRate(); + } + + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRepository.java b/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRepository.java new file mode 100644 index 000000000..e328b739d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/deposit/domain/DepositProductRepository.java @@ -0,0 +1,10 @@ +package org.mifosng.platform.deposit.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface DepositProductRepository extends + JpaRepository, + JpaSpecificationExecutor { + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductCommandValidator.java new file mode 100644 index 000000000..a724da906 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductCommandValidator.java @@ -0,0 +1,89 @@ +package org.mifosng.platform.depositproduct.service; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosng.platform.DataValidatorBuilder; +import org.mifosng.platform.api.commands.DepositProductCommand; +import org.mifosng.platform.api.data.ApiParameterError; +import org.mifosng.platform.exceptions.PlatformApiDataValidationException; + +public class DepositProductCommandValidator { + + private final DepositProductCommand command; + + public DepositProductCommandValidator(final DepositProductCommand command) { + this.command=command; + } + + public void validateForCreate() { + + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product"); + baseDataValidator.reset().parameter("name").value(command.getName()).notBlank(); + baseDataValidator.reset().parameter("description").value(command.getDescription()).notExceedingLengthOf(500); + baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank(); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6); + baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).notNull(); + baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).notNull(); + baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).notNull(); + baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).notNull(); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).notNull(); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).notNull(); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("canRenew").value(command.getCanRenew()).notNull(); + baseDataValidator.reset().parameter("canPreClose").value(command.getCanPreClose()).notNull(); + baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).notNull(); + baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).zeroOrPositiveAmount(); + + baseDataValidator.reset().comapareMinimumAndMaximumAmounts(command.getMinimumBalance(), command.getMaximumBalance()); + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } + + public void validateForUpdate() { + + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("savingsproduct"); + baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); + baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank(); + baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notExceedingLengthOf(500); + baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).ignoreIfNull().notBlank(); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().notNull().inMinMaxRange(0, 6); + baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).notNull(); + baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).notNull(); + baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).zeroOrPositiveAmount(); + + baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).notNull(); + baseDataValidator.reset().parameter("tenureMonths").value(command.getTenureMonths()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).notNull(); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(command.getMaturityDefaultInterestRate()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).notNull(); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(command.getMaturityMinInterestRate()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).notNull(); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(command.getMaturityMaxInterestRate()).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("canRenew").value(command.getCanRenew()).notNull(); + baseDataValidator.reset().parameter("canPreClose").value(command.getCanPreClose()).notNull(); + baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).notNull(); + baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).zeroOrPositiveAmount(); + + baseDataValidator.reset().comapareMinimumAndMaximumAmounts(command.getMinimumBalance(), command.getMaximumBalance()); + + baseDataValidator.reset().anyOfNotNull(command.getName(), command.getDescription(),command.getCurrencyCode(),command.getDigitsAfterDecimal(),command.getMinimumBalance(),command.getMaximumBalance(),command.getTenureMonths(),command.getMaturityDefaultInterestRate(),command.getMaturityMaxInterestRate(),command.getMaturityMinInterestRate(),command.getCanRenew(),command.getCanPreClose(),command.getPreClosureInterestRate()); + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformService.java new file mode 100644 index 000000000..d2139624f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformService.java @@ -0,0 +1,18 @@ +package org.mifosng.platform.depositproduct.service; + +import java.util.Collection; + +import org.mifosng.platform.api.data.DepositProductData; +import org.mifosng.platform.api.data.DepositProductLookup; + +public interface DepositProductReadPlatformService { + + Collection retrieveAllDepositProducts(); + + Collection retrieveAllDepositProductsForLookup(); + + DepositProductData retrieveDepositProductData(Long productId); + + DepositProductData retrieveNewDepositProductDetails(); + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformServiceImpl.java new file mode 100644 index 000000000..2aa0af31e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductReadPlatformServiceImpl.java @@ -0,0 +1,123 @@ +package org.mifosng.platform.depositproduct.service; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; + +import org.joda.time.DateTime; +import org.mifosng.platform.api.data.CurrencyData; +import org.mifosng.platform.api.data.DepositProductData; +import org.mifosng.platform.api.data.DepositProductLookup; +import org.mifosng.platform.currency.service.CurrencyReadPlatformService; +import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; +import org.mifosng.platform.security.PlatformSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class DepositProductReadPlatformServiceImpl implements + DepositProductReadPlatformService { + + private final PlatformSecurityContext context; + private final JdbcTemplate jdbcTemplate; + private final CurrencyReadPlatformService currencyReadPlatformService; + + @Autowired + public DepositProductReadPlatformServiceImpl(final PlatformSecurityContext context,final TenantAwareRoutingDataSource dataSource,final CurrencyReadPlatformService currencyReadPlatformService) { + this.context=context; + jdbcTemplate=new JdbcTemplate(dataSource); + this.currencyReadPlatformService=currencyReadPlatformService; + } + + @Override + public Collection retrieveAllDepositProducts() { + this.context.authenticatedUser(); + DepositProductMapper depositProductMapper= new DepositProductMapper(); + String sql="select "+depositProductMapper.depositProductSchema() + " where sp.is_deleted=0"; + return this.jdbcTemplate.query(sql,depositProductMapper, new Object[]{}); + } + + @Override + public Collection retrieveAllDepositProductsForLookup() { + this.context.authenticatedUser(); + DepositProductLookupMapper depositProductLookupMapper=new DepositProductLookupMapper(); + String sql = "select "+depositProductLookupMapper.depositProductLookupSchema(); + return this.jdbcTemplate.query(sql, depositProductLookupMapper, new Object[]{}); + } + + @Override + public DepositProductData retrieveDepositProductData(Long productId) { + DepositProductMapper depositProductMapper=new DepositProductMapper(); + String sql = "select "+ depositProductMapper.depositProductSchema() +" where dp.id = ? and dp.is_deleted=0"; + DepositProductData productData=this.jdbcTemplate.queryForObject(sql, depositProductMapper, new Object[]{productId}); + populateProductDataWithDropdownOptions(productData); + return productData; + } + + @Override + public DepositProductData retrieveNewDepositProductDetails() { + + DepositProductData productData=new DepositProductData(); + populateProductDataWithDropdownOptions(productData); + return productData; + } + + private static final class DepositProductMapper implements RowMapper{ + + public String depositProductSchema(){ + return "dp.id as id,dp.name as name, dp.description as description,dp.currency_code as currencyCode, dp.currency_digits as currencyDigits,dp.minimum_balance as minimumBalance,dp.maximum_balance as maximumBalance,dp.created_date as createdon, dp.lastmodified_date as modifiedon, " + + "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol " + + "from portfolio_product_deposit dp join ref_currency curr on curr.code = dp.currency_code "; + } + + @Override + public DepositProductData mapRow(ResultSet rs, int rowNum) + throws SQLException { + + Long id = rs.getLong("id"); + String name = rs.getString("name"); + String description = rs.getString("description"); + + String currencyCode = rs.getString("currencyCode"); + Integer currencyDigits = JdbcSupport.getInteger(rs,"currencyDigits"); + + DateTime createdOn = JdbcSupport.getDateTime(rs, "createdon"); + DateTime lastModifedOn = JdbcSupport.getDateTime(rs, "modifiedon"); + + BigDecimal minimumBalance=rs.getBigDecimal("minimumBalance"); + BigDecimal maximumBalance=rs.getBigDecimal("maximumBalance"); + return new DepositProductData(createdOn, lastModifedOn, id, name, description, currencyCode, currencyDigits, minimumBalance, maximumBalance); + } + + } + + private static final class DepositProductLookupMapper implements RowMapper { + + public String depositProductLookupSchema() { + return "dp.id as id, dp.name as name from portfolio_product_deposit dp"; + } + + @Override + public DepositProductLookup mapRow(final ResultSet rs, final int rowNum) + throws SQLException { + + Long id = rs.getLong("id"); + String name = rs.getString("name"); + + return new DepositProductLookup(id, name); + } + + } + + private void populateProductDataWithDropdownOptions(final DepositProductData productData) { + List currencyOptions = currencyReadPlatformService.retrieveAllowedCurrencies(); + productData.setCurrencyOptions(currencyOptions); + } + + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformService.java new file mode 100644 index 000000000..b903886b3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformService.java @@ -0,0 +1,18 @@ +package org.mifosng.platform.depositproduct.service; + +import org.mifosng.platform.api.commands.DepositProductCommand; +import org.mifosng.platform.api.data.EntityIdentifier; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface DepositProductWritePlatformService { + + @PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')") + EntityIdentifier createDepositProduct(DepositProductCommand command); + + @PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')") + EntityIdentifier updateDepositProduct(DepositProductCommand command); + + @PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')") + EntityIdentifier deleteDepositProduct(Long productId); + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..d6f328f4d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/depositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,78 @@ +package org.mifosng.platform.depositproduct.service; + +import org.mifosng.platform.api.commands.DepositProductCommand; +import org.mifosng.platform.api.data.EntityIdentifier; +import org.mifosng.platform.currency.domain.MonetaryCurrency; +import org.mifosng.platform.deposit.domain.DepositProduct; +import org.mifosng.platform.deposit.domain.DepositProductRepository; +import org.mifosng.platform.exceptions.DepositProductNotFoundException; +import org.mifosng.platform.security.PlatformSecurityContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class DepositProductWritePlatformServiceJpaRepositoryImpl implements + DepositProductWritePlatformService { + + private final PlatformSecurityContext context; + private final DepositProductRepository depositProductRepository; + + + @Autowired + public DepositProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final DepositProductRepository depositProductRepository){ + this.context=context; + this.depositProductRepository=depositProductRepository; + } + + @Transactional + @Override + public EntityIdentifier createDepositProduct(DepositProductCommand command) { + + this.context.authenticatedUser(); + DepositProductCommandValidator validator=new DepositProductCommandValidator(command); + validator.validateForCreate(); + + MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); + DepositProduct product = new DepositProduct(command.getName(),command.getDescription(),currency,command.getMinimumBalance(),command.getMaximumBalance(), + command.getTenureMonths(),command.getMaturityDefaultInterestRate(),command.getMaturityMinInterestRate(),command.getMaturityMaxInterestRate(), + command.getCanRenew(),command.getCanPreClose(),command.getPreClosureInterestRate()); + this.depositProductRepository.save(product); + + return new EntityIdentifier(product.getId()); + + } + + @Transactional + @Override + public EntityIdentifier updateDepositProduct(DepositProductCommand command) { + + this.context.authenticatedUser(); + DepositProductCommandValidator validator=new DepositProductCommandValidator(command); + validator.validateForUpdate(); + + DepositProduct product=this.depositProductRepository.findOne(command.getId()); + if(product==null){ + throw new DepositProductNotFoundException(command.getId()); + } + + product.update(command); + this.depositProductRepository.save(product); + return new EntityIdentifier(Long.valueOf(product.getId())); + } + + @Transactional + @Override + public EntityIdentifier deleteDepositProduct(Long productId) { + + this.context.authenticatedUser(); + DepositProduct product=this.depositProductRepository.findOne(productId); + if(product==null){ + throw new DepositProductNotFoundException(productId); + } + product.delete(); + this.depositProductRepository.save(product); + return new EntityIdentifier(Long.valueOf(product.getId())); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductNotFoundException.java b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductNotFoundException.java new file mode 100644 index 000000000..5aaa867f0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductNotFoundException.java @@ -0,0 +1,13 @@ +package org.mifosng.platform.exceptions; + +public class DepositProductNotFoundException extends + AbstractPlatformResourceNotFoundException { + + public DepositProductNotFoundException(Long id) { + super("error.msg.depositproduct.id.invalid", "Deposit product with identifier " + id + " does not exist", id); + // TODO Auto-generated constructor stub + } + + + +} diff --git a/mifosng-provider/src/test/resources/META-INF/context.xml b/mifosng-provider/src/test/resources/META-INF/context.xml index d9556190e..7c0a42100 100644 --- a/mifosng-provider/src/test/resources/META-INF/context.xml +++ b/mifosng-provider/src/test/resources/META-INF/context.xml @@ -5,7 +5,7 @@ driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/mifosplatform-tenants" username="root" - password="mysql" + password="mifos" validationQuery="select 1" maxActive="10" maxIdle="4"