Display deposit transactions in UI

Adding saving product

SavingProduct Definition

basic saving account creation

patch-2 reccuring deposit account

Saving account creation final patch
This commit is contained in:
Madhukar
2012-11-01 19:04:23 +05:30
parent 46c82b1f67
commit 3b4c1171e8
39 changed files with 2961 additions and 154 deletions
@@ -0,0 +1,47 @@
DROP TABLE if exists `m_saving_account`;
CREATE TABLE `m_saving_account` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`status_enum` smallint(5) NOT NULL DEFAULT '0',
`external_id` varchar(100) DEFAULT NULL,
`client_id` bigint(20) NOT NULL,
`product_id` bigint(20) NOT NULL,
`deposit_amount_per_period` decimal(19,6) NOT NULL,
`savings_product_type` smallint(5) DEFAULT NULL,
`currency_code` varchar(3) NOT NULL,
`currency_digits` smallint(5) NOT NULL,
`total_deposit_amount` decimal(19,6) NOT NULL,
`reccuring_nominal_interest_rate` decimal(19,6) NOT NULL,
`regular_saving_nominal_interest_rate` decimal(19,6) NOT NULL,
`tenure` int(11) NOT NULL,
`tenure_type` smallint(5) DEFAULT NULL,
`frequency` int(11) DEFAULT NULL,
`interest_type` smallint(5) DEFAULT NULL,
`interest_calculation_method` smallint(5) DEFAULT NULL,
`projected_commencement_date` date NOT NULL,
`actual_commencement_date` date DEFAULT NULL,
`matures_on_date` datetime DEFAULT NULL,
`projected_interest_accrued_on_maturity` decimal(19,6) NOT NULL,
`actual_interest_accrued` decimal(19,6) DEFAULT NULL,
`projected_total_maturity_amount` decimal(19,6) NOT NULL,
`actual_total_amount` decimal(19,6) DEFAULT NULL,
`is_preclosure_allowed` tinyint(1) NOT NULL DEFAULT '0',
`pre_closure_interest_rate` decimal(19,6) NOT NULL,
`is_lock_in_period_allowed` tinyint(1) NOT NULL DEFAULT '0',
`lock_in_period` bigint(20) DEFAULT NULL,
`lock_in_period_type` smallint(5) NOT NULL DEFAULT '1',
`withdrawnon_date` datetime DEFAULT NULL,
`rejectedon_date` datetime DEFAULT NULL,
`closedon_date` datetime DEFAULT NULL,
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `deposit_acc_external_id` (`external_id`),
KEY `FKSA0000000000001` (`client_id`),
KEY `FKSA0000000000002` (`product_id`),
CONSTRAINT `FKSA0000000000001` FOREIGN KEY (`client_id`) REFERENCES `m_client` (`id`),
CONSTRAINT `FKSA0000000000002` FOREIGN KEY (`product_id`) REFERENCES `m_product_savings` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
@@ -0,0 +1,33 @@
DROP TABLE IF EXISTS `m_product_savings`;
CREATE TABLE `m_product_savings` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`description` varchar(500) DEFAULT NULL,
`currency_code` varchar(3) DEFAULT NULL,
`currency_digits` smallint(5) DEFAULT NULL,
`interest_rate` decimal(19,6) DEFAULT NULL,
`min_interest_rate` decimal(19,6) DEFAULT NULL,
`max_interest_rate` decimal(19,6) DEFAULT NULL,
`savings_deposit_amount` decimal(19,6) NOT NULL,
`savings_product_type` smallint(5) DEFAULT NULL,
`tenure_type` smallint(5) DEFAULT NULL,
`tenure` int(11) DEFAULT NULL,
`frequency` int(11) DEFAULT NULL,
`interest_type` smallint(5) DEFAULT NULL,
`interest_calculation_method` smallint(5) DEFAULT NULL,
`min_bal_for_withdrawal` decimal(19,6) NOT NULL,
`is_partial_deposit_allowed` tinyint(1) NOT NULL DEFAULT '0',
`is_lock_in_period_allowed` tinyint(1) NOT NULL DEFAULT '0',
`lock_in_period` bigint(20) DEFAULT NULL,
`lock_in_period_type` smallint(5) NOT NULL DEFAULT '1',
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`createdby_id` bigint(20) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
`lastmodified_date` datetime DEFAULT NULL,
`lastmodifiedby_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKJPW0000000000003` (`createdby_id`),
KEY `FKJPW0000000000004` (`lastmodifiedby_id`),
CONSTRAINT `FKJPW0000000000003` FOREIGN KEY (`createdby_id`) REFERENCES `m_appuser` (`id`),
CONSTRAINT `FKJPW0000000000004` FOREIGN KEY (`lastmodifiedby_id`) REFERENCES `m_appuser` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
@@ -3,6 +3,7 @@ package org.mifosng.platform.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ws.rs.Consumes;
@@ -19,11 +20,21 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.data.CurrencyData;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.EnumOptionData;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
import org.mifosng.platform.currency.service.CurrencyReadPlatformService;
import org.mifosng.platform.savingproduct.domain.SavingFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod;
import org.mifosng.platform.savingproduct.domain.SavingProductType;
import org.mifosng.platform.savingproduct.domain.SavingsInterestType;
import org.mifosng.platform.savingproduct.domain.SavingsLockinPeriodEnum;
import org.mifosng.platform.savingproduct.domain.TenureTypeEnum;
import org.mifosng.platform.savingproduct.service.SavingProductEnumerations;
import org.mifosng.platform.savingproduct.service.SavingProductReadPlatformService;
import org.mifosng.platform.savingproduct.service.SavingProductWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -46,6 +57,9 @@ public class SavingProductsApiResource {
@Autowired
private ApiJsonSerializerService apiJsonSerializerService;
@Autowired
private CurrencyReadPlatformService currencyReadPlatformService;
@POST
@Consumes({MediaType.APPLICATION_JSON})
@@ -75,8 +89,10 @@ public class SavingProductsApiResource {
@Produces({MediaType.APPLICATION_JSON})
public String retrieveAllSavingProducts(@Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn",
"interestRate","currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance"));
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"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
@@ -95,8 +111,10 @@ public class SavingProductsApiResource {
@Produces({MediaType.APPLICATION_JSON})
public String retrieveSavingProductDetails(@PathParam("productId") final Long productId, @Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn",
"interestRate","currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance"));
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"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
@@ -120,7 +138,10 @@ public class SavingProductsApiResource {
public String retrieveNewSavingProductDetails(@Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("id", "name", "description", "createdOn", "lastModifedOn","interestRate","currencyCode","digitsAfterDecimal", "currencyOptions","minimumBalance","maximumBalance"));
Arrays.asList("id", "createdOn", "lastModifedOn",
"locale", "name", "description","currencyCode", "digitsAfterDecimal","interstRate",
"savingsDepositAmount","savingProductType","tenureType","tenure", "frequency","interestType","interestCalculationMethod",
"minimumBalanceForWithdrawal","isPartialDepositAllowed","isLockinPeriodAllowed","lockinPeriod","lockinPeriodType","currencyOptions"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) {
@@ -129,10 +150,42 @@ public class SavingProductsApiResource {
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
SavingProductData savingProduct = this.savingProductReadPlatformService.retrieveNewSavingProductDetails();
savingProduct = handleTemplateRelatedData(responseParameters,savingProduct);
return this.apiJsonSerializerService.serializeSavingProductDataToJson(prettyPrint, responseParameters, savingProduct);
}
private SavingProductData handleTemplateRelatedData(Set<String> responseParameters, SavingProductData savingProduct) {
responseParameters.addAll(Arrays.asList("currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions", "savingFrequencyOptions", "savingsInterestTypeOptions",
"lockinPeriodTypeOptions", "interestCalculationOptions"));
List<CurrencyData> currencyOptions = this.currencyReadPlatformService.retrieveAllowedCurrencies();
EnumOptionData reccuring = SavingProductEnumerations.savingProductType(SavingProductType.RECCURING);
EnumOptionData regular = SavingProductEnumerations.savingProductType(SavingProductType.REGULAR);
List<EnumOptionData> savingsProductTypeOptions = Arrays.asList(reccuring,regular);
EnumOptionData fixed = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.FIXED_PERIOD);
EnumOptionData perpetual = SavingProductEnumerations.tenureTypeEnum(TenureTypeEnum.PERPETUAL);
List<EnumOptionData> tenureTypeOptions = Arrays.asList(fixed,perpetual);
EnumOptionData monthly = SavingProductEnumerations.interestFrequencyType(SavingFrequencyType.MONTHLY);
List<EnumOptionData> savingFrequencyOptions = Arrays.asList(monthly);
EnumOptionData simple = SavingProductEnumerations.savingInterestType(SavingsInterestType.SIMPLE);
EnumOptionData compounding = SavingProductEnumerations.savingInterestType(SavingsInterestType.COMPOUNDING);
List<EnumOptionData> savingsInterestTypeOptions = Arrays.asList(simple,compounding);
EnumOptionData months = SavingProductEnumerations.savingsLockinPeriod(SavingsLockinPeriodEnum.MONTHS);
List<EnumOptionData> lockinPeriodTypeOptions = Arrays.asList(months);
EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL);
EnumOptionData minbal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL);
EnumOptionData monthlyCollection = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION);
List<EnumOptionData> interestCalculationOptions= Arrays.asList(averagebal,minbal,monthlyCollection);
return new SavingProductData(savingProduct,currencyOptions,savingsProductTypeOptions,tenureTypeOptions,savingFrequencyOptions,savingsInterestTypeOptions,lockinPeriodTypeOptions,interestCalculationOptions);
}
@DELETE
@Path("{productId}")
@Consumes({MediaType.APPLICATION_JSON})
@@ -0,0 +1,139 @@
package org.mifosng.platform.api;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.mifosng.platform.api.commands.SavingAccountCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.SavingAccountData;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
import org.mifosng.platform.saving.service.SavingAccountReadPlatformService;
import org.mifosng.platform.saving.service.SavingAccountWritePlatformService;
import org.mifosng.platform.savingproduct.service.SavingProductReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Path("/savingaccounts")
@Component
@Scope("singleton")
public class SavingsAccountApiResource {
@Autowired
private SavingAccountWritePlatformService savingAccountWritePlatformService;
@Autowired
private SavingAccountReadPlatformService savingAccountReadPlatformService;
@Autowired
private SavingProductReadPlatformService savingProductReadPlatformService;
@Autowired
private ApiDataConversionService apiDataConversionService;
@Autowired
private ApiJsonSerializerService apiJsonSerializerService;
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"));
@POST
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response createSavingAccount(final String jsonRequestBody){
final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(null, jsonRequestBody);
EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.createSavingAccount(command);
return Response.ok().entity(entityIdentifier).build();
}
@PUT
@Path("{accountId}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public Response updateSavingAccount(@PathParam("accountId") final Long accountId,final String jsonRequestBody){
final SavingAccountCommand command = this.apiDataConversionService.convertJsonToSavingAccountCommand(accountId, jsonRequestBody);
EntityIdentifier entityIdentifier = this.savingAccountWritePlatformService.updateSavingAccount(command);
return Response.ok().entity(entityIdentifier).build();
}
@GET
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveAllDepositAccounts(@Context final UriInfo uriInfo) {
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();
return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, accounts);
}
@GET
@Path("{accountId}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
public String retrieveDepositAccount(@PathParam("accountId") final Long accountId, @Context final UriInfo uriInfo) {
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);
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) {
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);
return this.apiJsonSerializerService.serializeSavingAccountsDataToJson(prettyPrint, responseParameters, account);
}
}
@@ -0,0 +1,235 @@
package org.mifosng.platform.api.commands;
import java.math.BigDecimal;
import java.util.Set;
import org.joda.time.LocalDate;
public class SavingAccountCommand {
private final Long id;
private final Long clientId;
private final Long productId;
private final String externalId;
private final String currencyCode;
private final Integer digitsAfterDecimal;
private final BigDecimal savingsDepositAmount;
private final BigDecimal recurringInterestRate;
private final BigDecimal savingInterestRate;
private final Integer tenure;
private final boolean isLockinPeriodAllowed;
private final Integer lockinPeriod;
private final Integer lockinPeriodType;
private final LocalDate commencementDate;
private final Integer savingProductType;
private final Integer tenureType;
private final Integer frequency;
private final Integer interestType;
private final Integer interestCalculationMethod;
private final BigDecimal minimumBalanceForWithdrawal;
private final boolean isPartialDepositAllowed;
private final Set<String> modifiedParameters;
public SavingAccountCommand(final Set<String> modifiedParameters,
final Long id,
final Long clientId,
final Long productId,
final String externalId,final String currencyCode, final Integer digitsAfterDecimal,
final BigDecimal savingsDepositAmount,
final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate,
final Integer tenure, final LocalDate commencementDate,
final Integer savingProductType, final Integer tenureType, final Integer frequency, final Integer interestType,
final BigDecimal minimumBalanceForWithdrawal, final Integer interestCalculationMethod,
final boolean isLockinPeriodAllowed, final boolean isPartialDepositAllowed, final Integer lockInPeriod, final Integer lockinPeriodType) {
this.id = id;
this.clientId = clientId;
this.productId = productId;
this.externalId = externalId;
this.currencyCode = currencyCode;
this.digitsAfterDecimal = digitsAfterDecimal;
this.savingsDepositAmount = savingsDepositAmount;
this.recurringInterestRate = recurringInterestRate;
this.savingInterestRate = savingInterestRate;
this.tenure = tenure;
this.modifiedParameters = modifiedParameters;
this.commencementDate = commencementDate;
this.savingProductType=savingProductType;
this.tenureType=tenureType;
this.frequency=frequency;
this.interestType=interestType;
this.isPartialDepositAllowed=isPartialDepositAllowed;
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockInPeriod;
this.lockinPeriodType = lockinPeriodType;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal;
this.interestCalculationMethod=interestCalculationMethod;
}
public Long getId() {
return id;
}
public Long getClientId() {
return clientId;
}
public Long getProductId() {
return productId;
}
public String getExternalId() {
return externalId;
}
public String getCurrencyCode() {
return currencyCode;
}
public Integer getDigitsAfterDecimal() {
return digitsAfterDecimal;
}
public BigDecimal getSavingsDepositAmount() {
return savingsDepositAmount;
}
public BigDecimal getRecurringInterestRate() {
return recurringInterestRate;
}
public BigDecimal getSavingInterestRate() {
return savingInterestRate;
}
public Integer getTenure() {
return tenure;
}
public boolean isLockinPeriodAllowed() {
return isLockinPeriodAllowed;
}
public Integer getLockinPeriod() {
return lockinPeriod;
}
public Integer getLockinPeriodType() {
return lockinPeriodType;
}
public LocalDate getCommencementDate() {
return commencementDate;
}
public Integer getSavingProductType() {
return savingProductType;
}
public Integer getTenureType() {
return tenureType;
}
public Integer getFrequency() {
return frequency;
}
public Integer getInterestType() {
return interestType;
}
public Integer getInterestCalculationMethod() {
return interestCalculationMethod;
}
public BigDecimal getMinimumBalanceForWithdrawal() {
return minimumBalanceForWithdrawal;
}
public boolean isPartialDepositAllowed() {
return isPartialDepositAllowed;
}
public boolean isNoFieldChanged() {
return this.modifiedParameters.isEmpty();
}
public boolean isProductIdChanged(){
return this.modifiedParameters.contains("productId");
}
public boolean isExternalIdChanged(){
return this.modifiedParameters.contains("externalId");
}
public boolean isDepositAmountChanged(){
return this.modifiedParameters.contains("deposit");
}
public boolean isTenureInMonthsChanged() {
return this.modifiedParameters.contains("tenureInMonths");
}
public boolean isLockinPeriodChanged() {
return this.modifiedParameters.contains("lockinPeriod");
}
public boolean isPreClosureInterestRateChanged(){
return this.modifiedParameters.contains("preClosureInterestRate");
}
public boolean isPreClosureAllowedChanged() {
return this.modifiedParameters.contains("preClosureAllowed");
}
public boolean isCommencementDateChanged() {
return this.modifiedParameters.contains("commencementDate");
}
public boolean isTenureTypeEnumChanged() {
return this.modifiedParameters.contains("tenureType");
}
public boolean isSavingProductTypeChanged() {
return this.modifiedParameters.contains("savingProductType");
}
public boolean isSavingFrequencyTypeChanged() {
return this.modifiedParameters.contains("frequency");
}
public boolean isSavingInterestCalculationMethodChanged() {
return this.modifiedParameters.contains("interestCalculationMethod");
}
public boolean isReccuringInterestRateChanged() {
return this.modifiedParameters.contains("recurringInterestRate");
}
public boolean isSavingInterestRateChanged() {
return this.modifiedParameters.contains("savingInterestRate");
}
public boolean isLockinPeriodAllowedChanged() {
return this.modifiedParameters.contains("isLockinPeriodAllowed");
}
public boolean isLockinPeriodTypeChanged() {
return this.modifiedParameters.contains("lockinPeriodType");
}
public boolean isPartialDepositAllowedChanged() {
return this.modifiedParameters.contains("isPartialDepositAllowed");
}
}
@@ -11,16 +11,37 @@ public class SavingProductCommand {
private final String currencyCode;
private final Integer digitsAfterDecimal;
private final BigDecimal interestRate;
private final BigDecimal minInterestRate;
private final BigDecimal maxInterestRate;
private final BigDecimal savingsDepositAmount;
private final Integer savingProductType;
private final Integer tenureType;
private final Integer tenure;
private final Integer frequency;
private final Integer interestType;
private final Integer interestCalculationMethod;
private final BigDecimal minimumBalanceForWithdrawal;
private final boolean isPartialDepositAllowed;
private final boolean isLockinPeriodAllowed;
private final Integer lockinPeriod;
private final Integer lockinPeriodType;
private final BigDecimal minimumBalance;
private final BigDecimal maximumBalance;
private final Set<String> modifiedParameters;
public SavingProductCommand(final Set<String> modifiedParameters,
final Long id, final String name, final String description,
final String currencyCode, final Integer digitsAfterDecimal,
final BigDecimal interestRate, final BigDecimal minimumBalance, final BigDecimal maximumBalance) {
public SavingProductCommand(Set<String> modifiedParameters,
Long id, String name, String description,
String currencyCode, Integer digitsAfterDecimal,
BigDecimal interestRate, BigDecimal minInterestRate,
BigDecimal maxInterestRate, BigDecimal savingsDepositAmount,
Integer savingProductType, Integer tenureType, Integer tenure,
Integer frequency, Integer interestType,
Integer interestCalculationMethod,
BigDecimal minimumBalanceForWithdrawal,
boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed,
Integer lockinPeriod, Integer lockinPeriodType) {
this.id = id;
this.name = name;
this.description = description;
@@ -28,9 +49,21 @@ public class SavingProductCommand {
this.currencyCode = currencyCode;
this.digitsAfterDecimal = digitsAfterDecimal;
this.interestRate = interestRate;
this.minInterestRate = minInterestRate;
this.maxInterestRate = maxInterestRate;
this.minimumBalance=minimumBalance;
this.maximumBalance=maximumBalance;
this.savingsDepositAmount=savingsDepositAmount;
this.savingProductType=savingProductType;
this.tenureType=tenureType;
this.tenure=tenure;
this.frequency=frequency;
this.interestType=interestType;
this.interestCalculationMethod=interestCalculationMethod;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal;
this.isPartialDepositAllowed=isPartialDepositAllowed;
this.isLockinPeriodAllowed=isLockinPeriodAllowed;
this.lockinPeriod=lockinPeriod;
this.lockinPeriodType=lockinPeriodType;
this.modifiedParameters = modifiedParameters;
}
@@ -58,14 +91,61 @@ public class SavingProductCommand {
public BigDecimal getInterestRate() {
return interestRate;
}
public BigDecimal getMinimumBalance() {
return minimumBalance;
public BigDecimal getMinInterestRate() {
return minInterestRate;
}
public BigDecimal getMaximumBalance() {
return maximumBalance;
public BigDecimal getMaxInterestRate() {
return maxInterestRate;
}
public BigDecimal getSavingsDepositAmount() {
return savingsDepositAmount;
}
public Integer getSavingProductType() {
return savingProductType;
}
public Integer getTenureType() {
return tenureType;
}
public Integer getTenure() {
return tenure;
}
public Integer getFrequency() {
return frequency;
}
public Integer getInterestType() {
return interestType;
}
public Integer getInterestCalculationMethod() {
return interestCalculationMethod;
}
public BigDecimal getMinimumBalanceForWithdrawal() {
return minimumBalanceForWithdrawal;
}
public boolean isPartialDepositAllowed() {
return isPartialDepositAllowed;
}
public boolean isLockinPeriodAllowed() {
return isLockinPeriodAllowed;
}
public Integer getLockinPeriod() {
return lockinPeriod;
}
public Integer getLockinPeriodType() {
return lockinPeriodType;
}
public boolean isNameChanged() {
@@ -88,11 +168,52 @@ public class SavingProductCommand {
return this.modifiedParameters.contains("interestRate");
}
public boolean isMinimumBalanceChanged(){
return this.modifiedParameters.contains("minimumBalance");
public boolean isSavingsDepositAmountChanged(){
return this.modifiedParameters.contains("savingsDepositAmount");
}
public boolean isMaximumBalanceChanged(){
return this.modifiedParameters.contains("maximumBalance");
public boolean isSavingProductTypeChanged() {
return this.modifiedParameters.contains("savingProductType");
}
public boolean isTenureTypeChanged() {
return this.modifiedParameters.contains("tenureType");
}
public boolean isTenureChanged() {
return this.modifiedParameters.contains("tenure");
}
public boolean isFrequencyChanged() {
return this.modifiedParameters.contains("frequency");
}
public boolean isInterestTypeChanged() {
return this.modifiedParameters.contains("interestType");
}
public boolean isInterestCalculationMethodChanged() {
return this.modifiedParameters.contains("interestCalculationMethod");
}
public boolean isMinimumBalanceForWithdrawalChanged() {
return this.modifiedParameters.contains("minimumBalanceForWithdrawal");
}
public boolean isPartialDepositAllowedChanged() {
return this.modifiedParameters.contains("isPartialDepositAllowed");
}
public boolean isLockinPeriodAllowedChanged() {
return this.modifiedParameters.contains("isLockinPeriodAllowed");
}
public boolean isLockinPeriodChanged() {
return this.modifiedParameters.contains("lockinPeriod");
}
public boolean isLockinPeriodTypeChanged() {
return this.modifiedParameters.contains("lockinPeriodType");
}
}
@@ -514,7 +514,7 @@ public class DepositAccountData {
if(this.status!=null){
if (account.getStatus().getId() == 300) {
BigDecimal interestGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue()/ new Double(account.getTenureInMonths()));
LocalDate interestWithdrawingDate= new LocalDate().isAfter(getMaturedOn())?getMaturedOn().plusDays(1):new LocalDate();
LocalDate interestWithdrawingDate= new LocalDate().isBefore(getMaturedOn())?new LocalDate():getMaturedOn().plusDays(1);
Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate).getMonths();
Integer noOfPeriods = noOfMonthsforInterestCal/ account.getInterestCompoundedEvery();
@@ -532,7 +532,7 @@ public class DepositAccountData {
BigDecimal avalablePreclosureWithdrawalAmount = BigDecimal.ZERO;
if(this.status != null){
if (account.getStatus().getId() == 300) {
if(new LocalDate().isBefore(account.getMaturedOn())){
if(new LocalDate().isBefore(account.getMaturedOn()) || new LocalDate().isEqual(account.getMaturedOn())){
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
Integer monthsInYear = 12;
BigDecimal interestRateAsFraction = account.getPreClosureInterestRate().divide(BigDecimal.valueOf(100), mc);
@@ -541,7 +541,7 @@ public class DepositAccountData {
Integer days = Days.daysBetween(account.getActualCommencementDate().plusMonths(noOfMonthsforInterestCal), new LocalDate()).getDays();
BigDecimal interest = BigDecimal.valueOf(account.getDeposit().doubleValue()*new Double(noOfMonthsforInterestCal)*interestRateForOneMonth.doubleValue());
avalablePreclosureWithdrawalAmount = interest.add(account.getDeposit()).subtract(account.getInterestPaid()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days));
}else if(new LocalDate().isAfter(account.getMaturedOn()) || new LocalDate().isEqual(account.getMaturedOn())){
}else if(new LocalDate().isAfter(account.getMaturedOn())){
Integer days = Days.daysBetween(account.getMaturedOn(), new LocalDate()).getDays();
avalablePreclosureWithdrawalAmount=determineAvailableInterestForWithdrawal(account).add(account.getDeposit()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days));
}
@@ -14,15 +14,19 @@ public class DepositAccountTransactionData {
private final LocalDate transactionDate;
private final BigDecimal transactionAmount;
private final Long accountId;
private final BigDecimal interestAmount;
private final BigDecimal total;
public DepositAccountTransactionData(
final Long transactionId, final Long accountId, final EnumOptionData transactionType,
final LocalDate transactionDate, final BigDecimal transactionAmount ) {
final LocalDate transactionDate, final BigDecimal transactionAmount, final BigDecimal interstAmount, final BigDecimal total ) {
this.transactionId = transactionId;
this.accountId = accountId;
this.transactionType = transactionType;
this.transactionDate = transactionDate;
this.transactionAmount = transactionAmount;
this.interestAmount = interstAmount;
this.total = total;
}
public Long getAccountId() {
@@ -44,4 +48,12 @@ public class DepositAccountTransactionData {
public BigDecimal getTransactionAmount() {
return transactionAmount;
}
public BigDecimal getInterestAmount() {
return interestAmount;
}
public BigDecimal getTotal() {
return total;
}
}
@@ -0,0 +1,231 @@
package org.mifosng.platform.api.data;
import java.math.BigDecimal;
import org.joda.time.LocalDate;
public class SavingAccountData {
private final Long id;
private final EnumOptionData status;
private final String externalId;
private final Long clientId;
private final String clientName;
private final Long productId;
private final String productName;
private final EnumOptionData productType;
private final CurrencyData currencyData;
private final BigDecimal savingsDepostiAmountPerPeriod;
private final EnumOptionData savingsFrequencyType;
private final BigDecimal totalDepositAmount;
private final BigDecimal reccuringInterestRate;
private final BigDecimal savingInterestRate;
private final EnumOptionData interestType;
private final EnumOptionData interestCalculationMethod;
private final Integer tenure;
private final EnumOptionData tenureType;
private final LocalDate projectedCommencementDate;
private final LocalDate actualCommencementDate;
private final LocalDate maturesOnDate;
private final BigDecimal projectedInterestAccuredOnMaturity;
private final BigDecimal actualInterestAccured;
private final BigDecimal projectedMaturityAmount;
private final BigDecimal actualMaturityAmount;
private final boolean preClosureAllowed;
private final BigDecimal preClosureInterestRate;
private final LocalDate withdrawnonDate;
private final LocalDate rejectedonDate;
private final LocalDate closedonDate;
private final boolean isLockinPeriodAllowed;
private final Integer lockinPeriod;
private final EnumOptionData lockinPeriodType;
public SavingAccountData(Long id, EnumOptionData status, String externalId,
Long clientId, String clientName, Long productId,
String productName, EnumOptionData productType,
CurrencyData currencyData,
BigDecimal savingsDepostiAmountPerPeriod,
EnumOptionData savingsFrequencyType, BigDecimal totalDepositAmount,
BigDecimal reccuringInterestRate, BigDecimal savingInterestRate,
EnumOptionData interestType,
EnumOptionData interestCalculationMethod, Integer tenure,
EnumOptionData tenureType, LocalDate projectedCommencementDate,
LocalDate actualCommencementDate, LocalDate maturesOnDate,
BigDecimal projectedInterestAccuredOnMaturity,
BigDecimal actualInterestAccured,
BigDecimal projectedMaturityAmount,
BigDecimal actualMaturityAmount, boolean preClosureAllowed,
BigDecimal preClosureInterestRate, LocalDate withdrawnonDate,
LocalDate rejectedonDate, LocalDate closedonDate,
boolean isLockinPeriodAllowed, Integer lockinPeriod,
EnumOptionData lockinPeriodType) {
this.id = id;
this.status = status;
this.externalId = externalId;
this.clientId = clientId;
this.clientName = clientName;
this.productId = productId;
this.productName = productName;
this.productType = productType;
this.currencyData = currencyData;
this.savingsDepostiAmountPerPeriod = savingsDepostiAmountPerPeriod;
this.savingsFrequencyType = savingsFrequencyType;
this.totalDepositAmount = totalDepositAmount;
this.reccuringInterestRate = reccuringInterestRate;
this.savingInterestRate = savingInterestRate;
this.interestType =interestType;
this.interestCalculationMethod = interestCalculationMethod;
this.tenure = tenure;
this.tenureType = tenureType;
this.projectedCommencementDate = projectedCommencementDate;
this.actualCommencementDate = actualCommencementDate;
this.maturesOnDate = maturesOnDate;
this.projectedInterestAccuredOnMaturity = projectedInterestAccuredOnMaturity;
this.actualInterestAccured = actualInterestAccured;
this.projectedMaturityAmount = projectedMaturityAmount;
this.actualMaturityAmount =actualMaturityAmount;
this.preClosureAllowed = preClosureAllowed;
this.preClosureInterestRate = preClosureInterestRate;
this.withdrawnonDate = withdrawnonDate;
this.rejectedonDate = rejectedonDate;
this.closedonDate = closedonDate;
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockinPeriod;
this.lockinPeriodType = lockinPeriodType;
}
public Long getId() {
return id;
}
public EnumOptionData getStatus() {
return status;
}
public String getExternalId() {
return externalId;
}
public Long getClientId() {
return clientId;
}
public String getClientName() {
return clientName;
}
public Long getProductId() {
return productId;
}
public String getProductName() {
return productName;
}
public EnumOptionData getProductType() {
return productType;
}
public CurrencyData getCurrencyData() {
return currencyData;
}
public BigDecimal getSavingsDepostiAmountPerPeriod() {
return savingsDepostiAmountPerPeriod;
}
public EnumOptionData getSavingsFrequencyType() {
return savingsFrequencyType;
}
public BigDecimal getTotalDepositAmount() {
return totalDepositAmount;
}
public BigDecimal getReccuringInterestRate() {
return reccuringInterestRate;
}
public BigDecimal getSavingInterestRate() {
return savingInterestRate;
}
public EnumOptionData getInterestType() {
return interestType;
}
public EnumOptionData getInterestCalculationMethod() {
return interestCalculationMethod;
}
public Integer getTenure() {
return tenure;
}
public EnumOptionData getTenureType() {
return tenureType;
}
public LocalDate getProjectedCommencementDate() {
return projectedCommencementDate;
}
public LocalDate getActualCommencementDate() {
return actualCommencementDate;
}
public LocalDate getMaturesOnDate() {
return maturesOnDate;
}
public BigDecimal getProjectedInterestAccuredOnMaturity() {
return projectedInterestAccuredOnMaturity;
}
public BigDecimal getActualInterestAccured() {
return actualInterestAccured;
}
public BigDecimal getProjectedMaturityAmount() {
return projectedMaturityAmount;
}
public BigDecimal getActualMaturityAmount() {
return actualMaturityAmount;
}
public boolean isPreClosureAllowed() {
return preClosureAllowed;
}
public BigDecimal getPreClosureInterestRate() {
return preClosureInterestRate;
}
public LocalDate getWithdrawnonDate() {
return withdrawnonDate;
}
public LocalDate getRejectedonDate() {
return rejectedonDate;
}
public LocalDate getClosedonDate() {
return closedonDate;
}
public boolean isLockinPeriodAllowed() {
return isLockinPeriodAllowed;
}
public Integer getLockinPeriod() {
return lockinPeriod;
}
public EnumOptionData getLockinPeriodType() {
return lockinPeriodType;
}
}
@@ -9,102 +9,226 @@ import org.joda.time.DateTime;
public class SavingProductData implements Serializable {
private Long id;
private String name;
private String description;
private String currencyCode;
private Integer digitsAfterDecimal;
private final Long id;
private final String name;
private final String description;
private final CurrencyData currency;
private final Integer digitsAfterDecimal;
private BigDecimal interestRate = BigDecimal.ZERO;
private BigDecimal minimumBalance = BigDecimal.ZERO;
private BigDecimal maximumBalance = BigDecimal.ZERO;
private final BigDecimal interestRate;
private final BigDecimal minInterestRate;
private final BigDecimal maxInterestRate;
private final BigDecimal savingsDepositAmount;
private final EnumOptionData savingProductType;
private final EnumOptionData tenureType;
private final Integer tenure;
private final EnumOptionData savingFrequencyType;
private final EnumOptionData interestType;
private final EnumOptionData interestCalculationMethod;
private final BigDecimal minimumBalanceForWithdrawal;
private final boolean isPartialDepositAllowed;
private final boolean isLockinPeriodAllowed;
private final Integer lockinPeriod;
private final EnumOptionData lockinPeriodType;
private DateTime createdOn;
private DateTime lastModifedOn;
private List<CurrencyData> currencyOptions = new ArrayList<CurrencyData>();
List<EnumOptionData> savingsProductTypeOptions = new ArrayList<EnumOptionData>();
List<EnumOptionData> tenureTypeOptions = new ArrayList<EnumOptionData>();
List<EnumOptionData> savingFrequencyOptions = new ArrayList<EnumOptionData>();
List<EnumOptionData> savingsInterestTypeOptions = new ArrayList<EnumOptionData>();
List<EnumOptionData> lockinPeriodTypeOptions = new ArrayList<EnumOptionData>();
List<EnumOptionData> interestCalculationOptions = new ArrayList<EnumOptionData>();
public SavingProductData(){
//
this.createdOn=new DateTime();
this.lastModifedOn=new DateTime();
this.id=null;
this.name=null;
this.description=null;
this.interestRate=BigDecimal.ZERO;
this.minInterestRate=BigDecimal.ZERO;
this.maxInterestRate=BigDecimal.ZERO;
this.currency=null;
this.digitsAfterDecimal=null;
this.savingsDepositAmount=null;
this.savingProductType=null;
this.tenureType = null;
this.tenure = null;
this.savingFrequencyType=null;
this.interestType=null;
this.interestCalculationMethod=null;
this.minimumBalanceForWithdrawal=null;
this.isPartialDepositAllowed=true;
this.isLockinPeriodAllowed=true;
this.lockinPeriod=null;
this.lockinPeriodType=null;
}
public SavingProductData(DateTime createdOn, DateTime lastModifedOn, Long id,String name, String description,BigDecimal interestRate,String currencyCode, Integer digitsAfterDecimal,BigDecimal minimumBalance,BigDecimal maximumBalance) {
public SavingProductData(DateTime createdOn, DateTime lastModifedOn,
Long id, String name, String description,
BigDecimal interestRate, BigDecimal minInterestRate, BigDecimal maxInterestRate, CurrencyData currency,
Integer digitsAfterDecimal, BigDecimal savingsDepositAmount,
EnumOptionData savingProductType,
EnumOptionData tenureType, Integer tenure,
EnumOptionData savingFrequencyType,
EnumOptionData savingInterestType,
EnumOptionData interestCalculationMethod,
BigDecimal minimumBalanceForWithdrawal,
boolean isPartialDepositAllowed, boolean isLockinPeriodAllowed,
Integer lockinPeriod, EnumOptionData lockinPeriodType) {
this.createdOn=createdOn;
this.lastModifedOn=lastModifedOn;
this.id=id;
this.name=name;
this.description=description;
this.interestRate=interestRate;
this.currencyCode=currencyCode;
this.minInterestRate=minInterestRate;
this.maxInterestRate=maxInterestRate;
this.currency=currency;
this.digitsAfterDecimal=digitsAfterDecimal;
this.minimumBalance=minimumBalance;
this.maximumBalance=maximumBalance;
this.savingsDepositAmount=savingsDepositAmount;
this.savingProductType=savingProductType;
this.tenureType = tenureType;
this.tenure = tenure;
this.savingFrequencyType=savingFrequencyType;
this.interestType=savingInterestType;
this.interestCalculationMethod=interestCalculationMethod;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal;
this.isPartialDepositAllowed=isPartialDepositAllowed;
this.isLockinPeriodAllowed=isLockinPeriodAllowed;
this.lockinPeriod=lockinPeriod;
this.lockinPeriodType=lockinPeriodType;
}
public SavingProductData(SavingProductData product,
List<CurrencyData> currencyOptions,
List<EnumOptionData> savingsProductTypeOptions,
List<EnumOptionData> tenureTypeOptions,
List<EnumOptionData> savingFrequencyOptions,
List<EnumOptionData> savingsInterestTypeOptions,
List<EnumOptionData> lockinPeriodTypeOptions,
List<EnumOptionData> interestCalculationOptions) {
this.createdOn=product.getCreatedOn();
this.lastModifedOn=product.getLastModifedOn();
this.id=product.getId();
this.name=product.getName();
this.description=product.getDescription();
this.interestRate=product.getInterestRate();
this.minInterestRate=product.getMinInterestRate();
this.maxInterestRate=product.getMaxInterestRate();
this.currency=product.getCurrency();
this.digitsAfterDecimal=product.getDigitsAfterDecimal();
this.savingsDepositAmount=product.getSavingsDepositAmount();
this.savingProductType=product.getSavingProductType();
this.tenureType = product.getTenureType();
this.tenure = product.getTenure();
this.savingFrequencyType=product.getSavingFrequencyType();
this.interestType=product.getInterestType();
this.interestCalculationMethod=product.getInterestCalculationMethod();
this.minimumBalanceForWithdrawal=product.getMinimumBalanceForWithdrawal();
this.isPartialDepositAllowed=product.isPartialDepositAllowed();
this.isLockinPeriodAllowed=product.isLockinPeriodAllowed();
this.lockinPeriod=product.getLockinPeriod();
this.lockinPeriodType=product.getLockinPeriodType();
this.currencyOptions=currencyOptions;
this.savingsProductTypeOptions=savingsProductTypeOptions;
this.tenureTypeOptions=tenureTypeOptions;
this.savingFrequencyOptions=savingFrequencyOptions;
this.savingsInterestTypeOptions=savingsInterestTypeOptions;
this.lockinPeriodTypeOptions=lockinPeriodTypeOptions;
this.interestCalculationOptions=interestCalculationOptions;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
public CurrencyData getCurrency() {
return currency;
}
public DateTime getCreatedOn() {
return createdOn;
public Integer getDigitsAfterDecimal() {
return digitsAfterDecimal;
}
public BigDecimal getInterestRate() {
return interestRate;
}
public void setInterestRate(BigDecimal interestRate) {
this.interestRate = interestRate;
public BigDecimal getMinInterestRate() {
return minInterestRate;
}
public void setCreatedOn(DateTime createdOn) {
this.createdOn = createdOn;
public BigDecimal getMaxInterestRate() {
return maxInterestRate;
}
public BigDecimal getSavingsDepositAmount() {
return savingsDepositAmount;
}
public EnumOptionData getSavingProductType() {
return savingProductType;
}
public EnumOptionData getTenureType() {
return tenureType;
}
public Integer getTenure() {
return tenure;
}
public EnumOptionData getInterestType() {
return interestType;
}
public EnumOptionData getInterestCalculationMethod() {
return interestCalculationMethod;
}
public BigDecimal getMinimumBalanceForWithdrawal() {
return minimumBalanceForWithdrawal;
}
public boolean isPartialDepositAllowed() {
return isPartialDepositAllowed;
}
public boolean isLockinPeriodAllowed() {
return isLockinPeriodAllowed;
}
public Integer getLockinPeriod() {
return lockinPeriod;
}
public EnumOptionData getLockinPeriodType() {
return lockinPeriodType;
}
public DateTime getCreatedOn() {
return createdOn;
}
public DateTime getLastModifedOn() {
return lastModifedOn;
}
public void setLastModifedOn(DateTime lastModifedOn) {
this.lastModifedOn = lastModifedOn;
}
public String getCurrencyCode() {
return currencyCode;
}
public void setCurrencyCode(String currencyCode) {
this.currencyCode = currencyCode;
}
public Integer getDigitsAfterDecimal() {
return digitsAfterDecimal;
}
public void setDigitsAfterDecimal(Integer digitsAfterDecimal) {
this.digitsAfterDecimal = digitsAfterDecimal;
}
public List<CurrencyData> getCurrencyOptions() {
return currencyOptions;
}
@@ -113,20 +237,32 @@ public class SavingProductData implements Serializable {
this.currencyOptions = currencyOptions;
}
public BigDecimal getMinimumBalance() {
return minimumBalance;
public EnumOptionData getSavingFrequencyType() {
return savingFrequencyType;
}
public void setMinimumBalance(BigDecimal minimumBalance) {
this.minimumBalance = minimumBalance;
public List<EnumOptionData> getSavingsProductTypeOptions() {
return savingsProductTypeOptions;
}
public BigDecimal getMaximumBalance() {
return maximumBalance;
public List<EnumOptionData> getTenureTypeOptions() {
return tenureTypeOptions;
}
public void setMaximumBalance(BigDecimal maximumBalance) {
this.maximumBalance = maximumBalance;
public List<EnumOptionData> getSavingFrequencyOptions() {
return savingFrequencyOptions;
}
public List<EnumOptionData> getSavingsInterestTypeOptions() {
return savingsInterestTypeOptions;
}
public List<EnumOptionData> getLockinPeriodTypeOptions() {
return lockinPeriodTypeOptions;
}
public List<EnumOptionData> getInterestCalculationOptions() {
return interestCalculationOptions;
}
}
@@ -24,6 +24,7 @@ import org.mifosng.platform.api.commands.NoteCommand;
import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.api.commands.OrganisationCurrencyCommand;
import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.commands.SavingAccountCommand;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.commands.StaffCommand;
import org.mifosng.platform.api.commands.UserCommand;
@@ -85,4 +86,6 @@ public interface ApiDataConversionService {
CodeCommand convertJsonToCodeCommand(Long resourceIdentifier, String json);
SavingAccountCommand convertJsonToSavingAccountCommand(Long resourceIdentifier,String jsonRequestBody);
}
@@ -41,6 +41,7 @@ import org.mifosng.platform.api.commands.NoteCommand;
import org.mifosng.platform.api.commands.OfficeCommand;
import org.mifosng.platform.api.commands.OrganisationCurrencyCommand;
import org.mifosng.platform.api.commands.RoleCommand;
import org.mifosng.platform.api.commands.SavingAccountCommand;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.api.commands.StaffCommand;
import org.mifosng.platform.api.commands.UserCommand;
@@ -1289,7 +1290,10 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(Arrays.asList("name","description","currencyCode", "digitsAfterDecimal","interestRate","locale","minimumBalance","maximumBalance"));
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"));
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
String name = extractStringParameter("name", requestMap,modifiedParameters);
@@ -1297,11 +1301,25 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
String currencyCode=extractStringParameter("currencyCode", requestMap,modifiedParameters);
Integer digitsAfterDecimalValue = extractIntegerParameter("digitsAfterDecimal", requestMap, modifiedParameters);
BigDecimal interestRate = extractBigDecimalParameter("interestRate", requestMap, modifiedParameters);
BigDecimal minimumBalance=extractBigDecimalParameter("minimumBalance", requestMap, modifiedParameters);
BigDecimal maximumBalance=extractBigDecimalParameter("maximumBalance", requestMap, modifiedParameters);
BigDecimal minInterestRate = extractBigDecimalParameter("minInterestRate", requestMap, modifiedParameters);
BigDecimal maxInterestRate = extractBigDecimalParameter("maxInterestRate", requestMap, modifiedParameters);
BigDecimal savingsDepositAmount=extractBigDecimalParameter("savingsDepositAmount", requestMap, modifiedParameters);
Integer savingProductType = extractIntegerParameter("savingProductType", requestMap, modifiedParameters);
Integer tenureType = extractIntegerParameter("tenureType", requestMap, modifiedParameters);
Integer tenure = extractIntegerParameter("tenure", requestMap, modifiedParameters);
Integer frequency = extractIntegerParameter("frequency", requestMap, modifiedParameters);
Integer interestType = extractIntegerParameter("interestType", requestMap, modifiedParameters);
Integer interestCalculationMethod=extractIntegerParameter("interestCalculationMethod", requestMap, modifiedParameters);
BigDecimal minimumBalanceForWithdrawal=extractBigDecimalParameter("minimumBalanceForWithdrawal", requestMap, modifiedParameters);
boolean isPartialDepositAllowed = extractBooleanParameter("isPartialDepositAllowed", requestMap, modifiedParameters);
boolean isLockinPeriodAllowed = extractBooleanParameter("isLockinPeriodAllowed", requestMap, modifiedParameters);
Integer lockinPeriod = extractIntegerParameter("lockinPeriod", requestMap, modifiedParameters);
Integer lockinPeriodType = extractIntegerParameter("lockinPeriodType", requestMap, modifiedParameters);
return new SavingProductCommand(modifiedParameters, resourceIdentifier,name, description,currencyCode,digitsAfterDecimalValue,interestRate,minimumBalance,maximumBalance);
return new SavingProductCommand(modifiedParameters, resourceIdentifier,name, description,currencyCode,digitsAfterDecimalValue,interestRate, minInterestRate,
maxInterestRate, savingsDepositAmount,savingProductType, tenureType,tenure,frequency,interestType,interestCalculationMethod,minimumBalanceForWithdrawal,
isPartialDepositAllowed, isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
}
@Override
@@ -1553,4 +1571,54 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
@Override
public SavingAccountCommand convertJsonToSavingAccountCommand(Long resourceIdentifier, String json) {
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
// currencyCode, currencyDigits
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("clientId", "productId", "externalId", "currencyCode", "digitsAfterDecimal", "savingsDepositAmountPerPeriod", "recurringInterestRate", "savingInterestRate",
"tenure", "commencementDate", "locale", "dateFormat","isLockinPeriodAllowed","lockinPeriod","lockinPeriodType",
"savingProductType","tenureType", "frequency","interestType","interestCalculationMethod",
"minimumBalanceForWithdrawal","isPartialDepositAllowed" )
);
checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>();
Long clientId = extractLongParameter("clientId", requestMap, modifiedParameters);
Long productId = extractLongParameter("productId", requestMap, modifiedParameters);
String externalId = extractStringParameter("externalId", requestMap,modifiedParameters);
String currencyCode=extractStringParameter("currencyCode", requestMap,modifiedParameters);
Integer digitsAfterDecimalValue = extractIntegerParameter("digitsAfterDecimal", requestMap, modifiedParameters);
BigDecimal savingsDepositAmount=extractBigDecimalParameter("savingsDepositAmountPerPeriod", requestMap, modifiedParameters);
BigDecimal recurringInterestRate = extractBigDecimalParameter("recurringInterestRate", requestMap, modifiedParameters);
BigDecimal savingInterestRate = extractBigDecimalParameter("savingInterestRate", requestMap, modifiedParameters);
Integer tenure = extractIntegerParameter("tenure", requestMap, modifiedParameters);
boolean isLockinPeriodAllowed = extractBooleanParameter("isLockinPeriodAllowed", requestMap, modifiedParameters);
Integer lockinPeriod = extractIntegerParameter("lockinPeriod", requestMap, modifiedParameters);
Integer lockinPeriodType = extractIntegerParameter("lockinPeriodType", requestMap, modifiedParameters);
LocalDate commencementDate = extractLocalDateParameter("commencementDate", requestMap, modifiedParameters);
Integer savingProductType = extractIntegerParameter("savingProductType", requestMap, modifiedParameters);
Integer tenureType = extractIntegerParameter("tenureType", requestMap, modifiedParameters);
Integer frequency = extractIntegerParameter("frequency", requestMap, modifiedParameters);
Integer interestType = extractIntegerParameter("interestType", requestMap, modifiedParameters);
Integer interestCalculationMethod=extractIntegerParameter("interestCalculationMethod", requestMap, modifiedParameters);
BigDecimal minimumBalanceForWithdrawal=extractBigDecimalParameter("minimumBalanceForWithdrawal", requestMap, modifiedParameters);
boolean isPartialDepositAllowed = extractBooleanParameter("isPartialDepositAllowed", requestMap, modifiedParameters);
return new SavingAccountCommand(modifiedParameters, resourceIdentifier, clientId, productId, externalId, currencyCode, digitsAfterDecimalValue,
savingsDepositAmount, recurringInterestRate,savingInterestRate, tenure, commencementDate, savingProductType, tenureType, frequency,
interestType, minimumBalanceForWithdrawal, interestCalculationMethod, isLockinPeriodAllowed, isPartialDepositAllowed, lockinPeriod, lockinPeriodType);
}
}
@@ -32,6 +32,7 @@ import org.mifosng.platform.api.data.OfficeData;
import org.mifosng.platform.api.data.OfficeTransactionData;
import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.api.data.SavingAccountData;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.data.StaffData;
@@ -133,4 +134,8 @@ public interface ApiJsonSerializerService {
String serializeCodeDataToJson(boolean prettyPrint,Set<String> responseParameters, CodeData code);
String serializeSavingAccountsDataToJson(boolean prettyPrint, Set<String> responseParameters, SavingAccountData account);
String serializeSavingAccountsDataToJson(boolean prettyPrint, Set<String> responseParameters, Collection<SavingAccountData> accounts);
}
@@ -34,6 +34,7 @@ import org.mifosng.platform.api.data.OfficeData;
import org.mifosng.platform.api.data.OfficeTransactionData;
import org.mifosng.platform.api.data.PermissionData;
import org.mifosng.platform.api.data.RoleData;
import org.mifosng.platform.api.data.SavingAccountData;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.data.StaffData;
import org.springframework.beans.factory.annotation.Autowired;
@@ -91,10 +92,12 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
"transactionProcessingStrategyOptions", "chargeOptions"));
private static final Set<String> SAVINGS_PRODUCT_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "name", "description", "createdOn",
"lastModifedOn", "interestRate", "currencyCode",
"digitsAfterDecimal", "currencyOptions", "minimumBalance",
"maximumBalance"));
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", "savingFrequencyOptions", "savingsInterestTypeOptions",
"lockinPeriodTypeOptions", "interestCalculationOptions"));
private static final Set<String> SAVINGS_DEPOSIT_PRODUCT_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("currencyOptions",
@@ -203,6 +206,12 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
private static final Set<String> CODE_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "codename"));
private static 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", "preClosureAllowed",
"preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType"));
private final GoogleGsonSerializerHelper helper;
@@ -702,4 +711,25 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
return helper.serializedJsonFrom(gsonDeserializer, code);
}
@Override
public String serializeSavingAccountsDataToJson(boolean prettyPrint,
Set<String> responseParameters, SavingAccountData account) {
final Gson gsonDeserializer = helper
.createGsonBuilderWithParameterExclusionSerializationStrategy(
SAVINGS_ACCOUNTS_DATA_PARAMETERS, prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer, account);
}
@Override
public String serializeSavingAccountsDataToJson(boolean prettyPrint,
Set<String> responseParameters,
Collection<SavingAccountData> accounts) {
final Gson gsonDeserializer = helper
.createGsonBuilderWithParameterExclusionSerializationStrategy(
SAVINGS_ACCOUNTS_DATA_PARAMETERS, prettyPrint, responseParameters);
return helper.serializedJsonFrom(gsonDeserializer,
accounts.toArray(new SavingAccountData[accounts.size()]));
}
}
@@ -0,0 +1,9 @@
package org.mifosng.platform.exceptions;
public class SavingAccountNotFoundException extends AbstractPlatformResourceNotFoundException {
public SavingAccountNotFoundException(final Long id) {
super("error.msg.saving.account.id.invalid", "Saving account with identifier " + id + " does not exist", id);
}
}
@@ -245,7 +245,9 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount();
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
this.depositStatus=depositStatus;
this.interstPaid = BigDecimal.ZERO;
this.interestAccrued=BigDecimal.ZERO;
this.interstPaid=BigDecimal.ZERO;
this.total=BigDecimal.ZERO;
}
private void setExternalId(final String externalId) {
@@ -677,6 +679,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockinPeriod;
this.lockinPeriodType = lockinPeriodType;
this.interestAccrued=BigDecimal.ZERO;
}
@@ -0,0 +1,76 @@
package org.mifosng.platform.saving.domain;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import org.joda.time.LocalDate;
import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.savingproduct.domain.SavingFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod;
import org.mifosng.platform.savingproduct.domain.TenureTypeEnum;
import org.springframework.stereotype.Service;
@Service
public class ReccuringDepositInterestCalculator {
public Money calculateInterestOnMaturityFor(Money savingsDepositPerPeriod,
Integer tenure, BigDecimal reccuringInterestRate,
LocalDate commencementDate, TenureTypeEnum tenureTypeEnum,
SavingFrequencyType savingFrequencyType,
SavingInterestCalculationMethod savingInterestCalculationMethod) {
/*
// Assuming tenure in months
// see http://www.onemint.com/2012/04/03/how-to-calculate-interest-on-recurring-deposits/
A=P(1+r/n)^nt
A = final amount
P = principal amount (initial investment)
r = annual nominal interest rate (as a decimal, not in percentage)
n = number of times the interest is compounded per year
t = number of years
*/
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
Integer monthsInYear = 12;
BigDecimal interestRateAsFraction = reccuringInterestRate.divide(BigDecimal.valueOf(100), mc);
Integer noofTimesInterestCompoundPerYear = Integer.valueOf(0);
switch (savingFrequencyType) {
case MONTHLY:
noofTimesInterestCompoundPerYear = monthsInYear;
break;
case QUATERLY:
noofTimesInterestCompoundPerYear = monthsInYear/3;
break;
case HALFYEARLY:
noofTimesInterestCompoundPerYear = monthsInYear/6;
break;
case YEARLY:
noofTimesInterestCompoundPerYear = monthsInYear/12;
break;
default:
throw new RuntimeException("The specified frequency not supported");
}
BigDecimal interestRatePerPeriod = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/noofTimesInterestCompoundPerYear.doubleValue());
BigDecimal onePlusInterestRatePerPeriod = BigDecimal.ONE.add(interestRatePerPeriod);
BigDecimal monthsExpressedInYears;
BigDecimal timeforOneCalculationPeriod;
BigDecimal amountPerPeriod;
BigDecimal finalAmount = BigDecimal.ZERO;
while (tenure > 0) {
monthsExpressedInYears = BigDecimal.valueOf(tenure.doubleValue()/monthsInYear.doubleValue());
timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear*monthsExpressedInYears.doubleValue());
amountPerPeriod = savingsDepositPerPeriod.getAmount().multiply(BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(), timeforOneCalculationPeriod.doubleValue())));
finalAmount=finalAmount.add(amountPerPeriod);
tenure--;
}
return Money.of(savingsDepositPerPeriod.getCurrency(), finalAmount);
}
}
@@ -0,0 +1,344 @@
package org.mifosng.platform.saving.domain;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
import org.joda.time.LocalDate;
import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod;
import org.mifosng.platform.savingproduct.domain.SavingProduct;
import org.mifosng.platform.savingproduct.domain.SavingProductType;
import org.mifosng.platform.savingproduct.domain.SavingsInterestType;
import org.mifosng.platform.savingproduct.domain.TenureTypeEnum;
import org.mifosng.platform.user.domain.AppUser;
@Entity
@Table(name = "m_saving_account", uniqueConstraints = @UniqueConstraint(name="saving_acc_external_id", columnNames = { "external_id" }))
public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@JoinColumn(name = "client_id", nullable = false)
private Client client;
@ManyToOne
@JoinColumn(name = "product_id")
private SavingProduct product;
@Column(name = "savings_product_type", nullable=false)
private SavingProductType savingProductType;
@Column(name = "external_id")
private String externalId;
@Embedded
private MonetaryCurrency currency;
@Column(name = "deposit_amount_per_period", scale = 6, precision = 19, nullable = false)
private BigDecimal savingsDepositAmountPerPeriod;
@Column(name = "total_deposit_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal totalSavingsAmount;
@Column(name = "reccuring_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal reccuringInterestRate;
@Column(name = "regular_saving_nominal_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal savingInterestRate;
@Column(name = "tenure", nullable=false)
private Integer tenure;
@Column(name = "tenure_type", nullable=false)
private TenureTypeEnum tenureType;
@Column(name = "frequency", nullable=false)
private SavingFrequencyType frequency;
@Column(name = "interest_type", nullable=false)
private SavingsInterestType interestType;
@Column(name = "interest_calculation_method")
private SavingInterestCalculationMethod interestCalculationMethod;
@Temporal(TemporalType.DATE)
@Column(name = "projected_commencement_date")
private Date projectedCommencementDate;
@Temporal(TemporalType.DATE)
@Column(name = "actual_commencement_date")
private Date actualCommencementDate;
@Temporal(TemporalType.DATE)
@Column(name = "matures_on_date")
private Date maturesOnDate;
@Column(name = "projected_interest_accrued_on_maturity", scale = 6, precision = 19, nullable = false)
private BigDecimal projectedInterestAccruedOnMaturity;
@Column(name = "actual_interest_accrued", scale = 6, precision = 19, nullable = false)
private BigDecimal interestAccrued;
@Column(name = "projected_total_maturity_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal projectedTotalOnMaturity;
@Column(name = "actual_total_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal total;
@Column(name = "pre_closure_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal preClosureInterestRate;
@Column(name = "is_preclosure_allowed", nullable = false)
private boolean preClosureAllowed = false;
@Column(name = "is_deleted", nullable=false)
private boolean deleted = false;
@Column(name = "status_enum", nullable = false)
private Integer accountStatus;
@Temporal(TemporalType.DATE)
@Column(name = "closedon_date")
private Date closedOnDate;
@Temporal(TemporalType.DATE)
@Column(name = "rejectedon_date")
private Date rejectedOnDate;
@Temporal(TemporalType.DATE)
@Column(name = "withdrawnon_date")
private Date withdrawnOnDate;
@Column(name = "is_lock_in_period_allowed", nullable=false)
private boolean isLockinPeriodAllowed = false;
@Column(name = "lock_in_period", nullable=false)
private Integer lockinPeriod;
@Column(name = "lock_in_period_type", nullable=false)
private PeriodFrequencyType lockinPeriodType;
public static SavingAccount openNew(
Client client,
SavingProduct product,
String externalId,
Money savingsDeposit,
BigDecimal reccuringInterestRate,
BigDecimal savingInterestRate,
Integer tenure,
LocalDate commencementDate,
TenureTypeEnum tenureTypeEnum,
SavingProductType savingProductType,
SavingFrequencyType savingFrequencyType,
SavingsInterestType interestType,
SavingInterestCalculationMethod savingInterestCalculationMethod,
boolean isLockinPeriodAllowed,
Integer lockinPeriod,
PeriodFrequencyType lockinPeriodType,
ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,
final DepositLifecycleStateMachine lifecycleStateMachine) {
Money futureValueOnMaturity = null;
if(savingProductType.isReccuring()){
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, reccuringInterestRate,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
} else if(savingProductType.isRegular()){
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, savingInterestRate,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
}
return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure,
commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, interestType, savingInterestCalculationMethod,
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, futureValueOnMaturity, lifecycleStateMachine);
}
public SavingAccount(Client client, String externalId,
SavingProduct product, Money savingsDeposit,
BigDecimal reccuringInterestRate, BigDecimal savingInterestRate,
Integer tenure, LocalDate commencementDate,
TenureTypeEnum tenureTypeEnum,
SavingProductType savingProductType,
SavingFrequencyType savingFrequencyType, SavingsInterestType interestType,
SavingInterestCalculationMethod savingInterestCalculationMethod,
boolean isLockinPeriodAllowed, Integer lockinPeriod,
PeriodFrequencyType lockinPeriodType, Money futureValueOnMaturity,
final DepositLifecycleStateMachine lifecycleStateMachine) {
DepositAccountStatus from = null;
if (accountStatus != null) {
from = DepositAccountStatus.fromInt(accountStatus);
}
DepositAccountStatus statusEnum = lifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CREATED, from);
accountStatus = statusEnum.getValue();
this.total=BigDecimal.ZERO;
this.preClosureInterestRate=BigDecimal.ZERO;
this.totalSavingsAmount = BigDecimal.ZERO;
this.interestAccrued = BigDecimal.ZERO;
this.client = client;
this.externalId = externalId;
this.product = product;
this.savingsDepositAmountPerPeriod = savingsDeposit.getAmount();
this.currency = savingsDeposit.getCurrency();
this.reccuringInterestRate = reccuringInterestRate;
this.savingInterestRate = savingInterestRate;
this.tenure =tenure;
this.projectedCommencementDate=commencementDate.toDate();
this.tenureType = tenureTypeEnum;
this.savingProductType = savingProductType;
this.frequency = savingFrequencyType;
this.interestType = interestType;
this.interestCalculationMethod= savingInterestCalculationMethod;
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockinPeriod;
this.lockinPeriodType = lockinPeriodType;
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
this.projectedInterestAccruedOnMaturity =futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue()*tenure.doubleValue()));
}
public void modifyAccount(
SavingProduct product,
String externalId,
Money savingsDeposit,
BigDecimal reccuringInterestRate,
BigDecimal savingInterestRate,
Integer tenure,
LocalDate commencementDate,
TenureTypeEnum tenureTypeEnum,
SavingProductType savingProductType,
SavingFrequencyType savingFrequencyType,
SavingInterestCalculationMethod savingInterestCalculationMethod,
boolean isLockinPeriodAllowed,
Integer lockinPeriod,
PeriodFrequencyType lockinPeriodType,
ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) {
Money futureValueOnMaturity = null;
if(savingProductType.isReccuring()){
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, reccuringInterestRate,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
} else if(savingProductType.isRegular()){
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure, savingInterestRate,
commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod);
}
this.product = product;
this.externalId=externalId;
this.savingsDepositAmountPerPeriod=savingsDeposit.getAmount();
this.reccuringInterestRate=reccuringInterestRate;
this.savingInterestRate = savingInterestRate;
this.tenure = tenure;
this.projectedCommencementDate = commencementDate.toDate();
this.tenureType = tenureTypeEnum;
this.savingProductType = savingProductType;
this.frequency =savingFrequencyType;
this.interestCalculationMethod = savingInterestCalculationMethod;
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
this.lockinPeriod = lockinPeriod;
this.lockinPeriodType = lockinPeriodType;
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
this.projectedInterestAccruedOnMaturity =futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue()*tenure.doubleValue()));
}
public boolean isDeleted() {
return this.deleted;
}
public boolean isPendingApproval() {
return this.accountStatus.equals(100);
}
public Client getClient() {
return client;
}
public SavingProduct getProduct() {
return product;
}
public SavingProductType getSavingProductType() {
return savingProductType;
}
public String getExternalId() {
return externalId;
}
public BigDecimal getSavingsDepositAmountPerPeriod() {
return savingsDepositAmountPerPeriod;
}
public BigDecimal getReccuringInterestRate() {
return reccuringInterestRate;
}
public BigDecimal getSavingInterestRate() {
return savingInterestRate;
}
public Integer getTenure() {
return tenure;
}
public TenureTypeEnum getTenureType() {
return tenureType;
}
public SavingFrequencyType getFrequency() {
return frequency;
}
public SavingsInterestType getInterestType() {
return interestType;
}
public SavingInterestCalculationMethod getInterestCalculationMethod() {
return interestCalculationMethod;
}
public Date getProjectedCommencementDate() {
return projectedCommencementDate;
}
public BigDecimal getPreClosureInterestRate() {
return preClosureInterestRate;
}
public boolean isPreClosureAllowed() {
return preClosureAllowed;
}
public Date getWithdrawnOnDate() {
return withdrawnOnDate;
}
public boolean isLockinPeriodAllowed() {
return isLockinPeriodAllowed;
}
public Integer getLockinPeriod() {
return lockinPeriod;
}
public PeriodFrequencyType getLockinPeriodType() {
return lockinPeriodType;
}
}
@@ -0,0 +1,10 @@
package org.mifosng.platform.saving.domain;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface SavingAccountRepository extends
JpaRepository<SavingAccount, Long>,
JpaSpecificationExecutor<SavingAccount>{
}
@@ -217,7 +217,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
private static final class DepositAccountTransactionMapper implements RowMapper<DepositAccountTransactionData>{
public String schema() {
return " txn.id as transactionId, txn.deposit_account_id as accountId, txn.transaction_type_enum as transactionType, txn.transaction_date as transactionDate, txn.amount as transactionAmount "
return " txn.id as transactionId, txn.deposit_account_id as accountId, txn.transaction_type_enum as transactionType, txn.transaction_date as transactionDate, txn.amount as transactionAmount, txn.interest as interestAmount "
+ " from m_deposit_account_transaction txn";
}
@@ -231,8 +231,10 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
EnumOptionData transactionType=DepositAccountTransactionEnumerations.depositType(transactionTypeValue);
LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate");
BigDecimal transactionAmount = rs.getBigDecimal("transactionAmount");
BigDecimal interestAmount = rs.getBigDecimal("interestAmount");
BigDecimal total = transactionAmount.add(interestAmount);
return new DepositAccountTransactionData(transactionId, accountId, transactionType, transactionDate, transactionAmount);
return new DepositAccountTransactionData(transactionId, accountId, transactionType, transactionDate, transactionAmount, interestAmount, total);
}
}
@@ -243,7 +245,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
boolean undoApprovalAllowed = (depositAccountData.getStatus().getId().equals(300L));
boolean renewelAllowed = false;
if(depositAccountData.getMaturedOn()!=null){
if(new LocalDate().isAfter(depositAccountData.getMaturedOn())||depositAccountData.getMaturedOn().isEqual(new LocalDate())){
if(new LocalDate().isAfter(depositAccountData.getMaturedOn())/*||depositAccountData.getMaturedOn().isEqual(new LocalDate())*/){
renewelAllowed = depositAccountData.isRenewalAllowed();
}
}
@@ -0,0 +1,209 @@
package org.mifosng.platform.saving.service;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import org.joda.time.LocalDate;
import org.mifosng.platform.api.commands.SavingAccountCommand;
import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.currency.domain.Money;
import org.mifosng.platform.exceptions.ClientNotFoundException;
import org.mifosng.platform.exceptions.ProductNotFoundException;
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.saving.domain.DepositAccountStatus;
import org.mifosng.platform.saving.domain.DepositLifecycleStateMachine;
import org.mifosng.platform.saving.domain.DepositLifecycleStateMachineImpl;
import org.mifosng.platform.saving.domain.ReccuringDepositInterestCalculator;
import org.mifosng.platform.saving.domain.SavingAccount;
import org.mifosng.platform.savingproduct.domain.SavingFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod;
import org.mifosng.platform.savingproduct.domain.SavingProduct;
import org.mifosng.platform.savingproduct.domain.SavingProductRepository;
import org.mifosng.platform.savingproduct.domain.SavingProductType;
import org.mifosng.platform.savingproduct.domain.SavingsInterestType;
import org.mifosng.platform.savingproduct.domain.TenureTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class SavingAccountAssembler {
private final ClientRepository clientRepository;
private final SavingProductRepository savingProductRepository;
private final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator;
@Autowired
public SavingAccountAssembler(final ClientRepository clientRepository,final SavingProductRepository savingProductRepository,
final ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) {
this.clientRepository=clientRepository;
this.savingProductRepository=savingProductRepository;
this.reccuringDepositInterestCalculator=reccuringDepositInterestCalculator;
}
//minimumBalanceForWithdrawal,isPartialDepositAllowed
public SavingAccount assembleFrom(SavingAccountCommand command){
Client client = this.clientRepository.findOne(command.getClientId());
if (client == null || client.isDeleted()) {
throw new ClientNotFoundException(command.getClientId());
}
SavingProduct product=this.savingProductRepository.findOne(command.getProductId());
if(product == null || product.isDeleted()){
throw new ProductNotFoundException(command.getProductId());
}
MonetaryCurrency currency = product.getCurrency();
if(command.getCurrencyCode() != null && command.getDigitsAfterDecimal() != null){
currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
}
Money savingsDeposit = Money.of(currency, command.getSavingsDepositAmount());
Integer tenure = product.getSavingProductRelatedDetail().getTenure();
if(command.getTenure() != null){
tenure=command.getTenure();
}
TenureTypeEnum tenureTypeEnum=product.getSavingProductRelatedDetail().getTenureType();
if (command.getTenureType() != null) {
tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType());
}
SavingProductType savingProductType= product.getSavingProductRelatedDetail().getSavingProductType();
if(command.getSavingProductType() != null){
savingProductType = SavingProductType.fromInt(command.getSavingProductType());
}
SavingFrequencyType savingFrequencyType = product.getSavingProductRelatedDetail().getFrequency();
if (command.getFrequency() != null) {
savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency());
}
SavingInterestCalculationMethod savingInterestCalculationMethod = product.getSavingProductRelatedDetail().getInterestCalculationMethod();
if (command.getInterestCalculationMethod() != null) {
savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod());
}
SavingsInterestType interestType = product.getSavingProductRelatedDetail().getInterestType();
if (command.getInterestType() != null) {
interestType = SavingsInterestType.fromInt(command.getInterestType());
}
BigDecimal reccuringInterestRate = command.getRecurringInterestRate();
BigDecimal savingInterestRate = product.getInterestRate();
if(command.getSavingInterestRate() != null)
savingInterestRate = command.getSavingInterestRate();
boolean isLockinPeriodAllowed = product.getSavingProductRelatedDetail().isLockinPeriodAllowed();
if(command.isLockinPeriodChanged()){
isLockinPeriodAllowed = command.isLockinPeriodAllowed();
}
Integer lockinPeriod = product.getSavingProductRelatedDetail().getLockinPeriod();
if(command.getLockinPeriod() != null){
lockinPeriod = command.getLockinPeriod();
}
PeriodFrequencyType lockinPeriodType = product.getSavingProductRelatedDetail().getLockinPeriodType();
if(command.getLockinPeriodType() != null){
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
}
SavingAccount account = SavingAccount.openNew(client, product, command.getExternalId(),savingsDeposit,
reccuringInterestRate,savingInterestRate,tenure,command.getCommencementDate(),tenureTypeEnum, savingProductType,
savingFrequencyType, interestType, savingInterestCalculationMethod, isLockinPeriodAllowed,lockinPeriod, lockinPeriodType,
this.reccuringDepositInterestCalculator, defaultDepositLifecycleStateMachine());
return account;
}
public void assembleFrom(SavingAccountCommand command, SavingAccount account) {
SavingProduct product=account.getProduct();
if(command.isProductIdChanged()){
if(product.getId() != command.getProductId()){
product = this.savingProductRepository.findOne(command.getProductId());
if(product == null || product.isDeleted())
throw new ProductNotFoundException(command.getProductId());
}
}
String externalId = account.getExternalId();
if(command.isExternalIdChanged()){
externalId = command.getExternalId();
}
Money savingsDeposit = Money.of(product.getCurrency(), account.getSavingsDepositAmountPerPeriod());
if(command.isDepositAmountChanged()){
savingsDeposit = Money.of(product.getCurrency(), command.getSavingsDepositAmount());
}
Integer tenure = account.getTenure();
if(command.isTenureInMonthsChanged()){
tenure = command.getTenure();
}
LocalDate commencementDate = new LocalDate(account.getProjectedCommencementDate());
if (command.isCommencementDateChanged()) {
commencementDate = command.getCommencementDate();
}
TenureTypeEnum tenureTypeEnum=account.getTenureType();
if(command.isTenureTypeEnumChanged()){
tenureTypeEnum = TenureTypeEnum.fromInt(command.getTenureType());
}
SavingProductType savingProductType= account.getSavingProductType();
if (command.isSavingProductTypeChanged()) {
savingProductType = SavingProductType.fromInt(command.getSavingProductType());
}
SavingFrequencyType savingFrequencyType = account.getFrequency();
if (command.isSavingFrequencyTypeChanged()) {
savingFrequencyType = SavingFrequencyType.fromInt(command.getFrequency());
}
SavingInterestCalculationMethod savingInterestCalculationMethod =account.getInterestCalculationMethod();
if (command.isSavingInterestCalculationMethodChanged()) {
savingInterestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod());
}
BigDecimal reccuringInterestRate = account.getReccuringInterestRate();
if (command.isReccuringInterestRateChanged()) {
reccuringInterestRate = command.getRecurringInterestRate();
}
BigDecimal savingInterestRate = account.getSavingInterestRate();
if (command.isSavingInterestRateChanged()) {
savingInterestRate = command.getSavingInterestRate();
}
boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed();
if (command.isLockinPeriodAllowedChanged()) {
isLockinPeriodAllowed = command.isLockinPeriodAllowed();
}
Integer lockinPeriod =account.getLockinPeriod();
if (command.isLockinPeriodChanged()) {
lockinPeriod = command.getLockinPeriod();
}
PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType();
if (command.isLockinPeriodTypeChanged()) {
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
}
account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure,
commencementDate, tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod,
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator);
}
private DepositLifecycleStateMachine defaultDepositLifecycleStateMachine() {
List<DepositAccountStatus> allowedDepositStatuses = Arrays.asList(DepositAccountStatus.values());
return new DepositLifecycleStateMachineImpl(allowedDepositStatuses);
}
}
@@ -0,0 +1,94 @@
package org.mifosng.platform.saving.service;
import java.util.ArrayList;
import java.util.List;
import org.mifosng.platform.DataValidatorBuilder;
import org.mifosng.platform.api.commands.SavingAccountCommand;
import org.mifosng.platform.api.data.ApiParameterError;
import org.mifosng.platform.exceptions.PlatformApiDataValidationException;
public class SavingAccountCommandValidator {
private final SavingAccountCommand command;
public SavingAccountCommandValidator(final SavingAccountCommand command) {
this.command = command;
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account");
baseDataValidator.reset().parameter("clientId").value(command.getClientId()).notNull();
baseDataValidator.reset().parameter("productId").value(command.getProductId()).notNull();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(command.getSavingsDepositAmount()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("recurringInterestRate").value(command.getRecurringInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate());
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).notNull();
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull();
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull();
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull();
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).notNull();
baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).notNull();
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).notNull();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).notNull();
baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).notNull();
baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).notNull();
baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).notNull();
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("saving.account");
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
baseDataValidator.reset().parameter("clientId").value(command.getClientId()).ignoreIfNull().notNull();
baseDataValidator.reset().parameter("productId").value(command.getProductId()).ignoreIfNull().notNull();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("savingsDepositAmountPerPeriod").value(command.getSavingsDepositAmount()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("recurringInterestRate").value(command.getRecurringInterestRate()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate());
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).ignoreIfNull();
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull();
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull();
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull();
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).ignoreIfNull();
baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).ignoreIfNull();
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).ignoreIfNull();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).ignoreIfNull();
baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).ignoreIfNull();
baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).ignoreIfNull();
baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull();
baseDataValidator.reset().parameter("commencementDate").value(command.getCommencementDate()).ignoreIfNull();
if (command.isNoFieldChanged()) {
StringBuilder validationErrorCode = new StringBuilder("validation.msg.").append("deposit.account").append(".no.parameters.for.update");
StringBuilder defaultEnglishMessage = new StringBuilder("No parameters passed for update.");
ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(), "id");
dataValidationErrors.add(error);
}
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
}
@@ -0,0 +1,15 @@
package org.mifosng.platform.saving.service;
import java.util.Collection;
import org.mifosng.platform.api.data.SavingAccountData;
public interface SavingAccountReadPlatformService {
Collection<SavingAccountData> retrieveAllSavingsAccounts();
SavingAccountData retrieveSavingsAccount(Long accountId);
SavingAccountData retrieveNewSavingsAccountDetails(Long clientId, Long productId);
}
@@ -0,0 +1,160 @@
package org.mifosng.platform.saving.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import org.joda.time.LocalDate;
import org.mifosng.platform.api.data.CurrencyData;
import org.mifosng.platform.api.data.EnumOptionData;
import org.mifosng.platform.api.data.SavingAccountData;
import org.mifosng.platform.client.service.ClientReadPlatformService;
import org.mifosng.platform.infrastructure.JdbcSupport;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.savingproduct.service.SavingProductEnumerations;
import org.mifosng.platform.savingproduct.service.SavingProductReadPlatformService;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
@Service
public class SavingAccountReadPlatformServiceImpl implements
SavingAccountReadPlatformService {
private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate;
private final SavingProductReadPlatformService savingProductReadPlatformService;
private final ClientReadPlatformService clientReadPlatformService;
@Autowired
public SavingAccountReadPlatformServiceImpl(
final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource,
SavingProductReadPlatformService savingProductReadPlatformService,
final ClientReadPlatformService clientReadPlatformService ) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.savingProductReadPlatformService = savingProductReadPlatformService;
this.clientReadPlatformService = clientReadPlatformService;
}
@Override
public Collection<SavingAccountData> retrieveAllSavingsAccounts() {
this.context.authenticatedUser();
SavingAccountMapper mapper = new SavingAccountMapper();
String sql = "select " + mapper.schema() + " where sa.is_deleted=0";
return this.jdbcTemplate.query(sql,mapper, new Object[]{});
}
@Override
public SavingAccountData retrieveSavingsAccount(Long accountId) {
this.context.authenticatedUser();
SavingAccountMapper mapper = new SavingAccountMapper();
String sql = "select " + mapper.schema() + " where sa.id = ? and sa.is_deleted=0";
SavingAccountData savingAccountData = this.jdbcTemplate.queryForObject(sql,mapper, new Object[]{accountId});
return savingAccountData;
}
@Override
public SavingAccountData retrieveNewSavingsAccountDetails(Long clientId,
Long productId) {
// TODO Auto-generated method stub
return null;
}
private static final class SavingAccountMapper implements RowMapper<SavingAccountData> {
public String schema() {
return "sa.id AS id, sa.status_enum AS status, sa.external_id AS externalId,"
+ " sa.client_id AS clientId, sa.product_id AS productId, sa.deposit_amount_per_period AS savingsDepostiAmountPerPeriod,"
+ " sa.savings_product_type AS savingsProductType, sa.currency_code AS currencyCode, sa.currency_digits AS currencyDigits,"
+ " sa.total_deposit_amount AS totalDepositAmount, sa.reccuring_nominal_interest_rate AS reccuringInterestRate,"
+ " sa.regular_saving_nominal_interest_rate AS savingInterestRate, sa.tenure AS tenure, sa.tenure_type AS tenureType,"
+ " sa.frequency AS savingsFrequencyType, sa.interest_type AS interestType, sa.interest_calculation_method AS interestCalculationMethod,"
+ " sa.projected_commencement_date AS projectedCommencementDate, sa.actual_commencement_date AS actualCommencementDate,"
+ " sa.matures_on_date AS maturesOnDate, sa.projected_interest_accrued_on_maturity AS projectedInterestAccuredOnMaturity,"
+ " sa.actual_interest_accrued AS actualInterestAccured, sa.projected_total_maturity_amount AS projectedTotalMaturityAmount,"
+ " sa.actual_total_amount AS actualTotalAmount, sa.is_preclosure_allowed AS isPreclosureAllowed,"
+ " sa.pre_closure_interest_rate AS preClosureInterestRate, sa.is_lock_in_period_allowed AS isLockinPeriodAllowed,"
+ " sa.lock_in_period AS lockinPeriod, sa.lock_in_period_type AS lockinPeriodType, sa.withdrawnon_date AS withdrawnonDate,"
+ " sa.rejectedon_date AS rejectedonDate, sa.closedon_date AS closedonDate, ps.name AS productName,"
+ " c.firstname AS firstname, c.lastname AS lastname, curr.name AS currencyName, "
+ " curr.internationalized_name_code AS currencyNameCode, curr.display_symbol AS currencyDisplaySymbol "
+ " FROM m_saving_account sa "
+ " JOIN m_client c ON c.id = sa.client_id"
+ " JOIN m_currency curr ON curr.code = sa.currency_code "
+ " JOIN m_product_savings ps ON sa.product_id = ps.id ";
}
@Override
public SavingAccountData mapRow(ResultSet rs, int rowNum) throws SQLException {
Long id = rs.getLong("id");
String externalId = rs.getString("externalId");
Long clientId = rs.getLong("clientId");
String clientName = rs.getString("firstname") + " " + rs.getString("lastname");
Long productId = rs.getLong("productId");
String productName = rs.getString("productName");
EnumOptionData productType = SavingProductEnumerations.savingProductType(JdbcSupport.getInteger(rs, "savingsProductType"));
Integer statusId = JdbcSupport.getInteger(rs, "status");
EnumOptionData status = DepositAccountEnumerations.status(statusId);
String currencyCode = rs.getString("currencyCode");
String currencyName = rs.getString("currencyName");
String currencyNameCode = rs.getString("currencyNameCode");
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
Integer currencyDigits = JdbcSupport.getInteger(rs,"currencyDigits");
CurrencyData currencyData = new CurrencyData(currencyCode,currencyName, currencyDigits, currencyDisplaySymbol,currencyNameCode);
BigDecimal savingsDepostiAmountPerPeriod = rs.getBigDecimal("savingsDepostiAmountPerPeriod");
EnumOptionData savingsFrequencyType = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs, "savingsFrequencyType"));
BigDecimal totalDepositAmount = rs.getBigDecimal("totalDepositAmount");
BigDecimal reccuringInterestRate = rs.getBigDecimal("reccuringInterestRate");
BigDecimal savingInterestRate = rs.getBigDecimal("savingInterestRate");
EnumOptionData interestType = SavingProductEnumerations.savingInterestType(JdbcSupport.getInteger(rs, "interestType"));
EnumOptionData interestCalculationMethod = SavingProductEnumerations.savingInterestCalculationMethod(JdbcSupport.getInteger(rs, "interestCalculationMethod"));
Integer tenure = JdbcSupport.getInteger(rs,"tenure");
EnumOptionData tenureType = SavingProductEnumerations.tenureTypeEnum(JdbcSupport.getInteger(rs, "tenureType"));
LocalDate projectedCommencementDate = JdbcSupport.getLocalDate(rs, "projectedCommencementDate");
LocalDate actualCommencementDate = JdbcSupport.getLocalDate(rs, "actualCommencementDate");
LocalDate maturesOnDate = JdbcSupport.getLocalDate(rs, "maturesOnDate");
BigDecimal projectedInterestAccuredOnMaturity = rs.getBigDecimal("projectedInterestAccuredOnMaturity");
BigDecimal actualInterestAccured = rs.getBigDecimal("actualInterestAccured");
BigDecimal projectedMaturityAmount = rs.getBigDecimal("projectedTotalMaturityAmount");
BigDecimal actualMaturityAmount = rs.getBigDecimal("actualTotalAmount");
boolean preClosureAllowed = rs.getBoolean("isPreclosureAllowed");
BigDecimal preClosureInterestRate = rs.getBigDecimal("preClosureInterestRate");
LocalDate withdrawnonDate = JdbcSupport.getLocalDate(rs, "withdrawnonDate");
LocalDate rejectedonDate = JdbcSupport.getLocalDate(rs, "rejectedonDate");
LocalDate closedonDate = JdbcSupport.getLocalDate(rs, "closedonDate");
boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed");
Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod");
Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType");
EnumOptionData lockinPeriodType = SavingProductEnumerations.savingsLockinPeriod(lockinPeriodTypeValue);
return new SavingAccountData(id, status, externalId, clientId, clientName, productId, productName, productType, currencyData,
savingsDepostiAmountPerPeriod, savingsFrequencyType, totalDepositAmount, reccuringInterestRate, savingInterestRate,
interestType, interestCalculationMethod, tenure, tenureType, projectedCommencementDate, actualCommencementDate,
maturesOnDate,projectedInterestAccuredOnMaturity, actualInterestAccured,
projectedMaturityAmount, actualMaturityAmount, preClosureAllowed, preClosureInterestRate, withdrawnonDate,
rejectedonDate, closedonDate, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType);
}
}
}
@@ -0,0 +1,18 @@
package org.mifosng.platform.saving.service;
import org.mifosng.platform.api.commands.SavingAccountCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.springframework.security.access.prepost.PreAuthorize;
public interface SavingAccountWritePlatformService {
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
EntityIdentifier createSavingAccount(SavingAccountCommand command);
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
EntityIdentifier deleteSavingAccount(SavingAccountCommand command);
@PreAuthorize(value = "hasRole('ORGANISATION_ADMINISTRATION_SUPER_USER_ROLE')")
EntityIdentifier updateSavingAccount(SavingAccountCommand command);
}
@@ -0,0 +1,99 @@
package org.mifosng.platform.saving.service;
import org.mifosng.platform.api.commands.SavingAccountCommand;
import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.client.domain.NoteRepository;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.exceptions.SavingAccountNotFoundException;
import org.mifosng.platform.saving.domain.SavingAccount;
import org.mifosng.platform.saving.domain.SavingAccountRepository;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SavingAccountWritePlatformServiceJpaRepositoryImpl implements SavingAccountWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(SavingAccountWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final SavingAccountRepository savingAccountRepository;
private final SavingAccountAssembler savingAccountAssembler;
@SuppressWarnings("unused")
private final NoteRepository noteRepository;
@Autowired
public SavingAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,final SavingAccountRepository savingAccountRepository,
SavingAccountAssembler savingAccountAssembler,NoteRepository noteRepository) {
this.context=context;
this.savingAccountRepository=savingAccountRepository;
this.savingAccountAssembler=savingAccountAssembler;
this.noteRepository=noteRepository;
}
@Transactional
@Override
public EntityIdentifier createSavingAccount(SavingAccountCommand command) {
try {
this.context.authenticatedUser();
SavingAccountCommandValidator validator=new SavingAccountCommandValidator(command);
validator.validateForCreate();
SavingAccount account=this.savingAccountAssembler.assembleFrom(command);
this.savingAccountRepository.save(account);
return new EntityIdentifier(account.getId());
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return new EntityIdentifier(Long.valueOf(-1));
}
}
@Override
public EntityIdentifier deleteSavingAccount(SavingAccountCommand command) {
return null;
}
@Override
public EntityIdentifier updateSavingAccount(SavingAccountCommand command) {
try {
this.context.authenticatedUser();
SavingAccountCommandValidator validator=new SavingAccountCommandValidator(command);
validator.validateForUpdate();
SavingAccount account=this.savingAccountRepository.findOne(command.getId());
if (account == null || account.isDeleted()) {
throw new SavingAccountNotFoundException(command.getId());
}
if(account.isPendingApproval()){
this.savingAccountAssembler.assembleFrom(command,account);
this.savingAccountRepository.save(account);
}
return new EntityIdentifier(account.getId());
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return new EntityIdentifier(Long.valueOf(-1));
}
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue is.
*/
private void handleDataIntegrityIssues(final SavingAccountCommand command, DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("saving_acc_external_id")) {
throw new PlatformDataIntegrityException("error.msg.saving.account.duplicate.externalId", "Saving account with externalId " + command.getExternalId() + " already exists", "externalId", command.getExternalId());
}
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.saving.account.unknown.data.integrity.issue", "Unknown data integrity issue with resource.");
}
}
@@ -29,7 +29,6 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "external_id", length=100)
private String externalId;
@SuppressWarnings("unused")
@Column(name = "description")
private String description;
@@ -0,0 +1,54 @@
package org.mifosng.platform.savingproduct.domain;
public enum SavingFrequencyType {
INVALID(0,"savingFrequencyType.invalid"),
DAILY(1,"savingFrequencyType.daily"),
MONTHLY(2,"savingFrequencyType.monthly"),
QUATERLY(3,"savingFrequencyType.quaterly"),
HALFYEARLY(4,"savingFrequencyType.halfyearly"),
YEARLY(5,"savingFrequencyType.yearly");
private final Integer value;
private final String code;
private SavingFrequencyType(final Integer value,final String code) {
this.value=value;
this.code=code;
}
public Integer getValue() {
return value;
}
public String getCode() {
return code;
}
public static SavingFrequencyType fromInt(final Integer frequency) {
SavingFrequencyType savingFrequencyType = SavingFrequencyType.INVALID;
switch (frequency) {
case 1:
savingFrequencyType = SavingFrequencyType.DAILY;
break;
case 2:
savingFrequencyType = SavingFrequencyType.MONTHLY;
break;
case 3:
savingFrequencyType = SavingFrequencyType.QUATERLY;
break;
case 4:
savingFrequencyType = SavingFrequencyType.HALFYEARLY;
break;
case 5:
savingFrequencyType = SavingFrequencyType.YEARLY;
break;
default:
savingFrequencyType = SavingFrequencyType.INVALID;
break;
}
return savingFrequencyType;
}
}
@@ -0,0 +1,44 @@
package org.mifosng.platform.savingproduct.domain;
public enum SavingInterestCalculationMethod {
AVERAGEBAL(1,"savinginterest.calculation.method.averagebal"),
MINBAL(2,"savinginterest.calculation.method.minbal"),
MONTHLYCOLLECTION(3,"savinginterest.calculation.method.monthlycllection"),
INVALID(0,"savinginterest.calculation.method.invalid");
private final Integer value;
private final String code;
private SavingInterestCalculationMethod(final Integer value,final String code) {
this.value=value;
this.code=code;
}
public Integer getValue() {
return value;
}
public String getCode() {
return code;
}
public static SavingInterestCalculationMethod fromInt(final Integer frequency) {
SavingInterestCalculationMethod savingInterestCalculationMethod = SavingInterestCalculationMethod.INVALID;
switch (frequency) {
case 1:
savingInterestCalculationMethod = SavingInterestCalculationMethod.AVERAGEBAL;
break;
case 2:
savingInterestCalculationMethod = SavingInterestCalculationMethod.MINBAL;
break;
case 3:
savingInterestCalculationMethod = SavingInterestCalculationMethod.MONTHLYCOLLECTION;
break;
default:
savingInterestCalculationMethod = SavingInterestCalculationMethod.INVALID;
break;
}
return savingInterestCalculationMethod;
}
}
@@ -11,6 +11,7 @@ import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.user.domain.AppUser;
@Entity
@@ -34,18 +35,23 @@ public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
this.description = null;
this.savingProductRelatedDetail = null;
}
public SavingProduct(final String name, final String description, final MonetaryCurrency currency,final BigDecimal interestRate, final BigDecimal minimumBalance,final BigDecimal maximumBalance) {
public SavingProduct(final String name, final String description, final MonetaryCurrency currency,final BigDecimal interestRate, final BigDecimal minInterestRate, final BigDecimal maxInterestRate, final BigDecimal savingsDepositAmount,
final SavingProductType savingProductType, final TenureTypeEnum tenureType, final Integer tenure, final SavingFrequencyType savingFrequencyType,
final SavingsInterestType savingsInterestType, SavingInterestCalculationMethod savingInterestCalculationMethod, final BigDecimal minimumBalanceForWithdrawal,
final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed, final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType){
this.name = name.trim();
if (StringUtils.isNotBlank(description)) {
this.description = description.trim();
} else {
this.description = null;
}
this.savingProductRelatedDetail=new SavingProductRelatedDetail(currency, interestRate,minimumBalance,maximumBalance);
this.savingProductRelatedDetail = new SavingProductRelatedDetail(currency, interestRate, minInterestRate, maxInterestRate, savingsDepositAmount, savingProductType, tenureType, tenure,
savingFrequencyType, savingsInterestType, savingInterestCalculationMethod, minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType);
}
public String getName() {
public String getName() {
return this.name;
}
@@ -65,10 +71,6 @@ public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
return this.savingProductRelatedDetail.getMinimumBalance();
}
public BigDecimal getMaximumBalance(){
return this.savingProductRelatedDetail.getMaximumBalance();
}
public boolean isDeleted() {
return deleted;
}
@@ -77,6 +79,10 @@ public class SavingProduct extends AbstractAuditableCustom<AppUser, Long> {
this.deleted = true;
}
public SavingProductRelatedDetail getSavingProductRelatedDetail() {
return savingProductRelatedDetail;
}
public void update(final SavingProductCommand command) {
if (command.isNameChanged()) {
@@ -8,6 +8,7 @@ import javax.persistence.Embedded;
import org.mifosng.platform.api.commands.SavingProductCommand;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
@Embeddable
public class SavingProductRelatedDetail {
@@ -18,25 +19,79 @@ public class SavingProductRelatedDetail {
@Column(name = "interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal interestRate;
@Column(name = "minimum_balance", scale = 6, precision = 19, nullable = false)
private BigDecimal minimumBalance;
@Column(name = "min_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal minInterestRate;
@Column(name = "maximum_balance", scale = 6, precision = 19, nullable = false)
private BigDecimal maximumBalance;
@Column(name = "max_interest_rate", scale = 6, precision = 19, nullable = false)
private BigDecimal maxInterestRate;
@Column(name = "savings_deposit_amount", scale = 6, precision = 19, nullable = false)
private BigDecimal savingsDepositAmount;
@Column(name = "savings_product_type", nullable=false)
private SavingProductType savingProductType;
@Column(name = "tenure_type", nullable=false)
private TenureTypeEnum tenureType;
@Column(name = "tenure", nullable=false)
private Integer tenure;
@Column(name = "frequency", nullable=false)
private SavingFrequencyType frequency;
@Column(name = "interest_type", nullable=false)
private SavingsInterestType interestType;
@Column(name = "interest_calculation_method")
private SavingInterestCalculationMethod interestCalculationMethod;
@Column(name = "min_bal_for_withdrawal", scale = 6, precision = 19, nullable = false)
private BigDecimal minimumBalanceForWithdrawal;
@Column(name = "is_partial_deposit_allowed", nullable=false)
private boolean isPartialDepositAllowed;
@Column(name = "is_lock_in_period_allowed", nullable=false)
private boolean isLockinPeriodAllowed;
@Column(name = "lock_in_period", nullable=false)
private Integer lockinPeriod;
@Column(name = "lock_in_period_type", nullable=false)
private PeriodFrequencyType lockinPeriodType;
public SavingProductRelatedDetail() {
this.interestRate=null;
this.maximumBalance=null;
this.minimumBalance=null;
this.savingsDepositAmount=null;
}
public SavingProductRelatedDetail(final MonetaryCurrency currency,final BigDecimal interestRate, final BigDecimal minimumBalance,final BigDecimal maximumBalance) {
public SavingProductRelatedDetail(final MonetaryCurrency currency,final BigDecimal interestRate, final BigDecimal minInterestRate, final BigDecimal maxInterestRate,
final BigDecimal savingsDepositAmount, final SavingProductType savingProductType,
final TenureTypeEnum tenureType, final Integer tenure,
final SavingFrequencyType frequency, final SavingsInterestType interestType,
final SavingInterestCalculationMethod interestCalculationMethod,
final BigDecimal minimumBalanceForWithdrawal,
final boolean isPartialDepositAllowed, final boolean isLockinPeriodAllowed,
final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType) {
this.currency=currency;
this.interestRate=interestRate;
this.minimumBalance=minimumBalance;
this.maximumBalance=maximumBalance;
this.minInterestRate = minInterestRate;
this.maxInterestRate = maxInterestRate;
this.savingsDepositAmount=savingsDepositAmount;
this.savingProductType=savingProductType;
this.tenureType=tenureType;
this.tenure=tenure;
this.frequency=frequency;
this.interestType=interestType;
this.interestCalculationMethod=interestCalculationMethod;
this.minimumBalanceForWithdrawal=minimumBalanceForWithdrawal;
this.isPartialDepositAllowed=isPartialDepositAllowed;
this.isLockinPeriodAllowed=isLockinPeriodAllowed;
this.lockinPeriod=lockinPeriod;
this.lockinPeriodType=lockinPeriodType;
}
public MonetaryCurrency getCurrency() {
return this.currency.copy();
}
@@ -46,17 +101,13 @@ public class SavingProductRelatedDetail {
}
public BigDecimal getMinimumBalance(){
return BigDecimal.valueOf(Double.valueOf(this.minimumBalance.stripTrailingZeros().toString()));
}
public BigDecimal getMaximumBalance(){
return BigDecimal.valueOf(Double.valueOf(this.maximumBalance.stripTrailingZeros().toString()));
return BigDecimal.valueOf(Double.valueOf(this.savingsDepositAmount.stripTrailingZeros().toString()));
}
public void update(SavingProductCommand command){
Integer digitsAfterDecimalChanged = this.currency.getDigitsAfterDecimal();
Integer digitsAfterDecimal = this.currency.getDigitsAfterDecimal();
if (command.isDigitsAfterDecimalChanged()) {
digitsAfterDecimalChanged = command.getDigitsAfterDecimal();
digitsAfterDecimal = command.getDigitsAfterDecimal();
}
String currencyCodeChanged = this.currency.getCode();
@@ -65,19 +116,108 @@ public class SavingProductRelatedDetail {
}
if (command.isDigitsAfterDecimalChanged() || command.isCurrencyCodeChanged()) {
this.currency = new MonetaryCurrency(currencyCodeChanged, digitsAfterDecimalChanged);
this.currency = new MonetaryCurrency(currencyCodeChanged, digitsAfterDecimal);
}
if (command.isInterestRateChanged()) {
this.interestRate = command.getInterestRate();
}
if(command.isMaximumBalanceChanged()){
this.minimumBalance=command.getMinimumBalance();
if(command.isSavingsDepositAmountChanged()){
this.savingsDepositAmount=command.getSavingsDepositAmount();
}
if(command.isMaximumBalanceChanged()){
this.maximumBalance=command.getMaximumBalance();
if (command.isSavingProductTypeChanged()) {
this.savingProductType=SavingProductType.fromInt(command.getSavingProductType());
}
if(command.isTenureTypeChanged()){
this.tenureType=TenureTypeEnum.fromInt(command.getTenureType());
}
if (command.isTenureChanged()) {
this.tenure = command.getTenure();
}
if (command.isFrequencyChanged()){
this.frequency = SavingFrequencyType.fromInt(command.getFrequency());
}
if (command.isInterestTypeChanged()) {
this.interestType = SavingsInterestType.fromInt(command.getInterestType());
}
if (command.isInterestCalculationMethodChanged()){
this.interestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod());
}
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());
}
}
public BigDecimal getSavingsDepositAmount() {
return savingsDepositAmount;
}
public SavingProductType getSavingProductType() {
return savingProductType;
}
public TenureTypeEnum getTenureType() {
return tenureType;
}
public Integer getTenure() {
return tenure;
}
public SavingFrequencyType getFrequency() {
return frequency;
}
public SavingsInterestType getInterestType() {
return interestType;
}
public SavingInterestCalculationMethod getInterestCalculationMethod() {
return interestCalculationMethod;
}
public BigDecimal getMinimumBalanceForWithdrawal() {
return minimumBalanceForWithdrawal;
}
public boolean isPartialDepositAllowed() {
return isPartialDepositAllowed;
}
public boolean isLockinPeriodAllowed() {
return isLockinPeriodAllowed;
}
public Integer getLockinPeriod() {
return lockinPeriod;
}
public PeriodFrequencyType getLockinPeriodType() {
return lockinPeriodType;
}
}
@@ -0,0 +1,50 @@
package org.mifosng.platform.savingproduct.domain;
public enum SavingProductType {
INVALID(0,"savingProductType.invalid"),
RECCURING(1,"savingProductType.reccuring"),
REGULAR(2,"savingProductType.regular");
private final Integer value;
private final String code;
private SavingProductType(final Integer value,final String code) {
this.value=value;
this.code=code;
}
public Integer getValue() {
return value;
}
public String getCode() {
return code;
}
public static SavingProductType fromInt(final Integer frequency) {
SavingProductType savingProductType = SavingProductType.INVALID;
switch (frequency) {
case 1:
savingProductType = SavingProductType.RECCURING;
break;
case 2:
savingProductType = SavingProductType.REGULAR;
break;
default:
savingProductType = SavingProductType.INVALID;
break;
}
return savingProductType;
}
public boolean isReccuring(){
return this.value.equals(SavingProductType.RECCURING.getValue());
}
public boolean isRegular(){
return this.value.equals(SavingProductType.REGULAR.getValue());
}
}
@@ -0,0 +1,42 @@
package org.mifosng.platform.savingproduct.domain;
public enum SavingsInterestType {
INVALID(0,"savingsInterestType.invalid"),
SIMPLE(1,"savingsInterestType.simple"),
COMPOUNDING(2,"savingsInterestType.compounding");
private final Integer value;
private final String code;
private SavingsInterestType(final Integer value,final String code) {
this.value=value;
this.code=code;
}
public Integer getValue() {
return value;
}
public String getCode() {
return code;
}
public static SavingsInterestType fromInt(final Integer frequency) {
SavingsInterestType savingsInterestType = SavingsInterestType.INVALID;
switch (frequency) {
case 1:
savingsInterestType = SavingsInterestType.SIMPLE;
break;
case 2:
savingsInterestType = SavingsInterestType.COMPOUNDING;
break;
default:
savingsInterestType = SavingsInterestType.INVALID;
break;
}
return savingsInterestType;
}
}
@@ -0,0 +1,52 @@
package org.mifosng.platform.savingproduct.domain;
public enum SavingsLockinPeriodEnum {
DAYS(0, "lockin.period.type.days"), //
WEEKS(1, "lockin.period.type.weeks"), //
MONTHS(2, "lockin.period.type.months"), //
YEARS(3, "lockin.period.type.years"), //
INVALID(4, "lockin.period.type.invalid");
private final Integer value;
private final String code;
private SavingsLockinPeriodEnum(final Integer value, final String code) {
this.value = value;
this.code = code;
}
public Integer getValue() {
return this.value;
}
public String getCode() {
return code;
}
public static SavingsLockinPeriodEnum fromInt(final Integer frequency) {
SavingsLockinPeriodEnum lockinPeriodType = SavingsLockinPeriodEnum.INVALID;
switch (frequency) {
case 0:
lockinPeriodType = SavingsLockinPeriodEnum.DAYS;
break;
case 1:
lockinPeriodType = SavingsLockinPeriodEnum.WEEKS;
break;
case 2:
lockinPeriodType = SavingsLockinPeriodEnum.MONTHS;
break;
case 3:
lockinPeriodType = SavingsLockinPeriodEnum.YEARS;
break;
default:
lockinPeriodType = SavingsLockinPeriodEnum.INVALID;
break;
}
return lockinPeriodType;
}
}
@@ -0,0 +1,42 @@
package org.mifosng.platform.savingproduct.domain;
public enum TenureTypeEnum {
INVALID(0,"tenureTypeEnum.invalid"),
FIXED_PERIOD(1,"tenureTypeEnum.fixedPeriod"),
PERPETUAL(2,"tenureTypeEnum.perpetual");
private final Integer value;
private final String code;
private TenureTypeEnum(final Integer value,final String code) {
this.value=value;
this.code=code;
}
public Integer getValue() {
return value;
}
public String getCode() {
return code;
}
public static TenureTypeEnum fromInt(final Integer frequency) {
TenureTypeEnum tenureTypeEnum = TenureTypeEnum.INVALID;
switch (frequency) {
case 1:
tenureTypeEnum = TenureTypeEnum.FIXED_PERIOD;
break;
case 2:
tenureTypeEnum = TenureTypeEnum.PERPETUAL;
break;
default:
tenureTypeEnum = TenureTypeEnum.INVALID;
break;
}
return tenureTypeEnum;
}
}
@@ -25,14 +25,25 @@ public class SavingProductCommandValidator {
baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("description").value(command.getDescription()).ignoreIfNull().notExceedingLengthOf(500);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().notNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).ignoreIfNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).notNull();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).notNull();
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().comapareMinimumAndMaximumAmounts(command.getMinimumBalance(), command.getMaximumBalance());
baseDataValidator.reset().anyOfNotNull(command.getName(), command.getDescription(),command.getCurrencyCode(),command.getDigitsAfterDecimal(),command.getInterestRate(),command.getMinimumBalance(),command.getMaximumBalance());
baseDataValidator.reset().parameter("minInterestRate").value(command.getMinInterestRate()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("maxInterestRate").value(command.getMaxInterestRate()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getInterestRate());
baseDataValidator.reset().parameter("savingsDepositAmount").value(command.getSavingsDepositAmount()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).ignoreIfNull();
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull();
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull();
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull();
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).ignoreIfNull();
baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).ignoreIfNull();
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).ignoreIfNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).ignoreIfNull();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).ignoreIfNull();
baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).ignoreIfNull();
baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).ignoreIfNull();
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
@@ -48,12 +59,25 @@ public class SavingProductCommandValidator {
baseDataValidator.reset().parameter("description").value(command.getDescription()).notExceedingLengthOf(500);
baseDataValidator.reset().parameter("currencyCode").value(command.getCurrencyCode()).notBlank();
baseDataValidator.reset().parameter("digitsAfterDecimal").value(command.getDigitsAfterDecimal()).notNull().inMinMaxRange(0, 6);
baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).notNull();
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).notNull();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).notNull();
baseDataValidator.reset().parameter("maximumBalance").value(command.getMaximumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minimumBalance").value(command.getMinimumBalance()).zeroOrPositiveAmount();
baseDataValidator.reset().comapareMinimumAndMaximumAmounts(command.getMinimumBalance(), command.getMaximumBalance());
baseDataValidator.reset().parameter("interestRate").value(command.getInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minInterestRate").value(command.getMinInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("maxInterestRate").value(command.getMaxInterestRate()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("interestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getInterestRate(), command.getMaxInterestRate());
baseDataValidator.reset().parameter("minInterestRate").comapareMinAndMaxOfTwoBigDecmimalNos(command.getMinInterestRate(), command.getInterestRate());
baseDataValidator.reset().parameter("savingsDepositAmount").value(command.getSavingsDepositAmount()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).notNull();
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull();
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull();
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull();
baseDataValidator.reset().parameter("interestType").value(command.getInterestType()).notNull();
baseDataValidator.reset().parameter("interestCalculationMethod").value(command.getInterestCalculationMethod()).notNull();
baseDataValidator.reset().parameter("minimumBalanceForWithdrawal").value(command.getMinimumBalanceForWithdrawal()).notNull().zeroOrPositiveAmount();
baseDataValidator.reset().parameter("isPartialDepositAllowed").value(command.isPartialDepositAllowed()).trueOrFalseRequired(command.isPartialDepositAllowedChanged()).notNull();
baseDataValidator.reset().parameter("isLockinPeriodAllowed").value(command.isLockinPeriodAllowed()).trueOrFalseRequired(command.isLockinPeriodAllowedChanged()).notNull();
baseDataValidator.reset().parameter("lockinPeriod").value(command.getLockinPeriod()).notNull();
baseDataValidator.reset().parameter("lockinPeriodType").value(command.getLockinPeriodType()).notNull();
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
@@ -0,0 +1,163 @@
package org.mifosng.platform.savingproduct.service;
import org.mifosng.platform.api.data.EnumOptionData;
import org.mifosng.platform.savingproduct.domain.SavingFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod;
import org.mifosng.platform.savingproduct.domain.SavingProductType;
import org.mifosng.platform.savingproduct.domain.SavingsInterestType;
import org.mifosng.platform.savingproduct.domain.SavingsLockinPeriodEnum;
import org.mifosng.platform.savingproduct.domain.TenureTypeEnum;
public class SavingProductEnumerations {
public static EnumOptionData savingProductType(final int id) {
return savingProductType(SavingProductType.fromInt(id));
}
public static EnumOptionData tenureTypeEnum(final int id) {
return tenureTypeEnum(TenureTypeEnum.fromInt(id));
}
public static EnumOptionData interestFrequencyType(final int id) {
return interestFrequencyType(SavingFrequencyType.fromInt(id));
}
public static EnumOptionData savingInterestType(final int id) {
return savingInterestType(SavingsInterestType.fromInt(id));
}
public static EnumOptionData savingInterestCalculationMethod(final int id) {
return savingInterestCalculationMethod(SavingInterestCalculationMethod.fromInt(id));
}
public static EnumOptionData savingsLockinPeriod(final int id){
return savingsLockinPeriod(SavingsLockinPeriodEnum.fromInt(id));
}
public static EnumOptionData savingsLockinPeriod(SavingsLockinPeriodEnum type) {
final String codePrefix = "savings.product.";
EnumOptionData optionData = null;
switch (type) {
case DAYS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.DAYS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.DAYS.getCode(), "Days");
break;
case MONTHS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.MONTHS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.MONTHS.getCode(), "Months");
break;
case WEEKS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.WEEKS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.WEEKS.getCode(), "Weeks");
break;
case YEARS:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.YEARS.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.YEARS.getCode(), "Years");
break;
default:
optionData = new EnumOptionData(SavingsLockinPeriodEnum.INVALID.getValue().longValue(), codePrefix+SavingsLockinPeriodEnum.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
public static EnumOptionData savingInterestCalculationMethod(SavingInterestCalculationMethod type) {
final String codePrefix = "savings.interestCalculation.method.";
EnumOptionData optionData = null;
switch (type) {
case MINBAL:
optionData = new EnumOptionData(SavingInterestCalculationMethod.MINBAL.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.MINBAL.getCode(), "Minimumbalance");
break;
case AVERAGEBAL:
optionData = new EnumOptionData(SavingInterestCalculationMethod.AVERAGEBAL.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.AVERAGEBAL.getCode(), "AverageBalance");
break;
case INVALID:
optionData = new EnumOptionData(SavingInterestCalculationMethod.INVALID.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.INVALID.getCode(), "Invalid");
break;
case MONTHLYCOLLECTION:
optionData = new EnumOptionData(SavingInterestCalculationMethod.MONTHLYCOLLECTION.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.MONTHLYCOLLECTION.getCode(), "MonthlyCollection");
break;
default:
optionData = new EnumOptionData(SavingInterestCalculationMethod.INVALID.getValue().longValue(), codePrefix+SavingInterestCalculationMethod.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
public static EnumOptionData savingInterestType(SavingsInterestType type) {
final String codePrefix = "savings.interest.type.";
EnumOptionData optionData = null;
switch (type) {
case COMPOUNDING:
optionData = new EnumOptionData(SavingsInterestType.COMPOUNDING.getValue().longValue(), codePrefix+SavingsInterestType.COMPOUNDING.getCode(), "Compounding");
break;
case SIMPLE:
optionData = new EnumOptionData(SavingsInterestType.SIMPLE.getValue().longValue(), codePrefix+SavingsInterestType.SIMPLE.getCode(), "Simple");
break;
default:
optionData = new EnumOptionData(SavingsInterestType.INVALID.getValue().longValue(), codePrefix+SavingsInterestType.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
public static EnumOptionData interestFrequencyType(SavingFrequencyType type) {
final String codePrefix = "saving.product.frequency.period.";
EnumOptionData optionData = null;
switch (type) {
case DAILY:
optionData = new EnumOptionData(SavingFrequencyType.DAILY.getValue().longValue(), codePrefix + SavingFrequencyType.DAILY.getCode(), "Days");
break;
case MONTHLY:
optionData = new EnumOptionData(SavingFrequencyType.MONTHLY.getValue().longValue(), codePrefix + SavingFrequencyType.MONTHLY.getCode(), "Weeks");
break;
case QUATERLY:
optionData = new EnumOptionData(SavingFrequencyType.QUATERLY.getValue().longValue(), codePrefix + SavingFrequencyType.QUATERLY.getCode(), "Months");
break;
case HALFYEARLY:
optionData = new EnumOptionData(SavingFrequencyType.HALFYEARLY.getValue().longValue(), codePrefix + SavingFrequencyType.HALFYEARLY.getCode(), "Months");
break;
case YEARLY:
optionData = new EnumOptionData(SavingFrequencyType.YEARLY.getValue().longValue(), codePrefix + SavingFrequencyType.YEARLY.getCode(), "Yearly");
break;
default:
optionData = new EnumOptionData(SavingFrequencyType.INVALID.getValue().longValue(), SavingFrequencyType.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
public static EnumOptionData tenureTypeEnum(final TenureTypeEnum type) {
final String codePrefix = "savings.tenure.";
EnumOptionData optionData = null;
switch (type) {
case FIXED_PERIOD:
optionData = new EnumOptionData(TenureTypeEnum.FIXED_PERIOD.getValue().longValue(), codePrefix+TenureTypeEnum.FIXED_PERIOD.getCode(), "FixedPeriod");
break;
case PERPETUAL:
optionData = new EnumOptionData(TenureTypeEnum.PERPETUAL.getValue().longValue(), codePrefix+TenureTypeEnum.PERPETUAL.getCode(), "Perpetual");
break;
default:
optionData = new EnumOptionData(TenureTypeEnum.INVALID.getValue().longValue(), codePrefix+TenureTypeEnum.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
public static EnumOptionData savingProductType(final SavingProductType type) {
final String codePrefix = "savings.product.";
EnumOptionData optionData = null;
switch (type) {
case RECCURING:
optionData = new EnumOptionData(SavingProductType.RECCURING.getValue().longValue(), codePrefix + SavingProductType.RECCURING.getCode(), "Reccuring");
break;
case REGULAR:
optionData = new EnumOptionData(SavingProductType.REGULAR.getValue().longValue(), codePrefix + SavingProductType.REGULAR.getCode(), "Regular");
break;
case INVALID:
optionData = new EnumOptionData(SavingProductType.INVALID.getValue().longValue(), codePrefix + SavingProductType.INVALID.getCode(), "Invalid");
break;
default:
optionData = new EnumOptionData(SavingProductType.INVALID.getValue().longValue(), SavingProductType.INVALID.getCode(), "Invalid");
break;
}
return optionData;
}
}
@@ -8,12 +8,15 @@ import java.util.List;
import org.joda.time.DateTime;
import org.mifosng.platform.api.data.CurrencyData;
import org.mifosng.platform.api.data.EnumOptionData;
import org.mifosng.platform.api.data.SavingProductData;
import org.mifosng.platform.api.data.SavingProductLookup;
import org.mifosng.platform.currency.service.CurrencyReadPlatformService;
import org.mifosng.platform.exceptions.LoanProductNotFoundException;
import org.mifosng.platform.infrastructure.JdbcSupport;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingProductType;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
@@ -65,6 +68,7 @@ public class SavingProductReadPlatformServiceImpl implements
@Override
public SavingProductData retrieveSavingProduct(Long savingProductId) {
try{
this.context.authenticatedUser();
SavingProductMapper savingProductMapper=new SavingProductMapper();
String sql = "select " + savingProductMapper.savingProductSchema()
+ " where sp.id = ? and sp.is_deleted=0";
@@ -92,7 +96,12 @@ public class SavingProductReadPlatformServiceImpl implements
private static final class SavingProductMapper implements RowMapper<SavingProductData> {
public String savingProductSchema(){
return "sp.id as id,sp.name as name, sp.description as description,sp.currency_code as currencyCode, sp.currency_digits as currencyDigits,sp.interest_rate as interestRate,sp.minimum_balance as minimumBalance,sp.maximum_balance as maximumBalance,sp.created_date as createdon, sp.lastmodified_date as modifiedon, "
return "sp.id as id,sp.name as name, sp.description as description,sp.currency_code as currencyCode, sp.currency_digits as currencyDigits,sp.interest_rate as interestRate, "
+ "sp.min_interest_rate as minInterestRate, sp.max_interest_rate as maxInterstRate, "
+ " sp.savings_deposit_amount as savingsDepositAmount, sp.savings_product_type as savingProductType, sp.tenure_type as tenureType, sp.tenure as tenure, sp.frequency as frequency, "
+ " sp.interest_type as interestType, sp.interest_calculation_method as interestCalculationMethod, sp.min_bal_for_withdrawal as minimumBalanceForWithdrawal, "
+ " sp.is_partial_deposit_allowed as isPartialDepositAllowed, sp.is_lock_in_period_allowed as isLockinPeriodAllowed, sp.lock_in_period as lockinPeriod, sp.lock_in_period_type as lockinPeriodType, "
+ " sp.created_date as createdon, sp.lastmodified_date as modifiedon, "
+ "curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol"
+ " from m_product_savings sp join m_currency curr on curr.code = sp.currency_code";
}
@@ -106,21 +115,35 @@ public class SavingProductReadPlatformServiceImpl implements
String description = rs.getString("description");
String currencyCode = rs.getString("currencyCode");
//String currencyName = rs.getString("currencyName");
//String currencyNameCode = rs.getString("currencyNameCode");
//String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
String currencyName = rs.getString("currencyName");
String currencyNameCode = rs.getString("currencyNameCode");
String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
Integer currencyDigits = JdbcSupport.getInteger(rs,"currencyDigits");
//CurrencyData currencyData = new CurrencyData(currencyCode,currencyName, currencyDigits, currencyDisplaySymbol,currencyNameCode);*/
CurrencyData currencyData = new CurrencyData(currencyCode,currencyName, currencyDigits, currencyDisplaySymbol,currencyNameCode);
BigDecimal interestRate = rs.getBigDecimal("interestRate");
BigDecimal minInterestRate = rs.getBigDecimal("minInterestRate");
BigDecimal maxInterestRate = rs.getBigDecimal("maxInterstRate");
DateTime createdOn = JdbcSupport.getDateTime(rs, "createdon");
DateTime lastModifedOn = JdbcSupport.getDateTime(rs, "modifiedon");
BigDecimal minimumBalance=rs.getBigDecimal("minimumBalance");
BigDecimal maximumBalance=rs.getBigDecimal("maximumBalance");
BigDecimal savingsDepositAmount=rs.getBigDecimal("savingsDepositAmount");
EnumOptionData savingProductTypeEnum=SavingProductEnumerations.savingProductType(SavingProductType.fromInt(JdbcSupport.getInteger(rs, "savingProductType")));
EnumOptionData tenureTypeEnum = SavingProductEnumerations.tenureTypeEnum(JdbcSupport.getInteger(rs, "tenureType"));
Integer tenure = JdbcSupport.getInteger(rs, "tenure");
EnumOptionData savingFrequencyType = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs, "frequency"));
EnumOptionData savingInterestType = SavingProductEnumerations.savingInterestType(JdbcSupport.getInteger(rs, "interestType"));
EnumOptionData interestCalculationMethodEnum=SavingProductEnumerations.savingInterestCalculationMethod(JdbcSupport.getInteger(rs, "interestCalculationMethod"));
BigDecimal minimumBalanceForWithdrawal=rs.getBigDecimal("minimumBalanceForWithdrawal");
boolean isPartialDepositAllowed = rs.getBoolean("isPartialDepositAllowed");
boolean isLockinPeriodAllowed =rs.getBoolean("isLockinPeriodAllowed");
Integer lockinPeriod=JdbcSupport.getInteger(rs, "lockinPeriod");
EnumOptionData lockinPeriodType= SavingsDepositEnumerations.interestCompoundingPeriodType(PeriodFrequencyType.fromInt(JdbcSupport.getInteger(rs, "lockinPeriodType")));
return new SavingProductData(createdOn, lastModifedOn, id, name,description,interestRate,currencyCode,currencyDigits,minimumBalance,maximumBalance);
return new SavingProductData(createdOn, lastModifedOn, id, name, description, interestRate, minInterestRate, maxInterestRate, currencyData, currencyDigits, savingsDepositAmount,
savingProductTypeEnum, tenureTypeEnum, tenure, savingFrequencyType, savingInterestType, interestCalculationMethodEnum,
minimumBalanceForWithdrawal, isPartialDepositAllowed, isLockinPeriodAllowed, lockinPeriod, lockinPeriodType);
}
}
@@ -132,7 +155,7 @@ public class SavingProductReadPlatformServiceImpl implements
}
@Override
public SavingProductLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum)
public SavingProductLookup mapRow(final ResultSet rs, final int rowNum)
throws SQLException {
Long id = rs.getLong("id");
@@ -5,8 +5,14 @@ import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.currency.domain.MonetaryCurrency;
import org.mifosng.platform.exceptions.ProductNotFoundException;
import org.mifosng.platform.exceptions.SavingProductNotFoundException;
import org.mifosng.platform.loan.domain.PeriodFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingFrequencyType;
import org.mifosng.platform.savingproduct.domain.SavingInterestCalculationMethod;
import org.mifosng.platform.savingproduct.domain.SavingProduct;
import org.mifosng.platform.savingproduct.domain.SavingProductRepository;
import org.mifosng.platform.savingproduct.domain.SavingProductType;
import org.mifosng.platform.savingproduct.domain.SavingsInterestType;
import org.mifosng.platform.savingproduct.domain.TenureTypeEnum;
import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -32,9 +38,19 @@ public class SavingProductWritePlatformServiceJpaRepositoryImpl implements Savin
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());
SavingProduct product = new SavingProduct(command.getName(),command.getDescription(),currency,command.getInterestRate(),command.getMinimumBalance(),command.getMaximumBalance());
SavingProduct product = new SavingProduct(command.getName(), command.getDescription(), currency, command.getInterestRate(), command.getMinInterestRate(), command.getMaxInterestRate(),
command.getSavingsDepositAmount(), savingProductType, tenureType, command.getTenure(), savingFrequencyType, interestType,
savingInterestCalculationMethod, command.getMinimumBalanceForWithdrawal(), command.isPartialDepositAllowed(),
command.isLockinPeriodAllowed(), command.getLockinPeriod(), lockinPeriodType);
this.savingProductRepository.save(product);
return new EntityIdentifier(product.getId());
}