Saving product Audit conversion

Saving Account Audit Conversion
This commit is contained in:
Madhukar
2013-02-22 19:44:30 +05:30
parent 5e69f4a558
commit 29360a8fd6
40 changed files with 2217 additions and 745 deletions
@@ -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 );
@@ -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");
}
}
@@ -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;
}
}
@@ -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());
}
@@ -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<String> SAVINGS_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>(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<SavingAccountData> toApiJsonSerializer;
private static final Set<String> typicalResponseParameters = new HashSet<String>(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<SavingScheduleData> 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<SavingAccountData> toApiJsonSerializer) {
final ToApiJsonSerializer<SavingAccountData> toApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService,
final FromJsonHelper fromJsonHelper,
final DefaultToApiJsonSerializer<SavingScheduleData> 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<String>());
}
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<String> 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<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
Collection<SavingAccountData> 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<SavingAccountTransactionsData> transactions = null;
Set<String> 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<String> 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<String> 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<String> responseParameters, SavingAccountData account) {
responseParameters.addAll(Arrays.asList("productOptions", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions",
"savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions",
"dueAmount"));
private SavingAccountData handleTemplateRelatedData(SavingAccountData account) {
Collection<SavingProductLookup> productOptions = savingProductReadPlatformService.retrieveAllSavingProductsForLookup();
Collection<CurrencyData> 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
@@ -49,4 +49,5 @@ public class SavingSchedulePeriodData {
public BigDecimal getInterestAccured() {
return this.interestAccured;
}
}
@@ -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<AppUser, Long> {
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<AppUser, Long> {
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<AppUser, Long> {
} else {
for (SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments) {
savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid()));
savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate());
savingScheduleInstallment.setPaymentDate(depositDateCommandValue.toDate());
}
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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());
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -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<String> supportedParams = new HashSet<String>(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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -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<String> supportedParams = new HashSet<String>(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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -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<String> supportedParams = new HashSet<String>(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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -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);
}
@@ -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<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
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());
}
}
@@ -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<String, Object> assembleFrom(JsonCommand command, SavingAccount account) {
JsonElement element = command.parsedJson();
Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(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<String, Object> approveSavingAccount(JsonCommand command, SavingAccount account) {
LocalDate approvalDate = account.projectedCommencementDate();
if (command.getApprovalDate() != null) {
approvalDate = command.getApprovalDate();
}
JsonElement element = command.parsedJson();
Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(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;
}
}
@@ -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<SavingAccountForLookup> savingAccounts);
}
@@ -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<String, Object> changes = new LinkedHashMap<String, Object>(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<String, Object> 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());
}
}
@@ -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<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
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<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
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;
}
}
@@ -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<String> SAVINGS_PRODUCT_DATA_PARAMETERS = new HashSet<String>(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<SavingProductData> 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<SavingProductData> toApiJsonSerializer) {
final DefaultToApiJsonSerializer<SavingProductData> 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<String> typicalResponseParameters = new HashSet<String>(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<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters);
}
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
context.authenticatedUser().validateHasReadPermission(entityType);
Collection<SavingProductData> 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<String> typicalResponseParameters = new HashSet<String>(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<String> 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<String> typicalResponseParameters = new HashSet<String>(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<String> 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<String> responseParameters, SavingProductData savingProduct) {
private SavingProductData handleTemplateRelatedData(SavingProductData savingProduct) {
responseParameters.addAll(Arrays.asList("currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions",
"savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions"));
Collection<CurrencyData> 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);
}
}
@@ -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<AppUser, Long> {
return savingProductRelatedDetail;
}
public void update(final SavingProductCommand command) {
public Map<String, Object> update(final JsonCommand command) {
if (command.isNameChanged()) {
this.name = command.getName();
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(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);
}
}
@@ -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<String, Object> update(final JsonCommand command, final Map<String, Object> 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() {
@@ -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);
}
}
@@ -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());
}
}
@@ -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);
}
}
@@ -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<String> supportedParams = new HashSet<String>(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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParams);
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<ApiParameterError> 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;
}
}
@@ -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);
}
@@ -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<String, Object> changes = product.update(command);
this.savingProductRepository.save(product);
return new CommandProcessingResultBuilder() //
.withEntityId(product.getId()) //
.with(changes)
.build();
}
@@ -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);
}
}
@@ -164,10 +164,10 @@ public class DepositAccountAssembler {
return new DepositLifecycleStateMachineImpl(allowedDepositStatuses);
}
public DepositAccount assembleFrom(final DepositAccount account, final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(20);
final String localeAsInput = command.locale();
public DepositAccount assembleFrom(DepositAccount account, JsonCommand command, Map<String, Object> actualChanges) {
final String localeAsInput = command.locale();
Client client = account.client();
@@ -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<DepositAccountsForLookup> accounts);
}
@@ -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<String, Object> changes = new LinkedHashMap<String, Object>(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<String, Object> changes = new LinkedHashMap<String, Object>(20);;
Map<String, Object> changes = new LinkedHashMap<String, Object>(20);
final DepositAccount account = this.depositAccountRepository.findOne(accountId);
if (account == null || account.isDeleted()) { throw new DepositAccountNotFoundException(accountId); }
@@ -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<Map<String, Object>>() {}.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<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -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);
}