diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java index c10a9dd39..0d5f4a216 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/api/SavingsAccountApiResource.java @@ -28,7 +28,6 @@ import org.mifosplatform.infrastructure.core.api.PortfolioApiJsonSerializerServi 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.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.monetary.data.CurrencyData; @@ -77,10 +76,10 @@ public class SavingsAccountApiResource { @Autowired private PortfolioApiJsonSerializerService apiJsonSerializerService; - - @Autowired + + @Autowired private SavingProductReadPlatformService savingProductReadPlatformService; - + @Autowired private CurrencyReadPlatformService currencyReadPlatformService; @@ -94,9 +93,6 @@ public class SavingsAccountApiResource { @Autowired private ToApiJsonSerializer toApiJsonSerializer; - - @Autowired - private FromJsonHelper fromJsonHelper; private static final Set typicalResponseParameters = new HashSet(Arrays.asList("id", "status", "externalId", "clientId", "clientName", "productId", "productName", "productType", "currencyData", "savingsDepostiAmountPerPeriod", @@ -104,7 +100,8 @@ public class SavingsAccountApiResource { "interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "actualCommencementDate", "maturesOnDate", "projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount", "preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed", - "lockinPeriod", "lockinPeriodType","outstandingAmount","savingScheduleData","transactions","interestPostEvery","interestPostFrequency")); + "lockinPeriod", "lockinPeriodType", "outstandingAmount", "savingScheduleData", "transactions", "interestPostEvery", + "interestPostFrequency")); @POST @Consumes({ MediaType.APPLICATION_JSON }) @@ -171,7 +168,7 @@ public class SavingsAccountApiResource { public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) { context.authenticatedUser().validateHasReadPermission(entityType); - + SavingPermissionData permissions = null; SavingScheduleData savingScheduleData = null; Collection transactions = null; @@ -180,141 +177,146 @@ public class SavingsAccountApiResource { if (responseParameters.isEmpty()) { responseParameters.addAll(typicalResponseParameters); } - - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - SavingAccountData account = this.savingAccountReadPlatformService.retrieveSavingsAccount(accountId); - - boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - if (template) { - account = handleTemplateRelatedData(responseParameters, account); - } - - Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); + + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + SavingAccountData account = this.savingAccountReadPlatformService.retrieveSavingsAccount(accountId); + + boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); + if (template) { + account = handleTemplateRelatedData(responseParameters, account); + } + + Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); if (!associationParameters.isEmpty()) { if (associationParameters.contains("all")) { - associationParameters.addAll(Arrays.asList("savingScheduleData","transactions")); - responseParameters.addAll(Arrays.asList("permissions","savingScheduleData","transactions")); + 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(); - savingScheduleData = this.savingAccountReadPlatformService.retrieveSavingsAccountSchedule(accountId,currencyData); - account = new SavingAccountData(account,savingScheduleData); - } + CurrencyData currencyData = account.getCurrencyData(); + savingScheduleData = this.savingAccountReadPlatformService.retrieveSavingsAccountSchedule(accountId, currencyData); + account = new SavingAccountData(account, savingScheduleData); + } if (associationParameters.contains("transactions")) { - transactions = this.savingAccountReadPlatformService.retrieveSavingsAccountTransactions(accountId); - account = new SavingAccountData(account,transactions); - } + transactions = this.savingAccountReadPlatformService.retrieveSavingsAccountTransactions(accountId); + account = new SavingAccountData(account, transactions); + } permissions = this.savingAccountReadPlatformService.retrieveSavingAccountPermissions(account); account = new SavingAccountData(account, permissions); } - - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); - } - @GET - @Path("template") - @Consumes({MediaType.APPLICATION_JSON}) - @Produces({MediaType.APPLICATION_JSON}) - public String retrieveNewDepositAccountDetails( - @QueryParam("clientId") final Long clientId, - @QueryParam("productId") final Long productId, - @Context final UriInfo uriInfo) { + return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); + } + + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveNewDepositAccountDetails(@QueryParam("clientId") final Long clientId, + @QueryParam("productId") final Long productId, @Context final UriInfo uriInfo) { + + context.authenticatedUser().validateHasReadPermission(entityType); + + Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); + if (responseParameters.isEmpty()) { + responseParameters.addAll(typicalResponseParameters); + } + boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); + + SavingAccountData account = this.savingAccountReadPlatformService.retrieveNewSavingsAccountDetails(clientId, productId); + account = handleTemplateRelatedData(responseParameters, account); + + return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); + } - context.authenticatedUser().validateHasReadPermission(entityType); - - Set responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); - if (responseParameters.isEmpty()) { - responseParameters.addAll(typicalResponseParameters); - } - boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); - - SavingAccountData account = this.savingAccountReadPlatformService.retrieveNewSavingsAccountDetails(clientId, productId); - account = handleTemplateRelatedData(responseParameters,account); - - return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account); - } - private SavingAccountData handleTemplateRelatedData(Set responseParameters, SavingAccountData account) { - responseParameters.addAll(Arrays.asList("productOptions", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", - "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions", "dueAmount")); - - Collection productOptions = savingProductReadPlatformService.retrieveAllSavingProductsForLookup(); - List currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies(); + responseParameters.addAll(Arrays.asList("productOptions", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", + "savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions", + "dueAmount")); - EnumOptionData recurring = SavingProductEnumerations.savingProductType(SavingProductType.RECURRING); - EnumOptionData regular = SavingProductEnumerations.savingProductType(SavingProductType.REGULAR); - List savingsProductTypeOptions = Arrays.asList(recurring, regular); + Collection productOptions = savingProductReadPlatformService.retrieveAllSavingProductsForLookup(); + List currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies(); - EnumOptionData fixed = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD); - EnumOptionData perpetual = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.PERPETUAL); - List tenureTypeOptions = Arrays.asList(fixed, perpetual); + EnumOptionData recurring = SavingProductEnumerations.savingProductType(SavingProductType.RECURRING); + EnumOptionData regular = SavingProductEnumerations.savingProductType(SavingProductType.REGULAR); + List savingsProductTypeOptions = Arrays.asList(recurring, regular); - EnumOptionData monthly = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY); - List savingFrequencyOptions = Arrays.asList(monthly); + EnumOptionData fixed = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD); + EnumOptionData perpetual = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.PERPETUAL); + List tenureTypeOptions = Arrays.asList(fixed, perpetual); - EnumOptionData simple = SavingProductEnumerations.savingInterestType(SavingsInterestType.SIMPLE); - EnumOptionData compounding = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING); - List savingsInterestTypeOptions = Arrays.asList(simple, compounding); + EnumOptionData monthly = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY); + List savingFrequencyOptions = Arrays.asList(monthly); - EnumOptionData months = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS); - List lockinPeriodTypeOptions = Arrays.asList(months); + EnumOptionData simple = SavingProductEnumerations.savingInterestType(SavingsInterestType.SIMPLE); + EnumOptionData compounding = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING); + List savingsInterestTypeOptions = Arrays.asList(simple, compounding); - EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL); - // EnumOptionData minbal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL); - EnumOptionData monthlyCollection = SavingProductEnumerations - .savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION); - List interestCalculationOptions = Arrays.asList(averagebal, monthlyCollection); - BigDecimal dueAmount = this.savingAccountReadPlatformService.deriveSavingDueAmount(account); - return new SavingAccountData(account, productOptions, currencyOptions, savingsProductTypeOptions,tenureTypeOptions,savingFrequencyOptions, - savingsInterestTypeOptions,lockinPeriodTypeOptions,interestCalculationOptions, dueAmount); - } + EnumOptionData months = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS); + List lockinPeriodTypeOptions = Arrays.asList(months); - private boolean is(final String commandParam, final String commandValue) { + EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL); + // EnumOptionData minbal = + // SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL); + EnumOptionData monthlyCollection = SavingProductEnumerations + .savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION); + List interestCalculationOptions = Arrays.asList(averagebal, monthlyCollection); + BigDecimal dueAmount = this.savingAccountReadPlatformService.deriveSavingDueAmount(account); + return new SavingAccountData(account, productOptions, currencyOptions, savingsProductTypeOptions, tenureTypeOptions, + savingFrequencyOptions, savingsInterestTypeOptions, lockinPeriodTypeOptions, interestCalculationOptions, dueAmount); + } + + private boolean is(final String commandParam, final String commandValue) { return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); } - - @POST - @Path("{accountId}") - @Consumes({ MediaType.APPLICATION_JSON }) + + @POST + @Path("{accountId}") + @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public Response savingStateTransitions(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam, final String jsonRequestBody) { - Response response = null; - if (is(commandParam, "approve")) { - SavingAccountApprovalCommand command = this.apiDataConversionService.convertJsonToSavingApprovalCommand(accountId, jsonRequestBody); - CommandProcessingResult identifier = this.savingAccountWritePlatformService.approveSavingAccount(command); - response = Response.ok().entity(identifier).build(); - } else if (is(commandParam, "depositmoney")) { - SavingAccountDepositCommand command = this.apiDataConversionService.convertJsonToSavingAccountDepositCommand(accountId, jsonRequestBody); - CommandProcessingResult identifier = this.savingAccountWritePlatformService.depositMoney(command); - response = Response.ok().entity(identifier).build(); - } else if (is(commandParam, "withdraw")) { - SavingAccountWithdrawalCommand command = this.apiDataConversionService.convertJsonToSavingAccountWithdrawalCommand(accountId, jsonRequestBody); - CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingAmount(command); - response = Response.ok().entity(identifier).build(); - } else { - SavingStateTransitionsCommand command = this.apiDataConversionService.convertJsonToSavingStateTransitionCommand(accountId, jsonRequestBody); - if (is(commandParam, "reject")) { - CommandProcessingResult identifier = this.savingAccountWritePlatformService.rejectSavingApplication(command); - response = Response.ok().entity(identifier).build(); - } else if (is(commandParam, "withdrewbyclient")) { - CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingApplication(command); - response = Response.ok().entity(identifier).build(); - } - UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); - if (is(commandParam, "undoapproval")) { - CommandProcessingResult identifier = this.savingAccountWritePlatformService.undoSavingAccountApproval(undoCommand); - response = Response.ok().entity(identifier).build(); - } - } - if (response == null) { throw new UnrecognizedQueryParamException("command", commandParam); } - return response; - } - - @DELETE + public Response savingStateTransitions(@PathParam("accountId") final Long accountId, @QueryParam("command") final String commandParam, + final String jsonRequestBody) { + Response response = null; + if (is(commandParam, "approve")) { + SavingAccountApprovalCommand command = this.apiDataConversionService.convertJsonToSavingApprovalCommand(accountId, + jsonRequestBody); + CommandProcessingResult identifier = this.savingAccountWritePlatformService.approveSavingAccount(command); + response = Response.ok().entity(identifier).build(); + } else if (is(commandParam, "depositmoney")) { + SavingAccountDepositCommand command = this.apiDataConversionService.convertJsonToSavingAccountDepositCommand(accountId, + jsonRequestBody); + CommandProcessingResult identifier = this.savingAccountWritePlatformService.depositMoney(command); + response = Response.ok().entity(identifier).build(); + } else if (is(commandParam, "withdraw")) { + SavingAccountWithdrawalCommand command = this.apiDataConversionService.convertJsonToSavingAccountWithdrawalCommand(accountId, + jsonRequestBody); + CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingAmount(command); + response = Response.ok().entity(identifier).build(); + } else { + SavingStateTransitionsCommand command = this.apiDataConversionService.convertJsonToSavingStateTransitionCommand(accountId, + jsonRequestBody); + if (is(commandParam, "reject")) { + CommandProcessingResult identifier = this.savingAccountWritePlatformService.rejectSavingApplication(command); + response = Response.ok().entity(identifier).build(); + } else if (is(commandParam, "withdrewbyclient")) { + CommandProcessingResult identifier = this.savingAccountWritePlatformService.withdrawSavingApplication(command); + response = Response.ok().entity(identifier).build(); + } + UndoStateTransitionCommand undoCommand = new UndoStateTransitionCommand(accountId, command.getNote()); + if (is(commandParam, "undoapproval")) { + CommandProcessingResult identifier = this.savingAccountWritePlatformService.undoSavingAccountApproval(undoCommand); + response = Response.ok().entity(identifier).build(); + } + } + if (response == null) { throw new UnrecognizedQueryParamException("command", commandParam); } + return response; + } + + @DELETE @Path("{accountId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) @@ -324,17 +326,16 @@ public class SavingsAccountApiResource { return Response.ok(new CommandProcessingResult(accountId)).build(); } - - @POST + + @POST @Path("postinterest") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) public Response postInterest() { - - Collection savingAccounts = this.savingAccountReadPlatformService.retrieveSavingAccountsForLookUp(); - CommandProcessingResult entityIdentifier = this.savingAccountWritePlatformService.postInterest(savingAccounts); - return Response.ok().entity(entityIdentifier).build(); + + Collection savingAccounts = this.savingAccountReadPlatformService.retrieveSavingAccountsForLookUp(); + CommandProcessingResult entityIdentifier = this.savingAccountWritePlatformService.postInterest(savingAccounts); + return Response.ok().entity(entityIdentifier).build(); } - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingAccountData.java index fc8e40e3a..d29b3c18e 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/data/SavingAccountData.java @@ -11,7 +11,7 @@ import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductLookup; /** - * Immutable data object reprsenting a savings account. + * Immutable data object representing a savings account. */ public class SavingAccountData { @@ -50,33 +50,25 @@ public class SavingAccountData { private final EnumOptionData lockinPeriodType; private final Integer depositEvery; - @SuppressWarnings("unused") private final List productOptions; - @SuppressWarnings("unused") private final List currencyOptions; - @SuppressWarnings("unused") private final List savingsProductTypeOptions; - @SuppressWarnings("unused") private final List tenureTypeOptions; - @SuppressWarnings("unused") private final List savingFrequencyOptions; - @SuppressWarnings("unused") private final List savingsInterestTypeOptions; - @SuppressWarnings("unused") private final List lockinPeriodTypeOptions; - @SuppressWarnings("unused") private final List interestCalculationOptions; - + private final Collection savingScheduleDatas; private final SavingPermissionData permissions; - private final BigDecimal outstandingAmount; - private final BigDecimal dueAmount; - private final SavingScheduleData savingScheduleData; - private final Collection transactions; - - private final Integer interestPostEvery; - private final EnumOptionData interestPostFrequency; - + private final BigDecimal outstandingAmount; + private final BigDecimal dueAmount; + private final SavingScheduleData savingScheduleData; + private final Collection transactions; + + private final Integer interestPostEvery; + private final EnumOptionData interestPostFrequency; + public static SavingAccountData createFrom(final Long clientId, final String clientDisplayName) { return new SavingAccountData(clientId, clientDisplayName); } @@ -89,7 +81,8 @@ public class SavingAccountData { BigDecimal projectedInterestAccuredOnMaturity, BigDecimal actualInterestAccured, BigDecimal projectedMaturityAmount, BigDecimal actualMaturityAmount, boolean preClosureAllowed, BigDecimal preClosureInterestRate, LocalDate withdrawnonDate, LocalDate rejectedonDate, LocalDate closedonDate, boolean isLockinPeriodAllowed, Integer lockinPeriod, - EnumOptionData lockinPeriodType, Integer depositEvery, BigDecimal outstandingAmount, Integer interestPostEvery, EnumOptionData interestPostFrequency) { + EnumOptionData lockinPeriodType, Integer depositEvery, BigDecimal outstandingAmount, Integer interestPostEvery, + EnumOptionData interestPostFrequency) { this.id = id; this.status = status; this.externalId = externalId; @@ -188,17 +181,17 @@ public class SavingAccountData { this.savingScheduleDatas = null; this.permissions = null; this.outstandingAmount = BigDecimal.ZERO; - this.dueAmount =BigDecimal.ZERO; + this.dueAmount = BigDecimal.ZERO; this.savingScheduleData = null; this.transactions = null; - this.interestPostEvery =null; + this.interestPostEvery = null; this.interestPostFrequency = null; } public SavingAccountData(SavingAccountData account, Collection productOptions, List currencyOptions, List savingsProductTypeOptions, List tenureTypeOptions, List savingFrequencyOptions, List savingsInterestTypeOptions, - List lockinPeriodTypeOptions, List interestCalculationOptions,BigDecimal dueAmount) { + List lockinPeriodTypeOptions, List interestCalculationOptions, BigDecimal dueAmount) { this.id = account.id; this.status = account.status; this.externalId = account.externalId; @@ -243,7 +236,7 @@ public class SavingAccountData { this.lockinPeriodTypeOptions = lockinPeriodTypeOptions; this.interestCalculationOptions = interestCalculationOptions; this.dueAmount = dueAmount; - + this.savingScheduleDatas = account.savingScheduleDatas; this.permissions = account.permissions; this.outstandingAmount = account.outstandingAmount; @@ -259,7 +252,6 @@ public class SavingAccountData { Integer tenure, EnumOptionData savingsFrequencyType, EnumOptionData interestType, EnumOptionData interestCalculationMethod, BigDecimal minimumBalanceForWithdrawal, boolean partialDepositAllowed, boolean lockinPeriodAllowed, Integer lockinPeriod, EnumOptionData lockinPeriodType, Integer depositEvery) { - this.id = null; this.status = null; this.externalId = null; @@ -308,12 +300,12 @@ public class SavingAccountData { this.dueAmount = BigDecimal.ZERO; this.savingScheduleData = null; this.transactions = null; - this.interestPostEvery =3; + this.interestPostEvery = 3; this.interestPostFrequency = savingsFrequencyType; } - public SavingAccountData(SavingAccountData account, SavingPermissionData permissions) { - this.id = account.id; + public SavingAccountData(SavingAccountData account, SavingPermissionData permissions) { + this.id = account.id; this.status = account.status; this.externalId = account.externalId; this.clientId = account.clientId; @@ -347,7 +339,7 @@ public class SavingAccountData { this.lockinPeriod = account.lockinPeriod; this.lockinPeriodType = account.lockinPeriodType; this.depositEvery = account.depositEvery; - + this.productOptions = account.productOptions; this.currencyOptions = account.currencyOptions; this.savingsProductTypeOptions = account.savingsProductTypeOptions; @@ -364,10 +356,10 @@ public class SavingAccountData { this.transactions = account.transactions; this.interestPostEvery = account.interestPostEvery; this.interestPostFrequency = account.interestPostFrequency; - } + } - public SavingAccountData(SavingAccountData account, SavingScheduleData savingScheduleData) { - this.id = account.id; + public SavingAccountData(SavingAccountData account, SavingScheduleData savingScheduleData) { + this.id = account.id; this.status = account.status; this.externalId = account.externalId; this.clientId = account.clientId; @@ -401,7 +393,7 @@ public class SavingAccountData { this.lockinPeriod = account.lockinPeriod; this.lockinPeriodType = account.lockinPeriodType; this.depositEvery = account.depositEvery; - + this.productOptions = account.productOptions; this.currencyOptions = account.currencyOptions; this.savingsProductTypeOptions = account.savingsProductTypeOptions; @@ -418,10 +410,10 @@ public class SavingAccountData { this.transactions = account.transactions; this.interestPostEvery = account.interestPostEvery; this.interestPostFrequency = account.interestPostFrequency; - } + } - public SavingAccountData(SavingAccountData account, Collection transactions) { - this.id = account.id; + public SavingAccountData(SavingAccountData account, Collection transactions) { + this.id = account.id; this.status = account.status; this.externalId = account.externalId; this.clientId = account.clientId; @@ -455,7 +447,7 @@ public class SavingAccountData { this.lockinPeriod = account.lockinPeriod; this.lockinPeriodType = account.lockinPeriodType; this.depositEvery = account.depositEvery; - + this.productOptions = account.productOptions; this.currencyOptions = account.currencyOptions; this.savingsProductTypeOptions = account.savingsProductTypeOptions; @@ -472,186 +464,41 @@ public class SavingAccountData { this.transactions = transactions; this.interestPostEvery = account.interestPostEvery; this.interestPostFrequency = account.interestPostFrequency; - } + } - public Long getId() { - return this.id; - } + public EnumOptionData getStatus() { + return this.status; + } - public EnumOptionData getStatus() { - return this.status; - } + public CurrencyData getCurrencyData() { + return this.currencyData; + } - public String getExternalId() { - return this.externalId; - } + public BigDecimal getSavingsDepostiAmountPerPeriod() { + return this.savingsDepositAmountPerPeriod; + } - public Long getClientId() { - return this.clientId; - } + public Integer getTenure() { + return this.tenure; + } - public String getClientName() { - return this.clientName; - } + public EnumOptionData getTenureType() { + return this.tenureType; + } - public Long getProductId() { - return this.productId; - } + public LocalDate getActualCommencementDate() { + return this.actualCommencementDate; + } - public String getProductName() { - return this.productName; - } + public LocalDate getMaturesOnDate() { + return this.maturesOnDate; + } - public EnumOptionData getProductType() { - return this.productType; - } + public Integer getDepositEvery() { + return this.depositEvery; + } - public CurrencyData getCurrencyData() { - return this.currencyData; - } - - public BigDecimal getSavingsDepostiAmountPerPeriod() { - return this.savingsDepositAmountPerPeriod; - } - - public EnumOptionData getSavingsFrequencyType() { - return this.savingsFrequencyType; - } - - public BigDecimal getTotalDepositAmount() { - return this.totalDepositAmount; - } - - public BigDecimal getReccuringInterestRate() { - return this.recurringInterestRate; - } - - public BigDecimal getSavingInterestRate() { - return this.savingInterestRate; - } - - public EnumOptionData getInterestType() { - return this.interestType; - } - - public EnumOptionData getInterestCalculationMethod() { - return this.interestCalculationMethod; - } - - public Integer getTenure() { - return this.tenure; - } - - public EnumOptionData getTenureType() { - return this.tenureType; - } - - public LocalDate getProjectedCommencementDate() { - return this.projectedCommencementDate; - } - - public LocalDate getActualCommencementDate() { - return this.actualCommencementDate; - } - - public LocalDate getMaturesOnDate() { - return this.maturesOnDate; - } - - public BigDecimal getProjectedInterestAccuredOnMaturity() { - return this.projectedInterestAccuredOnMaturity; - } - - public BigDecimal getActualInterestAccured() { - return this.actualInterestAccured; - } - - public BigDecimal getProjectedMaturityAmount() { - return this.projectedMaturityAmount; - } - - public BigDecimal getActualMaturityAmount() { - return this.actualMaturityAmount; - } - - public boolean isPreClosureAllowed() { - return this.preClosureAllowed; - } - - public BigDecimal getPreClosureInterestRate() { - return this.preClosureInterestRate; - } - - public LocalDate getWithdrawnonDate() { - return this.withdrawnonDate; - } - - public LocalDate getRejectedonDate() { - return this.rejectedonDate; - } - - public LocalDate getClosedonDate() { - return this.closedonDate; - } - - public boolean isLockinPeriodAllowed() { - return this.isLockinPeriodAllowed; - } - - public Integer getLockinPeriod() { - return this.lockinPeriod; - } - - public EnumOptionData getLockinPeriodType() { - return this.lockinPeriodType; - } - - public Integer getDepositEvery() { - return this.depositEvery; - } - - public List getProductOptions() { - return this.productOptions; - } - - public List getCurrencyOptions() { - return this.currencyOptions; - } - - public List getSavingsProductTypeOptions() { - return this.savingsProductTypeOptions; - } - - public List getTenureTypeOptions() { - return this.tenureTypeOptions; - } - - public List getSavingFrequencyOptions() { - return this.savingFrequencyOptions; - } - - public List getSavingsInterestTypeOptions() { - return this.savingsInterestTypeOptions; - } - - public List getLockinPeriodTypeOptions() { - return this.lockinPeriodTypeOptions; - } - - public List getInterestCalculationOptions() { - return this.interestCalculationOptions; - } - - public BigDecimal getOutstandingAmount() { - return this.outstandingAmount; - } - - public Integer getInterestPostEvery() { - return this.interestPostEvery; - } - - public EnumOptionData getInterestPostFrequency() { - return this.interestPostFrequency; - } - + public BigDecimal getOutstandingAmount() { + return this.outstandingAmount; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccount.java index 354391786..e55f73a96 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingAccount.java @@ -43,7 +43,7 @@ import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum; import org.mifosplatform.useradministration.domain.AppUser; @Entity -@Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name="saving_acc_external_id", columnNames = { "external_id" })) +@Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name = "saving_acc_external_id", columnNames = { "external_id" })) public class SavingAccount extends AbstractAuditableCustom { @ManyToOne @@ -60,14 +60,12 @@ public class SavingAccount extends AbstractAuditableCustom { @Column(name = "external_id") private String externalId; - @SuppressWarnings("unused") @Embedded private MonetaryCurrency currency; @Column(name = "deposit_amount_per_period", scale = 6, precision = 19, nullable = false) private BigDecimal savingsDepositAmountPerPeriod; - @SuppressWarnings("unused") @Column(name = "total_deposit_amount", scale = 6, precision = 19, nullable = false) private BigDecimal totalSavingsAmount; @@ -96,7 +94,6 @@ public class SavingAccount extends AbstractAuditableCustom { @Column(name = "projected_commencement_date") private Date projectedCommencementDate; - @SuppressWarnings("unused") @Temporal(TemporalType.DATE) @Column(name = "actual_commencement_date") private Date actualCommencementDate; @@ -124,7 +121,7 @@ public class SavingAccount extends AbstractAuditableCustom { @Column(name = "pre_closure_interest_rate", scale = 6, precision = 19, nullable = false) private BigDecimal preClosureInterestRate; - + @Column(name = "outstanding_amount", scale = 6, precision = 19, nullable = false) private BigDecimal outstandingAmount; @@ -159,16 +156,16 @@ public class SavingAccount extends AbstractAuditableCustom { @Column(name = "lock_in_period_type", nullable = false) private Integer lockinPeriodType; - + @Column(name = "deposit_every", nullable = false) private Integer payEvery; - + @Column(name = "interest_posting_every", nullable = false) private Integer interestPostEvery; - + @Column(name = "interest_posting_frequency", nullable = false) private Integer interestPostFrequency; - + @Column(name = "interest_posted_amount", scale = 6, precision = 19) private BigDecimal interestPostedAmount; @@ -185,45 +182,48 @@ public class SavingAccount extends AbstractAuditableCustom { @LazyCollection(LazyCollectionOption.FALSE) @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingAccount", orphanRemoval = true) private final List savingScheduleInstallments = new ArrayList(); - + @OrderBy(value = "id") @LazyCollection(LazyCollectionOption.FALSE) @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingAccount", orphanRemoval = true) private final List savingAccountTransactions = new ArrayList(); - - public SavingAccount() { - // TODO Auto-generated constructor stub - } + + protected SavingAccount() { + // + } public static SavingAccount openNew(Client client, SavingProduct product, String externalId, Money savingsDeposit, BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum, SavingProductType savingProductType, SavingFrequencyType savingFrequencyType, SavingsInterestType interestType, SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod, PeriodFrequencyType lockinPeriodType, - ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, final DepositLifecycleStateMachine lifecycleStateMachine, - Integer depositEvery, Integer interestPostEvery, Integer interestPostFrequency) { + ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, + final DepositLifecycleStateMachine lifecycleStateMachine, Integer depositEvery, Integer interestPostEvery, + Integer interestPostFrequency) { Money futureValueOnMaturity = null; if (savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod()) { futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, - reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,depositEvery); + reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod, + depositEvery); } else if (savingProductType.isReccuring() && tenureTypeEnum.isPerpetual()) { futureValueOnMaturity = savingsDeposit; } else { - futureValueOnMaturity = savingsDeposit; + futureValueOnMaturity = savingsDeposit; } return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, interestType, savingInterestCalculationMethod, - isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine,depositEvery,interestPostEvery, interestPostFrequency); + isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine, depositEvery, + interestPostEvery, interestPostFrequency); } public SavingAccount(Client client, String externalId, SavingProduct product, Money savingsDeposit, BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum, SavingProductType savingProductType, SavingFrequencyType savingFrequencyType, SavingsInterestType interestType, SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod, - PeriodFrequencyType lockinPeriodType, Money futureValueOnMaturity, final DepositLifecycleStateMachine lifecycleStateMachine,Integer payEvery, - Integer interestPostEvery, Integer interestPostFrequency) { + PeriodFrequencyType lockinPeriodType, Money futureValueOnMaturity, final DepositLifecycleStateMachine lifecycleStateMachine, + Integer payEvery, Integer interestPostEvery, Integer interestPostFrequency) { DepositAccountStatus from = null; if (accountStatus != null) { @@ -256,29 +256,35 @@ public class SavingAccount extends AbstractAuditableCustom { this.lockinPeriod = lockinPeriod; this.lockinPeriodType = lockinPeriodType.getValue(); this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); - BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); //presently only for months - this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring : BigDecimal.ZERO; + BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract( + BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); // presently + // only + // for + // months + this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring + : BigDecimal.ZERO; this.payEvery = payEvery; this.outstandingAmount = BigDecimal.ZERO; this.interestPostEvery = interestPostEvery; - this.interestPostFrequency=interestPostFrequency; + this.interestPostFrequency = interestPostFrequency; } public void modifyAccount(SavingProduct product, String externalId, Money savingsDeposit, BigDecimal reccuringInterestRate, BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum, SavingProductType savingProductType, SavingFrequencyType savingFrequencyType, SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod, - PeriodFrequencyType lockinPeriodType, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,Integer payEvery, + PeriodFrequencyType lockinPeriodType, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, Integer payEvery, SavingsInterestType interestType, Integer interestPostEvery, Integer interestPostFrequency) { - Money futureValueOnMaturity = null; + Money futureValueOnMaturity = null; if (savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod()) { - futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, - reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,payEvery); + futureValueOnMaturity = reccuringDepositInterestCalculator + .calculateInterestOnMaturityFor(savingsDeposit, tenure, reccuringInterestRate, commencementDate, tenureTypeEnum, + savingFrequencyType, savingInterestCalculationMethod, payEvery); } else if (savingProductType.isReccuring() && tenureTypeEnum.isPerpetual()) { futureValueOnMaturity = savingsDeposit; } else { - futureValueOnMaturity = savingsDeposit; + futureValueOnMaturity = savingsDeposit; } this.product = product; @@ -299,12 +305,17 @@ public class SavingAccount extends AbstractAuditableCustom { this.payEvery = payEvery; this.outstandingAmount = BigDecimal.ZERO; this.interestPostEvery = interestPostEvery; - this.interestPostFrequency=interestPostFrequency; + this.interestPostFrequency = interestPostFrequency; this.savingScheduleInstallments.clear(); this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount(); - BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); //presently only for months - this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring : BigDecimal.ZERO; + BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract( + BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); // presently + // only + // for + // months + this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring + : BigDecimal.ZERO; } public boolean isDeleted() { @@ -392,32 +403,31 @@ public class SavingAccount extends AbstractAuditableCustom { } public Integer getPayEvery() { - return this.payEvery; - } + return this.payEvery; + } - public BigDecimal getOutstandingAmount() { - return this.outstandingAmount; - } + public BigDecimal getOutstandingAmount() { + return this.outstandingAmount; + } - public Integer getInterestPostEvery() { - return this.interestPostEvery; - } + public Integer getInterestPostEvery() { + return this.interestPostEvery; + } - public Integer getInterestPostFrequency() { - return this.interestPostFrequency; - } + public Integer getInterestPostFrequency() { + return this.interestPostFrequency; + } - public List getSavingAccountTransactions() { - return this.savingAccountTransactions; - } + public List getSavingAccountTransactions() { + return this.savingAccountTransactions; + } - public void addSavingScheduleInstallment(final SavingScheduleInstallments installment) { + public void addSavingScheduleInstallment(final SavingScheduleInstallments installment) { installment.updateAccount(this); this.savingScheduleInstallments.add(installment); } - public void reject(LocalDate rejectedOn, DepositLifecycleStateMachine depositLifecycleStateMachine) { - + public void reject(LocalDate rejectedOn, DepositLifecycleStateMachine depositLifecycleStateMachine) { DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_REJECTED, DepositAccountStatus.fromInt(this.accountStatus)); @@ -432,7 +442,7 @@ public class SavingAccount extends AbstractAuditableCustom { final String errorMessage = "The date on which a saving account is rejected cannot be before its submittal date: " + projectedCommencementDate().toString(); throw new InvalidDepositStateTransitionException("reject", "cannot.be.before.submittal.date", errorMessage, rejectedOn, - projectedCommencementDate()); + projectedCommencementDate()); } if (rejectedOn.isAfter(new LocalDate())) { @@ -442,10 +452,9 @@ public class SavingAccount extends AbstractAuditableCustom { } - - } - - public LocalDate projectedCommencementDate() { + } + + public LocalDate projectedCommencementDate() { LocalDate date = null; if (this.projectedCommencementDate != null) { date = new LocalDate(this.projectedCommencementDate); @@ -453,9 +462,9 @@ public class SavingAccount extends AbstractAuditableCustom { return date; } - public void withdrawnByApplicant(LocalDate withdrawnOn, DepositLifecycleStateMachine depositLifecycleStateMachine) { - - DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_WITHDRAWN, + public void withdrawnByApplicant(LocalDate withdrawnOn, DepositLifecycleStateMachine depositLifecycleStateMachine) { + + DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_WITHDRAWN, DepositAccountStatus.fromInt(this.accountStatus)); this.accountStatus = statusEnum.getValue(); @@ -468,8 +477,8 @@ public class SavingAccount extends AbstractAuditableCustom { final String errorMessage = "The date on which a deposit is rejected cannot be before its submittal date: " + projectedCommencementDate().toString(); - throw new InvalidDepositStateTransitionException("withdrawnbyclient", "cannot.be.before.submittal.date", errorMessage, withdrawnOn, - projectedCommencementDate()); + throw new InvalidDepositStateTransitionException("withdrawnbyclient", "cannot.be.before.submittal.date", errorMessage, + withdrawnOn, projectedCommencementDate()); } @@ -477,208 +486,218 @@ public class SavingAccount extends AbstractAuditableCustom { final String errorMessage = "The date on which a deposit is rejected cannot be in the future."; throw new InvalidDepositStateTransitionException("withdrawnbyclient", "cannot.be.a.future.date", errorMessage, withdrawnOn); } - } + } - public void undoSavingAccountApproval(DepositLifecycleStateMachine depositLifecycleStateMachine) { - DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVAL_UNDO, + public void undoSavingAccountApproval(DepositLifecycleStateMachine depositLifecycleStateMachine) { + DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVAL_UNDO, DepositAccountStatus.fromInt(this.accountStatus)); this.accountStatus = statusEnum.getValue(); this.savingScheduleInstallments.clear(); this.closedOnDate = new Date(); - } + } - public void approveSavingAccount(LocalDate approvalDate, BigDecimal savingsDepositAmountPerPeriod, BigDecimal recurringInterestRate, - BigDecimal savingInterestRate, Integer interestType, Integer tenure, Integer tenureType, Integer frequency, Integer payEvery, - DepositLifecycleStateMachine depositLifecycleStateMachine, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, - Integer interestPostEvery, Integer interestPostFrequency) { - - DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVED, + public void approveSavingAccount(LocalDate approvalDate, BigDecimal savingsDepositAmountPerPeriod, BigDecimal recurringInterestRate, + BigDecimal savingInterestRate, Integer interestType, Integer tenure, Integer tenureType, Integer frequency, Integer payEvery, + DepositLifecycleStateMachine depositLifecycleStateMachine, + ReccuringDepositInterestCalculator reccuringDepositInterestCalculator, Integer interestPostEvery, Integer interestPostFrequency) { + + DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_APPROVED, DepositAccountStatus.fromInt(this.accountStatus)); this.accountStatus = statusEnum.getValue(); - + Money savingsAmountPerPeriod = Money.of(currency, savingsDepositAmountPerPeriod); - TenureTypeEnum tenureTypeEnum = TenureTypeEnum.fromInt(tenureType); + TenureTypeEnum tenureTypeEnum = TenureTypeEnum.fromInt(tenureType); SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(frequency); - SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(this.interestCalculationMethod); - + SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(this.interestCalculationMethod); + Money futureValueOnMaturity = null; if (SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isFixedPeriod()) { futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsAmountPerPeriod, tenure, - recurringInterestRate, approvalDate, tenureTypeEnum, savingFrequencyType, interestCalculationMethod,payEvery); - } else if (SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isPerpetual()) { + recurringInterestRate, approvalDate, tenureTypeEnum, savingFrequencyType, interestCalculationMethod, payEvery); + } else if (SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isPerpetual()) { futureValueOnMaturity = savingsAmountPerPeriod; } else { - futureValueOnMaturity = savingsAmountPerPeriod; + futureValueOnMaturity = savingsAmountPerPeriod; } - - this.actualCommencementDate = approvalDate.toDate(); - this.savingsDepositAmountPerPeriod = savingsDepositAmountPerPeriod; - this.reccuringInterestRate = recurringInterestRate; - this.savingInterestRate = savingInterestRate; - this.interestType = interestType; - this.tenure = tenure; - this.tenureType = tenureType; - this.frequency = frequency; - this.payEvery = payEvery; - this.savingScheduleInstallments.clear(); - this.total=futureValueOnMaturity.getAmount(); - BigDecimal interestForReccuring = futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDepositAmountPerPeriod.doubleValue() * tenure.doubleValue()/payEvery.doubleValue())); //presently only for months - this.interestAccrued = SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isFixedPeriod() ? interestForReccuring : BigDecimal.ZERO; - this.interestPostEvery = interestPostEvery; - this.interestPostFrequency = interestPostFrequency; - - // for interest posting initializing + + this.actualCommencementDate = approvalDate.toDate(); + this.savingsDepositAmountPerPeriod = savingsDepositAmountPerPeriod; + this.reccuringInterestRate = recurringInterestRate; + this.savingInterestRate = savingInterestRate; + this.interestType = interestType; + this.tenure = tenure; + this.tenureType = tenureType; + this.frequency = frequency; + this.payEvery = payEvery; + this.savingScheduleInstallments.clear(); + this.total = futureValueOnMaturity.getAmount(); + BigDecimal interestForReccuring = futureValueOnMaturity.getAmount().subtract( + BigDecimal.valueOf(savingsDepositAmountPerPeriod.doubleValue() * tenure.doubleValue() / payEvery.doubleValue())); // presently + // only + // for + // months + this.interestAccrued = SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isFixedPeriod() ? interestForReccuring + : BigDecimal.ZERO; + this.interestPostEvery = interestPostEvery; + this.interestPostFrequency = interestPostFrequency; + + // for interest posting initializing this.lastInterestPostedDate = this.actualCommencementDate; this.nextInterestPostingDate = new LocalDate(this.lastInterestPostedDate).plusMonths(this.interestPostEvery).toDate(); this.interestPostedAmount = BigDecimal.ZERO; - } + } - public void depositMoney(SavingAccountDepositCommand command) { - - BigDecimal depositAmount = BigDecimal.ZERO; - BigDecimal remainAmountToBePaid = BigDecimal.ZERO; - BigDecimal commandRemainDepositAmount = command.getSavingsDepostiAmountPerPeriod(); - - SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.deposit(command.getSavingsDepostiAmountPerPeriod(),command.getDepositDate()); - savingAccountTransaction.updateAccount(this); - this.savingAccountTransactions.add(savingAccountTransaction); - this.outstandingAmount = this.outstandingAmount.add(command.getSavingsDepostiAmountPerPeriod()); - this.totalSavingsAmount = this.totalSavingsAmount.add(command.getSavingsDepostiAmountPerPeriod()); - - if(SavingProductType.fromInt(this.savingProductType).isReccuring() && TenureTypeEnum.fromInt(tenureType).isFixedPeriod()) { - for(SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments){ - if(!savingScheduleInstallment.isCompleted()){ - depositAmount = savingScheduleInstallment.getDeposit(); - remainAmountToBePaid = depositAmount.subtract(savingScheduleInstallment.getDepositPaid()); - if (remainAmountToBePaid.doubleValue() > 0) { - if (commandRemainDepositAmount.doubleValue() > 0) { - if (commandRemainDepositAmount.doubleValue() >= remainAmountToBePaid.doubleValue()) { - savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid())); - savingScheduleInstallment.setPaymentDate(command.getDepositDate().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()); - commandRemainDepositAmount = BigDecimal.ZERO; - } - } - } - } - } - } else { - for(SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments){ - savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid())); - savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate()); - } - } - } + public void depositMoney(SavingAccountDepositCommand command) { - public boolean isActive() { - return DepositAccountStatus.fromInt(this.accountStatus).isActive(); - } + BigDecimal depositAmount = BigDecimal.ZERO; + BigDecimal remainAmountToBePaid = BigDecimal.ZERO; + BigDecimal commandRemainDepositAmount = command.getSavingsDepostiAmountPerPeriod(); - public void withdrawAmount(BigDecimal amount, LocalDate transactionDate) { - this.outstandingAmount = this.outstandingAmount.subtract(amount); - SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.withdraw(amount,transactionDate); - savingAccountTransaction.updateAccount(this); - this.savingAccountTransactions.add(savingAccountTransaction); - } - - - /** + SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.deposit(command.getSavingsDepostiAmountPerPeriod(), + command.getDepositDate()); + savingAccountTransaction.updateAccount(this); + this.savingAccountTransactions.add(savingAccountTransaction); + this.outstandingAmount = this.outstandingAmount.add(command.getSavingsDepostiAmountPerPeriod()); + this.totalSavingsAmount = this.totalSavingsAmount.add(command.getSavingsDepostiAmountPerPeriod()); + + if (SavingProductType.fromInt(this.savingProductType).isReccuring() && TenureTypeEnum.fromInt(tenureType).isFixedPeriod()) { + for (SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments) { + if (!savingScheduleInstallment.isCompleted()) { + depositAmount = savingScheduleInstallment.getDeposit(); + remainAmountToBePaid = depositAmount.subtract(savingScheduleInstallment.getDepositPaid()); + if (remainAmountToBePaid.doubleValue() > 0) { + if (commandRemainDepositAmount.doubleValue() > 0) { + if (commandRemainDepositAmount.doubleValue() >= remainAmountToBePaid.doubleValue()) { + savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment + .getDepositPaid())); + savingScheduleInstallment.setPaymentDate(command.getDepositDate().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()); + commandRemainDepositAmount = BigDecimal.ZERO; + } + } + } + } + } + } else { + for (SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments) { + savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid())); + savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate()); + } + } + } + + public boolean isActive() { + return DepositAccountStatus.fromInt(this.accountStatus).isActive(); + } + + public void withdrawAmount(BigDecimal amount, LocalDate transactionDate) { + this.outstandingAmount = this.outstandingAmount.subtract(amount); + SavingAccountTransaction savingAccountTransaction = SavingAccountTransaction.withdraw(amount, transactionDate); + savingAccountTransaction.updateAccount(this); + this.savingAccountTransactions.add(savingAccountTransaction); + } + + /** * Delete is a soft delete. Updates flag on account so it wont appear * in query/report results. * * Any fields with unique constraints and prepended with id of record. */ - public void delete() { - this.deleted = true; + public void delete() { + this.deleted = true; this.externalId = this.getId() + "_" + this.externalId; - } + } - public void postInterest() { - - LocalDate lastInterestPostedDate = getLastInterestPostedDate(); + public void postInterest() { + + LocalDate lastInterestPostedDate = getLastInterestPostedDate(); @SuppressWarnings("unused") - LocalDate nextInterestPostingDate = getNextInterestPostedDate(); + LocalDate nextInterestPostingDate = getNextInterestPostedDate(); @SuppressWarnings("unused") - SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(this.interestCalculationMethod); - + SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod + .fromInt(this.interestCalculationMethod); + Integer monthsForInterestCalculation = Months.monthsBetween(lastInterestPostedDate, new LocalDate()).getMonths(); Integer postInterestItereations = monthsForInterestCalculation / this.interestPostEvery; MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN); BigDecimal interestRateAsFraction = reccuringInterestRate.divide(BigDecimal.valueOf(100), mc); final Integer monthsInYear = 12; - + BigDecimal totalDepositedAmount = BigDecimal.ZERO; - BigDecimal totalWithdrawableAmount = BigDecimal.ZERO; - BigDecimal totalOutstandingAmount = BigDecimal.ZERO; - boolean isOutstandingAmountCalculated = false; - - while (postInterestItereations > 0 ) { - lastInterestPostedDate = getLastInterestPostedDate(); - nextInterestPostingDate = getNextInterestPostedDate(); - LocalDate transactionStartDate = lastInterestPostedDate; - - BigDecimal termTotalAmount = BigDecimal.ZERO; - BigDecimal averageBalanceForTerm = BigDecimal.ZERO; - - for (int i=0; i< interestPostEvery; i++){ - //default for months here - LocalDate transactionEndDate = transactionStartDate.plusMonths(1); - BigDecimal depositedAmount = BigDecimal.ZERO; - BigDecimal withdrawableAmount = BigDecimal.ZERO; - BigDecimal outstandingAmount = BigDecimal.ZERO; - - for(SavingAccountTransaction savingAccountTransaction : this.savingAccountTransactions){ - LocalDate actualTransactionDate = savingAccountTransaction.getTransactionDate(); - if (actualTransactionDate != null && (actualTransactionDate.isAfter(transactionStartDate) || actualTransactionDate.isEqual(transactionStartDate))) { - if (actualTransactionDate.isBefore(transactionEndDate)) { - if(savingAccountTransaction.getTypeOf().isDeposit()){ - depositedAmount = depositedAmount.add(savingAccountTransaction.getAmount()); - } else if (savingAccountTransaction.getTypeOf().isWithdraw()) { - withdrawableAmount = withdrawableAmount.add(savingAccountTransaction.getAmount()); - } - } - } else if (actualTransactionDate != null && (actualTransactionDate.isBefore(transactionStartDate))) { - if(!isOutstandingAmountCalculated){ - if(savingAccountTransaction.getTypeOf().isDeposit()){ - depositedAmount = depositedAmount.add(savingAccountTransaction.getAmount()); - } else if (savingAccountTransaction.getTypeOf().isWithdraw()) { - withdrawableAmount = withdrawableAmount.add(savingAccountTransaction.getAmount()); - } - } - } - } - outstandingAmount = depositedAmount.subtract(withdrawableAmount); - totalDepositedAmount = totalDepositedAmount.add(depositedAmount); - totalWithdrawableAmount = totalWithdrawableAmount.add(withdrawableAmount); - totalOutstandingAmount = totalOutstandingAmount.add(outstandingAmount); - termTotalAmount = termTotalAmount.add(totalOutstandingAmount); - transactionStartDate = transactionEndDate; - isOutstandingAmountCalculated = true; - - } - // TODO- calculate interest on calculation method - - // if (savingInterestCalculationMethod.isAverageBalance()) { - averageBalanceForTerm =BigDecimal.valueOf(termTotalAmount.doubleValue()/this.interestPostEvery); - BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/monthsInYear.doubleValue()*this.interestPostEvery.doubleValue()); - BigDecimal interestPerTerm = averageBalanceForTerm.multiply(interestRatePerTerm); - this.interestPostedAmount = this.interestPostedAmount.add(interestPerTerm); - totalOutstandingAmount = totalOutstandingAmount.add(interestPerTerm); - // } else if(savingInterestCalculationMethod.isMonthlyCollection()){ - - //} - this.outstandingAmount = this.outstandingAmount . add(interestPerTerm); - this.lastInterestPostedDate = getNextInterestPostedDate().toDate(); - this.nextInterestPostingDate = getNextInterestPostedDate().plusMonths(this.interestPostEvery).toDate(); - postInterestItereations--; + BigDecimal totalWithdrawableAmount = BigDecimal.ZERO; + BigDecimal totalOutstandingAmount = BigDecimal.ZERO; + boolean isOutstandingAmountCalculated = false; + + while (postInterestItereations > 0) { + lastInterestPostedDate = getLastInterestPostedDate(); + nextInterestPostingDate = getNextInterestPostedDate(); + LocalDate transactionStartDate = lastInterestPostedDate; + + BigDecimal termTotalAmount = BigDecimal.ZERO; + BigDecimal averageBalanceForTerm = BigDecimal.ZERO; + + for (int i = 0; i < interestPostEvery; i++) { + // default for months here + LocalDate transactionEndDate = transactionStartDate.plusMonths(1); + BigDecimal depositedAmount = BigDecimal.ZERO; + BigDecimal withdrawableAmount = BigDecimal.ZERO; + BigDecimal outstandingAmount = BigDecimal.ZERO; + + for (SavingAccountTransaction savingAccountTransaction : this.savingAccountTransactions) { + LocalDate actualTransactionDate = savingAccountTransaction.getTransactionDate(); + if (actualTransactionDate != null + && (actualTransactionDate.isAfter(transactionStartDate) || actualTransactionDate.isEqual(transactionStartDate))) { + if (actualTransactionDate.isBefore(transactionEndDate)) { + if (savingAccountTransaction.getTypeOf().isDeposit()) { + depositedAmount = depositedAmount.add(savingAccountTransaction.getAmount()); + } else if (savingAccountTransaction.getTypeOf().isWithdraw()) { + withdrawableAmount = withdrawableAmount.add(savingAccountTransaction.getAmount()); + } + } + } else if (actualTransactionDate != null && (actualTransactionDate.isBefore(transactionStartDate))) { + if (!isOutstandingAmountCalculated) { + if (savingAccountTransaction.getTypeOf().isDeposit()) { + depositedAmount = depositedAmount.add(savingAccountTransaction.getAmount()); + } else if (savingAccountTransaction.getTypeOf().isWithdraw()) { + withdrawableAmount = withdrawableAmount.add(savingAccountTransaction.getAmount()); + } + } + } + } + outstandingAmount = depositedAmount.subtract(withdrawableAmount); + totalDepositedAmount = totalDepositedAmount.add(depositedAmount); + totalWithdrawableAmount = totalWithdrawableAmount.add(withdrawableAmount); + totalOutstandingAmount = totalOutstandingAmount.add(outstandingAmount); + termTotalAmount = termTotalAmount.add(totalOutstandingAmount); + transactionStartDate = transactionEndDate; + isOutstandingAmountCalculated = true; + + } + // TODO- calculate interest on calculation method + + // if (savingInterestCalculationMethod.isAverageBalance()) { + averageBalanceForTerm = BigDecimal.valueOf(termTotalAmount.doubleValue() / this.interestPostEvery); + BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue() / monthsInYear.doubleValue() + * this.interestPostEvery.doubleValue()); + BigDecimal interestPerTerm = averageBalanceForTerm.multiply(interestRatePerTerm); + this.interestPostedAmount = this.interestPostedAmount.add(interestPerTerm); + totalOutstandingAmount = totalOutstandingAmount.add(interestPerTerm); + // } else if(savingInterestCalculationMethod.isMonthlyCollection()){ + + // } + this.outstandingAmount = this.outstandingAmount.add(interestPerTerm); + this.lastInterestPostedDate = getNextInterestPostedDate().toDate(); + this.nextInterestPostingDate = getNextInterestPostedDate().plusMonths(this.interestPostEvery).toDate(); + postInterestItereations--; } - } - - private final LocalDate getLastInterestPostedDate() { + } + + private final LocalDate getLastInterestPostedDate() { LocalDate lastInterestPostedDate; if (this.lastInterestPostedDate == null) { lastInterestPostedDate = new LocalDate(this.actualCommencementDate); @@ -697,14 +716,4 @@ public class SavingAccount extends AbstractAuditableCustom { } return nextInterestPostingDate; } - - private final LocalDate getMaturityDate(){ - LocalDate commencementDate; - if (this.actualCommencementDate == null) { - commencementDate = new LocalDate(this.projectedCommencementDate).plusMonths(this.tenure); - } else { - commencementDate = new LocalDate(this.actualCommencementDate).plusMonths(this.tenure); - } - return commencementDate; - } -} +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingScheduleInstallments.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingScheduleInstallments.java index 80270ee09..d101b45b2 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingScheduleInstallments.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savingsaccount/domain/SavingScheduleInstallments.java @@ -23,7 +23,6 @@ public class SavingScheduleInstallments extends AbstractAuditableCustom savingProducts = this.savingProductReadPlatformService.retrieveAllSavingProductsForLookup(); - - if (productId != null && productId != -1) { - SavingProductData selectedProduct = findSavingProductById(savingProducts, productId); + @Override + public SavingAccountData retrieveNewSavingsAccountDetails(Long clientId, Long productId) { - CurrencyData currency = selectedProduct.getCurrency(); + context.authenticatedUser(); + ClientData clientAccount = this.clientReadPlatformService.retrieveIndividualClient(clientId); + SavingAccountData accountData = null; + Collection savingProducts = this.savingProductReadPlatformService.retrieveAllSavingProductsForLookup(); - accountData = new SavingAccountData(clientAccount.id(), clientAccount.displayName(), selectedProduct.getId(), - selectedProduct.getName(), currency, selectedProduct.getInterestRate(), selectedProduct.getSavingsDepositAmount(), - selectedProduct.getSavingProductType(), selectedProduct.getTenureType(), selectedProduct.getTenure(), selectedProduct.getSavingFrequencyType(), - selectedProduct.getInterestType(), selectedProduct.getInterestCalculationMethod(),selectedProduct.getMinimumBalanceForWithdrawal(), - selectedProduct.isPartialDepositAllowed(), selectedProduct.isLockinPeriodAllowed(),selectedProduct.getLockinPeriod(), - selectedProduct.getLockinPeriodType(),selectedProduct.getDepositEvery()); - - } else { - accountData = SavingAccountData.createFrom(clientAccount.id(), clientAccount.displayName()); - } - return accountData; - } + if (productId != null && productId != -1) { + SavingProductData selectedProduct = findSavingProductById(savingProducts, productId); - private SavingProductData findSavingProductById( Collection savingProducts, Long productId) { - SavingProductData match = this.savingProductReadPlatformService.retrieveNewSavingProductDetails(); - for (SavingProductLookup savingProductLookup : savingProducts) { - if (savingProductLookup.hasId(productId)) { - match = this.savingProductReadPlatformService.retrieveSavingProduct(savingProductLookup.getId()); - break; - } - } - return match; - } + CurrencyData currency = selectedProduct.getCurrency(); - @Override - public SavingPermissionData retrieveSavingAccountPermissions(SavingAccountData savingAccountData) { - boolean pendingApproval = (savingAccountData.getStatus().getId().equals(100L)); - boolean undoApprovalAllowed = (savingAccountData.getStatus().getId().equals(300L)); - boolean renewelAllowed = false; - if (savingAccountData.getMaturesOnDate() != null && savingAccountData.getTenureType().equals(TenureTypeEnum.FIXED_PERIOD)) { - if (new LocalDate().isAfter(savingAccountData.getMaturesOnDate())) { - renewelAllowed = true; - } - } - boolean rejectAllowed = pendingApproval; - boolean withdrawnByApplicantAllowed = pendingApproval; - boolean isMaturedDepositAccount = (savingAccountData.getStatus().getId().equals(700L)); - return new SavingPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval, renewelAllowed, isMaturedDepositAccount); - } - - @SuppressWarnings("unused") - @Override - public BigDecimal deriveSavingDueAmount(SavingAccountData account) { - - BigDecimal dueAmount = BigDecimal.ZERO; - EnumOptionData status = account.getStatus(); - LocalDate date = account.getActualCommencementDate(); - - if (account.getStatus() != null && account.getActualCommencementDate() != null) { - BigDecimal amountPerPeriod = account.getSavingsDepostiAmountPerPeriod(); - Integer tenure = account.getTenure(); - Integer depositEvery = account.getDepositEvery(); - Integer noOfPeriods = tenure/depositEvery ; - Integer noOfMonths = Months.monthsBetween(date, new LocalDate()).getMonths(); - Integer noOfPeriodsExistedTillDate = noOfMonths/depositEvery; - BigDecimal totalAmountToBePaidTillDate = BigDecimal.valueOf(noOfPeriodsExistedTillDate.doubleValue()*amountPerPeriod.doubleValue()); - dueAmount = dueAmount.add(BigDecimal.valueOf(totalAmountToBePaidTillDate.doubleValue() - account.getOutstandingAmount().doubleValue())); - - } - dueAmount = dueAmount.doubleValue() < 0 ? BigDecimal.ZERO : dueAmount; - return dueAmount; - } - - @Override - public SavingScheduleData retrieveSavingsAccountSchedule(Long accountId, CurrencyData currency) { - this.context.authenticatedUser(); - SavingAccountScheduleMapper mapper = new SavingAccountScheduleMapper(); - String sql = "Select " + mapper.savingScheduleSchema() +" where ss.saving_account_id =? order by ss.installment"; - List periods = this.jdbcTemplate.query(sql, mapper, new Object[]{accountId}); - BigDecimal cumulativeDepositDue = BigDecimal.ZERO; - BigDecimal cumulativeDepositPaid = BigDecimal.ZERO; - BigDecimal cummulativeInterestAccured = BigDecimal.ZERO; - for(SavingSchedulePeriodData data : periods){ - cumulativeDepositDue = cumulativeDepositDue.add(data.getDepositDue())/*.subtract(data.getDepositPaid())*/; - cumulativeDepositPaid = cumulativeDepositPaid.add(data.getDepositPaid()); - cummulativeInterestAccured = cummulativeInterestAccured.add(data.getInterestAccured()); - } - SavingScheduleData scheduleData = new SavingScheduleData(currency, cumulativeDepositDue, cumulativeDepositPaid, cummulativeInterestAccured, periods); - return scheduleData; - } - - public static final class SavingAccountScheduleMapper implements RowMapper { - - public String savingScheduleSchema(){ - return "ss.id as id, ss.saving_account_id as savingAccountId, ss.duedate as dueDate, ss.installment as installment, " - + " ss.deposit as deposit, ss.payment_date as paymentDate, ss.deposit_paid as depositPaid, " - + " ss.completed_derived as completedDerived, ss.interest_accured AS interestAccured FROM m_saving_schedule ss"; - } + accountData = new SavingAccountData(clientAccount.id(), clientAccount.displayName(), selectedProduct.getId(), + selectedProduct.getName(), currency, selectedProduct.getInterestRate(), selectedProduct.getSavingsDepositAmount(), + selectedProduct.getSavingProductType(), selectedProduct.getTenureType(), selectedProduct.getTenure(), + selectedProduct.getSavingFrequencyType(), selectedProduct.getInterestType(), + selectedProduct.getInterestCalculationMethod(), selectedProduct.getMinimumBalanceForWithdrawal(), + selectedProduct.isPartialDepositAllowed(), selectedProduct.isLockinPeriodAllowed(), selectedProduct.getLockinPeriod(), + selectedProduct.getLockinPeriodType(), selectedProduct.getDepositEvery()); - @Override - public SavingSchedulePeriodData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { - - LocalDate dueDate = JdbcSupport.getLocalDate(rs, "dueDate"); - Integer installment = JdbcSupport.getInteger(rs, "installment"); - BigDecimal depositDue = rs.getBigDecimal("deposit"); - BigDecimal depositPaid = rs.getBigDecimal("depositPaid"); - BigDecimal interestAccured = rs.getBigDecimal("interestAccured"); - - return new SavingSchedulePeriodData(installment, dueDate, depositDue, depositPaid, interestAccured); - } - - } + } else { + accountData = SavingAccountData.createFrom(clientAccount.id(), clientAccount.displayName()); + } + return accountData; + } - @Override - public Collection retrieveSavingAccountsForLookUp() { - SavingAccountLookupMapper mapper = new SavingAccountLookupMapper(); - String sql = "select "+ mapper.schema(); - return this.jdbcTemplate.query(sql, mapper, new Object[] {}); - } + private SavingProductData findSavingProductById(Collection savingProducts, Long productId) { + SavingProductData match = this.savingProductReadPlatformService.retrieveNewSavingProductDetails(); + for (SavingProductLookup savingProductLookup : savingProducts) { + if (savingProductLookup.hasId(productId)) { + match = this.savingProductReadPlatformService.retrieveSavingProduct(savingProductLookup.getId()); + break; + } + } + return match; + } - private static final class SavingAccountLookupMapper implements RowMapper { - - public String schema(){ - return " sa.id as id from m_saving_account sa where sa.is_deleted=0 and sa.status_enum=300"; - } + @Override + public SavingPermissionData retrieveSavingAccountPermissions(SavingAccountData savingAccountData) { + boolean pendingApproval = (savingAccountData.getStatus().getId().equals(100L)); + boolean undoApprovalAllowed = (savingAccountData.getStatus().getId().equals(300L)); + boolean renewelAllowed = false; + if (savingAccountData.getMaturesOnDate() != null && savingAccountData.getTenureType().equals(TenureTypeEnum.FIXED_PERIOD)) { + if (new LocalDate().isAfter(savingAccountData.getMaturesOnDate())) { + renewelAllowed = true; + } + } + boolean rejectAllowed = pendingApproval; + boolean withdrawnByApplicantAllowed = pendingApproval; + boolean isMaturedDepositAccount = (savingAccountData.getStatus().getId().equals(700L)); + return new SavingPermissionData(rejectAllowed, withdrawnByApplicantAllowed, undoApprovalAllowed, pendingApproval, renewelAllowed, + isMaturedDepositAccount); + } - @Override - public SavingAccountForLookup mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { - Long id = rs.getLong("id"); - return new SavingAccountForLookup(id); - } - - } + @SuppressWarnings("unused") + @Override + public BigDecimal deriveSavingDueAmount(SavingAccountData account) { - @Override - public Collection retrieveSavingsAccountTransactions(Long accountId) { - this.context.authenticatedUser(); - SavingAccountTransactionMapper savingAccountTransactionMapper = new SavingAccountTransactionMapper(); - String sql = "select "+ savingAccountTransactionMapper.schema() + " where stxn.saving_account_id = ? "; - return jdbcTemplate.query(sql, savingAccountTransactionMapper, new Object[] {accountId}); - } - - private static final class SavingAccountTransactionMapper implements RowMapper { - - public String schema() { - return "stxn.id as id, stxn.transaction_type_enum as type, stxn.transaction_date as transactionDate, stxn.amount as amount FROM m_saving_account_transaction stxn"; - } + BigDecimal dueAmount = BigDecimal.ZERO; + EnumOptionData status = account.getStatus(); + LocalDate date = account.getActualCommencementDate(); - @Override - public SavingAccountTransactionsData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { - Long id = rs.getLong("id"); - LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate"); - Integer transactionTypeValue = JdbcSupport.getInteger(rs, "type"); - EnumOptionData transactionType = DepositAccountTransactionEnumerations.depositType(transactionTypeValue); - BigDecimal amount = rs.getBigDecimal("amount"); - return new SavingAccountTransactionsData(id, transactionDate, transactionType, amount); - } - - } + if (account.getStatus() != null && account.getActualCommencementDate() != null) { + BigDecimal amountPerPeriod = account.getSavingsDepostiAmountPerPeriod(); + Integer tenure = account.getTenure(); + Integer depositEvery = account.getDepositEvery(); + Integer noOfPeriods = tenure / depositEvery; + Integer noOfMonths = Months.monthsBetween(date, new LocalDate()).getMonths(); + Integer noOfPeriodsExistedTillDate = noOfMonths / depositEvery; + BigDecimal totalAmountToBePaidTillDate = BigDecimal.valueOf(noOfPeriodsExistedTillDate.doubleValue() + * amountPerPeriod.doubleValue()); + dueAmount = dueAmount.add(BigDecimal.valueOf(totalAmountToBePaidTillDate.doubleValue() + - account.getOutstandingAmount().doubleValue())); + } + dueAmount = dueAmount.doubleValue() < 0 ? BigDecimal.ZERO : dueAmount; + return dueAmount; + } + + @Override + public SavingScheduleData retrieveSavingsAccountSchedule(Long accountId, CurrencyData currency) { + this.context.authenticatedUser(); + SavingAccountScheduleMapper mapper = new SavingAccountScheduleMapper(); + String sql = "Select " + mapper.savingScheduleSchema() + " where ss.saving_account_id =? order by ss.installment"; + List periods = this.jdbcTemplate.query(sql, mapper, new Object[] { accountId }); + BigDecimal cumulativeDepositDue = BigDecimal.ZERO; + BigDecimal cumulativeDepositPaid = BigDecimal.ZERO; + BigDecimal cummulativeInterestAccured = BigDecimal.ZERO; + for (SavingSchedulePeriodData data : periods) { + cumulativeDepositDue = cumulativeDepositDue.add(data.getDepositDue()); + cumulativeDepositPaid = cumulativeDepositPaid.add(data.getDepositPaid()); + cummulativeInterestAccured = cummulativeInterestAccured.add(data.getInterestAccured()); + } + SavingScheduleData scheduleData = new SavingScheduleData(currency, cumulativeDepositDue, cumulativeDepositPaid, + cummulativeInterestAccured, periods); + return scheduleData; + } + + public static final class SavingAccountScheduleMapper implements RowMapper { + + public String savingScheduleSchema() { + return "ss.id as id, ss.saving_account_id as savingAccountId, ss.duedate as dueDate, ss.installment as installment, " + + " ss.deposit as deposit, ss.payment_date as paymentDate, ss.deposit_paid as depositPaid, " + + " ss.completed_derived as completedDerived, ss.interest_accured AS interestAccured FROM m_saving_schedule ss"; + } + + @Override + public SavingSchedulePeriodData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + + LocalDate dueDate = JdbcSupport.getLocalDate(rs, "dueDate"); + Integer installment = JdbcSupport.getInteger(rs, "installment"); + BigDecimal depositDue = rs.getBigDecimal("deposit"); + BigDecimal depositPaid = rs.getBigDecimal("depositPaid"); + BigDecimal interestAccured = rs.getBigDecimal("interestAccured"); + + return new SavingSchedulePeriodData(installment, dueDate, depositDue, depositPaid, interestAccured); + } + + } + + @Override + public Collection retrieveSavingAccountsForLookUp() { + SavingAccountLookupMapper mapper = new SavingAccountLookupMapper(); + String sql = "select " + mapper.schema(); + return this.jdbcTemplate.query(sql, mapper, new Object[] {}); + } + + private static final class SavingAccountLookupMapper implements RowMapper { + + public String schema() { + return " sa.id as id from m_saving_account sa where sa.is_deleted=0 and sa.status_enum=300"; + } + + @Override + public SavingAccountForLookup mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + Long id = rs.getLong("id"); + return new SavingAccountForLookup(id); + } + + } + + @Override + public Collection retrieveSavingsAccountTransactions(Long accountId) { + this.context.authenticatedUser(); + SavingAccountTransactionMapper savingAccountTransactionMapper = new SavingAccountTransactionMapper(); + String sql = "select " + savingAccountTransactionMapper.schema() + " where stxn.saving_account_id = ? "; + return jdbcTemplate.query(sql, savingAccountTransactionMapper, new Object[] { accountId }); + } + + private static final class SavingAccountTransactionMapper implements RowMapper { + + public String schema() { + return "stxn.id as id, stxn.transaction_type_enum as type, stxn.transaction_date as transactionDate, stxn.amount as amount FROM m_saving_account_transaction stxn"; + } + + @Override + public SavingAccountTransactionsData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + Long id = rs.getLong("id"); + LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate"); + Integer transactionTypeValue = JdbcSupport.getInteger(rs, "type"); + EnumOptionData transactionType = DepositAccountTransactionEnumerations.depositType(transactionTypeValue); + BigDecimal amount = rs.getBigDecimal("amount"); + return new SavingAccountTransactionsData(id, transactionDate, transactionType, amount); + } + } } \ No newline at end of file