Add interest posting functionality for saving accounts
rename_patches_after_rebasing remove existed db script file
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
Alter TABLE `m_saving_schedule`
|
||||||
|
ADD COLUMN `interest_accured` decimal(21,4) DEFAULT '0.0000' AFTER `deposit_paid`
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
ALTER TABLE m_saving_account
|
|
||||||
ADD COLUMN `deposit_every` bigint(20) DEFAULT NULL AFTER `tenure_type`;
|
|
||||||
+1
-1
@@ -55,7 +55,7 @@ public class GoogleGsonPortfolioApiJsonSerializerService implements PortfolioApi
|
|||||||
"preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed",
|
"preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed",
|
||||||
"lockinPeriod", "lockinPeriodType", "productOptions", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions",
|
"lockinPeriod", "lockinPeriodType", "productOptions", "currencyOptions", "savingsProductTypeOptions", "tenureTypeOptions",
|
||||||
"savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions","permissions","savingScheduleDatas",
|
"savingFrequencyOptions", "savingsInterestTypeOptions", "lockinPeriodTypeOptions", "interestCalculationOptions","permissions","savingScheduleDatas",
|
||||||
"dueAmount", "savingScheduleData"));
|
"dueAmount", "savingScheduleData", "transactions","interestPostEvery","interestPostFrequency"));
|
||||||
|
|
||||||
// guarantors
|
// guarantors
|
||||||
private static final Set<String> GUARANTOR_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("externalGuarantor", "existingClientId",
|
private static final Set<String> GUARANTOR_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("externalGuarantor", "existingClientId",
|
||||||
|
|||||||
+2
-3
@@ -817,7 +817,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
|||||||
Set<String> supportedParams = new HashSet<String>(Arrays.asList("clientId", "productId", "externalId", "currencyCode",
|
Set<String> supportedParams = new HashSet<String>(Arrays.asList("clientId", "productId", "externalId", "currencyCode",
|
||||||
"digitsAfterDecimal", "savingsDepositAmountPerPeriod", "recurringInterestRate", "savingInterestRate", "tenure",
|
"digitsAfterDecimal", "savingsDepositAmountPerPeriod", "recurringInterestRate", "savingInterestRate", "tenure",
|
||||||
"commencementDate", "locale", "dateFormat", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType",
|
"commencementDate", "locale", "dateFormat", "isLockinPeriodAllowed", "lockinPeriod", "lockinPeriodType",
|
||||||
"savingProductType", "tenureType", "depositfrequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal",
|
"tenureType", "depositfrequency", "interestType", "interestCalculationMethod", "minimumBalanceForWithdrawal",
|
||||||
"isPartialDepositAllowed", "depositEvery","interestPostEvery","interestPostFrequency"));
|
"isPartialDepositAllowed", "depositEvery","interestPostEvery","interestPostFrequency"));
|
||||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||||
Set<String> modifiedParameters = new HashSet<String>();
|
Set<String> modifiedParameters = new HashSet<String>();
|
||||||
@@ -837,7 +837,6 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
|||||||
Integer lockinPeriodType = extractIntegerParameter("lockinPeriodType", requestMap, modifiedParameters);
|
Integer lockinPeriodType = extractIntegerParameter("lockinPeriodType", requestMap, modifiedParameters);
|
||||||
|
|
||||||
LocalDate commencementDate = extractLocalDateParameter("commencementDate", requestMap, modifiedParameters);
|
LocalDate commencementDate = extractLocalDateParameter("commencementDate", requestMap, modifiedParameters);
|
||||||
Integer savingProductType = extractIntegerParameter("savingProductType", requestMap, modifiedParameters);
|
|
||||||
Integer tenureType = extractIntegerParameter("tenureType", requestMap, modifiedParameters);
|
Integer tenureType = extractIntegerParameter("tenureType", requestMap, modifiedParameters);
|
||||||
Integer depositfrequency = extractIntegerParameter("depositfrequency", requestMap, modifiedParameters);
|
Integer depositfrequency = extractIntegerParameter("depositfrequency", requestMap, modifiedParameters);
|
||||||
Integer interestType = extractIntegerParameter("interestType", requestMap, modifiedParameters);
|
Integer interestType = extractIntegerParameter("interestType", requestMap, modifiedParameters);
|
||||||
@@ -851,7 +850,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
|
|||||||
|
|
||||||
return new SavingAccountCommand(modifiedParameters, resourceIdentifier, clientId, productId, externalId, currencyCode,
|
return new SavingAccountCommand(modifiedParameters, resourceIdentifier, clientId, productId, externalId, currencyCode,
|
||||||
digitsAfterDecimalValue, savingsDepositAmount, recurringInterestRate, savingInterestRate, tenure, commencementDate,
|
digitsAfterDecimalValue, savingsDepositAmount, recurringInterestRate, savingInterestRate, tenure, commencementDate,
|
||||||
savingProductType, tenureType, depositfrequency, interestType, minimumBalanceForWithdrawal, interestCalculationMethod,
|
tenureType, depositfrequency, interestType, minimumBalanceForWithdrawal, interestCalculationMethod,
|
||||||
isLockinPeriodAllowed, isPartialDepositAllowed, lockinPeriod, lockinPeriodType, depositEvery, interestPostEvery, interestPostFrequency);
|
isLockinPeriodAllowed, isPartialDepositAllowed, lockinPeriod, lockinPeriodType, depositEvery, interestPostEvery, interestPostFrequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-5
@@ -42,6 +42,7 @@ import org.mifosplatform.portfolio.savingsaccount.command.SavingAccountWithdrawa
|
|||||||
import org.mifosplatform.portfolio.savingsaccount.command.SavingStateTransitionsCommand;
|
import org.mifosplatform.portfolio.savingsaccount.command.SavingStateTransitionsCommand;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountTransactionsData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.service.CalculateSavingSchedule;
|
import org.mifosplatform.portfolio.savingsaccount.service.CalculateSavingSchedule;
|
||||||
@@ -103,7 +104,7 @@ public class SavingsAccountApiResource {
|
|||||||
"interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "actualCommencementDate", "maturesOnDate",
|
"interestCalculationMethod", "tenure", "tenureType", "projectedCommencementDate", "actualCommencementDate", "maturesOnDate",
|
||||||
"projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount",
|
"projectedInterestAccuredOnMaturity", "actualInterestAccured", "projectedMaturityAmount", "actualMaturityAmount",
|
||||||
"preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed",
|
"preClosureAllowed", "preClosureInterestRate", "withdrawnonDate", "rejectedonDate", "closedonDate", "isLockinPeriodAllowed",
|
||||||
"lockinPeriod", "lockinPeriodType","outstandingAmount","savingScheduleData"));
|
"lockinPeriod", "lockinPeriodType","outstandingAmount","savingScheduleData","transactions","interestPostEvery","interestPostFrequency"));
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Consumes({ MediaType.APPLICATION_JSON })
|
@Consumes({ MediaType.APPLICATION_JSON })
|
||||||
@@ -173,6 +174,7 @@ public class SavingsAccountApiResource {
|
|||||||
|
|
||||||
SavingPermissionData permissions = null;
|
SavingPermissionData permissions = null;
|
||||||
SavingScheduleData savingScheduleData = null;
|
SavingScheduleData savingScheduleData = null;
|
||||||
|
Collection<SavingAccountTransactionsData> transactions = null;
|
||||||
|
|
||||||
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
if (responseParameters.isEmpty()) {
|
if (responseParameters.isEmpty()) {
|
||||||
@@ -191,8 +193,8 @@ public class SavingsAccountApiResource {
|
|||||||
Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||||
if (!associationParameters.isEmpty()) {
|
if (!associationParameters.isEmpty()) {
|
||||||
if (associationParameters.contains("all")) {
|
if (associationParameters.contains("all")) {
|
||||||
associationParameters.add("savingScheduleData");
|
associationParameters.addAll(Arrays.asList("savingScheduleData","transactions"));
|
||||||
responseParameters.addAll(Arrays.asList("permissions","savingScheduleData"));
|
responseParameters.addAll(Arrays.asList("permissions","savingScheduleData","transactions"));
|
||||||
} else {
|
} else {
|
||||||
responseParameters.addAll(associationParameters);
|
responseParameters.addAll(associationParameters);
|
||||||
}
|
}
|
||||||
@@ -202,6 +204,10 @@ public class SavingsAccountApiResource {
|
|||||||
savingScheduleData = this.savingAccountReadPlatformService.retrieveSavingsAccountSchedule(accountId,currencyData);
|
savingScheduleData = this.savingAccountReadPlatformService.retrieveSavingsAccountSchedule(accountId,currencyData);
|
||||||
account = new SavingAccountData(account,savingScheduleData);
|
account = new SavingAccountData(account,savingScheduleData);
|
||||||
}
|
}
|
||||||
|
if (associationParameters.contains("transactions")) {
|
||||||
|
transactions = this.savingAccountReadPlatformService.retrieveSavingsAccountTransactions(accountId);
|
||||||
|
account = new SavingAccountData(account,transactions);
|
||||||
|
}
|
||||||
permissions = this.savingAccountReadPlatformService.retrieveSavingAccountPermissions(account);
|
permissions = this.savingAccountReadPlatformService.retrieveSavingAccountPermissions(account);
|
||||||
account = new SavingAccountData(account, permissions);
|
account = new SavingAccountData(account, permissions);
|
||||||
}
|
}
|
||||||
@@ -258,10 +264,10 @@ public class SavingsAccountApiResource {
|
|||||||
List<EnumOptionData> lockinPeriodTypeOptions = Arrays.asList(months);
|
List<EnumOptionData> lockinPeriodTypeOptions = Arrays.asList(months);
|
||||||
|
|
||||||
EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL);
|
EnumOptionData averagebal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.AVERAGEBAL);
|
||||||
EnumOptionData minbal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL);
|
// EnumOptionData minbal = SavingProductEnumerations.savingInterestCalculationMethod(SavingInterestCalculationMethod.MINBAL);
|
||||||
EnumOptionData monthlyCollection = SavingProductEnumerations
|
EnumOptionData monthlyCollection = SavingProductEnumerations
|
||||||
.savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION);
|
.savingInterestCalculationMethod(SavingInterestCalculationMethod.MONTHLYCOLLECTION);
|
||||||
List<EnumOptionData> interestCalculationOptions = Arrays.asList(averagebal, minbal, monthlyCollection);
|
List<EnumOptionData> interestCalculationOptions = Arrays.asList(averagebal, monthlyCollection);
|
||||||
BigDecimal dueAmount = this.savingAccountReadPlatformService.deriveSavingDueAmount(account);
|
BigDecimal dueAmount = this.savingAccountReadPlatformService.deriveSavingDueAmount(account);
|
||||||
return new SavingAccountData(account, productOptions, currencyOptions, savingsProductTypeOptions,tenureTypeOptions,savingFrequencyOptions,
|
return new SavingAccountData(account, productOptions, currencyOptions, savingsProductTypeOptions,tenureTypeOptions,savingFrequencyOptions,
|
||||||
savingsInterestTypeOptions,lockinPeriodTypeOptions,interestCalculationOptions, dueAmount);
|
savingsInterestTypeOptions,lockinPeriodTypeOptions,interestCalculationOptions, dueAmount);
|
||||||
|
|||||||
+13
-1
@@ -13,12 +13,14 @@ public class CalculateSavingScheduleCommand {
|
|||||||
private final BigDecimal interestRate;
|
private final BigDecimal interestRate;
|
||||||
private final LocalDate paymentsStartingFromDate;
|
private final LocalDate paymentsStartingFromDate;
|
||||||
private final Integer tenure;
|
private final Integer tenure;
|
||||||
|
private final Integer tenureType;
|
||||||
private final Integer interestPostEvery;
|
private final Integer interestPostEvery;
|
||||||
private final Integer interestPostFrequency;
|
private final Integer interestPostFrequency;
|
||||||
|
private final Integer interestCalculationMethod;
|
||||||
|
|
||||||
public CalculateSavingScheduleCommand(final Long productId, final BigDecimal deposit, final Integer depositEvery,
|
public CalculateSavingScheduleCommand(final Long productId, final BigDecimal deposit, final Integer depositEvery,
|
||||||
final Integer paymentFrequencyType, final BigDecimal interestRate, final LocalDate paymentsStartingFromDate,
|
final Integer paymentFrequencyType, final BigDecimal interestRate, final LocalDate paymentsStartingFromDate,
|
||||||
final Integer tenure,final Integer interestPostEvery, final Integer interestPostFrequency) {
|
final Integer tenure, final Integer tenureType, final Integer interestPostEvery, final Integer interestPostFrequency, final Integer interestCalculationMethod) {
|
||||||
|
|
||||||
this.productId = productId;
|
this.productId = productId;
|
||||||
this.deposit = deposit;
|
this.deposit = deposit;
|
||||||
@@ -27,8 +29,10 @@ public class CalculateSavingScheduleCommand {
|
|||||||
this.interestRate = interestRate;
|
this.interestRate = interestRate;
|
||||||
this.paymentsStartingFromDate = paymentsStartingFromDate;
|
this.paymentsStartingFromDate = paymentsStartingFromDate;
|
||||||
this.tenure = tenure;
|
this.tenure = tenure;
|
||||||
|
this.tenureType = tenureType;
|
||||||
this.interestPostEvery = interestPostEvery;
|
this.interestPostEvery = interestPostEvery;
|
||||||
this.interestPostFrequency = interestPostFrequency;
|
this.interestPostFrequency = interestPostFrequency;
|
||||||
|
this.interestCalculationMethod = interestCalculationMethod;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,4 +72,12 @@ public class CalculateSavingScheduleCommand {
|
|||||||
return this.interestPostFrequency;
|
return this.interestPostFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getTenureType() {
|
||||||
|
return this.tenureType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getInterestCalculationMethod() {
|
||||||
|
return this.interestCalculationMethod;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-8
@@ -24,7 +24,6 @@ public class SavingAccountCommand {
|
|||||||
private final Integer lockinPeriodType;
|
private final Integer lockinPeriodType;
|
||||||
|
|
||||||
private final LocalDate commencementDate;
|
private final LocalDate commencementDate;
|
||||||
private final Integer savingProductType;
|
|
||||||
private final Integer tenureType;
|
private final Integer tenureType;
|
||||||
private final Integer frequency;
|
private final Integer frequency;
|
||||||
private final Integer interestType;
|
private final Integer interestType;
|
||||||
@@ -42,7 +41,7 @@ public class SavingAccountCommand {
|
|||||||
public SavingAccountCommand(final Set<String> modifiedParameters, final Long id, final Long clientId, final Long productId,
|
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 String externalId, final String currencyCode, final Integer digitsAfterDecimal, final BigDecimal savingsDepositAmount,
|
||||||
final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate, final Integer tenure,
|
final BigDecimal recurringInterestRate, final BigDecimal savingInterestRate, final Integer tenure,
|
||||||
final LocalDate commencementDate, final Integer savingProductType, final Integer tenureType, final Integer frequency,
|
final LocalDate commencementDate, final Integer tenureType, final Integer frequency,
|
||||||
final Integer interestType, final BigDecimal minimumBalanceForWithdrawal, final Integer interestCalculationMethod,
|
final Integer interestType, final BigDecimal minimumBalanceForWithdrawal, final Integer interestCalculationMethod,
|
||||||
final boolean isLockinPeriodAllowed, final boolean isPartialDepositAllowed, final Integer lockInPeriod,
|
final boolean isLockinPeriodAllowed, final boolean isPartialDepositAllowed, final Integer lockInPeriod,
|
||||||
final Integer lockinPeriodType, final Integer depositEvery,final Integer interestPostEvery,final Integer interestPostFrequency) {
|
final Integer lockinPeriodType, final Integer depositEvery,final Integer interestPostEvery,final Integer interestPostFrequency) {
|
||||||
@@ -61,7 +60,6 @@ public class SavingAccountCommand {
|
|||||||
this.modifiedParameters = modifiedParameters;
|
this.modifiedParameters = modifiedParameters;
|
||||||
this.commencementDate = commencementDate;
|
this.commencementDate = commencementDate;
|
||||||
|
|
||||||
this.savingProductType = savingProductType;
|
|
||||||
this.tenureType = tenureType;
|
this.tenureType = tenureType;
|
||||||
this.frequency = frequency;
|
this.frequency = frequency;
|
||||||
this.interestType = interestType;
|
this.interestType = interestType;
|
||||||
@@ -134,10 +132,6 @@ public class SavingAccountCommand {
|
|||||||
return commencementDate;
|
return commencementDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getSavingProductType() {
|
|
||||||
return savingProductType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getTenureType() {
|
public Integer getTenureType() {
|
||||||
return tenureType;
|
return tenureType;
|
||||||
}
|
}
|
||||||
@@ -261,7 +255,7 @@ public class SavingAccountCommand {
|
|||||||
|
|
||||||
public CalculateSavingScheduleCommand toCalculateSavingScheduleCommand() {
|
public CalculateSavingScheduleCommand toCalculateSavingScheduleCommand() {
|
||||||
return new CalculateSavingScheduleCommand(productId, savingsDepositAmount, depositEvery, frequency, recurringInterestRate,
|
return new CalculateSavingScheduleCommand(productId, savingsDepositAmount, depositEvery, frequency, recurringInterestRate,
|
||||||
commencementDate, tenure, interestPostEvery, interestPostFrequency);
|
commencementDate, tenure, tenureType, interestPostEvery, interestPostFrequency,interestCalculationMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -32,7 +32,6 @@ public class SavingAccountCommandValidator {
|
|||||||
baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).notNull().zeroOrPositiveAmount();
|
baseDataValidator.reset().parameter("savingInterestRate").value(command.getSavingInterestRate()).notNull().zeroOrPositiveAmount();
|
||||||
baseDataValidator.reset().parameter("savingInterestRate")
|
baseDataValidator.reset().parameter("savingInterestRate")
|
||||||
.comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate());
|
.comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate());
|
||||||
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).notNull();
|
|
||||||
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull();
|
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).notNull();
|
||||||
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull();
|
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).notNull();
|
||||||
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull();
|
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).notNull();
|
||||||
@@ -72,7 +71,6 @@ public class SavingAccountCommandValidator {
|
|||||||
.zeroOrPositiveAmount();
|
.zeroOrPositiveAmount();
|
||||||
baseDataValidator.reset().parameter("savingInterestRate")
|
baseDataValidator.reset().parameter("savingInterestRate")
|
||||||
.comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate());
|
.comapareMinAndMaxOfTwoBigDecmimalNos(command.getSavingInterestRate(), command.getRecurringInterestRate());
|
||||||
baseDataValidator.reset().parameter("savingProductType").value(command.getSavingProductType()).ignoreIfNull();
|
|
||||||
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull();
|
baseDataValidator.reset().parameter("tenureType").value(command.getTenureType()).ignoreIfNull();
|
||||||
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull();
|
baseDataValidator.reset().parameter("tenure").value(command.getTenure()).ignoreIfNull();
|
||||||
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull();
|
baseDataValidator.reset().parameter("frequency").value(command.getFrequency()).ignoreIfNull();
|
||||||
|
|||||||
+86
-2
@@ -72,6 +72,10 @@ public class SavingAccountData {
|
|||||||
private final BigDecimal outstandingAmount;
|
private final BigDecimal outstandingAmount;
|
||||||
private final BigDecimal dueAmount;
|
private final BigDecimal dueAmount;
|
||||||
private final SavingScheduleData savingScheduleData;
|
private final SavingScheduleData savingScheduleData;
|
||||||
|
private final Collection<SavingAccountTransactionsData> transactions;
|
||||||
|
|
||||||
|
private final Integer interestPostEvery;
|
||||||
|
private final EnumOptionData interestPostFrequency;
|
||||||
|
|
||||||
public static SavingAccountData createFrom(final Long clientId, final String clientDisplayName) {
|
public static SavingAccountData createFrom(final Long clientId, final String clientDisplayName) {
|
||||||
return new SavingAccountData(clientId, clientDisplayName);
|
return new SavingAccountData(clientId, clientDisplayName);
|
||||||
@@ -85,7 +89,7 @@ public class SavingAccountData {
|
|||||||
BigDecimal projectedInterestAccuredOnMaturity, BigDecimal actualInterestAccured, BigDecimal projectedMaturityAmount,
|
BigDecimal projectedInterestAccuredOnMaturity, BigDecimal actualInterestAccured, BigDecimal projectedMaturityAmount,
|
||||||
BigDecimal actualMaturityAmount, boolean preClosureAllowed, BigDecimal preClosureInterestRate, LocalDate withdrawnonDate,
|
BigDecimal actualMaturityAmount, boolean preClosureAllowed, BigDecimal preClosureInterestRate, LocalDate withdrawnonDate,
|
||||||
LocalDate rejectedonDate, LocalDate closedonDate, boolean isLockinPeriodAllowed, Integer lockinPeriod,
|
LocalDate rejectedonDate, LocalDate closedonDate, boolean isLockinPeriodAllowed, Integer lockinPeriod,
|
||||||
EnumOptionData lockinPeriodType, Integer depositEvery, BigDecimal outstandingAmount) {
|
EnumOptionData lockinPeriodType, Integer depositEvery, BigDecimal outstandingAmount, Integer interestPostEvery, EnumOptionData interestPostFrequency) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
@@ -133,6 +137,9 @@ public class SavingAccountData {
|
|||||||
this.outstandingAmount = outstandingAmount;
|
this.outstandingAmount = outstandingAmount;
|
||||||
this.dueAmount = BigDecimal.ZERO;
|
this.dueAmount = BigDecimal.ZERO;
|
||||||
this.savingScheduleData = null;
|
this.savingScheduleData = null;
|
||||||
|
this.transactions = null;
|
||||||
|
this.interestPostEvery = interestPostEvery;
|
||||||
|
this.interestPostFrequency = interestPostFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingAccountData(Long clientId, String clientName) {
|
public SavingAccountData(Long clientId, String clientName) {
|
||||||
@@ -183,6 +190,9 @@ public class SavingAccountData {
|
|||||||
this.outstandingAmount = BigDecimal.ZERO;
|
this.outstandingAmount = BigDecimal.ZERO;
|
||||||
this.dueAmount =BigDecimal.ZERO;
|
this.dueAmount =BigDecimal.ZERO;
|
||||||
this.savingScheduleData = null;
|
this.savingScheduleData = null;
|
||||||
|
this.transactions = null;
|
||||||
|
this.interestPostEvery =null;
|
||||||
|
this.interestPostFrequency = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingAccountData(SavingAccountData account, Collection<SavingProductLookup> productOptions, List<CurrencyData> currencyOptions,
|
public SavingAccountData(SavingAccountData account, Collection<SavingProductLookup> productOptions, List<CurrencyData> currencyOptions,
|
||||||
@@ -238,6 +248,9 @@ public class SavingAccountData {
|
|||||||
this.permissions = account.permissions;
|
this.permissions = account.permissions;
|
||||||
this.outstandingAmount = account.outstandingAmount;
|
this.outstandingAmount = account.outstandingAmount;
|
||||||
this.savingScheduleData = account.savingScheduleData;
|
this.savingScheduleData = account.savingScheduleData;
|
||||||
|
this.transactions = account.transactions;
|
||||||
|
this.interestPostEvery = account.interestPostEvery;
|
||||||
|
this.interestPostFrequency = account.interestPostFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME - Madhukar - unused variables been passed into construction - why?
|
// FIXME - Madhukar - unused variables been passed into construction - why?
|
||||||
@@ -277,7 +290,7 @@ public class SavingAccountData {
|
|||||||
this.withdrawnonDate = null;
|
this.withdrawnonDate = null;
|
||||||
this.rejectedonDate = null;
|
this.rejectedonDate = null;
|
||||||
this.closedonDate = null;
|
this.closedonDate = null;
|
||||||
this.isLockinPeriodAllowed = false;
|
this.isLockinPeriodAllowed = lockinPeriodAllowed;
|
||||||
this.lockinPeriod = lockinPeriod;
|
this.lockinPeriod = lockinPeriod;
|
||||||
this.lockinPeriodType = lockinPeriodType;
|
this.lockinPeriodType = lockinPeriodType;
|
||||||
this.depositEvery = depositEvery;
|
this.depositEvery = depositEvery;
|
||||||
@@ -294,6 +307,9 @@ public class SavingAccountData {
|
|||||||
this.outstandingAmount = BigDecimal.ZERO;
|
this.outstandingAmount = BigDecimal.ZERO;
|
||||||
this.dueAmount = BigDecimal.ZERO;
|
this.dueAmount = BigDecimal.ZERO;
|
||||||
this.savingScheduleData = null;
|
this.savingScheduleData = null;
|
||||||
|
this.transactions = null;
|
||||||
|
this.interestPostEvery =3;
|
||||||
|
this.interestPostFrequency = savingsFrequencyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingAccountData(SavingAccountData account, SavingPermissionData permissions) {
|
public SavingAccountData(SavingAccountData account, SavingPermissionData permissions) {
|
||||||
@@ -345,6 +361,9 @@ public class SavingAccountData {
|
|||||||
this.outstandingAmount = account.outstandingAmount;
|
this.outstandingAmount = account.outstandingAmount;
|
||||||
this.dueAmount = account.dueAmount;
|
this.dueAmount = account.dueAmount;
|
||||||
this.savingScheduleData = account.savingScheduleData;
|
this.savingScheduleData = account.savingScheduleData;
|
||||||
|
this.transactions = account.transactions;
|
||||||
|
this.interestPostEvery = account.interestPostEvery;
|
||||||
|
this.interestPostFrequency = account.interestPostFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingAccountData(SavingAccountData account, SavingScheduleData savingScheduleData) {
|
public SavingAccountData(SavingAccountData account, SavingScheduleData savingScheduleData) {
|
||||||
@@ -396,6 +415,63 @@ public class SavingAccountData {
|
|||||||
this.outstandingAmount = account.outstandingAmount;
|
this.outstandingAmount = account.outstandingAmount;
|
||||||
this.dueAmount = account.dueAmount;
|
this.dueAmount = account.dueAmount;
|
||||||
this.savingScheduleData = savingScheduleData;
|
this.savingScheduleData = savingScheduleData;
|
||||||
|
this.transactions = account.transactions;
|
||||||
|
this.interestPostEvery = account.interestPostEvery;
|
||||||
|
this.interestPostFrequency = account.interestPostFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavingAccountData(SavingAccountData account, Collection<SavingAccountTransactionsData> transactions) {
|
||||||
|
this.id = account.id;
|
||||||
|
this.status = account.status;
|
||||||
|
this.externalId = account.externalId;
|
||||||
|
this.clientId = account.clientId;
|
||||||
|
this.clientName = account.clientName;
|
||||||
|
this.productId = account.productId;
|
||||||
|
this.productName = account.productName;
|
||||||
|
this.productType = account.productType;
|
||||||
|
this.currencyData = account.currencyData;
|
||||||
|
this.savingsDepositAmountPerPeriod = account.savingsDepositAmountPerPeriod;
|
||||||
|
this.savingsFrequencyType = account.savingsFrequencyType;
|
||||||
|
this.totalDepositAmount = account.totalDepositAmount;
|
||||||
|
this.recurringInterestRate = account.recurringInterestRate;
|
||||||
|
this.savingInterestRate = account.savingInterestRate;
|
||||||
|
this.interestType = account.interestType;
|
||||||
|
this.interestCalculationMethod = account.interestCalculationMethod;
|
||||||
|
this.tenure = account.tenure;
|
||||||
|
this.tenureType = account.tenureType;
|
||||||
|
this.projectedCommencementDate = account.projectedCommencementDate;
|
||||||
|
this.actualCommencementDate = account.actualCommencementDate;
|
||||||
|
this.maturesOnDate = account.maturesOnDate;
|
||||||
|
this.projectedInterestAccuredOnMaturity = account.projectedInterestAccuredOnMaturity;
|
||||||
|
this.actualInterestAccured = account.actualInterestAccured;
|
||||||
|
this.projectedMaturityAmount = account.projectedMaturityAmount;
|
||||||
|
this.actualMaturityAmount = account.actualMaturityAmount;
|
||||||
|
this.preClosureAllowed = account.preClosureAllowed;
|
||||||
|
this.preClosureInterestRate = account.preClosureInterestRate;
|
||||||
|
this.withdrawnonDate = account.withdrawnonDate;
|
||||||
|
this.rejectedonDate = account.rejectedonDate;
|
||||||
|
this.closedonDate = account.closedonDate;
|
||||||
|
this.isLockinPeriodAllowed = account.isLockinPeriodAllowed;
|
||||||
|
this.lockinPeriod = account.lockinPeriod;
|
||||||
|
this.lockinPeriodType = account.lockinPeriodType;
|
||||||
|
this.depositEvery = account.depositEvery;
|
||||||
|
|
||||||
|
this.productOptions = account.productOptions;
|
||||||
|
this.currencyOptions = account.currencyOptions;
|
||||||
|
this.savingsProductTypeOptions = account.savingsProductTypeOptions;
|
||||||
|
this.tenureTypeOptions = account.tenureTypeOptions;
|
||||||
|
this.savingFrequencyOptions = account.savingFrequencyOptions;
|
||||||
|
this.savingsInterestTypeOptions = account.savingsInterestTypeOptions;
|
||||||
|
this.lockinPeriodTypeOptions = account.lockinPeriodTypeOptions;
|
||||||
|
this.interestCalculationOptions = account.interestCalculationOptions;
|
||||||
|
this.savingScheduleDatas = account.savingScheduleDatas;
|
||||||
|
this.permissions = account.permissions;
|
||||||
|
this.outstandingAmount = account.outstandingAmount;
|
||||||
|
this.dueAmount = account.dueAmount;
|
||||||
|
this.savingScheduleData = account.savingScheduleData;
|
||||||
|
this.transactions = transactions;
|
||||||
|
this.interestPostEvery = account.interestPostEvery;
|
||||||
|
this.interestPostFrequency = account.interestPostFrequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@@ -570,4 +646,12 @@ public class SavingAccountData {
|
|||||||
return this.outstandingAmount;
|
return this.outstandingAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getInterestPostEvery() {
|
||||||
|
return this.interestPostEvery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumOptionData getInterestPostFrequency() {
|
||||||
|
return this.interestPostFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+33
@@ -0,0 +1,33 @@
|
|||||||
|
package org.mifosplatform.portfolio.savingsaccount.data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
|
||||||
|
|
||||||
|
public class SavingAccountTransactionsData {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final Long id;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final LocalDate transactionDate;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final EnumOptionData transactionType;
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final BigDecimal amount;
|
||||||
|
|
||||||
|
public SavingAccountTransactionsData() {
|
||||||
|
this.id = null;
|
||||||
|
this.transactionDate = null;
|
||||||
|
this.transactionType = null;
|
||||||
|
this.amount = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SavingAccountTransactionsData(final Long id, final LocalDate transactionDate, EnumOptionData transactionType, BigDecimal amount){
|
||||||
|
this.id = id;
|
||||||
|
this.transactionDate = transactionDate;
|
||||||
|
this.transactionType = transactionType;
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+15
-3
@@ -9,12 +9,16 @@ public class SavingScheduleData {
|
|||||||
|
|
||||||
private final CurrencyData currency;
|
private final CurrencyData currency;
|
||||||
private final BigDecimal cumulativeDepositDue;
|
private final BigDecimal cumulativeDepositDue;
|
||||||
|
private final BigDecimal cumulativeDepositPaid;
|
||||||
|
private final BigDecimal cummulativeInterestAccured;
|
||||||
private final Collection<SavingSchedulePeriodData> periods;
|
private final Collection<SavingSchedulePeriodData> periods;
|
||||||
|
|
||||||
public SavingScheduleData(final CurrencyData currency, final BigDecimal cumulativeDepositDue,
|
public SavingScheduleData(final CurrencyData currency, final BigDecimal cumulativeDepositDue, final BigDecimal cumulativeDepositPaid,
|
||||||
final Collection<SavingSchedulePeriodData> periods) {
|
final BigDecimal cummulativeInterestAccured, final Collection<SavingSchedulePeriodData> periods) {
|
||||||
this.currency = currency;
|
this.currency = currency;
|
||||||
this.cumulativeDepositDue = cumulativeDepositDue;
|
this.cumulativeDepositDue = cumulativeDepositDue;
|
||||||
|
this.cumulativeDepositPaid = cumulativeDepositPaid;
|
||||||
|
this.cummulativeInterestAccured = cummulativeInterestAccured;
|
||||||
this.periods = periods;
|
this.periods = periods;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -27,7 +31,15 @@ public class SavingScheduleData {
|
|||||||
return this.cumulativeDepositDue;
|
return this.cumulativeDepositDue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<SavingSchedulePeriodData> getPeriods() {
|
public BigDecimal getCumulativeDepositPaid() {
|
||||||
|
return this.cumulativeDepositPaid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getCummulativeInterestAccured() {
|
||||||
|
return this.cummulativeInterestAccured;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<SavingSchedulePeriodData> getPeriods() {
|
||||||
return this.periods;
|
return this.periods;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -10,17 +10,19 @@ public class SavingSchedulePeriodData {
|
|||||||
private final LocalDate dueDate;
|
private final LocalDate dueDate;
|
||||||
private final BigDecimal depositDue;
|
private final BigDecimal depositDue;
|
||||||
private final BigDecimal depositPaid;
|
private final BigDecimal depositPaid;
|
||||||
|
private final BigDecimal interestAccured;
|
||||||
|
|
||||||
public SavingSchedulePeriodData(final Integer period, final LocalDate dueDate, final BigDecimal depositDue, final BigDecimal depositPaid) {
|
public SavingSchedulePeriodData(final Integer period, final LocalDate dueDate, final BigDecimal depositDue, final BigDecimal depositPaid, final BigDecimal interestAccured) {
|
||||||
this.period = period;
|
this.period = period;
|
||||||
this.dueDate = dueDate;
|
this.dueDate = dueDate;
|
||||||
this.depositDue = depositDue;
|
this.depositDue = depositDue;
|
||||||
this.depositPaid = depositPaid;
|
this.depositPaid = depositPaid;
|
||||||
|
this.interestAccured = interestAccured;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SavingSchedulePeriodData addScheduleInformation(int periodNumber, LocalDate scheduleDate,
|
public static SavingSchedulePeriodData addScheduleInformation(int periodNumber, LocalDate scheduleDate,
|
||||||
BigDecimal depositAmountPerPeriod) {
|
BigDecimal depositAmountPerPeriod, BigDecimal interestAccured) {
|
||||||
return new SavingSchedulePeriodData(periodNumber, scheduleDate, depositAmountPerPeriod, BigDecimal.ZERO);
|
return new SavingSchedulePeriodData(periodNumber, scheduleDate, depositAmountPerPeriod, BigDecimal.ZERO, interestAccured);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getPeriod() {
|
public Integer getPeriod() {
|
||||||
@@ -39,5 +41,7 @@ public class SavingSchedulePeriodData {
|
|||||||
return this.depositPaid;
|
return this.depositPaid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal getInterestAccured() {
|
||||||
|
return this.interestAccured;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -3,11 +3,11 @@ package org.mifosplatform.portfolio.savingsaccount.domain;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||||
|
|
||||||
public interface DepositScheduleDateGenerator {
|
public interface DepositScheduleDateGenerator {
|
||||||
|
|
||||||
List<LocalDate> generate(LocalDate startDate, Integer paymentPeriods, Integer depositFrequency, PeriodFrequencyType depositFrequencyType);
|
List<LocalDate> generate(LocalDate startDate, Integer paymentPeriods, Integer depositFrequency, SavingFrequencyType savingFrequencyType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-9
@@ -34,27 +34,29 @@ public class ReccuringDepositInterestCalculator {
|
|||||||
|
|
||||||
if(savingInterestCalculationMethod.isAverageBalance()){
|
if(savingInterestCalculationMethod.isAverageBalance()){
|
||||||
|
|
||||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
|
||||||
BigDecimal termAmount = BigDecimal.ZERO;
|
BigDecimal termAmount = BigDecimal.ZERO;
|
||||||
BigDecimal totalInterest = BigDecimal.ZERO;
|
BigDecimal totalInterest = BigDecimal.ZERO;
|
||||||
|
BigDecimal closingBalance = BigDecimal.ZERO;
|
||||||
BigDecimal amountPerPeriod = savingsDepositPerPeriod.getAmount();
|
BigDecimal amountPerPeriod = savingsDepositPerPeriod.getAmount();
|
||||||
Integer depositEveryOriginalValue = depositEvery;
|
Integer depositEveryOriginalValue = depositEvery;
|
||||||
BigDecimal amountPermonth = amountPerPeriod.divide(BigDecimal.valueOf(depositEvery.doubleValue()));
|
BigDecimal amountPermonth = BigDecimal.valueOf(amountPerPeriod.doubleValue()/depositEvery.doubleValue());
|
||||||
|
|
||||||
while (noOfTimestobeCalculated > 0) {
|
while (noOfTimestobeCalculated > 0) {
|
||||||
while (depositEvery > 0) {
|
while (depositEvery > 0) {
|
||||||
termAmount = termAmount.add(amountPermonth);
|
closingBalance = closingBalance.add(amountPermonth);
|
||||||
totalAmount = totalAmount.add(termAmount);
|
termAmount = termAmount.add(closingBalance);
|
||||||
depositEvery--;
|
depositEvery--;
|
||||||
}
|
}
|
||||||
BigDecimal averageAmount = BigDecimal.valueOf(totalAmount.doubleValue()/depositEveryOriginalValue.doubleValue());
|
|
||||||
|
BigDecimal averageAmount = BigDecimal.valueOf(termAmount.doubleValue()/depositEveryOriginalValue.doubleValue());
|
||||||
BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/monthsInYear.doubleValue()*depositEveryOriginalValue.doubleValue());
|
BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/monthsInYear.doubleValue()*depositEveryOriginalValue.doubleValue());
|
||||||
BigDecimal interestperTerm = averageAmount.multiply(interestRatePerTerm);
|
BigDecimal interestperTerm = averageAmount.multiply(interestRatePerTerm);
|
||||||
totalInterest = totalInterest.add(interestperTerm);
|
totalInterest = totalInterest.add(interestperTerm);
|
||||||
depositEvery = depositEveryOriginalValue;
|
depositEvery = depositEveryOriginalValue;
|
||||||
totalAmount = BigDecimal.ZERO;
|
termAmount = BigDecimal.ZERO;
|
||||||
noOfTimestobeCalculated--;
|
noOfTimestobeCalculated--;
|
||||||
}
|
}
|
||||||
finalAmount = termAmount.add(totalInterest);
|
finalAmount = closingBalance.add(totalInterest);
|
||||||
|
|
||||||
} else if(savingInterestCalculationMethod.isMonthlyCollection()){
|
} else if(savingInterestCalculationMethod.isMonthlyCollection()){
|
||||||
/*
|
/*
|
||||||
@@ -73,14 +75,15 @@ public class ReccuringDepositInterestCalculator {
|
|||||||
BigDecimal monthsExpressedInYears;
|
BigDecimal monthsExpressedInYears;
|
||||||
BigDecimal timeforOneCalculationPeriod;
|
BigDecimal timeforOneCalculationPeriod;
|
||||||
BigDecimal amountPerPeriod;
|
BigDecimal amountPerPeriod;
|
||||||
|
Integer tempTenure = tenure;
|
||||||
while (noOfTimestobeCalculated > 0) {
|
while (noOfTimestobeCalculated > 0) {
|
||||||
monthsExpressedInYears = BigDecimal.valueOf(tenure.doubleValue() / monthsInYear.doubleValue());
|
monthsExpressedInYears = BigDecimal.valueOf(tempTenure.doubleValue() / monthsInYear.doubleValue());
|
||||||
timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear * monthsExpressedInYears.doubleValue());
|
timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear * monthsExpressedInYears.doubleValue());
|
||||||
amountPerPeriod = savingsDepositPerPeriod.getAmount().multiply(
|
amountPerPeriod = savingsDepositPerPeriod.getAmount().multiply(
|
||||||
BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(), timeforOneCalculationPeriod.doubleValue())));
|
BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(), timeforOneCalculationPeriod.doubleValue())));
|
||||||
finalAmount = finalAmount.add(amountPerPeriod);
|
finalAmount = finalAmount.add(amountPerPeriod);
|
||||||
noOfTimestobeCalculated--;
|
noOfTimestobeCalculated--;
|
||||||
|
tempTenure = tempTenure-depositEvery;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Money.of(savingsDepositPerPeriod.getCurrency(), finalAmount);
|
return Money.of(savingsDepositPerPeriod.getCurrency(), finalAmount);
|
||||||
|
|||||||
+54
-38
@@ -204,12 +204,13 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
Integer depositEvery, Integer interestPostEvery, Integer interestPostFrequency) {
|
Integer depositEvery, Integer interestPostEvery, Integer interestPostFrequency) {
|
||||||
|
|
||||||
Money futureValueOnMaturity = null;
|
Money futureValueOnMaturity = null;
|
||||||
if (savingProductType.isReccuring()) {
|
if (savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod()) {
|
||||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
||||||
reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,depositEvery);
|
reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,depositEvery);
|
||||||
} else if (savingProductType.isRegular()) {
|
} else if (savingProductType.isReccuring() && tenureTypeEnum.isPerpetual()) {
|
||||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
futureValueOnMaturity = savingsDeposit;
|
||||||
savingInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,depositEvery);
|
} else {
|
||||||
|
futureValueOnMaturity = savingsDeposit;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure,
|
return new SavingAccount(client, externalId, product, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure,
|
||||||
@@ -255,8 +256,8 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.lockinPeriod = lockinPeriod;
|
this.lockinPeriod = lockinPeriod;
|
||||||
this.lockinPeriodType = lockinPeriodType.getValue();
|
this.lockinPeriodType = lockinPeriodType.getValue();
|
||||||
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
||||||
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.getAmount().subtract(
|
BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); //presently only for months
|
||||||
BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); //presently only for months
|
this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring : BigDecimal.ZERO;
|
||||||
this.payEvery = payEvery;
|
this.payEvery = payEvery;
|
||||||
this.outstandingAmount = BigDecimal.ZERO;
|
this.outstandingAmount = BigDecimal.ZERO;
|
||||||
this.interestPostEvery = interestPostEvery;
|
this.interestPostEvery = interestPostEvery;
|
||||||
@@ -267,15 +268,17 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum,
|
BigDecimal savingInterestRate, Integer tenure, LocalDate commencementDate, TenureTypeEnum tenureTypeEnum,
|
||||||
SavingProductType savingProductType, SavingFrequencyType savingFrequencyType,
|
SavingProductType savingProductType, SavingFrequencyType savingFrequencyType,
|
||||||
SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod,
|
SavingInterestCalculationMethod savingInterestCalculationMethod, boolean isLockinPeriodAllowed, Integer lockinPeriod,
|
||||||
PeriodFrequencyType lockinPeriodType, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,Integer payEvery) {
|
PeriodFrequencyType lockinPeriodType, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,Integer payEvery,
|
||||||
|
SavingsInterestType interestType, Integer interestPostEvery, Integer interestPostFrequency) {
|
||||||
|
|
||||||
Money futureValueOnMaturity = null;
|
Money futureValueOnMaturity = null;
|
||||||
if (savingProductType.isReccuring()) {
|
if (savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod()) {
|
||||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
||||||
reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,payEvery);
|
reccuringInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,payEvery);
|
||||||
} else if (savingProductType.isRegular()) {
|
} else if (savingProductType.isReccuring() && tenureTypeEnum.isPerpetual()) {
|
||||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsDeposit, tenure,
|
futureValueOnMaturity = savingsDeposit;
|
||||||
savingInterestRate, commencementDate, tenureTypeEnum, savingFrequencyType, savingInterestCalculationMethod,payEvery);
|
} else {
|
||||||
|
futureValueOnMaturity = savingsDeposit;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.product = product;
|
this.product = product;
|
||||||
@@ -288,17 +291,20 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.tenureType = tenureTypeEnum.getValue();
|
this.tenureType = tenureTypeEnum.getValue();
|
||||||
this.savingProductType = savingProductType.getValue();
|
this.savingProductType = savingProductType.getValue();
|
||||||
this.frequency = savingFrequencyType.getValue();
|
this.frequency = savingFrequencyType.getValue();
|
||||||
|
this.interestType = interestType.getValue();
|
||||||
this.interestCalculationMethod = savingInterestCalculationMethod.getValue();
|
this.interestCalculationMethod = savingInterestCalculationMethod.getValue();
|
||||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||||
this.lockinPeriod = lockinPeriod;
|
this.lockinPeriod = lockinPeriod;
|
||||||
this.lockinPeriodType = lockinPeriodType.getValue();
|
this.lockinPeriodType = lockinPeriodType.getValue();
|
||||||
this.payEvery = payEvery;
|
this.payEvery = payEvery;
|
||||||
this.outstandingAmount = BigDecimal.ZERO;
|
this.outstandingAmount = BigDecimal.ZERO;
|
||||||
|
this.interestPostEvery = interestPostEvery;
|
||||||
|
this.interestPostFrequency=interestPostFrequency;
|
||||||
|
this.savingScheduleInstallments.clear();
|
||||||
|
|
||||||
// FIXME - MADHUKAR - futureValueOnMaturity is possibly null
|
|
||||||
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
||||||
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.getAmount().subtract(
|
BigDecimal projectedInterestForReccuring = futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue() / payEvery)); //presently only for months
|
||||||
BigDecimal.valueOf(savingsDeposit.getAmount().doubleValue() * tenure.doubleValue()));
|
this.projectedInterestAccruedOnMaturity = savingProductType.isReccuring() && tenureTypeEnum.isFixedPeriod() ? projectedInterestForReccuring : BigDecimal.ZERO;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDeleted() {
|
public boolean isDeleted() {
|
||||||
@@ -456,6 +462,7 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.maturesOnDate = null;
|
this.maturesOnDate = null;
|
||||||
this.withdrawnOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
this.withdrawnOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
||||||
this.closedOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
this.closedOnDate = withdrawnOn.toDateTimeAtCurrentTime().toDate();
|
||||||
|
this.savingScheduleInstallments.clear();
|
||||||
|
|
||||||
if (withdrawnOn.isBefore(projectedCommencementDate())) {
|
if (withdrawnOn.isBefore(projectedCommencementDate())) {
|
||||||
|
|
||||||
@@ -480,7 +487,6 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.closedOnDate = new Date();
|
this.closedOnDate = new Date();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("null")
|
|
||||||
public void approveSavingAccount(LocalDate approvalDate, BigDecimal savingsDepositAmountPerPeriod, BigDecimal recurringInterestRate,
|
public void approveSavingAccount(LocalDate approvalDate, BigDecimal savingsDepositAmountPerPeriod, BigDecimal recurringInterestRate,
|
||||||
BigDecimal savingInterestRate, Integer interestType, Integer tenure, Integer tenureType, Integer frequency, Integer payEvery,
|
BigDecimal savingInterestRate, Integer interestType, Integer tenure, Integer tenureType, Integer frequency, Integer payEvery,
|
||||||
DepositLifecycleStateMachine depositLifecycleStateMachine, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,
|
DepositLifecycleStateMachine depositLifecycleStateMachine, ReccuringDepositInterestCalculator reccuringDepositInterestCalculator,
|
||||||
@@ -496,12 +502,13 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(this.interestCalculationMethod);
|
SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(this.interestCalculationMethod);
|
||||||
|
|
||||||
Money futureValueOnMaturity = null;
|
Money futureValueOnMaturity = null;
|
||||||
if (SavingProductType.fromInt(product.getSavingProductRelatedDetail().getSavingProductType()).isReccuring()) {
|
if (SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isFixedPeriod()) {
|
||||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsAmountPerPeriod, tenure,
|
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsAmountPerPeriod, tenure,
|
||||||
recurringInterestRate, approvalDate, tenureTypeEnum, savingFrequencyType, interestCalculationMethod,payEvery);
|
recurringInterestRate, approvalDate, tenureTypeEnum, savingFrequencyType, interestCalculationMethod,payEvery);
|
||||||
} else if (SavingProductType.fromInt(product.getSavingProductRelatedDetail().getSavingProductType()).isRegular()) {
|
} else if (SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isPerpetual()) {
|
||||||
futureValueOnMaturity = reccuringDepositInterestCalculator.calculateInterestOnMaturityFor(savingsAmountPerPeriod, tenure,
|
futureValueOnMaturity = savingsAmountPerPeriod;
|
||||||
savingInterestRate, approvalDate, tenureTypeEnum, savingFrequencyType, interestCalculationMethod,payEvery);
|
} else {
|
||||||
|
futureValueOnMaturity = savingsAmountPerPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actualCommencementDate = approvalDate.toDate();
|
this.actualCommencementDate = approvalDate.toDate();
|
||||||
@@ -515,7 +522,8 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.payEvery = payEvery;
|
this.payEvery = payEvery;
|
||||||
this.savingScheduleInstallments.clear();
|
this.savingScheduleInstallments.clear();
|
||||||
this.total=futureValueOnMaturity.getAmount();
|
this.total=futureValueOnMaturity.getAmount();
|
||||||
this.interestAccrued = futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDepositAmountPerPeriod.doubleValue() * tenure/payEvery.doubleValue()));
|
BigDecimal interestForReccuring = futureValueOnMaturity.getAmount().subtract(BigDecimal.valueOf(savingsDepositAmountPerPeriod.doubleValue() * tenure.doubleValue()/payEvery.doubleValue())); //presently only for months
|
||||||
|
this.interestAccrued = SavingProductType.fromInt(this.savingProductType).isReccuring() && tenureTypeEnum.isFixedPeriod() ? interestForReccuring : BigDecimal.ZERO;
|
||||||
this.interestPostEvery = interestPostEvery;
|
this.interestPostEvery = interestPostEvery;
|
||||||
this.interestPostFrequency = interestPostFrequency;
|
this.interestPostFrequency = interestPostFrequency;
|
||||||
|
|
||||||
@@ -537,25 +545,32 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.outstandingAmount = this.outstandingAmount.add(command.getSavingsDepostiAmountPerPeriod());
|
this.outstandingAmount = this.outstandingAmount.add(command.getSavingsDepostiAmountPerPeriod());
|
||||||
this.totalSavingsAmount = this.totalSavingsAmount.add(command.getSavingsDepostiAmountPerPeriod());
|
this.totalSavingsAmount = this.totalSavingsAmount.add(command.getSavingsDepostiAmountPerPeriod());
|
||||||
|
|
||||||
for(SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments){
|
if(SavingProductType.fromInt(this.savingProductType).isReccuring() && TenureTypeEnum.fromInt(tenureType).isFixedPeriod()) {
|
||||||
if(!savingScheduleInstallment.isCompleted()){
|
for(SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments){
|
||||||
depositAmount = savingScheduleInstallment.getDeposit();
|
if(!savingScheduleInstallment.isCompleted()){
|
||||||
remainAmountToBePaid = depositAmount.subtract(savingScheduleInstallment.getDepositPaid());
|
depositAmount = savingScheduleInstallment.getDeposit();
|
||||||
if (remainAmountToBePaid.doubleValue() > 0) {
|
remainAmountToBePaid = depositAmount.subtract(savingScheduleInstallment.getDepositPaid());
|
||||||
if (commandRemainDepositAmount.doubleValue() > 0) {
|
if (remainAmountToBePaid.doubleValue() > 0) {
|
||||||
if (commandRemainDepositAmount.doubleValue() >= remainAmountToBePaid.doubleValue()) {
|
if (commandRemainDepositAmount.doubleValue() > 0) {
|
||||||
savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid()));
|
if (commandRemainDepositAmount.doubleValue() >= remainAmountToBePaid.doubleValue()) {
|
||||||
savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate());
|
savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid()));
|
||||||
savingScheduleInstallment.setCompleted(true);
|
savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate());
|
||||||
commandRemainDepositAmount = commandRemainDepositAmount.subtract(remainAmountToBePaid);
|
savingScheduleInstallment.setCompleted(true);
|
||||||
} else if(commandRemainDepositAmount.doubleValue() < remainAmountToBePaid.doubleValue()){
|
commandRemainDepositAmount = commandRemainDepositAmount.subtract(remainAmountToBePaid);
|
||||||
savingScheduleInstallment.setDepositPaid(commandRemainDepositAmount.add(savingScheduleInstallment.getDepositPaid()));
|
} else if(commandRemainDepositAmount.doubleValue() < remainAmountToBePaid.doubleValue()){
|
||||||
savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate());
|
savingScheduleInstallment.setDepositPaid(commandRemainDepositAmount.add(savingScheduleInstallment.getDepositPaid()));
|
||||||
commandRemainDepositAmount = BigDecimal.ZERO;
|
savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate());
|
||||||
|
commandRemainDepositAmount = BigDecimal.ZERO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for(SavingScheduleInstallments savingScheduleInstallment : this.savingScheduleInstallments){
|
||||||
|
savingScheduleInstallment.setDepositPaid(remainAmountToBePaid.add(savingScheduleInstallment.getDepositPaid()));
|
||||||
|
savingScheduleInstallment.setPaymentDate(command.getDepositDate().toDate());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,7 +597,7 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
this.externalId = this.getId() + "_" + this.externalId;
|
this.externalId = this.getId() + "_" + this.externalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postInterest(ReccuringDepositInterestCalculator reccuringDepositInterestCalculator) {
|
public void postInterest() {
|
||||||
|
|
||||||
LocalDate lastInterestPostedDate = getLastInterestPostedDate();
|
LocalDate lastInterestPostedDate = getLastInterestPostedDate();
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@@ -643,8 +658,9 @@ public class SavingAccount extends AbstractAuditableCustom<AppUser, Long> {
|
|||||||
termTotalAmount = termTotalAmount.add(totalOutstandingAmount);
|
termTotalAmount = termTotalAmount.add(totalOutstandingAmount);
|
||||||
transactionStartDate = transactionEndDate;
|
transactionStartDate = transactionEndDate;
|
||||||
isOutstandingAmountCalculated = true;
|
isOutstandingAmountCalculated = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
// FIXME-MADHUKAR calculate interest on calculation method
|
// TODO- calculate interest on calculation method
|
||||||
|
|
||||||
// if (savingInterestCalculationMethod.isAverageBalance()) {
|
// if (savingInterestCalculationMethod.isAverageBalance()) {
|
||||||
averageBalanceForTerm =BigDecimal.valueOf(termTotalAmount.doubleValue()/this.interestPostEvery);
|
averageBalanceForTerm =BigDecimal.valueOf(termTotalAmount.doubleValue()/this.interestPostEvery);
|
||||||
|
|||||||
+6
-1
@@ -45,6 +45,10 @@ public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser,
|
|||||||
@Column(name = "deposit_paid", scale = 6, precision = 19, nullable = true)
|
@Column(name = "deposit_paid", scale = 6, precision = 19, nullable = true)
|
||||||
private BigDecimal depositPaid;
|
private BigDecimal depositPaid;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Column(name = "interest_accured", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal interstAccured;
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Column(name = "completed_derived", nullable = false)
|
@Column(name = "completed_derived", nullable = false)
|
||||||
private boolean completed;
|
private boolean completed;
|
||||||
@@ -55,7 +59,7 @@ public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser,
|
|||||||
this.paymentDate = null;
|
this.paymentDate = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingScheduleInstallments(SavingAccount account, Date dueDate, Integer installmentNumber, BigDecimal deposit) {
|
public SavingScheduleInstallments(SavingAccount account, Date dueDate, Integer installmentNumber, BigDecimal deposit, BigDecimal interstAccured) {
|
||||||
this.savingAccount = account;
|
this.savingAccount = account;
|
||||||
this.dueDate = dueDate;
|
this.dueDate = dueDate;
|
||||||
this.installmentNumber = installmentNumber;
|
this.installmentNumber = installmentNumber;
|
||||||
@@ -63,6 +67,7 @@ public class SavingScheduleInstallments extends AbstractAuditableCustom<AppUser,
|
|||||||
this.paymentDate = null;
|
this.paymentDate = null;
|
||||||
this.depositPaid = BigDecimal.ZERO;
|
this.depositPaid = BigDecimal.ZERO;
|
||||||
this.completed = false;
|
this.completed = false;
|
||||||
|
this.interstAccured = interstAccured;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateAccount(SavingAccount account) {
|
public void updateAccount(SavingAccount account) {
|
||||||
|
|||||||
+25
-5
@@ -1,17 +1,24 @@
|
|||||||
package org.mifosplatform.portfolio.savingsaccount.service;
|
package org.mifosplatform.portfolio.savingsaccount.service;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
|
||||||
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepository;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
|
||||||
import org.mifosplatform.portfolio.savingsaccount.command.CalculateSavingScheduleCommand;
|
import org.mifosplatform.portfolio.savingsaccount.command.CalculateSavingScheduleCommand;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
||||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductRepository;
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductRepository;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProductType;
|
||||||
import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingProductNotFoundException;
|
import org.mifosplatform.portfolio.savingsaccountproduct.exception.SavingProductNotFoundException;
|
||||||
|
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -36,23 +43,36 @@ public class CalculateSavingScheduleImpl implements CalculateSavingSchedule {
|
|||||||
public SavingScheduleData calculateSavingSchedule(CalculateSavingScheduleCommand command) {
|
public SavingScheduleData calculateSavingSchedule(CalculateSavingScheduleCommand command) {
|
||||||
|
|
||||||
context.authenticatedUser();
|
context.authenticatedUser();
|
||||||
|
SavingScheduleData savingScheduleData = null;
|
||||||
|
|
||||||
// FIXME Validations should write here
|
// FIXME Validations should write here
|
||||||
final SavingProduct savingProduct = this.savingProductRepository.findOne(command.getProductId());
|
final SavingProduct savingProduct = this.savingProductRepository.findOne(command.getProductId());
|
||||||
if (savingProduct == null) throw new SavingProductNotFoundException(command.getProductId());
|
if (savingProduct == null) throw new SavingProductNotFoundException(command.getProductId());
|
||||||
|
|
||||||
final Integer depositFrequency = command.getDepositEvery();
|
final Integer depositFrequency = command.getDepositEvery();
|
||||||
final PeriodFrequencyType depositFrequencyType = PeriodFrequencyType.fromInt(command.getPaymentFrequencyType());
|
final SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(command.getPaymentFrequencyType());
|
||||||
final LocalDate scheduleStartDate = command.getPaymentsStartingFromDate();
|
final LocalDate scheduleStartDate = command.getPaymentsStartingFromDate();
|
||||||
@SuppressWarnings("unused")
|
|
||||||
final BigDecimal interestRate = command.getInterestRate();
|
final BigDecimal interestRate = command.getInterestRate();
|
||||||
final BigDecimal depositAmountPerPeriod = command.getDeposit();
|
final BigDecimal depositAmountPerPeriod = command.getDeposit();
|
||||||
final Integer tenure = command.getTenure();
|
final Integer tenure = command.getTenure();
|
||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency()
|
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneByCode(savingProduct.getCurrency()
|
||||||
.getCode());
|
.getCode());
|
||||||
|
|
||||||
SavingScheduleData savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod,
|
SavingProductType savingProductType = SavingProductType.fromInt(savingProduct.getSavingProductRelatedDetail().getSavingProductType());
|
||||||
depositFrequency, depositFrequencyType, savingProduct, tenure, applicationCurrency);
|
TenureTypeEnum tenureType = TenureTypeEnum.fromInt(command.getTenureType());
|
||||||
|
SavingInterestCalculationMethod interestCalculationMethod = SavingInterestCalculationMethod.fromInt(command.getInterestCalculationMethod());
|
||||||
|
if (savingProductType.isReccuring() && tenureType.isFixedPeriod()) {
|
||||||
|
savingScheduleData = savingScheduleGenerator.generate(scheduleStartDate, depositAmountPerPeriod,
|
||||||
|
depositFrequency, savingFrequencyType, savingProduct, tenure, applicationCurrency,interestRate,interestCalculationMethod);
|
||||||
|
} else {
|
||||||
|
final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
|
||||||
|
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(),
|
||||||
|
savingProduct.getCurrency().getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||||
|
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(1, new LocalDate(command.getPaymentsStartingFromDate()).plusMonths(depositFrequency), command.getDeposit(), BigDecimal.ZERO);
|
||||||
|
periods.add(installment);
|
||||||
|
savingScheduleData = new SavingScheduleData(currencyData, command.getDeposit(), BigDecimal.ZERO, BigDecimal.ZERO, periods);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return savingScheduleData;
|
return savingScheduleData;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-11
@@ -4,14 +4,14 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
|
||||||
import org.mifosplatform.portfolio.savingsaccount.domain.DepositScheduleDateGenerator;
|
import org.mifosplatform.portfolio.savingsaccount.domain.DepositScheduleDateGenerator;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||||
|
|
||||||
public class DefaultDepositScheduleDateGenerator implements DepositScheduleDateGenerator {
|
public class DefaultDepositScheduleDateGenerator implements DepositScheduleDateGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<LocalDate> generate(LocalDate scheuleStartDate, Integer paymentPeriods, Integer depositFrequency,
|
public List<LocalDate> generate(LocalDate scheuleStartDate, Integer paymentPeriods, Integer depositFrequency,
|
||||||
PeriodFrequencyType depositFrequencyType) {
|
SavingFrequencyType savingFrequencyType) {
|
||||||
|
|
||||||
List<LocalDate> duePaymentPeriodDates = new ArrayList<LocalDate>(depositFrequency);
|
List<LocalDate> duePaymentPeriodDates = new ArrayList<LocalDate>(depositFrequency);
|
||||||
LocalDate startDate = scheuleStartDate;
|
LocalDate startDate = scheuleStartDate;
|
||||||
@@ -22,21 +22,24 @@ public class DefaultDepositScheduleDateGenerator implements DepositScheduleDateG
|
|||||||
if (period == 1) {
|
if (period == 1) {
|
||||||
duePaymentPeriodDate = startDate;
|
duePaymentPeriodDate = startDate;
|
||||||
} else {
|
} else {
|
||||||
switch (depositFrequencyType) {
|
switch (savingFrequencyType) {
|
||||||
case DAYS:
|
case DAILY:
|
||||||
duePaymentPeriodDate = startDate.plusDays(depositFrequency);
|
duePaymentPeriodDate = startDate.plusDays(depositFrequency);
|
||||||
break;
|
break;
|
||||||
case WEEKS:
|
case MONTHLY:
|
||||||
duePaymentPeriodDate = startDate.plusWeeks(depositFrequency);
|
|
||||||
break;
|
|
||||||
case MONTHS:
|
|
||||||
duePaymentPeriodDate = startDate.plusMonths(depositFrequency);
|
duePaymentPeriodDate = startDate.plusMonths(depositFrequency);
|
||||||
break;
|
break;
|
||||||
case YEARS:
|
case QUATERLY:
|
||||||
duePaymentPeriodDate = startDate.plusYears(depositFrequency);
|
duePaymentPeriodDate = startDate.plusMonths(3*depositFrequency);
|
||||||
break;
|
break;
|
||||||
case INVALID:
|
case HALFYEARLY:
|
||||||
|
duePaymentPeriodDate = startDate.plusMonths(6*depositFrequency);
|
||||||
break;
|
break;
|
||||||
|
case YEARLY:
|
||||||
|
duePaymentPeriodDate = startDate.plusYears(depositFrequency);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
duePaymentPeriodDates.add(duePaymentPeriodDate);
|
duePaymentPeriodDates.add(duePaymentPeriodDate);
|
||||||
|
|||||||
+24
-11
@@ -80,9 +80,6 @@ public class SavingAccountAssembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SavingProductType savingProductType = SavingProductType.fromInt(product.getSavingProductRelatedDetail().getSavingProductType());
|
SavingProductType savingProductType = SavingProductType.fromInt(product.getSavingProductRelatedDetail().getSavingProductType());
|
||||||
if (command.getSavingProductType() != null) {
|
|
||||||
savingProductType = SavingProductType.fromInt(command.getSavingProductType());
|
|
||||||
}
|
|
||||||
|
|
||||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(product.getSavingProductRelatedDetail().getFrequency());
|
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(product.getSavingProductRelatedDetail().getFrequency());
|
||||||
if (command.getFrequency() != null) {
|
if (command.getFrequency() != null) {
|
||||||
@@ -135,7 +132,7 @@ public class SavingAccountAssembler {
|
|||||||
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
||||||
|
|
||||||
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
||||||
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue());
|
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(), savingSchedulePeriodData.getInterestAccured());
|
||||||
account.addSavingScheduleInstallment(installment);
|
account.addSavingScheduleInstallment(installment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,9 +174,6 @@ public class SavingAccountAssembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SavingProductType savingProductType = SavingProductType.fromInt(account.getSavingProductType());
|
SavingProductType savingProductType = SavingProductType.fromInt(account.getSavingProductType());
|
||||||
if (command.isSavingProductTypeChanged()) {
|
|
||||||
savingProductType = SavingProductType.fromInt(command.getSavingProductType());
|
|
||||||
}
|
|
||||||
|
|
||||||
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(account.getFrequency());
|
SavingFrequencyType savingFrequencyType = SavingFrequencyType.fromInt(account.getFrequency());
|
||||||
if (command.isSavingFrequencyTypeChanged()) {
|
if (command.isSavingFrequencyTypeChanged()) {
|
||||||
@@ -220,9 +214,28 @@ public class SavingAccountAssembler {
|
|||||||
if(command.isDepositEveryChanged()){
|
if(command.isDepositEveryChanged()){
|
||||||
payEvery = command.getDepositEvery();
|
payEvery = command.getDepositEvery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SavingsInterestType interestType = SavingsInterestType.fromInt(product.getSavingProductRelatedDetail().getInterestType());
|
||||||
|
if (command.getInterestType() != null) {
|
||||||
|
interestType = SavingsInterestType.fromInt(command.getInterestType());
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer interestPostEvery = command.getInterestPostEvery();
|
||||||
|
|
||||||
|
Integer interestPostFrequency =command.getInterestPostFrequency();
|
||||||
|
|
||||||
account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, commencementDate,
|
account.modifyAccount(product, externalId, savingsDeposit, reccuringInterestRate, savingInterestRate, tenure, commencementDate,
|
||||||
tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, isLockinPeriodAllowed,
|
tenureTypeEnum, savingProductType, savingFrequencyType, savingInterestCalculationMethod, isLockinPeriodAllowed,
|
||||||
lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator,payEvery);
|
lockinPeriod, lockinPeriodType, this.reccuringDepositInterestCalculator,payEvery, interestType, interestPostEvery, interestPostFrequency);
|
||||||
|
|
||||||
|
SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(command
|
||||||
|
.toCalculateSavingScheduleCommand());
|
||||||
|
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
||||||
|
|
||||||
|
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
||||||
|
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(), savingSchedulePeriodData.getInterestAccured());
|
||||||
|
account.addSavingScheduleInstallment(installment);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,13 +305,13 @@ public class SavingAccountAssembler {
|
|||||||
|
|
||||||
|
|
||||||
CalculateSavingScheduleCommand calculateSavingScheduleCommand = new CalculateSavingScheduleCommand(account.getProduct().getId(), savingsDepositAmountPerPeriod, payEvery,
|
CalculateSavingScheduleCommand calculateSavingScheduleCommand = new CalculateSavingScheduleCommand(account.getProduct().getId(), savingsDepositAmountPerPeriod, payEvery,
|
||||||
frequency, recurringInterestRate, approvalDate, tenure,interestPostEvery,interestPostFrequency);
|
frequency, recurringInterestRate, approvalDate, tenure,tenureType,interestPostEvery,interestPostFrequency,account.getInterestCalculationMethod());
|
||||||
|
|
||||||
SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(calculateSavingScheduleCommand);
|
SavingScheduleData savingScheduleData = this.calculateSavingSchedule.calculateSavingSchedule(calculateSavingScheduleCommand);
|
||||||
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
for (SavingSchedulePeriodData savingSchedulePeriodData : savingScheduleData.getPeriods()) {
|
||||||
|
|
||||||
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
final SavingScheduleInstallments installment = new SavingScheduleInstallments(account, savingSchedulePeriodData.getDueDate()
|
||||||
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue());
|
.toDate(), savingSchedulePeriodData.getPeriod(), savingSchedulePeriodData.getDepositDue(),savingSchedulePeriodData.getInterestAccured());
|
||||||
account.addSavingScheduleInstallment(installment);
|
account.addSavingScheduleInstallment(installment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,7 +328,7 @@ public class SavingAccountAssembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void postInterest(SavingAccount account) {
|
public void postInterest(SavingAccount account) {
|
||||||
account.postInterest(this.reccuringDepositInterestCalculator);
|
account.postInterest();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+3
@@ -6,6 +6,7 @@ import java.util.Collection;
|
|||||||
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountTransactionsData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||||
|
|
||||||
@@ -24,4 +25,6 @@ public interface SavingAccountReadPlatformService {
|
|||||||
SavingScheduleData retrieveSavingsAccountSchedule(Long accountId, CurrencyData currencyData);
|
SavingScheduleData retrieveSavingsAccountSchedule(Long accountId, CurrencyData currencyData);
|
||||||
|
|
||||||
Collection<SavingAccountForLookup> retrieveSavingAccountsForLookUp();
|
Collection<SavingAccountForLookup> retrieveSavingAccountsForLookUp();
|
||||||
|
|
||||||
|
Collection<SavingAccountTransactionsData> retrieveSavingsAccountTransactions(Long accountId);
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-7
@@ -17,6 +17,7 @@ import org.mifosplatform.portfolio.client.data.ClientData;
|
|||||||
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountForLookup;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingAccountTransactionsData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingPermissionData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
||||||
@@ -25,6 +26,7 @@ import org.mifosplatform.portfolio.savingsaccountproduct.data.SavingProductLooku
|
|||||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations;
|
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductEnumerations;
|
||||||
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductReadPlatformService;
|
import org.mifosplatform.portfolio.savingsaccountproduct.service.SavingProductReadPlatformService;
|
||||||
import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountEnumerations;
|
import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountEnumerations;
|
||||||
|
import org.mifosplatform.portfolio.savingsdepositaccount.service.DepositAccountTransactionEnumerations;
|
||||||
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
import org.mifosplatform.portfolio.savingsdepositproduct.domain.TenureTypeEnum;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
@@ -85,6 +87,7 @@ public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPl
|
|||||||
+ " sa.pre_closure_interest_rate AS preClosureInterestRate, sa.is_lock_in_period_allowed AS isLockinPeriodAllowed,"
|
+ " 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.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, sa.deposit_every as depositEvery, "
|
+ " sa.rejectedon_date AS rejectedonDate, sa.closedon_date AS closedonDate, ps.name AS productName, sa.deposit_every as depositEvery, "
|
||||||
|
+ " sa.interest_posting_every AS interestPostEvery, sa.interest_posting_frequency AS interestPostFrequency, "
|
||||||
+ " c.firstname AS firstname, c.lastname AS lastname, curr.name AS currencyName, "
|
+ " c.firstname AS firstname, c.lastname AS lastname, curr.name AS currencyName, "
|
||||||
+ " curr.internationalized_name_code AS currencyNameCode, curr.display_symbol AS currencyDisplaySymbol "
|
+ " 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"
|
+ " FROM m_saving_account sa " + " JOIN m_client c ON c.id = sa.client_id"
|
||||||
@@ -151,12 +154,16 @@ public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPl
|
|||||||
EnumOptionData lockinPeriodType = SavingProductEnumerations.savingsLockinPeriod(lockinPeriodTypeValue);
|
EnumOptionData lockinPeriodType = SavingProductEnumerations.savingsLockinPeriod(lockinPeriodTypeValue);
|
||||||
Integer depositEvery = JdbcSupport.getInteger(rs, "depositEvery");
|
Integer depositEvery = JdbcSupport.getInteger(rs, "depositEvery");
|
||||||
|
|
||||||
|
Integer interestPostEvery = JdbcSupport.getInteger(rs, "interestPostEvery");
|
||||||
|
EnumOptionData interestPostFrequency = SavingProductEnumerations.interestFrequencyType(JdbcSupport.getInteger(rs, "interestPostFrequency"));
|
||||||
|
|
||||||
|
|
||||||
return new SavingAccountData(id, status, externalId, clientId, clientName, productId, productName, productType, currencyData,
|
return new SavingAccountData(id, status, externalId, clientId, clientName, productId, productName, productType, currencyData,
|
||||||
savingsDepostiAmountPerPeriod, savingsFrequencyType, totalDepositAmount, reccuringInterestRate, savingInterestRate,
|
savingsDepostiAmountPerPeriod, savingsFrequencyType, totalDepositAmount, reccuringInterestRate, savingInterestRate,
|
||||||
interestType, interestCalculationMethod, tenure, tenureType, projectedCommencementDate, actualCommencementDate,
|
interestType, interestCalculationMethod, tenure, tenureType, projectedCommencementDate, actualCommencementDate,
|
||||||
maturesOnDate, projectedInterestAccuredOnMaturity, actualInterestAccured, projectedMaturityAmount,
|
maturesOnDate, projectedInterestAccuredOnMaturity, actualInterestAccured, projectedMaturityAmount,
|
||||||
actualMaturityAmount, preClosureAllowed, preClosureInterestRate, withdrawnonDate, rejectedonDate, closedonDate,
|
actualMaturityAmount, preClosureAllowed, preClosureInterestRate, withdrawnonDate, rejectedonDate, closedonDate,
|
||||||
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType,depositEvery,outstandingAmount);
|
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType,depositEvery,outstandingAmount, interestPostEvery, interestPostFrequency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,10 +236,10 @@ public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPl
|
|||||||
Integer noOfMonths = Months.monthsBetween(date, new LocalDate()).getMonths();
|
Integer noOfMonths = Months.monthsBetween(date, new LocalDate()).getMonths();
|
||||||
Integer noOfPeriodsExistedTillDate = noOfMonths/depositEvery;
|
Integer noOfPeriodsExistedTillDate = noOfMonths/depositEvery;
|
||||||
BigDecimal totalAmountToBePaidTillDate = BigDecimal.valueOf(noOfPeriodsExistedTillDate.doubleValue()*amountPerPeriod.doubleValue());
|
BigDecimal totalAmountToBePaidTillDate = BigDecimal.valueOf(noOfPeriodsExistedTillDate.doubleValue()*amountPerPeriod.doubleValue());
|
||||||
dueAmount = dueAmount.add(BigDecimal.valueOf(totalAmountToBePaidTillDate.doubleValue() - account.getTotalDepositAmount().doubleValue()));
|
dueAmount = dueAmount.add(BigDecimal.valueOf(totalAmountToBePaidTillDate.doubleValue() - account.getOutstandingAmount().doubleValue()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
dueAmount = dueAmount.doubleValue() < 0 ? BigDecimal.ZERO : dueAmount;
|
||||||
return dueAmount;
|
return dueAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,10 +250,14 @@ public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPl
|
|||||||
String sql = "Select " + mapper.savingScheduleSchema() +" where ss.saving_account_id =? order by ss.installment";
|
String sql = "Select " + mapper.savingScheduleSchema() +" where ss.saving_account_id =? order by ss.installment";
|
||||||
List<SavingSchedulePeriodData> periods = this.jdbcTemplate.query(sql, mapper, new Object[]{accountId});
|
List<SavingSchedulePeriodData> periods = this.jdbcTemplate.query(sql, mapper, new Object[]{accountId});
|
||||||
BigDecimal cumulativeDepositDue = BigDecimal.ZERO;
|
BigDecimal cumulativeDepositDue = BigDecimal.ZERO;
|
||||||
|
BigDecimal cumulativeDepositPaid = BigDecimal.ZERO;
|
||||||
|
BigDecimal cummulativeInterestAccured = BigDecimal.ZERO;
|
||||||
for(SavingSchedulePeriodData data : periods){
|
for(SavingSchedulePeriodData data : periods){
|
||||||
cumulativeDepositDue = cumulativeDepositDue.add(data.getDepositDue()).subtract(data.getDepositPaid());
|
cumulativeDepositDue = cumulativeDepositDue.add(data.getDepositDue())/*.subtract(data.getDepositPaid())*/;
|
||||||
|
cumulativeDepositPaid = cumulativeDepositPaid.add(data.getDepositPaid());
|
||||||
|
cummulativeInterestAccured = cummulativeInterestAccured.add(data.getInterestAccured());
|
||||||
}
|
}
|
||||||
SavingScheduleData scheduleData = new SavingScheduleData(currency, cumulativeDepositDue, periods);
|
SavingScheduleData scheduleData = new SavingScheduleData(currency, cumulativeDepositDue, cumulativeDepositPaid, cummulativeInterestAccured, periods);
|
||||||
return scheduleData;
|
return scheduleData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,7 +266,7 @@ public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPl
|
|||||||
public String savingScheduleSchema(){
|
public String savingScheduleSchema(){
|
||||||
return "ss.id as id, ss.saving_account_id as savingAccountId, ss.duedate as dueDate, ss.installment as installment, "
|
return "ss.id as id, ss.saving_account_id as savingAccountId, ss.duedate as dueDate, ss.installment as installment, "
|
||||||
+ " ss.deposit as deposit, ss.payment_date as paymentDate, ss.deposit_paid as depositPaid, "
|
+ " ss.deposit as deposit, ss.payment_date as paymentDate, ss.deposit_paid as depositPaid, "
|
||||||
+ " ss.completed_derived as completedDerived FROM m_saving_schedule ss";
|
+ " ss.completed_derived as completedDerived, ss.interest_accured AS interestAccured FROM m_saving_schedule ss";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -265,8 +276,9 @@ public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPl
|
|||||||
Integer installment = JdbcSupport.getInteger(rs, "installment");
|
Integer installment = JdbcSupport.getInteger(rs, "installment");
|
||||||
BigDecimal depositDue = rs.getBigDecimal("deposit");
|
BigDecimal depositDue = rs.getBigDecimal("deposit");
|
||||||
BigDecimal depositPaid = rs.getBigDecimal("depositPaid");
|
BigDecimal depositPaid = rs.getBigDecimal("depositPaid");
|
||||||
|
BigDecimal interestAccured = rs.getBigDecimal("interestAccured");
|
||||||
|
|
||||||
return new SavingSchedulePeriodData(installment, dueDate, depositDue, depositPaid);
|
return new SavingSchedulePeriodData(installment, dueDate, depositDue, depositPaid, interestAccured);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -292,4 +304,30 @@ public class SavingAccountReadPlatformServiceImpl implements SavingAccountReadPl
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<SavingAccountTransactionsData> retrieveSavingsAccountTransactions(Long accountId) {
|
||||||
|
this.context.authenticatedUser();
|
||||||
|
SavingAccountTransactionMapper savingAccountTransactionMapper = new SavingAccountTransactionMapper();
|
||||||
|
String sql = "select "+ savingAccountTransactionMapper.schema() + " where stxn.saving_account_id = ? ";
|
||||||
|
return jdbcTemplate.query(sql, savingAccountTransactionMapper, new Object[] {accountId});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class SavingAccountTransactionMapper implements RowMapper<SavingAccountTransactionsData> {
|
||||||
|
|
||||||
|
public String schema() {
|
||||||
|
return "stxn.id as id, stxn.transaction_type_enum as type, stxn.transaction_date as transactionDate, stxn.amount as amount FROM m_saving_account_transaction stxn";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SavingAccountTransactionsData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
|
||||||
|
Long id = rs.getLong("id");
|
||||||
|
LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate");
|
||||||
|
Integer transactionTypeValue = JdbcSupport.getInteger(rs, "type");
|
||||||
|
EnumOptionData transactionType = DepositAccountTransactionEnumerations.depositType(transactionTypeValue);
|
||||||
|
BigDecimal amount = rs.getBigDecimal("amount");
|
||||||
|
return new SavingAccountTransactionsData(id, transactionDate, transactionType, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+83
-10
@@ -1,6 +1,8 @@
|
|||||||
package org.mifosplatform.portfolio.savingsaccount.service;
|
package org.mifosplatform.portfolio.savingsaccount.service;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -10,19 +12,21 @@ import org.mifosplatform.organisation.monetary.data.CurrencyData;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingScheduleData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
import org.mifosplatform.portfolio.savingsaccount.data.SavingSchedulePeriodData;
|
||||||
import org.mifosplatform.portfolio.savingsaccount.domain.DepositScheduleDateGenerator;
|
import org.mifosplatform.portfolio.savingsaccount.domain.DepositScheduleDateGenerator;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingFrequencyType;
|
||||||
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingInterestCalculationMethod;
|
||||||
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
import org.mifosplatform.portfolio.savingsaccountproduct.domain.SavingProduct;
|
||||||
|
|
||||||
public class SavingScheduleGenerator {
|
public class SavingScheduleGenerator {
|
||||||
|
|
||||||
private final DepositScheduleDateGenerator scheduledDateGenerator = new DefaultDepositScheduleDateGenerator();
|
private final DepositScheduleDateGenerator scheduledDateGenerator = new DefaultDepositScheduleDateGenerator();
|
||||||
|
private final Integer monthsInYear = 12;
|
||||||
|
|
||||||
public SavingScheduleData generate(final LocalDate scheduleStartDate, final BigDecimal depositAmountPerPeriod,
|
public SavingScheduleData generate(final LocalDate scheduleStartDate, final BigDecimal depositAmountPerPeriod,
|
||||||
final Integer depositFrequency, final PeriodFrequencyType depositFrequencyType, final SavingProduct savingProduct,
|
final Integer depositFrequency, final SavingFrequencyType savingFrequencyType, final SavingProduct savingProduct,
|
||||||
final Integer tenure, final ApplicationCurrency applicationCurrency) {
|
final Integer tenure, final ApplicationCurrency applicationCurrency, final BigDecimal interestRate, final SavingInterestCalculationMethod interestCalculationMethod) {
|
||||||
|
|
||||||
LocalDate startDate = scheduleStartDate;
|
LocalDate startDate = scheduleStartDate;
|
||||||
int periodNumber = 1;
|
int periodNumber = 1;
|
||||||
@@ -30,23 +34,92 @@ public class SavingScheduleGenerator {
|
|||||||
Integer paymentPeriods = tenure / depositFrequency;
|
Integer paymentPeriods = tenure / depositFrequency;
|
||||||
final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
|
final Collection<SavingSchedulePeriodData> periods = new ArrayList<SavingSchedulePeriodData>();
|
||||||
final List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(startDate, paymentPeriods, depositFrequency,
|
final List<LocalDate> scheduledDates = this.scheduledDateGenerator.generate(startDate, paymentPeriods, depositFrequency,
|
||||||
depositFrequencyType);
|
savingFrequencyType);
|
||||||
final MonetaryCurrency currency = savingProduct.getCurrency();
|
final MonetaryCurrency currency = savingProduct.getCurrency();
|
||||||
final Money depositAmount = Money.of(currency, depositAmountPerPeriod);
|
final Money depositAmount = Money.of(currency, depositAmountPerPeriod);
|
||||||
Money totalDeposit = Money.zero(currency);
|
Money totalDeposit = Money.zero(currency);
|
||||||
|
|
||||||
|
|
||||||
|
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||||
|
BigDecimal interestRateAsFraction = interestRate.divide(BigDecimal.valueOf(100), mc);
|
||||||
|
Integer noofTimesInterestCompoundPerYear = determineIntValue(savingFrequencyType);
|
||||||
|
BigDecimal interestRatePerPeriod = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/ noofTimesInterestCompoundPerYear.doubleValue());
|
||||||
|
BigDecimal onePlusInterestRatePerPeriod = BigDecimal.ONE.add(interestRatePerPeriod);
|
||||||
|
BigDecimal cummulativeDepositPaid = BigDecimal.ZERO;
|
||||||
|
BigDecimal cummulativeInterestAccured = BigDecimal.ZERO;
|
||||||
|
Integer tempTenure = tenure;
|
||||||
|
|
||||||
|
BigDecimal termAmount = BigDecimal.ZERO;
|
||||||
|
BigDecimal totalInterest = BigDecimal.ZERO;
|
||||||
|
BigDecimal closingBalance = BigDecimal.ZERO;
|
||||||
|
|
||||||
for (LocalDate scheduleDate : scheduledDates) {
|
for (LocalDate scheduleDate : scheduledDates) {
|
||||||
totalDeposit = totalDeposit.plus(depositAmount);
|
|
||||||
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(periodNumber, scheduleDate,
|
if (interestCalculationMethod.isMonthlyCollection()) {
|
||||||
depositAmount.getAmount());
|
BigDecimal monthsExpressedInYears = BigDecimal.valueOf(tempTenure.doubleValue() / monthsInYear.doubleValue());
|
||||||
periods.add(installment);
|
BigDecimal timeforOneCalculationPeriod = BigDecimal.valueOf(noofTimesInterestCompoundPerYear * monthsExpressedInYears.doubleValue());
|
||||||
periodNumber++;
|
BigDecimal amountPerPeriod = depositAmountPerPeriod.multiply(BigDecimal.valueOf(Math.pow(onePlusInterestRatePerPeriod.doubleValue(), timeforOneCalculationPeriod.doubleValue())));
|
||||||
|
BigDecimal interestAccured = amountPerPeriod.subtract(depositAmountPerPeriod);
|
||||||
|
|
||||||
|
totalDeposit = totalDeposit.plus(depositAmount);
|
||||||
|
cummulativeInterestAccured = cummulativeInterestAccured.add(interestAccured);
|
||||||
|
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(periodNumber, scheduleDate,
|
||||||
|
depositAmount.getAmount(), interestAccured);
|
||||||
|
periods.add(installment);
|
||||||
|
periodNumber++;
|
||||||
|
tempTenure = tempTenure - depositFrequency;
|
||||||
|
} else if (interestCalculationMethod.isAverageBalance()){
|
||||||
|
|
||||||
|
BigDecimal amountPerPeriod = depositAmount.getAmount();
|
||||||
|
Integer depositEveryOriginalValue = depositFrequency;
|
||||||
|
BigDecimal amountPermonth = BigDecimal.valueOf(amountPerPeriod.doubleValue()/depositFrequency.doubleValue());
|
||||||
|
|
||||||
|
while (depositEveryOriginalValue > 0) {
|
||||||
|
closingBalance = closingBalance.add(amountPermonth);
|
||||||
|
termAmount = termAmount.add(closingBalance);
|
||||||
|
depositEveryOriginalValue--;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal averageAmount = BigDecimal.valueOf(termAmount.doubleValue()/depositFrequency.doubleValue());
|
||||||
|
BigDecimal interestRatePerTerm = BigDecimal.valueOf(interestRateAsFraction.doubleValue()/monthsInYear.doubleValue()*depositFrequency.doubleValue());
|
||||||
|
BigDecimal interestAccured = averageAmount.multiply(interestRatePerTerm);
|
||||||
|
totalInterest = totalInterest.add(interestAccured);
|
||||||
|
depositEveryOriginalValue = depositFrequency;
|
||||||
|
termAmount = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
totalDeposit = totalDeposit.plus(depositAmount);
|
||||||
|
cummulativeInterestAccured = totalInterest;
|
||||||
|
SavingSchedulePeriodData installment = SavingSchedulePeriodData.addScheduleInformation(periodNumber, scheduleDate,
|
||||||
|
depositAmount.getAmount(), interestAccured);
|
||||||
|
periods.add(installment);
|
||||||
|
periodNumber++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(),
|
CurrencyData currencyData = new CurrencyData(applicationCurrency.getCode(), applicationCurrency.getName(),
|
||||||
currency.getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
currency.getDigitsAfterDecimal(), applicationCurrency.getDisplaySymbol(), applicationCurrency.getNameCode());
|
||||||
|
|
||||||
return new SavingScheduleData(currencyData, totalDeposit.getAmount(), periods);
|
return new SavingScheduleData(currencyData, totalDeposit.getAmount(),cummulativeDepositPaid, cummulativeInterestAccured, periods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Integer determineIntValue(SavingFrequencyType frequencyType){
|
||||||
|
Integer noofTimesInterestCompoundPerYear = Integer.valueOf(0);
|
||||||
|
switch (frequencyType) {
|
||||||
|
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");
|
||||||
|
|
||||||
|
}
|
||||||
|
return noofTimesInterestCompoundPerYear;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -38,4 +38,12 @@ public enum TenureTypeEnum {
|
|||||||
}
|
}
|
||||||
return tenureTypeEnum;
|
return tenureTypeEnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isFixedPeriod() {
|
||||||
|
return this.value.equals(TenureTypeEnum.FIXED_PERIOD.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPerpetual() {
|
||||||
|
return this.value.equals(TenureTypeEnum.PERPETUAL.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user