diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java deleted file mode 100644 index e7d55214a..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositAccountsApiResource.java +++ /dev/null @@ -1,269 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -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.QueryParam; -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.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.DepositAccountCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionCommand; -import org.mifosng.platform.api.data.DepositAccountData; -import org.mifosng.platform.api.data.DepositPermissionData; -import org.mifosng.platform.api.data.DepositProductLookup; -import org.mifosng.platform.saving.service.DepositAccountReadPlatformService; -import org.mifosng.platform.saving.service.DepositAccountWritePlatformService; -import org.mifosng.platform.savingproduct.service.DepositProductReadPlatformService; -import org.mifosng.platform.savingproduct.service.SavingsDepositEnumerations; -import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; -import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService; -import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; -import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; -import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/depositaccounts") -@Component -@Scope("singleton") -public class DepositAccountsApiResource { - - @Autowired - private DepositAccountReadPlatformService depositAccountReadPlatformService; - - @Autowired - private DepositProductReadPlatformService depositProductReadPlatformService; - - @Autowired - private DepositAccountWritePlatformService depositAccountWritePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "DEPOSITACCOUNT"; - @Autowired - private PlatformSecurityContext context; - - private static final Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "externalId", "clientId", "clientName", - "productId", "productName", "status", "currency", - "deposit", "maturityInterestRate", "tenureInMonths", - "interestCompoundedEvery","interestCompoundingAllowed", - "interestCompoundedEveryPeriodType", "renewalAllowed", - "preClosureAllowed", "preClosureInterestRate", - "withdrawnonDate","rejectedonDate","closedonDate","transactions","interestPaid","isInterestWithdrawable", - "availableInterestForWithdrawal","availableWithdrawalAmount","todaysDate", - "isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")); - - - @POST - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response createDepositAccount(final String jsonRequestBody){ - - final DepositAccountCommand command = this.apiDataConversionService.convertJsonToDepositAccountCommand(null, jsonRequestBody); - - EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.createDepositAccount(command); - - return Response.ok().entity(entityIdentifier).build(); - } - - @PUT - @Path("{accountId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response updateDepositAccount(@PathParam("accountId") final Long accountId,final String jsonRequestBody){ - - final DepositAccountCommand command = this.apiDataConversionService.convertJsonToDepositAccountCommand(accountId, jsonRequestBody); - - EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.updateDepositAccount(command); - - return Response.ok().entity(entityIdentifier).build(); - } - - @GET - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - Collection accounts = this.depositAccountReadPlatformService.retrieveAllDepositAccounts(); - - return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, accounts); - } - - @GET - @Path("{accountId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - - DepositPermissionData permissions = null; - - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - DepositAccountData account = this.depositAccountReadPlatformService.retrieveDepositAccount(accountId); - - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - if (template) { - account = handleTemplateRelatedData(responseParameters, account); - } - - Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); - if (!associationParameters.isEmpty()) { - if (associationParameters.contains("all")) { - responseParameters.addAll(Arrays.asList("permissions")); - } else { - responseParameters.addAll(associationParameters); - } - permissions = this.depositAccountReadPlatformService.retrieveDepositAccountsPermissions(account); - account = new DepositAccountData(account, permissions, account.getTransactions()); - } - - return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, account); - } - - @GET - @Path("template") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveNewDepositAccountDetails( - @QueryParam("clientId") final Long clientId, - @QueryParam("productId") final Long productId, - @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - DepositAccountData account = this.depositAccountReadPlatformService.retrieveNewDepositAccountDetails(clientId,productId); - - account = handleTemplateRelatedData(responseParameters, account); - - return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, account); - } - - @DELETE - @Path("{accountId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response deleteProduct(@PathParam("accountId") final Long accountId) { - - this.depositAccountWritePlatformService.deleteDepositAccount(accountId); - - return Response.ok(new EntityIdentifier(accountId)).build(); - } - - private DepositAccountData handleTemplateRelatedData( - final Set responseParameters, - final DepositAccountData account) { - - responseParameters.addAll(Arrays.asList("interestCompoundedEveryPeriodTypeOptions", "productOptions")); - - Collection productOptions = depositProductReadPlatformService.retrieveAllDepositProductsForLookup(); - - EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS); - List interestCompoundedEveryPeriodTypeOptions = Arrays.asList(monthly); - - return new DepositAccountData(account, interestCompoundedEveryPeriodTypeOptions, productOptions); - } - - @POST - @Path("{accountId}") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public Response SubmitDepositApplication(@PathParam("accountId") final Long accountId, - @QueryParam("command") final String commandParam, final String jsonRequestBody) { - - Response response=null; - - if (is(commandParam, "approve")) { - DepositStateTransitionApprovalCommand command=apiDataConversionService.convertJsonToDepositStateTransitionApprovalCommand(accountId, jsonRequestBody); - EntityIdentifier identifier = this.depositAccountWritePlatformService.approveDepositApplication(command); - response = Response.ok().entity(identifier).build(); - } else if(is(commandParam, "withdrawal")){ - DepositAccountWithdrawalCommand command = apiDataConversionService.convertJsonToDepositWithdrawalCommand(accountId, jsonRequestBody); - EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountMoney(command); - response = Response.ok().entity(identifier).build(); - } else if(is(commandParam, "interestwithdraw")){ - DepositAccountWithdrawInterestCommand command = apiDataConversionService.convertJsonToDepositAccountWithdrawInterestCommand(accountId, jsonRequestBody); - EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountInterestMoney(command); - response = Response.ok().entity(identifier).build(); - } else if(is(commandParam, "renew")){ - DepositAccountCommand command = apiDataConversionService.convertJsonToDepositAccountCommand(accountId, jsonRequestBody); - EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.renewDepositAccount(command); - return Response.ok().entity(entityIdentifier).build(); - } else { - DepositStateTransitionCommand command=apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, jsonRequestBody); - if (is(commandParam, "reject")) { - EntityIdentifier identifier = this.depositAccountWritePlatformService.rejectDepositApplication(command); - response = Response.ok().entity(identifier).build(); - } else if (is(commandParam, "withdrewbyclient")) { - EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositApplication(command); - response = Response.ok().entity(identifier).build(); - } - - UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); - - if (is(commandParam, "undoapproval")) { - EntityIdentifier identifier = this.depositAccountWritePlatformService.undoDepositApproval(undoCommand); - response = Response.ok().entity(identifier).build(); - } - } - - if (response == null) { - throw new UnrecognizedQueryParamException("command", commandParam); - } - - return response; - } - - private boolean is(final String commandParam, final String commandValue) { - return StringUtils.isNotBlank(commandParam) - && commandParam.trim().equalsIgnoreCase(commandValue); - } -} \ No newline at end of file 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 deleted file mode 100644 index 4569ff00c..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/DepositProductsApiResource.java +++ /dev/null @@ -1,197 +0,0 @@ -package org.mifosng.platform.api; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -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.savingproduct.service.DepositProductReadPlatformService; -import org.mifosng.platform.savingproduct.service.DepositProductWritePlatformService; -import org.mifosng.platform.savingproduct.service.SavingsDepositEnumerations; -import org.mifosplatform.infrastructure.configuration.data.CurrencyData; -import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; -import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; -import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService; -import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -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 CurrencyReadPlatformService currencyReadPlatformService; - - @Autowired - private DepositProductWritePlatformService depositProductWritePlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "DEPOSITPRODUCT"; - @Autowired - private PlatformSecurityContext context; - - @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) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "externalId", "name", "description", "createdOn", "lastModifedOn", - "currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance","tenureInMonths", - "maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate", - "interestCompoundedEvery", "interestCompoundedEveryPeriodType", - "renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed", - "isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")); - - 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.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, products); - } - - @GET - @Path("{productId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveDepositProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "externalId", "name", "description", "createdOn", "lastModifedOn", - "currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance","tenureInMonths", - "maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate", - "interestCompoundedEvery", "interestCompoundedEveryPeriodType", - "renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed", - "isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - DepositProductData productData = this.depositProductReadPlatformService.retrieveDepositProductData(productId); - - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - if (template) { - productData = handleTemplateRelatedData(responseParameters, productData); - } - - return this.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, productData); - } - - @GET - @Path("template") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveNewDepositProductDetails(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet( - Arrays.asList("currencyOptions", "interestCompoundedEveryPeriodTypeOptions", - "id", "externalId", "name", "description", "createdOn", "lastModifedOn", - "currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance","tenureInMonths", - "maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate", - "interestCompoundedEvery", "interestCompoundedEveryPeriodType", - "renewalAllowed","preClosureAllowed","preClosureInterestRate", - "isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - DepositProductData depositProduct = this.depositProductReadPlatformService.retrieveNewDepositProductDetails(); - - depositProduct = handleTemplateRelatedData(responseParameters, depositProduct); - - return this.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, depositProduct); - } - - private DepositProductData handleTemplateRelatedData( - final Set responseParameters, - final DepositProductData productData) { - - responseParameters.addAll(Arrays.asList("currencyOptions", "interestCompoundedEveryPeriodTypeOptions")); - List allowedCurrencies = this.currencyReadPlatformService.retrieveAllowedCurrencies(); - - EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS); - List interestCompoundedEveryPeriodTypeOptions = Arrays.asList(monthly); - - return new DepositProductData(productData, allowedCurrencies, interestCompoundedEveryPeriodTypeOptions); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingsAccountApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingsAccountApiResource.java deleted file mode 100644 index cf507ceb7..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingsAccountApiResource.java +++ /dev/null @@ -1,147 +0,0 @@ -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.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.QueryParam; -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.SavingAccountCommand; -import org.mifosng.platform.api.data.SavingAccountData; -import org.mifosng.platform.saving.service.SavingAccountReadPlatformService; -import org.mifosng.platform.saving.service.SavingAccountWritePlatformService; -import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; -import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService; -import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -@Path("/savingaccounts") -@Component -@Scope("singleton") -public class SavingsAccountApiResource { - - @Autowired - private SavingAccountWritePlatformService savingAccountWritePlatformService; - - @Autowired - private SavingAccountReadPlatformService savingAccountReadPlatformService; - - @Autowired - private PortfolioApiDataConversionService apiDataConversionService; - - @Autowired - private PortfolioApiJsonSerializerService apiJsonSerializerService; - - private final String entityType = "SAVINGSACCOUNT"; - @Autowired - private PlatformSecurityContext context; - - private static final Set typicalResponseParameters = new HashSet( - Arrays.asList("id", "status", "externalId", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", "savingsFrequencyType", - "totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType", "interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", - "actualCommencementDate", "maturesOnDate", "projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount", "preClosureAllowed", - "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType")); - - @POST - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response createSavingAccount(final String jsonRequestBody){ - - final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(null, jsonRequestBody); - - EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.createSavingAccount(command); - - return Response.ok().entity(entityIdentifier).build(); - } - - @PUT - @Path("{accountId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public Response updateSavingAccount(@PathParam("accountId") final Long accountId,final String jsonRequestBody){ - - final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(accountId, jsonRequestBody); - - EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.updateSavingAccount(command); - - return Response.ok().entity(entityIdentifier).build(); - } - - @GET - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - Collection accounts = this.savingAccountReadPlatformService.retrieveAllSavingsAccounts(); - - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, accounts); - } - - @GET - @Path("{accountId}") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - SavingAccountData account = this.savingAccountReadPlatformService.retrieveSavingsAccount(accountId); - - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); - } - - @SuppressWarnings("unused") - @GET - @Path("template") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveNewDepositAccountDetails( - @QueryParam("clientId") final Long clientId, - @QueryParam("productId") final Long productId, - @Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - SavingAccountData account = null; -// this.savingAccountReadPlatformService.retrieveNewSavingsAccountDetails(clientId, productId); - - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountCommand.java deleted file mode 100644 index 881a205d1..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountCommand.java +++ /dev/null @@ -1,199 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.math.BigDecimal; -import java.util.Set; - -import org.joda.time.LocalDate; - -/** - * Immutable command used when create/renewing deposit accounts - */ -public class DepositAccountCommand { - - private final Long id; - private final Long clientId; - private final Long productId; - private final String externalId; - - private final BigDecimal depositAmount; - private final BigDecimal maturityInterestRate; - private final BigDecimal preClosureInterestRate; - private final Integer tenureInMonths; - - private final boolean isLockinPeriodAllowed; - private final Integer lockinPeriod; - private final Integer lockinPeriodType; - - private final Integer interestCompoundedEvery; - private final Integer interestCompoundedEveryPeriodType; - private final LocalDate commencementDate; - - private final boolean renewalAllowed; - private final boolean preClosureAllowed; - private final boolean isInterestWithdrawable; - private final boolean interestCompoundingAllowed; - - private final Set modifiedParameters; - - public DepositAccountCommand(final Set modifiedParameters, - final Long id, - final Long clientId, - final Long productId, - final String externalId, - final BigDecimal depositAmount, - final BigDecimal interestRate, final BigDecimal preClosureInterestRate, - final Integer tenureInMonths, final Integer compoundingInterestFrequency, final Integer compoundingInterestFrequencyType, final LocalDate commencementDate, - final boolean renewalAllowed, final boolean preClosureAllowed,final boolean isInterstWithdrawable, final boolean interestCompoundingAllowed, - final boolean isLockinPeriodAllowed, final Integer lockInPeriod, final Integer lockinPeriodType) { - this.id = id; - this.clientId = clientId; - this.productId = productId; - this.externalId = externalId; - - this.depositAmount = depositAmount; - this.maturityInterestRate = interestRate; - this.preClosureInterestRate = preClosureInterestRate; - this.tenureInMonths = tenureInMonths; - - this.modifiedParameters = modifiedParameters; - this.interestCompoundedEvery = compoundingInterestFrequency; - this.interestCompoundedEveryPeriodType = compoundingInterestFrequencyType; - this.commencementDate = commencementDate; - this.renewalAllowed = renewalAllowed; - this.preClosureAllowed = preClosureAllowed; - this.isInterestWithdrawable = isInterstWithdrawable; - this.interestCompoundingAllowed = interestCompoundingAllowed; - - this.isLockinPeriodAllowed = isLockinPeriodAllowed; - this.lockinPeriod = lockInPeriod; - this.lockinPeriodType = lockinPeriodType; - } - - public Long getId() { - return id; - } - - public Long getClientId() { - return clientId; - } - - public Long getProductId() { - return productId; - } - - public String getExternalId() { - return externalId; - } - - public BigDecimal getDepositAmount() { - return depositAmount; - } - - public BigDecimal getMaturityInterestRate() { - return maturityInterestRate; - } - - public BigDecimal getPreClosureInterestRate() { - return preClosureInterestRate; - } - - public Integer getTenureInMonths() { - return tenureInMonths; - } - - public Integer getInterestCompoundedEvery() { - return interestCompoundedEvery; - } - - public Integer getInterestCompoundedEveryPeriodType() { - return interestCompoundedEveryPeriodType; - } - - public LocalDate getCommencementDate() { - return commencementDate; - } - - public boolean isInterestWithdrawable() { - return isInterestWithdrawable; - } - - public boolean isRenewalAllowed() { - return renewalAllowed; - } - - public boolean isPreClosureAllowed() { - return preClosureAllowed; - } - - public boolean isInterestCompoundingAllowed() { - return interestCompoundingAllowed; - } - - public boolean isLockinPeriodAllowed() { - return isLockinPeriodAllowed; - } - - public Integer getLockinPeriod() { - return lockinPeriod; - } - - public Integer getLockinPeriodType() { - return lockinPeriodType; - } - - public boolean isNoFieldChanged() { - return this.modifiedParameters.isEmpty(); - } - - public boolean isExternalIdChanged(){ - return this.modifiedParameters.contains("externalId"); - } - - public boolean isDepositAmountChanged(){ - return this.modifiedParameters.contains("deposit"); - } - - public boolean isTenureInMonthsChanged() { - return this.modifiedParameters.contains("tenureInMonths"); - } - - public boolean isLockinPeriodChanged() { - return this.modifiedParameters.contains("lockinPeriod"); - } - - public boolean isMaturityActualInterestRateChanged() { - return this.modifiedParameters.contains("maturityInterestRate"); - } - - public boolean isPreClosureInterestRateChanged(){ - return this.modifiedParameters.contains("preClosureInterestRate"); - } - - public boolean isCompoundingInterestEveryChanged(){ - return this.modifiedParameters.contains("interestCompoundedEvery"); - } - - public boolean isInterestCompoundedEveryPeriodTypeChaged(){ - return this.modifiedParameters.contains("interestCompoundedEveryPeriodType"); - } - - public boolean isRenewalAllowedChanged() { - return this.modifiedParameters.contains("renewalAllowed"); - } - - public boolean isPreClosureAllowedChanged() { - return this.modifiedParameters.contains("preClosureAllowed"); - } - - public boolean isInterestWithdrawableChanged(){ - return this.modifiedParameters.contains("isInterestWithdrawable"); - } - - public boolean isInterestCompoundingAllowedChanged(){ - return this.modifiedParameters.contains("interestCompoundingAllowed"); - } - - public boolean isCommencementDateChanged() { - return this.modifiedParameters.contains("commencementDate"); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawInterestCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawInterestCommand.java deleted file mode 100644 index aebb3002e..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawInterestCommand.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.math.BigDecimal; - -public class DepositAccountWithdrawInterestCommand { - - private final Long accountId; - private final BigDecimal withdrawInterest; - private final String note; - - public DepositAccountWithdrawInterestCommand(final Long accountId, BigDecimal withdrawInterest, String note){ - this.accountId=accountId; - this.withdrawInterest=withdrawInterest; - this.note=note; - } - - public Long getAccountId() { - return accountId; - } - public BigDecimal getWithdrawInterest() { - return withdrawInterest; - } - public String getNote() { - return note; - } -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawalCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawalCommand.java deleted file mode 100644 index ac457c8ce..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositAccountWithdrawalCommand.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.mifosng.platform.api.commands; - -import org.joda.time.LocalDate; - - -public class DepositAccountWithdrawalCommand { - - private final Long accountId; - private final String note; - private final LocalDate maturesOnDate; - - public DepositAccountWithdrawalCommand(final Long accountId, final String note, final LocalDate maturesOnDate) { - this.accountId = accountId; - this.note = note; - this.maturesOnDate=maturesOnDate; - } - - public Long getAccountId() { - return accountId; - } - - public String getNote() { - return note; - } - - public LocalDate getMaturesOnDate() { - return maturesOnDate; - } -} 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 deleted file mode 100644 index 90e87dfb9..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositProductCommand.java +++ /dev/null @@ -1,250 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.math.BigDecimal; -import java.util.Set; - -public class DepositProductCommand { - - private final Long id; - private final String externalId; - 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 tenureInMonths; - private final BigDecimal maturityDefaultInterestRate; - private final BigDecimal maturityMinInterestRate; - private final BigDecimal maturityMaxInterestRate; - private final Integer interestCompoundedEvery; - private final Integer interestCompoundedEveryPeriodType; - private final boolean isLockinPeriodAllowed; - private final Integer lockinPeriod; - private final Integer lockinPeriodType; - - private final boolean renewalAllowed; - private final boolean preClosureAllowed; - private final BigDecimal preClosureInterestRate; - - private final boolean interestCompoundingAllowed; - - private final Set modifiedParameters; - - public DepositProductCommand(final Set modifiedParameters, - final Long id, final String externalId, final String name, final String description, - final String currencyCode, final Integer digitsAfterDecimal, - final BigDecimal minimumBalance, final BigDecimal maximumBalance, - final Integer tenureInMonths, final BigDecimal maturityDefaultInterestRate, - final BigDecimal maturityMinInterestRate, final BigDecimal maturityMaxInterestRate, - final Integer interestCompoundedEvery, - final Integer interestCompoundedEveryPeriodType, - final boolean renewalAllowed, final boolean preClosureAllowed, - final BigDecimal preClosureInterestRate, final boolean interestCompoundingAllowed, - final boolean isLockinPeriodAllowed,final Integer lockinPeriod,final Integer lockinPeriodType ) { - this.id = id; - this.externalId = externalId; - this.name = name; - this.description = description; - - this.currencyCode = currencyCode; - this.digitsAfterDecimal = digitsAfterDecimal; - - this.minimumBalance=minimumBalance; - this.maximumBalance=maximumBalance; - - this.tenureInMonths=tenureInMonths; - this.maturityDefaultInterestRate = maturityDefaultInterestRate; - this.maturityMinInterestRate = maturityMinInterestRate; - this.maturityMaxInterestRate = maturityMaxInterestRate; - this.interestCompoundedEvery = interestCompoundedEvery; - this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; - this.preClosureInterestRate = preClosureInterestRate; - - this.renewalAllowed = renewalAllowed; - this.preClosureAllowed = preClosureAllowed; - this.interestCompoundingAllowed = interestCompoundingAllowed; - - this.isLockinPeriodAllowed = isLockinPeriodAllowed; - this.lockinPeriod = lockinPeriod; - this.lockinPeriodType = lockinPeriodType; - - this.modifiedParameters = modifiedParameters; - - } - - public Long getId() { - return id; - } - - public String getExternalId() { - return externalId; - } - - 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 getTenureInMonths() { - return tenureInMonths; - } - - public BigDecimal getMaturityDefaultInterestRate() { - return maturityDefaultInterestRate; - } - - public BigDecimal getMaturityMinInterestRate() { - return maturityMinInterestRate; - } - - public BigDecimal getMaturityMaxInterestRate() { - return maturityMaxInterestRate; - } - - public Integer getInterestCompoundedEvery() { - return interestCompoundedEvery; - } - - public Integer getInterestCompoundedEveryPeriodType() { - return interestCompoundedEveryPeriodType; - } - - public boolean isRenewalAllowed() { - return renewalAllowed; - } - - public boolean isPreClosureAllowed() { - return preClosureAllowed; - } - - public BigDecimal getPreClosureInterestRate() { - return preClosureInterestRate; - } - - public boolean isInterestCompoundingAllowed() { - return interestCompoundingAllowed; - } - - public boolean isLockinPeriodAllowed() { - return isLockinPeriodAllowed; - } - - public Integer getLockinPeriod() { - return lockinPeriod; - } - - public Integer getLockinPeriodType() { - return lockinPeriodType; - } - - public boolean isExternalIdChanged() { - return this.modifiedParameters.contains("externalId"); - } - - 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 isInterestCompoundedEveryChanged() { - return this.modifiedParameters.contains("interestCompoundedEvery"); - } - - public boolean isInterestCompoundedEveryPeriodTypeChanged() { - return this.modifiedParameters.contains("interestCompoundedEveryPeriodType"); - } - - public boolean isRenewalAllowedChanged() { - return this.modifiedParameters.contains("renewalAllowed"); - } - - public boolean isPreClosureAllowedChanged() { - return this.modifiedParameters.contains("preClosureAllowed"); - } - - public boolean isPreClosureInterestRateChanged() { - return this.modifiedParameters.contains("preClosureInterestRate"); - } - - public boolean isNoFieldChanged() { - return this.modifiedParameters.isEmpty(); - } - - public boolean interestCompoundingAllowedChanged(){ - return this.modifiedParameters.contains("interestCompoundingAllowed"); - } - - public boolean isLockinPeriodAllowedChanged() { - return this.modifiedParameters.contains("isLockinPeriodAllowed"); - } - - public boolean isLockinPeriodChanged() { - return this.modifiedParameters.contains("lockinPeriod"); - } - - public boolean isLockinPeriodTypeChanged() { - return this.modifiedParameters.contains("lockinPeriodType"); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositStateTransitionApprovalCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositStateTransitionApprovalCommand.java deleted file mode 100644 index cac856837..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositStateTransitionApprovalCommand.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.math.BigDecimal; - -import org.joda.time.LocalDate; - -public class DepositStateTransitionApprovalCommand { - - private final Long accountId; - private final Long productId; - private final LocalDate eventDate; - private final BigDecimal depositAmount; - private final BigDecimal maturityInterestRate; - private final Integer tenureInMonths; - private final Integer interestCompoundedEveryPeriodType; - private final Integer interestCompoundedEvery; - - private final String note; - - public DepositStateTransitionApprovalCommand(final Long resourceIdentifier,final Long productId,final LocalDate eventDate,final Integer tenureInMonths, - final BigDecimal depositAmount,final Integer interestCompoundedEveryPeriodType,final Integer interestCompoundedEvery,final String note,final BigDecimal maturityInterestRate) { - - this.accountId=resourceIdentifier; - this.eventDate=eventDate; - this.depositAmount=depositAmount; - this.maturityInterestRate=maturityInterestRate; - this.tenureInMonths=tenureInMonths; - this.interestCompoundedEveryPeriodType=interestCompoundedEveryPeriodType; - this.productId=productId; - this.interestCompoundedEvery=interestCompoundedEvery; - - this.note = note; - - } - - public Long getAccountId() { - return accountId; - } - - public LocalDate getEventDate() { - return eventDate; - } - - public BigDecimal getDepositAmount() { - return depositAmount; - } - - public BigDecimal getMaturityInterestRate() { - return maturityInterestRate; - } - - public Integer getTenureInMonths() { - return tenureInMonths; - } - - public Integer getInterestCompoundedEveryPeriodType() { - return interestCompoundedEveryPeriodType; - } - - public Long getProductId() { - return productId; - } - - public Integer getInterestCompoundedEvery() { - return interestCompoundedEvery; - } - - public String getNote() { - return note; - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositStateTransitionCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositStateTransitionCommand.java deleted file mode 100644 index a9d985870..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/DepositStateTransitionCommand.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.mifosng.platform.api.commands; - -import org.joda.time.LocalDate; - -public class DepositStateTransitionCommand { - - private final Long accountId; - private final LocalDate eventDate; - - private final String note; - - public DepositStateTransitionCommand(final Long accountId, final LocalDate enentDate, final String note) { - this.accountId=accountId; - this.eventDate=enentDate; - this.note = note; - } - - public Long getAccountId() { - return accountId; - } - - public LocalDate getEventDate() { - return eventDate; - } - - public String getNote() { - return note; - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SavingAccountCommand.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SavingAccountCommand.java deleted file mode 100644 index e72b3943e..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SavingAccountCommand.java +++ /dev/null @@ -1,235 +0,0 @@ -package org.mifosng.platform.api.commands; - -import java.math.BigDecimal; -import java.util.Set; - -import org.joda.time.LocalDate; - -public class SavingAccountCommand { - - - private final Long id; - private final Long clientId; - private final Long productId; - private final String externalId; - - private final String currencyCode; - private final Integer digitsAfterDecimal; - private final BigDecimal savingsDepositAmount; - private final BigDecimal recurringInterestRate; - private final BigDecimal savingInterestRate; - private final Integer tenure; - - private final boolean isLockinPeriodAllowed; - private final Integer lockinPeriod; - private final Integer lockinPeriodType; - - private final LocalDate commencementDate; - private final Integer savingProductType; - private final Integer tenureType; - private final Integer frequency; - private final Integer interestType; - - private final Integer interestCalculationMethod; - private final BigDecimal minimumBalanceForWithdrawal; - private final boolean isPartialDepositAllowed; - - private final Set modifiedParameters; - - public SavingAccountCommand(final Set modifiedParameters, - final Long id, - final Long clientId, - final Long productId, - final String externalId,final String currencyCode, final Integer digitsAfterDecimal, - final BigDecimal savingsDepositAmount, - final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate, - final Integer tenure, final LocalDate commencementDate, - final Integer savingProductType, final Integer tenureType, final Integer frequency, final Integer interestType, - final BigDecimal minimumBalanceForWithdrawal, final Integer interestCalculationMethod, - final boolean isLockinPeriodAllowed, final boolean isPartialDepositAllowed, final Integer lockInPeriod, final Integer lockinPeriodType) { - this.id = id; - this.clientId = clientId; - this.productId = productId; - this.externalId = externalId; - - this.currencyCode = currencyCode; - this.digitsAfterDecimal = digitsAfterDecimal; - this.savingsDepositAmount = savingsDepositAmount; - this.recurringInterestRate = recurringInterestRate; - this.savingInterestRate = savingInterestRate; - this.tenure = tenure; - - this.modifiedParameters = modifiedParameters; - this.commencementDate = commencementDate; - - this.savingProductType=savingProductType; - this.tenureType=tenureType; - this.frequency=frequency; - this.interestType=interestType; - this.isPartialDepositAllowed=isPartialDepositAllowed; - - - this.isLockinPeriodAllowed = isLockinPeriodAllowed; - this.lockinPeriod = lockInPeriod; - this.lockinPeriodType = lockinPeriodType; - this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal; - this.interestCalculationMethod=interestCalculationMethod; - } - - public Long getId() { - return id; - } - - public Long getClientId() { - return clientId; - } - - public Long getProductId() { - return productId; - } - - public String getExternalId() { - return externalId; - } - - public String getCurrencyCode() { - return currencyCode; - } - - public Integer getDigitsAfterDecimal() { - return digitsAfterDecimal; - } - - public BigDecimal getSavingsDepositAmount() { - return savingsDepositAmount; - } - - public BigDecimal getRecurringInterestRate() { - return recurringInterestRate; - } - - public BigDecimal getSavingInterestRate() { - return savingInterestRate; - } - - public Integer getTenure() { - return tenure; - } - - public boolean isLockinPeriodAllowed() { - return isLockinPeriodAllowed; - } - - public Integer getLockinPeriod() { - return lockinPeriod; - } - - public Integer getLockinPeriodType() { - return lockinPeriodType; - } - - public LocalDate getCommencementDate() { - return commencementDate; - } - - public Integer getSavingProductType() { - return savingProductType; - } - - public Integer getTenureType() { - return tenureType; - } - - public Integer getFrequency() { - return frequency; - } - - public Integer getInterestType() { - return interestType; - } - - public Integer getInterestCalculationMethod() { - return interestCalculationMethod; - } - - public BigDecimal getMinimumBalanceForWithdrawal() { - return minimumBalanceForWithdrawal; - } - - public boolean isPartialDepositAllowed() { - return isPartialDepositAllowed; - } - - public boolean isNoFieldChanged() { - return this.modifiedParameters.isEmpty(); - } - - public boolean isProductIdChanged(){ - return this.modifiedParameters.contains("productId"); - } - - public boolean isExternalIdChanged(){ - return this.modifiedParameters.contains("externalId"); - } - - public boolean isDepositAmountChanged(){ - return this.modifiedParameters.contains("deposit"); - } - - public boolean isTenureInMonthsChanged() { - return this.modifiedParameters.contains("tenureInMonths"); - } - - public boolean isLockinPeriodChanged() { - return this.modifiedParameters.contains("lockinPeriod"); - } - - public boolean isPreClosureInterestRateChanged(){ - return this.modifiedParameters.contains("preClosureInterestRate"); - } - - public boolean isPreClosureAllowedChanged() { - return this.modifiedParameters.contains("preClosureAllowed"); - } - - public boolean isCommencementDateChanged() { - return this.modifiedParameters.contains("commencementDate"); - } - - public boolean isTenureTypeEnumChanged() { - return this.modifiedParameters.contains("tenureType"); - } - - public boolean isSavingProductTypeChanged() { - return this.modifiedParameters.contains("savingProductType"); - } - - public boolean isSavingFrequencyTypeChanged() { - return this.modifiedParameters.contains("frequency"); - } - - public boolean isSavingInterestCalculationMethodChanged() { - return this.modifiedParameters.contains("interestCalculationMethod"); - } - - public boolean isReccuringInterestRateChanged() { - return this.modifiedParameters.contains("recurringInterestRate"); - } - - public boolean isSavingInterestRateChanged() { - return this.modifiedParameters.contains("savingInterestRate"); - } - - public boolean isLockinPeriodAllowedChanged() { - return this.modifiedParameters.contains("isLockinPeriodAllowed"); - } - - public boolean isLockinPeriodTypeChanged() { - return this.modifiedParameters.contains("lockinPeriodType"); - } - - public boolean isPartialDepositAllowedChanged() { - return this.modifiedParameters.contains("isPartialDepositAllowed"); - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountData.java deleted file mode 100644 index b84824500..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountData.java +++ /dev/null @@ -1,567 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.joda.time.Days; -import org.joda.time.LocalDate; -import org.joda.time.Months; -import org.mifosplatform.infrastructure.configuration.data.CurrencyData; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; - -/** - * Immutable data object for deposit accounts. - */ -public class DepositAccountData { - - private final Long id; - private final String externalId; - private final EnumOptionData status; - private final Long clientId; - private final String clientName; - private final Long productId; - private final String productName; - - private final CurrencyData currency; - private final BigDecimal deposit; - private final BigDecimal maturityInterestRate; - - private final Integer tenureInMonths; - private final LocalDate projectedCommencementDate; - private final LocalDate actualCommencementDate; - private final LocalDate maturedOn; - private final LocalDate withdrawnonDate; - private final LocalDate rejectedonDate; - private final LocalDate closedonDate; - private final BigDecimal projectedInterestAccrued; - private final BigDecimal actualInterestAccrued; - private final BigDecimal projectedMaturityAmount; - private final BigDecimal actualMaturityAmount; - - private final Integer interestCompoundedEvery; - private final EnumOptionData interestCompoundedEveryPeriodType; - private final boolean renewalAllowed; - private final boolean preClosureAllowed; - private final BigDecimal preClosureInterestRate; - - private final boolean isInterestWithdrawable; - private final BigDecimal interestPaid; - private final boolean interestCompoundingAllowed; - - private final List interestCompoundedEveryPeriodTypeOptions; - private final List productOptions; - - private final Collection transactions; - private final DepositPermissionData permissions; - private final BigDecimal availableInterestForWithdrawal; - private final BigDecimal availableWithdrawalAmount; - private final LocalDate todaysDate; - - private final boolean isLockinPeriodAllowed; - private final Integer lockinPeriod; - private final EnumOptionData lockinPeriodType; - - /* - * used when returning account template data but only a clientId is passed, no selected product. - */ - public static DepositAccountData createFrom(final Long clientId, final String clientDisplayName) { - return new DepositAccountData(clientId, clientDisplayName); - } - - private DepositAccountData( - final Long clientId, - final String clientName) { - this.id=null; - this.externalId = null; - this.status = null; - this.clientId = clientId; - this.clientName = clientName; - this.productId = null; - this.productName = null; - this.currency = null; - this.deposit = null; - this.maturityInterestRate=null; - this.tenureInMonths = null; - this.projectedCommencementDate = null; - this.actualCommencementDate = null; - this.maturedOn = null; - this.projectedInterestAccrued = null; - this.actualInterestAccrued = null; - this.projectedMaturityAmount = null; - this.actualMaturityAmount = null; - this.interestCompoundedEvery = null; - this.interestCompoundedEveryPeriodType = null; - this.renewalAllowed = false; - this.preClosureAllowed = false; - this.preClosureInterestRate = null; - - this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); - this.productOptions = new ArrayList(); - - this.withdrawnonDate=null; - this.closedonDate=null; - this.rejectedonDate=null; - - this.transactions=null; - this.permissions=null; - - this.interestPaid=null; - this.isInterestWithdrawable=false; - this.interestCompoundingAllowed = true; - this.availableInterestForWithdrawal = new BigDecimal(0); - this.availableWithdrawalAmount= new BigDecimal(0); - this.todaysDate = new LocalDate(); - - this.isLockinPeriodAllowed =true; - this.lockinPeriod = null; - this.lockinPeriodType = null; - } - - public DepositAccountData( - final DepositAccountData account, - final List interestCompoundedEveryPeriodTypeOptions, - final Collection productOptions) { - this.id = account.getId(); - this.externalId = account.getExternalId(); - this.status = account.getStatus(); - this.clientId = account.getClientId(); - this.clientName = account.getClientName(); - this.productId = account.getProductId(); - this.productName = account.getProductName(); - this.currency = account.getCurrency(); - this.deposit = account.getDeposit(); - this.maturityInterestRate = account.getMaturityInterestRate(); - this.tenureInMonths = account.getTenureInMonths(); - this.projectedCommencementDate = account.getProjectedCommencementDate(); - this.actualCommencementDate = account.getActualCommencementDate(); - this.maturedOn = account.getMaturedOn(); - this.projectedInterestAccrued = account.getProjectedInterestAccrued(); - this.actualInterestAccrued = account.getActualInterestAccrued(); - this.projectedMaturityAmount = account.getProjectedMaturityAmount(); - this.actualMaturityAmount = account.getActualMaturityAmount(); - this.interestCompoundedEvery = account.getInterestCompoundedEvery(); - this.interestCompoundedEveryPeriodType = account.getInterestCompoundedEveryPeriodType(); - this.renewalAllowed = account.isRenewalAllowed(); - this.preClosureAllowed = account.isPreClosureAllowed(); - this.preClosureInterestRate = account.getPreClosureInterestRate(); - - this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions; - this.productOptions = new ArrayList(productOptions); - - this.withdrawnonDate=account.getWithdrawnonDate(); - this.rejectedonDate=account.getRejectedonDate(); - this.closedonDate=account.getClosedonDate(); - - this.transactions=account.getTransactions(); - this.permissions=account.getPermissions(); - this.interestPaid=account.getInterestPaid(); - this.isInterestWithdrawable=account.isInterestWithdrawable(); - this.interestCompoundingAllowed=account.isInterestCompoundingAllowed(); - this.availableInterestForWithdrawal=determineAvailableInterestForWithdrawal(account); - this.availableWithdrawalAmount=determineAvalableWithdrawalAmount(account); - this.todaysDate = new LocalDate(); - - this.lockinPeriod = account.getLockinPeriod(); - this.lockinPeriodType = account.getLockinPeriodType(); - this.isLockinPeriodAllowed = account.isLockinPeriodAllowed(); - } - - public DepositAccountData(final DepositAccountData account, final DepositPermissionData permissions, final Collection transactions) { - this.id = account.getId(); - this.externalId = account.getExternalId(); - this.status = account.getStatus(); - this.clientId = account.getClientId(); - this.clientName = account.getClientName(); - this.productId = account.getProductId(); - this.productName = account.getProductName(); - this.currency = account.getCurrency(); - this.deposit = account.getDeposit(); - this.maturityInterestRate = account.getMaturityInterestRate(); - this.tenureInMonths = account.getTenureInMonths(); - this.projectedCommencementDate = account.getProjectedCommencementDate(); - this.actualCommencementDate = account.getActualCommencementDate(); - this.maturedOn = account.getMaturedOn(); - this.projectedInterestAccrued = account.getProjectedInterestAccrued(); - this.actualInterestAccrued = account.getActualInterestAccrued(); - this.projectedMaturityAmount = account.getProjectedMaturityAmount(); - this.actualMaturityAmount = account.getActualMaturityAmount(); - this.interestCompoundedEvery = account.getInterestCompoundedEvery(); - this.interestCompoundedEveryPeriodType = account.getInterestCompoundedEveryPeriodType(); - this.renewalAllowed = account.isRenewalAllowed(); - this.preClosureAllowed = account.isPreClosureAllowed(); - this.preClosureInterestRate = account.getPreClosureInterestRate(); - - this.interestCompoundedEveryPeriodTypeOptions = account.getInterestCompoundedEveryPeriodTypeOptions(); - this.productOptions = account.getProductOptions(); - - this.withdrawnonDate=account.getWithdrawnonDate(); - this.rejectedonDate=account.getRejectedonDate(); - this.closedonDate=account.getClosedonDate(); - - this.transactions=transactions; - this.permissions=permissions; - this.interestPaid=account.getInterestPaid(); - this.isInterestWithdrawable=account.isInterestWithdrawable(); - this.interestCompoundingAllowed = account.isInterestCompoundingAllowed(); - this.availableInterestForWithdrawal=determineAvailableInterestForWithdrawal(account); - this.availableWithdrawalAmount=determineAvalableWithdrawalAmount(account); - this.todaysDate = new LocalDate(); - - this.lockinPeriod = account.getLockinPeriod(); - this.lockinPeriodType = account.getLockinPeriodType(); - this.isLockinPeriodAllowed = account.isLockinPeriodAllowed(); - } - - public DepositAccountData( - final Long id, - final String externalId, - final EnumOptionData status, - final Long clientId, - final String clientName, - final Long productId, - final String productName, - final CurrencyData currency, - final BigDecimal deposit, final BigDecimal interestRate, - final Integer tenureInMonths, - final LocalDate projectedCommencementDate, - final LocalDate actualCommencementDate, - final LocalDate maturedOn, - final BigDecimal projectedInterestAccrued, - final BigDecimal actualInterestAccrued, - final BigDecimal projectedMaturityAmount, - final BigDecimal actualMaturityAmount, - final Integer interestCompoundedEvery, - final EnumOptionData interestCompoundedEveryPeriodType, - final boolean renewalAllowed, - final boolean preClosureAllowed, - final BigDecimal preClosureInterestRate, - final LocalDate withdrawnonDate, - final LocalDate rejectedonDate, - final LocalDate closedonDate, - final boolean isInterestWithdrawable, - final BigDecimal interestPaid, - final boolean interestCompoundingAllowed, - final boolean isLockinPeriodAllowed, - final Integer lockinPeriod, - final EnumOptionData lockinPeriodType) { - this.id=id; - this.externalId = externalId; - this.status = status; - this.clientId = clientId; - this.clientName = clientName; - this.productId = productId; - this.productName = productName; - this.currency = currency; - this.deposit = deposit; - this.maturityInterestRate=interestRate; - this.tenureInMonths = tenureInMonths; - this.projectedCommencementDate = projectedCommencementDate; - this.actualCommencementDate = actualCommencementDate; - this.maturedOn = maturedOn; - this.projectedInterestAccrued = projectedInterestAccrued; - this.actualInterestAccrued = actualInterestAccrued; - this.projectedMaturityAmount = projectedMaturityAmount; - this.actualMaturityAmount = actualMaturityAmount; - this.interestCompoundedEvery = interestCompoundedEvery; - this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; - this.renewalAllowed = renewalAllowed; - this.preClosureAllowed = preClosureAllowed; - this.preClosureInterestRate = preClosureInterestRate; - - this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); - this.productOptions = new ArrayList(); - - this.withdrawnonDate = withdrawnonDate; - this.rejectedonDate = rejectedonDate; - this.closedonDate = closedonDate; - - this.transactions = null; - this.permissions = null; - - this.interestPaid =interestPaid; - this.isInterestWithdrawable=isInterestWithdrawable; - this.interestCompoundingAllowed = interestCompoundingAllowed; - this.availableInterestForWithdrawal = BigDecimal.ZERO; - this.availableWithdrawalAmount = BigDecimal.ZERO; - this.todaysDate = new LocalDate(); - - this.isLockinPeriodAllowed = isLockinPeriodAllowed; - this.lockinPeriod =lockinPeriod; - this.lockinPeriodType = lockinPeriodType; - } - - public DepositAccountData( - final Long clientId, - final String clientName, - final Long productId, - final String productName, - final CurrencyData currency, - final BigDecimal deposit, final BigDecimal interestRate, - final Integer tenureInMonths, - final Integer interestCompoundedEvery, - final EnumOptionData interestCompoundedEveryPeriodType, - final boolean renewalAllowed, - final boolean preClosureAllowed, - final BigDecimal preClosureInterestRate, - final boolean interestCompoundingAllowed) { - this.id=null; - this.externalId = null; - this.status = null; - this.clientId = clientId; - this.clientName = clientName; - this.productId = productId; - this.productName = productName; - this.currency = currency; - this.deposit = deposit; - this.maturityInterestRate=interestRate; - this.tenureInMonths = tenureInMonths; - this.projectedCommencementDate = new LocalDate(); - this.actualCommencementDate = null; - this.maturedOn = null; - this.projectedInterestAccrued = null; - this.actualInterestAccrued = null; - this.projectedMaturityAmount = null; - this.actualMaturityAmount = null; - this.interestCompoundedEvery = interestCompoundedEvery; - this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; - this.renewalAllowed = renewalAllowed; - this.preClosureAllowed = preClosureAllowed; - this.preClosureInterestRate = preClosureInterestRate; - - this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); - this.productOptions = new ArrayList(); - - this.withdrawnonDate=null; - this.closedonDate=null; - this.rejectedonDate=null; - - this.transactions = null; - this.permissions = null; - this.interestPaid=null; - this.isInterestWithdrawable=false; - this.interestCompoundingAllowed=interestCompoundingAllowed; - this.availableInterestForWithdrawal= BigDecimal.ZERO; - this.availableWithdrawalAmount = BigDecimal.ZERO; - this.todaysDate = new LocalDate(); - - //need to update in constructor's call method and update it - this.lockinPeriod = Integer.valueOf(0); - this.isLockinPeriodAllowed =true; - this.lockinPeriodType = interestCompoundedEveryPeriodType; - } - - public Long getId() { - return id; - } - - public String getExternalId() { - return externalId; - } - - public EnumOptionData getStatus() { - return status; - } - - public Long getClientId() { - return clientId; - } - - public String getClientName() { - return clientName; - } - - public Long getProductId() { - return productId; - } - - public String getProductName() { - return productName; - } - - public CurrencyData getCurrency() { - return currency; - } - - public BigDecimal getDeposit() { - return deposit; - } - - public BigDecimal getMaturityInterestRate() { - return maturityInterestRate; - } - - public Integer getTenureInMonths() { - return tenureInMonths; - } - - public LocalDate getProjectedCommencementDate() { - return projectedCommencementDate; - } - - public LocalDate getActualCommencementDate() { - return actualCommencementDate; - } - - public LocalDate getMaturedOn() { - return maturedOn; - } - - public BigDecimal getProjectedInterestAccrued() { - return projectedInterestAccrued; - } - - public BigDecimal getActualInterestAccrued() { - return actualInterestAccrued; - } - - public BigDecimal getProjectedMaturityAmount() { - return projectedMaturityAmount; - } - - public BigDecimal getActualMaturityAmount() { - return actualMaturityAmount; - } - - public Integer getInterestCompoundedEvery() { - return interestCompoundedEvery; - } - - public EnumOptionData getInterestCompoundedEveryPeriodType() { - return interestCompoundedEveryPeriodType; - } - - public boolean isRenewalAllowed() { - return renewalAllowed; - } - - public boolean isPreClosureAllowed() { - return preClosureAllowed; - } - - public BigDecimal getPreClosureInterestRate() { - return preClosureInterestRate; - } - - public List getInterestCompoundedEveryPeriodTypeOptions() { - return interestCompoundedEveryPeriodTypeOptions; - } - - public List getProductOptions() { - return productOptions; - } - - public LocalDate getWithdrawnonDate() { - return withdrawnonDate; - } - - public LocalDate getRejectedonDate() { - return rejectedonDate; - } - - public LocalDate getClosedonDate() { - return closedonDate; - } - - public Collection getTransactions() { - return transactions; - } - - public DepositPermissionData getPermissions() { - return permissions; - } - - public boolean isInterestWithdrawable() { - return isInterestWithdrawable; - } - - public BigDecimal getInterestPaid() { - return interestPaid; - } - - public boolean isInterestCompoundingAllowed() { - return interestCompoundingAllowed; - } - - public BigDecimal getAvailableInterestForWithdrawal() { - return availableInterestForWithdrawal; - } - - public BigDecimal getAvailableWithdrawalAmount() { - return availableWithdrawalAmount; - } - - public LocalDate getTodaysDate() { - return todaysDate; - } - - public boolean isLockinPeriodAllowed() { - return isLockinPeriodAllowed; - } - - public Integer getLockinPeriod() { - return lockinPeriod; - } - - public EnumOptionData getLockinPeriodType() { - return lockinPeriodType; - } - - private BigDecimal determineAvailableInterestForWithdrawal(final DepositAccountData account) { - BigDecimal availableInterestForWithdrawal = BigDecimal.ZERO; - - if(this.status!=null){ - if (account.getStatus().getId() == 300) { - BigDecimal interestGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue()/ new Double(account.getTenureInMonths())); - LocalDate interestWithdrawingDate= new LocalDate().isBefore(getMaturedOn())?new LocalDate():getMaturedOn().plusDays(1); - Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate).getMonths(); - Integer noOfPeriods = noOfMonthsforInterestCal/ account.getInterestCompoundedEvery(); - - availableInterestForWithdrawal = BigDecimal.valueOf(interestGettingForPeriod.multiply(new BigDecimal(noOfPeriods)).doubleValue()- account.getInterestPaid().doubleValue()); - }else { - return BigDecimal.ZERO; - } - }else return BigDecimal.ZERO; - - return availableInterestForWithdrawal; - } - - private BigDecimal determineAvalableWithdrawalAmount(final DepositAccountData account) { - - BigDecimal avalablePreclosureWithdrawalAmount = BigDecimal.ZERO; - if(this.status != null){ - if (account.getStatus().getId() == 300) { - if(new LocalDate().isBefore(account.getMaturedOn()) || new LocalDate().isEqual(account.getMaturedOn())){ - MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); - Integer monthsInYear = 12; - BigDecimal interestRateAsFraction = account.getPreClosureInterestRate().divide(BigDecimal.valueOf(100), mc); - BigDecimal interestRateForOneMonth = interestRateAsFraction.divide(BigDecimal.valueOf(monthsInYear.doubleValue()), mc); - Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()).getMonths(); - Integer days = Days.daysBetween(account.getActualCommencementDate().plusMonths(noOfMonthsforInterestCal), new LocalDate()).getDays(); - BigDecimal interest = BigDecimal.valueOf(account.getDeposit().doubleValue()*new Double(noOfMonthsforInterestCal)*interestRateForOneMonth.doubleValue()); - avalablePreclosureWithdrawalAmount = interest.add(account.getDeposit()).subtract(account.getInterestPaid()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days)); - }else if(new LocalDate().isAfter(account.getMaturedOn())){ - Integer days = Days.daysBetween(account.getMaturedOn(), new LocalDate()).getDays(); - avalablePreclosureWithdrawalAmount=determineAvailableInterestForWithdrawal(account).add(account.getDeposit()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days)); - } - }else{ - avalablePreclosureWithdrawalAmount=account.getDeposit(); - } - } - return avalablePreclosureWithdrawalAmount; - } - - private BigDecimal determineRemainInerestAmount(final BigDecimal depsoitAmount, final BigDecimal interstRateApplicable, final Integer days){ - - MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); - Integer daysInYear = 365; - BigDecimal interestRateAsFraction = interstRateApplicable.divide(BigDecimal.valueOf(100), mc); - BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc); - return BigDecimal.valueOf(depsoitAmount.doubleValue()*days.doubleValue()*interestRateForOneDay.doubleValue()); - - } - -} \ No newline at end of file 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 deleted file mode 100644 index 043ccd806..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductData.java +++ /dev/null @@ -1,271 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; - -import org.joda.time.DateTime; -import org.mifosplatform.infrastructure.configuration.data.CurrencyData; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; - -/** - * Immutable data object representing details of a deposit product. - */ -public class DepositProductData { - - private final Long id; - private final String externalId; - 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 tenureInMonths; - private final BigDecimal maturityDefaultInterestRate; - private final BigDecimal maturityMinInterestRate; - private final BigDecimal maturityMaxInterestRate; - private final Integer interestCompoundedEvery; - private final EnumOptionData interestCompoundedEveryPeriodType; - - private final boolean renewalAllowed; - private final boolean preClosureAllowed; - private final BigDecimal preClosureInterestRate; - private final boolean interestCompoundingAllowed; - - private final boolean isLockinPeriodAllowed; - private final Integer lockinPeriod; - private final EnumOptionData lockinPeriodType; - - private final DateTime createdOn; - private final DateTime lastModifedOn; - - private final List currencyOptions; - private final List interestCompoundedEveryPeriodTypeOptions; - - public DepositProductData( - final DateTime createdOn, - final DateTime lastModifedOn, - final Long id, - final String externalId, - 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 Integer interestCompoundedEvery, - final EnumOptionData interestCompoundedEveryPeriodType, - final boolean renewalAllowed, - final boolean preClosureAllowed, - final BigDecimal preClosureInterestRate, - final boolean interestCompoundingAllowed, - final boolean isLockinPeriodAllowed, - final Integer lockinPeriod, - final EnumOptionData lockinPeriodType) { - - this.createdOn=createdOn; - this.lastModifedOn=lastModifedOn; - this.id=id; - this.externalId = externalId; - this.name=name; - this.description=description; - this.currencyCode=currencyCode; - this.digitsAfterDecimal=digitsAfterDecimal; - this.minimumBalance=minimumBalance; - this.maximumBalance=maximumBalance; - - this.tenureInMonths=tenureMonths; - this.maturityDefaultInterestRate = maturityDefaultInterestRate; - this.maturityMinInterestRate=maturityMinInterestRate; - this.maturityMaxInterestRate=maturityMaxInterestRate; - this.interestCompoundedEvery = interestCompoundedEvery; - this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; - this.renewalAllowed=renewalAllowed; - this.preClosureAllowed=preClosureAllowed; - this.preClosureInterestRate=preClosureInterestRate; - this.interestCompoundingAllowed=interestCompoundingAllowed; - - this.lockinPeriod=lockinPeriod; - this.lockinPeriodType=lockinPeriodType; - this.isLockinPeriodAllowed=isLockinPeriodAllowed; - - this.currencyOptions = new ArrayList(); - this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); - } - - public DepositProductData( - final List currencyOptions, - final EnumOptionData defaultInterestCompoundedEveryPeriodType, - final List interestCompoundedEveryPeriodTypeOptions) { - this.createdOn=null; - this.lastModifedOn=null; - this.id=null; - this.externalId = null; - this.name=null; - this.description=null; - this.currencyCode=null; - this.digitsAfterDecimal=Integer.valueOf(0); - this.minimumBalance=BigDecimal.ZERO; - this.maximumBalance=BigDecimal.ZERO; - - this.tenureInMonths=Integer.valueOf(0); - this.maturityDefaultInterestRate = BigDecimal.ZERO; - this.maturityMinInterestRate=BigDecimal.ZERO; - this.maturityMaxInterestRate=BigDecimal.ZERO; - this.interestCompoundedEvery = Integer.valueOf(1); - this.interestCompoundedEveryPeriodType = defaultInterestCompoundedEveryPeriodType; - - this.renewalAllowed=true; - this.preClosureAllowed=true; - this.preClosureInterestRate=BigDecimal.ZERO; - this.interestCompoundingAllowed=true; - - this.isLockinPeriodAllowed=true; - this.lockinPeriod=Integer.valueOf(0); - this.lockinPeriodType=defaultInterestCompoundedEveryPeriodType; - - this.currencyOptions = currencyOptions; - this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions; - } - - public DepositProductData( - final DepositProductData product, - final List currencyOptions, - final List interestCompoundedEveryPeriodTypeOptions) { - this.createdOn=product.getCreatedOn(); - this.lastModifedOn=product.getLastModifedOn(); - this.id=product.getId(); - this.externalId = product.getExternalId(); - this.name=product.getName(); - this.description=product.getDescription(); - this.currencyCode=product.getCurrencyCode(); - this.digitsAfterDecimal=product.getDigitsAfterDecimal(); - this.minimumBalance=product.getMinimumBalance(); - this.maximumBalance=product.getMaximumBalance(); - - this.tenureInMonths=product.getTenureInMonths(); - this.maturityDefaultInterestRate = product.getMaturityDefaultInterestRate(); - this.maturityMinInterestRate=product.getMaturityMinInterestRate(); - this.maturityMaxInterestRate=product.getMaturityMaxInterestRate(); - this.interestCompoundedEvery = product.getInterestCompoundedEvery(); - this.interestCompoundedEveryPeriodType = product.getInterestCompoundedEveryPeriodType(); - - this.renewalAllowed=product.isRenewalAllowed(); - this.preClosureAllowed=product.isPreClosureAllowed(); - this.preClosureInterestRate=product.getPreClosureInterestRate(); - this.interestCompoundingAllowed=product.isInterestCompoundingAllowed(); - - this.lockinPeriod=product.getLockinPeriod(); - this.lockinPeriodType=product.getLockinPeriodType(); - this.isLockinPeriodAllowed=product.isLockinPeriodAllowed(); - - this.currencyOptions = currencyOptions; - this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions; - } - - public Long getId() { - return id; - } - - public String getExternalId() { - return externalId; - } - - 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 getTenureInMonths() { - return tenureInMonths; - } - - public BigDecimal getMaturityDefaultInterestRate() { - return maturityDefaultInterestRate; - } - - public BigDecimal getMaturityMinInterestRate() { - return maturityMinInterestRate; - } - - public BigDecimal getMaturityMaxInterestRate() { - return maturityMaxInterestRate; - } - - public Integer getInterestCompoundedEvery() { - return interestCompoundedEvery; - } - - public EnumOptionData getInterestCompoundedEveryPeriodType() { - return interestCompoundedEveryPeriodType; - } - - public boolean isRenewalAllowed() { - return renewalAllowed; - } - - public boolean isPreClosureAllowed() { - return preClosureAllowed; - } - - public BigDecimal getPreClosureInterestRate() { - return preClosureInterestRate; - } - - public DateTime getCreatedOn() { - return createdOn; - } - - public DateTime getLastModifedOn() { - return lastModifedOn; - } - - public List getCurrencyOptions() { - return currencyOptions; - } - - public List getInterestCompoundedEveryPeriodTypeOptions() { - return interestCompoundedEveryPeriodTypeOptions; - } - - public boolean isInterestCompoundingAllowed() { - return interestCompoundingAllowed; - } - - public boolean isLockinPeriodAllowed() { - return isLockinPeriodAllowed; - } - - public Integer getLockinPeriod() { - return lockinPeriod; - } - - public EnumOptionData getLockinPeriodType() { - return lockinPeriodType; - } - -} \ No newline at end of file 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 deleted file mode 100644 index e0be0c382..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositProductLookup.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.mifosng.platform.api.data; - -public class DepositProductLookup { - - private final Long id; - private final String name; - - public DepositProductLookup(final Long id, final String name) { - this.id = id; - this.name = name; - } - - public Long getId() { - return id; - } - - public String getName() { - return name; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingAccountData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingAccountData.java deleted file mode 100644 index c7cda59ac..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingAccountData.java +++ /dev/null @@ -1,134 +0,0 @@ -package org.mifosng.platform.api.data; - -import java.math.BigDecimal; - -import org.joda.time.LocalDate; -import org.mifosplatform.infrastructure.configuration.data.CurrencyData; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; - -/** - * Immutable data object reprsenting a savings account. - */ -public class SavingAccountData { - - @SuppressWarnings("unused") - private final Long id; - @SuppressWarnings("unused") - private final EnumOptionData status; - @SuppressWarnings("unused") - private final String externalId; - @SuppressWarnings("unused") - private final Long clientId; - @SuppressWarnings("unused") - private final String clientName; - @SuppressWarnings("unused") - private final Long productId; - @SuppressWarnings("unused") - private final String productName; - @SuppressWarnings("unused") - private final EnumOptionData productType; - @SuppressWarnings("unused") - private final CurrencyData currencyData; - @SuppressWarnings("unused") - private final BigDecimal savingsDepostiAmountPerPeriod; - @SuppressWarnings("unused") - private final EnumOptionData savingsFrequencyType; - @SuppressWarnings("unused") - private final BigDecimal totalDepositAmount; - @SuppressWarnings("unused") - private final BigDecimal reccuringInterestRate; - @SuppressWarnings("unused") - private final BigDecimal savingInterestRate; - @SuppressWarnings("unused") - private final EnumOptionData interestType; - @SuppressWarnings("unused") - private final EnumOptionData interestCalculationMethod; - @SuppressWarnings("unused") - private final Integer tenure; - @SuppressWarnings("unused") - private final EnumOptionData tenureType; - @SuppressWarnings("unused") - private final LocalDate projectedCommencementDate; - @SuppressWarnings("unused") - private final LocalDate actualCommencementDate; - @SuppressWarnings("unused") - private final LocalDate maturesOnDate; - @SuppressWarnings("unused") - private final BigDecimal projectedInterestAccuredOnMaturity; - @SuppressWarnings("unused") - private final BigDecimal actualInterestAccured; - @SuppressWarnings("unused") - private final BigDecimal projectedMaturityAmount; - @SuppressWarnings("unused") - private final BigDecimal actualMaturityAmount; - @SuppressWarnings("unused") - private final boolean preClosureAllowed; - @SuppressWarnings("unused") - private final BigDecimal preClosureInterestRate; - @SuppressWarnings("unused") - private final LocalDate withdrawnonDate; - @SuppressWarnings("unused") - private final LocalDate rejectedonDate; - @SuppressWarnings("unused") - private final LocalDate closedonDate; - @SuppressWarnings("unused") - private final boolean isLockinPeriodAllowed; - @SuppressWarnings("unused") - private final Integer lockinPeriod; - @SuppressWarnings("unused") - private final EnumOptionData lockinPeriodType; - - public SavingAccountData(Long id, EnumOptionData status, String externalId, - Long clientId, String clientName, Long productId, - String productName, EnumOptionData productType, - CurrencyData currencyData, - BigDecimal savingsDepostiAmountPerPeriod, - EnumOptionData savingsFrequencyType, BigDecimal totalDepositAmount, - BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, - EnumOptionData interestType, - EnumOptionData interestCalculationMethod, Integer tenure, - EnumOptionData tenureType, LocalDate projectedCommencementDate, - LocalDate actualCommencementDate, LocalDate maturesOnDate, - BigDecimal projectedInterestAccuredOnMaturity, - BigDecimal actualInterestAccured, - BigDecimal projectedMaturityAmount, - BigDecimal actualMaturityAmount, boolean preClosureAllowed, - BigDecimal preClosureInterestRate, LocalDate withdrawnonDate, - LocalDate rejectedonDate, LocalDate closedonDate, - boolean isLockinPeriodAllowed, Integer lockinPeriod, - EnumOptionData lockinPeriodType) { - this.id = id; - this.status = status; - this.externalId = externalId; - this.clientId = clientId; - this.clientName = clientName; - this.productId = productId; - this.productName = productName; - this.productType = productType; - this.currencyData = currencyData; - this.savingsDepostiAmountPerPeriod = savingsDepostiAmountPerPeriod; - this.savingsFrequencyType = savingsFrequencyType; - this.totalDepositAmount = totalDepositAmount; - this.reccuringInterestRate = reccuringInterestRate; - this.savingInterestRate = savingInterestRate; - this.interestType =interestType; - this.interestCalculationMethod = interestCalculationMethod; - this.tenure = tenure; - this.tenureType = tenureType; - this.projectedCommencementDate = projectedCommencementDate; - this.actualCommencementDate = actualCommencementDate; - this.maturesOnDate = maturesOnDate; - this.projectedInterestAccuredOnMaturity = projectedInterestAccuredOnMaturity; - this.actualInterestAccured = actualInterestAccured; - this.projectedMaturityAmount = projectedMaturityAmount; - this.actualMaturityAmount =actualMaturityAmount; - this.preClosureAllowed = preClosureAllowed; - this.preClosureInterestRate = preClosureInterestRate; - this.withdrawnonDate = withdrawnonDate; - this.rejectedonDate = rejectedonDate; - this.closedonDate = closedonDate; - this.isLockinPeriodAllowed = isLockinPeriodAllowed; - this.lockinPeriod = lockinPeriod; - this.lockinPeriodType = lockinPeriodType; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/InvalidDepositStateTransitionException.java b/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/InvalidDepositStateTransitionException.java deleted file mode 100644 index bd71a5bc6..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/InvalidDepositStateTransitionException.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.mifosng.platform.exceptions; - -import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; - -public class InvalidDepositStateTransitionException extends - AbstractPlatformDomainRuleException { - - public InvalidDepositStateTransitionException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) { - super("error.msg.deposit." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs); - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/ReccuringDepositInterestCalculator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/ReccuringDepositInterestCalculator.java deleted file mode 100644 index adae614a5..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/ReccuringDepositInterestCalculator.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.mifosng.platform.saving.domain; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; - -import org.joda.time.LocalDate; -import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; -import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; -import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; -import org.mifosplatform.infrastructure.configuration.domain.Money; -import org.springframework.stereotype.Service; - -@Service -public class ReccuringDepositInterestCalculator { - - // FIXME - MADHUKAR - Are the unused field here needed? - public Money calculateInterestOnMaturityFor(Money savingsDepositPerPeriod, - Integer tenure, BigDecimal reccuringInterestRate, - LocalDate commencementDate, TenureTypeEnum tenureTypeEnum, - SavingFrequencyType savingFrequencyType, - SavingInterestCalculationMethod savingInterestCalculationMethod) { - - /* - // Assuming tenure in months - // see http://www.onemint.com/2012/04/03/how-to-calculate-interest-on-recurring-deposits/ - - A=P(1+r/n)^nt - - A = final amount - P = principal amount (initial investment) - r = annual nominal interest rate (as a decimal, not in percentage) - n = number of times the interest is compounded per year - t = number of years - - */ - MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); - Integer monthsInYear = 12; - - BigDecimal interestRateAsFraction = reccuringInterestRate.divide(BigDecimal.valueOf(100), mc); - Integer noofTimesInterestCompoundPerYear = Integer.valueOf(0); - switch (savingFrequencyType) { - case MONTHLY: - noofTimesInterestCompoundPerYear = monthsInYear; - break; - case QUATERLY: - noofTimesInterestCompoundPerYear = monthsInYear/3; - break; - case HALFYEARLY: - noofTimesInterestCompoundPerYear = monthsInYear/6; - break; - case YEARLY: - noofTimesInterestCompoundPerYear = monthsInYear/12; - break; - default: - throw new RuntimeException("The specified frequency not supported"); - - } - - BigDecimal interestRatePerPeriod = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/noofTimesInterestCompoundPerYear.doubleValue()); - BigDecimal onePlusInterestRatePerPeriod = BigDecimal.ONE.add(interestRatePerPeriod); - BigDecimal monthsExpressedInYears; - BigDecimal timeforOneCalculationPeriod; - BigDecimal amountPerPeriod; - BigDecimal finalAmount = BigDecimal.ZERO; - while (tenure > 0) { - monthsExpressedInYears = BigDecimal.valueOf(tenure.doubleValue()/monthsInYear.doubleValue()); - timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear*monthsExpressedInYears.doubleValue()); - amountPerPeriod = savingsDepositPerPeriod.getAmount().multiply(BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(), timeforOneCalculationPeriod.doubleValue()))); - finalAmount=finalAmount.add(amountPerPeriod); - tenure--; - } - - return Money.of(savingsDepositPerPeriod.getCurrency(), finalAmount); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccount.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccount.java deleted file mode 100644 index 3f0f84d83..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccount.java +++ /dev/null @@ -1,359 +0,0 @@ -package org.mifosng.platform.saving.domain; - -import java.math.BigDecimal; -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.persistence.UniqueConstraint; - -import org.joda.time.LocalDate; -import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; -import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; -import org.mifosng.platform.savingproduct.domain.SavingProduct; -import org.mifosng.platform.savingproduct.domain.SavingProductType; -import org.mifosng.platform.savingproduct.domain.SavingsInterestType; -import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; -import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; -import org.mifosplatform.infrastructure.configuration.domain.Money; -import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; -import org.mifosplatform.infrastructure.user.domain.AppUser; -import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; - -@Entity -@Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name="saving_acc_external_id", columnNames = { "external_id" })) -public class SavingAccount extends AbstractAuditableCustom { - - @ManyToOne - @JoinColumn(name = "client_id", nullable = false) - private Client client; - - @ManyToOne - @JoinColumn(name = "product_id") - private SavingProduct product; - - // FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; - @Column(name = "savings_product_type", nullable=false) - private SavingProductType savingProductType; - - @Column(name = "external_id") - private String externalId; - - @SuppressWarnings("unused") - @Embedded - private MonetaryCurrency currency; - - @Column(name = "deposit_amount_per_period", scale = 6, precision = 19, nullable = false) - private BigDecimal savingsDepositAmountPerPeriod; - - @SuppressWarnings("unused") - @Column(name = "total_deposit_amount", scale = 6, precision = 19, nullable = false) - private BigDecimal totalSavingsAmount; - - @Column(name = "reccuring_nominal_interest_rate", scale = 6, precision = 19, nullable = false) - private BigDecimal reccuringInterestRate; - - @Column(name = "regular_saving_nominal_interest_rate", scale = 6, precision = 19, nullable = false) - private BigDecimal savingInterestRate; - - @Column(name = "tenure", nullable=false) - private Integer tenure; - - @Column(name = "tenure_type", nullable=false) - private TenureTypeEnum tenureType; - - // FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; - @Column(name = "frequency", nullable=false) - private SavingFrequencyType frequency; - - // FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; - @Column(name = "interest_type", nullable=false) - private SavingsInterestType interestType; - - // FIXME - MADHUKAR - Do not use the actual enum type here but instead use Integer e.g. private Integer savingProductType; - @Column(name = "interest_calculation_method") - private SavingInterestCalculationMethod interestCalculationMethod; - - @Temporal(TemporalType.DATE) - @Column(name = "projected_commencement_date") - private Date projectedCommencementDate; - - @SuppressWarnings("unused") - @Temporal(TemporalType.DATE) - @Column(name = "actual_commencement_date") - private Date actualCommencementDate; - - @SuppressWarnings("unused") - @Temporal(TemporalType.DATE) - @Column(name = "matures_on_date") - private Date maturesOnDate; - - @SuppressWarnings("unused") - @Column(name = "projected_interest_accrued_on_maturity", scale = 6, precision = 19, nullable = false) - private BigDecimal projectedInterestAccruedOnMaturity; - - @SuppressWarnings("unused") - @Column(name = "actual_interest_accrued", scale = 6, precision = 19, nullable = false) - private BigDecimal interestAccrued; - - @SuppressWarnings("unused") - @Column(name = "projected_total_maturity_amount", scale = 6, precision = 19, nullable = false) - private BigDecimal projectedTotalOnMaturity; - - @SuppressWarnings("unused") - @Column(name = "actual_total_amount", scale = 6, precision = 19, nullable = false) - private BigDecimal total; - - @Column(name = "pre_closure_interest_rate", scale = 6, precision = 19, nullable = false) - private BigDecimal preClosureInterestRate; - - @Column(name = "is_preclosure_allowed", nullable = false) - private boolean preClosureAllowed = false; - - @Column(name = "is_deleted", nullable=false) - private boolean deleted = false; - - @Column(name = "status_enum", nullable = false) - private Integer accountStatus; - - @SuppressWarnings("unused") - @Temporal(TemporalType.DATE) - @Column(name = "closedon_date") - private Date closedOnDate; - - @SuppressWarnings("unused") - @Temporal(TemporalType.DATE) - @Column(name = "rejectedon_date") - private Date rejectedOnDate; - - @Temporal(TemporalType.DATE) - @Column(name = "withdrawnon_date") - private Date withdrawnOnDate; - - @Column(name = "is_lock_in_period_allowed", nullable=false) - private boolean isLockinPeriodAllowed = false; - - @Column(name = "lock_in_period", nullable=false) - private Integer lockinPeriod; - - @Column(name = "lock_in_period_type", nullable=false) - private PeriodFrequencyType lockinPeriodType; - - public static SavingAccount openNew( - Client client, - SavingProduct product, - String externalId, - Money savingsDeposit, - BigDecimal reccuringInterestRate, - BigDecimal savingInterestRate, - Integer tenure, - LocalDate commencementDate, - TenureTypeEnum tenureTypeEnum, - SavingProductType savingProductType, - SavingFrequencyType savingFrequencyType, - SavingsInterestType interestType, - SavingInterestCalculationMethod savingInterestCalculationMethod, - boolean isLockinPeriodAllowed, - Integer lockinPeriod, - PeriodFrequencyType lockinPeriodType, - ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, - final DepositLifecycleStateMachine lifecycleStateMachine) { - - Money futureValueOnMaturity = null; - if(savingProductType.isReccuring()){ - futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, reccuringInterestRate, - commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); - } else if(savingProductType.isRegular()){ - futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, savingInterestRate, - commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); - } - - return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, - commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, interestType, savingInterestCalculationMethod, - isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine); - } - - public SavingAccount(Client client, String externalId, - SavingProduct product, Money savingsDeposit, - BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, - Integer tenure, LocalDate commencementDate, - TenureTypeEnum tenureTypeEnum, - SavingProductType savingProductType, - SavingFrequencyType savingFrequencyType, SavingsInterestType interestType, - SavingInterestCalculationMethod savingInterestCalculationMethod, - boolean isLockinPeriodAllowed, Integer lockinPeriod, - PeriodFrequencyType lockinPeriodType, Money futureValueOnMaturity, - final DepositLifecycleStateMachine lifecycleStateMachine) { - - DepositAccountStatus from = null; - if (accountStatus != null) { - from = DepositAccountStatus.fromInt(accountStatus); - } - - DepositAccountStatus statusEnum = lifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CREATED, from); - accountStatus = statusEnum.getValue(); - - this.total=BigDecimal.ZERO; - this.preClosureInterestRate=BigDecimal.ZERO; - this.totalSavingsAmount = BigDecimal.ZERO; - this.interestAccrued = BigDecimal.ZERO; - - this.client = client; - this.externalId = externalId; - this.product = product; - this.savingsDepositAmountPerPeriod = savingsDeposit.getAmount(); - this.currency = savingsDeposit.getCurrency(); - this.reccuringInterestRate = reccuringInterestRate; - this.savingInterestRate = savingInterestRate; - this.tenure =tenure; - this.projectedCommencementDate=commencementDate.toDate(); - this.tenureType = tenureTypeEnum; - this.savingProductType = savingProductType; - this.frequency = savingFrequencyType; - this.interestType = interestType; - this.interestCalculationMethod= savingInterestCalculationMethod; - this.isLockinPeriodAllowed = isLockinPeriodAllowed; - this.lockinPeriod = lockinPeriod; - this.lockinPeriodType = lockinPeriodType; - this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); - this.projectedInterestAccruedOnMaturity =futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue()*tenure.doubleValue())); - } - - public void modifyAccount( - SavingProduct product, - String externalId, - Money savingsDeposit, - BigDecimal reccuringInterestRate, - BigDecimal savingInterestRate, - Integer tenure, - LocalDate commencementDate, - TenureTypeEnum tenureTypeEnum, - SavingProductType savingProductType, - SavingFrequencyType savingFrequencyType, - SavingInterestCalculationMethod savingInterestCalculationMethod, - boolean isLockinPeriodAllowed, - Integer lockinPeriod, - PeriodFrequencyType lockinPeriodType, - ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) { - - - Money futureValueOnMaturity = null; - if(savingProductType.isReccuring()){ - futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, reccuringInterestRate, - commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); - } else if(savingProductType.isRegular()){ - futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, savingInterestRate, - commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); - } - - this.product = product; - this.externalId=externalId; - this.savingsDepositAmountPerPeriod=savingsDeposit.getAmount(); - this.reccuringInterestRate=reccuringInterestRate; - this.savingInterestRate = savingInterestRate; - this.tenure = tenure; - this.projectedCommencementDate = commencementDate.toDate(); - this.tenureType = tenureTypeEnum; - this.savingProductType = savingProductType; - this.frequency =savingFrequencyType; - this.interestCalculationMethod = savingInterestCalculationMethod; - this.isLockinPeriodAllowed = isLockinPeriodAllowed; - this.lockinPeriod = lockinPeriod; - this.lockinPeriodType = lockinPeriodType; - - // FIXME - MADHUKAR - futureValueOnMaturity is possibly null - this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); - this.projectedInterestAccruedOnMaturity =futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue()*tenure.doubleValue())); - } - - public boolean isDeleted() { - return this.deleted; - } - - public boolean isPendingApproval() { - return this.accountStatus.equals(100); - } - - public Client getClient() { - return client; - } - - public SavingProduct getProduct() { - return product; - } - - public SavingProductType getSavingProductType() { - return savingProductType; - } - - public String getExternalId() { - return externalId; - } - - public BigDecimal getSavingsDepositAmountPerPeriod() { - return savingsDepositAmountPerPeriod; - } - - public BigDecimal getReccuringInterestRate() { - return reccuringInterestRate; - } - - public BigDecimal getSavingInterestRate() { - return savingInterestRate; - } - - public Integer getTenure() { - return tenure; - } - - public TenureTypeEnum getTenureType() { - return tenureType; - } - - public SavingFrequencyType getFrequency() { - return frequency; - } - - public SavingsInterestType getInterestType() { - return interestType; - } - - public SavingInterestCalculationMethod getInterestCalculationMethod() { - return interestCalculationMethod; - } - - public Date getProjectedCommencementDate() { - return projectedCommencementDate; - } - - public BigDecimal getPreClosureInterestRate() { - return preClosureInterestRate; - } - - public boolean isPreClosureAllowed() { - return preClosureAllowed; - } - - public Date getWithdrawnOnDate() { - return withdrawnOnDate; - } - - public boolean isLockinPeriodAllowed() { - return isLockinPeriodAllowed; - } - - public Integer getLockinPeriod() { - return lockinPeriod; - } - - public PeriodFrequencyType getLockinPeriodType() { - return lockinPeriodType; - } -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountCommandValidator.java deleted file mode 100644 index d9d36be5a..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountCommandValidator.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.api.commands.DepositAccountCommand; -import org.mifosplatform.infrastructure.core.data.ApiParameterError; -import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; -import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; - -public class DepositAccountCommandValidator { - - private final DepositAccountCommand command; - - public DepositAccountCommandValidator(final DepositAccountCommand command) { - this.command=command; - } - - public void validateForUpdate() { - - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); - - baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); - baseDataValidator.reset().parameter("clientId").value(command.getClientId()).ignoreIfNull().notNull(); - baseDataValidator.reset().parameter("productId").value(command.getProductId()).ignoreIfNull().notNull(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); - - baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().notNull().integerGreaterThanZero(); - - baseDataValidator.reset().parameter("interestCompoundedEvery").value(command.getInterestCompoundedEvery()).ignoreIfNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2); - baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull(); - - if (command.isNoFieldChanged()) { - StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append("deposit.account").append(".no.parameters.for.update"); - StringBuilder defaultEnglishMessage = new StringBuilder("No parameters passed for update."); - ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), "id"); - dataValidationErrors.add(error); - } - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } - - public void validateForCreate() { - - List dataValidationErrors = new ArrayList(); - - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); - - baseDataValidator.reset().parameter("clientId").value(command.getClientId()).notNull(); - baseDataValidator.reset().parameter("productId").value(command.getProductId()).notNull(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); - - baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero(); - - baseDataValidator.reset().parameter("interestCompoundedEvery").value(command.getInterestCompoundedEvery()).ignoreIfNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2); - baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).notNull(); - - if (!dataValidationErrors.isEmpty()) { - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformService.java deleted file mode 100644 index f3e33d1a3..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformService.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.math.BigDecimal; -import java.util.Collection; - -import org.mifosng.platform.api.data.DepositAccountData; -import org.mifosng.platform.api.data.DepositPermissionData; - -public interface DepositAccountReadPlatformService { - - Collection retrieveAllDepositAccounts(); - - DepositAccountData retrieveDepositAccount(Long accountId); - - DepositAccountData retrieveNewDepositAccountDetails(Long clientId, Long productId); - - DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData); - - BigDecimal retrieveAvailableInterestForWithdrawal(DepositAccountData account); -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java deleted file mode 100644 index 0d25f400d..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountReadPlatformServiceImpl.java +++ /dev/null @@ -1,267 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.math.BigDecimal; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; - -import org.joda.time.LocalDate; -import org.joda.time.Months; -import org.mifosng.platform.api.data.DepositAccountData; -import org.mifosng.platform.api.data.DepositAccountTransactionData; -import org.mifosng.platform.api.data.DepositPermissionData; -import org.mifosng.platform.api.data.DepositProductData; -import org.mifosng.platform.api.data.DepositProductLookup; -import org.mifosng.platform.savingproduct.service.DepositProductReadPlatformService; -import org.mifosng.platform.savingproduct.service.SavingsDepositEnumerations; -import org.mifosplatform.infrastructure.configuration.data.CurrencyData; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; -import org.mifosplatform.infrastructure.core.domain.JdbcSupport; -import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.client.data.ClientData; -import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; -import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -@Service -public class DepositAccountReadPlatformServiceImpl implements DepositAccountReadPlatformService { - - private final PlatformSecurityContext context; - private final JdbcTemplate jdbcTemplate; - private final DepositProductReadPlatformService depositProductReadPlatformService; - private final ClientReadPlatformService clientReadPlatformService; - - @Autowired - public DepositAccountReadPlatformServiceImpl(final PlatformSecurityContext context,final TenantAwareRoutingDataSource dataSource, final DepositProductReadPlatformService depositProductReadPlatformService,final ClientReadPlatformService clientReadPlatformService) { - this.context=context; - jdbcTemplate=new JdbcTemplate(dataSource); - this.depositProductReadPlatformService=depositProductReadPlatformService; - this.clientReadPlatformService=clientReadPlatformService; - } - - @Override - public Collection retrieveAllDepositAccounts() { - - this.context.authenticatedUser(); - - DepositAccountMapper mapper = new DepositAccountMapper(); - - String sql = "select " + mapper.schema() + " where da.is_deleted=0"; - - return this.jdbcTemplate.query(sql,mapper, new Object[]{}); - } - - @Override - public DepositAccountData retrieveDepositAccount(final Long accountId) { - try{ - DepositAccountMapper mapper = new DepositAccountMapper(); - - String sql = "select " + mapper.schema() + " where da.id = ? and da.is_deleted=0"; - - DepositAccountData depositAccountData = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { accountId }); - - // FIXME - kw - the call to find transactions for deposit account to add to the deposit account payload can be decided at the api level - // depending on whether the requester wants them or not instead of always getting the transactions - DepositAccountTransactionMapper transactionMapper = new DepositAccountTransactionMapper(); - String transactionSchema = "select " + transactionMapper.schema() + " where txn.deposit_account_id = ? "; - - Collection depositAccountTransactions = this.jdbcTemplate.query(transactionSchema, transactionMapper, new Object[]{accountId}); - if (!depositAccountTransactions.isEmpty()) { - DepositPermissionData permissions = null; - depositAccountData = new DepositAccountData(depositAccountData, permissions, depositAccountTransactions); - } - - return depositAccountData; - } catch (EmptyResultDataAccessException e) { - throw new LoanProductNotFoundException(accountId); - } - } - - @Override - public DepositAccountData retrieveNewDepositAccountDetails(final Long clientId, final Long productId) { - - context.authenticatedUser(); - - ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId); - - DepositAccountData accountData = null; - - Collection depositProducts = this.depositProductReadPlatformService.retrieveAllDepositProductsForLookup(); - - if (productId != null) { - DepositProductData selectedProduct = findDepositProductById(depositProducts,productId); - - CurrencyData currency = new CurrencyData(selectedProduct.getCurrencyCode(), "", selectedProduct.getDigitsAfterDecimal(), "", ""); - - accountData = new DepositAccountData( - clientAccount.id(), clientAccount.displayName(), selectedProduct.getId(), selectedProduct.getName(), - currency, selectedProduct.getMinimumBalance(), selectedProduct.getMaturityDefaultInterestRate(), - selectedProduct.getTenureInMonths(), selectedProduct.getInterestCompoundedEvery(), selectedProduct.getInterestCompoundedEveryPeriodType(), - selectedProduct.isRenewalAllowed(), selectedProduct.isPreClosureAllowed(), - selectedProduct.getPreClosureInterestRate(),selectedProduct.isInterestCompoundingAllowed()); - } else { - accountData = DepositAccountData.createFrom(clientAccount.id(), clientAccount.displayName()); - } - - return accountData; - } - - private DepositProductData findDepositProductById( - final Collection depositProducts, - final Long productId) { - DepositProductData match= this.depositProductReadPlatformService.retrieveNewDepositProductDetails(); - for(DepositProductLookup depositProductLookup : depositProducts){ - if (depositProductLookup.getId().equals(productId)) { - match=this.depositProductReadPlatformService.retrieveDepositProductData(depositProductLookup.getId()); - break; - } - } - return match; - } - - private static final class DepositAccountMapper implements RowMapper { - - public String schema() { - return "da.id as id, da.external_id as externalId, da.client_id as clientId, da.product_id as productId, " - + " da.currency_code as currencyCode, da.currency_digits as currencyDigits, " - + " da.deposit_amount as depositAmount, da.status_enum as statusId, " - + " da.maturity_nominal_interest_rate as interestRate, da.tenure_months as termInMonths, da.projected_commencement_date as projectedCommencementDate," - + " da.actual_commencement_date as actualCommencementDate, da.matures_on_date as maturedOn," - + " da.projected_interest_accrued_on_maturity as projectedInterestAccrued, da.actual_interest_accrued as actualInterestAccrued, " - + " da.projected_total_maturity_amount as projectedMaturityAmount, da.actual_total_amount as actualMaturityAmount, " - + " da.interest_compounded_every as interestCompoundedEvery, da.interest_compounded_every_period_enum as interestCompoundedEveryPeriodType, " - + " da.is_renewal_allowed as renewalAllowed, da.is_preclosure_allowed as preClosureAllowed, da.pre_closure_interest_rate as preClosureInterestRate, " - + " da.withdrawnon_date as withdrawnonDate, da.rejectedon_date as rejectedonDate, da.closedon_date as closedonDate, " - + " da.interest_paid as interestPaid, da.is_interest_withdrawable as isInterestWithdrawable, da.is_compounding_interest_allowed as interestCompoundingAllowed, " - + " da.is_lock_in_period_allowed as isLockinPeriodAllowed, da.lock_in_period as lockinPeriod, da.lock_in_period_type lockinPeriodType, " - + " c.firstname as firstname, c.lastname as lastname, pd.name as productName," - + " curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol " - + " from m_deposit_account da " - + " join m_currency curr on curr.code = da.currency_code " - + " join m_client c on c.id = da.client_id " - + " join m_product_deposit pd on pd.id = da.product_id"; - } - - @Override - public DepositAccountData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) - throws SQLException { - - Long id = rs.getLong("id"); - String externalId = rs.getString("externalId"); - Long clientId = rs.getLong("clientId"); - String clientName = rs.getString("firstname") + " " + rs.getString("lastname"); - Long productId = rs.getLong("productId"); - String productName = rs.getString("productName"); - - Integer statusId = JdbcSupport.getInteger(rs, "statusId"); - EnumOptionData status = DepositAccountEnumerations.status(statusId); - - String currencyCode = rs.getString("currencyCode"); - String currencyName = rs.getString("currencyName"); - String currencyNameCode = rs.getString("currencyNameCode"); - String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); - Integer currencyDigits = JdbcSupport.getInteger(rs,"currencyDigits"); - CurrencyData currencyData = new CurrencyData(currencyCode,currencyName, currencyDigits, currencyDisplaySymbol,currencyNameCode); - - BigDecimal depositAmount = rs.getBigDecimal("depositAmount"); - BigDecimal interestRate = rs.getBigDecimal("interestRate"); - - Integer termInMonths = JdbcSupport.getInteger(rs,"termInMonths"); - - LocalDate projectedCommencementDate = JdbcSupport.getLocalDate(rs, "projectedCommencementDate"); - LocalDate actualCommencementDate = JdbcSupport.getLocalDate(rs, "actualCommencementDate"); - LocalDate maturedOn = JdbcSupport.getLocalDate(rs, "maturedOn"); - BigDecimal projectedInterestAccrued = rs.getBigDecimal("projectedInterestAccrued"); - BigDecimal actualInterestAccrued = rs.getBigDecimal("actualInterestAccrued"); - - BigDecimal projectedMaturityAmount = rs.getBigDecimal("projectedMaturityAmount"); - BigDecimal actualMaturityAmount = rs.getBigDecimal("actualMaturityAmount"); - - Integer interestCompoundedEvery = JdbcSupport.getInteger(rs, "interestCompoundedEvery"); - Integer interestCompoundedEveryPeriodTypeValue = JdbcSupport.getInteger(rs, "interestCompoundedEveryPeriodType"); - EnumOptionData interestCompoundedEveryPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(interestCompoundedEveryPeriodTypeValue); - - boolean renewalAllowed = rs.getBoolean("renewalAllowed"); - boolean preClosureAllowed = rs.getBoolean("preClosureAllowed"); - boolean interestCompoundingAllowed = rs.getBoolean("interestCompoundingAllowed"); - - BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate"); - - LocalDate withdrawnonDate = JdbcSupport.getLocalDate(rs, "withdrawnonDate"); - LocalDate rejectedonDate = JdbcSupport.getLocalDate(rs, "rejectedonDate"); - LocalDate closedonDate = JdbcSupport.getLocalDate(rs, "closedonDate"); - - boolean isInterestWithdrawable = rs.getBoolean("isInterestWithdrawable"); - BigDecimal interestPaid = rs.getBigDecimal("interestPaid"); - - boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed"); - Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod"); - Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType"); - EnumOptionData lockinPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(lockinPeriodTypeValue); - - return new DepositAccountData(id, externalId, status, clientId, clientName, productId, productName, currencyData, depositAmount, - interestRate, termInMonths, projectedCommencementDate, actualCommencementDate, maturedOn, - projectedInterestAccrued, actualInterestAccrued, projectedMaturityAmount, actualMaturityAmount, - interestCompoundedEvery, interestCompoundedEveryPeriodType, - renewalAllowed, preClosureAllowed, preClosureInterestRate, - withdrawnonDate,rejectedonDate,closedonDate,isInterestWithdrawable,interestPaid,interestCompoundingAllowed, - isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); - } - } - - private static final class DepositAccountTransactionMapper implements RowMapper{ - - public String schema() { - return " txn.id as transactionId, txn.deposit_account_id as accountId, txn.transaction_type_enum as transactionType, txn.transaction_date as transactionDate, txn.amount as transactionAmount, txn.interest as interestAmount " - + " from m_deposit_account_transaction txn"; - } - - @Override - public DepositAccountTransactionData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) - throws SQLException { - - Long transactionId = rs.getLong("transactionId"); - Long accountId = rs.getLong("accountId"); - Integer transactionTypeValue = JdbcSupport.getInteger(rs, "transactionType"); - EnumOptionData transactionType=DepositAccountTransactionEnumerations.depositType(transactionTypeValue); - LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate"); - BigDecimal transactionAmount = rs.getBigDecimal("transactionAmount"); - BigDecimal interestAmount = rs.getBigDecimal("interestAmount"); - BigDecimal total = transactionAmount.add(interestAmount); - - return new DepositAccountTransactionData(transactionId, accountId, transactionType, transactionDate, transactionAmount, interestAmount, total); - } - - } - - @Override - public DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData) { - boolean pendingApproval = (depositAccountData.getStatus().getId().equals(100L)); - boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L)); - boolean renewelAllowed = false; - if(depositAccountData.getMaturedOn()!=null){ - if(new LocalDate().isAfter(depositAccountData.getMaturedOn())/*||depositAccountData.getMaturedOn().isEqual(new LocalDate())*/){ - renewelAllowed = depositAccountData.isRenewalAllowed(); - } - } - boolean rejectAllowed = pendingApproval; - boolean withdrawnByApplicantAllowed = pendingApproval; - boolean interestWithdrawAllowed = depositAccountData.isInterestWithdrawable(); - boolean isMaturedDepositAccount = (depositAccountData.getStatus().getId().equals(700L)); - - return new DepositPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval, interestWithdrawAllowed, renewelAllowed, isMaturedDepositAccount); - } - - @Override - public BigDecimal retrieveAvailableInterestForWithdrawal(DepositAccountData account) { - BigDecimal interstGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue()/new Double(account.getTenureInMonths())); - Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()).getMonths(); - Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery(); - return BigDecimal.valueOf(interstGettingForPeriod.multiply(new BigDecimal(noOfPeriods)).doubleValue()-account.getInterestPaid().doubleValue()); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWithdrawalCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWithdrawalCommandValidator.java deleted file mode 100644 index 4613917d3..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWithdrawalCommandValidator.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; -import org.mifosplatform.infrastructure.core.data.ApiParameterError; -import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; -import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; - -public class DepositAccountWithdrawalCommandValidator { - - private final DepositAccountWithdrawalCommand command; - public DepositAccountWithdrawalCommandValidator(final DepositAccountWithdrawalCommand command) { - this.command=command; - } - - public void validate(){ - List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transaction"); - - baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); - - 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/saving/service/DepositAccountWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformService.java deleted file mode 100644 index d22cdf19e..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformService.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.mifosng.platform.saving.service; - -import org.mifosng.platform.api.commands.DepositAccountCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionCommand; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface DepositAccountWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_DEPOSITACCOUNT')") - EntityIdentifier createDepositAccount(DepositAccountCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_DEPOSITACCOUNT')") - EntityIdentifier updateDepositAccount(DepositAccountCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_DEPOSITACCOUNT')") - EntityIdentifier deleteDepositAccount(Long productId); - - // NOTE - took out permissions relating to doing things with deposit - // accounts in the past as doesn't appear to be code for it - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'APPROVE_DEPOSITACCOUNT')") - EntityIdentifier approveDepositApplication( - DepositStateTransitionApprovalCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'REJECT_DEPOSITACCOUNT')") - EntityIdentifier rejectDepositApplication( - DepositStateTransitionCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'WITHDRAW_DEPOSITACCOUNT')") - EntityIdentifier withdrawDepositApplication( - DepositStateTransitionCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'APPROVALUNDO_DEPOSITACCOUNT')") - EntityIdentifier undoDepositApproval(UndoStateTransitionCommand undoCommand); - - /* - * @PreAuthorize(value = - * "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', '')" - * ) EntityIdentifier matureDepositApplication(DepositStateTransitionCommand - * command); - */ - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'WITHDRAWAL_DEPOSITACCOUNT')") - EntityIdentifier withdrawDepositAccountMoney(DepositAccountWithdrawalCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'INTEREST_DEPOSITACCOUNT')") - EntityIdentifier withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'RENEW_DEPOSITACCOUNT')") - EntityIdentifier renewDepositAccount(DepositAccountCommand command); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 93b37081f..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,422 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.joda.time.LocalDate; -import org.joda.time.Months; -import org.mifosng.platform.api.commands.DepositAccountCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionCommand; -import org.mifosng.platform.exceptions.DepositAccountNotFoundException; -import org.mifosng.platform.exceptions.DepositAccountReopenException; -import org.mifosng.platform.exceptions.DepositAccountTransactionsException; -import org.mifosng.platform.exceptions.SavingsProductNotFoundException; -import org.mifosng.platform.saving.domain.DepositAccount; -import org.mifosng.platform.saving.domain.DepositAccountRepository; -import org.mifosng.platform.saving.domain.DepositAccountStatus; -import org.mifosng.platform.saving.domain.DepositLifecycleStateMachine; -import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl; -import org.mifosng.platform.saving.domain.FixedTermDepositInterestCalculator; -import org.mifosplatform.infrastructure.configuration.domain.Money; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.client.domain.Note; -import org.mifosplatform.portfolio.client.domain.NoteRepository; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements DepositAccountWritePlatformService { - - private final static Logger logger = LoggerFactory.getLogger(DepositAccountWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final DepositAccountRepository depositAccountRepository; - private final DepositAccountAssembler depositAccountAssembler; - private final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator; - private final NoteRepository noteRepository; - - @Autowired - public DepositAccountWritePlatformServiceJpaRepositoryImpl( - final PlatformSecurityContext context, - final DepositAccountRepository depositAccountRepository, - final DepositAccountAssembler depositAccountAssembler, - final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, - final NoteRepository noteRepository) { - this.context=context; - this.depositAccountRepository = depositAccountRepository; - this.depositAccountAssembler = depositAccountAssembler; - this.fixedTermDepositInterestCalculator = fixedTermDepositInterestCalculator; - this.noteRepository = noteRepository; - } - - /* - * Guaranteed to throw an exception no matter what the data integrity issue is. - */ - private void handleDataIntegrityIssues(final DepositAccountCommand command, DataIntegrityViolationException dve) { - - Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("deposit_acc_external_id")) { - throw new PlatformDataIntegrityException("error.msg.desposit.account.duplicate.externalId", "Deposit account with externalId " + command.getExternalId() + " already exists", "externalId", command.getExternalId()); - } - - logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException("error.msg.deposit.account.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); - } - - @Transactional - @Override - public EntityIdentifier createDepositAccount(final DepositAccountCommand command) { - - try { - this.context.authenticatedUser(); - - DepositAccountCommandValidator validator = new DepositAccountCommandValidator(command); - validator.validateForCreate(); - - final DepositAccount account = this.depositAccountAssembler.assembleFrom(command); - this.depositAccountRepository.save(account); - - return new EntityIdentifier(account.getId()); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new EntityIdentifier(Long.valueOf(-1)); - } - } - - @Transactional - @Override - public EntityIdentifier deleteDepositAccount(final Long accountId) { - - this.context.authenticatedUser(); - - DepositAccount account = this.depositAccountRepository.findOne(accountId); - if (account==null || account.isDeleted()) { - throw new SavingsProductNotFoundException(accountId); - } - - account.delete(); - this.depositAccountRepository.save(account); - - return new EntityIdentifier(accountId); - } - - @Transactional - @Override - public EntityIdentifier approveDepositApplication(final DepositStateTransitionApprovalCommand command) { - - //AppUser currentUser = context.authenticatedUser(); - - DepositStateTransitionApprovalCommandValidator validator = new DepositStateTransitionApprovalCommandValidator(command); - validator.validate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getAccountId()); - } - - // FIXME - madhukar - you are checking for loan permission here instead of some specific deposit account permission. - // removing check for now until rules dealing with creating and maintaining deposit accounts in the past is clarified - LocalDate eventDate = command.getEventDate(); - //if (this.isBeforeToday(eventDate) && currentUser.canNotApproveLoanInPast()) { - // throw new NoAuthorizationException("User has no authority to approve deposit with a date in the past."); - //} - - account.approve(eventDate, defaultDepositLifecycleStateMachine(), command, this.fixedTermDepositInterestCalculator); - - this.depositAccountRepository.save(account); - - String noteText = command.getNote(); - if (StringUtils.isNotBlank(noteText)) { - Note note = Note.depositNote(account, noteText); - this.noteRepository.save(note); - } - - - return new EntityIdentifier(account.getId()); - - } - - //private boolean isBeforeToday(final LocalDate date) { - // return date.isBefore(new LocalDate()); - //} - private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() { - List allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values()); - return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); - } - - @Transactional - @Override - public EntityIdentifier rejectDepositApplication(DepositStateTransitionCommand command) { - - //AppUser currentUser = context.authenticatedUser(); - - DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); - validator.validate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getAccountId()); - } - - // removing check for now until rules dealing with creating and maintaining deposit accounts in the past is clarified - LocalDate eventDate = command.getEventDate(); - //if (this.isBeforeToday(eventDate) && currentUser.canNotApproveLoanInPast()) { - // throw new NoAuthorizationException("User has no authority to approve deposit with a date in the past."); - //} - - account.reject(eventDate, defaultDepositLifecycleStateMachine()); - this.depositAccountRepository.save(account); - - String noteText = command.getNote(); - if (StringUtils.isNotBlank(noteText)) { - Note note = Note.depositNote(account, noteText); - this.noteRepository.save(note); - } - - return new EntityIdentifier(account.getId()); - } - - @Transactional - @Override - public EntityIdentifier withdrawDepositApplication(DepositStateTransitionCommand command) { - - //AppUser currentUser = context.authenticatedUser(); - - DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); - validator.validate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getAccountId()); - } - - // removing check for now until rules dealing with creating and maintaining deposit accounts in the past is clarified - LocalDate eventDate = command.getEventDate(); - //if (this.isBeforeToday(eventDate) && currentUser.canNotApproveLoanInPast()) { - // throw new NoAuthorizationException("User has no authority to approve deposit with a date in the past."); - //} - - account.withdrawnByApplicant(eventDate, defaultDepositLifecycleStateMachine()); - this.depositAccountRepository.save(account); - - String noteText = command.getNote(); - if (StringUtils.isNotBlank(noteText)) { - Note note = Note.depositNote(account, noteText); - this.noteRepository.save(note); - } - - return new EntityIdentifier(account.getId()); - } - - @Transactional - @Override - public EntityIdentifier undoDepositApproval(UndoStateTransitionCommand command) { - - context.authenticatedUser(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getLoanId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getLoanId()); - } - - account.undoDepositApproval(defaultDepositLifecycleStateMachine()); - this.depositAccountRepository.save(account); - - String noteText = command.getNote(); - if (StringUtils.isNotBlank(noteText)) { - Note note = Note.depositNote(account, noteText); - this.noteRepository.save(note); - } - return new EntityIdentifier(account.getId()); - } - - /*@Transactional - @Override - public EntityIdentifier matureDepositApplication(DepositStateTransitionCommand command) { - - AppUser currentUser = context.authenticatedUser(); - - DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); - validator.validate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getAccountId()); - } - - LocalDate eventDate = command.getEventDate(); - if (this.isBeforeToday(eventDate) && currentUser.canNotApproveLoanInPast()) { - throw new NoAuthorizationException("User has no authority to mature deposit with a date in the past."); - } - - account.matureDepositApplication(eventDate, defaultDepositLifecycleStateMachine()); - this.depositAccountRepository.save(account); - - if(account.isRenewalAllowed()){ - final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account); - this.depositAccountRepository.save(renewedAccount); - return new EntityIdentifier(renewedAccount.getId()); //returns the new deposit application id - } - - String noteText = command.getNote(); - if (StringUtils.isNotBlank(noteText)) { - Note note = Note.depositNote(account, noteText); - this.noteRepository.save(note); - } - - return new EntityIdentifier(account.getId()); - }*/ - - @Transactional - @Override - public EntityIdentifier withdrawDepositAccountMoney(final DepositAccountWithdrawalCommand command) { - - context.authenticatedUser(); - - DepositAccountWithdrawalCommandValidator validator = new DepositAccountWithdrawalCommandValidator(command); - validator.validate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getAccountId()); - } - - LocalDate eventDate = command.getMaturesOnDate(); - - Integer lockinPeriod = account.getLockinPeriod(); - LocalDate lockinPeriodExpDate = account.getActualCommencementDate().plusMonths(Integer.valueOf(lockinPeriod)); - if(account.isLockinPeriodAllowed()){ - if(eventDate.isBefore(lockinPeriodExpDate)){ - throw new DepositAccountTransactionsException("deposit.transaction.canot.withdraw.before.lockinperiod.reached","You can not withdraw your application before maturity date reached"); - } - } - if(eventDate.isBefore(account.maturesOnDate())){ - this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account,eventDate); - } - account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine(),fixedTermDepositInterestCalculator,eventDate); - this.depositAccountRepository.save(account); - String noteText = command.getNote(); - if (StringUtils.isNotBlank(noteText)) { - Note note = Note.depositNote(account, noteText); - this.noteRepository.save(note); - } - - return new EntityIdentifier(account.getId()); - } - - @Transactional - @Override - public EntityIdentifier withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command) { - - context.authenticatedUser(); - - WithDrawDepositAccountInterestCommandValidator validator = new WithDrawDepositAccountInterestCommandValidator(command); - validator.validate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getAccountId()); - } - if(account.isInterestWithdrawable() && !account.isInterestCompoundingAllowed()){ - - BigDecimal totalAvailableInterestForWithdrawal = getTotalWithdrawableInterestAvailable(account); - BigDecimal interestPaid = account.getInterstPaid(); - BigDecimal remainInterestForWithdrawal = totalAvailableInterestForWithdrawal.subtract(interestPaid); - - if(remainInterestForWithdrawal.doubleValue() > 0){ - if(remainInterestForWithdrawal.doubleValue() >= command.getWithdrawInterest().doubleValue()&&command.getWithdrawInterest().doubleValue()>0){ - account.withdrawInterest(Money.of(account.getDeposit().getCurrency(), command.getWithdrawInterest())); - this.depositAccountRepository.save(account); - }else { - throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.exceed","You can Withdraw "+remainInterestForWithdrawal+" only"); - } - }else { - throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.insufficient.amount","You don't have enough money for withdrawal"); - } - }else{ - throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.cannot.withdraw","You can not withdraw interst for this account"); - } - return new EntityIdentifier(account.getId()); - } - - private BigDecimal getTotalWithdrawableInterestAvailable(DepositAccount account){ - BigDecimal interstGettingForPeriod = BigDecimal.valueOf(account.getAccuredInterest().getAmount().doubleValue()/new Double(account.getTenureInMonths())); - Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()).getMonths(); - Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery(); - return interstGettingForPeriod.multiply(new BigDecimal(noOfPeriods)); - } - - @Transactional - @Override - public EntityIdentifier renewDepositAccount(DepositAccountCommand command) { - - this.context.authenticatedUser(); - - RenewDepositAccountCommandValidator validator = new RenewDepositAccountCommandValidator(command); - validator.validateForCreate(); - - DepositAccount account = this.depositAccountRepository.findOne(command.getId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getId()); - } - - // FIXME - KW - extract whats in this if into a method that naturally describes what you are checking. - if (account.isRenewalAllowed() - && (new LocalDate().isAfter(account.maturesOnDate()) || new LocalDate() - .isEqual(account.maturesOnDate()))) { - - if (account.isActive()) { - final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account, command); - this.depositAccountRepository.save(renewedAccount); - account.closeDepositAccount(defaultDepositLifecycleStateMachine()); - this.depositAccountRepository.save(account); - return new EntityIdentifier(renewedAccount.getId()); - } - - throw new DepositAccountReopenException(account.getMaturityDate()); - } - - throw new DepositAccountReopenException(account.getMaturityDate()); - } - - @Override - public EntityIdentifier updateDepositAccount(DepositAccountCommand command) { - - try { - this.context.authenticatedUser(); - - DepositAccountCommandValidator validator = new DepositAccountCommandValidator(command); - validator.validateForUpdate(); - - final DepositAccount account = this.depositAccountRepository.findOne(command.getId()); - if (account == null || account.isDeleted()) { - throw new DepositAccountNotFoundException(command.getId()); - } - - if (account.isSubmittedAndPendingApproval()) { - this.depositAccountAssembler.assembleUpdatedDepositAccount(account, command); - } else if (account.isActive()) { - this.depositAccountAssembler.updateApprovedDepositAccount(account, command); - } - - this.depositAccountRepository.save(account); - - return new EntityIdentifier(account.getId()); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new EntityIdentifier(Long.valueOf(-1)); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionApprovalCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionApprovalCommandValidator.java deleted file mode 100644 index 287eb9be8..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionApprovalCommandValidator.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; -import org.mifosplatform.infrastructure.core.data.ApiParameterError; -import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; -import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; - -public class DepositStateTransitionApprovalCommandValidator { - - - - private final DepositStateTransitionApprovalCommand command; - - public DepositStateTransitionApprovalCommandValidator(final DepositStateTransitionApprovalCommand command) { - this.command=command; - } - - public void validate(){ - - List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transition"); - baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("commencementDate").value(command.getEventDate()).notNull(); - - baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()).ignoreIfNull().inMinMaxRange(2, 2); - - baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); - - 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/saving/service/SavingAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountAssembler.java deleted file mode 100644 index 2319d449b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountAssembler.java +++ /dev/null @@ -1,207 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.List; - -import org.joda.time.LocalDate; -import org.mifosng.platform.api.commands.SavingAccountCommand; -import org.mifosng.platform.exceptions.SavingsProductNotFoundException; -import org.mifosng.platform.saving.domain.DepositAccountStatus; -import org.mifosng.platform.saving.domain.DepositLifecycleStateMachine; -import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl; -import org.mifosng.platform.saving.domain.ReccuringDepositInterestCalculator; -import org.mifosng.platform.saving.domain.SavingAccount; -import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; -import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; -import org.mifosng.platform.savingproduct.domain.SavingProduct; -import org.mifosng.platform.savingproduct.domain.SavingProductRepository; -import org.mifosng.platform.savingproduct.domain.SavingProductType; -import org.mifosng.platform.savingproduct.domain.SavingsInterestType; -import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; -import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; -import org.mifosplatform.infrastructure.configuration.domain.Money; -import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; -import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -public class SavingAccountAssembler { - - private final ClientRepository clientRepository; - private final SavingProductRepository savingProductRepository; - private final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator; - - @Autowired - public SavingAccountAssembler(final ClientRepository clientRepository,final SavingProductRepository savingProductRepository, - final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) { - this.clientRepository=clientRepository; - this.savingProductRepository=savingProductRepository; - this.reccuringDepositInterestCalculator=reccuringDepositInterestCalculator; - } - //minimumBalanceForWithdrawal,isPartialDepositAllowed - public SavingAccount assembleFrom(SavingAccountCommand command){ - - Client client = this.clientRepository.findOne(command.getClientId()); - if (client == null || client.isDeleted()) { - throw new ClientNotFoundException(command.getClientId()); - } - - SavingProduct product=this.savingProductRepository.findOne(command.getProductId()); - if(product == null || product.isDeleted()){ - throw new SavingsProductNotFoundException(command.getProductId()); - } - - MonetaryCurrency currency = product.getCurrency(); - if(command.getCurrencyCode() != null && command.getDigitsAfterDecimal() != null){ - currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); - } - - Money savingsDeposit = Money.of(currency, command.getSavingsDepositAmount()); - - Integer tenure = product.getSavingProductRelatedDetail().getTenure(); - if(command.getTenure() != null){ - tenure=command.getTenure(); - } - - TenureTypeEnum tenureTypeEnum=product.getSavingProductRelatedDetail().getTenureType(); - if (command.getTenureType() != null) { - tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); - } - - SavingProductType savingProductType= product.getSavingProductRelatedDetail().getSavingProductType(); - if(command.getSavingProductType() != null){ - savingProductType = SavingProductType.fromInt(command.getSavingProductType()); - } - - SavingFrequencyType savingFrequencyType = product.getSavingProductRelatedDetail().getFrequency(); - if (command.getFrequency() != null) { - savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); - } - - SavingInterestCalculationMethod savingInterestCalculationMethod = product.getSavingProductRelatedDetail().getInterestCalculationMethod(); - if (command.getInterestCalculationMethod() != null) { - savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); - } - - SavingsInterestType interestType = product.getSavingProductRelatedDetail().getInterestType(); - if (command.getInterestType() != null) { - interestType = SavingsInterestType.fromInt(command.getInterestType()); - } - - BigDecimal reccuringInterestRate = command.getRecurringInterestRate(); - BigDecimal savingInterestRate = product.getInterestRate(); - if(command.getSavingInterestRate() != null) - savingInterestRate = command.getSavingInterestRate(); - - boolean isLockinPeriodAllowed = product.getSavingProductRelatedDetail().isLockinPeriodAllowed(); - if(command.isLockinPeriodChanged()){ - isLockinPeriodAllowed = command.isLockinPeriodAllowed(); - } - - Integer lockinPeriod = product.getSavingProductRelatedDetail().getLockinPeriod(); - if(command.getLockinPeriod() != null){ - lockinPeriod = command.getLockinPeriod(); - } - - PeriodFrequencyType lockinPeriodType = product.getSavingProductRelatedDetail().getLockinPeriodType(); - if(command.getLockinPeriodType() != null){ - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); - } - - SavingAccount account = SavingAccount.openNew(client, product, command.getExternalId(),savingsDeposit, - reccuringInterestRate,savingInterestRate,tenure,command.getCommencementDate(),tenureTypeEnum, savingProductType, - savingFrequencyType, interestType, savingInterestCalculationMethod, isLockinPeriodAllowed,lockinPeriod, lockinPeriodType, - this.reccuringDepositInterestCalculator, defaultDepositLifecycleStateMachine()); - - return account; - } - - public void assembleFrom(SavingAccountCommand command, SavingAccount account) { - - SavingProduct product=account.getProduct(); - if(command.isProductIdChanged()){ - if(product.getId() != command.getProductId()){ - product = this.savingProductRepository.findOne(command.getProductId()); - if(product == null || product.isDeleted()) - throw new SavingsProductNotFoundException(command.getProductId()); - } - } - - String externalId = account.getExternalId(); - if(command.isExternalIdChanged()){ - externalId = command.getExternalId(); - } - - Money savingsDeposit = Money.of(product.getCurrency(), account.getSavingsDepositAmountPerPeriod()); - if(command.isDepositAmountChanged()){ - savingsDeposit = Money.of(product.getCurrency(), command.getSavingsDepositAmount()); - } - Integer tenure = account.getTenure(); - if(command.isTenureInMonthsChanged()){ - tenure = command.getTenure(); - } - - LocalDate commencementDate = new LocalDate(account.getProjectedCommencementDate()); - if (command.isCommencementDateChanged()) { - commencementDate = command.getCommencementDate(); - } - - TenureTypeEnum tenureTypeEnum=account.getTenureType(); - if(command.isTenureTypeEnumChanged()){ - tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); - } - - SavingProductType savingProductType= account.getSavingProductType(); - if (command.isSavingProductTypeChanged()) { - savingProductType = SavingProductType.fromInt(command.getSavingProductType()); - } - - SavingFrequencyType savingFrequencyType = account.getFrequency(); - if (command.isSavingFrequencyTypeChanged()) { - savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); - } - - SavingInterestCalculationMethod savingInterestCalculationMethod =account.getInterestCalculationMethod(); - if (command.isSavingInterestCalculationMethodChanged()) { - savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); - } - - BigDecimal reccuringInterestRate = account.getReccuringInterestRate(); - if (command.isReccuringInterestRateChanged()) { - reccuringInterestRate = command.getRecurringInterestRate(); - } - - BigDecimal savingInterestRate = account.getSavingInterestRate(); - if (command.isSavingInterestRateChanged()) { - savingInterestRate = command.getSavingInterestRate(); - } - - boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); - if (command.isLockinPeriodAllowedChanged()) { - isLockinPeriodAllowed = command.isLockinPeriodAllowed(); - } - - Integer lockinPeriod =account.getLockinPeriod(); - if (command.isLockinPeriodChanged()) { - lockinPeriod = command.getLockinPeriod(); - } - - PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType(); - if (command.isLockinPeriodTypeChanged()) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); - } - account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, - commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, - isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator); - - } - - private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() { - List allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values()); - return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountCommandValidator.java deleted file mode 100644 index 0add042de..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountCommandValidator.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.api.commands.SavingAccountCommand; -import org.mifosplatform.infrastructure.core.data.ApiParameterError; -import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; -import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; - -public class SavingAccountCommandValidator { - - private final SavingAccountCommand command; - - public SavingAccountCommandValidator(final SavingAccountCommand command) { - this.command = command; - } - - public void validateForCreate() { - - List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account"); - - baseDataValidator.reset().parameter("clientId").value(command.getClientId()).notNull(); - baseDataValidator.reset().parameter("productId").value(command.getProductId()).notNull(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); - baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank(); - baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6); - baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(command.getSavingsDepositAmount()).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("recurringInterestRate").value(command.getRecurringInterestRate()).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("savingInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate()); - baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).notNull(); - baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull(); - baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull(); - baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull(); - baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).notNull(); - baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).notNull(); - baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).notNull(); - baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).notNull(); - baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).notNull(); - baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).notNull(); - baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).notNull(); - - 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("saving.account"); - - baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); - baseDataValidator.reset().parameter("clientId").value(command.getClientId()).ignoreIfNull().notNull(); - baseDataValidator.reset().parameter("productId").value(command.getProductId()).ignoreIfNull().notNull(); - baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); - baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank(); - baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().inMinMaxRange(0, 6); - baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(command.getSavingsDepositAmount()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("recurringInterestRate").value(command.getRecurringInterestRate()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("savingInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate()); - baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).ignoreIfNull(); - baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull(); - baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull(); - baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull(); - baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).ignoreIfNull(); - baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).ignoreIfNull(); - baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).ignoreIfNull(); - baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).ignoreIfNull(); - baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).ignoreIfNull(); - baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).ignoreIfNull(); - baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull(); - baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull(); - - if (command.isNoFieldChanged()) { - StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append("deposit.account").append(".no.parameters.for.update"); - StringBuilder defaultEnglishMessage = new StringBuilder("No parameters passed for update."); - ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), "id"); - dataValidationErrors.add(error); - } - - 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/saving/service/SavingAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformService.java deleted file mode 100644 index 2116b76d8..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformService.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.util.Collection; - -import org.mifosng.platform.api.data.SavingAccountData; - -public interface SavingAccountReadPlatformService { - - Collection retrieveAllSavingsAccounts(); - - SavingAccountData retrieveSavingsAccount(Long accountId); -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformServiceImpl.java deleted file mode 100644 index 7995ff0e6..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountReadPlatformServiceImpl.java +++ /dev/null @@ -1,150 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.math.BigDecimal; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.Collection; - -import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.SavingAccountData; -import org.mifosng.platform.savingproduct.service.SavingProductEnumerations; -import org.mifosplatform.infrastructure.configuration.data.CurrencyData; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; -import org.mifosplatform.infrastructure.core.domain.JdbcSupport; -import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; -import org.mifosplatform.infrastructure.security.service.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 SavingAccountReadPlatformServiceImpl implements - SavingAccountReadPlatformService { - - private final PlatformSecurityContext context; - private final JdbcTemplate jdbcTemplate; -// private final SavingProductReadPlatformService savingProductReadPlatformService; -// private final ClientReadPlatformService clientReadPlatformService; - - @Autowired - public SavingAccountReadPlatformServiceImpl( - final PlatformSecurityContext context, - final TenantAwareRoutingDataSource dataSource -// final SavingProductReadPlatformService savingProductReadPlatformService, -// final ClientReadPlatformService clientReadPlatformService - ) { - this.context = context; - this.jdbcTemplate = new JdbcTemplate(dataSource); -// this.savingProductReadPlatformService = savingProductReadPlatformService; -// this.clientReadPlatformService = clientReadPlatformService; - } - - @Override - public Collection retrieveAllSavingsAccounts() { - - this.context.authenticatedUser(); - SavingAccountMapper mapper = new SavingAccountMapper(); - String sql = "select " + mapper.schema() + " where sa.is_deleted=0"; - return this.jdbcTemplate.query(sql,mapper, new Object[]{}); - - } - - @Override - public SavingAccountData retrieveSavingsAccount(Long accountId) { - - this.context.authenticatedUser(); - SavingAccountMapper mapper = new SavingAccountMapper(); - String sql = "select " + mapper.schema() + " where sa.id = ? and sa.is_deleted=0"; - SavingAccountData savingAccountData = this.jdbcTemplate.queryForObject(sql,mapper, new Object[]{accountId}); - return savingAccountData; - } - - private static final class SavingAccountMapper implements RowMapper { - - public String schema() { - return "sa.id AS id, sa.status_enum AS status, sa.external_id AS externalId," - + " sa.client_id AS clientId, sa.product_id AS productId, sa.deposit_amount_per_period AS savingsDepostiAmountPerPeriod," - + " sa.savings_product_type AS savingsProductType, sa.currency_code AS currencyCode, sa.currency_digits AS currencyDigits," - + " sa.total_deposit_amount AS totalDepositAmount, sa.reccuring_nominal_interest_rate AS reccuringInterestRate," - + " sa.regular_saving_nominal_interest_rate AS savingInterestRate, sa.tenure AS tenure, sa.tenure_type AS tenureType," - + " sa.frequency AS savingsFrequencyType, sa.interest_type AS interestType, sa.interest_calculation_method AS interestCalculationMethod," - + " sa.projected_commencement_date AS projectedCommencementDate, sa.actual_commencement_date AS actualCommencementDate," - + " sa.matures_on_date AS maturesOnDate, sa.projected_interest_accrued_on_maturity AS projectedInterestAccuredOnMaturity," - + " sa.actual_interest_accrued AS actualInterestAccured, sa.projected_total_maturity_amount AS projectedTotalMaturityAmount," - + " sa.actual_total_amount AS actualTotalAmount, sa.is_preclosure_allowed AS isPreclosureAllowed," - + " sa.pre_closure_interest_rate AS preClosureInterestRate, sa.is_lock_in_period_allowed AS isLockinPeriodAllowed," - + " sa.lock_in_period AS lockinPeriod, sa.lock_in_period_type AS lockinPeriodType, sa.withdrawnon_date AS withdrawnonDate," - + " sa.rejectedon_date AS rejectedonDate, sa.closedon_date AS closedonDate, ps.name AS productName," - + " c.firstname AS firstname, c.lastname AS lastname, curr.name AS currencyName, " - + " curr.internationalized_name_code AS currencyNameCode, curr.display_symbol AS currencyDisplaySymbol " - + " FROM m_saving_account sa " - + " JOIN m_client c ON c.id = sa.client_id" - + " JOIN m_currency curr ON curr.code = sa.currency_code " - + " JOIN m_product_savings ps ON sa.product_id = ps.id "; - } - - @Override - public SavingAccountData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { - - Long id = rs.getLong("id"); - String externalId = rs.getString("externalId"); - Long clientId = rs.getLong("clientId"); - String clientName = rs.getString("firstname") + " " + rs.getString("lastname"); - - Long productId = rs.getLong("productId"); - String productName = rs.getString("productName"); - EnumOptionData productType = SavingProductEnumerations.savingProductType(JdbcSupport.getInteger(rs, "savingsProductType")); - - Integer statusId = JdbcSupport.getInteger(rs, "status"); - EnumOptionData status = DepositAccountEnumerations.status(statusId); - - String currencyCode = rs.getString("currencyCode"); - String currencyName = rs.getString("currencyName"); - String currencyNameCode = rs.getString("currencyNameCode"); - String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); - Integer currencyDigits = JdbcSupport.getInteger(rs,"currencyDigits"); - CurrencyData currencyData = new CurrencyData(currencyCode,currencyName, currencyDigits, currencyDisplaySymbol,currencyNameCode); - - BigDecimal savingsDepostiAmountPerPeriod = rs.getBigDecimal("savingsDepostiAmountPerPeriod"); - EnumOptionData savingsFrequencyType = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs, "savingsFrequencyType")); - BigDecimal totalDepositAmount = rs.getBigDecimal("totalDepositAmount"); - - BigDecimal reccuringInterestRate = rs.getBigDecimal("reccuringInterestRate"); - BigDecimal savingInterestRate = rs.getBigDecimal("savingInterestRate"); - EnumOptionData interestType = SavingProductEnumerations.savingInterestType(JdbcSupport.getInteger(rs, "interestType")); - EnumOptionData interestCalculationMethod = SavingProductEnumerations.savingInterestCalculationMethod(JdbcSupport.getInteger(rs, "interestCalculationMethod")); - - Integer tenure = JdbcSupport.getInteger(rs,"tenure"); - EnumOptionData tenureType = SavingProductEnumerations.tenureTypeEnum(JdbcSupport.getInteger(rs, "tenureType")); - - LocalDate projectedCommencementDate = JdbcSupport.getLocalDate(rs, "projectedCommencementDate"); - LocalDate actualCommencementDate = JdbcSupport.getLocalDate(rs, "actualCommencementDate"); - LocalDate maturesOnDate = JdbcSupport.getLocalDate(rs, "maturesOnDate"); - BigDecimal projectedInterestAccuredOnMaturity = rs.getBigDecimal("projectedInterestAccuredOnMaturity"); - BigDecimal actualInterestAccured = rs.getBigDecimal("actualInterestAccured"); - - BigDecimal projectedMaturityAmount = rs.getBigDecimal("projectedTotalMaturityAmount"); - BigDecimal actualMaturityAmount = rs.getBigDecimal("actualTotalAmount"); - - boolean preClosureAllowed = rs.getBoolean("isPreclosureAllowed"); - BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate"); - - LocalDate withdrawnonDate = JdbcSupport.getLocalDate(rs, "withdrawnonDate"); - LocalDate rejectedonDate = JdbcSupport.getLocalDate(rs, "rejectedonDate"); - LocalDate closedonDate = JdbcSupport.getLocalDate(rs, "closedonDate"); - - boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed"); - Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod"); - Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType"); - EnumOptionData lockinPeriodType = SavingProductEnumerations.savingsLockinPeriod(lockinPeriodTypeValue); - - return new SavingAccountData(id, status, externalId, clientId, clientName, productId, productName, productType, currencyData, - savingsDepostiAmountPerPeriod, savingsFrequencyType, totalDepositAmount, reccuringInterestRate, savingInterestRate, - interestType, interestCalculationMethod, tenure, tenureType, projectedCommencementDate, actualCommencementDate, - maturesOnDate,projectedInterestAccuredOnMaturity, actualInterestAccured, - projectedMaturityAmount, actualMaturityAmount, preClosureAllowed, preClosureInterestRate, withdrawnonDate, - rejectedonDate, closedonDate, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); - } - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformService.java deleted file mode 100644 index 27caea978..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformService.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.mifosng.platform.saving.service; - -import org.mifosng.platform.api.commands.SavingAccountCommand; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface SavingAccountWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_SAVINGSACCOUNT')") - EntityIdentifier createSavingAccount(SavingAccountCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_SAVINGSACCOUNT')") - EntityIdentifier updateSavingAccount(SavingAccountCommand command); -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 07260dfe7..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.mifosng.platform.saving.service; - -import org.mifosng.platform.api.commands.SavingAccountCommand; -import org.mifosng.platform.exceptions.SavingAccountNotFoundException; -import org.mifosng.platform.saving.domain.SavingAccount; -import org.mifosng.platform.saving.domain.SavingAccountRepository; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.client.domain.NoteRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements SavingAccountWritePlatformService { - - private final static Logger logger = LoggerFactory.getLogger(SavingAccountWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final SavingAccountRepository savingAccountRepository; - private final SavingAccountAssembler savingAccountAssembler; - @SuppressWarnings("unused") - private final NoteRepository noteRepository; - - @Autowired - public SavingAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,final SavingAccountRepository savingAccountRepository, - SavingAccountAssembler savingAccountAssembler,NoteRepository noteRepository) { - this.context=context; - this.savingAccountRepository=savingAccountRepository; - this.savingAccountAssembler=savingAccountAssembler; - this.noteRepository=noteRepository; - } - - - @Transactional - @Override - public EntityIdentifier createSavingAccount(SavingAccountCommand command) { - try { - this.context.authenticatedUser(); - SavingAccountCommandValidator validator=new SavingAccountCommandValidator(command); - validator.validateForCreate(); - - SavingAccount account=this.savingAccountAssembler.assembleFrom(command); - this.savingAccountRepository.save(account); - - return new EntityIdentifier(account.getId()); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new EntityIdentifier(Long.valueOf(-1)); - } - - } - - @Override - public EntityIdentifier updateSavingAccount(SavingAccountCommand command) { - try { - this.context.authenticatedUser(); - SavingAccountCommandValidator validator=new SavingAccountCommandValidator(command); - validator.validateForUpdate(); - - SavingAccount account=this.savingAccountRepository.findOne(command.getId()); - if (account == null || account.isDeleted()) { - throw new SavingAccountNotFoundException(command.getId()); - } - if(account.isPendingApproval()){ - this.savingAccountAssembler.assembleFrom(command,account); - this.savingAccountRepository.save(account); - } - return new EntityIdentifier(account.getId()); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new EntityIdentifier(Long.valueOf(-1)); - } - } - - /* - * Guaranteed to throw an exception no matter what the data integrity issue is. - */ - private void handleDataIntegrityIssues(final SavingAccountCommand command, DataIntegrityViolationException dve) { - - Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("saving_acc_external_id")) { - throw new PlatformDataIntegrityException("error.msg.saving.account.duplicate.externalId", "Saving account with externalId " + command.getExternalId() + " already exists", "externalId", command.getExternalId()); - } - - logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException("error.msg.saving.account.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); - } -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/WithDrawDepositAccountInterestCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/WithDrawDepositAccountInterestCommandValidator.java deleted file mode 100644 index 135a88291..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/WithDrawDepositAccountInterestCommandValidator.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.mifosng.platform.saving.service; - -import java.util.ArrayList; -import java.util.List; - -import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; -import org.mifosplatform.infrastructure.core.data.ApiParameterError; -import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; -import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; - -public class WithDrawDepositAccountInterestCommandValidator { - - private final DepositAccountWithdrawInterestCommand command; - - public WithDrawDepositAccountInterestCommandValidator(final DepositAccountWithdrawInterestCommand command) { - this.command=command; - } - - public void validate(){ - List dataValidationErrors = new ArrayList(); - DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transaction"); - - baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); - baseDataValidator.reset().parameter("amount").value(command.getWithdrawInterest()).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); - - 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/savingproduct/domain/TenureTypeEnum.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/TenureTypeEnum.java deleted file mode 100644 index 16fc6dbef..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/TenureTypeEnum.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.mifosng.platform.savingproduct.domain; - - -public enum TenureTypeEnum { - - INVALID(0,"tenureTypeEnum.invalid"), - FIXED_PERIOD(1,"tenureTypeEnum.fixedPeriod"), - PERPETUAL(2,"tenureTypeEnum.perpetual"); - - private final Integer value; - private final String code; - - private TenureTypeEnum(final Integer value,final String code) { - this.value=value; - this.code=code; - } - - public Integer getValue() { - return value; - } - public String getCode() { - return code; - } - - public static TenureTypeEnum fromInt(final Integer frequency) { - - TenureTypeEnum tenureTypeEnum = TenureTypeEnum.INVALID; - switch (frequency) { - case 1: - tenureTypeEnum = TenureTypeEnum.FIXED_PERIOD; - break; - case 2: - tenureTypeEnum = TenureTypeEnum.PERPETUAL; - break; - default: - tenureTypeEnum = TenureTypeEnum.INVALID; - break; - } - return tenureTypeEnum; - } - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformService.java deleted file mode 100644 index 4c06933d5..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformService.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mifosng.platform.savingproduct.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/savingproduct/service/DepositProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformServiceImpl.java deleted file mode 100644 index 6398aa26b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductReadPlatformServiceImpl.java +++ /dev/null @@ -1,146 +0,0 @@ -package org.mifosng.platform.savingproduct.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.DepositProductData; -import org.mifosng.platform.api.data.DepositProductLookup; -import org.mifosplatform.infrastructure.configuration.data.CurrencyData; -import org.mifosplatform.infrastructure.core.data.EnumOptionData; -import org.mifosplatform.infrastructure.core.domain.JdbcSupport; -import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -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; - - @Autowired - public DepositProductReadPlatformServiceImpl(final PlatformSecurityContext context,final TenantAwareRoutingDataSource dataSource) { - this.context=context; - jdbcTemplate=new JdbcTemplate(dataSource); - } - - @Override - public Collection retrieveAllDepositProducts() { - this.context.authenticatedUser(); - DepositProductMapper depositProductMapper= new DepositProductMapper(); - String sql="select "+depositProductMapper.depositProductSchema() + " where dp.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"; - - return this.jdbcTemplate.queryForObject(sql, depositProductMapper, new Object[]{productId}); - } - - @Override - public DepositProductData retrieveNewDepositProductDetails() { - - List currencyOptions = null; - List interestCompoundedEveryPeriodTypeOptions = null; - EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS); - - return new DepositProductData(currencyOptions, monthly, interestCompoundedEveryPeriodTypeOptions); - } - - private static final class DepositProductMapper implements RowMapper{ - - public String depositProductSchema(){ - return " dp.id as id, dp.external_id as exernalId, 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,dp.tenure_months as tenureMonths, " + - "dp.interest_compounded_every as interestCompoundedEvery, dp.interest_compounded_every_period_enum as interestCompoundedEveryPeriodType, " + - "dp.maturity_default_interest_rate as maturityDefaultInterestRate, dp.is_compounding_interest_allowed as interestCompoundingAllowed, " + - "dp.maturity_min_interest_rate as maturityMinInterestRate, dp.maturity_max_interest_rate as maturityMaxInterestRate, dp.is_renewal_allowed as canRenew, dp.is_preclosure_allowed as canPreClose, dp.pre_closure_interest_rate as preClosureInterestRate, " + - "dp.is_lock_in_period_allowed as isLockinPeriodAllowed, dp.lock_in_period as lockinPeriod, dp.lock_in_period_type as lockinPeriodType, "+ - "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol " + - "from m_product_deposit dp join m_currency curr on curr.code = dp.currency_code "; - } - - @Override - public DepositProductData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) - throws SQLException { - - Long id = rs.getLong("id"); - String exernalId = rs.getString("exernalId"); - 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"); - - Integer tenureMonths = JdbcSupport.getInteger(rs, "tenureMonths"); - Integer interestCompoundedEvery = JdbcSupport.getInteger(rs, "interestCompoundedEvery"); - Integer interestCompoundedEveryPeriodTypeValue = JdbcSupport.getInteger(rs, "interestCompoundedEveryPeriodType"); - EnumOptionData interestCompoundedEveryPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(interestCompoundedEveryPeriodTypeValue); - - BigDecimal maturityDefaultInterestRate=rs.getBigDecimal("maturityDefaultInterestRate"); - BigDecimal maturityMinInterestRate= rs.getBigDecimal("maturityMinInterestRate"); - BigDecimal maturityMaxInterestRate = rs.getBigDecimal("maturityMaxInterestRate"); - - Boolean canRenew = rs.getBoolean("canRenew"); - Boolean canPreClose=rs.getBoolean("canPreClose"); - Boolean interestCompoundingAllowed= rs.getBoolean("interestCompoundingAllowed"); - - BigDecimal preClosureInterestRate=rs.getBigDecimal("preClosureInterestRate"); - - Boolean isLockinPeriodAllowed=rs.getBoolean("isLockinPeriodAllowed"); - Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod"); - Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType"); - EnumOptionData lockinPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(lockinPeriodTypeValue); - - - return new DepositProductData(createdOn, lastModifedOn, id, exernalId, name, description, currencyCode, currencyDigits, minimumBalance, maximumBalance, - tenureMonths, maturityDefaultInterestRate,maturityMinInterestRate,maturityMaxInterestRate, - interestCompoundedEvery, interestCompoundedEveryPeriodType, - canRenew,canPreClose,preClosureInterestRate,interestCompoundingAllowed,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType); - } - - } - - private static final class DepositProductLookupMapper implements RowMapper { - - public String depositProductLookupSchema() { - return "dp.id as id, dp.name as name from m_product_deposit dp"; - } - - @Override - public DepositProductLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { - - Long id = rs.getLong("id"); - String name = rs.getString("name"); - - return new DepositProductLookup(id, name); - } - - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformService.java deleted file mode 100644 index 729083fd1..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformService.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.mifosng.platform.savingproduct.service; - -import org.mifosng.platform.api.commands.DepositProductCommand; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.springframework.security.access.prepost.PreAuthorize; - -public interface DepositProductWritePlatformService { - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_DEPOSITPRODUCT')") - EntityIdentifier createDepositProduct(DepositProductCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_DEPOSITPRODUCT')") - EntityIdentifier updateDepositProduct(DepositProductCommand command); - - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'DELETE_DEPOSITPRODUCT')") - EntityIdentifier deleteDepositProduct(Long productId); - -} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java deleted file mode 100644 index 9f8483c2b..000000000 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -package org.mifosng.platform.savingproduct.service; - -import org.mifosng.platform.api.commands.DepositProductCommand; -import org.mifosng.platform.exceptions.DepositProductNotFoundException; -import org.mifosng.platform.savingproduct.domain.DepositProduct; -import org.mifosng.platform.savingproduct.domain.DepositProductRepository; -import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; -import org.mifosplatform.infrastructure.core.data.EntityIdentifier; -import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; -import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class DepositProductWritePlatformServiceJpaRepositoryImpl implements DepositProductWritePlatformService { - - private final static Logger logger = LoggerFactory.getLogger(DepositProductWritePlatformServiceJpaRepositoryImpl.class); - - private final PlatformSecurityContext context; - private final DepositProductRepository depositProductRepository; - - @Autowired - public DepositProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final DepositProductRepository depositProductRepository){ - this.context=context; - this.depositProductRepository=depositProductRepository; - } - - /* - * Guaranteed to throw an exception no matter what the data integrity issue is. - */ - private void handleDataIntegrityIssues(final DepositProductCommand command, final DataIntegrityViolationException dve) { - - Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("name_deposit_product")) { - throw new PlatformDataIntegrityException("error.msg.desposit.product.duplicate.name", "Deposit product with name: " + command.getName() + " already exists", "name", command.getName()); - } - if (realCause.getMessage().contains("externalid_deposit_product")) { - throw new PlatformDataIntegrityException("error.msg.desposit.product.duplicate.externalId", "Deposit product with externalId " + command.getExternalId() + " already exists", "externalId", command.getExternalId()); - } - - logger.error(dve.getMessage(), dve); - throw new PlatformDataIntegrityException("error.msg.deposit.product.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); - } - - @Transactional - @Override - public EntityIdentifier createDepositProduct(final DepositProductCommand command) { - - try { - this.context.authenticatedUser(); - DepositProductCommandValidator validator=new DepositProductCommandValidator(command); - validator.validateForCreate(); - - PeriodFrequencyType interestCompoundingPeriodType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); - PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); - MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); - DepositProduct product = new DepositProduct(command.getName(), command.getExternalId(), command.getDescription(),currency,command.getMinimumBalance(),command.getMaximumBalance(), - command.getTenureInMonths(),command.getMaturityDefaultInterestRate(),command.getMaturityMinInterestRate(),command.getMaturityMaxInterestRate(), - command.getInterestCompoundedEvery(), interestCompoundingPeriodType, - command.isRenewalAllowed(), command.isPreClosureAllowed(), - command.getPreClosureInterestRate(),command.isInterestCompoundingAllowed(), - command.isLockinPeriodAllowed(),command.getLockinPeriod(),lockinPeriodType); - this.depositProductRepository.save(product); - - return new EntityIdentifier(product.getId()); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new EntityIdentifier(Long.valueOf(-1)); - } - } - - @Transactional - @Override - public EntityIdentifier updateDepositProduct(final DepositProductCommand command) { - - try { - 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()); - } - - PeriodFrequencyType interestCompoundingFrequency = null; - if (command.isInterestCompoundedEveryPeriodTypeChanged()) { - interestCompoundingFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); - } - - PeriodFrequencyType lockinPeriodType = null; - if (command.isLockinPeriodTypeChanged()) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); - } - - product.update(command, interestCompoundingFrequency, lockinPeriodType); - this.depositProductRepository.save(product); - return new EntityIdentifier(Long.valueOf(product.getId())); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - return new EntityIdentifier(Long.valueOf(-1)); - } - } - - @Transactional - @Override - public EntityIdentifier deleteDepositProduct(final 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())); - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java index 03622b93f..68b5766ff 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/GoogleGsonPortfolioApiJsonSerializerService.java @@ -5,10 +5,6 @@ import java.util.Collection; import java.util.HashSet; import java.util.Set; -import org.mifosng.platform.api.data.DepositAccountData; -import org.mifosng.platform.api.data.DepositProductData; -import org.mifosng.platform.api.data.SavingAccountData; -import org.mifosng.platform.api.data.SavingProductData; import org.mifosplatform.commands.api.data.CommandSourceData; import org.mifosplatform.infrastructure.codes.data.CodeData; import org.mifosplatform.infrastructure.configuration.data.ConfigurationData; @@ -39,6 +35,10 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData; import org.mifosplatform.portfolio.loanaccount.gaurantor.data.GuarantorData; import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData; import org.mifosplatform.portfolio.loanproduct.data.LoanProductData; +import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData; +import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductData; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountData; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java index 8fb46776c..785423854 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionService.java @@ -1,13 +1,5 @@ package org.mifosplatform.infrastructure.core.api; -import org.mifosng.platform.api.commands.DepositAccountCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; -import org.mifosng.platform.api.commands.DepositProductCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionCommand; -import org.mifosng.platform.api.commands.SavingAccountCommand; -import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosplatform.infrastructure.codes.command.CodeCommand; import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; import org.mifosplatform.infrastructure.office.command.BranchMoneyTransferCommand; @@ -32,6 +24,14 @@ import org.mifosplatform.portfolio.loanaccount.command.LoanStateTransitionComman import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand; import org.mifosplatform.portfolio.loanaccount.gaurantor.command.GuarantorCommand; import org.mifosplatform.portfolio.loanproduct.command.LoanProductCommand; +import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; +import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; public interface PortfolioApiDataConversionService { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java index 305f43f26..6c15d20ba 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiDataConversionServiceImpl.java @@ -17,14 +17,6 @@ import java.util.Set; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; -import org.mifosng.platform.api.commands.DepositAccountCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawInterestCommand; -import org.mifosng.platform.api.commands.DepositAccountWithdrawalCommand; -import org.mifosng.platform.api.commands.DepositProductCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; -import org.mifosng.platform.api.commands.DepositStateTransitionCommand; -import org.mifosng.platform.api.commands.SavingAccountCommand; -import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosplatform.infrastructure.codes.command.CodeCommand; import org.mifosplatform.infrastructure.configuration.command.CurrencyCommand; import org.mifosplatform.infrastructure.core.data.ApiParameterError; @@ -53,6 +45,14 @@ import org.mifosplatform.portfolio.loanaccount.command.LoanStateTransitionComman import org.mifosplatform.portfolio.loanaccount.command.LoanTransactionCommand; import org.mifosplatform.portfolio.loanaccount.gaurantor.command.GuarantorCommand; import org.mifosplatform.portfolio.loanproduct.command.LoanProductCommand; +import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; +import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.number.NumberFormatter; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java index b6bc02c6a..21cabdbc4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/PortfolioApiJsonSerializerService.java @@ -3,10 +3,6 @@ package org.mifosplatform.infrastructure.core.api; import java.util.Collection; import java.util.Set; -import org.mifosng.platform.api.data.DepositAccountData; -import org.mifosng.platform.api.data.DepositProductData; -import org.mifosng.platform.api.data.SavingAccountData; -import org.mifosng.platform.api.data.SavingProductData; import org.mifosplatform.commands.api.data.CommandSourceData; import org.mifosplatform.infrastructure.codes.data.CodeData; import org.mifosplatform.infrastructure.configuration.data.ConfigurationData; @@ -37,6 +33,10 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanTransactionData; import org.mifosplatform.portfolio.loanaccount.gaurantor.data.GuarantorData; import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData; import org.mifosplatform.portfolio.loanproduct.data.LoanProductData; +import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData; +import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductData; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountData; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData; public interface PortfolioApiJsonSerializerService { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Note.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Note.java index f2934c634..b503bd72e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Note.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Note.java @@ -6,11 +6,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.mifosng.platform.saving.domain.DepositAccount; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.mifosplatform.portfolio.loanaccount.domain.Loan; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount; @Entity @Table(name = "m_note") diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java new file mode 100644 index 000000000..9f200c6e5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java @@ -0,0 +1,148 @@ +package org.mifosplatform.portfolio.savingsaccount.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.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +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.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService; +import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService; +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; +import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountReadPlatformService; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/savingaccounts") +@Component +@Scope("singleton") +public class SavingsAccountApiResource { + + @Autowired + private SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + private SavingAccountReadPlatformService savingAccountReadPlatformService; + + @Autowired + private PortfolioApiDataConversionService apiDataConversionService; + + @Autowired + private PortfolioApiJsonSerializerService apiJsonSerializerService; + + private final String entityType = "SAVINGSACCOUNT"; + @Autowired + private PlatformSecurityContext context; + + private static final Set typicalResponseParameters = new HashSet(Arrays.asList("id", "status", "externalId", + "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", + "savingsFrequencyType", "totalDepositAmount", "reccuringInterestRate", "savingInterestRate", "interestType", + "interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "actualCommencementDate", "maturesOnDate", + "projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount", + "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed", + "lockinPeriod", "lockinPeriodType")); + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response createSavingAccount(final String jsonRequestBody) { + + final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(null, jsonRequestBody); + + EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.createSavingAccount(command); + + return Response.ok().entity(entityIdentifier).build(); + } + + @PUT + @Path("{accountId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response updateSavingAccount(@PathParam("accountId") final Long accountId, final String jsonRequestBody) { + + final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(accountId, jsonRequestBody); + + EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.updateSavingAccount(command); + + return Response.ok().entity(entityIdentifier).build(); + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + Collection accounts = this.savingAccountReadPlatformService.retrieveAllSavingsAccounts(); + + return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, accounts); + } + + @GET + @Path("{accountId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + SavingAccountData account = this.savingAccountReadPlatformService.retrieveSavingsAccount(accountId); + + return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); + } + + @SuppressWarnings("unused") + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveNewDepositAccountDetails(@QueryParam("clientId") final Long clientId, + @QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + SavingAccountData account = null; + // this.savingAccountReadPlatformService.retrieveNewSavingsAccountDetails(clientId, + // productId); + + return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/command/SavingAccountCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/command/SavingAccountCommand.java new file mode 100644 index 000000000..e4d83362f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/command/SavingAccountCommand.java @@ -0,0 +1,229 @@ +package org.mifosplatform.portfolio.savingsaccount.command; + +import java.math.BigDecimal; +import java.util.Set; + +import org.joda.time.LocalDate; + +public class SavingAccountCommand { + + private final Long id; + private final Long clientId; + private final Long productId; + private final String externalId; + + private final String currencyCode; + private final Integer digitsAfterDecimal; + private final BigDecimal savingsDepositAmount; + private final BigDecimal recurringInterestRate; + private final BigDecimal savingInterestRate; + private final Integer tenure; + + private final boolean isLockinPeriodAllowed; + private final Integer lockinPeriod; + private final Integer lockinPeriodType; + + private final LocalDate commencementDate; + private final Integer savingProductType; + private final Integer tenureType; + private final Integer frequency; + private final Integer interestType; + + private final Integer interestCalculationMethod; + private final BigDecimal minimumBalanceForWithdrawal; + private final boolean isPartialDepositAllowed; + + private final Set modifiedParameters; + + public SavingAccountCommand(final Set modifiedParameters, final Long id, final Long clientId, final Long productId, + final String externalId, final String currencyCode, final Integer digitsAfterDecimal, final BigDecimal savingsDepositAmount, + final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate, final Integer tenure, + final LocalDate commencementDate, final Integer savingProductType, final Integer tenureType, final Integer frequency, + final Integer interestType, final BigDecimal minimumBalanceForWithdrawal, final Integer interestCalculationMethod, + final boolean isLockinPeriodAllowed, final boolean isPartialDepositAllowed, final Integer lockInPeriod, + final Integer lockinPeriodType) { + this.id = id; + this.clientId = clientId; + this.productId = productId; + this.externalId = externalId; + + this.currencyCode = currencyCode; + this.digitsAfterDecimal = digitsAfterDecimal; + this.savingsDepositAmount = savingsDepositAmount; + this.recurringInterestRate = recurringInterestRate; + this.savingInterestRate = savingInterestRate; + this.tenure = tenure; + + this.modifiedParameters = modifiedParameters; + this.commencementDate = commencementDate; + + this.savingProductType = savingProductType; + this.tenureType = tenureType; + this.frequency = frequency; + this.interestType = interestType; + this.isPartialDepositAllowed = isPartialDepositAllowed; + + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + this.lockinPeriod = lockInPeriod; + this.lockinPeriodType = lockinPeriodType; + this.minimumBalanceForWithdrawal = minimumBalanceForWithdrawal; + this.interestCalculationMethod = interestCalculationMethod; + } + + public Long getId() { + return id; + } + + public Long getClientId() { + return clientId; + } + + public Long getProductId() { + return productId; + } + + public String getExternalId() { + return externalId; + } + + public String getCurrencyCode() { + return currencyCode; + } + + public Integer getDigitsAfterDecimal() { + return digitsAfterDecimal; + } + + public BigDecimal getSavingsDepositAmount() { + return savingsDepositAmount; + } + + public BigDecimal getRecurringInterestRate() { + return recurringInterestRate; + } + + public BigDecimal getSavingInterestRate() { + return savingInterestRate; + } + + public Integer getTenure() { + return tenure; + } + + public boolean isLockinPeriodAllowed() { + return isLockinPeriodAllowed; + } + + public Integer getLockinPeriod() { + return lockinPeriod; + } + + public Integer getLockinPeriodType() { + return lockinPeriodType; + } + + public LocalDate getCommencementDate() { + return commencementDate; + } + + public Integer getSavingProductType() { + return savingProductType; + } + + public Integer getTenureType() { + return tenureType; + } + + public Integer getFrequency() { + return frequency; + } + + public Integer getInterestType() { + return interestType; + } + + public Integer getInterestCalculationMethod() { + return interestCalculationMethod; + } + + public BigDecimal getMinimumBalanceForWithdrawal() { + return minimumBalanceForWithdrawal; + } + + public boolean isPartialDepositAllowed() { + return isPartialDepositAllowed; + } + + public boolean isNoFieldChanged() { + return this.modifiedParameters.isEmpty(); + } + + public boolean isProductIdChanged() { + return this.modifiedParameters.contains("productId"); + } + + public boolean isExternalIdChanged() { + return this.modifiedParameters.contains("externalId"); + } + + public boolean isDepositAmountChanged() { + return this.modifiedParameters.contains("deposit"); + } + + public boolean isTenureInMonthsChanged() { + return this.modifiedParameters.contains("tenureInMonths"); + } + + public boolean isLockinPeriodChanged() { + return this.modifiedParameters.contains("lockinPeriod"); + } + + public boolean isPreClosureInterestRateChanged() { + return this.modifiedParameters.contains("preClosureInterestRate"); + } + + public boolean isPreClosureAllowedChanged() { + return this.modifiedParameters.contains("preClosureAllowed"); + } + + public boolean isCommencementDateChanged() { + return this.modifiedParameters.contains("commencementDate"); + } + + public boolean isTenureTypeEnumChanged() { + return this.modifiedParameters.contains("tenureType"); + } + + public boolean isSavingProductTypeChanged() { + return this.modifiedParameters.contains("savingProductType"); + } + + public boolean isSavingFrequencyTypeChanged() { + return this.modifiedParameters.contains("frequency"); + } + + public boolean isSavingInterestCalculationMethodChanged() { + return this.modifiedParameters.contains("interestCalculationMethod"); + } + + public boolean isReccuringInterestRateChanged() { + return this.modifiedParameters.contains("recurringInterestRate"); + } + + public boolean isSavingInterestRateChanged() { + return this.modifiedParameters.contains("savingInterestRate"); + } + + public boolean isLockinPeriodAllowedChanged() { + return this.modifiedParameters.contains("isLockinPeriodAllowed"); + } + + public boolean isLockinPeriodTypeChanged() { + return this.modifiedParameters.contains("lockinPeriodType"); + } + + public boolean isPartialDepositAllowedChanged() { + return this.modifiedParameters.contains("isPartialDepositAllowed"); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/command/SavingAccountCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/command/SavingAccountCommandValidator.java new file mode 100644 index 000000000..d6831abac --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/command/SavingAccountCommandValidator.java @@ -0,0 +1,106 @@ +package org.mifosplatform.portfolio.savingsaccount.command; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; + +public class SavingAccountCommandValidator { + + private final SavingAccountCommand command; + + public SavingAccountCommandValidator(final SavingAccountCommand command) { + this.command = command; + } + + public void validateForCreate() { + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account"); + + baseDataValidator.reset().parameter("clientId").value(command.getClientId()).notNull(); + baseDataValidator.reset().parameter("productId").value(command.getProductId()).notNull(); + baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); + baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank(); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6); + baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(command.getSavingsDepositAmount()).notNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("recurringInterestRate").value(command.getRecurringInterestRate()).notNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("savingInterestRate") + .comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate()); + baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).notNull(); + baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull(); + baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull(); + baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull(); + baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).notNull(); + baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).notNull(); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).notNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()) + .trueOrFalseRequired(command.isPartialDepositAllowedChanged()).notNull(); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()) + .trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).notNull(); + baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).notNull(); + baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).notNull(); + baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).notNull(); + + 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("saving.account"); + + baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); + baseDataValidator.reset().parameter("clientId").value(command.getClientId()).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter("productId").value(command.getProductId()).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); + baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank(); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().inMinMaxRange(0, 6); + baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(command.getSavingsDepositAmount()).ignoreIfNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("recurringInterestRate").value(command.getRecurringInterestRate()).ignoreIfNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).ignoreIfNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("savingInterestRate") + .comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate()); + baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).ignoreIfNull(); + baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull(); + baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull(); + baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull(); + baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).ignoreIfNull(); + baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).ignoreIfNull(); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).ignoreIfNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()) + .trueOrFalseRequired(command.isPartialDepositAllowedChanged()).ignoreIfNull(); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()) + .trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).ignoreIfNull(); + baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).ignoreIfNull(); + baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).ignoreIfNull(); + baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull(); + baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull(); + + if (command.isNoFieldChanged()) { + StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append("deposit.account").append( + ".no.parameters.for.update"); + StringBuilder defaultEnglishMessage = new StringBuilder("No parameters passed for update."); + ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), + "id"); + dataValidationErrors.add(error); + } + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingAccountData.java new file mode 100644 index 000000000..ab18e4d3b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingAccountData.java @@ -0,0 +1,124 @@ +package org.mifosplatform.portfolio.savingsaccount.data; + +import java.math.BigDecimal; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; + +/** + * Immutable data object reprsenting a savings account. + */ +public class SavingAccountData { + + @SuppressWarnings("unused") + private final Long id; + @SuppressWarnings("unused") + private final EnumOptionData status; + @SuppressWarnings("unused") + private final String externalId; + @SuppressWarnings("unused") + private final Long clientId; + @SuppressWarnings("unused") + private final String clientName; + @SuppressWarnings("unused") + private final Long productId; + @SuppressWarnings("unused") + private final String productName; + @SuppressWarnings("unused") + private final EnumOptionData productType; + @SuppressWarnings("unused") + private final CurrencyData currencyData; + @SuppressWarnings("unused") + private final BigDecimal savingsDepostiAmountPerPeriod; + @SuppressWarnings("unused") + private final EnumOptionData savingsFrequencyType; + @SuppressWarnings("unused") + private final BigDecimal totalDepositAmount; + @SuppressWarnings("unused") + private final BigDecimal reccuringInterestRate; + @SuppressWarnings("unused") + private final BigDecimal savingInterestRate; + @SuppressWarnings("unused") + private final EnumOptionData interestType; + @SuppressWarnings("unused") + private final EnumOptionData interestCalculationMethod; + @SuppressWarnings("unused") + private final Integer tenure; + @SuppressWarnings("unused") + private final EnumOptionData tenureType; + @SuppressWarnings("unused") + private final LocalDate projectedCommencementDate; + @SuppressWarnings("unused") + private final LocalDate actualCommencementDate; + @SuppressWarnings("unused") + private final LocalDate maturesOnDate; + @SuppressWarnings("unused") + private final BigDecimal projectedInterestAccuredOnMaturity; + @SuppressWarnings("unused") + private final BigDecimal actualInterestAccured; + @SuppressWarnings("unused") + private final BigDecimal projectedMaturityAmount; + @SuppressWarnings("unused") + private final BigDecimal actualMaturityAmount; + @SuppressWarnings("unused") + private final boolean preClosureAllowed; + @SuppressWarnings("unused") + private final BigDecimal preClosureInterestRate; + @SuppressWarnings("unused") + private final LocalDate withdrawnonDate; + @SuppressWarnings("unused") + private final LocalDate rejectedonDate; + @SuppressWarnings("unused") + private final LocalDate closedonDate; + @SuppressWarnings("unused") + private final boolean isLockinPeriodAllowed; + @SuppressWarnings("unused") + private final Integer lockinPeriod; + @SuppressWarnings("unused") + private final EnumOptionData lockinPeriodType; + + public SavingAccountData(Long id, EnumOptionData status, String externalId, Long clientId, String clientName, Long productId, + String productName, EnumOptionData productType, CurrencyData currencyData, BigDecimal savingsDepostiAmountPerPeriod, + EnumOptionData savingsFrequencyType, BigDecimal totalDepositAmount, BigDecimal reccuringInterestRate, + BigDecimal savingInterestRate, EnumOptionData interestType, EnumOptionData interestCalculationMethod, Integer tenure, + EnumOptionData tenureType, LocalDate projectedCommencementDate, LocalDate actualCommencementDate, LocalDate maturesOnDate, + BigDecimal projectedInterestAccuredOnMaturity, BigDecimal actualInterestAccured, BigDecimal projectedMaturityAmount, + BigDecimal actualMaturityAmount, boolean preClosureAllowed, BigDecimal preClosureInterestRate, LocalDate withdrawnonDate, + LocalDate rejectedonDate, LocalDate closedonDate, boolean isLockinPeriodAllowed, Integer lockinPeriod, + EnumOptionData lockinPeriodType) { + this.id = id; + this.status = status; + this.externalId = externalId; + this.clientId = clientId; + this.clientName = clientName; + this.productId = productId; + this.productName = productName; + this.productType = productType; + this.currencyData = currencyData; + this.savingsDepostiAmountPerPeriod = savingsDepostiAmountPerPeriod; + this.savingsFrequencyType = savingsFrequencyType; + this.totalDepositAmount = totalDepositAmount; + this.reccuringInterestRate = reccuringInterestRate; + this.savingInterestRate = savingInterestRate; + this.interestType = interestType; + this.interestCalculationMethod = interestCalculationMethod; + this.tenure = tenure; + this.tenureType = tenureType; + this.projectedCommencementDate = projectedCommencementDate; + this.actualCommencementDate = actualCommencementDate; + this.maturesOnDate = maturesOnDate; + this.projectedInterestAccuredOnMaturity = projectedInterestAccuredOnMaturity; + this.actualInterestAccured = actualInterestAccured; + this.projectedMaturityAmount = projectedMaturityAmount; + this.actualMaturityAmount = actualMaturityAmount; + this.preClosureAllowed = preClosureAllowed; + this.preClosureInterestRate = preClosureInterestRate; + this.withdrawnonDate = withdrawnonDate; + this.rejectedonDate = rejectedonDate; + this.closedonDate = closedonDate; + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + this.lockinPeriod = lockinPeriod; + this.lockinPeriodType = lockinPeriodType; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/ReccuringDepositInterestCalculator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/ReccuringDepositInterestCalculator.java new file mode 100644 index 000000000..9ae7199c6 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/ReccuringDepositInterestCalculator.java @@ -0,0 +1,74 @@ +package org.mifosplatform.portfolio.savingsaccount.domain; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; +import org.springframework.stereotype.Service; + +@Service +public class ReccuringDepositInterestCalculator { + + // FIXME - MADHUKAR - Are the unused field here needed? + public Money calculateInterestOnMaturityFor(Money savingsDepositPerPeriod, Integer tenure, BigDecimal reccuringInterestRate, + LocalDate commencementDate, TenureTypeEnum tenureTypeEnum, SavingFrequencyType savingFrequencyType, + SavingInterestCalculationMethod savingInterestCalculationMethod) { + + /* + * // Assuming tenure in months // see + * http://www.onemint.com/2012/04/03/ + * how-to-calculate-interest-on-recurring-deposits/ + * + * A=P(1+r/n)^nt + * + * A = final amount P = principal amount (initial investment) r = annual + * nominal interest rate (as a decimal, not in percentage) n = number of + * times the interest is compounded per year t = number of years + */ + MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); + Integer monthsInYear = 12; + + BigDecimal interestRateAsFraction = reccuringInterestRate.divide(BigDecimal.valueOf(100), mc); + Integer noofTimesInterestCompoundPerYear = Integer.valueOf(0); + switch (savingFrequencyType) { + case MONTHLY: + noofTimesInterestCompoundPerYear = monthsInYear; + break; + case QUATERLY: + noofTimesInterestCompoundPerYear = monthsInYear / 3; + break; + case HALFYEARLY: + noofTimesInterestCompoundPerYear = monthsInYear / 6; + break; + case YEARLY: + noofTimesInterestCompoundPerYear = monthsInYear / 12; + break; + default: + throw new RuntimeException("The specified frequency not supported"); + + } + + BigDecimal interestRatePerPeriod = BigDecimal.valueOf(interestRateAsFraction.doubleValue() + / noofTimesInterestCompoundPerYear.doubleValue()); + BigDecimal onePlusInterestRatePerPeriod = BigDecimal.ONE.add(interestRatePerPeriod); + BigDecimal monthsExpressedInYears; + BigDecimal timeforOneCalculationPeriod; + BigDecimal amountPerPeriod; + BigDecimal finalAmount = BigDecimal.ZERO; + while (tenure > 0) { + monthsExpressedInYears = BigDecimal.valueOf(tenure.doubleValue() / monthsInYear.doubleValue()); + timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear * monthsExpressedInYears.doubleValue()); + amountPerPeriod = savingsDepositPerPeriod.getAmount().multiply( + BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(), timeforOneCalculationPeriod.doubleValue()))); + finalAmount = finalAmount.add(amountPerPeriod); + tenure--; + } + + return Money.of(savingsDepositPerPeriod.getCurrency(), finalAmount); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccount.java new file mode 100644 index 000000000..25599572f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccount.java @@ -0,0 +1,337 @@ +package org.mifosplatform.portfolio.savingsaccount.domain; + +import java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; +import org.mifosplatform.infrastructure.user.domain.AppUser; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountEvent; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachine; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; + +@Entity +@Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name = "saving_acc_external_id", columnNames = { "external_id" })) +public class SavingAccount extends AbstractAuditableCustom { + + @ManyToOne + @JoinColumn(name = "client_id", nullable = false) + private Client client; + + @ManyToOne + @JoinColumn(name = "product_id") + private SavingProduct product; + + // FIXME - MADHUKAR - Do not use the actual enum type here but instead use + // Integer e.g. private Integer savingProductType; + @Column(name = "savings_product_type", nullable = false) + private SavingProductType savingProductType; + + @Column(name = "external_id") + private String externalId; + + @SuppressWarnings("unused") + @Embedded + private MonetaryCurrency currency; + + @Column(name = "deposit_amount_per_period", scale = 6, precision = 19, nullable = false) + private BigDecimal savingsDepositAmountPerPeriod; + + @SuppressWarnings("unused") + @Column(name = "total_deposit_amount", scale = 6, precision = 19, nullable = false) + private BigDecimal totalSavingsAmount; + + @Column(name = "reccuring_nominal_interest_rate", scale = 6, precision = 19, nullable = false) + private BigDecimal reccuringInterestRate; + + @Column(name = "regular_saving_nominal_interest_rate", scale = 6, precision = 19, nullable = false) + private BigDecimal savingInterestRate; + + @Column(name = "tenure", nullable = false) + private Integer tenure; + + @Column(name = "tenure_type", nullable = false) + private TenureTypeEnum tenureType; + + // FIXME - MADHUKAR - Do not use the actual enum type here but instead use + // Integer e.g. private Integer savingProductType; + @Column(name = "frequency", nullable = false) + private SavingFrequencyType frequency; + + // FIXME - MADHUKAR - Do not use the actual enum type here but instead use + // Integer e.g. private Integer savingProductType; + @Column(name = "interest_type", nullable = false) + private SavingsInterestType interestType; + + // FIXME - MADHUKAR - Do not use the actual enum type here but instead use + // Integer e.g. private Integer savingProductType; + @Column(name = "interest_calculation_method") + private SavingInterestCalculationMethod interestCalculationMethod; + + @Temporal(TemporalType.DATE) + @Column(name = "projected_commencement_date") + private Date projectedCommencementDate; + + @SuppressWarnings("unused") + @Temporal(TemporalType.DATE) + @Column(name = "actual_commencement_date") + private Date actualCommencementDate; + + @SuppressWarnings("unused") + @Temporal(TemporalType.DATE) + @Column(name = "matures_on_date") + private Date maturesOnDate; + + @SuppressWarnings("unused") + @Column(name = "projected_interest_accrued_on_maturity", scale = 6, precision = 19, nullable = false) + private BigDecimal projectedInterestAccruedOnMaturity; + + @SuppressWarnings("unused") + @Column(name = "actual_interest_accrued", scale = 6, precision = 19, nullable = false) + private BigDecimal interestAccrued; + + @SuppressWarnings("unused") + @Column(name = "projected_total_maturity_amount", scale = 6, precision = 19, nullable = false) + private BigDecimal projectedTotalOnMaturity; + + @SuppressWarnings("unused") + @Column(name = "actual_total_amount", scale = 6, precision = 19, nullable = false) + private BigDecimal total; + + @Column(name = "pre_closure_interest_rate", scale = 6, precision = 19, nullable = false) + private BigDecimal preClosureInterestRate; + + @Column(name = "is_preclosure_allowed", nullable = false) + private boolean preClosureAllowed = false; + + @Column(name = "is_deleted", nullable = false) + private boolean deleted = false; + + @Column(name = "status_enum", nullable = false) + private Integer accountStatus; + + @SuppressWarnings("unused") + @Temporal(TemporalType.DATE) + @Column(name = "closedon_date") + private Date closedOnDate; + + @SuppressWarnings("unused") + @Temporal(TemporalType.DATE) + @Column(name = "rejectedon_date") + private Date rejectedOnDate; + + @Temporal(TemporalType.DATE) + @Column(name = "withdrawnon_date") + private Date withdrawnOnDate; + + @Column(name = "is_lock_in_period_allowed", nullable = false) + private boolean isLockinPeriodAllowed = false; + + @Column(name = "lock_in_period", nullable = false) + private Integer lockinPeriod; + + @Column(name = "lock_in_period_type", nullable = false) + private PeriodFrequencyType lockinPeriodType; + + public static SavingAccount openNew(Client client, SavingProduct product, String externalId, Money savingsDeposit, + BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, + TenureTypeEnum tenureTypeEnum, SavingProductType savingProductType, SavingFrequencyType savingFrequencyType, + SavingsInterestType interestType, SavingInterestCalculationMethod savingInterestCalculationMethod, + boolean isLockinPeriodAllowed, Integer lockinPeriod, PeriodFrequencyType lockinPeriodType, + ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, final DepositLifecycleStateMachine lifecycleStateMachine) { + + Money futureValueOnMaturity = null; + if (savingProductType.isReccuring()) { + futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, + reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); + } else if (savingProductType.isRegular()) { + futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, + savingInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); + } + + return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, + commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, interestType, savingInterestCalculationMethod, + isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine); + } + + public SavingAccount(Client client, String externalId, SavingProduct product, Money savingsDeposit, BigDecimal reccuringInterestRate, + BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum, + SavingProductType savingProductType, SavingFrequencyType savingFrequencyType, SavingsInterestType interestType, + SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod, + PeriodFrequencyType lockinPeriodType, Money futureValueOnMaturity, final DepositLifecycleStateMachine lifecycleStateMachine) { + + DepositAccountStatus from = null; + if (accountStatus != null) { + from = DepositAccountStatus.fromInt(accountStatus); + } + + DepositAccountStatus statusEnum = lifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CREATED, from); + accountStatus = statusEnum.getValue(); + + this.total = BigDecimal.ZERO; + this.preClosureInterestRate = BigDecimal.ZERO; + this.totalSavingsAmount = BigDecimal.ZERO; + this.interestAccrued = BigDecimal.ZERO; + + this.client = client; + this.externalId = externalId; + this.product = product; + this.savingsDepositAmountPerPeriod = savingsDeposit.getAmount(); + this.currency = savingsDeposit.getCurrency(); + this.reccuringInterestRate = reccuringInterestRate; + this.savingInterestRate = savingInterestRate; + this.tenure = tenure; + this.projectedCommencementDate = commencementDate.toDate(); + this.tenureType = tenureTypeEnum; + this.savingProductType = savingProductType; + this.frequency = savingFrequencyType; + this.interestType = interestType; + this.interestCalculationMethod = savingInterestCalculationMethod; + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + this.lockinPeriod = lockinPeriod; + this.lockinPeriodType = lockinPeriodType; + this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); + this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.getAmount().subtract( + BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue())); + } + + public void modifyAccount(SavingProduct product, String externalId, Money savingsDeposit, BigDecimal reccuringInterestRate, + BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum, + SavingProductType savingProductType, SavingFrequencyType savingFrequencyType, + SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod, + PeriodFrequencyType lockinPeriodType, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) { + + Money futureValueOnMaturity = null; + if (savingProductType.isReccuring()) { + futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, + reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); + } else if (savingProductType.isRegular()) { + futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, + savingInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod); + } + + this.product = product; + this.externalId = externalId; + this.savingsDepositAmountPerPeriod = savingsDeposit.getAmount(); + this.reccuringInterestRate = reccuringInterestRate; + this.savingInterestRate = savingInterestRate; + this.tenure = tenure; + this.projectedCommencementDate = commencementDate.toDate(); + this.tenureType = tenureTypeEnum; + this.savingProductType = savingProductType; + this.frequency = savingFrequencyType; + this.interestCalculationMethod = savingInterestCalculationMethod; + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + this.lockinPeriod = lockinPeriod; + this.lockinPeriodType = lockinPeriodType; + + // FIXME - MADHUKAR - futureValueOnMaturity is possibly null + this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); + this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.getAmount().subtract( + BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue())); + } + + public boolean isDeleted() { + return this.deleted; + } + + public boolean isPendingApproval() { + return this.accountStatus.equals(100); + } + + public Client getClient() { + return client; + } + + public SavingProduct getProduct() { + return product; + } + + public SavingProductType getSavingProductType() { + return savingProductType; + } + + public String getExternalId() { + return externalId; + } + + public BigDecimal getSavingsDepositAmountPerPeriod() { + return savingsDepositAmountPerPeriod; + } + + public BigDecimal getReccuringInterestRate() { + return reccuringInterestRate; + } + + public BigDecimal getSavingInterestRate() { + return savingInterestRate; + } + + public Integer getTenure() { + return tenure; + } + + public TenureTypeEnum getTenureType() { + return tenureType; + } + + public SavingFrequencyType getFrequency() { + return frequency; + } + + public SavingsInterestType getInterestType() { + return interestType; + } + + public SavingInterestCalculationMethod getInterestCalculationMethod() { + return interestCalculationMethod; + } + + public Date getProjectedCommencementDate() { + return projectedCommencementDate; + } + + public BigDecimal getPreClosureInterestRate() { + return preClosureInterestRate; + } + + public boolean isPreClosureAllowed() { + return preClosureAllowed; + } + + public Date getWithdrawnOnDate() { + return withdrawnOnDate; + } + + public boolean isLockinPeriodAllowed() { + return isLockinPeriodAllowed; + } + + public Integer getLockinPeriod() { + return lockinPeriod; + } + + public PeriodFrequencyType getLockinPeriodType() { + return lockinPeriodType; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccountRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccountRepository.java similarity index 81% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccountRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccountRepository.java index 16a7944cc..a65b7f432 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/SavingAccountRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccountRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsaccount.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingAccountNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/exception/SavingAccountNotFoundException.java similarity index 85% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingAccountNotFoundException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/exception/SavingAccountNotFoundException.java index d98c74e09..ba2cdf1f9 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingAccountNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/exception/SavingAccountNotFoundException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsaccount.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountAssembler.java new file mode 100644 index 000000000..1a77ba55b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountAssembler.java @@ -0,0 +1,203 @@ +package org.mifosplatform.portfolio.savingsaccount.service; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.portfolio.client.domain.Client; +import org.mifosplatform.portfolio.client.domain.ClientRepository; +import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; +import org.mifosplatform.portfolio.savingsaccount.domain.ReccuringDepositInterestCalculator; +import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductRepository; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType; +import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingsProductNotFoundException; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachine; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachineImpl; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class SavingAccountAssembler { + + private final ClientRepository clientRepository; + private final SavingProductRepository savingProductRepository; + private final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator; + + @Autowired + public SavingAccountAssembler(final ClientRepository clientRepository, final SavingProductRepository savingProductRepository, + final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) { + this.clientRepository = clientRepository; + this.savingProductRepository = savingProductRepository; + this.reccuringDepositInterestCalculator = reccuringDepositInterestCalculator; + } + + // minimumBalanceForWithdrawal,isPartialDepositAllowed + public SavingAccount assembleFrom(SavingAccountCommand command) { + + Client client = this.clientRepository.findOne(command.getClientId()); + if (client == null || client.isDeleted()) { throw new ClientNotFoundException(command.getClientId()); } + + SavingProduct product = this.savingProductRepository.findOne(command.getProductId()); + if (product == null || product.isDeleted()) { throw new SavingsProductNotFoundException(command.getProductId()); } + + MonetaryCurrency currency = product.getCurrency(); + if (command.getCurrencyCode() != null && command.getDigitsAfterDecimal() != null) { + currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); + } + + Money savingsDeposit = Money.of(currency, command.getSavingsDepositAmount()); + + Integer tenure = product.getSavingProductRelatedDetail().getTenure(); + if (command.getTenure() != null) { + tenure = command.getTenure(); + } + + TenureTypeEnum tenureTypeEnum = product.getSavingProductRelatedDetail().getTenureType(); + if (command.getTenureType() != null) { + tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); + } + + SavingProductType savingProductType = product.getSavingProductRelatedDetail().getSavingProductType(); + if (command.getSavingProductType() != null) { + savingProductType = SavingProductType.fromInt(command.getSavingProductType()); + } + + SavingFrequencyType savingFrequencyType = product.getSavingProductRelatedDetail().getFrequency(); + if (command.getFrequency() != null) { + savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); + } + + SavingInterestCalculationMethod savingInterestCalculationMethod = product.getSavingProductRelatedDetail() + .getInterestCalculationMethod(); + if (command.getInterestCalculationMethod() != null) { + savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); + } + + SavingsInterestType interestType = product.getSavingProductRelatedDetail().getInterestType(); + if (command.getInterestType() != null) { + interestType = SavingsInterestType.fromInt(command.getInterestType()); + } + + BigDecimal reccuringInterestRate = command.getRecurringInterestRate(); + BigDecimal savingInterestRate = product.getInterestRate(); + if (command.getSavingInterestRate() != null) savingInterestRate = command.getSavingInterestRate(); + + boolean isLockinPeriodAllowed = product.getSavingProductRelatedDetail().isLockinPeriodAllowed(); + if (command.isLockinPeriodChanged()) { + isLockinPeriodAllowed = command.isLockinPeriodAllowed(); + } + + Integer lockinPeriod = product.getSavingProductRelatedDetail().getLockinPeriod(); + if (command.getLockinPeriod() != null) { + lockinPeriod = command.getLockinPeriod(); + } + + PeriodFrequencyType lockinPeriodType = product.getSavingProductRelatedDetail().getLockinPeriodType(); + if (command.getLockinPeriodType() != null) { + lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + } + + SavingAccount account = SavingAccount.openNew(client, product, command.getExternalId(), savingsDeposit, reccuringInterestRate, + savingInterestRate, tenure, command.getCommencementDate(), tenureTypeEnum, savingProductType, savingFrequencyType, + interestType, savingInterestCalculationMethod, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, + this.reccuringDepositInterestCalculator, defaultDepositLifecycleStateMachine()); + + return account; + } + + public void assembleFrom(SavingAccountCommand command, SavingAccount account) { + + SavingProduct product = account.getProduct(); + if (command.isProductIdChanged()) { + if (product.getId() != command.getProductId()) { + product = this.savingProductRepository.findOne(command.getProductId()); + if (product == null || product.isDeleted()) throw new SavingsProductNotFoundException(command.getProductId()); + } + } + + String externalId = account.getExternalId(); + if (command.isExternalIdChanged()) { + externalId = command.getExternalId(); + } + + Money savingsDeposit = Money.of(product.getCurrency(), account.getSavingsDepositAmountPerPeriod()); + if (command.isDepositAmountChanged()) { + savingsDeposit = Money.of(product.getCurrency(), command.getSavingsDepositAmount()); + } + Integer tenure = account.getTenure(); + if (command.isTenureInMonthsChanged()) { + tenure = command.getTenure(); + } + + LocalDate commencementDate = new LocalDate(account.getProjectedCommencementDate()); + if (command.isCommencementDateChanged()) { + commencementDate = command.getCommencementDate(); + } + + TenureTypeEnum tenureTypeEnum = account.getTenureType(); + if (command.isTenureTypeEnumChanged()) { + tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); + } + + SavingProductType savingProductType = account.getSavingProductType(); + if (command.isSavingProductTypeChanged()) { + savingProductType = SavingProductType.fromInt(command.getSavingProductType()); + } + + SavingFrequencyType savingFrequencyType = account.getFrequency(); + if (command.isSavingFrequencyTypeChanged()) { + savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); + } + + SavingInterestCalculationMethod savingInterestCalculationMethod = account.getInterestCalculationMethod(); + if (command.isSavingInterestCalculationMethodChanged()) { + savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); + } + + BigDecimal reccuringInterestRate = account.getReccuringInterestRate(); + if (command.isReccuringInterestRateChanged()) { + reccuringInterestRate = command.getRecurringInterestRate(); + } + + BigDecimal savingInterestRate = account.getSavingInterestRate(); + if (command.isSavingInterestRateChanged()) { + savingInterestRate = command.getSavingInterestRate(); + } + + boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); + if (command.isLockinPeriodAllowedChanged()) { + isLockinPeriodAllowed = command.isLockinPeriodAllowed(); + } + + Integer lockinPeriod = account.getLockinPeriod(); + if (command.isLockinPeriodChanged()) { + lockinPeriod = command.getLockinPeriod(); + } + + PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType(); + if (command.isLockinPeriodTypeChanged()) { + lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + } + account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, commencementDate, + tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, isLockinPeriodAllowed, + lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator); + + } + + private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() { + List allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values()); + return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountReadPlatformService.java new file mode 100644 index 000000000..06ae7dd0b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountReadPlatformService.java @@ -0,0 +1,12 @@ +package org.mifosplatform.portfolio.savingsaccount.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData; + +public interface SavingAccountReadPlatformService { + + Collection retrieveAllSavingsAccounts(); + + SavingAccountData retrieveSavingsAccount(Long accountId); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountReadPlatformServiceImpl.java new file mode 100644 index 000000000..cd74f16e1 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountReadPlatformServiceImpl.java @@ -0,0 +1,142 @@ +package org.mifosplatform.portfolio.savingsaccount.service; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations; +import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountEnumerations; +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 SavingAccountReadPlatformServiceImpl implements SavingAccountReadPlatformService { + + private final PlatformSecurityContext context; + private final JdbcTemplate jdbcTemplate; + + @Autowired + public SavingAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public Collection retrieveAllSavingsAccounts() { + + this.context.authenticatedUser(); + SavingAccountMapper mapper = new SavingAccountMapper(); + String sql = "select " + mapper.schema() + " where sa.is_deleted=0"; + return this.jdbcTemplate.query(sql, mapper, new Object[] {}); + + } + + @Override + public SavingAccountData retrieveSavingsAccount(Long accountId) { + + this.context.authenticatedUser(); + SavingAccountMapper mapper = new SavingAccountMapper(); + String sql = "select " + mapper.schema() + " where sa.id = ? and sa.is_deleted=0"; + SavingAccountData savingAccountData = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { accountId }); + return savingAccountData; + } + + private static final class SavingAccountMapper implements RowMapper { + + public String schema() { + return "sa.id AS id, sa.status_enum AS status, sa.external_id AS externalId," + + " sa.client_id AS clientId, sa.product_id AS productId, sa.deposit_amount_per_period AS savingsDepostiAmountPerPeriod," + + " sa.savings_product_type AS savingsProductType, sa.currency_code AS currencyCode, sa.currency_digits AS currencyDigits," + + " sa.total_deposit_amount AS totalDepositAmount, sa.reccuring_nominal_interest_rate AS reccuringInterestRate," + + " sa.regular_saving_nominal_interest_rate AS savingInterestRate, sa.tenure AS tenure, sa.tenure_type AS tenureType," + + " sa.frequency AS savingsFrequencyType, sa.interest_type AS interestType, sa.interest_calculation_method AS interestCalculationMethod," + + " sa.projected_commencement_date AS projectedCommencementDate, sa.actual_commencement_date AS actualCommencementDate," + + " sa.matures_on_date AS maturesOnDate, sa.projected_interest_accrued_on_maturity AS projectedInterestAccuredOnMaturity," + + " sa.actual_interest_accrued AS actualInterestAccured, sa.projected_total_maturity_amount AS projectedTotalMaturityAmount," + + " sa.actual_total_amount AS actualTotalAmount, sa.is_preclosure_allowed AS isPreclosureAllowed," + + " sa.pre_closure_interest_rate AS preClosureInterestRate, sa.is_lock_in_period_allowed AS isLockinPeriodAllowed," + + " sa.lock_in_period AS lockinPeriod, sa.lock_in_period_type AS lockinPeriodType, sa.withdrawnon_date AS withdrawnonDate," + + " sa.rejectedon_date AS rejectedonDate, sa.closedon_date AS closedonDate, ps.name AS productName," + + " c.firstname AS firstname, c.lastname AS lastname, curr.name AS currencyName, " + + " curr.internationalized_name_code AS currencyNameCode, curr.display_symbol AS currencyDisplaySymbol " + + " FROM m_saving_account sa " + " JOIN m_client c ON c.id = sa.client_id" + + " JOIN m_currency curr ON curr.code = sa.currency_code " + " JOIN m_product_savings ps ON sa.product_id = ps.id "; + } + + @Override + public SavingAccountData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + + Long id = rs.getLong("id"); + String externalId = rs.getString("externalId"); + Long clientId = rs.getLong("clientId"); + String clientName = rs.getString("firstname") + " " + rs.getString("lastname"); + + Long productId = rs.getLong("productId"); + String productName = rs.getString("productName"); + EnumOptionData productType = SavingProductEnumerations.savingProductType(JdbcSupport.getInteger(rs, "savingsProductType")); + + Integer statusId = JdbcSupport.getInteger(rs, "status"); + EnumOptionData status = DepositAccountEnumerations.status(statusId); + + String currencyCode = rs.getString("currencyCode"); + String currencyName = rs.getString("currencyName"); + String currencyNameCode = rs.getString("currencyNameCode"); + String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); + Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits"); + CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol, + currencyNameCode); + + BigDecimal savingsDepostiAmountPerPeriod = rs.getBigDecimal("savingsDepostiAmountPerPeriod"); + EnumOptionData savingsFrequencyType = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs, + "savingsFrequencyType")); + BigDecimal totalDepositAmount = rs.getBigDecimal("totalDepositAmount"); + + BigDecimal reccuringInterestRate = rs.getBigDecimal("reccuringInterestRate"); + BigDecimal savingInterestRate = rs.getBigDecimal("savingInterestRate"); + EnumOptionData interestType = SavingProductEnumerations.savingInterestType(JdbcSupport.getInteger(rs, "interestType")); + EnumOptionData interestCalculationMethod = SavingProductEnumerations.savingInterestCalculationMethod(JdbcSupport.getInteger(rs, + "interestCalculationMethod")); + + Integer tenure = JdbcSupport.getInteger(rs, "tenure"); + EnumOptionData tenureType = SavingProductEnumerations.tenureTypeEnum(JdbcSupport.getInteger(rs, "tenureType")); + + LocalDate projectedCommencementDate = JdbcSupport.getLocalDate(rs, "projectedCommencementDate"); + LocalDate actualCommencementDate = JdbcSupport.getLocalDate(rs, "actualCommencementDate"); + LocalDate maturesOnDate = JdbcSupport.getLocalDate(rs, "maturesOnDate"); + BigDecimal projectedInterestAccuredOnMaturity = rs.getBigDecimal("projectedInterestAccuredOnMaturity"); + BigDecimal actualInterestAccured = rs.getBigDecimal("actualInterestAccured"); + + BigDecimal projectedMaturityAmount = rs.getBigDecimal("projectedTotalMaturityAmount"); + BigDecimal actualMaturityAmount = rs.getBigDecimal("actualTotalAmount"); + + boolean preClosureAllowed = rs.getBoolean("isPreclosureAllowed"); + BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate"); + + LocalDate withdrawnonDate = JdbcSupport.getLocalDate(rs, "withdrawnonDate"); + LocalDate rejectedonDate = JdbcSupport.getLocalDate(rs, "rejectedonDate"); + LocalDate closedonDate = JdbcSupport.getLocalDate(rs, "closedonDate"); + + boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed"); + Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod"); + Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType"); + EnumOptionData lockinPeriodType = SavingProductEnumerations.savingsLockinPeriod(lockinPeriodTypeValue); + + return new SavingAccountData(id, status, externalId, clientId, clientName, productId, productName, productType, currencyData, + savingsDepostiAmountPerPeriod, savingsFrequencyType, totalDepositAmount, reccuringInterestRate, savingInterestRate, + interestType, interestCalculationMethod, tenure, tenureType, projectedCommencementDate, actualCommencementDate, + maturesOnDate, projectedInterestAccuredOnMaturity, actualInterestAccured, projectedMaturityAmount, + actualMaturityAmount, preClosureAllowed, preClosureInterestRate, withdrawnonDate, rejectedonDate, closedonDate, + isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformService.java new file mode 100644 index 000000000..d9b850fe9 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformService.java @@ -0,0 +1,14 @@ +package org.mifosplatform.portfolio.savingsaccount.service; + +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface SavingAccountWritePlatformService { + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_SAVINGSACCOUNT')") + EntityIdentifier createSavingAccount(SavingAccountCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_SAVINGSACCOUNT')") + EntityIdentifier updateSavingAccount(SavingAccountCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..3b297a7a1 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingAccountWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,94 @@ +package org.mifosplatform.portfolio.savingsaccount.service; + +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.client.domain.NoteRepository; +import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; +import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommandValidator; +import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount; +import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccountRepository; +import org.mifosplatform.portfolio.savingsaccount.exception.SavingAccountNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements SavingAccountWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(SavingAccountWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final SavingAccountRepository savingAccountRepository; + private final SavingAccountAssembler savingAccountAssembler; + @SuppressWarnings("unused") + private final NoteRepository noteRepository; + + @Autowired + public SavingAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, + final SavingAccountRepository savingAccountRepository, final SavingAccountAssembler savingAccountAssembler, + final NoteRepository noteRepository) { + this.context = context; + this.savingAccountRepository = savingAccountRepository; + this.savingAccountAssembler = savingAccountAssembler; + this.noteRepository = noteRepository; + } + + @Transactional + @Override + public EntityIdentifier createSavingAccount(final SavingAccountCommand command) { + try { + this.context.authenticatedUser(); + SavingAccountCommandValidator validator = new SavingAccountCommandValidator(command); + validator.validateForCreate(); + + SavingAccount account = this.savingAccountAssembler.assembleFrom(command); + this.savingAccountRepository.save(account); + + return new EntityIdentifier(account.getId()); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new EntityIdentifier(Long.valueOf(-1)); + } + + } + + @Override + public EntityIdentifier updateSavingAccount(final SavingAccountCommand command) { + try { + this.context.authenticatedUser(); + SavingAccountCommandValidator validator = new SavingAccountCommandValidator(command); + validator.validateForUpdate(); + + SavingAccount account = this.savingAccountRepository.findOne(command.getId()); + if (account == null || account.isDeleted()) { throw new SavingAccountNotFoundException(command.getId()); } + if (account.isPendingApproval()) { + this.savingAccountAssembler.assembleFrom(command, account); + this.savingAccountRepository.save(account); + } + return new EntityIdentifier(account.getId()); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new EntityIdentifier(Long.valueOf(-1)); + } + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleDataIntegrityIssues(final SavingAccountCommand command, final DataIntegrityViolationException dve) { + + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("saving_acc_external_id")) { throw new PlatformDataIntegrityException( + "error.msg.saving.account.duplicate.externalId", "Saving account with externalId " + command.getExternalId() + + " already exists", "externalId", command.getExternalId()); } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.saving.account.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java similarity index 90% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/SavingProductsApiResource.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java index 246d1cbc4..244a2bd7e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/SavingProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api; +package org.mifosplatform.portfolio.savingsaccountproduct.api; import java.util.Arrays; import java.util.Collection; @@ -19,17 +19,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; -import org.mifosng.platform.api.commands.SavingProductCommand; -import org.mifosng.platform.api.data.SavingProductData; -import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; -import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; -import org.mifosng.platform.savingproduct.domain.SavingProductType; -import org.mifosng.platform.savingproduct.domain.SavingsInterestType; -import org.mifosng.platform.savingproduct.domain.SavingsLockinPeriodEnum; -import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; -import org.mifosng.platform.savingproduct.service.SavingProductEnumerations; -import org.mifosng.platform.savingproduct.service.SavingProductReadPlatformService; -import org.mifosng.platform.savingproduct.service.SavingProductWritePlatformService; import org.mifosplatform.infrastructure.configuration.data.CurrencyData; import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; @@ -38,6 +27,17 @@ import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerServi import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; +import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductData; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsLockinPeriodEnum; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductReadPlatformService; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductWritePlatformService; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SavingProductCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/command/SavingProductCommand.java similarity index 98% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SavingProductCommand.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/command/SavingProductCommand.java index 6ea17c8fd..47a093cae 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/commands/SavingProductCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/command/SavingProductCommand.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.commands; +package org.mifosplatform.portfolio.savingsaccountproduct.command; import java.math.BigDecimal; import java.util.Set; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/data/SavingProductData.java similarity index 99% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductData.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/data/SavingProductData.java index 341f77600..23e8e6c41 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/data/SavingProductData.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.data; +package org.mifosplatform.portfolio.savingsaccountproduct.data; import java.io.Serializable; import java.math.BigDecimal; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductLookup.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/data/SavingProductLookup.java similarity index 87% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductLookup.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/data/SavingProductLookup.java index f41b77050..52d3d97c0 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/SavingProductLookup.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/data/SavingProductLookup.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.data; +package org.mifosplatform.portfolio.savingsaccountproduct.data; import java.io.Serializable; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingFrequencyType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingFrequencyType.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingFrequencyType.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingFrequencyType.java index 1076515db..6fa426f74 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingFrequencyType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingFrequencyType.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; public enum SavingFrequencyType { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingInterestCalculationMethod.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingInterestCalculationMethod.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingInterestCalculationMethod.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingInterestCalculationMethod.java index 6fbb5f966..596f2eada 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingInterestCalculationMethod.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingInterestCalculationMethod.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; public enum SavingInterestCalculationMethod { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProduct.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProduct.java similarity index 93% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProduct.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProduct.java index 36f3d11fa..51081b96b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProduct.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProduct.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; import java.math.BigDecimal; @@ -8,11 +8,12 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; @Entity @Table(name = "m_product_savings") diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRelatedDetail.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRelatedDetail.java similarity index 96% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRelatedDetail.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRelatedDetail.java index d011454ec..21236bfb8 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRelatedDetail.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRelatedDetail.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; import java.math.BigDecimal; @@ -6,9 +6,10 @@ import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.Embedded; -import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; @Embeddable public class SavingProductRelatedDetail { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRepository.java similarity index 80% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRepository.java index 062b422df..d9885cbda 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductType.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductType.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductType.java index aea6a5731..127cc5b5b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingProductType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductType.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; public enum SavingProductType { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingsInterestType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingsInterestType.java similarity index 93% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingsInterestType.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingsInterestType.java index 61c6714f0..ed58801e1 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingsInterestType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingsInterestType.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; public enum SavingsInterestType { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingsLockinPeriodEnum.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingsLockinPeriodEnum.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingsLockinPeriodEnum.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingsLockinPeriodEnum.java index 05ef48cb2..29ab5621e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/SavingsLockinPeriodEnum.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingsLockinPeriodEnum.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsaccountproduct.domain; public enum SavingsLockinPeriodEnum { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingProductNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/exception/SavingProductNotFoundException.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingProductNotFoundException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/exception/SavingProductNotFoundException.java index b384f481f..efe2a7c39 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingProductNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/exception/SavingProductNotFoundException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsaccountproduct.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingsProductNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/exception/SavingsProductNotFoundException.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingsProductNotFoundException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/exception/SavingsProductNotFoundException.java index dc857d086..f8d473ca4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/SavingsProductNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/exception/SavingsProductNotFoundException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsaccountproduct.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductCommandValidator.java similarity index 97% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductCommandValidator.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductCommandValidator.java index b268a5518..da8226823 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductCommandValidator.java @@ -1,12 +1,12 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsaccountproduct.service; import java.util.ArrayList; import java.util.List; -import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; public class SavingProductCommandValidator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductEnumerations.java similarity index 92% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductEnumerations.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductEnumerations.java index f7c9d9544..0959deb5b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductEnumerations.java @@ -1,12 +1,12 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsaccountproduct.service; -import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; -import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; -import org.mifosng.platform.savingproduct.domain.SavingProductType; -import org.mifosng.platform.savingproduct.domain.SavingsInterestType; -import org.mifosng.platform.savingproduct.domain.SavingsLockinPeriodEnum; -import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsLockinPeriodEnum; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; public class SavingProductEnumerations { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductReadPlatformService.java similarity index 59% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformService.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductReadPlatformService.java index d53589c1a..1be8bd70d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductReadPlatformService.java @@ -1,9 +1,9 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsaccountproduct.service; import java.util.Collection; -import org.mifosng.platform.api.data.SavingProductData; -import org.mifosng.platform.api.data.SavingProductLookup; +import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductData; +import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductLookup; public interface SavingProductReadPlatformService { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductReadPlatformServiceImpl.java similarity index 96% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformServiceImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductReadPlatformServiceImpl.java index d0771d8d6..5895df132 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductReadPlatformServiceImpl.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsaccountproduct.service; import java.math.BigDecimal; import java.sql.ResultSet; @@ -7,9 +7,6 @@ import java.util.Collection; import java.util.List; import org.joda.time.DateTime; -import org.mifosng.platform.api.data.SavingProductData; -import org.mifosng.platform.api.data.SavingProductLookup; -import org.mifosng.platform.savingproduct.domain.SavingProductType; import org.mifosplatform.infrastructure.configuration.data.CurrencyData; import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; import org.mifosplatform.infrastructure.core.data.EnumOptionData; @@ -18,6 +15,9 @@ import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSourc import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException; +import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductData; +import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductLookup; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformService.java similarity index 82% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformService.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformService.java index f1abc6056..669a0280b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformService.java @@ -1,7 +1,7 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsaccountproduct.service; -import org.mifosng.platform.api.commands.SavingProductCommand; import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; import org.springframework.security.access.prepost.PreAuthorize; public interface SavingProductWritePlatformService { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java similarity index 79% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java index 0f53c27d8..81948eb65 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java @@ -1,19 +1,19 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsaccountproduct.service; -import org.mifosng.platform.api.commands.SavingProductCommand; -import org.mifosng.platform.exceptions.SavingsProductNotFoundException; -import org.mifosng.platform.exceptions.SavingProductNotFoundException; -import org.mifosng.platform.savingproduct.domain.SavingFrequencyType; -import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod; -import org.mifosng.platform.savingproduct.domain.SavingProduct; -import org.mifosng.platform.savingproduct.domain.SavingProductRepository; -import org.mifosng.platform.savingproduct.domain.SavingProductType; -import org.mifosng.platform.savingproduct.domain.SavingsInterestType; -import org.mifosng.platform.savingproduct.domain.TenureTypeEnum; import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductRepository; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType; +import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestType; +import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingProductNotFoundException; +import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingsProductNotFoundException; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingsDepositEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingsDepositEnumerations.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingsDepositEnumerations.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingsDepositEnumerations.java index fa4ef4cd7..f56a09742 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/SavingsDepositEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingsDepositEnumerations.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsaccountproduct.service; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/api/DepositAccountsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/api/DepositAccountsApiResource.java new file mode 100644 index 000000000..408c9096d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/api/DepositAccountsApiResource.java @@ -0,0 +1,261 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +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.QueryParam; +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.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService; +import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService; +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; +import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingsDepositEnumerations; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountData; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositPermissionData; +import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountReadPlatformService; +import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountWritePlatformService; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductLookup; +import org.mifosplatform.portfolio.savingsdepositproduct.service.DepositProductReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/depositaccounts") +@Component +@Scope("singleton") +public class DepositAccountsApiResource { + + @Autowired + private DepositAccountReadPlatformService depositAccountReadPlatformService; + + @Autowired + private DepositProductReadPlatformService depositProductReadPlatformService; + + @Autowired + private DepositAccountWritePlatformService depositAccountWritePlatformService; + + @Autowired + private PortfolioApiDataConversionService apiDataConversionService; + + @Autowired + private PortfolioApiJsonSerializerService apiJsonSerializerService; + + private final String entityType = "DEPOSITACCOUNT"; + @Autowired + private PlatformSecurityContext context; + + private static final Set typicalResponseParameters = new HashSet(Arrays.asList("id", "externalId", "clientId", + "clientName", "productId", "productName", "status", "currency", "deposit", "maturityInterestRate", "tenureInMonths", + "interestCompoundedEvery", "interestCompoundingAllowed", "interestCompoundedEveryPeriodType", "renewalAllowed", + "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "transactions", + "interestPaid", "isInterestWithdrawable", "availableInterestForWithdrawal", "availableWithdrawalAmount", "todaysDate", + "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType")); + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response createDepositAccount(final String jsonRequestBody) { + + final DepositAccountCommand command = this.apiDataConversionService.convertJsonToDepositAccountCommand(null, jsonRequestBody); + + EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.createDepositAccount(command); + + return Response.ok().entity(entityIdentifier).build(); + } + + @PUT + @Path("{accountId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response updateDepositAccount(@PathParam("accountId") final Long accountId, final String jsonRequestBody) { + + final DepositAccountCommand command = this.apiDataConversionService.convertJsonToDepositAccountCommand(accountId, jsonRequestBody); + + EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.updateDepositAccount(command); + + return Response.ok().entity(entityIdentifier).build(); + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + Collection accounts = this.depositAccountReadPlatformService.retrieveAllDepositAccounts(); + + return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, accounts); + } + + @GET + @Path("{accountId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + + DepositPermissionData permissions = null; + + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + DepositAccountData account = this.depositAccountReadPlatformService.retrieveDepositAccount(accountId); + + boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); + if (template) { + account = handleTemplateRelatedData(responseParameters, account); + } + + Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); + if (!associationParameters.isEmpty()) { + if (associationParameters.contains("all")) { + responseParameters.addAll(Arrays.asList("permissions")); + } else { + responseParameters.addAll(associationParameters); + } + permissions = this.depositAccountReadPlatformService.retrieveDepositAccountsPermissions(account); + account = new DepositAccountData(account, permissions, account.getTransactions()); + } + + return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, account); + } + + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveNewDepositAccountDetails(@QueryParam("clientId") final Long clientId, + @QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + DepositAccountData account = this.depositAccountReadPlatformService.retrieveNewDepositAccountDetails(clientId, productId); + + account = handleTemplateRelatedData(responseParameters, account); + + return this.apiJsonSerializerService.serializeDepositAccountDataToJson(prettyPrint, responseParameters, account); + } + + @DELETE + @Path("{accountId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response deleteProduct(@PathParam("accountId") final Long accountId) { + + this.depositAccountWritePlatformService.deleteDepositAccount(accountId); + + return Response.ok(new EntityIdentifier(accountId)).build(); + } + + private DepositAccountData handleTemplateRelatedData(final Set responseParameters, final DepositAccountData account) { + + responseParameters.addAll(Arrays.asList("interestCompoundedEveryPeriodTypeOptions", "productOptions")); + + Collection productOptions = depositProductReadPlatformService.retrieveAllDepositProductsForLookup(); + + EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS); + List interestCompoundedEveryPeriodTypeOptions = Arrays.asList(monthly); + + return new DepositAccountData(account, interestCompoundedEveryPeriodTypeOptions, productOptions); + } + + @POST + @Path("{accountId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response SubmitDepositApplication(@PathParam("accountId") final Long accountId, + @QueryParam("command") final String commandParam, final String jsonRequestBody) { + + Response response = null; + + if (is(commandParam, "approve")) { + DepositStateTransitionApprovalCommand command = apiDataConversionService.convertJsonToDepositStateTransitionApprovalCommand( + accountId, jsonRequestBody); + EntityIdentifier identifier = this.depositAccountWritePlatformService.approveDepositApplication(command); + response = Response.ok().entity(identifier).build(); + } else if (is(commandParam, "withdrawal")) { + DepositAccountWithdrawalCommand command = apiDataConversionService.convertJsonToDepositWithdrawalCommand(accountId, + jsonRequestBody); + EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountMoney(command); + response = Response.ok().entity(identifier).build(); + } else if (is(commandParam, "interestwithdraw")) { + DepositAccountWithdrawInterestCommand command = apiDataConversionService.convertJsonToDepositAccountWithdrawInterestCommand( + accountId, jsonRequestBody); + EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositAccountInterestMoney(command); + response = Response.ok().entity(identifier).build(); + } else if (is(commandParam, "renew")) { + DepositAccountCommand command = apiDataConversionService.convertJsonToDepositAccountCommand(accountId, jsonRequestBody); + EntityIdentifier entityIdentifier = this.depositAccountWritePlatformService.renewDepositAccount(command); + return Response.ok().entity(entityIdentifier).build(); + } else { + DepositStateTransitionCommand command = apiDataConversionService.convertJsonToDepositStateTransitionCommand(accountId, + jsonRequestBody); + if (is(commandParam, "reject")) { + EntityIdentifier identifier = this.depositAccountWritePlatformService.rejectDepositApplication(command); + response = Response.ok().entity(identifier).build(); + } else if (is(commandParam, "withdrewbyclient")) { + EntityIdentifier identifier = this.depositAccountWritePlatformService.withdrawDepositApplication(command); + response = Response.ok().entity(identifier).build(); + } + + UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); + + if (is(commandParam, "undoapproval")) { + EntityIdentifier identifier = this.depositAccountWritePlatformService.undoDepositApproval(undoCommand); + response = Response.ok().entity(identifier).build(); + } + } + + if (response == null) { throw new UnrecognizedQueryParamException("command", commandParam); } + + return response; + } + + private boolean is(final String commandParam, final String commandValue) { + return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountCommand.java new file mode 100644 index 000000000..58de23ac0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountCommand.java @@ -0,0 +1,195 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import java.math.BigDecimal; +import java.util.Set; + +import org.joda.time.LocalDate; + +/** + * Immutable command used when create/renewing deposit accounts + */ +public class DepositAccountCommand { + + private final Long id; + private final Long clientId; + private final Long productId; + private final String externalId; + + private final BigDecimal depositAmount; + private final BigDecimal maturityInterestRate; + private final BigDecimal preClosureInterestRate; + private final Integer tenureInMonths; + + private final boolean isLockinPeriodAllowed; + private final Integer lockinPeriod; + private final Integer lockinPeriodType; + + private final Integer interestCompoundedEvery; + private final Integer interestCompoundedEveryPeriodType; + private final LocalDate commencementDate; + + private final boolean renewalAllowed; + private final boolean preClosureAllowed; + private final boolean isInterestWithdrawable; + private final boolean interestCompoundingAllowed; + + private final Set modifiedParameters; + + public DepositAccountCommand(final Set modifiedParameters, final Long id, final Long clientId, final Long productId, + final String externalId, final BigDecimal depositAmount, final BigDecimal interestRate, + final BigDecimal preClosureInterestRate, final Integer tenureInMonths, final Integer compoundingInterestFrequency, + final Integer compoundingInterestFrequencyType, final LocalDate commencementDate, final boolean renewalAllowed, + final boolean preClosureAllowed, final boolean isInterstWithdrawable, final boolean interestCompoundingAllowed, + final boolean isLockinPeriodAllowed, final Integer lockInPeriod, final Integer lockinPeriodType) { + this.id = id; + this.clientId = clientId; + this.productId = productId; + this.externalId = externalId; + + this.depositAmount = depositAmount; + this.maturityInterestRate = interestRate; + this.preClosureInterestRate = preClosureInterestRate; + this.tenureInMonths = tenureInMonths; + + this.modifiedParameters = modifiedParameters; + this.interestCompoundedEvery = compoundingInterestFrequency; + this.interestCompoundedEveryPeriodType = compoundingInterestFrequencyType; + this.commencementDate = commencementDate; + this.renewalAllowed = renewalAllowed; + this.preClosureAllowed = preClosureAllowed; + this.isInterestWithdrawable = isInterstWithdrawable; + this.interestCompoundingAllowed = interestCompoundingAllowed; + + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + this.lockinPeriod = lockInPeriod; + this.lockinPeriodType = lockinPeriodType; + } + + public Long getId() { + return id; + } + + public Long getClientId() { + return clientId; + } + + public Long getProductId() { + return productId; + } + + public String getExternalId() { + return externalId; + } + + public BigDecimal getDepositAmount() { + return depositAmount; + } + + public BigDecimal getMaturityInterestRate() { + return maturityInterestRate; + } + + public BigDecimal getPreClosureInterestRate() { + return preClosureInterestRate; + } + + public Integer getTenureInMonths() { + return tenureInMonths; + } + + public Integer getInterestCompoundedEvery() { + return interestCompoundedEvery; + } + + public Integer getInterestCompoundedEveryPeriodType() { + return interestCompoundedEveryPeriodType; + } + + public LocalDate getCommencementDate() { + return commencementDate; + } + + public boolean isInterestWithdrawable() { + return isInterestWithdrawable; + } + + public boolean isRenewalAllowed() { + return renewalAllowed; + } + + public boolean isPreClosureAllowed() { + return preClosureAllowed; + } + + public boolean isInterestCompoundingAllowed() { + return interestCompoundingAllowed; + } + + public boolean isLockinPeriodAllowed() { + return isLockinPeriodAllowed; + } + + public Integer getLockinPeriod() { + return lockinPeriod; + } + + public Integer getLockinPeriodType() { + return lockinPeriodType; + } + + public boolean isNoFieldChanged() { + return this.modifiedParameters.isEmpty(); + } + + public boolean isExternalIdChanged() { + return this.modifiedParameters.contains("externalId"); + } + + public boolean isDepositAmountChanged() { + return this.modifiedParameters.contains("deposit"); + } + + public boolean isTenureInMonthsChanged() { + return this.modifiedParameters.contains("tenureInMonths"); + } + + public boolean isLockinPeriodChanged() { + return this.modifiedParameters.contains("lockinPeriod"); + } + + public boolean isMaturityActualInterestRateChanged() { + return this.modifiedParameters.contains("maturityInterestRate"); + } + + public boolean isPreClosureInterestRateChanged() { + return this.modifiedParameters.contains("preClosureInterestRate"); + } + + public boolean isCompoundingInterestEveryChanged() { + return this.modifiedParameters.contains("interestCompoundedEvery"); + } + + public boolean isInterestCompoundedEveryPeriodTypeChaged() { + return this.modifiedParameters.contains("interestCompoundedEveryPeriodType"); + } + + public boolean isRenewalAllowedChanged() { + return this.modifiedParameters.contains("renewalAllowed"); + } + + public boolean isPreClosureAllowedChanged() { + return this.modifiedParameters.contains("preClosureAllowed"); + } + + public boolean isInterestWithdrawableChanged() { + return this.modifiedParameters.contains("isInterestWithdrawable"); + } + + public boolean isInterestCompoundingAllowedChanged() { + return this.modifiedParameters.contains("interestCompoundingAllowed"); + } + + public boolean isCommencementDateChanged() { + return this.modifiedParameters.contains("commencementDate"); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountCommandValidator.java new file mode 100644 index 000000000..e2e183c44 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountCommandValidator.java @@ -0,0 +1,80 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; + +public class DepositAccountCommandValidator { + + private final DepositAccountCommand command; + + public DepositAccountCommandValidator(final DepositAccountCommand command) { + this.command = command; + } + + public void validateForUpdate() { + + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + + baseDataValidator.reset().parameter("id").value(command.getId()).notNull(); + baseDataValidator.reset().parameter("clientId").value(command.getClientId()).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter("productId").value(command.getProductId()).ignoreIfNull().notNull(); + baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); + + baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull().notNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().notNull() + .integerGreaterThanZero(); + + baseDataValidator.reset().parameter("interestCompoundedEvery").value(command.getInterestCompoundedEvery()).ignoreIfNull() + .integerGreaterThanZero(); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()) + .ignoreIfNull().inMinMaxRange(2, 2); + baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull(); + + if (command.isNoFieldChanged()) { + StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append("deposit.account").append( + ".no.parameters.for.update"); + StringBuilder defaultEnglishMessage = new StringBuilder("No parameters passed for update."); + ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), + "id"); + dataValidationErrors.add(error); + } + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + public void validateForCreate() { + + List dataValidationErrors = new ArrayList(); + + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.account"); + + baseDataValidator.reset().parameter("clientId").value(command.getClientId()).notNull(); + baseDataValidator.reset().parameter("productId").value(command.getProductId()).notNull(); + baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); + + baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("preClosureInterestRate").value(command.getPreClosureInterestRate()).ignoreIfNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero(); + + baseDataValidator.reset().parameter("interestCompoundedEvery").value(command.getInterestCompoundedEvery()).ignoreIfNull() + .integerGreaterThanZero(); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()) + .ignoreIfNull().inMinMaxRange(2, 2); + baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).notNull(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawInterestCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawInterestCommand.java new file mode 100644 index 000000000..082b027eb --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawInterestCommand.java @@ -0,0 +1,28 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import java.math.BigDecimal; + +public class DepositAccountWithdrawInterestCommand { + + private final Long accountId; + private final BigDecimal withdrawInterest; + private final String note; + + public DepositAccountWithdrawInterestCommand(final Long accountId, BigDecimal withdrawInterest, String note) { + this.accountId = accountId; + this.withdrawInterest = withdrawInterest; + this.note = note; + } + + public Long getAccountId() { + return accountId; + } + + public BigDecimal getWithdrawInterest() { + return withdrawInterest; + } + + public String getNote() { + return note; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawalCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawalCommand.java new file mode 100644 index 000000000..1568cf47c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawalCommand.java @@ -0,0 +1,28 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import org.joda.time.LocalDate; + +public class DepositAccountWithdrawalCommand { + + private final Long accountId; + private final String note; + private final LocalDate maturesOnDate; + + public DepositAccountWithdrawalCommand(final Long accountId, final String note, final LocalDate maturesOnDate) { + this.accountId = accountId; + this.note = note; + this.maturesOnDate = maturesOnDate; + } + + public Long getAccountId() { + return accountId; + } + + public String getNote() { + return note; + } + + public LocalDate getMaturesOnDate() { + return maturesOnDate; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawalCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawalCommandValidator.java new file mode 100644 index 000000000..7a17c69d5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositAccountWithdrawalCommandValidator.java @@ -0,0 +1,30 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; + +public class DepositAccountWithdrawalCommandValidator { + + private final DepositAccountWithdrawalCommand command; + + public DepositAccountWithdrawalCommandValidator(final DepositAccountWithdrawalCommand command) { + this.command = command; + } + + public void validate() { + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transaction"); + + baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionApprovalCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionApprovalCommand.java new file mode 100644 index 000000000..5a4b9b00c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionApprovalCommand.java @@ -0,0 +1,72 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import java.math.BigDecimal; + +import org.joda.time.LocalDate; + +public class DepositStateTransitionApprovalCommand { + + private final Long accountId; + private final Long productId; + private final LocalDate eventDate; + private final BigDecimal depositAmount; + private final BigDecimal maturityInterestRate; + private final Integer tenureInMonths; + private final Integer interestCompoundedEveryPeriodType; + private final Integer interestCompoundedEvery; + + private final String note; + + public DepositStateTransitionApprovalCommand(final Long resourceIdentifier, final Long productId, final LocalDate eventDate, + final Integer tenureInMonths, final BigDecimal depositAmount, final Integer interestCompoundedEveryPeriodType, + final Integer interestCompoundedEvery, final String note, final BigDecimal maturityInterestRate) { + + this.accountId = resourceIdentifier; + this.eventDate = eventDate; + this.depositAmount = depositAmount; + this.maturityInterestRate = maturityInterestRate; + this.tenureInMonths = tenureInMonths; + this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; + this.productId = productId; + this.interestCompoundedEvery = interestCompoundedEvery; + + this.note = note; + + } + + public Long getAccountId() { + return accountId; + } + + public LocalDate getEventDate() { + return eventDate; + } + + public BigDecimal getDepositAmount() { + return depositAmount; + } + + public BigDecimal getMaturityInterestRate() { + return maturityInterestRate; + } + + public Integer getTenureInMonths() { + return tenureInMonths; + } + + public Integer getInterestCompoundedEveryPeriodType() { + return interestCompoundedEveryPeriodType; + } + + public Long getProductId() { + return productId; + } + + public Integer getInterestCompoundedEvery() { + return interestCompoundedEvery; + } + + public String getNote() { + return note; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionApprovalCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionApprovalCommandValidator.java new file mode 100644 index 000000000..558c25fdb --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionApprovalCommandValidator.java @@ -0,0 +1,37 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; + +public class DepositStateTransitionApprovalCommandValidator { + + private final DepositStateTransitionApprovalCommand command; + + public DepositStateTransitionApprovalCommandValidator(final DepositStateTransitionApprovalCommand command) { + this.command = command; + } + + public void validate() { + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transition"); + baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("commencementDate").value(command.getEventDate()).notNull(); + + baseDataValidator.reset().parameter("deposit").value(command.getDepositAmount()).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityInterestRate").value(command.getMaturityInterestRate()).ignoreIfNull() + .zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("tenureInMonths").value(command.getTenureInMonths()).ignoreIfNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(command.getInterestCompoundedEveryPeriodType()) + .ignoreIfNull().inMinMaxRange(2, 2); + + baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionCommand.java new file mode 100644 index 000000000..7cf119601 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/DepositStateTransitionCommand.java @@ -0,0 +1,30 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import org.joda.time.LocalDate; + +public class DepositStateTransitionCommand { + + private final Long accountId; + private final LocalDate eventDate; + + private final String note; + + public DepositStateTransitionCommand(final Long accountId, final LocalDate enentDate, final String note) { + this.accountId = accountId; + this.eventDate = enentDate; + this.note = note; + } + + public Long getAccountId() { + return accountId; + } + + public LocalDate getEventDate() { + return eventDate; + } + + public String getNote() { + return note; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/WithDrawDepositAccountInterestCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/WithDrawDepositAccountInterestCommandValidator.java new file mode 100644 index 000000000..d2e1ebf73 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/command/WithDrawDepositAccountInterestCommandValidator.java @@ -0,0 +1,30 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.command; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; + +public class WithDrawDepositAccountInterestCommandValidator { + + private final DepositAccountWithdrawInterestCommand command; + + public WithDrawDepositAccountInterestCommandValidator(final DepositAccountWithdrawInterestCommand command) { + this.command = command; + } + + public void validate() { + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("deposit.transaction"); + + baseDataValidator.reset().parameter("accountId").value(command.getAccountId()).notNull().integerGreaterThanZero(); + baseDataValidator.reset().parameter("amount").value(command.getWithdrawInterest()).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("note").value(command.getNote()).notNull(); + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositAccountData.java new file mode 100644 index 000000000..4baec124e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositAccountData.java @@ -0,0 +1,544 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.data; + +import java.math.BigDecimal; +import java.math.MathContext; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.joda.time.Days; +import org.joda.time.LocalDate; +import org.joda.time.Months; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductLookup; + +/** + * Immutable data object for deposit accounts. + */ +public class DepositAccountData { + + private final Long id; + private final String externalId; + private final EnumOptionData status; + private final Long clientId; + private final String clientName; + private final Long productId; + private final String productName; + + private final CurrencyData currency; + private final BigDecimal deposit; + private final BigDecimal maturityInterestRate; + + private final Integer tenureInMonths; + private final LocalDate projectedCommencementDate; + private final LocalDate actualCommencementDate; + private final LocalDate maturedOn; + private final LocalDate withdrawnonDate; + private final LocalDate rejectedonDate; + private final LocalDate closedonDate; + private final BigDecimal projectedInterestAccrued; + private final BigDecimal actualInterestAccrued; + private final BigDecimal projectedMaturityAmount; + private final BigDecimal actualMaturityAmount; + + private final Integer interestCompoundedEvery; + private final EnumOptionData interestCompoundedEveryPeriodType; + private final boolean renewalAllowed; + private final boolean preClosureAllowed; + private final BigDecimal preClosureInterestRate; + + private final boolean isInterestWithdrawable; + private final BigDecimal interestPaid; + private final boolean interestCompoundingAllowed; + + private final List interestCompoundedEveryPeriodTypeOptions; + private final List productOptions; + + private final Collection transactions; + private final DepositPermissionData permissions; + private final BigDecimal availableInterestForWithdrawal; + private final BigDecimal availableWithdrawalAmount; + private final LocalDate todaysDate; + + private final boolean isLockinPeriodAllowed; + private final Integer lockinPeriod; + private final EnumOptionData lockinPeriodType; + + /* + * used when returning account template data but only a clientId is passed, + * no selected product. + */ + public static DepositAccountData createFrom(final Long clientId, final String clientDisplayName) { + return new DepositAccountData(clientId, clientDisplayName); + } + + private DepositAccountData(final Long clientId, final String clientName) { + this.id = null; + this.externalId = null; + this.status = null; + this.clientId = clientId; + this.clientName = clientName; + this.productId = null; + this.productName = null; + this.currency = null; + this.deposit = null; + this.maturityInterestRate = null; + this.tenureInMonths = null; + this.projectedCommencementDate = null; + this.actualCommencementDate = null; + this.maturedOn = null; + this.projectedInterestAccrued = null; + this.actualInterestAccrued = null; + this.projectedMaturityAmount = null; + this.actualMaturityAmount = null; + this.interestCompoundedEvery = null; + this.interestCompoundedEveryPeriodType = null; + this.renewalAllowed = false; + this.preClosureAllowed = false; + this.preClosureInterestRate = null; + + this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); + this.productOptions = new ArrayList(); + + this.withdrawnonDate = null; + this.closedonDate = null; + this.rejectedonDate = null; + + this.transactions = null; + this.permissions = null; + + this.interestPaid = null; + this.isInterestWithdrawable = false; + this.interestCompoundingAllowed = true; + this.availableInterestForWithdrawal = new BigDecimal(0); + this.availableWithdrawalAmount = new BigDecimal(0); + this.todaysDate = new LocalDate(); + + this.isLockinPeriodAllowed = true; + this.lockinPeriod = null; + this.lockinPeriodType = null; + } + + public DepositAccountData(final DepositAccountData account, final List interestCompoundedEveryPeriodTypeOptions, + final Collection productOptions) { + this.id = account.getId(); + this.externalId = account.getExternalId(); + this.status = account.getStatus(); + this.clientId = account.getClientId(); + this.clientName = account.getClientName(); + this.productId = account.getProductId(); + this.productName = account.getProductName(); + this.currency = account.getCurrency(); + this.deposit = account.getDeposit(); + this.maturityInterestRate = account.getMaturityInterestRate(); + this.tenureInMonths = account.getTenureInMonths(); + this.projectedCommencementDate = account.getProjectedCommencementDate(); + this.actualCommencementDate = account.getActualCommencementDate(); + this.maturedOn = account.getMaturedOn(); + this.projectedInterestAccrued = account.getProjectedInterestAccrued(); + this.actualInterestAccrued = account.getActualInterestAccrued(); + this.projectedMaturityAmount = account.getProjectedMaturityAmount(); + this.actualMaturityAmount = account.getActualMaturityAmount(); + this.interestCompoundedEvery = account.getInterestCompoundedEvery(); + this.interestCompoundedEveryPeriodType = account.getInterestCompoundedEveryPeriodType(); + this.renewalAllowed = account.isRenewalAllowed(); + this.preClosureAllowed = account.isPreClosureAllowed(); + this.preClosureInterestRate = account.getPreClosureInterestRate(); + + this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions; + this.productOptions = new ArrayList(productOptions); + + this.withdrawnonDate = account.getWithdrawnonDate(); + this.rejectedonDate = account.getRejectedonDate(); + this.closedonDate = account.getClosedonDate(); + + this.transactions = account.getTransactions(); + this.permissions = account.getPermissions(); + this.interestPaid = account.getInterestPaid(); + this.isInterestWithdrawable = account.isInterestWithdrawable(); + this.interestCompoundingAllowed = account.isInterestCompoundingAllowed(); + this.availableInterestForWithdrawal = determineAvailableInterestForWithdrawal(account); + this.availableWithdrawalAmount = determineAvalableWithdrawalAmount(account); + this.todaysDate = new LocalDate(); + + this.lockinPeriod = account.getLockinPeriod(); + this.lockinPeriodType = account.getLockinPeriodType(); + this.isLockinPeriodAllowed = account.isLockinPeriodAllowed(); + } + + public DepositAccountData(final DepositAccountData account, final DepositPermissionData permissions, + final Collection transactions) { + this.id = account.getId(); + this.externalId = account.getExternalId(); + this.status = account.getStatus(); + this.clientId = account.getClientId(); + this.clientName = account.getClientName(); + this.productId = account.getProductId(); + this.productName = account.getProductName(); + this.currency = account.getCurrency(); + this.deposit = account.getDeposit(); + this.maturityInterestRate = account.getMaturityInterestRate(); + this.tenureInMonths = account.getTenureInMonths(); + this.projectedCommencementDate = account.getProjectedCommencementDate(); + this.actualCommencementDate = account.getActualCommencementDate(); + this.maturedOn = account.getMaturedOn(); + this.projectedInterestAccrued = account.getProjectedInterestAccrued(); + this.actualInterestAccrued = account.getActualInterestAccrued(); + this.projectedMaturityAmount = account.getProjectedMaturityAmount(); + this.actualMaturityAmount = account.getActualMaturityAmount(); + this.interestCompoundedEvery = account.getInterestCompoundedEvery(); + this.interestCompoundedEveryPeriodType = account.getInterestCompoundedEveryPeriodType(); + this.renewalAllowed = account.isRenewalAllowed(); + this.preClosureAllowed = account.isPreClosureAllowed(); + this.preClosureInterestRate = account.getPreClosureInterestRate(); + + this.interestCompoundedEveryPeriodTypeOptions = account.getInterestCompoundedEveryPeriodTypeOptions(); + this.productOptions = account.getProductOptions(); + + this.withdrawnonDate = account.getWithdrawnonDate(); + this.rejectedonDate = account.getRejectedonDate(); + this.closedonDate = account.getClosedonDate(); + + this.transactions = transactions; + this.permissions = permissions; + this.interestPaid = account.getInterestPaid(); + this.isInterestWithdrawable = account.isInterestWithdrawable(); + this.interestCompoundingAllowed = account.isInterestCompoundingAllowed(); + this.availableInterestForWithdrawal = determineAvailableInterestForWithdrawal(account); + this.availableWithdrawalAmount = determineAvalableWithdrawalAmount(account); + this.todaysDate = new LocalDate(); + + this.lockinPeriod = account.getLockinPeriod(); + this.lockinPeriodType = account.getLockinPeriodType(); + this.isLockinPeriodAllowed = account.isLockinPeriodAllowed(); + } + + public DepositAccountData(final Long id, final String externalId, final EnumOptionData status, final Long clientId, + final String clientName, final Long productId, final String productName, final CurrencyData currency, final BigDecimal deposit, + final BigDecimal interestRate, final Integer tenureInMonths, final LocalDate projectedCommencementDate, + final LocalDate actualCommencementDate, final LocalDate maturedOn, final BigDecimal projectedInterestAccrued, + final BigDecimal actualInterestAccrued, final BigDecimal projectedMaturityAmount, final BigDecimal actualMaturityAmount, + final Integer interestCompoundedEvery, final EnumOptionData interestCompoundedEveryPeriodType, final boolean renewalAllowed, + final boolean preClosureAllowed, final BigDecimal preClosureInterestRate, final LocalDate withdrawnonDate, + final LocalDate rejectedonDate, final LocalDate closedonDate, final boolean isInterestWithdrawable, + final BigDecimal interestPaid, final boolean interestCompoundingAllowed, final boolean isLockinPeriodAllowed, + final Integer lockinPeriod, final EnumOptionData lockinPeriodType) { + this.id = id; + this.externalId = externalId; + this.status = status; + this.clientId = clientId; + this.clientName = clientName; + this.productId = productId; + this.productName = productName; + this.currency = currency; + this.deposit = deposit; + this.maturityInterestRate = interestRate; + this.tenureInMonths = tenureInMonths; + this.projectedCommencementDate = projectedCommencementDate; + this.actualCommencementDate = actualCommencementDate; + this.maturedOn = maturedOn; + this.projectedInterestAccrued = projectedInterestAccrued; + this.actualInterestAccrued = actualInterestAccrued; + this.projectedMaturityAmount = projectedMaturityAmount; + this.actualMaturityAmount = actualMaturityAmount; + this.interestCompoundedEvery = interestCompoundedEvery; + this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; + this.renewalAllowed = renewalAllowed; + this.preClosureAllowed = preClosureAllowed; + this.preClosureInterestRate = preClosureInterestRate; + + this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); + this.productOptions = new ArrayList(); + + this.withdrawnonDate = withdrawnonDate; + this.rejectedonDate = rejectedonDate; + this.closedonDate = closedonDate; + + this.transactions = null; + this.permissions = null; + + this.interestPaid = interestPaid; + this.isInterestWithdrawable = isInterestWithdrawable; + this.interestCompoundingAllowed = interestCompoundingAllowed; + this.availableInterestForWithdrawal = BigDecimal.ZERO; + this.availableWithdrawalAmount = BigDecimal.ZERO; + this.todaysDate = new LocalDate(); + + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + this.lockinPeriod = lockinPeriod; + this.lockinPeriodType = lockinPeriodType; + } + + public DepositAccountData(final Long clientId, final String clientName, final Long productId, final String productName, + final CurrencyData currency, final BigDecimal deposit, final BigDecimal interestRate, final Integer tenureInMonths, + final Integer interestCompoundedEvery, final EnumOptionData interestCompoundedEveryPeriodType, final boolean renewalAllowed, + final boolean preClosureAllowed, final BigDecimal preClosureInterestRate, final boolean interestCompoundingAllowed) { + this.id = null; + this.externalId = null; + this.status = null; + this.clientId = clientId; + this.clientName = clientName; + this.productId = productId; + this.productName = productName; + this.currency = currency; + this.deposit = deposit; + this.maturityInterestRate = interestRate; + this.tenureInMonths = tenureInMonths; + this.projectedCommencementDate = new LocalDate(); + this.actualCommencementDate = null; + this.maturedOn = null; + this.projectedInterestAccrued = null; + this.actualInterestAccrued = null; + this.projectedMaturityAmount = null; + this.actualMaturityAmount = null; + this.interestCompoundedEvery = interestCompoundedEvery; + this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; + this.renewalAllowed = renewalAllowed; + this.preClosureAllowed = preClosureAllowed; + this.preClosureInterestRate = preClosureInterestRate; + + this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); + this.productOptions = new ArrayList(); + + this.withdrawnonDate = null; + this.closedonDate = null; + this.rejectedonDate = null; + + this.transactions = null; + this.permissions = null; + this.interestPaid = null; + this.isInterestWithdrawable = false; + this.interestCompoundingAllowed = interestCompoundingAllowed; + this.availableInterestForWithdrawal = BigDecimal.ZERO; + this.availableWithdrawalAmount = BigDecimal.ZERO; + this.todaysDate = new LocalDate(); + + // need to update in constructor's call method and update it + this.lockinPeriod = Integer.valueOf(0); + this.isLockinPeriodAllowed = true; + this.lockinPeriodType = interestCompoundedEveryPeriodType; + } + + public Long getId() { + return id; + } + + public String getExternalId() { + return externalId; + } + + public EnumOptionData getStatus() { + return status; + } + + public Long getClientId() { + return clientId; + } + + public String getClientName() { + return clientName; + } + + public Long getProductId() { + return productId; + } + + public String getProductName() { + return productName; + } + + public CurrencyData getCurrency() { + return currency; + } + + public BigDecimal getDeposit() { + return deposit; + } + + public BigDecimal getMaturityInterestRate() { + return maturityInterestRate; + } + + public Integer getTenureInMonths() { + return tenureInMonths; + } + + public LocalDate getProjectedCommencementDate() { + return projectedCommencementDate; + } + + public LocalDate getActualCommencementDate() { + return actualCommencementDate; + } + + public LocalDate getMaturedOn() { + return maturedOn; + } + + public BigDecimal getProjectedInterestAccrued() { + return projectedInterestAccrued; + } + + public BigDecimal getActualInterestAccrued() { + return actualInterestAccrued; + } + + public BigDecimal getProjectedMaturityAmount() { + return projectedMaturityAmount; + } + + public BigDecimal getActualMaturityAmount() { + return actualMaturityAmount; + } + + public Integer getInterestCompoundedEvery() { + return interestCompoundedEvery; + } + + public EnumOptionData getInterestCompoundedEveryPeriodType() { + return interestCompoundedEveryPeriodType; + } + + public boolean isRenewalAllowed() { + return renewalAllowed; + } + + public boolean isPreClosureAllowed() { + return preClosureAllowed; + } + + public BigDecimal getPreClosureInterestRate() { + return preClosureInterestRate; + } + + public List getInterestCompoundedEveryPeriodTypeOptions() { + return interestCompoundedEveryPeriodTypeOptions; + } + + public List getProductOptions() { + return productOptions; + } + + public LocalDate getWithdrawnonDate() { + return withdrawnonDate; + } + + public LocalDate getRejectedonDate() { + return rejectedonDate; + } + + public LocalDate getClosedonDate() { + return closedonDate; + } + + public Collection getTransactions() { + return transactions; + } + + public DepositPermissionData getPermissions() { + return permissions; + } + + public boolean isInterestWithdrawable() { + return isInterestWithdrawable; + } + + public BigDecimal getInterestPaid() { + return interestPaid; + } + + public boolean isInterestCompoundingAllowed() { + return interestCompoundingAllowed; + } + + public BigDecimal getAvailableInterestForWithdrawal() { + return availableInterestForWithdrawal; + } + + public BigDecimal getAvailableWithdrawalAmount() { + return availableWithdrawalAmount; + } + + public LocalDate getTodaysDate() { + return todaysDate; + } + + public boolean isLockinPeriodAllowed() { + return isLockinPeriodAllowed; + } + + public Integer getLockinPeriod() { + return lockinPeriod; + } + + public EnumOptionData getLockinPeriodType() { + return lockinPeriodType; + } + + private BigDecimal determineAvailableInterestForWithdrawal(final DepositAccountData account) { + BigDecimal availableInterestForWithdrawal = BigDecimal.ZERO; + + if (this.status != null) { + if (account.getStatus().getId() == 300) { + BigDecimal interestGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue() + / new Double(account.getTenureInMonths())); + LocalDate interestWithdrawingDate = new LocalDate().isBefore(getMaturedOn()) ? new LocalDate() : getMaturedOn().plusDays(1); + Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate) + .getMonths(); + Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery(); + + availableInterestForWithdrawal = BigDecimal.valueOf(interestGettingForPeriod.multiply(new BigDecimal(noOfPeriods)) + .doubleValue() - account.getInterestPaid().doubleValue()); + } else { + return BigDecimal.ZERO; + } + } else + return BigDecimal.ZERO; + + return availableInterestForWithdrawal; + } + + private BigDecimal determineAvalableWithdrawalAmount(final DepositAccountData account) { + + BigDecimal avalablePreclosureWithdrawalAmount = BigDecimal.ZERO; + if (this.status != null) { + if (account.getStatus().getId() == 300) { + if (new LocalDate().isBefore(account.getMaturedOn()) || new LocalDate().isEqual(account.getMaturedOn())) { + MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); + Integer monthsInYear = 12; + BigDecimal interestRateAsFraction = account.getPreClosureInterestRate().divide(BigDecimal.valueOf(100), mc); + BigDecimal interestRateForOneMonth = interestRateAsFraction.divide(BigDecimal.valueOf(monthsInYear.doubleValue()), mc); + Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()) + .getMonths(); + Integer days = Days.daysBetween(account.getActualCommencementDate().plusMonths(noOfMonthsforInterestCal), + new LocalDate()).getDays(); + BigDecimal interest = BigDecimal.valueOf(account.getDeposit().doubleValue() * new Double(noOfMonthsforInterestCal) + * interestRateForOneMonth.doubleValue()); + avalablePreclosureWithdrawalAmount = interest.add(account.getDeposit()).subtract(account.getInterestPaid()) + .add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days)); + } else if (new LocalDate().isAfter(account.getMaturedOn())) { + Integer days = Days.daysBetween(account.getMaturedOn(), new LocalDate()).getDays(); + avalablePreclosureWithdrawalAmount = determineAvailableInterestForWithdrawal(account).add(account.getDeposit()).add( + determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days)); + } + } else { + avalablePreclosureWithdrawalAmount = account.getDeposit(); + } + } + return avalablePreclosureWithdrawalAmount; + } + + private BigDecimal determineRemainInerestAmount(final BigDecimal depsoitAmount, final BigDecimal interstRateApplicable, + final Integer days) { + + MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); + Integer daysInYear = 365; + BigDecimal interestRateAsFraction = interstRateApplicable.divide(BigDecimal.valueOf(100), mc); + BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc); + return BigDecimal.valueOf(depsoitAmount.doubleValue() * days.doubleValue() * interestRateForOneDay.doubleValue()); + + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountTransactionData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositAccountTransactionData.java similarity index 95% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountTransactionData.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositAccountTransactionData.java index a34f0ae09..30c25306b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositAccountTransactionData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositAccountTransactionData.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.data; +package org.mifosplatform.portfolio.savingsdepositaccount.data; import java.math.BigDecimal; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositPermissionData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositPermissionData.java similarity index 96% rename from mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositPermissionData.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositPermissionData.java index 421bdaa93..0f7e799e2 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/DepositPermissionData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/data/DepositPermissionData.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.api.data; +package org.mifosplatform.portfolio.savingsdepositaccount.data; public class DepositPermissionData { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccount.java similarity index 98% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccount.java index e6397f82d..ef60e0bf6 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccount.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; import java.math.BigDecimal; import java.util.ArrayList; @@ -25,15 +25,15 @@ import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.Months; -import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand; -import org.mifosng.platform.exceptions.InvalidDepositStateTransitionException; -import org.mifosng.platform.savingproduct.domain.DepositProduct; import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.exception.InvalidDepositStateTransitionException; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProduct; @Entity @Table(name = "m_deposit_account", uniqueConstraints = @UniqueConstraint(name="deposit_acc_external_id", columnNames = { "external_id" })) diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountEvent.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountEvent.java similarity index 74% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountEvent.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountEvent.java index 8a6209c83..71ecb640e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountEvent.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountEvent.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; public enum DepositAccountEvent { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountRepository.java similarity index 80% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountRepository.java index ad8856b09..61baec5fb 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountStatus.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountStatus.java similarity index 97% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountStatus.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountStatus.java index 3448d1837..4de350f32 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountStatus.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountStatus.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; public enum DepositAccountStatus { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountTransaction.java similarity index 98% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountTransaction.java index 2583e7363..663a29027 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountTransaction.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; import java.math.BigDecimal; import java.util.Date; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransactionType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountTransactionType.java similarity index 94% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransactionType.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountTransactionType.java index 80abf07f6..598c41d73 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositAccountTransactionType.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositAccountTransactionType.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; public enum DepositAccountTransactionType { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachine.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositLifecycleStateMachine.java similarity index 69% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachine.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositLifecycleStateMachine.java index 321fdcf9d..007ff8a6d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachine.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositLifecycleStateMachine.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; public interface DepositLifecycleStateMachine { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachineImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositLifecycleStateMachineImpl.java similarity index 96% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachineImpl.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositLifecycleStateMachineImpl.java index 56ed6a348..d64be509e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/DepositLifecycleStateMachineImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/DepositLifecycleStateMachineImpl.java @@ -1,8 +1,8 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; import java.util.List; -import org.mifosng.platform.exceptions.InvalidDepositStateTransitionException; +import org.mifosplatform.portfolio.savingsdepositaccount.exception.InvalidDepositStateTransitionException; public class DepositLifecycleStateMachineImpl implements DepositLifecycleStateMachine { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/FixedTermDepositInterestCalculator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/FixedTermDepositInterestCalculator.java similarity index 98% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/FixedTermDepositInterestCalculator.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/FixedTermDepositInterestCalculator.java index 07215d5eb..a198965fe 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/domain/FixedTermDepositInterestCalculator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/domain/FixedTermDepositInterestCalculator.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.saving.domain; +package org.mifosplatform.portfolio.savingsdepositaccount.domain; import java.math.BigDecimal; import java.math.MathContext; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccounDataValidationtException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccounDataValidationtException.java similarity index 90% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccounDataValidationtException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccounDataValidationtException.java index 903b4aa57..01a7b915c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccounDataValidationtException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccounDataValidationtException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsdepositaccount.exception; import java.math.BigDecimal; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountNotFoundException.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountNotFoundException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountNotFoundException.java index 4dc6bb724..a30778fe1 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountNotFoundException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsdepositaccount.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountReopenException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountReopenException.java similarity index 85% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountReopenException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountReopenException.java index 5df550f65..3f1854d46 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountReopenException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountReopenException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsdepositaccount.exception; import org.joda.time.LocalDate; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountTransactionsException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountTransactionsException.java similarity index 85% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountTransactionsException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountTransactionsException.java index 79753a0ed..f8b882fdb 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositAccountTransactionsException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/DepositAccountTransactionsException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsdepositaccount.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/InvalidDepositStateTransitionException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/InvalidDepositStateTransitionException.java new file mode 100644 index 000000000..e4ed5e775 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/InvalidDepositStateTransitionException.java @@ -0,0 +1,12 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class InvalidDepositStateTransitionException extends AbstractPlatformDomainRuleException { + + public InvalidDepositStateTransitionException(final String action, String postFix, String defaultUserMessage, + Object... defaultUserMessageArgs) { + super("error.msg.deposit." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java similarity index 93% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountAssembler.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java index d6a92b1af..bbee5aec2 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java @@ -1,25 +1,25 @@ -package org.mifosng.platform.saving.service; +package org.mifosplatform.portfolio.savingsdepositaccount.service; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import org.joda.time.LocalDate; -import org.mifosng.platform.api.commands.DepositAccountCommand; -import org.mifosng.platform.exceptions.DepositAccounDataValidationtException; -import org.mifosng.platform.exceptions.DepositProductNotFoundException; -import org.mifosng.platform.saving.domain.DepositAccount; -import org.mifosng.platform.saving.domain.DepositAccountStatus; -import org.mifosng.platform.saving.domain.DepositLifecycleStateMachine; -import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl; -import org.mifosng.platform.saving.domain.FixedTermDepositInterestCalculator; -import org.mifosng.platform.savingproduct.domain.DepositProduct; -import org.mifosng.platform.savingproduct.domain.DepositProductRepository; import org.mifosplatform.infrastructure.configuration.domain.Money; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientRepository; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachine; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachineImpl; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.FixedTermDepositInterestCalculator; +import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccounDataValidationtException; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProduct; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProductRepository; +import org.mifosplatform.portfolio.savingsdepositproduct.exception.DepositProductNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountEnumerations.java similarity index 93% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountEnumerations.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountEnumerations.java index f9a0dac3b..ba09f3983 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountEnumerations.java @@ -1,7 +1,7 @@ -package org.mifosng.platform.saving.service; +package org.mifosplatform.portfolio.savingsdepositaccount.service; -import org.mifosng.platform.saving.domain.DepositAccountStatus; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus; public class DepositAccountEnumerations { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformService.java new file mode 100644 index 000000000..da9cb900b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformService.java @@ -0,0 +1,20 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.service; + +import java.math.BigDecimal; +import java.util.Collection; + +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountData; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositPermissionData; + +public interface DepositAccountReadPlatformService { + + Collection retrieveAllDepositAccounts(); + + DepositAccountData retrieveDepositAccount(Long accountId); + + DepositAccountData retrieveNewDepositAccountDetails(Long clientId, Long productId); + + DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData); + + BigDecimal retrieveAvailableInterestForWithdrawal(DepositAccountData account); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformServiceImpl.java new file mode 100644 index 000000000..46a5472b3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountReadPlatformServiceImpl.java @@ -0,0 +1,283 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.service; + +import java.math.BigDecimal; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.joda.time.LocalDate; +import org.joda.time.Months; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.client.data.ClientData; +import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; +import org.mifosplatform.portfolio.loanproduct.exception.LoanProductNotFoundException; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingsDepositEnumerations; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountData; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountTransactionData; +import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositPermissionData; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductLookup; +import org.mifosplatform.portfolio.savingsdepositproduct.service.DepositProductReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class DepositAccountReadPlatformServiceImpl implements DepositAccountReadPlatformService { + + private final PlatformSecurityContext context; + private final JdbcTemplate jdbcTemplate; + private final DepositProductReadPlatformService depositProductReadPlatformService; + private final ClientReadPlatformService clientReadPlatformService; + + @Autowired + public DepositAccountReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, + final DepositProductReadPlatformService depositProductReadPlatformService, + final ClientReadPlatformService clientReadPlatformService) { + this.context = context; + jdbcTemplate = new JdbcTemplate(dataSource); + this.depositProductReadPlatformService = depositProductReadPlatformService; + this.clientReadPlatformService = clientReadPlatformService; + } + + @Override + public Collection retrieveAllDepositAccounts() { + + this.context.authenticatedUser(); + + DepositAccountMapper mapper = new DepositAccountMapper(); + + String sql = "select " + mapper.schema() + " where da.is_deleted=0"; + + return this.jdbcTemplate.query(sql, mapper, new Object[] {}); + } + + @Override + public DepositAccountData retrieveDepositAccount(final Long accountId) { + try { + DepositAccountMapper mapper = new DepositAccountMapper(); + + String sql = "select " + mapper.schema() + " where da.id = ? and da.is_deleted=0"; + + DepositAccountData depositAccountData = this.jdbcTemplate.queryForObject(sql, mapper, new Object[] { accountId }); + + // FIXME - kw - the call to find transactions for deposit account to + // add to the deposit account payload can be decided at the api + // level + // depending on whether the requester wants them or not instead of + // always getting the transactions + DepositAccountTransactionMapper transactionMapper = new DepositAccountTransactionMapper(); + String transactionSchema = "select " + transactionMapper.schema() + " where txn.deposit_account_id = ? "; + + Collection depositAccountTransactions = this.jdbcTemplate.query(transactionSchema, + transactionMapper, new Object[] { accountId }); + if (!depositAccountTransactions.isEmpty()) { + DepositPermissionData permissions = null; + depositAccountData = new DepositAccountData(depositAccountData, permissions, depositAccountTransactions); + } + + return depositAccountData; + } catch (EmptyResultDataAccessException e) { + throw new LoanProductNotFoundException(accountId); + } + } + + @Override + public DepositAccountData retrieveNewDepositAccountDetails(final Long clientId, final Long productId) { + + context.authenticatedUser(); + + ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId); + + DepositAccountData accountData = null; + + Collection depositProducts = this.depositProductReadPlatformService.retrieveAllDepositProductsForLookup(); + + if (productId != null) { + DepositProductData selectedProduct = findDepositProductById(depositProducts, productId); + + CurrencyData currency = new CurrencyData(selectedProduct.getCurrencyCode(), "", selectedProduct.getDigitsAfterDecimal(), "", ""); + + accountData = new DepositAccountData(clientAccount.id(), clientAccount.displayName(), selectedProduct.getId(), + selectedProduct.getName(), currency, selectedProduct.getMinimumBalance(), + selectedProduct.getMaturityDefaultInterestRate(), selectedProduct.getTenureInMonths(), + selectedProduct.getInterestCompoundedEvery(), selectedProduct.getInterestCompoundedEveryPeriodType(), + selectedProduct.isRenewalAllowed(), selectedProduct.isPreClosureAllowed(), selectedProduct.getPreClosureInterestRate(), + selectedProduct.isInterestCompoundingAllowed()); + } else { + accountData = DepositAccountData.createFrom(clientAccount.id(), clientAccount.displayName()); + } + + return accountData; + } + + private DepositProductData findDepositProductById(final Collection depositProducts, final Long productId) { + DepositProductData match = this.depositProductReadPlatformService.retrieveNewDepositProductDetails(); + for (DepositProductLookup depositProductLookup : depositProducts) { + if (depositProductLookup.hasId(productId)) { + match = this.depositProductReadPlatformService.retrieveDepositProductData(depositProductLookup.id()); + break; + } + } + return match; + } + + private static final class DepositAccountMapper implements RowMapper { + + public String schema() { + return "da.id as id, da.external_id as externalId, da.client_id as clientId, da.product_id as productId, " + + " da.currency_code as currencyCode, da.currency_digits as currencyDigits, " + + " da.deposit_amount as depositAmount, da.status_enum as statusId, " + + " da.maturity_nominal_interest_rate as interestRate, da.tenure_months as termInMonths, da.projected_commencement_date as projectedCommencementDate," + + " da.actual_commencement_date as actualCommencementDate, da.matures_on_date as maturedOn," + + " da.projected_interest_accrued_on_maturity as projectedInterestAccrued, da.actual_interest_accrued as actualInterestAccrued, " + + " da.projected_total_maturity_amount as projectedMaturityAmount, da.actual_total_amount as actualMaturityAmount, " + + " da.interest_compounded_every as interestCompoundedEvery, da.interest_compounded_every_period_enum as interestCompoundedEveryPeriodType, " + + " da.is_renewal_allowed as renewalAllowed, da.is_preclosure_allowed as preClosureAllowed, da.pre_closure_interest_rate as preClosureInterestRate, " + + " da.withdrawnon_date as withdrawnonDate, da.rejectedon_date as rejectedonDate, da.closedon_date as closedonDate, " + + " da.interest_paid as interestPaid, da.is_interest_withdrawable as isInterestWithdrawable, da.is_compounding_interest_allowed as interestCompoundingAllowed, " + + " da.is_lock_in_period_allowed as isLockinPeriodAllowed, da.lock_in_period as lockinPeriod, da.lock_in_period_type lockinPeriodType, " + + " c.firstname as firstname, c.lastname as lastname, pd.name as productName," + + " curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol " + + " from m_deposit_account da " + " join m_currency curr on curr.code = da.currency_code " + + " join m_client c on c.id = da.client_id " + " join m_product_deposit pd on pd.id = da.product_id"; + } + + @Override + public DepositAccountData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + + Long id = rs.getLong("id"); + String externalId = rs.getString("externalId"); + Long clientId = rs.getLong("clientId"); + String clientName = rs.getString("firstname") + " " + rs.getString("lastname"); + Long productId = rs.getLong("productId"); + String productName = rs.getString("productName"); + + Integer statusId = JdbcSupport.getInteger(rs, "statusId"); + EnumOptionData status = DepositAccountEnumerations.status(statusId); + + String currencyCode = rs.getString("currencyCode"); + String currencyName = rs.getString("currencyName"); + String currencyNameCode = rs.getString("currencyNameCode"); + String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol"); + Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits"); + CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol, + currencyNameCode); + + BigDecimal depositAmount = rs.getBigDecimal("depositAmount"); + BigDecimal interestRate = rs.getBigDecimal("interestRate"); + + Integer termInMonths = JdbcSupport.getInteger(rs, "termInMonths"); + + LocalDate projectedCommencementDate = JdbcSupport.getLocalDate(rs, "projectedCommencementDate"); + LocalDate actualCommencementDate = JdbcSupport.getLocalDate(rs, "actualCommencementDate"); + LocalDate maturedOn = JdbcSupport.getLocalDate(rs, "maturedOn"); + BigDecimal projectedInterestAccrued = rs.getBigDecimal("projectedInterestAccrued"); + BigDecimal actualInterestAccrued = rs.getBigDecimal("actualInterestAccrued"); + + BigDecimal projectedMaturityAmount = rs.getBigDecimal("projectedMaturityAmount"); + BigDecimal actualMaturityAmount = rs.getBigDecimal("actualMaturityAmount"); + + Integer interestCompoundedEvery = JdbcSupport.getInteger(rs, "interestCompoundedEvery"); + Integer interestCompoundedEveryPeriodTypeValue = JdbcSupport.getInteger(rs, "interestCompoundedEveryPeriodType"); + EnumOptionData interestCompoundedEveryPeriodType = SavingsDepositEnumerations + .interestCompoundingPeriodType(interestCompoundedEveryPeriodTypeValue); + + boolean renewalAllowed = rs.getBoolean("renewalAllowed"); + boolean preClosureAllowed = rs.getBoolean("preClosureAllowed"); + boolean interestCompoundingAllowed = rs.getBoolean("interestCompoundingAllowed"); + + BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate"); + + LocalDate withdrawnonDate = JdbcSupport.getLocalDate(rs, "withdrawnonDate"); + LocalDate rejectedonDate = JdbcSupport.getLocalDate(rs, "rejectedonDate"); + LocalDate closedonDate = JdbcSupport.getLocalDate(rs, "closedonDate"); + + boolean isInterestWithdrawable = rs.getBoolean("isInterestWithdrawable"); + BigDecimal interestPaid = rs.getBigDecimal("interestPaid"); + + boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed"); + Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod"); + Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType"); + EnumOptionData lockinPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(lockinPeriodTypeValue); + + return new DepositAccountData(id, externalId, status, clientId, clientName, productId, productName, currencyData, + depositAmount, interestRate, termInMonths, projectedCommencementDate, actualCommencementDate, maturedOn, + projectedInterestAccrued, actualInterestAccrued, projectedMaturityAmount, actualMaturityAmount, + interestCompoundedEvery, interestCompoundedEveryPeriodType, renewalAllowed, preClosureAllowed, preClosureInterestRate, + withdrawnonDate, rejectedonDate, closedonDate, isInterestWithdrawable, interestPaid, interestCompoundingAllowed, + isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); + } + } + + private static final class DepositAccountTransactionMapper implements RowMapper { + + public String schema() { + return " txn.id as transactionId, txn.deposit_account_id as accountId, txn.transaction_type_enum as transactionType, txn.transaction_date as transactionDate, txn.amount as transactionAmount, txn.interest as interestAmount " + + " from m_deposit_account_transaction txn"; + } + + @Override + public DepositAccountTransactionData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + + Long transactionId = rs.getLong("transactionId"); + Long accountId = rs.getLong("accountId"); + Integer transactionTypeValue = JdbcSupport.getInteger(rs, "transactionType"); + EnumOptionData transactionType = DepositAccountTransactionEnumerations.depositType(transactionTypeValue); + LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate"); + BigDecimal transactionAmount = rs.getBigDecimal("transactionAmount"); + BigDecimal interestAmount = rs.getBigDecimal("interestAmount"); + BigDecimal total = transactionAmount.add(interestAmount); + + return new DepositAccountTransactionData(transactionId, accountId, transactionType, transactionDate, transactionAmount, + interestAmount, total); + } + + } + + @Override + public DepositPermissionData retrieveDepositAccountsPermissions(DepositAccountData depositAccountData) { + boolean pendingApproval = (depositAccountData.getStatus().getId().equals(100L)); + boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L)); + boolean renewelAllowed = false; + if (depositAccountData.getMaturedOn() != null) { + if (new LocalDate().isAfter(depositAccountData.getMaturedOn())/* + * || + * depositAccountData + * . + * getMaturedOn + * (). + * isEqual + * ( + * new + * LocalDate + * ()) + */) { + renewelAllowed = depositAccountData.isRenewalAllowed(); + } + } + boolean rejectAllowed = pendingApproval; + boolean withdrawnByApplicantAllowed = pendingApproval; + boolean interestWithdrawAllowed = depositAccountData.isInterestWithdrawable(); + boolean isMaturedDepositAccount = (depositAccountData.getStatus().getId().equals(700L)); + + return new DepositPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval, + interestWithdrawAllowed, renewelAllowed, isMaturedDepositAccount); + } + + @Override + public BigDecimal retrieveAvailableInterestForWithdrawal(DepositAccountData account) { + BigDecimal interstGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue() + / new Double(account.getTenureInMonths())); + Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()).getMonths(); + Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery(); + return BigDecimal.valueOf(interstGettingForPeriod.multiply(new BigDecimal(noOfPeriods)).doubleValue() + - account.getInterestPaid().doubleValue()); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountTransactionEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountTransactionEnumerations.java similarity index 88% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountTransactionEnumerations.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountTransactionEnumerations.java index 9f279ad9d..2b84c2984 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositAccountTransactionEnumerations.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountTransactionEnumerations.java @@ -1,7 +1,7 @@ -package org.mifosng.platform.saving.service; +package org.mifosplatform.portfolio.savingsdepositaccount.service; -import org.mifosng.platform.saving.domain.DepositAccountTransactionType; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountTransactionType; public class DepositAccountTransactionEnumerations { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformService.java new file mode 100644 index 000000000..ceebae674 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformService.java @@ -0,0 +1,52 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.service; + +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface DepositAccountWritePlatformService { + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_DEPOSITACCOUNT')") + EntityIdentifier createDepositAccount(DepositAccountCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'UPDATE_DEPOSITACCOUNT')") + EntityIdentifier updateDepositAccount(DepositAccountCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'DELETE_DEPOSITACCOUNT')") + EntityIdentifier deleteDepositAccount(Long productId); + + // NOTE - took out permissions relating to doing things with deposit + // accounts in the past as doesn't appear to be code for it + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'APPROVE_DEPOSITACCOUNT')") + EntityIdentifier approveDepositApplication(DepositStateTransitionApprovalCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'REJECT_DEPOSITACCOUNT')") + EntityIdentifier rejectDepositApplication(DepositStateTransitionCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'WITHDRAW_DEPOSITACCOUNT')") + EntityIdentifier withdrawDepositApplication(DepositStateTransitionCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'APPROVALUNDO_DEPOSITACCOUNT')") + EntityIdentifier undoDepositApproval(UndoStateTransitionCommand undoCommand); + + /* + * @PreAuthorize(value = + * "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', '')" ) + * EntityIdentifier matureDepositApplication(DepositStateTransitionCommand + * command); + */ + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'WITHDRAWAL_DEPOSITACCOUNT')") + EntityIdentifier withdrawDepositAccountMoney(DepositAccountWithdrawalCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'INTEREST_DEPOSITACCOUNT')") + EntityIdentifier withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'RENEW_DEPOSITACCOUNT')") + EntityIdentifier renewDepositAccount(DepositAccountCommand command); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..da3ba9344 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,422 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.service; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.joda.time.Months; +import org.mifosplatform.infrastructure.configuration.domain.Money; +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.client.domain.Note; +import org.mifosplatform.portfolio.client.domain.NoteRepository; +import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; +import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingsProductNotFoundException; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommandValidator; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawInterestCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountWithdrawalCommandValidator; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionApprovalCommandValidator; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; +import org.mifosplatform.portfolio.savingsdepositaccount.command.WithDrawDepositAccountInterestCommandValidator; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccount; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountRepository; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositAccountStatus; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachine; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.DepositLifecycleStateMachineImpl; +import org.mifosplatform.portfolio.savingsdepositaccount.domain.FixedTermDepositInterestCalculator; +import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountNotFoundException; +import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountReopenException; +import org.mifosplatform.portfolio.savingsdepositaccount.exception.DepositAccountTransactionsException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements DepositAccountWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(DepositAccountWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final DepositAccountRepository depositAccountRepository; + private final DepositAccountAssembler depositAccountAssembler; + private final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator; + private final NoteRepository noteRepository; + + @Autowired + public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, + final DepositAccountRepository depositAccountRepository, final DepositAccountAssembler depositAccountAssembler, + final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator, final NoteRepository noteRepository) { + this.context = context; + this.depositAccountRepository = depositAccountRepository; + this.depositAccountAssembler = depositAccountAssembler; + this.fixedTermDepositInterestCalculator = fixedTermDepositInterestCalculator; + this.noteRepository = noteRepository; + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleDataIntegrityIssues(final DepositAccountCommand command, final DataIntegrityViolationException dve) { + + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("deposit_acc_external_id")) { throw new PlatformDataIntegrityException( + "error.msg.desposit.account.duplicate.externalId", "Deposit account with externalId " + command.getExternalId() + + " already exists", "externalId", command.getExternalId()); } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.deposit.account.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + + @Transactional + @Override + public EntityIdentifier createDepositAccount(final DepositAccountCommand command) { + + try { + this.context.authenticatedUser(); + + DepositAccountCommandValidator validator = new DepositAccountCommandValidator(command); + validator.validateForCreate(); + + final DepositAccount account = this.depositAccountAssembler.assembleFrom(command); + this.depositAccountRepository.save(account); + + return new EntityIdentifier(account.getId()); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new EntityIdentifier(Long.valueOf(-1)); + } + } + + @Transactional + @Override + public EntityIdentifier deleteDepositAccount(final Long accountId) { + + this.context.authenticatedUser(); + + DepositAccount account = this.depositAccountRepository.findOne(accountId); + if (account == null || account.isDeleted()) { throw new SavingsProductNotFoundException(accountId); } + + account.delete(); + this.depositAccountRepository.save(account); + + return new EntityIdentifier(accountId); + } + + @Transactional + @Override + public EntityIdentifier approveDepositApplication(final DepositStateTransitionApprovalCommand command) { + + // AppUser currentUser = context.authenticatedUser(); + + DepositStateTransitionApprovalCommandValidator validator = new DepositStateTransitionApprovalCommandValidator(command); + validator.validate(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } + + // FIXME - madhukar - you are checking for loan permission here instead + // of some specific deposit account permission. + // removing check for now until rules dealing with creating and + // maintaining deposit accounts in the past is clarified + LocalDate eventDate = command.getEventDate(); + // if (this.isBeforeToday(eventDate) && + // currentUser.canNotApproveLoanInPast()) { + // throw new + // NoAuthorizationException("User has no authority to approve deposit with a date in the past."); + // } + + account.approve(eventDate, defaultDepositLifecycleStateMachine(), command, this.fixedTermDepositInterestCalculator); + + this.depositAccountRepository.save(account); + + String noteText = command.getNote(); + if (StringUtils.isNotBlank(noteText)) { + Note note = Note.depositNote(account, noteText); + this.noteRepository.save(note); + } + + return new EntityIdentifier(account.getId()); + + } + + // private boolean isBeforeToday(final LocalDate date) { + // return date.isBefore(new LocalDate()); + // } + private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() { + List allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values()); + return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); + } + + @Transactional + @Override + public EntityIdentifier rejectDepositApplication(DepositStateTransitionCommand command) { + + // AppUser currentUser = context.authenticatedUser(); + + DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); + validator.validate(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } + + // removing check for now until rules dealing with creating and + // maintaining deposit accounts in the past is clarified + LocalDate eventDate = command.getEventDate(); + // if (this.isBeforeToday(eventDate) && + // currentUser.canNotApproveLoanInPast()) { + // throw new + // NoAuthorizationException("User has no authority to approve deposit with a date in the past."); + // } + + account.reject(eventDate, defaultDepositLifecycleStateMachine()); + this.depositAccountRepository.save(account); + + String noteText = command.getNote(); + if (StringUtils.isNotBlank(noteText)) { + Note note = Note.depositNote(account, noteText); + this.noteRepository.save(note); + } + + return new EntityIdentifier(account.getId()); + } + + @Transactional + @Override + public EntityIdentifier withdrawDepositApplication(DepositStateTransitionCommand command) { + + // AppUser currentUser = context.authenticatedUser(); + + DepositStateTransitionCommandValidator validator = new DepositStateTransitionCommandValidator(command); + validator.validate(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } + + // removing check for now until rules dealing with creating and + // maintaining deposit accounts in the past is clarified + LocalDate eventDate = command.getEventDate(); + // if (this.isBeforeToday(eventDate) && + // currentUser.canNotApproveLoanInPast()) { + // throw new + // NoAuthorizationException("User has no authority to approve deposit with a date in the past."); + // } + + account.withdrawnByApplicant(eventDate, defaultDepositLifecycleStateMachine()); + this.depositAccountRepository.save(account); + + String noteText = command.getNote(); + if (StringUtils.isNotBlank(noteText)) { + Note note = Note.depositNote(account, noteText); + this.noteRepository.save(note); + } + + return new EntityIdentifier(account.getId()); + } + + @Transactional + @Override + public EntityIdentifier undoDepositApproval(UndoStateTransitionCommand command) { + + context.authenticatedUser(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getLoanId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getLoanId()); } + + account.undoDepositApproval(defaultDepositLifecycleStateMachine()); + this.depositAccountRepository.save(account); + + String noteText = command.getNote(); + if (StringUtils.isNotBlank(noteText)) { + Note note = Note.depositNote(account, noteText); + this.noteRepository.save(note); + } + return new EntityIdentifier(account.getId()); + } + + /* + * @Transactional + * + * @Override public EntityIdentifier + * matureDepositApplication(DepositStateTransitionCommand command) { + * + * AppUser currentUser = context.authenticatedUser(); + * + * DepositStateTransitionCommandValidator validator = new + * DepositStateTransitionCommandValidator(command); validator.validate(); + * + * DepositAccount account = + * this.depositAccountRepository.findOne(command.getAccountId()); if + * (account == null || account.isDeleted()) { throw new + * DepositAccountNotFoundException(command.getAccountId()); } + * + * LocalDate eventDate = command.getEventDate(); if + * (this.isBeforeToday(eventDate) && currentUser.canNotApproveLoanInPast()) + * { throw new NoAuthorizationException( + * "User has no authority to mature deposit with a date in the past."); } + * + * account.matureDepositApplication(eventDate, + * defaultDepositLifecycleStateMachine()); + * this.depositAccountRepository.save(account); + * + * if(account.isRenewalAllowed()){ final DepositAccount renewedAccount = + * this.depositAccountAssembler.assembleFrom(account); + * this.depositAccountRepository.save(renewedAccount); return new + * EntityIdentifier(renewedAccount.getId()); //returns the new deposit + * application id } + * + * String noteText = command.getNote(); if + * (StringUtils.isNotBlank(noteText)) { Note note = + * Note.depositNote(account, noteText); this.noteRepository.save(note); } + * + * return new EntityIdentifier(account.getId()); } + */ + + @Transactional + @Override + public EntityIdentifier withdrawDepositAccountMoney(final DepositAccountWithdrawalCommand command) { + + context.authenticatedUser(); + + DepositAccountWithdrawalCommandValidator validator = new DepositAccountWithdrawalCommandValidator(command); + validator.validate(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } + + LocalDate eventDate = command.getMaturesOnDate(); + + Integer lockinPeriod = account.getLockinPeriod(); + LocalDate lockinPeriodExpDate = account.getActualCommencementDate().plusMonths(Integer.valueOf(lockinPeriod)); + if (account.isLockinPeriodAllowed()) { + if (eventDate.isBefore(lockinPeriodExpDate)) { throw new DepositAccountTransactionsException( + "deposit.transaction.canot.withdraw.before.lockinperiod.reached", + "You can not withdraw your application before maturity date reached"); } + } + if (eventDate.isBefore(account.maturesOnDate())) { + this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account, eventDate); + } + account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine(), fixedTermDepositInterestCalculator, eventDate); + this.depositAccountRepository.save(account); + String noteText = command.getNote(); + if (StringUtils.isNotBlank(noteText)) { + Note note = Note.depositNote(account, noteText); + this.noteRepository.save(note); + } + + return new EntityIdentifier(account.getId()); + } + + @Transactional + @Override + public EntityIdentifier withdrawDepositAccountInterestMoney(DepositAccountWithdrawInterestCommand command) { + + context.authenticatedUser(); + + WithDrawDepositAccountInterestCommandValidator validator = new WithDrawDepositAccountInterestCommandValidator(command); + validator.validate(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getAccountId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getAccountId()); } + if (account.isInterestWithdrawable() && !account.isInterestCompoundingAllowed()) { + + BigDecimal totalAvailableInterestForWithdrawal = getTotalWithdrawableInterestAvailable(account); + BigDecimal interestPaid = account.getInterstPaid(); + BigDecimal remainInterestForWithdrawal = totalAvailableInterestForWithdrawal.subtract(interestPaid); + + if (remainInterestForWithdrawal.doubleValue() > 0) { + if (remainInterestForWithdrawal.doubleValue() >= command.getWithdrawInterest().doubleValue() + && command.getWithdrawInterest().doubleValue() > 0) { + account.withdrawInterest(Money.of(account.getDeposit().getCurrency(), command.getWithdrawInterest())); + this.depositAccountRepository.save(account); + } else { + throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.exceed", "You can Withdraw " + + remainInterestForWithdrawal + " only"); + } + } else { + throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.insufficient.amount", + "You don't have enough money for withdrawal"); + } + } else { + throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.cannot.withdraw", + "You can not withdraw interst for this account"); + } + return new EntityIdentifier(account.getId()); + } + + private BigDecimal getTotalWithdrawableInterestAvailable(DepositAccount account) { + BigDecimal interstGettingForPeriod = BigDecimal.valueOf(account.getAccuredInterest().getAmount().doubleValue() + / new Double(account.getTenureInMonths())); + Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()).getMonths(); + Integer noOfPeriods = noOfMonthsforInterestCal / account.getInterestCompoundedEvery(); + return interstGettingForPeriod.multiply(new BigDecimal(noOfPeriods)); + } + + @Transactional + @Override + public EntityIdentifier renewDepositAccount(DepositAccountCommand command) { + + this.context.authenticatedUser(); + + RenewDepositAccountCommandValidator validator = new RenewDepositAccountCommandValidator(command); + validator.validateForCreate(); + + DepositAccount account = this.depositAccountRepository.findOne(command.getId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getId()); } + + // FIXME - KW - extract whats in this if into a method that naturally + // describes what you are checking. + if (account.isRenewalAllowed() + && (new LocalDate().isAfter(account.maturesOnDate()) || new LocalDate().isEqual(account.maturesOnDate()))) { + + if (account.isActive()) { + final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account, command); + this.depositAccountRepository.save(renewedAccount); + account.closeDepositAccount(defaultDepositLifecycleStateMachine()); + this.depositAccountRepository.save(account); + return new EntityIdentifier(renewedAccount.getId()); + } + + throw new DepositAccountReopenException(account.getMaturityDate()); + } + + throw new DepositAccountReopenException(account.getMaturityDate()); + } + + @Override + public EntityIdentifier updateDepositAccount(DepositAccountCommand command) { + + try { + this.context.authenticatedUser(); + + DepositAccountCommandValidator validator = new DepositAccountCommandValidator(command); + validator.validateForUpdate(); + + final DepositAccount account = this.depositAccountRepository.findOne(command.getId()); + if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(command.getId()); } + + if (account.isSubmittedAndPendingApproval()) { + this.depositAccountAssembler.assembleUpdatedDepositAccount(account, command); + } else if (account.isActive()) { + this.depositAccountAssembler.updateApprovedDepositAccount(account, command); + } + + this.depositAccountRepository.save(account); + + return new EntityIdentifier(account.getId()); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new EntityIdentifier(Long.valueOf(-1)); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositStateTransitionCommandValidator.java similarity index 88% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionCommandValidator.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositStateTransitionCommandValidator.java index bee3018d3..39dbe2586 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/DepositStateTransitionCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositStateTransitionCommandValidator.java @@ -1,12 +1,12 @@ -package org.mifosng.platform.saving.service; +package org.mifosplatform.portfolio.savingsdepositaccount.service; import java.util.ArrayList; import java.util.List; -import org.mifosng.platform.api.commands.DepositStateTransitionCommand; import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositStateTransitionCommand; public class DepositStateTransitionCommandValidator { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/RenewDepositAccountCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/RenewDepositAccountCommandValidator.java similarity index 93% rename from mifosng-provider/src/main/java/org/mifosng/platform/saving/service/RenewDepositAccountCommandValidator.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/RenewDepositAccountCommandValidator.java index 754517375..bb75fe5a1 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/saving/service/RenewDepositAccountCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/RenewDepositAccountCommandValidator.java @@ -1,12 +1,12 @@ -package org.mifosng.platform.saving.service; +package org.mifosplatform.portfolio.savingsdepositaccount.service; import java.util.ArrayList; import java.util.List; -import org.mifosng.platform.api.commands.DepositAccountCommand; import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.portfolio.savingsdepositaccount.command.DepositAccountCommand; public class RenewDepositAccountCommandValidator { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/api/DepositProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/api/DepositProductsApiResource.java new file mode 100644 index 000000000..d7faadf84 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/api/DepositProductsApiResource.java @@ -0,0 +1,190 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +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.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.configuration.service.CurrencyReadPlatformService; +import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService; +import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerService; +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingsDepositEnumerations; +import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData; +import org.mifosplatform.portfolio.savingsdepositproduct.service.DepositProductReadPlatformService; +import org.mifosplatform.portfolio.savingsdepositproduct.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 { + + private final String entityType = "DEPOSITPRODUCT"; + + @Autowired + private DepositProductReadPlatformService depositProductReadPlatformService; + + @Autowired + private CurrencyReadPlatformService currencyReadPlatformService; + + @Autowired + private DepositProductWritePlatformService depositProductWritePlatformService; + + @Autowired + private PortfolioApiDataConversionService apiDataConversionService; + + @Autowired + private PortfolioApiJsonSerializerService apiJsonSerializerService; + + @Autowired + private PlatformSecurityContext context; + + @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) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set typicalResponseParameters = new HashSet(Arrays.asList("id", "externalId", "name", "description", "createdOn", + "lastModifedOn", "currencyCode", "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", + "maturityDefaultInterestRate", "maturityMinInterestRate", "maturityMaxInterestRate", "interestCompoundedEvery", + "interestCompoundedEveryPeriodType", "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", + "interestCompoundingAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType")); + + 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.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, products); + } + + @GET + @Path("{productId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveDepositProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set typicalResponseParameters = new HashSet(Arrays.asList("id", "externalId", "name", "description", "createdOn", + "lastModifedOn", "currencyCode", "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", + "maturityDefaultInterestRate", "maturityMinInterestRate", "maturityMaxInterestRate", "interestCompoundedEvery", + "interestCompoundedEveryPeriodType", "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", + "interestCompoundingAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType")); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + DepositProductData productData = this.depositProductReadPlatformService.retrieveDepositProductData(productId); + + boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); + if (template) { + productData = handleTemplateRelatedData(responseParameters, productData); + } + + return this.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, productData); + } + + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveNewDepositProductDetails(@Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set typicalResponseParameters = new HashSet(Arrays.asList("currencyOptions", + "interestCompoundedEveryPeriodTypeOptions", "id", "externalId", "name", "description", "createdOn", "lastModifedOn", + "currencyCode", "digitsAfterDecimal", "minimumBalance", "maximumBalance", "tenureInMonths", "maturityDefaultInterestRate", + "maturityMinInterestRate", "maturityMaxInterestRate", "interestCompoundedEvery", "interestCompoundedEveryPeriodType", + "renewalAllowed", "preClosureAllowed", "preClosureInterestRate", "isLockinPeriodAllowed", "lockinPeriod", + "lockinPeriodType")); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + DepositProductData depositProduct = this.depositProductReadPlatformService.retrieveNewDepositProductDetails(); + + depositProduct = handleTemplateRelatedData(responseParameters, depositProduct); + + return this.apiJsonSerializerService.serializeDepositProductDataToJson(prettyPrint, responseParameters, depositProduct); + } + + private DepositProductData handleTemplateRelatedData(final Set responseParameters, final DepositProductData productData) { + + responseParameters.addAll(Arrays.asList("currencyOptions", "interestCompoundedEveryPeriodTypeOptions")); + List allowedCurrencies = this.currencyReadPlatformService.retrieveAllowedCurrencies(); + + EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS); + List interestCompoundedEveryPeriodTypeOptions = Arrays.asList(monthly); + + return new DepositProductData(productData, allowedCurrencies, interestCompoundedEveryPeriodTypeOptions); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/command/DepositProductCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/command/DepositProductCommand.java new file mode 100644 index 000000000..025e73d71 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/command/DepositProductCommand.java @@ -0,0 +1,246 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.command; + +import java.math.BigDecimal; +import java.util.Set; + +public class DepositProductCommand { + + private final Long id; + private final String externalId; + 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 tenureInMonths; + private final BigDecimal maturityDefaultInterestRate; + private final BigDecimal maturityMinInterestRate; + private final BigDecimal maturityMaxInterestRate; + private final Integer interestCompoundedEvery; + private final Integer interestCompoundedEveryPeriodType; + private final boolean isLockinPeriodAllowed; + private final Integer lockinPeriod; + private final Integer lockinPeriodType; + + private final boolean renewalAllowed; + private final boolean preClosureAllowed; + private final BigDecimal preClosureInterestRate; + + private final boolean interestCompoundingAllowed; + + private final Set modifiedParameters; + + public DepositProductCommand(final Set modifiedParameters, final Long id, final String externalId, final String name, + final String description, final String currencyCode, final Integer digitsAfterDecimal, final BigDecimal minimumBalance, + final BigDecimal maximumBalance, final Integer tenureInMonths, final BigDecimal maturityDefaultInterestRate, + final BigDecimal maturityMinInterestRate, final BigDecimal maturityMaxInterestRate, final Integer interestCompoundedEvery, + final Integer interestCompoundedEveryPeriodType, final boolean renewalAllowed, final boolean preClosureAllowed, + final BigDecimal preClosureInterestRate, final boolean interestCompoundingAllowed, final boolean isLockinPeriodAllowed, + final Integer lockinPeriod, final Integer lockinPeriodType) { + this.id = id; + this.externalId = externalId; + this.name = name; + this.description = description; + + this.currencyCode = currencyCode; + this.digitsAfterDecimal = digitsAfterDecimal; + + this.minimumBalance = minimumBalance; + this.maximumBalance = maximumBalance; + + this.tenureInMonths = tenureInMonths; + this.maturityDefaultInterestRate = maturityDefaultInterestRate; + this.maturityMinInterestRate = maturityMinInterestRate; + this.maturityMaxInterestRate = maturityMaxInterestRate; + this.interestCompoundedEvery = interestCompoundedEvery; + this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; + this.preClosureInterestRate = preClosureInterestRate; + + this.renewalAllowed = renewalAllowed; + this.preClosureAllowed = preClosureAllowed; + this.interestCompoundingAllowed = interestCompoundingAllowed; + + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + this.lockinPeriod = lockinPeriod; + this.lockinPeriodType = lockinPeriodType; + + this.modifiedParameters = modifiedParameters; + + } + + public Long getId() { + return id; + } + + public String getExternalId() { + return externalId; + } + + 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 getTenureInMonths() { + return tenureInMonths; + } + + public BigDecimal getMaturityDefaultInterestRate() { + return maturityDefaultInterestRate; + } + + public BigDecimal getMaturityMinInterestRate() { + return maturityMinInterestRate; + } + + public BigDecimal getMaturityMaxInterestRate() { + return maturityMaxInterestRate; + } + + public Integer getInterestCompoundedEvery() { + return interestCompoundedEvery; + } + + public Integer getInterestCompoundedEveryPeriodType() { + return interestCompoundedEveryPeriodType; + } + + public boolean isRenewalAllowed() { + return renewalAllowed; + } + + public boolean isPreClosureAllowed() { + return preClosureAllowed; + } + + public BigDecimal getPreClosureInterestRate() { + return preClosureInterestRate; + } + + public boolean isInterestCompoundingAllowed() { + return interestCompoundingAllowed; + } + + public boolean isLockinPeriodAllowed() { + return isLockinPeriodAllowed; + } + + public Integer getLockinPeriod() { + return lockinPeriod; + } + + public Integer getLockinPeriodType() { + return lockinPeriodType; + } + + public boolean isExternalIdChanged() { + return this.modifiedParameters.contains("externalId"); + } + + 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 isInterestCompoundedEveryChanged() { + return this.modifiedParameters.contains("interestCompoundedEvery"); + } + + public boolean isInterestCompoundedEveryPeriodTypeChanged() { + return this.modifiedParameters.contains("interestCompoundedEveryPeriodType"); + } + + public boolean isRenewalAllowedChanged() { + return this.modifiedParameters.contains("renewalAllowed"); + } + + public boolean isPreClosureAllowedChanged() { + return this.modifiedParameters.contains("preClosureAllowed"); + } + + public boolean isPreClosureInterestRateChanged() { + return this.modifiedParameters.contains("preClosureInterestRate"); + } + + public boolean isNoFieldChanged() { + return this.modifiedParameters.isEmpty(); + } + + public boolean interestCompoundingAllowedChanged() { + return this.modifiedParameters.contains("interestCompoundingAllowed"); + } + + public boolean isLockinPeriodAllowedChanged() { + return this.modifiedParameters.contains("isLockinPeriodAllowed"); + } + + public boolean isLockinPeriodChanged() { + return this.modifiedParameters.contains("lockinPeriod"); + } + + public boolean isLockinPeriodTypeChanged() { + return this.modifiedParameters.contains("lockinPeriodType"); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductData.java new file mode 100644 index 000000000..9b7b8ce5e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductData.java @@ -0,0 +1,251 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.data; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.joda.time.DateTime; +import org.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; + +/** + * Immutable data object representing details of a deposit product. + */ +public class DepositProductData { + + private final Long id; + private final String externalId; + 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 tenureInMonths; + private final BigDecimal maturityDefaultInterestRate; + private final BigDecimal maturityMinInterestRate; + private final BigDecimal maturityMaxInterestRate; + private final Integer interestCompoundedEvery; + private final EnumOptionData interestCompoundedEveryPeriodType; + + private final boolean renewalAllowed; + private final boolean preClosureAllowed; + private final BigDecimal preClosureInterestRate; + private final boolean interestCompoundingAllowed; + + private final boolean isLockinPeriodAllowed; + private final Integer lockinPeriod; + private final EnumOptionData lockinPeriodType; + + private final DateTime createdOn; + private final DateTime lastModifedOn; + + private final List currencyOptions; + private final List interestCompoundedEveryPeriodTypeOptions; + + public DepositProductData(final DateTime createdOn, final DateTime lastModifedOn, final Long id, final String externalId, + 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 Integer interestCompoundedEvery, + final EnumOptionData interestCompoundedEveryPeriodType, final boolean renewalAllowed, final boolean preClosureAllowed, + final BigDecimal preClosureInterestRate, final boolean interestCompoundingAllowed, final boolean isLockinPeriodAllowed, + final Integer lockinPeriod, final EnumOptionData lockinPeriodType) { + + this.createdOn = createdOn; + this.lastModifedOn = lastModifedOn; + this.id = id; + this.externalId = externalId; + this.name = name; + this.description = description; + this.currencyCode = currencyCode; + this.digitsAfterDecimal = digitsAfterDecimal; + this.minimumBalance = minimumBalance; + this.maximumBalance = maximumBalance; + + this.tenureInMonths = tenureMonths; + this.maturityDefaultInterestRate = maturityDefaultInterestRate; + this.maturityMinInterestRate = maturityMinInterestRate; + this.maturityMaxInterestRate = maturityMaxInterestRate; + this.interestCompoundedEvery = interestCompoundedEvery; + this.interestCompoundedEveryPeriodType = interestCompoundedEveryPeriodType; + this.renewalAllowed = renewalAllowed; + this.preClosureAllowed = preClosureAllowed; + this.preClosureInterestRate = preClosureInterestRate; + this.interestCompoundingAllowed = interestCompoundingAllowed; + + this.lockinPeriod = lockinPeriod; + this.lockinPeriodType = lockinPeriodType; + this.isLockinPeriodAllowed = isLockinPeriodAllowed; + + this.currencyOptions = new ArrayList(); + this.interestCompoundedEveryPeriodTypeOptions = new ArrayList(); + } + + public DepositProductData(final List currencyOptions, final EnumOptionData defaultInterestCompoundedEveryPeriodType, + final List interestCompoundedEveryPeriodTypeOptions) { + this.createdOn = null; + this.lastModifedOn = null; + this.id = null; + this.externalId = null; + this.name = null; + this.description = null; + this.currencyCode = null; + this.digitsAfterDecimal = Integer.valueOf(0); + this.minimumBalance = BigDecimal.ZERO; + this.maximumBalance = BigDecimal.ZERO; + + this.tenureInMonths = Integer.valueOf(0); + this.maturityDefaultInterestRate = BigDecimal.ZERO; + this.maturityMinInterestRate = BigDecimal.ZERO; + this.maturityMaxInterestRate = BigDecimal.ZERO; + this.interestCompoundedEvery = Integer.valueOf(1); + this.interestCompoundedEveryPeriodType = defaultInterestCompoundedEveryPeriodType; + + this.renewalAllowed = true; + this.preClosureAllowed = true; + this.preClosureInterestRate = BigDecimal.ZERO; + this.interestCompoundingAllowed = true; + + this.isLockinPeriodAllowed = true; + this.lockinPeriod = Integer.valueOf(0); + this.lockinPeriodType = defaultInterestCompoundedEveryPeriodType; + + this.currencyOptions = currencyOptions; + this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions; + } + + public DepositProductData(final DepositProductData product, final List currencyOptions, + final List interestCompoundedEveryPeriodTypeOptions) { + this.createdOn = product.getCreatedOn(); + this.lastModifedOn = product.getLastModifedOn(); + this.id = product.getId(); + this.externalId = product.getExternalId(); + this.name = product.getName(); + this.description = product.getDescription(); + this.currencyCode = product.getCurrencyCode(); + this.digitsAfterDecimal = product.getDigitsAfterDecimal(); + this.minimumBalance = product.getMinimumBalance(); + this.maximumBalance = product.getMaximumBalance(); + + this.tenureInMonths = product.getTenureInMonths(); + this.maturityDefaultInterestRate = product.getMaturityDefaultInterestRate(); + this.maturityMinInterestRate = product.getMaturityMinInterestRate(); + this.maturityMaxInterestRate = product.getMaturityMaxInterestRate(); + this.interestCompoundedEvery = product.getInterestCompoundedEvery(); + this.interestCompoundedEveryPeriodType = product.getInterestCompoundedEveryPeriodType(); + + this.renewalAllowed = product.isRenewalAllowed(); + this.preClosureAllowed = product.isPreClosureAllowed(); + this.preClosureInterestRate = product.getPreClosureInterestRate(); + this.interestCompoundingAllowed = product.isInterestCompoundingAllowed(); + + this.lockinPeriod = product.getLockinPeriod(); + this.lockinPeriodType = product.getLockinPeriodType(); + this.isLockinPeriodAllowed = product.isLockinPeriodAllowed(); + + this.currencyOptions = currencyOptions; + this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions; + } + + public Long getId() { + return id; + } + + public String getExternalId() { + return externalId; + } + + 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 getTenureInMonths() { + return tenureInMonths; + } + + public BigDecimal getMaturityDefaultInterestRate() { + return maturityDefaultInterestRate; + } + + public BigDecimal getMaturityMinInterestRate() { + return maturityMinInterestRate; + } + + public BigDecimal getMaturityMaxInterestRate() { + return maturityMaxInterestRate; + } + + public Integer getInterestCompoundedEvery() { + return interestCompoundedEvery; + } + + public EnumOptionData getInterestCompoundedEveryPeriodType() { + return interestCompoundedEveryPeriodType; + } + + public boolean isRenewalAllowed() { + return renewalAllowed; + } + + public boolean isPreClosureAllowed() { + return preClosureAllowed; + } + + public BigDecimal getPreClosureInterestRate() { + return preClosureInterestRate; + } + + public DateTime getCreatedOn() { + return createdOn; + } + + public DateTime getLastModifedOn() { + return lastModifedOn; + } + + public List getCurrencyOptions() { + return currencyOptions; + } + + public List getInterestCompoundedEveryPeriodTypeOptions() { + return interestCompoundedEveryPeriodTypeOptions; + } + + public boolean isInterestCompoundingAllowed() { + return interestCompoundingAllowed; + } + + public boolean isLockinPeriodAllowed() { + return isLockinPeriodAllowed; + } + + public Integer getLockinPeriod() { + return lockinPeriod; + } + + public EnumOptionData getLockinPeriodType() { + return lockinPeriodType; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductLookup.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductLookup.java new file mode 100644 index 000000000..90e6e5a10 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/data/DepositProductLookup.java @@ -0,0 +1,21 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.data; + +public class DepositProductLookup { + + private final Long id; + @SuppressWarnings("unused") + private final String name; + + public DepositProductLookup(final Long id, final String name) { + this.id = id; + this.name = name; + } + + public boolean hasId(final Long matchingId) { + return this.id.equals(matchingId); + } + + public Long id() { + return this.id; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProduct.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProduct.java similarity index 97% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProduct.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProduct.java index 8ae98894e..31e471834 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProduct.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProduct.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsdepositproduct.domain; import java.math.BigDecimal; @@ -9,12 +9,12 @@ import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; -import org.mifosng.platform.api.commands.DepositProductCommand; -import org.mifosng.platform.exceptions.DepositProductValueOutsideRangeException; import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.user.domain.AppUser; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; +import org.mifosplatform.portfolio.savingsdepositproduct.exception.DepositProductValueOutsideRangeException; @Entity @Table(name = "m_product_deposit", uniqueConstraints={ diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProductRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProductRepository.java similarity index 80% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProductRepository.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProductRepository.java index bea467736..eb5dbcd0f 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/domain/DepositProductRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/DepositProductRepository.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.savingproduct.domain; +package org.mifosplatform.portfolio.savingsdepositproduct.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/TenureTypeEnum.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/TenureTypeEnum.java new file mode 100644 index 000000000..5255a6d17 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/domain/TenureTypeEnum.java @@ -0,0 +1,41 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.domain; + +public enum TenureTypeEnum { + + INVALID(0, "tenureTypeEnum.invalid"), // + FIXED_PERIOD(1, "tenureTypeEnum.fixedPeriod"), // + PERPETUAL(2, "tenureTypeEnum.perpetual"); + + private final Integer value; + private final String code; + + private TenureTypeEnum(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + public Integer getValue() { + return value; + } + + public String getCode() { + return code; + } + + public static TenureTypeEnum fromInt(final Integer frequency) { + + TenureTypeEnum tenureTypeEnum = TenureTypeEnum.INVALID; + switch (frequency) { + case 1: + tenureTypeEnum = TenureTypeEnum.FIXED_PERIOD; + break; + case 2: + tenureTypeEnum = TenureTypeEnum.PERPETUAL; + break; + default: + tenureTypeEnum = TenureTypeEnum.INVALID; + break; + } + return tenureTypeEnum; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/exception/DepositProductNotFoundException.java similarity index 84% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductNotFoundException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/exception/DepositProductNotFoundException.java index 9cfd3f4d0..414a598cc 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductNotFoundException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/exception/DepositProductNotFoundException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsdepositproduct.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductValueOutsideRangeException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/exception/DepositProductValueOutsideRangeException.java similarity index 90% rename from mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductValueOutsideRangeException.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/exception/DepositProductValueOutsideRangeException.java index 12a2cbcf8..718c921f0 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/exceptions/DepositProductValueOutsideRangeException.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/exception/DepositProductValueOutsideRangeException.java @@ -1,4 +1,4 @@ -package org.mifosng.platform.exceptions; +package org.mifosplatform.portfolio.savingsdepositproduct.exception; import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductCommandValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductCommandValidator.java similarity index 97% rename from mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductCommandValidator.java rename to mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductCommandValidator.java index e21d0bec4..05b132e23 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/savingproduct/service/DepositProductCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductCommandValidator.java @@ -1,12 +1,12 @@ -package org.mifosng.platform.savingproduct.service; +package org.mifosplatform.portfolio.savingsdepositproduct.service; import java.util.ArrayList; import java.util.List; -import org.mifosng.platform.api.commands.DepositProductCommand; import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; public class DepositProductCommandValidator { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformService.java new file mode 100644 index 000000000..96c23a675 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformService.java @@ -0,0 +1,18 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductLookup; + +public interface DepositProductReadPlatformService { + + Collection retrieveAllDepositProducts(); + + Collection retrieveAllDepositProductsForLookup(); + + DepositProductData retrieveDepositProductData(Long productId); + + DepositProductData retrieveNewDepositProductDetails(); + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformServiceImpl.java new file mode 100644 index 000000000..22eb7f2e4 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductReadPlatformServiceImpl.java @@ -0,0 +1,145 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.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.mifosplatform.infrastructure.configuration.data.CurrencyData; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingsDepositEnumerations; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductData; +import org.mifosplatform.portfolio.savingsdepositproduct.data.DepositProductLookup; +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; + + @Autowired + public DepositProductReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { + this.context = context; + jdbcTemplate = new JdbcTemplate(dataSource); + } + + @Override + public Collection retrieveAllDepositProducts() { + this.context.authenticatedUser(); + DepositProductMapper depositProductMapper = new DepositProductMapper(); + String sql = "select " + depositProductMapper.depositProductSchema() + " where dp.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"; + + return this.jdbcTemplate.queryForObject(sql, depositProductMapper, new Object[] { productId }); + } + + @Override + public DepositProductData retrieveNewDepositProductDetails() { + + List currencyOptions = null; + List interestCompoundedEveryPeriodTypeOptions = null; + EnumOptionData monthly = SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.MONTHS); + + return new DepositProductData(currencyOptions, monthly, interestCompoundedEveryPeriodTypeOptions); + } + + private static final class DepositProductMapper implements RowMapper { + + public String depositProductSchema() { + return " dp.id as id, dp.external_id as exernalId, 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,dp.tenure_months as tenureMonths, " + + "dp.interest_compounded_every as interestCompoundedEvery, dp.interest_compounded_every_period_enum as interestCompoundedEveryPeriodType, " + + "dp.maturity_default_interest_rate as maturityDefaultInterestRate, dp.is_compounding_interest_allowed as interestCompoundingAllowed, " + + "dp.maturity_min_interest_rate as maturityMinInterestRate, dp.maturity_max_interest_rate as maturityMaxInterestRate, dp.is_renewal_allowed as canRenew, dp.is_preclosure_allowed as canPreClose, dp.pre_closure_interest_rate as preClosureInterestRate, " + + "dp.is_lock_in_period_allowed as isLockinPeriodAllowed, dp.lock_in_period as lockinPeriod, dp.lock_in_period_type as lockinPeriodType, " + + "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol " + + "from m_product_deposit dp join m_currency curr on curr.code = dp.currency_code "; + } + + @Override + public DepositProductData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + + Long id = rs.getLong("id"); + String exernalId = rs.getString("exernalId"); + 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"); + + Integer tenureMonths = JdbcSupport.getInteger(rs, "tenureMonths"); + Integer interestCompoundedEvery = JdbcSupport.getInteger(rs, "interestCompoundedEvery"); + Integer interestCompoundedEveryPeriodTypeValue = JdbcSupport.getInteger(rs, "interestCompoundedEveryPeriodType"); + EnumOptionData interestCompoundedEveryPeriodType = SavingsDepositEnumerations + .interestCompoundingPeriodType(interestCompoundedEveryPeriodTypeValue); + + BigDecimal maturityDefaultInterestRate = rs.getBigDecimal("maturityDefaultInterestRate"); + BigDecimal maturityMinInterestRate = rs.getBigDecimal("maturityMinInterestRate"); + BigDecimal maturityMaxInterestRate = rs.getBigDecimal("maturityMaxInterestRate"); + + Boolean canRenew = rs.getBoolean("canRenew"); + Boolean canPreClose = rs.getBoolean("canPreClose"); + Boolean interestCompoundingAllowed = rs.getBoolean("interestCompoundingAllowed"); + + BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate"); + + Boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed"); + Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod"); + Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType"); + EnumOptionData lockinPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(lockinPeriodTypeValue); + + return new DepositProductData(createdOn, lastModifedOn, id, exernalId, name, description, currencyCode, currencyDigits, + minimumBalance, maximumBalance, tenureMonths, maturityDefaultInterestRate, maturityMinInterestRate, + maturityMaxInterestRate, interestCompoundedEvery, interestCompoundedEveryPeriodType, canRenew, canPreClose, + preClosureInterestRate, interestCompoundingAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); + } + + } + + private static final class DepositProductLookupMapper implements RowMapper { + + public String depositProductLookupSchema() { + return "dp.id as id, dp.name as name from m_product_deposit dp"; + } + + @Override + public DepositProductLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + Long id = rs.getLong("id"); + String name = rs.getString("name"); + + return new DepositProductLookup(id, name); + } + + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java new file mode 100644 index 000000000..fb60c12b0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java @@ -0,0 +1,17 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.service; + +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; +import org.springframework.security.access.prepost.PreAuthorize; + +public interface DepositProductWritePlatformService { + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'CREATE_DEPOSITPRODUCT')") + EntityIdentifier createDepositProduct(DepositProductCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'UPDATE_DEPOSITPRODUCT')") + EntityIdentifier updateDepositProduct(DepositProductCommand command); + + @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'ORGANISATION_ADMINISTRATION_SUPER_USER', 'DELETE_DEPOSITPRODUCT')") + EntityIdentifier deleteDepositProduct(Long productId); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..db64f0962 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,122 @@ +package org.mifosplatform.portfolio.savingsdepositproduct.service; + +import org.mifosplatform.infrastructure.configuration.domain.MonetaryCurrency; +import org.mifosplatform.infrastructure.core.data.EntityIdentifier; +import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; +import org.mifosplatform.portfolio.savingsdepositproduct.command.DepositProductCommand; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProduct; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.DepositProductRepository; +import org.mifosplatform.portfolio.savingsdepositproduct.exception.DepositProductNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class DepositProductWritePlatformServiceJpaRepositoryImpl implements DepositProductWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(DepositProductWritePlatformServiceJpaRepositoryImpl.class); + + private final PlatformSecurityContext context; + private final DepositProductRepository depositProductRepository; + + @Autowired + public DepositProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, + final DepositProductRepository depositProductRepository) { + this.context = context; + this.depositProductRepository = depositProductRepository; + } + + /* + * Guaranteed to throw an exception no matter what the data integrity issue + * is. + */ + private void handleDataIntegrityIssues(final DepositProductCommand command, final DataIntegrityViolationException dve) { + + Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("name_deposit_product")) { throw new PlatformDataIntegrityException( + "error.msg.desposit.product.duplicate.name", "Deposit product with name: " + command.getName() + " already exists", "name", + command.getName()); } + if (realCause.getMessage().contains("externalid_deposit_product")) { throw new PlatformDataIntegrityException( + "error.msg.desposit.product.duplicate.externalId", "Deposit product with externalId " + command.getExternalId() + + " already exists", "externalId", command.getExternalId()); } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.deposit.product.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + + @Transactional + @Override + public EntityIdentifier createDepositProduct(final DepositProductCommand command) { + + try { + this.context.authenticatedUser(); + DepositProductCommandValidator validator = new DepositProductCommandValidator(command); + validator.validateForCreate(); + + PeriodFrequencyType interestCompoundingPeriodType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); + PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); + DepositProduct product = new DepositProduct(command.getName(), command.getExternalId(), command.getDescription(), currency, + command.getMinimumBalance(), command.getMaximumBalance(), command.getTenureInMonths(), + command.getMaturityDefaultInterestRate(), command.getMaturityMinInterestRate(), command.getMaturityMaxInterestRate(), + command.getInterestCompoundedEvery(), interestCompoundingPeriodType, command.isRenewalAllowed(), + command.isPreClosureAllowed(), command.getPreClosureInterestRate(), command.isInterestCompoundingAllowed(), + command.isLockinPeriodAllowed(), command.getLockinPeriod(), lockinPeriodType); + this.depositProductRepository.save(product); + + return new EntityIdentifier(product.getId()); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new EntityIdentifier(Long.valueOf(-1)); + } + } + + @Transactional + @Override + public EntityIdentifier updateDepositProduct(final DepositProductCommand command) { + + try { + 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()); } + + PeriodFrequencyType interestCompoundingFrequency = null; + if (command.isInterestCompoundedEveryPeriodTypeChanged()) { + interestCompoundingFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()); + } + + PeriodFrequencyType lockinPeriodType = null; + if (command.isLockinPeriodTypeChanged()) { + lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + } + + product.update(command, interestCompoundingFrequency, lockinPeriodType); + this.depositProductRepository.save(product); + return new EntityIdentifier(Long.valueOf(product.getId())); + } catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return new EntityIdentifier(Long.valueOf(-1)); + } + } + + @Transactional + @Override + public EntityIdentifier deleteDepositProduct(final 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())); + } +} \ No newline at end of file