diff --git a/mifosng-db/patches/11_add_saving_permissions.sql b/mifosng-db/patches/11_add_saving_permissions.sql new file mode 100644 index 000000000..f5c78c8c3 --- /dev/null +++ b/mifosng-db/patches/11_add_saving_permissions.sql @@ -0,0 +1,14 @@ + INSERT INTO `m_permission` (grouping, code, entity_name, action_name, can_maker_checker) VALUES + ('transaction_savings', 'APPROVE_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'APPROVE', 1 ), + ('transaction_savings', 'REJECT_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'REJECT', 1 ), + ('transaction_savings', 'WITHDRAW_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'WITHDRAW', 1 ), + ('transaction_savings', 'APPROVALUNDO_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'APPROVALUNDO', 1 ), + ('transaction_savings', 'WITHDRAWAL_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'WITHDRAWAL', 1 ), + ('transaction_savings', 'DEPOSIT_SAVINGSACCOUNT', 'SAVINGSACCOUNT', 'DEPOSIT', 1 ), + + ('transaction_savings', 'APPROVE_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'APPROVE', 1 ), + ('transaction_savings', 'REJECT_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'REJECT', 1 ), + ('transaction_savings', 'WITHDRAW_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'WITHDRAW', 1 ), + ('transaction_savings', 'APPROVALUNDO_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'APPROVALUNDO', 1 ), + ('transaction_savings', 'WITHDRAWAL_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'WITHDRAWAL', 1 ), + ('transaction_savings', 'DEPOSIT_SAVINGSACCOUNT_CHECKER', 'SAVINGSACCOUNT', 'DEPOSIT', 1 ); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java index 3f54f78e9..0502359df 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java @@ -396,4 +396,39 @@ public class CommandWrapper { public boolean isUndoApprovalOfDepositApplication() { return this.actionName.equalsIgnoreCase("APPROVALUNDO") && this.entityName.equalsIgnoreCase("DEPOSITACCOUNT"); } + + public boolean isSavingProductResource() { + return this.entityName.equalsIgnoreCase("SAVINGSPRODUCT"); + } + + public boolean isSavingAccountResource() { + return this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); + } + + public boolean isApprovalOfSaving() { + return this.actionName.equalsIgnoreCase("APPROVE") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); + } + + public boolean isSavingAccountDeposit() { + return this.actionName.equalsIgnoreCase("DEPOSIT") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); + } + + public boolean isRejectOfSavingAccount() { + return this.actionName.equalsIgnoreCase("REJECT") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); + } + + public boolean isWithdrawSavingAmount() { + return this.actionName.equalsIgnoreCase("WITHDRAWAL") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); + } + + public boolean isWithdrawOfSavingApplicatin() { + return this.actionName.equalsIgnoreCase("WITHDRAW") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); + } + + public boolean isUndoApprovalOfSavingAccount() { + return this.actionName.equalsIgnoreCase("APPROVALUNDO") && this.entityName.equalsIgnoreCase("SAVINGSACCOUNT"); + } + + + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index 923f9d4d0..c8b7b6515 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -769,5 +769,101 @@ public class CommandWrapperBuilder { this.href = "/depositaccounts/"+accountId; return this; } + + public CommandWrapperBuilder createSavingProduct() { + this.actionName = "CREATE"; + this.entityName = "SAVINGSPRODUCT"; + this.entityId = null; + this.href = "/savingproducts/template"; + return this; + } + + public CommandWrapperBuilder updateSavingProduct(Long productId) { + this.actionName = "UPDATE"; + this.entityName = "SAVINGSPRODUCT"; + this.entityId = productId; + this.href = "/savingproducts/"+productId; + return this; + } + + public CommandWrapperBuilder deleteSavingProduct(Long productId) { + this.actionName = "DELETE"; + this.entityName = "SAVINGSPRODUCT"; + this.entityId = productId; + this.href = "/savingproducts/"+productId; + return this; + } + + public CommandWrapperBuilder createSavingAccount() { + this.actionName = "CREATE"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = null; + this.href = "/savingaccounts/template"; + return this; + } + + public CommandWrapperBuilder updateSavingAccount(Long accountId) { + this.actionName = "UPDATE"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/savingproducts/"+accountId; + return this; + } + + public CommandWrapperBuilder deleteSavingAccount(Long accountId) { + this.actionName = "DELETE"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/savingproducts/"+accountId; + return this; + } + + public CommandWrapperBuilder approveSavingAccountApplication(Long accountId) { + this.actionName = "APPROVE"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder depositOfSavingAmount(Long accountId) { + this.actionName = "DEPOSIT"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder withdrawSavingAmount(Long accountId) { + this.actionName = "WITHDRAWAL"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder rejectSavingApplication(Long accountId) { + this.actionName = "REJECT"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder withdrawSavingApplication(Long accountId) { + this.actionName = "WITHDRAW"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } + + public CommandWrapperBuilder undoApprovalOfSavingApplication(Long accountId) { + this.actionName = "APPROVALUNDO"; + this.entityName = "SAVINGSACCOUNT"; + this.entityId = accountId; + this.href = "/depositaccounts/"+accountId; + return this; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java index 678a4eb34..c840804a9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java @@ -371,6 +371,38 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer } else { throw new UnsupportedCommandException(wrapper.commandName()); } + } else if (wrapper.isSavingProductResource()) { + if (wrapper.isCreate()) { + handler = applicationContext.getBean("createSavingProductCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isUpdate()) { + handler = applicationContext.getBean("updateSavingProductCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isDelete()) { + handler = applicationContext.getBean("deleteSavingProductCommandHandler", NewCommandSourceHandler.class); + } else { + throw new UnsupportedCommandException(wrapper.commandName()); + } + } else if (wrapper.isSavingAccountResource()) { + if (wrapper.isCreate()) { + handler = applicationContext.getBean("createSavingAccountCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isUpdate()) { + handler = applicationContext.getBean("updateSavingAccountCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isDelete()) { + handler = applicationContext.getBean("deleteSavingAccountCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isApprovalOfSaving()) { + handler = applicationContext.getBean("approveSavingAccountCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isSavingAccountDeposit()) { + handler = applicationContext.getBean("depositSavingAmountCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isRejectOfSavingAccount()) { + handler = applicationContext.getBean("rejectSavingAccountCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isWithdrawSavingAmount()) { + handler = applicationContext.getBean("withdrawSavingAmountCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isWithdrawOfSavingApplicatin()) { + handler = applicationContext.getBean("withdrawSavingApplicationCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isUndoApprovalOfSavingAccount()) { + handler = applicationContext.getBean("undoApprovalSavingAccountCommandHandler", NewCommandSourceHandler.class); + } else { + throw new UnsupportedCommandException(wrapper.commandName()); + } } else { throw new UnsupportedCommandException(wrapper.commandName()); } 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 index 3e11f7afe..f3ca0b764 100644 --- 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 @@ -23,27 +23,25 @@ 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.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; +import org.mifosplatform.infrastructure.core.api.JsonQuery; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiDataConversionService; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiJsonSerializerService; -import org.mifosplatform.portfolio.savingsaccount.command.CalculateSavingScheduleCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountApprovalCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountDepositCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountWithdrawalCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingStateTransitionsCommand; import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData; import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup; import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountTransactionsData; @@ -65,89 +63,99 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import com.google.gson.JsonElement; + @Path("/savingaccounts") @Component @Scope("singleton") public class SavingsAccountApiResource { + + private final Set SAVINGS_ACCOUNTS_DATA_PARAMETERS = 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","outstandingAmount", + "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed", + "lockinPeriod", "lockinPeriodType", "productOptions", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", + "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions","permissions","savingScheduleDatas", + "dueAmount", "savingScheduleData", "transactions","interestPostEvery","interestPostFrequency")); private final SavingAccountWritePlatformService savingAccountWritePlatformService; private final SavingAccountReadPlatformService savingAccountReadPlatformService; - private final PortfolioApiDataConversionService apiDataConversionService; - private final PortfolioApiJsonSerializerService apiJsonSerializerService; private final SavingProductReadPlatformService savingProductReadPlatformService; private final CurrencyReadPlatformService currencyReadPlatformService; private final String entityType = "SAVINGSACCOUNT"; private final PlatformSecurityContext context; private final CalculateSavingSchedule calculateSavingSchedule; private final ToApiJsonSerializer toApiJsonSerializer; - - 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", "outstandingAmount", "savingScheduleData", "transactions", "interestPostEvery", - "interestPostFrequency")); + private final ApiRequestParameterHelper apiRequestParameterHelper; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final FromJsonHelper fromJsonHelper; + private final DefaultToApiJsonSerializer savingScheduleToApiJsonSerializer; @Autowired public SavingsAccountApiResource(final SavingAccountWritePlatformService savingAccountWritePlatformService, final SavingAccountReadPlatformService savingAccountReadPlatformService, - final PortfolioApiDataConversionService apiDataConversionService, - final PortfolioApiJsonSerializerService apiJsonSerializerService, final SavingProductReadPlatformService savingProductReadPlatformService, final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context,final CalculateSavingSchedule calculateSavingSchedule, - final ToApiJsonSerializer toApiJsonSerializer) { + final ToApiJsonSerializer toApiJsonSerializer, + final ApiRequestParameterHelper apiRequestParameterHelper, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, + final FromJsonHelper fromJsonHelper, + final DefaultToApiJsonSerializer savingScheduleToApiJsonSerializer) { this.savingAccountWritePlatformService = savingAccountWritePlatformService; this.savingAccountReadPlatformService = savingAccountReadPlatformService; - this.apiDataConversionService = apiDataConversionService; - this.apiJsonSerializerService =apiJsonSerializerService; this.savingProductReadPlatformService = savingProductReadPlatformService; this.currencyReadPlatformService = currencyReadPlatformService; this.context = context; this.calculateSavingSchedule = calculateSavingSchedule; this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + this.fromJsonHelper = fromJsonHelper; + this.savingScheduleToApiJsonSerializer = savingScheduleToApiJsonSerializer; } @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String createSavingAccount(@QueryParam("command") final String commandParam, @Context final UriInfo uriInfo, - final String jsonRequestBody) { - - final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(null, jsonRequestBody); - - if (is(commandParam, "calculateSavingSchedule")) { - CalculateSavingScheduleCommand calculateSavingScheduleCommand = command.toCalculateSavingScheduleCommand(); - return calculateSavingSchedule(uriInfo, calculateSavingScheduleCommand); + final String apiRequestBodyAsJson) { + + if (is(commandParam, "calculateSavingSchedule")) { + + final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson); + final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper); + + SavingScheduleData savingSchedule = this.calculateSavingSchedule.calculateSavingSchedule(query); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + + return this.savingScheduleToApiJsonSerializer.serialize(settings, savingSchedule, new HashSet()); + } + + final CommandWrapper commandRequest = new CommandWrapperBuilder().createSavingAccount().withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - CommandProcessingResult entityIdentifier = this.savingAccountWritePlatformService.createSavingAccount(command); + return this.toApiJsonSerializer.serialize(result); - return this.toApiJsonSerializer.serialize(entityIdentifier); } - private String calculateSavingSchedule(final UriInfo uriInfo, final CalculateSavingScheduleCommand command) { - - SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(command); - final Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - return this.apiJsonSerializerService.serializeSavingScheduleDataToJson(prettyPrint, responseParameters, savingScheduleData); - } @PUT @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String updateSavingAccount(@PathParam("accountId") final Long accountId, final String jsonRequestBody) { + public String updateSavingAccount(@PathParam("accountId") final Long accountId, final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSavingAccount(accountId).withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(accountId, jsonRequestBody); - - CommandProcessingResult entityIdentifier = this.savingAccountWritePlatformService.updateSavingAccount(command); - - return this.toApiJsonSerializer.serialize(entityIdentifier); + return this.toApiJsonSerializer.serialize(result); } @GET @@ -157,15 +165,11 @@ public class SavingsAccountApiResource { 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(); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, accounts); + return this.toApiJsonSerializer.serialize(settings, accounts, SAVINGS_ACCOUNTS_DATA_PARAMETERS); } @GET @@ -180,28 +184,19 @@ public class SavingsAccountApiResource { SavingScheduleData savingScheduleData = null; Collection transactions = null; - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - SavingAccountData account = this.savingAccountReadPlatformService.retrieveSavingsAccount(accountId); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - if (template) { - account = handleTemplateRelatedData(responseParameters, account); + if (settings.isTemplate()) { + account = handleTemplateRelatedData(account); } Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); if (!associationParameters.isEmpty()) { if (associationParameters.contains("all")) { associationParameters.addAll(Arrays.asList("savingScheduleData", "transactions")); - responseParameters.addAll(Arrays.asList("permissions", "savingScheduleData", "transactions")); - } else { - responseParameters.addAll(associationParameters); - } + } if (associationParameters.contains("savingScheduleData")) { CurrencyData currencyData = account.getCurrencyData(); @@ -216,7 +211,7 @@ public class SavingsAccountApiResource { account = new SavingAccountData(account, permissions); } - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); + return this.toApiJsonSerializer.serialize(settings, account, SAVINGS_ACCOUNTS_DATA_PARAMETERS); } @GET @@ -228,23 +223,15 @@ public class SavingsAccountApiResource { 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.retrieveNewSavingsAccountDetails(clientId, productId); - account = handleTemplateRelatedData(responseParameters, account); - - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); + account = handleTemplateRelatedData(account); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, account, SAVINGS_ACCOUNTS_DATA_PARAMETERS); } - private SavingAccountData handleTemplateRelatedData(Set responseParameters, SavingAccountData account) { - responseParameters.addAll(Arrays.asList("productOptions", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", - "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions", - "dueAmount")); - + private SavingAccountData handleTemplateRelatedData(SavingAccountData account) { + Collection productOptions = savingProductReadPlatformService.retrieveAllSavingProductsForLookup(); Collection currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies(); @@ -286,52 +273,46 @@ public class SavingsAccountApiResource { @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String savingStateTransitions(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam, - final String jsonRequestBody) { - String response = null; + final String apiRequestBodyAsJson) { + + CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson); + CommandProcessingResult result = null; + if (is(commandParam, "approve")) { - SavingAccountApprovalCommand command = this.apiDataConversionService.convertJsonToSavingApprovalCommand(accountId, - jsonRequestBody); - CommandProcessingResult identifier = this.savingAccountWritePlatformService.approveSavingAccount(command); - response = this.toApiJsonSerializer.serialize(identifier); + final CommandWrapper commandRequest = builder.approveSavingAccountApplication(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); } else if (is(commandParam, "depositmoney")) { - SavingAccountDepositCommand command = this.apiDataConversionService.convertJsonToSavingAccountDepositCommand(accountId, - jsonRequestBody); - CommandProcessingResult identifier = this.savingAccountWritePlatformService.depositMoney(command); - response = this.toApiJsonSerializer.serialize(identifier); + final CommandWrapper commandRequest = builder.depositOfSavingAmount(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); } else if (is(commandParam, "withdraw")) { - SavingAccountWithdrawalCommand command = this.apiDataConversionService.convertJsonToSavingAccountWithdrawalCommand(accountId, - jsonRequestBody); - CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingAmount(command); - response = this.toApiJsonSerializer.serialize(identifier); - } else { - SavingStateTransitionsCommand command = this.apiDataConversionService.convertJsonToSavingStateTransitionCommand(accountId, - jsonRequestBody); - if (is(commandParam, "reject")) { - CommandProcessingResult identifier = this.savingAccountWritePlatformService.rejectSavingApplication(command); - response = this.toApiJsonSerializer.serialize(identifier); - } else if (is(commandParam, "withdrewbyclient")) { - CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingApplication(command); - response =this.toApiJsonSerializer.serialize(identifier); - } - UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); - if (is(commandParam, "undoapproval")) { - CommandProcessingResult identifier = this.savingAccountWritePlatformService.undoSavingAccountApproval(undoCommand); - response = this.toApiJsonSerializer.serialize(identifier); - } - } - if (response == null) { throw new UnrecognizedQueryParamException("command", commandParam); } - return response; + final CommandWrapper commandRequest = builder.withdrawSavingAmount(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "reject")) { + final CommandWrapper commandRequest = builder.rejectSavingApplication(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "withdrewbyclient")) { + final CommandWrapper commandRequest = builder.withdrawSavingApplication(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else if (is(commandParam, "undoapproval")) { + final CommandWrapper commandRequest = builder.undoApprovalOfSavingApplication(accountId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } else { throw new UnrecognizedQueryParamException("command", commandParam); } + + return this.toApiJsonSerializer.serialize(result); } @DELETE @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response deleteSavingAccount(@PathParam("accountId") final Long accountId) { + public String deleteSavingAccount(@PathParam("accountId") final Long accountId) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSavingAccount(accountId).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - this.savingAccountWritePlatformService.deleteSavingAccount(accountId); + return this.toApiJsonSerializer.serialize(result); - return Response.ok(new CommandProcessingResult(accountId)).build(); } @POST diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingSchedulePeriodData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingSchedulePeriodData.java index ad8d707b2..6e9f687a2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingSchedulePeriodData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingSchedulePeriodData.java @@ -49,4 +49,5 @@ public class SavingSchedulePeriodData { public BigDecimal getInterestAccured() { return this.interestAccured; } + } 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 index bb0594aae..05e73e573 100644 --- 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 @@ -29,12 +29,12 @@ import org.hibernate.annotations.LazyCollection; import org.hibernate.annotations.LazyCollectionOption; import org.joda.time.LocalDate; import org.joda.time.Months; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountDepositCommand; import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType; import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod; import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct; @@ -556,18 +556,20 @@ public class SavingAccount extends AbstractAuditableCustom { this.interestPostedAmount = BigDecimal.ZERO; } - public void depositMoney(final SavingAccountDepositCommand command) { - + public void depositMoney(final JsonCommand command) { + + final BigDecimal depositAmountCommandValue = command.bigDecimalValueOfParameterNamed("savingsDepositAmountPerPeriod"); + final LocalDate depositDateCommandValue = command.localDateValueOfParameterNamed("depositDate"); + BigDecimal depositAmount = BigDecimal.ZERO; BigDecimal remainAmountToBePaid = BigDecimal.ZERO; - BigDecimal commandRemainDepositAmount = command.getSavingsDepostiAmountPerPeriod(); + BigDecimal commandRemainDepositAmount = depositAmountCommandValue; - SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.deposit(command.getSavingsDepostiAmountPerPeriod(), - command.getDepositDate()); + SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.deposit(depositAmountCommandValue, depositDateCommandValue); savingAccountTransaction.updateAccount(this); this.savingAccountTransactions.add(savingAccountTransaction); - this.outstandingAmount = this.outstandingAmount.add(command.getSavingsDepostiAmountPerPeriod()); - this.totalSavingsAmount = this.totalSavingsAmount.add(command.getSavingsDepostiAmountPerPeriod()); + this.outstandingAmount = this.outstandingAmount.add(depositAmountCommandValue); + this.totalSavingsAmount = this.totalSavingsAmount.add(depositAmountCommandValue); if (SavingProductType.fromInt(this.savingProductType).isReccuring() && TenureTypeEnum.fromInt(tenureType).isFixedPeriod()) { for (SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments) { @@ -579,13 +581,13 @@ public class SavingAccount extends AbstractAuditableCustom { if (commandRemainDepositAmount.doubleValue() >= remainAmountToBePaid.doubleValue()) { savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment .getDepositPaid())); - savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate()); + savingScheduleInstallment.setPaymentDate(depositDateCommandValue.toDate()); savingScheduleInstallment.setCompleted(true); commandRemainDepositAmount = commandRemainDepositAmount.subtract(remainAmountToBePaid); } else if (commandRemainDepositAmount.doubleValue() < remainAmountToBePaid.doubleValue()) { savingScheduleInstallment.setDepositPaid(commandRemainDepositAmount.add(savingScheduleInstallment .getDepositPaid())); - savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate()); + savingScheduleInstallment.setPaymentDate(depositDateCommandValue.toDate()); commandRemainDepositAmount = BigDecimal.ZERO; } } @@ -595,7 +597,7 @@ public class SavingAccount extends AbstractAuditableCustom { } else { for (SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments) { savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid())); - savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate()); + savingScheduleInstallment.setPaymentDate(depositDateCommandValue.toDate()); } } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/ApproveSavingAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/ApproveSavingAccountCommandHandler.java new file mode 100644 index 000000000..8d30c8727 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/ApproveSavingAccountCommandHandler.java @@ -0,0 +1,24 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class ApproveSavingAccountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public ApproveSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.approveSavingAccount(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/CreateSavingAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/CreateSavingAccountCommandHandler.java new file mode 100644 index 000000000..56dfd9dcf --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/CreateSavingAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CreateSavingAccountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public CreateSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.createSavingAccount(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/DeleteSavingAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/DeleteSavingAccountCommandHandler.java new file mode 100644 index 000000000..3755b6824 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/DeleteSavingAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DeleteSavingAccountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public DeleteSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.deleteSavingAccount(command.entityId()); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/DepositSavingAmountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/DepositSavingAmountCommandHandler.java new file mode 100644 index 000000000..bf5579376 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/DepositSavingAmountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DepositSavingAmountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public DepositSavingAmountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.depositMoney(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/RejectSavingAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/RejectSavingAccountCommandHandler.java new file mode 100644 index 000000000..dca553e24 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/RejectSavingAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class RejectSavingAccountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public RejectSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.rejectSavingApplication(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/UndoApprovalSavingAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/UndoApprovalSavingAccountCommandHandler.java new file mode 100644 index 000000000..4f9bda0a0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/UndoApprovalSavingAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UndoApprovalSavingAccountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public UndoApprovalSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.undoSavingAccountApproval(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/UpdateSavingAccountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/UpdateSavingAccountCommandHandler.java new file mode 100644 index 000000000..cd95421cf --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/UpdateSavingAccountCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UpdateSavingAccountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public UpdateSavingAccountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.updateSavingAccount(command.entityId(), command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/WithdrawSavingAmountCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/WithdrawSavingAmountCommandHandler.java new file mode 100644 index 000000000..24212f3dd --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/WithdrawSavingAmountCommandHandler.java @@ -0,0 +1,24 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class WithdrawSavingAmountCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public WithdrawSavingAmountCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.withdrawSavingAmount(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/WithdrawSavingApplicationCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/WithdrawSavingApplicationCommandHandler.java new file mode 100644 index 000000000..7f6cffdb8 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/handler/WithdrawSavingApplicationCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccount.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccount.service.SavingAccountWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class WithdrawSavingApplicationCommandHandler implements NewCommandSourceHandler { + + private final SavingAccountWritePlatformService savingAccountWritePlatformService; + + @Autowired + public WithdrawSavingApplicationCommandHandler(final SavingAccountWritePlatformService savingAccountWritePlatformService) { + this.savingAccountWritePlatformService = savingAccountWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingAccountWritePlatformService.withdrawSavingApplication(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/serialization/CalculateSavingScheduleQueryFromApiJsonHelper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/serialization/CalculateSavingScheduleQueryFromApiJsonHelper.java new file mode 100644 index 000000000..c784374e3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/serialization/CalculateSavingScheduleQueryFromApiJsonHelper.java @@ -0,0 +1,123 @@ +package org.mifosplatform.portfolio.savingsaccount.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public final class CalculateSavingScheduleQueryFromApiJsonHelper { + + final Set supportedParams = new HashSet(Arrays.asList("clientId", "productId", "externalId", "savingsDepositAmountPerPeriod", "recurringInterestRate", + "savingInterestRate", "tenure", "commencementDate", "locale", "dateFormat", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "tenureType", "frequency", + "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed","depositEvery", "interestPostEvery", "interestPostFrequency")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public CalculateSavingScheduleQueryFromApiJsonHelper(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account"); + + final JsonElement element = fromApiJsonHelper.parse(json); + + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + baseDataValidator.reset().parameter("productId").value(productId).notNull(); + + final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element); + baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).notNull().zeroOrPositiveAmount(); + + final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element); + baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element); + baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).notNull().zeroOrPositiveAmount(); + + final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenure").value(tenure).notNull(); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull(); + + final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue).trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3); + + final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull(); + + final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull(); + + final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull(); + + final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull(); + + final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal", element); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull().zeroOrPositiveAmount(); + + final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element); + baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue) + .trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull(); + + final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("depositEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("depositEvery").value(depositEvery).notNull().zeroOrPositiveAmount(); + + final Integer interestPostEvery = fromApiJsonHelper.extractIntegerNamed("interestPostEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestPostEvery").value(interestPostEvery).notNull().zeroOrPositiveAmount(); + + final Integer interestPostFrequency = fromApiJsonHelper.extractIntegerNamed("interestPostFrequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestPostFrequency").value(interestPostFrequency).notNull().zeroOrPositiveAmount(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + 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/serialization/SavingAccountCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/serialization/SavingAccountCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..6b0198859 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/serialization/SavingAccountCommandFromApiJsonDeserializer.java @@ -0,0 +1,204 @@ +package org.mifosplatform.portfolio.savingsaccount.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public class SavingAccountCommandFromApiJsonDeserializer { + + final Set supportedParams = new HashSet(Arrays.asList("clientId", "productId", "externalId", "currencyCode", "digitsAfterDecimal", + "savingsDepositAmountPerPeriod", "recurringInterestRate", "savingInterestRate", "tenure","commencementDate", "locale", "dateFormat", "isLockinPeriodAllowed", + "lockinPeriod", "lockinPeriodType", "tenureType", "frequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal", + "isPartialDepositAllowed", "depositEvery", "interestPostEvery", "interestPostFrequency")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public SavingAccountCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForCreate(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account"); + + final JsonElement element = fromApiJsonHelper.parse(json); + + final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element); + baseDataValidator.reset().parameter("clientId").value(clientId).notNull(); + + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + baseDataValidator.reset().parameter("productId").value(productId).notNull(); + + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100); + + final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element); + baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).notNull().zeroOrPositiveAmount(); + + final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element); + baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element); + baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).notNull().zeroOrPositiveAmount(); + + final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenure").value(tenure).notNull(); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull(); + + final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue).trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3); + + final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull(); + + final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull(); + + final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull(); + + final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull(); + + final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal", element); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull().zeroOrPositiveAmount(); + + final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element); + baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue) + .trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull(); + + final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("depositEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("depositEvery").value(depositEvery).notNull().zeroOrPositiveAmount(); + + final Integer interestPostEvery = fromApiJsonHelper.extractIntegerNamed("interestPostEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestPostEvery").value(interestPostEvery).notNull().zeroOrPositiveAmount(); + + final Integer interestPostFrequency = fromApiJsonHelper.extractIntegerNamed("interestPostFrequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestPostFrequency").value(interestPostFrequency).notNull().zeroOrPositiveAmount(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForUpdate(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account"); + + final JsonElement element = fromApiJsonHelper.parse(json); + + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + baseDataValidator.reset().parameter("productId").value(productId).ignoreIfNull(); + + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + baseDataValidator.reset().parameter("externalId").value(externalId).ignoreIfNull().notExceedingLengthOf(100); + + final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element); + baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element); + baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element); + baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenure").value(tenure).ignoreIfNull(); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).ignoreIfNull(); + + final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue).trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull(); + + final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull(); + + final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull(); + + final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull(); + + final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal", element); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull().zeroOrPositiveAmount(); + + final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element); + baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue) + .trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull(); + + final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("depositEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("depositEvery").value(depositEvery).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer interestPostEvery = fromApiJsonHelper.extractIntegerNamed("interestPostEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestPostEvery").value(interestPostEvery).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer interestPostFrequency = fromApiJsonHelper.extractIntegerNamed("interestPostFrequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestPostFrequency").value(interestPostFrequency).ignoreIfNull().zeroOrPositiveAmount(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + 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/serialization/SavingAccountStateTransitionCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/serialization/SavingAccountStateTransitionCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..f2c5cf0f7 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/serialization/SavingAccountStateTransitionCommandFromApiJsonDeserializer.java @@ -0,0 +1,147 @@ +package org.mifosplatform.portfolio.savingsaccount.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public class SavingAccountStateTransitionCommandFromApiJsonDeserializer { + + private final Set supportedParams = new HashSet(Arrays.asList("locale", "dateFormat", "commencementDate", "eventDate", + "savingsDepositAmountPerPeriod", "minimumBalanceForWithdrawal", "recurringInterestRate", "savingInterestRate", "depositDate", + "interestType", "tenure", "tenureType", "frequency", "payEvery", "note", "interestPostEvery", "interestPostFrequency")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public SavingAccountStateTransitionCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForApprove(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account.transition"); + + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + baseDataValidator.reset().parameter("commencementDate").value(commencementDate).notNull(); + + final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element); + baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal", element); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal recurringInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element); + baseDataValidator.reset().parameter("recurringInterestRate").value(recurringInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal savingInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingInterestRate", element); + baseDataValidator.reset().parameter("savingInterestRate").value(savingInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenure").value(tenure).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer depositEvery = fromApiJsonHelper.extractIntegerNamed("payEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("payEvery").value(depositEvery).ignoreIfNull().zeroOrPositiveAmount(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForReject(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account.transition"); + + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate eventDate = fromApiJsonHelper.extractLocalDateNamed("eventDate", element); + baseDataValidator.reset().parameter("eventDate").value(eventDate).notNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForWithdrawApplication(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account.transition"); + + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate eventDate = fromApiJsonHelper.extractLocalDateNamed("eventDate", element); + baseDataValidator.reset().parameter("eventDate").value(eventDate).notNull(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForDepositAmount(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account.transaction.deposit"); + + final JsonElement element = fromApiJsonHelper.parse(json); + + final LocalDate depositDate = fromApiJsonHelper.extractLocalDateNamed("depositDate", element); + baseDataValidator.reset().parameter("depositDate").value(depositDate).notNull(); + + final BigDecimal savingsDepositAmountPerPeriod = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element); + baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(savingsDepositAmountPerPeriod).notNull().zeroOrPositiveAmount(); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + 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/service/CalculateSavingSchedule.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/CalculateSavingSchedule.java index bdea9c918..8efa1367b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/CalculateSavingSchedule.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/CalculateSavingSchedule.java @@ -5,10 +5,10 @@ */ package org.mifosplatform.portfolio.savingsaccount.service; -import org.mifosplatform.portfolio.savingsaccount.command.CalculateSavingScheduleCommand; +import org.mifosplatform.infrastructure.core.api.JsonQuery; import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData; public interface CalculateSavingSchedule { - SavingScheduleData calculateSavingSchedule(CalculateSavingScheduleCommand command); + SavingScheduleData calculateSavingSchedule(JsonQuery query); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/CalculateSavingScheduleImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/CalculateSavingScheduleImpl.java index 440845911..59541ad23 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/CalculateSavingScheduleImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/CalculateSavingScheduleImpl.java @@ -5,25 +5,10 @@ */ package org.mifosplatform.portfolio.savingsaccount.service; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collection; - -import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonQuery; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; -import org.mifosplatform.organisation.monetary.data.CurrencyData; -import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; -import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository; -import org.mifosplatform.portfolio.savingsaccount.command.CalculateSavingScheduleCommand; import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData; -import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData; -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.exception.SavingProductNotFoundException; -import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; +import org.mifosplatform.portfolio.savingsaccount.serialization.CalculateSavingScheduleQueryFromApiJsonHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -31,55 +16,27 @@ import org.springframework.stereotype.Service; public class CalculateSavingScheduleImpl implements CalculateSavingSchedule { private final PlatformSecurityContext context; - private final SavingProductRepository savingProductRepository; - private final SavingScheduleGenerator savingScheduleGenerator; - private final ApplicationCurrencyRepository applicationCurrencyRepository; + private final CalculateSavingScheduleQueryFromApiJsonHelper fromApiJsonDeserializer; + private final SavingScheduleAssembler savingScheduleAssembler; @Autowired - public CalculateSavingScheduleImpl(final PlatformSecurityContext context, final SavingProductRepository savingProductRepository, - final ApplicationCurrencyRepository applicationCurrencyRepository) { + public CalculateSavingScheduleImpl(final PlatformSecurityContext context, + final CalculateSavingScheduleQueryFromApiJsonHelper fromApiJsonDeserializer, + final SavingScheduleAssembler savingScheduleAssembler) { this.context = context; - this.savingProductRepository = savingProductRepository; - this.savingScheduleGenerator = new SavingScheduleGenerator(); - this.applicationCurrencyRepository = applicationCurrencyRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + this.savingScheduleAssembler = savingScheduleAssembler; } @Override - public SavingScheduleData calculateSavingSchedule(final CalculateSavingScheduleCommand command) { - + public SavingScheduleData calculateSavingSchedule(final JsonQuery query) { + context.authenticatedUser(); - SavingScheduleData savingScheduleData = null; - - // FIXME - HUGO - Validations should write here - final SavingProduct savingProduct = this.savingProductRepository.findOne(command.getProductId()); - if (savingProduct == null) throw new SavingProductNotFoundException(command.getProductId()); - - final Integer depositFrequency = command.getDepositEvery(); - final SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(command.getPaymentFrequencyType()); - final LocalDate scheduleStartDate = command.getPaymentsStartingFromDate(); - final BigDecimal interestRate = command.getInterestRate(); - final BigDecimal depositAmountPerPeriod = command.getDeposit(); - final Integer tenure = command.getTenure(); - final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency() - .getCode()); - SavingProductType savingProductType = SavingProductType.fromInt(savingProduct.getSavingProductRelatedDetail().getSavingProductType()); - TenureTypeEnum tenureType = TenureTypeEnum.fromInt(command.getTenureType()); - SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); - if (savingProductType.isReccuring() && tenureType.isFixedPeriod()) { - savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod, - depositFrequency, savingFrequencyType, savingProduct, tenure, applicationCurrency,interestRate,interestCalculationMethod); - } else { - final Collection periods = new ArrayList(); - CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(), - savingProduct.getCurrency().getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode()); - SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(1, new LocalDate(command.getPaymentsStartingFromDate()).plusMonths(depositFrequency), command.getDeposit(), BigDecimal.ZERO); - periods.add(installment); - savingScheduleData = new SavingScheduleData(currencyData, command.getDeposit(), BigDecimal.ZERO, BigDecimal.ZERO, periods); - } - - - return savingScheduleData; + this.fromApiJsonDeserializer.validate(query.json()); + + return this.savingScheduleAssembler.fromJson(query.parsedJson()); + } } 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 index fc5818940..63d9620c3 100644 --- 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 @@ -7,19 +7,19 @@ package org.mifosplatform.portfolio.savingsaccount.service; import java.math.BigDecimal; import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.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.CalculateSavingScheduleCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountApprovalCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountWithdrawalCommand; import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData; import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData; import org.mifosplatform.portfolio.savingsaccount.domain.ReccuringDepositInterestCalculator; @@ -40,100 +40,126 @@ import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import com.google.gson.JsonElement; + @Service public class SavingAccountAssembler { private final ClientRepository clientRepository; private final SavingProductRepository savingProductRepository; private final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator; - private final CalculateSavingSchedule calculateSavingSchedule; + private final FromJsonHelper fromApiJsonHelper; + private final SavingScheduleAssembler savingScheduleAssembler; @Autowired - public SavingAccountAssembler(final ClientRepository clientRepository, final SavingProductRepository savingProductRepository, + public SavingAccountAssembler( final ClientRepository clientRepository, + final SavingProductRepository savingProductRepository, final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, - final CalculateSavingSchedule calculateSavingSchedule) { + final FromJsonHelper fromApiJsonHelper, + final SavingScheduleAssembler savingScheduleAssembler) { this.clientRepository = clientRepository; this.savingProductRepository = savingProductRepository; this.reccuringDepositInterestCalculator = reccuringDepositInterestCalculator; - this.calculateSavingSchedule = calculateSavingSchedule; + this.fromApiJsonHelper = fromApiJsonHelper; + this.savingScheduleAssembler = savingScheduleAssembler; } - // minimumBalanceForWithdrawal,isPartialDepositAllowed - public SavingAccount assembleFrom(SavingAccountCommand command) { + public SavingAccount assembleFrom(JsonCommand command) { + + final JsonElement element = command.parsedJson(); + final Long clientId = fromApiJsonHelper.extractLongNamed("clientId", element); + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); + final String currencyCode = command.stringValueOfParameterNamed("currencyCode"); + final Integer digitsAfterDecimal = command.integerValueOfParameterNamed("digitsAfterDecimal"); + final BigDecimal savingsDepositAmountPerPeriod = command.bigDecimalValueOfParameterNamed("savingsDepositAmountPerPeriod"); + final BigDecimal recurringInterestRate = command.bigDecimalValueOfParameterNamed("recurringInterestRate"); + final BigDecimal savingInterestRateCommandValue = command.bigDecimalValueOfParameterNamed("savingInterestRate"); + final Integer tenureCommandValue = command.integerValueOfParameterNamed("tenure"); + final LocalDate commencementDate = command.localDateValueOfParameterNamed("commencementDate"); + final Integer lockinPeriodTypeCommandValue = command.integerValueOfParameterNamed("lockinPeriodType"); + final boolean isLockinPeriodAllowedCommandValue = command.booleanPrimitiveValueOfParameterNamed("isLockinPeriodAllowed"); + final Integer lockinPeriodCommandValue = command.integerValueOfParameterNamed("lockinPeriod"); + final Integer tenureTypeCommandValue = command.integerValueOfParameterNamed("tenureType"); + final Integer frequencyCommandValue = command.integerValueOfParameterNamed("frequency"); + final Integer interestTypeCommandValue = command.integerValueOfParameterNamed("interestType"); + final Integer interestCalculationMethodCommandValue = command.integerValueOfParameterNamed("interestCalculationMethod"); + // final BigDecimal minimumBalanceForWithdrawal = command.bigDecimalValueOfParameterNamed("minimumBalanceForWithdrawal"); + // final boolean isPartialDepositAllowed = command.booleanPrimitiveValueOfParameterNamed("isPartialDepositAllowed"); + final Integer depositEvery = command.integerValueOfParameterNamed("depositEvery"); + final Integer interestPostEvery = command.integerValueOfParameterNamed("interestPostEvery"); + final Integer interestPostFrequencyCommandValue = command.integerValueOfParameterNamed("interestPostFrequency"); + - Client client = this.clientRepository.findOne(command.getClientId()); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(command.getClientId()); } + Client client = this.clientRepository.findOne(clientId); + if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } - SavingProduct product = this.savingProductRepository.findOne(command.getProductId()); - if (product == null || product.isDeleted()) { throw new SavingProductNotFoundException(command.getProductId()); } + SavingProduct product = this.savingProductRepository.findOne(productId); + if (product == null || product.isDeleted()) { throw new SavingProductNotFoundException(productId); } 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()); + if (currencyCode != null) currency = new MonetaryCurrency(currencyCode, currency.getDigitsAfterDecimal()); + if (digitsAfterDecimal != null) currency = new MonetaryCurrency(currency.getCode(), digitsAfterDecimal); + Money savingsDeposit = Money.of(currency, product.getSavingProductRelatedDetail().getSavingsDepositAmount()); + if (savingsDepositAmountPerPeriod != null) { + savingsDeposit = Money.of(currency, savingsDepositAmountPerPeriod); + } + Integer tenure = product.getSavingProductRelatedDetail().getTenure(); - if (command.getTenure() != null) { - tenure = command.getTenure(); + if (tenureCommandValue != null) { + tenure = tenureCommandValue; } TenureTypeEnum tenureTypeEnum = TenureTypeEnum.fromInt(product.getSavingProductRelatedDetail().getTenureType()); - if (command.getTenureType() != null) { - tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); + if (tenureTypeCommandValue != null) { + tenureTypeEnum = TenureTypeEnum.fromInt(tenureTypeCommandValue); } SavingProductType savingProductType = SavingProductType.fromInt(product.getSavingProductRelatedDetail().getSavingProductType()); SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(product.getSavingProductRelatedDetail().getFrequency()); - if (command.getFrequency() != null) { - savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); + if (frequencyCommandValue != null) { + savingFrequencyType = SavingFrequencyType.fromInt(frequencyCommandValue); } SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(product.getSavingProductRelatedDetail() .getInterestCalculationMethod()); - if (command.getInterestCalculationMethod() != null) { - savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); + if (interestCalculationMethodCommandValue != null) { + savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(interestCalculationMethodCommandValue); } SavingsInterestType interestType = SavingsInterestType.fromInt(product.getSavingProductRelatedDetail().getInterestType()); - if (command.getInterestType() != null) { - interestType = SavingsInterestType.fromInt(command.getInterestType()); + if (interestTypeCommandValue != null) { + interestType = SavingsInterestType.fromInt(interestTypeCommandValue); } - BigDecimal reccuringInterestRate = command.getRecurringInterestRate(); BigDecimal savingInterestRate = product.getInterestRate(); - if (command.getSavingInterestRate() != null) savingInterestRate = command.getSavingInterestRate(); + if (savingInterestRateCommandValue != null) savingInterestRate = savingInterestRateCommandValue; boolean isLockinPeriodAllowed = product.getSavingProductRelatedDetail().isLockinPeriodAllowed(); - if (command.isLockinPeriodChanged()) { - isLockinPeriodAllowed = command.isLockinPeriodAllowed(); + if (isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)) { + isLockinPeriodAllowed = isLockinPeriodAllowedCommandValue; } Integer lockinPeriod = product.getSavingProductRelatedDetail().getLockinPeriod(); - if (command.getLockinPeriod() != null) { - lockinPeriod = command.getLockinPeriod(); + if (lockinPeriodCommandValue != null) { + lockinPeriod = lockinPeriodCommandValue; } PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(product.getSavingProductRelatedDetail().getLockinPeriodType()); - if (command.getLockinPeriodType() != null) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + if (lockinPeriodTypeCommandValue != null) { + lockinPeriodType = PeriodFrequencyType.fromInt(lockinPeriodTypeCommandValue); } - Integer depositEvery = command.getDepositEvery(); - - Integer interestPostEvery = command.getInterestPostEvery(); + Integer interestPostFrequency = PeriodFrequencyType.fromInt(interestPostFrequencyCommandValue).getValue(); - Integer interestPostFrequency =command.getInterestPostFrequency(); - - SavingAccount account = SavingAccount.openNew(client, product, command.getExternalId(), savingsDeposit, reccuringInterestRate, - savingInterestRate, tenure, command.getCommencementDate(), tenureTypeEnum, savingProductType, savingFrequencyType, + SavingAccount account = SavingAccount.openNew(client, product, externalId, savingsDeposit, recurringInterestRate, + savingInterestRate, tenure, commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, interestType, savingInterestCalculationMethod, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator, defaultDepositLifecycleStateMachine(),depositEvery,interestPostEvery, interestPostFrequency); - SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(command - .toCalculateSavingScheduleCommand()); + SavingScheduleData savingScheduleData = this.savingScheduleAssembler.fromJson(element); for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) { final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate() @@ -144,103 +170,181 @@ public class SavingAccountAssembler { return account; } - public void assembleFrom(SavingAccountCommand command, SavingAccount account) { + public Map assembleFrom(JsonCommand command, SavingAccount account) { + + JsonElement element = command.parsedJson(); + Map actualChanges = new LinkedHashMap(20); + final String localeAsInput = command.locale(); 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 SavingProductNotFoundException(command.getProductId()); + final String productIdParamName = "productId"; + if (command.isChangeInLongParameterNamed(productIdParamName, product.getId())) { + final Long newValue = command.longValueOfParameterNamed(productIdParamName); + if (newValue != null) { + product = this.savingProductRepository.findOne(newValue); + actualChanges.put("productId", newValue); + if (product == null || product.isDeleted()) throw new SavingProductNotFoundException(newValue); } } String externalId = account.getExternalId(); - if (command.isExternalIdChanged()) { - externalId = command.getExternalId(); + final String externalIdParamName = "externalId"; + if (command.isChangeInStringParameterNamed(externalIdParamName, externalId)) { + final String newValue = command.stringValueOfParameterNamed(externalIdParamName); + actualChanges.put(externalIdParamName, newValue); + externalId = newValue; } Money savingsDeposit = Money.of(product.getCurrency(), account.getSavingsDepositAmountPerPeriod()); - if (command.isDepositAmountChanged()) { - savingsDeposit = Money.of(product.getCurrency(), command.getSavingsDepositAmount()); + + final String savingsDepositAmountPerPeriodParamName = "savingsDepositAmountPerPeriod"; + if (command.isChangeInBigDecimalParameterNamed(savingsDepositAmountPerPeriodParamName, savingsDeposit.getAmount())) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingsDepositAmountPerPeriodParamName); + actualChanges.put(savingsDepositAmountPerPeriodParamName, newValue); + actualChanges.put("locale", localeAsInput); + savingsDeposit = Money.of(savingsDeposit.getCurrency(), newValue); } + Integer tenure = account.getTenure(); - if (command.isTenureInMonthsChanged()) { - tenure = command.getTenure(); + final String tenureParamName = "tenure"; + if (command.isChangeInIntegerParameterNamed(tenureParamName, tenure)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureParamName); + actualChanges.put(tenureParamName, newValue); + actualChanges.put("locale", localeAsInput); + tenure = newValue; } - + LocalDate commencementDate = new LocalDate(account.getProjectedCommencementDate()); - if (command.isCommencementDateChanged()) { - commencementDate = command.getCommencementDate(); + final String commencementDateParamName = "commencementDate"; + if (command.isChangeInLocalDateParameterNamed("commencementDate", commencementDate)) { + final LocalDate newValue = command.localDateValueOfParameterNamed(commencementDateParamName); + actualChanges.put(commencementDateParamName, newValue); + commencementDate = newValue; } - + TenureTypeEnum tenureTypeEnum = TenureTypeEnum.fromInt(account.getTenureType()); - if (command.isTenureTypeEnumChanged()) { - tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType()); + final String tenureTypeParamName = "tenureType"; + if (command.isChangeInIntegerParameterNamed(tenureTypeParamName, tenureTypeEnum.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(tenureTypeParamName); + actualChanges.put(tenureTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + tenureTypeEnum = TenureTypeEnum.fromInt(newValue); } - + SavingProductType savingProductType = SavingProductType.fromInt(account.getSavingProductType()); SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(account.getFrequency()); - if (command.isSavingFrequencyTypeChanged()) { - savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); + final String frequencyParamName = "frequency"; + if (command.isChangeInIntegerParameterNamed(frequencyParamName, savingFrequencyType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(frequencyParamName); + actualChanges.put(frequencyParamName, newValue); + actualChanges.put("locale", localeAsInput); + savingFrequencyType = SavingFrequencyType.fromInt(newValue); } SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(account.getInterestCalculationMethod()); - if (command.isSavingInterestCalculationMethodChanged()) { - savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); + final String interestCalculationMethodParamName = "interestCalculationMethod"; + if (command.isChangeInIntegerParameterNamed(interestCalculationMethodParamName, savingInterestCalculationMethod.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(interestCalculationMethodParamName); + actualChanges.put(interestCalculationMethodParamName, newValue); + actualChanges.put("locale", localeAsInput); + savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(newValue); } BigDecimal reccuringInterestRate = account.getReccuringInterestRate(); - if (command.isReccuringInterestRateChanged()) { - reccuringInterestRate = command.getRecurringInterestRate(); + final String reccuringInterestRateParamName = "reccuringInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(reccuringInterestRateParamName, reccuringInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(reccuringInterestRateParamName); + actualChanges.put(reccuringInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + reccuringInterestRate = newValue; } - + BigDecimal savingInterestRate = account.getSavingInterestRate(); - if (command.isSavingInterestRateChanged()) { - savingInterestRate = command.getSavingInterestRate(); + final String savingInterestRateParamName = "savingInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(savingInterestRateParamName, savingInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingInterestRateParamName); + actualChanges.put(savingInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + savingInterestRate = newValue; } - - boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); - if (command.isLockinPeriodAllowedChanged()) { - isLockinPeriodAllowed = command.isLockinPeriodAllowed(); + + Boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed(); + final String isLockinPeriodAllowedParamName = "isLockinPeriodAllowed"; + if (command.isChangeInBooleanParameterNamed(isLockinPeriodAllowedParamName, isLockinPeriodAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isLockinPeriodAllowedParamName); + actualChanges.put(isLockinPeriodAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + isLockinPeriodAllowed = newValue; } Integer lockinPeriod = account.getLockinPeriod(); - if (command.isLockinPeriodChanged()) { - lockinPeriod = command.getLockinPeriod(); + final String lockinPeriodParamName = "lockinPeriod"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodParamName, lockinPeriod)) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodParamName); + actualChanges.put(lockinPeriodParamName, newValue); + actualChanges.put("locale", localeAsInput); + lockinPeriod = newValue; } PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(account.getLockinPeriodType()); - if (command.isLockinPeriodTypeChanged()) { - lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); + final String lockinPeriodTypeParamName = "lockinPeriodType"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodTypeParamName, lockinPeriodType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodTypeParamName); + actualChanges.put(lockinPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + lockinPeriodType = PeriodFrequencyType.fromInt(newValue); } - + Integer payEvery = account.getPayEvery(); - if(command.isDepositEveryChanged()){ - payEvery = command.getDepositEvery(); + final String depositEveryParamName = "depositEvery"; + if (command.isChangeInIntegerParameterNamed(depositEveryParamName, payEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(depositEveryParamName); + actualChanges.put(depositEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + payEvery = newValue; } SavingsInterestType interestType = SavingsInterestType.fromInt(product.getSavingProductRelatedDetail().getInterestType()); - if (command.getInterestType() != null) { - interestType = SavingsInterestType.fromInt(command.getInterestType()); + final String interestTypeParamName = "interestType"; + if (command.isChangeInIntegerParameterNamed(interestTypeParamName, interestType.getValue())) { + final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName); + actualChanges.put(interestTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestType = SavingsInterestType.fromInt(newValue); } - Integer interestPostEvery = command.getInterestPostEvery(); + Integer interestPostEvery = account.getInterestPostEvery(); + final String interestPostEveryParamName = "interestPostEvery"; + if (command.isChangeInIntegerParameterNamed(interestPostEveryParamName, interestPostEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(interestPostEveryParamName); + actualChanges.put(interestPostEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestPostEvery = newValue; + } + + Integer interestPostFrequency =account.getInterestPostFrequency(); + final String interestPostFrequencyParamName = "interestPostFrequency"; + if (command.isChangeInIntegerParameterNamed(interestPostFrequencyParamName, interestPostFrequency)) { + final Integer newValue = command.integerValueOfParameterNamed(interestPostFrequencyParamName); + actualChanges.put(interestPostFrequencyParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestPostFrequency = PeriodFrequencyType.fromInt(newValue).getValue(); + } - Integer interestPostFrequency =command.getInterestPostFrequency(); - account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator,payEvery, interestType, interestPostEvery, interestPostFrequency); - SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(command - .toCalculateSavingScheduleCommand()); + SavingScheduleData savingScheduleData = this.savingScheduleAssembler.fromJson(element); for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) { final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate() .toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(), savingSchedulePeriodData.getInterestAccured()); account.addSavingScheduleInstallment(installment); } + + return actualChanges; } @@ -249,91 +353,151 @@ public class SavingAccountAssembler { return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); } - public void approveSavingAccount(SavingAccountApprovalCommand command, SavingAccount account) { + public Map approveSavingAccount(JsonCommand command, SavingAccount account) { - LocalDate approvalDate = account.projectedCommencementDate(); - if (command.getApprovalDate() != null) { - approvalDate = command.getApprovalDate(); - } + JsonElement element = command.parsedJson(); + Map actualChanges = new LinkedHashMap(20); + final String localeAsInput = command.locale(); + + LocalDate approvalDate = account.projectedCommencementDate(); + final String commencementDateParamName = "commencementDate"; + if (command.isChangeInLocalDateParameterNamed("commencementDate", approvalDate)) { + final LocalDate newValue = command.localDateValueOfParameterNamed(commencementDateParamName); + actualChanges.put(commencementDateParamName, newValue); + approvalDate = newValue; + } BigDecimal savingsDepositAmountPerPeriod=account.getSavingsDepositAmountPerPeriod(); - if (command.getDepositAmountPerPeriod() != null) { - savingsDepositAmountPerPeriod = command.getDepositAmountPerPeriod(); - } + final String savingsDepositAmountPerPeriodParamName = "savingsDepositAmountPerPeriod"; + if (command.isChangeInBigDecimalParameterNamed(savingsDepositAmountPerPeriodParamName, savingsDepositAmountPerPeriod)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingsDepositAmountPerPeriodParamName); + actualChanges.put(savingsDepositAmountPerPeriodParamName, newValue); + actualChanges.put("locale", localeAsInput); + savingsDepositAmountPerPeriod = newValue; + } BigDecimal recurringInterestRate = account.getReccuringInterestRate(); - if (command.getRecurringInterestRate() != null) { - recurringInterestRate = command.getRecurringInterestRate(); - } + final String reccuringInterestRateParamName = "reccuringInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(reccuringInterestRateParamName, recurringInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(reccuringInterestRateParamName); + actualChanges.put(reccuringInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + recurringInterestRate = newValue; + } BigDecimal savingInterestRate = account.getSavingInterestRate(); - if (command.getSavingInterestRate() != null) { - savingInterestRate = command.getSavingInterestRate(); - } + final String savingInterestRateParamName = "savingInterestRate"; + if (command.isChangeInBigDecimalParameterNamed(savingInterestRateParamName, savingInterestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingInterestRateParamName); + actualChanges.put(savingInterestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + savingInterestRate = newValue; + } Integer interestType = account.getInterestType(); - if (command.getInterestType() != null) { - interestType = SavingsInterestType.fromInt(command.getInterestType()).getValue(); - } + final String interestTypeParamName = "interestType"; + if (command.isChangeInIntegerParameterNamed(interestTypeParamName, interestType)) { + final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName); + actualChanges.put(interestTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestType = SavingsInterestType.fromInt(newValue).getValue(); + } Integer tenure = account.getTenure(); - if (command.getTenure() != null) { - tenure = command.getTenure(); - } + final String tenureParamName = "tenure"; + if (command.isChangeInIntegerParameterNamed(tenureParamName, tenure)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureParamName); + actualChanges.put(tenureParamName, newValue); + actualChanges.put("locale", localeAsInput); + tenure = newValue; + } Integer tenureType = account.getTenureType(); - if (command.getTenureType() != null) { - tenureType = TenureTypeEnum.fromInt(command.getTenureType()).getValue(); - } + final String tenureTypeParamName = "tenureType"; + if (command.isChangeInIntegerParameterNamed(tenureTypeParamName, tenureType)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureTypeParamName); + actualChanges.put(tenureTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + tenureType = TenureTypeEnum.fromInt(newValue).getValue(); + } Integer frequency = account.getFrequency(); - if (command.getDepositFrequencyType() != null) { - frequency = SavingFrequencyType.fromInt(command.getDepositFrequencyType()).getValue(); - } + final String frequencyParamName = "frequency"; + if (command.isChangeInIntegerParameterNamed(frequencyParamName, frequency)) { + final Integer newValue = command.integerValueOfParameterNamed(frequencyParamName); + actualChanges.put(frequencyParamName, newValue); + actualChanges.put("locale", localeAsInput); + frequency = SavingFrequencyType.fromInt(newValue).getValue(); + } - Integer payEvery = account.getPayEvery(); - if (command.getDepositEvery() != null) { - payEvery = command.getDepositEvery(); - } + Integer depositEvery = account.getPayEvery(); + final String depositEveryParamName = "depositEvery"; + if (command.isChangeInIntegerParameterNamed(depositEveryParamName, depositEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(depositEveryParamName); + actualChanges.put(depositEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + depositEvery = newValue; + } Integer interestPostEvery = account.getInterestPostEvery(); - if (command.getInterestPostEvery() != null) { - interestPostEvery = command.getInterestPostEvery(); - } + final String interestPostEveryParamName = "interestPostEvery"; + if (command.isChangeInIntegerParameterNamed(interestPostEveryParamName, interestPostEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(interestPostEveryParamName); + actualChanges.put(interestPostEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestPostEvery = newValue; + } + Integer interestPostFrequency =account.getInterestPostFrequency(); - if (command.getInterestPostFrequency() != null) { - interestPostFrequency = command.getInterestPostFrequency(); - } + final String interestPostFrequencyParamName = "interestPostFrequency"; + if (command.isChangeInIntegerParameterNamed(interestPostFrequencyParamName, interestPostFrequency)) { + final Integer newValue = command.integerValueOfParameterNamed(interestPostFrequencyParamName); + actualChanges.put(interestPostFrequencyParamName, newValue); + actualChanges.put("locale", localeAsInput); + interestPostFrequency = PeriodFrequencyType.fromInt(newValue).getValue(); + } account.approveSavingAccount(approvalDate, savingsDepositAmountPerPeriod, recurringInterestRate, savingInterestRate, interestType, - tenure, tenureType, frequency, payEvery,defaultDepositLifecycleStateMachine(),this.reccuringDepositInterestCalculator, interestPostEvery, interestPostFrequency); + tenure, tenureType, frequency, depositEvery,defaultDepositLifecycleStateMachine(),this.reccuringDepositInterestCalculator, interestPostEvery, interestPostFrequency); - CalculateSavingScheduleCommand calculateSavingScheduleCommand = new CalculateSavingScheduleCommand(account.getProduct().getId(), savingsDepositAmountPerPeriod, payEvery, - frequency, recurringInterestRate, approvalDate, tenure,tenureType,interestPostEvery,interestPostFrequency,account.getInterestCalculationMethod()); + /*CalculateSavingScheduleCommand calculateSavingScheduleCommand = new CalculateSavingScheduleCommand(account.getProduct().getId(), savingsDepositAmountPerPeriod, payEvery, + frequency, recurringInterestRate, approvalDate, tenure,tenureType,interestPostEvery,interestPostFrequency,account.getInterestCalculationMethod());*/ - SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(calculateSavingScheduleCommand); + SavingScheduleData savingScheduleData = this.savingScheduleAssembler.calculateSavingSchedule(element,account); for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) { final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate() .toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(),savingSchedulePeriodData.getInterestAccured()); account.addSavingScheduleInstallment(installment); } + + return actualChanges; } - public void withdrawSavingAccountMoney( SavingAccountWithdrawalCommand command, SavingAccount account) { + public void withdrawSavingAccountMoney( JsonCommand command, SavingAccount account) { - if (command.getAmount().doubleValue() > account.getOutstandingAmount().doubleValue()) { + LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); + BigDecimal withdraAmount = command.bigDecimalValueOfParameterNamed("amount"); + if (withdraAmount.doubleValue() > account.getOutstandingAmount().doubleValue()) { throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.exceed", "You can Withdraw " + account.getOutstandingAmount() + " only"); } - account.withdrawAmount(command.getAmount(),command.getTransactionDate()); + account.withdrawAmount(withdraAmount, transactionDate); } public void postInterest(SavingAccount account) { account.postInterest(); } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } } \ 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 index bafa0bee1..bfbb4ac8c 100644 --- 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 @@ -7,45 +7,30 @@ package org.mifosplatform.portfolio.savingsaccount.service; import java.util.Collection; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.loanaccount.command.UndoStateTransitionCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountApprovalCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountDepositCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountWithdrawalCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingStateTransitionsCommand; import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup; -import org.springframework.security.access.prepost.PreAuthorize; public interface SavingAccountWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_SAVINGSACCOUNT')") - CommandProcessingResult createSavingAccount(SavingAccountCommand command); + CommandProcessingResult createSavingAccount(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_SAVINGSACCOUNT')") - CommandProcessingResult updateSavingAccount(SavingAccountCommand command); + CommandProcessingResult updateSavingAccount(Long accountId, JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - CommandProcessingResult rejectSavingApplication(SavingStateTransitionsCommand command); + CommandProcessingResult rejectSavingApplication(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - CommandProcessingResult withdrawSavingApplication(SavingStateTransitionsCommand command); + CommandProcessingResult withdrawSavingApplication(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - CommandProcessingResult undoSavingAccountApproval(UndoStateTransitionCommand undoCommand); + CommandProcessingResult undoSavingAccountApproval(JsonCommand undoCommand); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - CommandProcessingResult approveSavingAccount(SavingAccountApprovalCommand command); + CommandProcessingResult approveSavingAccount(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - CommandProcessingResult depositMoney(SavingAccountDepositCommand command); + CommandProcessingResult depositMoney(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") - CommandProcessingResult withdrawSavingAmount(SavingAccountWithdrawalCommand command); + CommandProcessingResult withdrawSavingAmount(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") CommandProcessingResult deleteSavingAccount(Long accountId); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER')") CommandProcessingResult postInterest(Collection savingAccounts); + } \ 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 index d5ba8438d..f46cc2461 100644 --- 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 @@ -5,37 +5,31 @@ */ package org.mifosplatform.portfolio.savingsaccount.service; -import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; - import java.util.Arrays; import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.bouncycastle.crypto.RuntimeCryptoException; import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; 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.savingsaccount.command.SavingAccountApprovalCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountApprovalCommandValidator; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountCommandValidator; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountDepositCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountDepositCommandValidator; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountStateTransitionCommandValidator; -import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountWithdrawalCommand; -import org.mifosplatform.portfolio.savingsaccount.command.SavingStateTransitionsCommand; import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup; import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccount; import org.mifosplatform.portfolio.savingsaccount.domain.SavingAccountRepository; import org.mifosplatform.portfolio.savingsaccount.exception.SavingAccountNotFoundException; +import org.mifosplatform.portfolio.savingsaccount.serialization.SavingAccountCommandFromApiJsonDeserializer; +import org.mifosplatform.portfolio.savingsaccount.serialization.SavingAccountStateTransitionCommandFromApiJsonDeserializer; 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.exception.InvalidSavingStateTransitionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -52,24 +46,29 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin private final SavingAccountRepository savingAccountRepository; private final SavingAccountAssembler savingAccountAssembler; private final NoteRepository noteRepository; + private final SavingAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer; + private final SavingAccountStateTransitionCommandFromApiJsonDeserializer savingAccountStateTransitionCommandFromApiJsonDeserializer; @Autowired public SavingAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final SavingAccountRepository savingAccountRepository, final SavingAccountAssembler savingAccountAssembler, - final NoteRepository noteRepository) { + final NoteRepository noteRepository, + final SavingAccountCommandFromApiJsonDeserializer fromApiJsonDeserializer, + final SavingAccountStateTransitionCommandFromApiJsonDeserializer savingAccountStateTransitionCommandFromApiJsonDeserializer) { this.context = context; this.savingAccountRepository = savingAccountRepository; this.savingAccountAssembler = savingAccountAssembler; this.noteRepository = noteRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + this.savingAccountStateTransitionCommandFromApiJsonDeserializer = savingAccountStateTransitionCommandFromApiJsonDeserializer; } @Transactional @Override - public CommandProcessingResult createSavingAccount(final SavingAccountCommand command) { + public CommandProcessingResult createSavingAccount(final JsonCommand command) { try { this.context.authenticatedUser(); - SavingAccountCommandValidator validator = new SavingAccountCommandValidator(command); - validator.validateForCreate(); + this.fromApiJsonDeserializer.validateForCreate(command.json()); SavingAccount account = this.savingAccountAssembler.assembleFrom(command); this.savingAccountRepository.save(account); @@ -85,20 +84,22 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin } @Override - public CommandProcessingResult updateSavingAccount(final SavingAccountCommand command) { + public CommandProcessingResult updateSavingAccount(final Long accountId, final JsonCommand command) { try { this.context.authenticatedUser(); - SavingAccountCommandValidator validator = new SavingAccountCommandValidator(command); - validator.validateForUpdate(); + this.fromApiJsonDeserializer.validateForUpdate(command.json()); + + Map changes = new LinkedHashMap(20);; - SavingAccount account = this.savingAccountRepository.findOne(command.getId()); - if (account == null || account.isDeleted()) { throw new SavingAccountNotFoundException(command.getId()); } + SavingAccount account = this.savingAccountRepository.findOne(accountId); + if (account == null || account.isDeleted()) { throw new SavingAccountNotFoundException(accountId); } if (account.isPendingApproval()) { - this.savingAccountAssembler.assembleFrom(command, account); + changes = this.savingAccountAssembler.assembleFrom(command, account); this.savingAccountRepository.save(account); } return new CommandProcessingResultBuilder() // .withEntityId(account.getId()) // + .with(changes) .build(); } catch (DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve); @@ -110,12 +111,14 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final SavingAccountCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand 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()); } + if (realCause.getMessage().contains("saving_acc_external_id")) { + final String externalId = command.stringValueOfParameterNamed("externalId"); + throw new PlatformDataIntegrityException( + "error.msg.saving.account.duplicate.externalId", "Saving account with externalId " + externalId + + " already exists", "externalId", externalId); } logger.error(dve.getMessage(), dve); throw new PlatformDataIntegrityException("error.msg.saving.account.unknown.data.integrity.issue", @@ -123,22 +126,25 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin } @Override - public CommandProcessingResult rejectSavingApplication(SavingStateTransitionsCommand command) { + public CommandProcessingResult rejectSavingApplication(JsonCommand command) { this.context.authenticatedUser(); + this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForReject(command.json()); - SavingAccountStateTransitionCommandValidator validator = new SavingAccountStateTransitionCommandValidator(command); - validator.validate(); - - SavingAccount account = this.savingAccountRepository.findOne(command.getAccountId()); + SavingAccount account = this.savingAccountRepository.findOne(command.entityId()); if (account == null || account.isDeleted()) { - throw new SavingAccountNotFoundException(command.getAccountId()); + throw new SavingAccountNotFoundException(command.entityId()); } - LocalDate eventDate = command.getEventDate(); + LocalDate eventDate = command.localDateValueOfParameterNamed("eventDate"); + if (this.isBeforeToday(eventDate)) { + final String errorMessage = "User has no authority to reject saving with a date in the past. "; + + throw new InvalidSavingStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, account.projectedCommencementDate(), eventDate); + } account.reject(eventDate, defaultDepositLifecycleStateMachine()); this.savingAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); @@ -155,21 +161,25 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin } @Override - public CommandProcessingResult withdrawSavingApplication(SavingStateTransitionsCommand command) { + public CommandProcessingResult withdrawSavingApplication(JsonCommand command) { this.context.authenticatedUser(); + this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForWithdrawApplication(command.json()); - SavingAccountStateTransitionCommandValidator validator = new SavingAccountStateTransitionCommandValidator(command); - validator.validate(); - - SavingAccount account = this.savingAccountRepository.findOne(command.getAccountId()); + SavingAccount account = this.savingAccountRepository.findOne(command.entityId()); if (account == null || account.isDeleted()) { - throw new SavingAccountNotFoundException(command.getAccountId()); + throw new SavingAccountNotFoundException(command.entityId()); } - LocalDate eventDate = command.getEventDate(); + LocalDate eventDate = command.localDateValueOfParameterNamed("eventDate"); + if (this.isBeforeToday(eventDate)) { + final String errorMessage = "User has no authority to withdraw saving with a date in the past. "; + + throw new InvalidSavingStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, account.projectedCommencementDate(), eventDate); + } + account.withdrawnByApplicant(eventDate, defaultDepositLifecycleStateMachine()); this.savingAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); @@ -181,17 +191,17 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin } @Override - public CommandProcessingResult undoSavingAccountApproval(UndoStateTransitionCommand command) { + public CommandProcessingResult undoSavingAccountApproval(JsonCommand command) { this.context.authenticatedUser(); - SavingAccount account = this.savingAccountRepository.findOne(command.getLoanId()); + SavingAccount account = this.savingAccountRepository.findOne(command.entityId()); if (account == null || account.isDeleted()) { throw new SavingAccountNotFoundException(command.getLoanId()); } account.undoSavingAccountApproval(defaultDepositLifecycleStateMachine()); this.savingAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); @@ -203,23 +213,27 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin } @Override - public CommandProcessingResult approveSavingAccount(SavingAccountApprovalCommand command) { + public CommandProcessingResult approveSavingAccount(JsonCommand command) { this.context.authenticatedUser(); - SavingAccountApprovalCommandValidator validator = new SavingAccountApprovalCommandValidator(command); - validator.validate(); - SavingAccount account = this.savingAccountRepository.findOne(command.getAccountId()); + this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForApprove(command.json()); + + SavingAccount account = this.savingAccountRepository.findOne(command.entityId()); if (account == null || account.isDeleted()) { - throw new SavingAccountNotFoundException(command.getAccountId()); + throw new SavingAccountNotFoundException(command.entityId()); } - LocalDate approvalDate = command.getApprovalDate(); + LocalDate approvalDate = command.localDateValueOfParameterNamed("commencementDate"); if (approvalDate.isBefore(account.projectedCommencementDate())) { - throw new RuntimeCryptoException("Date of approval cannot before application submission date"); + final String errorMessage = "The date on which a saving is approved cannot be before its submittal date: " + + approvalDate.toString(); + + throw new InvalidSavingStateTransitionException("approval", "cannot.be.before.submittal.date", errorMessage, + account.projectedCommencementDate(), approvalDate); } - this.savingAccountAssembler.approveSavingAccount(command,account); + Map changes = this.savingAccountAssembler.approveSavingAccount(command,account); this.savingAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); @@ -227,25 +241,25 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin return new CommandProcessingResultBuilder() // .withEntityId(account.getId()) // + .with(changes) .build(); } @Override - public CommandProcessingResult depositMoney(SavingAccountDepositCommand command) { + public CommandProcessingResult depositMoney(JsonCommand command) { this.context.authenticatedUser(); - SavingAccountDepositCommandValidator validator = new SavingAccountDepositCommandValidator(command); - validator.validate(); + this.savingAccountStateTransitionCommandFromApiJsonDeserializer.validateForDepositAmount(command.json()); - SavingAccount account = this.savingAccountRepository.findOne(command.getAccountId()); + SavingAccount account = this.savingAccountRepository.findOne(command.entityId()); if (account == null || account.isDeleted()) { - throw new SavingAccountNotFoundException(command.getAccountId()); + throw new SavingAccountNotFoundException(command.entityId()); } if (account.isActive()) account.depositMoney(command); this.savingAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); @@ -256,17 +270,17 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin } @Override - public CommandProcessingResult withdrawSavingAmount(SavingAccountWithdrawalCommand command) { + public CommandProcessingResult withdrawSavingAmount(JsonCommand command) { this.context.authenticatedUser(); - SavingAccount account = this.savingAccountRepository.findOne(command.getAccountId()); + SavingAccount account = this.savingAccountRepository.findOne(command.entityId()); if (account == null || account.isDeleted()) { - throw new SavingAccountNotFoundException(command.getAccountId()); + throw new SavingAccountNotFoundException(command.entityId()); } if (account.isActive()) this.savingAccountAssembler.withdrawSavingAccountMoney(command,account); this.savingAccountRepository.save(account); - String noteText = command.getNote(); + String noteText = command.stringValueOfParameterNamed("note"); if (StringUtils.isNotBlank(noteText)) { Note note = Note.savingNote(account, noteText); this.noteRepository.save(note); @@ -307,4 +321,7 @@ public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements Savin return new CommandProcessingResult(Long.valueOf(-1)); } } + private boolean isBeforeToday(final LocalDate date) { + return date.isBefore(new LocalDate()); + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingScheduleAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingScheduleAssembler.java new file mode 100644 index 000000000..a23d9eedf --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/service/SavingScheduleAssembler.java @@ -0,0 +1,139 @@ +package org.mifosplatform.portfolio.savingsaccount.service; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.organisation.monetary.data.CurrencyData; +import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; +import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository; +import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData; +import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData; +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.exception.SavingProductNotFoundException; +import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.google.gson.JsonElement; + +@Service +public class SavingScheduleAssembler { + + private final FromJsonHelper fromApiJsonHelper; + private final SavingProductRepository savingProductRepository; + private final SavingScheduleGenerator savingScheduleGenerator; + private final ApplicationCurrencyRepository applicationCurrencyRepository; + + @Autowired + public SavingScheduleAssembler( final FromJsonHelper fromApiJsonHelper, + final SavingProductRepository savingProductRepository, + final ApplicationCurrencyRepository applicationCurrencyRepository) { + this.fromApiJsonHelper = fromApiJsonHelper; + this.savingProductRepository = savingProductRepository; + this.savingScheduleGenerator = new SavingScheduleGenerator(); + this.applicationCurrencyRepository = applicationCurrencyRepository; + } + + public SavingScheduleData fromJson(JsonElement element) { + + SavingScheduleData savingScheduleData = null; + + final Long productId = fromApiJsonHelper.extractLongNamed("productId", element); + final Integer depositEvery = fromApiJsonHelper.extractIntegerWithLocaleNamed("depositEvery", element); + final LocalDate scheduleStartDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + final BigDecimal interestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element); + final BigDecimal depositAmountPerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element); + final Integer tenure = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenure", element); + + final Integer tenureTypeCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenureType", element); + TenureTypeEnum tenureType = TenureTypeEnum.fromInt(tenureTypeCommandValue); + final Integer frequencyCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("frequency", element); + SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(frequencyCommandValue); + //final Integer interestTypeCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("interestType", element); + //SavingsInterestType interestType = SavingsInterestType.fromInt(interestTypeCommandValue); + final Integer interestCalculationMethodCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("interestCalculationMethod", element); + SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(interestCalculationMethodCommandValue); + + final SavingProduct savingProduct = this.savingProductRepository.findOne(productId); + if (savingProduct == null) throw new SavingProductNotFoundException(productId); + final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency().getCode()); + + SavingProductType savingProductType = SavingProductType.fromInt(savingProduct.getSavingProductRelatedDetail().getSavingProductType()); + + if (savingProductType.isReccuring() && tenureType.isFixedPeriod()) { + savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod, + depositEvery, savingFrequencyType, savingProduct, tenure, applicationCurrency,interestRate,interestCalculationMethod); + } else { + final Collection periods = new ArrayList(); + CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(), + savingProduct.getCurrency().getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode()); + SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(1, new LocalDate(scheduleStartDate).plusMonths(depositEvery), depositAmountPerPeriod, BigDecimal.ZERO); + periods.add(installment); + savingScheduleData = new SavingScheduleData(currencyData, depositAmountPerPeriod, BigDecimal.ZERO, BigDecimal.ZERO, periods); + } + + return savingScheduleData; + } + + public SavingScheduleData calculateSavingSchedule(JsonElement element, SavingAccount account) { + + SavingScheduleData savingScheduleData = null; + + SavingProduct savingProduct = account.getProduct(); + SavingProductType savingProductType = SavingProductType.fromInt(account.getSavingProductType()); + SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(account.getInterestCalculationMethod()); + + TenureTypeEnum tenureType = TenureTypeEnum.fromInt(account.getTenureType()); + final Integer tenureTypeCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenureType", element); + if (tenureTypeCommandValue != null) tenureType = TenureTypeEnum.fromInt(tenureTypeCommandValue); + + LocalDate scheduleStartDate = new LocalDate(account.getProjectedCommencementDate()); + final LocalDate commencementDate = fromApiJsonHelper.extractLocalDateNamed("commencementDate", element); + if (commencementDate != null) scheduleStartDate = commencementDate ; + + BigDecimal depositAmountPerPeriod = account.getSavingsDepositAmountPerPeriod(); + final BigDecimal savingsDepositAmountPerPeriod = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmountPerPeriod", element); + if (savingsDepositAmountPerPeriod != null ) depositAmountPerPeriod = savingsDepositAmountPerPeriod; + + Integer depositEvery = account.getPayEvery(); + final Integer depositEveryCommandValue = fromApiJsonHelper.extractIntegerWithLocaleNamed("depositEvery", element); + if (depositEveryCommandValue != null ) depositEvery = depositEveryCommandValue; + + SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(account.getFrequency()); + final Integer frequencyCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("frequency", element); + if (frequencyCommandValue != null ) savingFrequencyType = SavingFrequencyType.fromInt(frequencyCommandValue); + + Integer tenure = account.getTenure(); + final Integer tenureCommandValue = this.fromApiJsonHelper.extractIntegerWithLocaleNamed("tenure", element); + if (tenureCommandValue != null ) tenure = tenureCommandValue; + + BigDecimal interestRate = account.getReccuringInterestRate(); + final BigDecimal recurringInterestRate = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("recurringInterestRate", element); + if (recurringInterestRate != null ) interestRate = recurringInterestRate; + + final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency().getCode()); + + if (savingProductType.isReccuring() && tenureType.isFixedPeriod()) { + savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod, + depositEvery, savingFrequencyType, savingProduct, tenure, applicationCurrency,interestRate,interestCalculationMethod); + } else { + final Collection periods = new ArrayList(); + CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(), + savingProduct.getCurrency().getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode()); + SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(1, new LocalDate(scheduleStartDate).plusMonths(depositEvery), depositAmountPerPeriod, BigDecimal.ZERO); + periods.add(installment); + savingScheduleData = new SavingScheduleData(currencyData, depositAmountPerPeriod, BigDecimal.ZERO, BigDecimal.ZERO, periods); + } + + return savingScheduleData; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java index 14e3e295b..b62d89ec6 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/api/SavingProductsApiResource.java @@ -23,16 +23,17 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; -import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +import org.mifosplatform.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.organisation.monetary.service.CurrencyReadPlatformService; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiDataConversionService; -import org.mifosplatform.portfolio.savingsaccount.PortfolioApiJsonSerializerService; -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; @@ -41,7 +42,6 @@ import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingsInterestT 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; @@ -51,78 +51,76 @@ import org.springframework.stereotype.Component; @Component @Scope("singleton") public class SavingProductsApiResource { + + private final Set SAVINGS_PRODUCT_DATA_PARAMETERS = new HashSet(Arrays.asList("currencyOptions", "id", + "createdOn", "lastModifedOn", "locale", "name", "description", "currencyCode", "digitsAfterDecimal", "interstRate", + "minInterestRate", "maxInterestRate", "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency", + "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "isLockinPeriodAllowed", + "lockinPeriod", "lockinPeriodType", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", "depositEvery", + "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions")); private final SavingProductReadPlatformService savingProductReadPlatformService; - private final SavingProductWritePlatformService savingProductWritePlatformService; - private final PortfolioApiDataConversionService apiDataConversionService; - private final PortfolioApiJsonSerializerService apiJsonSerializerService; private final CurrencyReadPlatformService currencyReadPlatformService; private final String entityType = "SAVINGSPRODUCT"; private final PlatformSecurityContext context; private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final ApiRequestParameterHelper apiRequestParameterHelper; @Autowired public SavingProductsApiResource(final SavingProductReadPlatformService savingProductReadPlatformService, - final SavingProductWritePlatformService savingProductWritePlatformService, - final PortfolioApiDataConversionService apiDataConversionService, - final PortfolioApiJsonSerializerService apiJsonSerializerService, final CurrencyReadPlatformService currencyReadPlatformService, final PlatformSecurityContext context, - final DefaultToApiJsonSerializer toApiJsonSerializer) { + final DefaultToApiJsonSerializer toApiJsonSerializer, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, + final ApiRequestParameterHelper apiRequestParameterHelper) { this.savingProductReadPlatformService = savingProductReadPlatformService; - this.savingProductWritePlatformService = savingProductWritePlatformService; - this.apiDataConversionService = apiDataConversionService; - this.apiJsonSerializerService = apiJsonSerializerService; this.currencyReadPlatformService = currencyReadPlatformService; this.context = context; this.toApiJsonSerializer = toApiJsonSerializer; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + this.apiRequestParameterHelper = apiRequestParameterHelper; } @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String createSavingProduct(final String jsonRequestBody) { + public String createSavingProduct(final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().createSavingProduct().withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - final SavingProductCommand command = this.apiDataConversionService.convertJsonToSavingProductCommand(null, jsonRequestBody); + return this.toApiJsonSerializer.serialize(result); - CommandProcessingResult entityIdentifier = this.savingProductWritePlatformService.createSavingProduct(command); - - return this.toApiJsonSerializer.serialize(entityIdentifier); } @PUT @Path("{productId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String updateSavingProduct(@PathParam("productId") final Long productId, final String jsonRequestBody) { + public String updateSavingProduct(@PathParam("productId") final Long productId, final String apiRequestBodyAsJson) { - SavingProductCommand command = this.apiDataConversionService.convertJsonToSavingProductCommand(productId, jsonRequestBody); - CommandProcessingResult entityIdentifier = this.savingProductWritePlatformService.updateSavingProduct(command); - return this.toApiJsonSerializer.serialize(entityIdentifier); + final CommandWrapper commandRequest = new CommandWrapperBuilder().updateSavingProduct(productId).withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String retrieveAllSavingProducts(@Context final UriInfo uriInfo) { - - context.authenticatedUser().validateHasReadPermission(entityType); - - Set typicalResponseParameters = new HashSet(Arrays.asList("id", "createdOn", "lastModifedOn", "locale", "name", - "description", "currencyCode", "digitsAfterDecimal", "interstRate", "minInterestRate", "maxInterestRate", - "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency", "interestType", - "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "isLockinPeriodAllowed", - "lockinPeriod", "lockinPeriodType", "depositEvery")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - + + context.authenticatedUser().validateHasReadPermission(entityType); + Collection products = this.savingProductReadPlatformService.retrieveAllSavingProducts(); - - return this.apiJsonSerializerService.serializeSavingProductDataToJson(prettyPrint, responseParameters, products); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + + return this.toApiJsonSerializer.serialize(settings, products, SAVINGS_PRODUCT_DATA_PARAMETERS); } @GET @@ -133,26 +131,15 @@ public class SavingProductsApiResource { context.authenticatedUser().validateHasReadPermission(entityType); - Set typicalResponseParameters = new HashSet(Arrays.asList("id", "createdOn", "lastModifedOn", "locale", "name", - "description", "currencyCode", "digitsAfterDecimal", "interstRate", "minInterestRate", "maxInterestRate", - "savingsDepositAmount", "savingProductType", "tenureType", "tenure", "frequency", "interestType", - "interestCalculationMethod", "minimumBalanceForWithdrawal", "isPartialDepositAllowed", "isLockinPeriodAllowed", - "lockinPeriod", "lockinPeriodType", "depositEvery")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveSavingProduct(productId); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - if (template) { - savingProduct = handleTemplateRelatedData(responseParameters, savingProduct); + if (settings.isTemplate()) { + savingProduct = handleTemplateRelatedData(savingProduct); } - return this.apiJsonSerializerService.serializeSavingProductDataToJson(prettyPrint, responseParameters, savingProduct); + return this.toApiJsonSerializer.serialize(settings, savingProduct, SAVINGS_PRODUCT_DATA_PARAMETERS); } @GET @@ -163,26 +150,17 @@ public class SavingProductsApiResource { context.authenticatedUser().validateHasReadPermission(entityType); - Set typicalResponseParameters = new HashSet(Arrays.asList("id", "createdOn", "lastModifedOn", "locale", "name", - "description", "currencyCode", "digitsAfterDecimal", "interstRate", "savingsDepositAmount", "savingProductType", - "tenureType", "tenure", "frequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal", - "isPartialDepositAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "currencyOptions", "depositEvery")); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveNewSavingProductDetails(); - savingProduct = handleTemplateRelatedData(responseParameters, savingProduct); - return this.apiJsonSerializerService.serializeSavingProductDataToJson(prettyPrint, responseParameters, savingProduct); + + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + + savingProduct = handleTemplateRelatedData(savingProduct); + + return this.toApiJsonSerializer.serialize(settings, savingProduct, SAVINGS_PRODUCT_DATA_PARAMETERS); } - private SavingProductData handleTemplateRelatedData(Set responseParameters, SavingProductData savingProduct) { + private SavingProductData handleTemplateRelatedData(SavingProductData savingProduct) { - responseParameters.addAll(Arrays.asList("currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", - "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions")); Collection currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies(); EnumOptionData reccuring = SavingProductEnumerations.savingProductType(SavingProductType.RECURRING); @@ -218,9 +196,12 @@ public class SavingProductsApiResource { @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public String deleteProduct(@PathParam("productId") final Long productId) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteSavingProduct(productId).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - this.savingProductWritePlatformService.deleteSavingProduct(productId); + return this.toApiJsonSerializer.serialize(result); - return this.toApiJsonSerializer.serialize(productId); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProduct.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProduct.java index 4ff4ab769..6d0d26a4d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProduct.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProduct.java @@ -6,6 +6,8 @@ package org.mifosplatform.portfolio.savingsaccountproduct.domain; import java.math.BigDecimal; +import java.util.LinkedHashMap; +import java.util.Map; import javax.persistence.Column; import javax.persistence.Embedded; @@ -13,10 +15,10 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; import org.mifosplatform.useradministration.domain.AppUser; @@ -94,16 +96,46 @@ public class SavingProduct extends AbstractAuditableCustom { return savingProductRelatedDetail; } - public void update(final SavingProductCommand command) { + public Map update(final JsonCommand command) { - if (command.isNameChanged()) { - this.name = command.getName(); + final Map actualChanges = new LinkedHashMap(20); + + final String nameParamName = "name"; + if (command.isChangeInStringParameterNamed(nameParamName, this.name)) { + final String newValue = command.stringValueOfParameterNamed(nameParamName); + actualChanges.put(nameParamName, newValue); + this.name = newValue; + } + + final String descriptionParamName = "description"; + if (command.isChangeInStringParameterNamed(descriptionParamName, this.description)) { + final String newValue = command.stringValueOfParameterNamed(descriptionParamName); + actualChanges.put(descriptionParamName, newValue); + this.description = newValue; } - if (command.isDescriptionChanged()) { - this.description = command.getDescription(); - } - - this.savingProductRelatedDetail.update(command); + return this.savingProductRelatedDetail.update(command, actualChanges); } + + public static SavingProduct assembleFromJson(JsonCommand command, MonetaryCurrency currency, SavingProductType savingProductType, TenureTypeEnum tenureType, + SavingFrequencyType savingFrequencyType, SavingsInterestType interestType, SavingInterestCalculationMethod savingInterestCalculationMethod, + PeriodFrequencyType lockinPeriodType) { + + final String name = command.stringValueOfParameterNamed("name"); + final String description = command.stringValueOfParameterNamed("description"); + final BigDecimal interestRate = command.bigDecimalValueOfParameterNamed("interestRate"); + final BigDecimal minInterestRate = command.bigDecimalValueOfParameterNamed("minInterestRate"); + final BigDecimal maxInterestRate = command.bigDecimalValueOfParameterNamed("maxInterestRate"); + final BigDecimal savingsDepositAmount = command.bigDecimalValueOfParameterNamed("savingsDepositAmount"); + final Integer tenure = command.integerValueOfParameterNamed("tenure"); + final BigDecimal minimumBalanceForWithdrawal = command.bigDecimalValueOfParameterNamed("minimumBalanceForWithdrawal"); + final boolean isPartialDepositAllowed = command.booleanPrimitiveValueOfParameterNamed("isPartialDepositAllowed"); + final boolean isLockinPeriodAllowed = command.booleanPrimitiveValueOfParameterNamed("isLockinPeriodAllowed"); + final Integer lockinPeriod = command.integerValueOfParameterNamed("lockinPeriod"); + final Integer depositEvery = command.integerValueOfParameterNamed("depositEvery"); + + return new SavingProduct(name, description, currency, interestRate, minInterestRate, maxInterestRate, savingsDepositAmount, depositEvery, savingProductType, + tenureType, tenure, savingFrequencyType, interestType, savingInterestCalculationMethod, minimumBalanceForWithdrawal, isPartialDepositAllowed, + isLockinPeriodAllowed, lockinPeriod, lockinPeriodType); + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRelatedDetail.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRelatedDetail.java index d7400b605..4583d833d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRelatedDetail.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/domain/SavingProductRelatedDetail.java @@ -6,14 +6,15 @@ package org.mifosplatform.portfolio.savingsaccountproduct.domain; import java.math.BigDecimal; +import java.util.Map; import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.Embedded; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType; -import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; @Embeddable @@ -114,76 +115,145 @@ public class SavingProductRelatedDetail { return BigDecimal.valueOf(Double.valueOf(this.savingsDepositAmount.stripTrailingZeros().toString())); } - public void update(SavingProductCommand command) { - Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal(); - if (command.isDigitsAfterDecimalChanged()) { - digitsAfterDecimal = command.getDigitsAfterDecimal(); + public Map update(final JsonCommand command, final Map actualChanges) { + + final String localeAsInput = command.locale(); + + Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal(); + final String digitsAfterDecimalParamName = "digitsAfterDecimal"; + if (command.isChangeInIntegerParameterNamed(digitsAfterDecimalParamName, digitsAfterDecimal)) { + final Integer newValue = command.integerValueOfParameterNamed(digitsAfterDecimalParamName); + actualChanges.put(digitsAfterDecimalParamName, newValue); + actualChanges.put("locale", localeAsInput); + digitsAfterDecimal = newValue; + this.currency = new MonetaryCurrency(this.currency.getCode(), digitsAfterDecimal); } - String currencyCodeChanged = this.currency.getCode(); - if (command.isCurrencyCodeChanged()) { - currencyCodeChanged = command.getCurrencyCode(); - } - - if (command.isDigitsAfterDecimalChanged() || command.isCurrencyCodeChanged()) { - this.currency = new MonetaryCurrency(currencyCodeChanged, digitsAfterDecimal); - } - - if (command.isInterestRateChanged()) { - this.interestRate = command.getInterestRate(); - } - - if (command.isSavingsDepositAmountChanged()) { - this.savingsDepositAmount = command.getSavingsDepositAmount(); + String currencyCode = this.currency.getCode(); + final String currencyCodeParamName = "currencyCode"; + if (command.isChangeInStringParameterNamed(currencyCodeParamName, currencyCode)) { + final String newValue = command.stringValueOfParameterNamed(currencyCodeParamName); + actualChanges.put(currencyCodeParamName, newValue); + currencyCode = newValue; + this.currency = new MonetaryCurrency(currencyCode, this.currency.getDigitsAfterDecimal()); } - if (command.isDepositEveryChanged()) { - this.depositEvery=command.getDepositEvery(); - } - - if (command.isSavingProductTypeChanged()) { - this.savingProductType = SavingProductType.fromInt(command.getSavingProductType()).getValue(); + final String interestRateParamName = "interestRate"; + if (command.isChangeInBigDecimalParameterNamed(interestRateParamName, this.interestRate)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(interestRateParamName); + actualChanges.put(interestRateParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestRate = newValue; } - if (command.isTenureTypeChanged()) { - this.tenureType = TenureTypeEnum.fromInt(command.getTenureType()).getValue(); + final String savingsDepositAmountParamName = "savingsDepositAmount"; + if (command.isChangeInBigDecimalParameterNamed(savingsDepositAmountParamName, this.savingsDepositAmount)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(savingsDepositAmountParamName); + actualChanges.put(savingsDepositAmountParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.savingsDepositAmount = newValue; + } + + final String depositEveryParamName = "depositEvery"; + if (command.isChangeInIntegerParameterNamed(depositEveryParamName, this.depositEvery)) { + final Integer newValue = command.integerValueOfParameterNamed(depositEveryParamName); + actualChanges.put(depositEveryParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.depositEvery = newValue; + } + + + final String savingProductTypeParamName = "savingProductType"; + if (command.isChangeInIntegerParameterNamed(savingProductTypeParamName, this.savingProductType)) { + final Integer newValue = command.integerValueOfParameterNamed(savingProductTypeParamName); + actualChanges.put(savingProductTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.savingProductType = SavingProductType.fromInt(newValue).getValue(); + } + + final String tenureTypeParamName = "tenureType"; + if (command.isChangeInIntegerParameterNamed(tenureTypeParamName, this.tenureType)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureTypeParamName); + actualChanges.put(tenureTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.tenureType = TenureTypeEnum.fromInt(newValue).getValue(); } - if (command.isTenureChanged()) { - this.tenure = command.getTenure(); + final String tenureParamName = "tenure"; + if (command.isChangeInIntegerParameterNamed(tenureParamName, this.tenure)) { + final Integer newValue = command.integerValueOfParameterNamed(tenureParamName); + actualChanges.put(tenureParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.tenure = newValue; + } + + final String frequencyParamName = "frequency"; + if (command.isChangeInIntegerParameterNamed(frequencyParamName, this.frequency)) { + final Integer newValue = command.integerValueOfParameterNamed(frequencyParamName); + actualChanges.put(frequencyParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.frequency = SavingFrequencyType.fromInt(newValue).getValue(); + } + + final String interestTypeParamName = "interestType"; + if (command.isChangeInIntegerParameterNamed(interestTypeParamName, this.interestType)) { + final Integer newValue = command.integerValueOfParameterNamed(interestTypeParamName); + actualChanges.put(interestTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestType = SavingsInterestType.fromInt(newValue).getValue(); + } + + final String interestCalculationMethodParamName = "interestCalculationMethod"; + if (command.isChangeInIntegerParameterNamed(interestCalculationMethodParamName, this.interestCalculationMethod)) { + final Integer newValue = command.integerValueOfParameterNamed(interestCalculationMethodParamName); + actualChanges.put(interestCalculationMethodParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.interestCalculationMethod = SavingInterestCalculationMethod.fromInt(newValue).getValue(); } - if (command.isFrequencyChanged()) { - this.frequency = SavingFrequencyType.fromInt(command.getFrequency()).getValue(); + final String minimumBalanceForWithdrawalParamName = "minimumBalanceForWithdrawal"; + if (command.isChangeInBigDecimalParameterNamed(minimumBalanceForWithdrawalParamName, this.minimumBalanceForWithdrawal)) { + final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minimumBalanceForWithdrawalParamName); + actualChanges.put(minimumBalanceForWithdrawalParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.minimumBalanceForWithdrawal = newValue; } - if (command.isInterestTypeChanged()) { - this.interestType = SavingsInterestType.fromInt(command.getInterestType()).getValue(); + final String isPartialDepositAllowedParamName = "isPartialDepositAllowed"; + if (command.isChangeInBooleanParameterNamed(isPartialDepositAllowedParamName, this.isPartialDepositAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isPartialDepositAllowedParamName); + actualChanges.put(isPartialDepositAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.isPartialDepositAllowed = newValue; } + + final String isLockinPeriodAllowedParamName = "isLockinPeriodAllowed"; + if (command.isChangeInBooleanParameterNamed(isLockinPeriodAllowedParamName, this.isLockinPeriodAllowed)) { + final Boolean newValue = command.booleanObjectValueOfParameterNamed(isLockinPeriodAllowedParamName); + actualChanges.put(isLockinPeriodAllowedParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.isLockinPeriodAllowed = newValue; + } + + final String lockinPeriodParamName = "lockinPeriod"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodParamName, this.lockinPeriod)) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodParamName); + actualChanges.put(lockinPeriodParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.lockinPeriod = newValue; + } + + + final String lockinPeriodTypeParamName = "lockinPeriodType"; + if (command.isChangeInIntegerParameterNamed(lockinPeriodTypeParamName, this.lockinPeriodType)) { + final Integer newValue = command.integerValueOfParameterNamed(lockinPeriodTypeParamName); + actualChanges.put(lockinPeriodTypeParamName, newValue); + actualChanges.put("locale", localeAsInput); + this.lockinPeriodType = PeriodFrequencyType.fromInt(newValue).getValue(); + } + + return actualChanges; - if (command.isInterestCalculationMethodChanged()) { - this.interestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()).getValue(); - } - - if (command.isMinimumBalanceForWithdrawalChanged()) { - this.minimumBalanceForWithdrawal = command.getMinimumBalanceForWithdrawal(); - } - - if (command.isPartialDepositAllowedChanged()) { - this.isPartialDepositAllowed = command.isPartialDepositAllowed(); - } - - if (command.isLockinPeriodAllowedChanged()) { - this.isLockinPeriodAllowed = command.isLockinPeriodAllowed(); - } - - if (command.isLockinPeriodChanged()) { - this.lockinPeriod = command.getLockinPeriod(); - } - - if (command.isLockinPeriodTypeChanged()) { - this.lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()).getValue(); - } } public BigDecimal getSavingsDepositAmount() { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/CreateSavingProductCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/CreateSavingProductCommandHandler.java new file mode 100644 index 000000000..7ab5f81c3 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/CreateSavingProductCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccountproduct.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CreateSavingProductCommandHandler implements NewCommandSourceHandler{ + + private final SavingProductWritePlatformService savingProductWritePlatformService; + + @Autowired + public CreateSavingProductCommandHandler(final SavingProductWritePlatformService savingProductWritePlatformService) { + this.savingProductWritePlatformService = savingProductWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingProductWritePlatformService.createSavingProduct(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/DeleteSavingProductCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/DeleteSavingProductCommandHandler.java new file mode 100644 index 000000000..307ed6b05 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/DeleteSavingProductCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccountproduct.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class DeleteSavingProductCommandHandler implements NewCommandSourceHandler { + + private final SavingProductWritePlatformService savingProductWritePlatformService; + + @Autowired + public DeleteSavingProductCommandHandler(final SavingProductWritePlatformService savingProductWritePlatformService) { + this.savingProductWritePlatformService = savingProductWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingProductWritePlatformService.deleteSavingProduct(command.entityId()); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/UpdateSavingProductCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/UpdateSavingProductCommandHandler.java new file mode 100644 index 000000000..a3b5942ff --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/handler/UpdateSavingProductCommandHandler.java @@ -0,0 +1,25 @@ +package org.mifosplatform.portfolio.savingsaccountproduct.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class UpdateSavingProductCommandHandler implements NewCommandSourceHandler { + + private final SavingProductWritePlatformService savingProductWritePlatformService; + + @Autowired + public UpdateSavingProductCommandHandler(final SavingProductWritePlatformService savingProductWritePlatformService) { + this.savingProductWritePlatformService = savingProductWritePlatformService; + } + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return this.savingProductWritePlatformService.updateSavingProduct(command.entityId(), command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/serialization/SavingProductCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/serialization/SavingProductCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..6bcc54083 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/serialization/SavingProductCommandFromApiJsonDeserializer.java @@ -0,0 +1,208 @@ +package org.mifosplatform.portfolio.savingsaccountproduct.serialization; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public class SavingProductCommandFromApiJsonDeserializer { + + Set supportedParams = new HashSet(Arrays.asList("locale", "name", "description", "currencyCode", + "digitsAfterDecimal", "interestRate", "minInterestRate", "maxInterestRate", "savingsDepositAmount", "savingProductType", + "tenureType", "tenure", "frequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal", + "isPartialDepositAllowed", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType", "depositEvery")); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public SavingProductCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForCreate(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final String name = fromApiJsonHelper.extractStringNamed("name", element); + baseDataValidator.reset().parameter("name").value(name).notBlank().notExceedingLengthOf(100); + + final String description = fromApiJsonHelper.extractStringNamed("description", element); + baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(500); + + final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element); + baseDataValidator.reset().parameter("currencyCode").value(currencyCode).notBlank(); + + final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault()); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).notNull().inMinMaxRange(0, 6); + + final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRate", element); + baseDataValidator.reset().parameter("interestRate").value(interestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal minInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minInterestRate", element); + baseDataValidator.reset().parameter("minInterestRate").value(minInterestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal maxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxInterestRate", element); + baseDataValidator.reset().parameter("maxInterestRate").value(maxInterestRate).notNull().zeroOrPositiveAmount(); + + baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate,maxInterestRate); + baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(interestRate,maxInterestRate); + baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate,interestRate); + + final BigDecimal savingsDepositAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmount", element); + baseDataValidator.reset().parameter("savingsDepositAmount").value(savingsDepositAmount).notNull().zeroOrPositiveAmount(); + + final Integer savingProductType = fromApiJsonHelper.extractIntegerNamed("savingProductType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("savingProductType").value(savingProductType).notNull(); + + final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureType").value(tenureType).notNull(); + + final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenure").value(tenure).notNull(); + + final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("frequency").value(frequency).notNull(); + + final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestType").value(interestType).notNull(); + + final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).notNull(); + + final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal", element); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).notNull().zeroOrPositiveAmount(); + + final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element); + baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue) + .trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).notNull(); + + final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue).trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + + public void validateForUpdate(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); + + List dataValidationErrors = new ArrayList(); + DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("product"); + final JsonElement element = fromApiJsonHelper.parse(json); + + final String name = fromApiJsonHelper.extractStringNamed("name", element); + baseDataValidator.reset().parameter("name").value(name).ignoreIfNull().notBlank().notExceedingLengthOf(100); + + final String description = fromApiJsonHelper.extractStringNamed("description", element); + baseDataValidator.reset().parameter("description").value(description).notExceedingLengthOf(500); + + final String currencyCode = fromApiJsonHelper.extractStringNamed("currencyCode", element); + baseDataValidator.reset().parameter("currencyCode").value(currencyCode).ignoreIfNull().notBlank(); + + final Integer digitsAfterDecimal = fromApiJsonHelper.extractIntegerNamed("digitsAfterDecimal", element, Locale.getDefault()); + baseDataValidator.reset().parameter("digitsAfterDecimal").value(digitsAfterDecimal).ignoreIfNull().inMinMaxRange(0, 6); + + final BigDecimal interestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("interestRate", element); + baseDataValidator.reset().parameter("interestRate").value(interestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal minInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minInterestRate", element); + baseDataValidator.reset().parameter("minInterestRate").value(minInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maxInterestRate", element); + baseDataValidator.reset().parameter("maxInterestRate").value(maxInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate,maxInterestRate); + baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(interestRate,maxInterestRate); + baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(minInterestRate,interestRate); + + final BigDecimal savingsDepositAmount = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("savingsDepositAmount", element); + baseDataValidator.reset().parameter("savingsDepositAmount").value(savingsDepositAmount).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer savingProductType = fromApiJsonHelper.extractIntegerNamed("savingProductType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("savingProductType").value(savingProductType).ignoreIfNull(); + + final Integer tenureType = fromApiJsonHelper.extractIntegerNamed("tenureType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureType").value(tenureType).ignoreIfNull(); + + final Integer tenure = fromApiJsonHelper.extractIntegerNamed("tenure", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenure").value(tenure).ignoreIfNull().integerGreaterThanZero(); + + final Integer frequency = fromApiJsonHelper.extractIntegerNamed("frequency", element, Locale.getDefault()); + baseDataValidator.reset().parameter("frequency").value(frequency).ignoreIfNull(); + + final Integer interestType = fromApiJsonHelper.extractIntegerNamed("interestType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestType").value(interestType).ignoreIfNull(); + + final Integer interestCalculationMethod = fromApiJsonHelper.extractIntegerNamed("interestCalculationMethod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCalculationMethod").value(interestCalculationMethod).ignoreIfNull(); + + final BigDecimal minimumBalanceForWithdrawal = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minimumBalanceForWithdrawal", element); + baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(minimumBalanceForWithdrawal).ignoreIfNull().zeroOrPositiveAmount(); + + final Boolean isPartialDepositAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isPartialDepositAllowed", element); + baseDataValidator.reset().parameter("isPartialDepositAllowed").value(isPartialDepositAllowedCommandValue) + .trueOrFalseRequired(isBooleanValueUpdated(isPartialDepositAllowedCommandValue)).ignoreIfNull(); + + final Boolean isLockinPeriodAllowedCommandValue = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowedCommandValue) + .trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowedCommandValue)).ignoreIfNull(); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformService.java index c153b8dce..da1926677 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformService.java @@ -5,18 +5,14 @@ */ package org.mifosplatform.portfolio.savingsaccountproduct.service; +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.mifosplatform.portfolio.savingsaccountproduct.command.SavingProductCommand; -import org.springframework.security.access.prepost.PreAuthorize; public interface SavingProductWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_SAVINGSPRODUCT')") - CommandProcessingResult createSavingProduct(SavingProductCommand command); + CommandProcessingResult createSavingProduct(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_SAVINGSPRODUCT')") - CommandProcessingResult updateSavingProduct(SavingProductCommand command); + CommandProcessingResult updateSavingProduct(Long productId, JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_SAVINGSPRODUCT')") CommandProcessingResult deleteSavingProduct(Long productId); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java index 43f5d684d..87917f7ad 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccountproduct/service/SavingProductWritePlatformServiceJpaRepositoryImpl.java @@ -5,12 +5,15 @@ */ package org.mifosplatform.portfolio.savingsaccountproduct.service; +import java.util.Map; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.infrastructure.security.exception.NoAuthorizationException; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; 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; @@ -19,6 +22,7 @@ import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductTyp 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.savingsaccountproduct.serialization.SavingProductCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -29,29 +33,39 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin private final PlatformSecurityContext context; private final SavingProductRepository savingProductRepository; + private final SavingProductCommandFromApiJsonDeserializer fromApiJsonDeserializer; @Autowired public SavingProductWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, - final SavingProductRepository savingProductRepository) { + final SavingProductRepository savingProductRepository, + final SavingProductCommandFromApiJsonDeserializer fromApiJsonDeserializer) { this.context = context; this.savingProductRepository = savingProductRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; } @Transactional @Override - public CommandProcessingResult createSavingProduct(final SavingProductCommand command) { + public CommandProcessingResult createSavingProduct(final JsonCommand command) { this.context.authenticatedUser(); - SavingProductCommandValidator validator = new SavingProductCommandValidator(command); - validator.validateForCreate(); - - SavingProductType savingProductType = SavingProductType.fromInt(command.getSavingProductType()); - TenureTypeEnum tenureType = TenureTypeEnum.fromInt(command.getTenureType()); - SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency()); - SavingsInterestType interestType = SavingsInterestType.fromInt(command.getInterestType()); - PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType()); - SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod()); - MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal()); + this.fromApiJsonDeserializer.validateForCreate(command.json()); + + final Integer savingProductTypeCommandValue = command.integerValueOfParameterNamed("savingProductType"); + SavingProductType savingProductType = SavingProductType.fromInt(savingProductTypeCommandValue); + final Integer tenureTypeCommandValue = command.integerValueOfParameterNamed("tenureType"); + TenureTypeEnum tenureType = TenureTypeEnum.fromInt(tenureTypeCommandValue); + final Integer frequencyCommandValue = command.integerValueOfParameterNamed("frequency"); + SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(frequencyCommandValue); + final Integer interestTypeCommandValue = command.integerValueOfParameterNamed("interestType"); + SavingsInterestType interestType = SavingsInterestType.fromInt(interestTypeCommandValue); + final Integer lockinPeriodTypeCommandValue = command.integerValueOfParameterNamed("lockinPeriodType"); + PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(lockinPeriodTypeCommandValue); + final Integer interestCalculationMethodCommandValue = command.integerValueOfParameterNamed("interestCalculationMethod"); + SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(interestCalculationMethodCommandValue); + final String currencyCode = command.stringValueOfParameterNamed("currencyCode"); + final Integer digitsAfterDecimal = command.integerValueOfParameterNamed("digitsAfterDecimal"); + MonetaryCurrency currency = new MonetaryCurrency(currencyCode, digitsAfterDecimal); if ( savingProductType.equals(SavingProductType.INVALID) || tenureType.equals(TenureTypeEnum.INVALID) || @@ -60,14 +74,11 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin lockinPeriodType.equals(PeriodFrequencyType.INVALID)|| savingInterestCalculationMethod.equals(SavingInterestCalculationMethod.INVALID) ) { - throw new RuntimeException("Please select a valid types"); + throw new NoAuthorizationException("Please select a valid types"); } - - SavingProduct product = new SavingProduct(command.getName(), command.getDescription(), currency, command.getInterestRate(), - command.getMinInterestRate(), command.getMaxInterestRate(), command.getSavingsDepositAmount(),command.getDepositEvery(), savingProductType, - tenureType, command.getTenure(), savingFrequencyType, interestType, savingInterestCalculationMethod, - command.getMinimumBalanceForWithdrawal(), command.isPartialDepositAllowed(), command.isLockinPeriodAllowed(), - command.getLockinPeriod(), lockinPeriodType); + + SavingProduct product = SavingProduct.assembleFromJson(command, currency, savingProductType, tenureType, savingFrequencyType, + interestType, savingInterestCalculationMethod, lockinPeriodType); this.savingProductRepository.save(product); return new CommandProcessingResultBuilder() // @@ -77,18 +88,22 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin @Transactional @Override - public CommandProcessingResult updateSavingProduct(final SavingProductCommand command) { + public CommandProcessingResult updateSavingProduct(final Long productId, final JsonCommand command) { this.context.authenticatedUser(); - SavingProductCommandValidator validator = new SavingProductCommandValidator(command); - validator.validateForUpdate(); + this.fromApiJsonDeserializer.validateForUpdate(command.json()); - SavingProduct product = this.savingProductRepository.findOne(command.getId()); - if (product == null) { throw new SavingProductNotFoundException(command.getId()); } - product.update(command); + SavingProduct product = this.savingProductRepository.findOne(productId); + + if (product == null) { throw new SavingProductNotFoundException(productId); } + + Map changes = product.update(command); + this.savingProductRepository.save(product); + return new CommandProcessingResultBuilder() // .withEntityId(product.getId()) // + .with(changes) .build(); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/InvalidSavingStateTransitionException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/InvalidSavingStateTransitionException.java new file mode 100644 index 000000000..786d43055 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/exception/InvalidSavingStateTransitionException.java @@ -0,0 +1,11 @@ +package org.mifosplatform.portfolio.savingsdepositaccount.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class InvalidSavingStateTransitionException extends AbstractPlatformDomainRuleException { + + public InvalidSavingStateTransitionException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) { + super("error.msg.saving." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java index d2e677a42..ffec9fae5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositaccount/service/DepositAccountAssembler.java @@ -164,10 +164,10 @@ public class DepositAccountAssembler { return new DepositLifecycleStateMachineImpl(allowedDepositStatuses); } - public DepositAccount assembleFrom(final DepositAccount account, final JsonCommand command) { - final Map actualChanges = new LinkedHashMap(20); - final String localeAsInput = command.locale(); + public DepositAccount assembleFrom(DepositAccount account, JsonCommand command, Map actualChanges) { + + final String localeAsInput = command.locale(); Client client = account.client(); 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 index 780d3c143..23d9595ba 100644 --- 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 @@ -10,41 +10,29 @@ import java.util.Collection; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.portfolio.savingsdepositaccount.data.DepositAccountsForLookup; -import org.springframework.security.access.prepost.PreAuthorize; public interface DepositAccountWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_DEPOSITACCOUNT')") CommandProcessingResult createDepositAccount(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_DEPOSITACCOUNT')") CommandProcessingResult updateDepositAccount(Long accountId, JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_DEPOSITACCOUNT')") CommandProcessingResult deleteDepositAccount(Long entityId); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'APPROVE_DEPOSITACCOUNT')") CommandProcessingResult approveDepositApplication(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'REJECT_DEPOSITACCOUNT')") CommandProcessingResult rejectDepositApplication(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'WITHDRAW_DEPOSITACCOUNT')") CommandProcessingResult withdrawDepositApplication(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'APPROVALUNDO_DEPOSITACCOUNT')") CommandProcessingResult undoDepositApproval(JsonCommand undoCommand); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'WITHDRAWAL_DEPOSITACCOUNT')") CommandProcessingResult withdrawDepositAccountMoney(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'INTEREST_DEPOSITACCOUNT')") CommandProcessingResult withdrawDepositAccountInterestMoney(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'RENEW_DEPOSITACCOUNT')") CommandProcessingResult renewDepositAccount(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS')") CommandProcessingResult postInterestToDepositAccount(Collection accounts); } \ 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 index 78cd4d359..1172bbaab 100644 --- 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 @@ -204,7 +204,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo LocalDate eventDate = command.localDateValueOfParameterNamed("eventDate"); if (this.isBeforeToday(eventDate)) { - throw new NoAuthorizationException("User has no authority to reject deposit with a date in the past."); + throw new NoAuthorizationException("User has no authority to withdraw deposit application with a date in the past."); } account.withdrawnByApplicant(eventDate, defaultDepositLifecycleStateMachine()); @@ -333,12 +333,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo && (new LocalDate().isAfter(account.maturesOnDate()) || new LocalDate().isEqual(account.maturesOnDate()))) { if (account.isActive()) { - final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account, command); + final Map changes = new LinkedHashMap(20); + final DepositAccount renewedAccount = this.depositAccountAssembler.assembleFrom(account, command,changes); this.depositAccountRepository.save(renewedAccount); account.closeDepositAccount(defaultDepositLifecycleStateMachine()); this.depositAccountRepository.save(account); return new CommandProcessingResultBuilder() // .withEntityId(account.getId()) // + .with(changes) .build(); } @@ -357,7 +359,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo this.context.authenticatedUser(); this.fromApiJsonDeserializer.validateForUpdate(command.json()); - Map changes = new LinkedHashMap(20);; + Map changes = new LinkedHashMap(20); final DepositAccount account = this.depositAccountRepository.findOne(accountId); if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(accountId); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/serialization/DepositProductCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/serialization/DepositProductCommandFromApiJsonDeserializer.java index a5df6c96a..07cf86203 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/serialization/DepositProductCommandFromApiJsonDeserializer.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/serialization/DepositProductCommandFromApiJsonDeserializer.java @@ -71,67 +71,58 @@ public final class DepositProductCommandFromApiJsonDeserializer { baseDataValidator.reset().parameter("minimumBalance").value(minimumBalance).notNull().zeroOrPositiveAmount(); final BigDecimal maximumBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maximumBalance", element); - baseDataValidator.reset().parameter("maximumBalance").value(maximumBalance).zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("minimumBalance").comapareMinimumAndMaximumAmounts(minimumBalance, maximumBalance); + baseDataValidator.reset().parameter("maximumBalance").value(maximumBalance).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("minimumBalance").comapareMinimumAndMaximumAmounts(minimumBalance, maximumBalance); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).notNull().zeroOrPositiveAmount(); + + final BigDecimal maturityDefaultInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityDefaultInterestRate", element); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(maturityDefaultInterestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMinInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMinInterestRate", element); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(maturityMinInterestRate).notNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMaxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMaxInterestRate", element); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(maturityMaxInterestRate).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityDefaultInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityDefaultInterestRate); + + final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).notNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).notNull().inMinMaxRange(1, 3); + + final Boolean renewalAllowed = fromApiJsonHelper.extractBooleanNamed("renewalAllowed", element); + baseDataValidator.reset().parameter("renewalAllowed").value(renewalAllowed).trueOrFalseRequired(isBooleanValueUpdated(renewalAllowed)); + + final Boolean preClosureAllowed = fromApiJsonHelper.extractBooleanNamed("preClosureAllowed", element); + baseDataValidator.reset().parameter("preClosureAllowed").value(preClosureAllowed).trueOrFalseRequired(isBooleanValueUpdated(preClosureAllowed)); + + final Boolean interestCompoundingAllowed = fromApiJsonHelper.extractBooleanNamed("interestCompoundingAllowed", element); + baseDataValidator.reset().parameter("interestCompoundingAllowed").value(interestCompoundingAllowed).trueOrFalseRequired(isBooleanValueUpdated(interestCompoundingAllowed)); - final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); - baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).notNull().zeroOrPositiveAmount(); - - final BigDecimal maturityDefaultInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityDefaultInterestRate", - element); - baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(maturityDefaultInterestRate).notNull() - .zeroOrPositiveAmount(); - - final BigDecimal maturityMinInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMinInterestRate", element); - baseDataValidator.reset().parameter("maturityMinInterestRate").value(maturityMinInterestRate).notNull().zeroOrPositiveAmount(); - - final BigDecimal maturityMaxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMaxInterestRate", element); - baseDataValidator.reset().parameter("maturityMaxInterestRate").value(maturityMaxInterestRate).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("maturityMinInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityMaxInterestRate); - baseDataValidator.reset().parameter("maturityDefaultInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(maturityDefaultInterestRate, maturityMaxInterestRate); - baseDataValidator.reset().parameter("maturityMinInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityDefaultInterestRate); - - final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, - Locale.getDefault()); - baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).notNull().zeroOrPositiveAmount(); - - final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", - element, Locale.getDefault()); - baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).notNull() - .inMinMaxRange(1, 3); - - final Boolean renewalAllowed = fromApiJsonHelper.extractBooleanNamed("renewalAllowed", element); - baseDataValidator.reset().parameter("renewalAllowed").trueOrFalseRequired(renewalAllowed); - - final Boolean preClosureAllowed = fromApiJsonHelper.extractBooleanNamed("preClosureAllowed", element); - baseDataValidator.reset().parameter("preClosureAllowed").trueOrFalseRequired(preClosureAllowed); - - final Boolean interestCompoundingAllowed = fromApiJsonHelper.extractBooleanNamed("interestCompoundingAllowed", element); - baseDataValidator.reset().parameter("interestCompoundingAllowed").trueOrFalseRequired(interestCompoundingAllowed); - - final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); - baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).notNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("preClosureInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(preClosureInterestRate, maturityMinInterestRate); - - final Boolean isLockinPeriodAllowed = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); - baseDataValidator.reset().parameter("isLockinPeriodAllowed").trueOrFalseRequired(isLockinPeriodAllowed); - - final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); - baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount(); - - final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); - baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3); - - throwExceptionIfValidationWarningsExist(dataValidationErrors); - } - - public void validateForUpdate(final String json) { - - if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).notNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("preClosureInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(preClosureInterestRate,maturityMinInterestRate); + + final Boolean isLockinPeriodAllowed = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(isLockinPeriodAllowed).trueOrFalseRequired(isBooleanValueUpdated(isLockinPeriodAllowed)); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).notNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).notNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + public void validateForUpdate(String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } final Type typeOfMap = new TypeToken>() {}.getType(); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams); @@ -159,80 +150,67 @@ public final class DepositProductCommandFromApiJsonDeserializer { baseDataValidator.reset().parameter("minimumBalance").value(minimumBalance).ignoreIfNull().zeroOrPositiveAmount(); final BigDecimal maximumBalance = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maximumBalance", element); - baseDataValidator.reset().parameter("maximumBalance").value(maximumBalance).zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("minimumBalance").comapareMinimumAndMaximumAmounts(minimumBalance, maximumBalance); + baseDataValidator.reset().parameter("maximumBalance").value(maximumBalance).zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("minimumBalance").comapareMinimumAndMaximumAmounts(minimumBalance, maximumBalance); + + final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); + baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityDefaultInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityDefaultInterestRate", element); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(maturityDefaultInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMinInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMinInterestRate", element); + baseDataValidator.reset().parameter("maturityMinInterestRate").value(maturityMinInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + + final BigDecimal maturityMaxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMaxInterestRate", element); + baseDataValidator.reset().parameter("maturityMaxInterestRate").value(maturityMaxInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityDefaultInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityDefaultInterestRate, maturityMaxInterestRate); + baseDataValidator.reset().parameter("maturityMinInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityDefaultInterestRate); + + final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + final Boolean renewalAllowed = fromApiJsonHelper.extractBooleanNamed("renewalAllowed", element); + baseDataValidator.reset().parameter("renewalAllowed").value(renewalAllowed).trueOrFalseRequired(isBooleanValueUpdated(renewalAllowed)); + + final Boolean preClosureAllowed = fromApiJsonHelper.extractBooleanNamed("preClosureAllowed", element); + baseDataValidator.reset().parameter("preClosureAllowed").value(preClosureAllowed).trueOrFalseRequired(isBooleanValueUpdated(preClosureAllowed)); + + final Boolean interestCompoundingAllowed = fromApiJsonHelper.extractBooleanNamed("interestCompoundingAllowed", element); + baseDataValidator.reset().parameter("interestCompoundingAllowed").value(interestCompoundingAllowed).trueOrFalseRequired(isBooleanValueUpdated(interestCompoundingAllowed)); - final Integer tenureInMonths = fromApiJsonHelper.extractIntegerNamed("tenureInMonths", element, Locale.getDefault()); - baseDataValidator.reset().parameter("tenureInMonths").value(tenureInMonths).ignoreIfNull().zeroOrPositiveAmount(); + final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); + baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).ignoreIfNull().zeroOrPositiveAmount(); + baseDataValidator.reset().parameter("preClosureInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(preClosureInterestRate,maturityMinInterestRate); + + final Boolean lockinPeriodAllowed = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); + baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(lockinPeriodAllowed).trueOrFalseRequired(isBooleanValueUpdated(lockinPeriodAllowed)); + + final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount(); + + final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); + baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3); + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + + } + + private Boolean isBooleanValueUpdated(Boolean actualValue) { + Boolean isUpdated = false; + if(actualValue != null){ + isUpdated = true; + } + return isUpdated; + } - final BigDecimal maturityDefaultInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityDefaultInterestRate", - element); - baseDataValidator.reset().parameter("maturityDefaultInterestRate").value(maturityDefaultInterestRate).ignoreIfNull() - .zeroOrPositiveAmount(); - - final BigDecimal maturityMinInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMinInterestRate", element); - baseDataValidator.reset().parameter("maturityMinInterestRate").value(maturityMinInterestRate).ignoreIfNull().zeroOrPositiveAmount(); - - final BigDecimal maturityMaxInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("maturityMaxInterestRate", element); - baseDataValidator.reset().parameter("maturityMaxInterestRate").value(maturityMaxInterestRate).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("maturityMinInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityMaxInterestRate); - baseDataValidator.reset().parameter("maturityDefaultInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(maturityDefaultInterestRate, maturityMaxInterestRate); - baseDataValidator.reset().parameter("maturityMinInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(maturityMinInterestRate, maturityDefaultInterestRate); - - final Integer interestCompoundedEvery = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEvery", element, - Locale.getDefault()); - baseDataValidator.reset().parameter("interestCompoundedEvery").value(interestCompoundedEvery).ignoreIfNull().zeroOrPositiveAmount(); - - final Integer interestCompoundedEveryPeriodType = fromApiJsonHelper.extractIntegerNamed("interestCompoundedEveryPeriodType", - element, Locale.getDefault()); - baseDataValidator.reset().parameter("interestCompoundedEveryPeriodType").value(interestCompoundedEveryPeriodType).ignoreIfNull() - .inMinMaxRange(1, 3); - - final Boolean renewalAllowed = fromApiJsonHelper.extractBooleanNamed("renewalAllowed", element); - final Boolean isrenewalAllowedChanged = isBooleanValueUpdated(renewalAllowed); - baseDataValidator.reset().parameter("renewalAllowed").trueOrFalseRequired(isrenewalAllowedChanged); - - final Boolean preClosureAllowed = fromApiJsonHelper.extractBooleanNamed("preClosureAllowed", element); - final Boolean isPreClosureAllowedChanged = isBooleanValueUpdated(preClosureAllowed); - baseDataValidator.reset().parameter("preClosureAllowed").trueOrFalseRequired(isPreClosureAllowedChanged); - - final Boolean interestCompoundingAllowed = fromApiJsonHelper.extractBooleanNamed("interestCompoundingAllowed", element); - final Boolean isInterestCompoundingAllowed = isBooleanValueUpdated(interestCompoundingAllowed); - baseDataValidator.reset().parameter("interestCompoundingAllowed").trueOrFalseRequired(isInterestCompoundingAllowed); - - final BigDecimal preClosureInterestRate = fromApiJsonHelper.extractBigDecimalWithLocaleNamed("preClosureInterestRate", element); - baseDataValidator.reset().parameter("preClosureInterestRate").value(preClosureInterestRate).ignoreIfNull().zeroOrPositiveAmount(); - baseDataValidator.reset().parameter("preClosureInterestRate") - .comapareMinAndMaxOfTwoBigDecmimalNos(preClosureInterestRate, maturityMinInterestRate); - - final Boolean lockinPeriodAllowed = fromApiJsonHelper.extractBooleanNamed("isLockinPeriodAllowed", element); - final Boolean isLockinPeriodAllowed = isBooleanValueUpdated(lockinPeriodAllowed); - baseDataValidator.reset().parameter("isLockinPeriodAllowed").trueOrFalseRequired(isLockinPeriodAllowed); - - final Integer lockinPeriod = fromApiJsonHelper.extractIntegerNamed("lockinPeriod", element, Locale.getDefault()); - baseDataValidator.reset().parameter("lockinPeriod").value(lockinPeriod).ignoreIfNull().zeroOrPositiveAmount(); - - final Integer lockinPeriodType = fromApiJsonHelper.extractIntegerNamed("lockinPeriodType", element, Locale.getDefault()); - baseDataValidator.reset().parameter("lockinPeriodType").value(lockinPeriodType).ignoreIfNull().inMinMaxRange(1, 3); - - throwExceptionIfValidationWarningsExist(dataValidationErrors); - - } - - private Boolean isBooleanValueUpdated(final Boolean actualValue) { - Boolean isUpdated = false; - if (actualValue != null) { - isUpdated = true; - } - return isUpdated; - } - - private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { - if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); } - } + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + 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/savingsdepositproduct/service/DepositProductWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsdepositproduct/service/DepositProductWritePlatformService.java index 8ba7255eb..f42fd6081 100644 --- 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 @@ -7,16 +7,12 @@ package org.mifosplatform.portfolio.savingsdepositproduct.service; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; -import org.springframework.security.access.prepost.PreAuthorize; public interface DepositProductWritePlatformService { - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_DEPOSITPRODUCT')") CommandProcessingResult createDepositProduct(JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_DEPOSITPRODUCT')") CommandProcessingResult updateDepositProduct(Long productId, JsonCommand command); - @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_DEPOSITPRODUCT')") CommandProcessingResult deleteDepositProduct(Long productId); } \ No newline at end of file