Advanced deposit products and accounts (FD & RD) with interest rate
slabs extensions
This commit is contained in:
+4
@@ -210,4 +210,8 @@ public class InterestRateChartSlabFields {
|
|||||||
}
|
}
|
||||||
return actualDepositPeriod;
|
return actualDepositPeriod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAmountBetween(final BigDecimal depositAmount){
|
||||||
|
return depositAmount.compareTo(amountRangeFrom) >= 0 && depositAmount.compareTo(amountRangeTo) <= 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+8
-3
@@ -69,6 +69,7 @@ public class DepositsApiConstants {
|
|||||||
public static final String approvedOnDateParamName = "approvedOnDate";
|
public static final String approvedOnDateParamName = "approvedOnDate";
|
||||||
public static final String activatedOnDateParamName = "activatedOnDate";
|
public static final String activatedOnDateParamName = "activatedOnDate";
|
||||||
public static final String closedOnDateParamName = "closedOnDate";
|
public static final String closedOnDateParamName = "closedOnDate";
|
||||||
|
public static final String expectedFirstDepositOnDateParamName = "expectedFirstDepositOnDate";
|
||||||
|
|
||||||
public static final String activeParamName = "active";
|
public static final String activeParamName = "active";
|
||||||
public static final String nameParamName = "name";
|
public static final String nameParamName = "name";
|
||||||
@@ -118,6 +119,8 @@ public class DepositsApiConstants {
|
|||||||
public static final String inMultiplesOfDepositTermType = "inMultiplesOfDepositTermType";
|
public static final String inMultiplesOfDepositTermType = "inMultiplesOfDepositTermType";
|
||||||
|
|
||||||
public static final String depositAmountParamName = "depositAmount";
|
public static final String depositAmountParamName = "depositAmount";
|
||||||
|
public static final String depositMinAmountParamName = "minDepositAmount";
|
||||||
|
public static final String depositMaxAmountParamName = "maxDepositAmount";
|
||||||
public static final String depositPeriodParamName = "depositPeriod";
|
public static final String depositPeriodParamName = "depositPeriod";
|
||||||
public static final String depositPeriodFrequencyIdParamName = "depositPeriodFrequencyId";
|
public static final String depositPeriodFrequencyIdParamName = "depositPeriodFrequencyId";
|
||||||
|
|
||||||
@@ -211,11 +214,13 @@ public class DepositsApiConstants {
|
|||||||
|
|
||||||
private static final Set<String> DEPOSIT_TERM_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
private static final Set<String> DEPOSIT_TERM_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
||||||
maxDepositTermParamName, minDepositTermTypeIdParamName, maxDepositTermTypeIdParamName, inMultiplesOfDepositTermParamName,
|
maxDepositTermParamName, minDepositTermTypeIdParamName, maxDepositTermTypeIdParamName, inMultiplesOfDepositTermParamName,
|
||||||
inMultiplesOfDepositTermTypeIdParamName));
|
inMultiplesOfDepositTermTypeIdParamName, depositAmountParamName,
|
||||||
|
depositMinAmountParamName, depositMaxAmountParamName));
|
||||||
|
|
||||||
private static final Set<String> DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
private static final Set<String> DEPOSIT_TERM_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(minDepositTermParamName,
|
||||||
maxDepositTermParamName, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTermParamName,
|
maxDepositTermParamName, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTermParamName,
|
||||||
inMultiplesOfDepositTermType));
|
inMultiplesOfDepositTermType, depositAmountParamName,
|
||||||
|
depositMinAmountParamName, depositMaxAmountParamName));
|
||||||
|
|
||||||
private static final Set<String> RECURRING_DETAILS_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
private static final Set<String> RECURRING_DETAILS_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(
|
||||||
recurringDepositAmountParamName, recurringDepositTypeIdParamName, recurringDepositFrequencyTypeIdParamName,
|
recurringDepositAmountParamName, recurringDepositTypeIdParamName, recurringDepositFrequencyTypeIdParamName,
|
||||||
@@ -277,7 +282,7 @@ public class DepositsApiConstants {
|
|||||||
interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
|
interestCompoundingPeriodTypeParamName, interestPostingPeriodTypeParamName, interestCalculationTypeParamName,
|
||||||
interestCalculationDaysInYearTypeParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName,
|
interestCalculationDaysInYearTypeParamName, lockinPeriodFrequencyParamName, lockinPeriodFrequencyTypeParamName,
|
||||||
chargesParamName, chartsParamName, depositAmountParamName, depositPeriodParamName, depositPeriodFrequencyIdParamName,
|
chargesParamName, chartsParamName, depositAmountParamName, depositPeriodParamName, depositPeriodFrequencyIdParamName,
|
||||||
savingsAccounts));
|
savingsAccounts, expectedFirstDepositOnDateParamName));
|
||||||
|
|
||||||
public static final Set<String> FIXED_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS = fixedDepositAccountRequestData();
|
public static final Set<String> FIXED_DEPOSIT_ACCOUNT_REQUEST_DATA_PARAMETERS = fixedDepositAccountRequestData();
|
||||||
public static final Set<String> FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS = fixedDepositAccountResponseData();
|
public static final Set<String> FIXED_DEPOSIT_ACCOUNT_RESPONSE_DATA_PARAMETERS = fixedDepositAccountResponseData();
|
||||||
|
|||||||
+10
-10
@@ -20,11 +20,11 @@ public enum SavingsCompoundingInterestPeriodType {
|
|||||||
DAILY(1, "savingsCompoundingInterestPeriodType.daily"), //
|
DAILY(1, "savingsCompoundingInterestPeriodType.daily"), //
|
||||||
// WEEKLY(2, "savingsCompoundingInterestPeriodType.weekly"), //
|
// WEEKLY(2, "savingsCompoundingInterestPeriodType.weekly"), //
|
||||||
// BIWEEKLY(3, "savingsCompoundingInterestPeriodType.biweekly"), //
|
// BIWEEKLY(3, "savingsCompoundingInterestPeriodType.biweekly"), //
|
||||||
MONTHLY(4, "savingsCompoundingInterestPeriodType.monthly");
|
MONTHLY(4, "savingsCompoundingInterestPeriodType.monthly"),
|
||||||
|
|
||||||
// QUATERLY(5, "savingsCompoundingInterestPeriodType.quarterly"), //
|
QUATERLY(5, "savingsCompoundingInterestPeriodType.quarterly"), //
|
||||||
// BI_ANNUAL(6, "savingsCompoundingInterestPeriodType.biannual"), //
|
BI_ANNUAL(6, "savingsCompoundingInterestPeriodType.biannual"), //
|
||||||
// ANNUAL(7, "savingsCompoundingInterestPeriodType.annual"), //
|
ANNUAL(7, "savingsCompoundingInterestPeriodType.annual"); //
|
||||||
// NO_COMPOUNDING_SIMPLE_INTEREST(8,
|
// NO_COMPOUNDING_SIMPLE_INTEREST(8,
|
||||||
// "savingsCompoundingInterestPeriodType.nocompounding");
|
// "savingsCompoundingInterestPeriodType.nocompounding");
|
||||||
|
|
||||||
@@ -74,16 +74,16 @@ public enum SavingsCompoundingInterestPeriodType {
|
|||||||
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.MONTHLY;
|
repaymentFrequencyType = SavingsCompoundingInterestPeriodType.MONTHLY;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// repaymentFrequencyType =
|
repaymentFrequencyType =
|
||||||
// SavingsCompoundingInterestPeriodType.QUATERLY;
|
SavingsCompoundingInterestPeriodType.QUATERLY;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
// repaymentFrequencyType =
|
repaymentFrequencyType =
|
||||||
// SavingsCompoundingInterestPeriodType.BI_ANNUAL;
|
SavingsCompoundingInterestPeriodType.BI_ANNUAL;
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// repaymentFrequencyType =
|
repaymentFrequencyType =
|
||||||
// SavingsCompoundingInterestPeriodType.ANNUAL;
|
SavingsCompoundingInterestPeriodType.ANNUAL;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
// repaymentFrequencyType =
|
// repaymentFrequencyType =
|
||||||
|
|||||||
+4
@@ -17,6 +17,7 @@ public enum SavingsPostingInterestPeriodType {
|
|||||||
INVALID(0, "savingsPostingInterestPeriodType.invalid"), //
|
INVALID(0, "savingsPostingInterestPeriodType.invalid"), //
|
||||||
MONTHLY(4, "savingsPostingInterestPeriodType.monthly"), //
|
MONTHLY(4, "savingsPostingInterestPeriodType.monthly"), //
|
||||||
QUATERLY(5, "savingsPostingInterestPeriodType.quarterly"), //
|
QUATERLY(5, "savingsPostingInterestPeriodType.quarterly"), //
|
||||||
|
BIANNUAL(6, "savingsPostingInterestPeriodType.biannual"),
|
||||||
ANNUAL(7, "savingsPostingInterestPeriodType.annual");
|
ANNUAL(7, "savingsPostingInterestPeriodType.annual");
|
||||||
|
|
||||||
private final Integer value;
|
private final Integer value;
|
||||||
@@ -56,6 +57,9 @@ public enum SavingsPostingInterestPeriodType {
|
|||||||
case 5:
|
case 5:
|
||||||
repaymentFrequencyType = SavingsPostingInterestPeriodType.QUATERLY;
|
repaymentFrequencyType = SavingsPostingInterestPeriodType.QUATERLY;
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
repaymentFrequencyType = SavingsPostingInterestPeriodType.BIANNUAL;
|
||||||
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
repaymentFrequencyType = SavingsPostingInterestPeriodType.ANNUAL;
|
repaymentFrequencyType = SavingsPostingInterestPeriodType.ANNUAL;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+82
@@ -27,6 +27,9 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosur
|
|||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositAmountParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositMinAmountParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositMaxAmountParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.descriptionParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.descriptionParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName;
|
||||||
@@ -48,6 +51,8 @@ import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawal
|
|||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -110,6 +115,8 @@ public class DepositProductDataValidator {
|
|||||||
|
|
||||||
validateChartsData(element, baseDataValidator);
|
validateChartsData(element, baseDataValidator);
|
||||||
|
|
||||||
|
validateDepositAmountForCreate(element, baseDataValidator);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +139,8 @@ public class DepositProductDataValidator {
|
|||||||
|
|
||||||
validateChartsData(element, baseDataValidator);
|
validateChartsData(element, baseDataValidator);
|
||||||
|
|
||||||
|
validateDepositAmountForUpdate(element, baseDataValidator);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +166,8 @@ public class DepositProductDataValidator {
|
|||||||
|
|
||||||
validateChartsData(element, baseDataValidator);
|
validateChartsData(element, baseDataValidator);
|
||||||
|
|
||||||
|
validateDepositAmountForCreate(element, baseDataValidator);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +192,8 @@ public class DepositProductDataValidator {
|
|||||||
|
|
||||||
validateChartsData(element, baseDataValidator);
|
validateChartsData(element, baseDataValidator);
|
||||||
|
|
||||||
|
validateDepositAmountForUpdate(element, baseDataValidator);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,4 +746,73 @@ public class DepositProductDataValidator {
|
|||||||
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
|
.isOneOfTheseValues(SavingsPeriodFrequencyType.integerValues());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateDepositAmountForCreate(JsonElement element, DataValidatorBuilder baseDataValidator) {
|
||||||
|
final BigDecimal depositAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositAmountParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notNull().positiveAmount();
|
||||||
|
|
||||||
|
BigDecimal depositMinAmount = null;
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(depositMinAmountParamName, element)) {
|
||||||
|
depositMinAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositMinAmountParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(depositMinAmountParamName).value(depositMinAmount).notNull().positiveAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal depositMaxAmount = null;
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(depositMaxAmountParamName, element)) {
|
||||||
|
depositMaxAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositMaxAmountParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(depositMaxAmountParamName).value(depositMaxAmount).notNull().positiveAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depositMaxAmount != null && depositMaxAmount.compareTo(BigDecimal.ZERO) != -1) {
|
||||||
|
if (depositMinAmount != null && depositMinAmount.compareTo(BigDecimal.ZERO) != -1) {
|
||||||
|
baseDataValidator.reset().parameter(depositMaxAmountParamName).value(depositMaxAmount).notLessThanMin(depositMinAmount);
|
||||||
|
if (depositMinAmount.compareTo(depositMaxAmount) <= 0) {
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount)
|
||||||
|
.inMinAndMaxAmountRange(depositMinAmount, depositMaxAmount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notGreaterThanMax(depositMaxAmount);
|
||||||
|
}
|
||||||
|
} else if (depositMinAmount != null && depositMinAmount.compareTo(BigDecimal.ZERO) != -1) {
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notLessThanMin(depositMinAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateDepositAmountForUpdate(JsonElement element, DataValidatorBuilder baseDataValidator) {
|
||||||
|
BigDecimal depositAmount = null;
|
||||||
|
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(depositAmountParamName, element)) {
|
||||||
|
depositAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositAmountParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(depositMinAmountParamName).value(depositAmount).notNull().positiveAmount();
|
||||||
|
}
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notNull().positiveAmount();
|
||||||
|
|
||||||
|
BigDecimal depositMinAmount = null;
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(depositMinAmountParamName, element)) {
|
||||||
|
depositMinAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositMinAmountParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(depositMinAmountParamName).value(depositMinAmount).notNull().positiveAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal depositMaxAmount = null;
|
||||||
|
if (this.fromApiJsonHelper.parameterExists(depositMaxAmountParamName, element)) {
|
||||||
|
depositMaxAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(depositMaxAmountParamName, element);
|
||||||
|
baseDataValidator.reset().parameter(depositMaxAmountParamName).value(depositMaxAmount).notNull().positiveAmount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(depositAmount != null) {
|
||||||
|
if (depositMaxAmount != null && depositMaxAmount.compareTo(BigDecimal.ZERO) != -1) {
|
||||||
|
if (depositMinAmount != null && depositMinAmount.compareTo(BigDecimal.ZERO) != -1) {
|
||||||
|
baseDataValidator.reset().parameter(depositMaxAmountParamName).value(depositMaxAmount).notLessThanMin(depositMinAmount);
|
||||||
|
if (depositMinAmount.compareTo(depositMaxAmount) <= 0) {
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount)
|
||||||
|
.inMinAndMaxAmountRange(depositMinAmount, depositMaxAmount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notGreaterThanMax(depositMaxAmount);
|
||||||
|
}
|
||||||
|
} else if (depositMinAmount != null && depositMinAmount.compareTo(BigDecimal.ZERO) != -1) {
|
||||||
|
baseDataValidator.reset().parameter(depositAmountParamName).value(depositAmount).notLessThanMin(depositMinAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+17
-9
@@ -47,6 +47,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
private EnumOptionData recurringDepositType;
|
private EnumOptionData recurringDepositType;
|
||||||
private Integer recurringDepositFrequency;
|
private Integer recurringDepositFrequency;
|
||||||
private EnumOptionData recurringDepositFrequencyType;
|
private EnumOptionData recurringDepositFrequencyType;
|
||||||
|
private LocalDate expectedFirstDepositOnDate;
|
||||||
|
|
||||||
// used for account close
|
// used for account close
|
||||||
private EnumOptionData onAccountClosure;
|
private EnumOptionData onAccountClosure;
|
||||||
@@ -73,7 +74,8 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
final BigDecimal maturityAmount, final LocalDate maturityDate, final Integer depositPeriod,
|
final BigDecimal maturityAmount, final LocalDate maturityDate, final Integer depositPeriod,
|
||||||
final EnumOptionData depositPeriodFrequency, final BigDecimal recurringDepositAmount,
|
final EnumOptionData depositPeriodFrequency, final BigDecimal recurringDepositAmount,
|
||||||
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
|
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
|
||||||
final EnumOptionData recurringDepositFrequencyType, final EnumOptionData onAccountClosure) {
|
final EnumOptionData recurringDepositFrequencyType, final EnumOptionData onAccountClosure,
|
||||||
|
final LocalDate expectedFirstDepositOnDate) {
|
||||||
|
|
||||||
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
final Collection<EnumOptionData> interestFreePeriodTypeOptions = null;
|
||||||
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
|
final Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions = null;
|
||||||
@@ -108,7 +110,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
depositPeriod, depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
depositPeriod, depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
||||||
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
|
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
|
||||||
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
|
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositAccountData withInterestChart(final RecurringDepositAccountData account,
|
public static RecurringDepositAccountData withInterestChart(final RecurringDepositAccountData account,
|
||||||
@@ -132,7 +134,8 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
account.depositTermTypeOptions, account.inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
|
account.depositTermTypeOptions, account.inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
|
||||||
account.recurringDepositFrequency, account.recurringDepositFrequencyType, account.recurringDepositTypeOptions,
|
account.recurringDepositFrequency, account.recurringDepositFrequencyType, account.recurringDepositTypeOptions,
|
||||||
account.recurringDepositFrequencyTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
|
account.recurringDepositFrequencyTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
|
||||||
account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts);
|
account.onAccountClosure, account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts,
|
||||||
|
account.expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositAccountData withTemplateOptions(final RecurringDepositAccountData account,
|
public static RecurringDepositAccountData withTemplateOptions(final RecurringDepositAccountData account,
|
||||||
@@ -186,7 +189,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
account.recurringDepositType, account.recurringDepositFrequency, account.recurringDepositFrequencyType,
|
account.recurringDepositType, account.recurringDepositFrequency, account.recurringDepositFrequencyType,
|
||||||
template.recurringDepositTypeOptions, template.recurringDepositFrequencyTypeOptions,
|
template.recurringDepositTypeOptions, template.recurringDepositFrequencyTypeOptions,
|
||||||
template.depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure, account.onAccountClosureOptions,
|
template.depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure, account.onAccountClosureOptions,
|
||||||
account.paymentTypeOptions, account.savingsAccounts);
|
account.paymentTypeOptions, account.savingsAccounts, account.expectedFirstDepositOnDate);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +226,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
|
depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
|
||||||
account.recurringDepositFrequency, account.recurringDepositFrequencyType, recurringDepositTypeOptions,
|
account.recurringDepositFrequency, account.recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure,
|
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, account.depositType, account.onAccountClosure,
|
||||||
account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts);
|
account.onAccountClosureOptions, account.paymentTypeOptions, account.savingsAccounts, account.expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
|
public static RecurringDepositAccountData withClientTemplate(final Long clientId, final String clientName, final Long groupId,
|
||||||
@@ -301,6 +304,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
final Collection<EnumOptionData> onAccountClosureOptions = null;
|
final Collection<EnumOptionData> onAccountClosureOptions = null;
|
||||||
final Collection<CodeValueData> paymentTypeOptions = null;
|
final Collection<CodeValueData> paymentTypeOptions = null;
|
||||||
final Collection<SavingsAccountData> savingsAccountDatas = null;
|
final Collection<SavingsAccountData> savingsAccountDatas = null;
|
||||||
|
final LocalDate expectedFirstDepositOnDate = null;
|
||||||
|
|
||||||
return new RecurringDepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
return new RecurringDepositAccountData(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName,
|
||||||
fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
|
fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
|
||||||
@@ -316,7 +320,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
||||||
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
|
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
|
||||||
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
|
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositAccountData preClosureDetails(final Long accountId, BigDecimal maturityAmount,
|
public static RecurringDepositAccountData preClosureDetails(final Long accountId, BigDecimal maturityAmount,
|
||||||
@@ -394,6 +398,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
final String groupName = null;
|
final String groupName = null;
|
||||||
final Long clientId = null;
|
final Long clientId = null;
|
||||||
final String clientName = null;
|
final String clientName = null;
|
||||||
|
final LocalDate expectedFirstDepositOnDate = null;
|
||||||
|
|
||||||
return new RecurringDepositAccountData(accountId, accountNo, externalId, groupId, groupName, clientId, clientName, productId,
|
return new RecurringDepositAccountData(accountId, accountNo, externalId, groupId, groupName, clientId, clientName, productId,
|
||||||
productName, fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
|
productName, fieldOfficerId, fieldOfficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType,
|
||||||
@@ -409,7 +414,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
depositPeriodFrequency, recurringDepositAmount, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
||||||
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
|
recurringDepositFrequencyTypeOptions, depositPeriodFrequencyOptions, depositType, onAccountClosure,
|
||||||
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
|
onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas, expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositAccountData withClosureTemplateDetails(final RecurringDepositAccountData account,
|
public static RecurringDepositAccountData withClosureTemplateDetails(final RecurringDepositAccountData account,
|
||||||
@@ -434,7 +439,8 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
account.depositTermTypeOptions, account.inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
|
account.depositTermTypeOptions, account.inMultiplesOfDepositTermTypeOptions, account.recurringDepositType,
|
||||||
account.recurringDepositFrequency, account.recurringDepositFrequencyType, account.recurringDepositTypeOptions,
|
account.recurringDepositFrequency, account.recurringDepositFrequencyType, account.recurringDepositTypeOptions,
|
||||||
account.recurringDepositFrequencyTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
|
account.recurringDepositFrequencyTypeOptions, account.depositPeriodFrequencyOptions, account.depositType,
|
||||||
account.onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas);
|
account.onAccountClosure, onAccountClosureOptions, paymentTypeOptions, savingsAccountDatas,
|
||||||
|
account.expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecurringDepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
|
private RecurringDepositAccountData(final Long id, final String accountNo, final String externalId, final Long groupId,
|
||||||
@@ -469,7 +475,8 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions,
|
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions,
|
||||||
final Collection<EnumOptionData> depositPeriodFrequencyOptions, final EnumOptionData depositType,
|
final Collection<EnumOptionData> depositPeriodFrequencyOptions, final EnumOptionData depositType,
|
||||||
final EnumOptionData onAccountClosure, final Collection<EnumOptionData> onAccountClosureOptions,
|
final EnumOptionData onAccountClosure, final Collection<EnumOptionData> onAccountClosureOptions,
|
||||||
final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas) {
|
final Collection<CodeValueData> paymentTypeOptions, final Collection<SavingsAccountData> savingsAccountDatas,
|
||||||
|
final LocalDate expectedFirstDepositOnDate) {
|
||||||
|
|
||||||
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId,
|
super(id, accountNo, externalId, groupId, groupName, clientId, clientName, productId, productName, fieldofficerId,
|
||||||
fieldofficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
|
fieldofficerName, status, timeline, currency, nominalAnnualInterestRate, interestPeriodType, interestPostingPeriodType,
|
||||||
@@ -501,6 +508,7 @@ public class RecurringDepositAccountData extends DepositAccountData {
|
|||||||
this.recurringDepositFrequencyType = recurringDepositFrequencyType;
|
this.recurringDepositFrequencyType = recurringDepositFrequencyType;
|
||||||
this.recurringDepositFrequency = recurringDepositFrequency;
|
this.recurringDepositFrequency = recurringDepositFrequency;
|
||||||
this.recurringDepositType = recurringDepositType;
|
this.recurringDepositType = recurringDepositType;
|
||||||
|
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate;
|
||||||
|
|
||||||
// template data
|
// template data
|
||||||
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
|
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
|
||||||
|
|||||||
+33
-11
@@ -40,6 +40,9 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
private EnumOptionData recurringDepositType;
|
private EnumOptionData recurringDepositType;
|
||||||
private Integer recurringDepositFrequency;
|
private Integer recurringDepositFrequency;
|
||||||
private EnumOptionData recurringDepositFrequencyType;
|
private EnumOptionData recurringDepositFrequencyType;
|
||||||
|
private BigDecimal minDepositAmount;
|
||||||
|
private BigDecimal depositAmount;
|
||||||
|
private BigDecimal maxDepositAmount;
|
||||||
|
|
||||||
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
|
private Collection<EnumOptionData> interestFreePeriodTypeOptions;
|
||||||
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
|
private Collection<EnumOptionData> preClosurePenalInterestOnTypeOptions;
|
||||||
@@ -96,6 +99,9 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
final EnumOptionData maxDepositTermType = null;
|
final EnumOptionData maxDepositTermType = null;
|
||||||
final Integer inMultiplesOfDepositTerm = null;
|
final Integer inMultiplesOfDepositTerm = null;
|
||||||
final EnumOptionData inMultiplesOfDepositTermType = null;
|
final EnumOptionData inMultiplesOfDepositTermType = null;
|
||||||
|
final BigDecimal minDepositAmount = null;
|
||||||
|
final BigDecimal depositAmount = null;
|
||||||
|
final BigDecimal maxDepositAmount = null;
|
||||||
|
|
||||||
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
|
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
|
||||||
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
|
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
|
||||||
@@ -106,9 +112,10 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
|
penaltyToIncomeAccountMappings, interestRateCharts, chartTemplate, interestFreePeriodApplicable, interestFreeFromPeriod,
|
||||||
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
||||||
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
|
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
|
||||||
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
|
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, recurringDepositType,
|
||||||
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
|
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
||||||
|
minDepositAmount, depositAmount, maxDepositAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositProductData withCharges(final RecurringDepositProductData existingProduct,
|
public static RecurringDepositProductData withCharges(final RecurringDepositProductData existingProduct,
|
||||||
@@ -134,7 +141,8 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
existingProduct.recurringDepositType, existingProduct.recurringDepositFrequency,
|
existingProduct.recurringDepositType, existingProduct.recurringDepositFrequency,
|
||||||
existingProduct.recurringDepositFrequencyType, existingProduct.recurringDepositTypeOptions,
|
existingProduct.recurringDepositFrequencyType, existingProduct.recurringDepositTypeOptions,
|
||||||
existingProduct.recurringDepositFrequencyTypeOptions, existingProduct.depositTermTypeOptions,
|
existingProduct.recurringDepositFrequencyTypeOptions, existingProduct.depositTermTypeOptions,
|
||||||
existingProduct.inMultiplesOfDepositTermTypeOptions);
|
existingProduct.inMultiplesOfDepositTermTypeOptions, existingProduct.minDepositAmount,
|
||||||
|
existingProduct.depositAmount, existingProduct.maxDepositAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,7 +183,8 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
|
existingProduct.minDepositTermType, existingProduct.maxDepositTermType, existingProduct.inMultiplesOfDepositTerm,
|
||||||
existingProduct.inMultiplesOfDepositTermType, existingProduct.recurringDepositType,
|
existingProduct.inMultiplesOfDepositTermType, existingProduct.recurringDepositType,
|
||||||
existingProduct.recurringDepositFrequency, existingProduct.recurringDepositFrequencyType, recurringDepositTypeOptions,
|
existingProduct.recurringDepositFrequency, existingProduct.recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
|
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions, existingProduct.minDepositAmount,
|
||||||
|
existingProduct.depositAmount, existingProduct.maxDepositAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositProductData withAccountingDetails(final RecurringDepositProductData existingProduct,
|
public static RecurringDepositProductData withAccountingDetails(final RecurringDepositProductData existingProduct,
|
||||||
@@ -216,7 +225,8 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
existingProduct.recurringDepositType, existingProduct.recurringDepositFrequency,
|
existingProduct.recurringDepositType, existingProduct.recurringDepositFrequency,
|
||||||
existingProduct.recurringDepositFrequencyType, existingProduct.recurringDepositTypeOptions,
|
existingProduct.recurringDepositFrequencyType, existingProduct.recurringDepositTypeOptions,
|
||||||
existingProduct.recurringDepositFrequencyTypeOptions, existingProduct.depositTermTypeOptions,
|
existingProduct.recurringDepositFrequencyTypeOptions, existingProduct.depositTermTypeOptions,
|
||||||
existingProduct.inMultiplesOfDepositTermTypeOptions);
|
existingProduct.inMultiplesOfDepositTermTypeOptions, existingProduct.minDepositAmount,
|
||||||
|
existingProduct.depositAmount, existingProduct.maxDepositAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositProductData instance(final DepositProductData depositProductData,
|
public static RecurringDepositProductData instance(final DepositProductData depositProductData,
|
||||||
@@ -226,7 +236,9 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
|
final Integer maxDepositTerm, final EnumOptionData minDepositTermType, final EnumOptionData maxDepositTermType,
|
||||||
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType,
|
final Integer inMultiplesOfDepositTerm, final EnumOptionData inMultiplesOfDepositTermType,
|
||||||
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
|
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
|
||||||
final EnumOptionData recurringDepositFrequencyType) {
|
final EnumOptionData recurringDepositFrequencyType,
|
||||||
|
final BigDecimal minDepositAmount,final BigDecimal depositAmount,
|
||||||
|
final BigDecimal maxDepositAmount) {
|
||||||
|
|
||||||
final Map<String, Object> accountingMappings = null;
|
final Map<String, Object> accountingMappings = null;
|
||||||
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
|
final Collection<PaymentTypeToGLAccountMapper> paymentChannelToFundSourceMappings = null;
|
||||||
@@ -269,7 +281,8 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
|
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
|
||||||
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
|
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
|
||||||
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
|
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
||||||
|
minDepositAmount, depositAmount, maxDepositAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositProductData lookup(final Long id, final String name) {
|
public static RecurringDepositProductData lookup(final Long id, final String name) {
|
||||||
@@ -329,6 +342,9 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
final EnumOptionData inMultiplesOfDepositTermType = null;
|
final EnumOptionData inMultiplesOfDepositTermType = null;
|
||||||
final Collection<EnumOptionData> depositTermTypeOptions = null;
|
final Collection<EnumOptionData> depositTermTypeOptions = null;
|
||||||
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
|
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions = null;
|
||||||
|
final BigDecimal minDepositAmount = null;
|
||||||
|
final BigDecimal depositAmount = null;
|
||||||
|
final BigDecimal maxDepositAmount = null;
|
||||||
|
|
||||||
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
|
return new RecurringDepositProductData(id, name, shortName, description, currency, nominalAnnualInterestRate,
|
||||||
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
|
interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType,
|
||||||
@@ -341,7 +357,8 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
|
preClosurePenalInterestOnType, interestFreePeriodTypes, preClosurePenalInterestOnTypeOptions, minDepositTerm,
|
||||||
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
|
maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm, inMultiplesOfDepositTermType,
|
||||||
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType, recurringDepositTypeOptions,
|
||||||
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions);
|
recurringDepositFrequencyTypeOptions, depositTermTypeOptions, inMultiplesOfDepositTermTypeOptions,
|
||||||
|
minDepositAmount, depositAmount, maxDepositAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RecurringDepositProductData withInterestChart(final RecurringDepositProductData product,
|
public static RecurringDepositProductData withInterestChart(final RecurringDepositProductData product,
|
||||||
@@ -362,7 +379,8 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
product.minDepositTerm, product.maxDepositTerm, product.minDepositTermType, product.maxDepositTermType,
|
product.minDepositTerm, product.maxDepositTerm, product.minDepositTermType, product.maxDepositTermType,
|
||||||
product.inMultiplesOfDepositTerm, product.inMultiplesOfDepositTermType, product.recurringDepositType,
|
product.inMultiplesOfDepositTerm, product.inMultiplesOfDepositTermType, product.recurringDepositType,
|
||||||
product.recurringDepositFrequency, product.recurringDepositFrequencyType, product.recurringDepositTypeOptions,
|
product.recurringDepositFrequency, product.recurringDepositFrequencyType, product.recurringDepositTypeOptions,
|
||||||
product.recurringDepositFrequencyTypeOptions, product.depositTermTypeOptions, product.inMultiplesOfDepositTermTypeOptions);
|
product.recurringDepositFrequencyTypeOptions, product.depositTermTypeOptions, product.inMultiplesOfDepositTermTypeOptions, product.minDepositAmount,
|
||||||
|
product.depositAmount, product.maxDepositAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RecurringDepositProductData(final Long id, final String name, final String shortName, final String description,
|
private RecurringDepositProductData(final Long id, final String name, final String shortName, final String description,
|
||||||
@@ -393,7 +411,8 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
|
final EnumOptionData recurringDepositType, final Integer recurringDepositFrequency,
|
||||||
final EnumOptionData recurringDepositFrequencyType, final Collection<EnumOptionData> recurringDepositTypeOptions,
|
final EnumOptionData recurringDepositFrequencyType, final Collection<EnumOptionData> recurringDepositTypeOptions,
|
||||||
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
|
final Collection<EnumOptionData> recurringDepositFrequencyTypeOptions, final Collection<EnumOptionData> depositTermTypeOptions,
|
||||||
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions) {
|
final Collection<EnumOptionData> inMultiplesOfDepositTermTypeOptions,final BigDecimal minDepositAmount,
|
||||||
|
final BigDecimal depositAmount, final BigDecimal maxDepositAmount) {
|
||||||
|
|
||||||
super(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
super(id, name, shortName, description, currency, nominalAnnualInterestRate, interestCompoundingPeriodType,
|
||||||
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
|
interestPostingPeriodType, interestCalculationType, interestCalculationDaysInYearType, lockinPeriodFrequency,
|
||||||
@@ -419,6 +438,9 @@ public class RecurringDepositProductData extends DepositProductData {
|
|||||||
this.recurringDepositFrequencyType = recurringDepositFrequencyType;
|
this.recurringDepositFrequencyType = recurringDepositFrequencyType;
|
||||||
this.recurringDepositFrequency = recurringDepositFrequency;
|
this.recurringDepositFrequency = recurringDepositFrequency;
|
||||||
this.recurringDepositType = recurringDepositType;
|
this.recurringDepositType = recurringDepositType;
|
||||||
|
this.minDepositAmount = minDepositAmount;
|
||||||
|
this.depositAmount = depositAmount;
|
||||||
|
this.maxDepositAmount = maxDepositAmount;
|
||||||
|
|
||||||
// template data
|
// template data
|
||||||
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
|
this.interestFreePeriodTypeOptions = interestFreePeriodTypeOptions;
|
||||||
|
|||||||
+3
-1
@@ -13,6 +13,7 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurring
|
|||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.expectedFirstDepositOnDateParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.accountNoParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.accountNoParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.clientIdParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.clientIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.externalIdParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.externalIdParamName;
|
||||||
@@ -312,6 +313,7 @@ public class DepositAccountAssembler {
|
|||||||
final Integer depositPeriodFrequencyId = command.integerValueOfParameterNamed(depositPeriodFrequencyIdParamName);
|
final Integer depositPeriodFrequencyId = command.integerValueOfParameterNamed(depositPeriodFrequencyIdParamName);
|
||||||
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(depositPeriodFrequencyId);
|
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(depositPeriodFrequencyId);
|
||||||
final SavingsAccount account = null;
|
final SavingsAccount account = null;
|
||||||
|
final LocalDate expectedFirstDepositOnDate = command.localDateValueOfParameterNamed(expectedFirstDepositOnDateParamName);
|
||||||
|
|
||||||
// calculate maturity amount
|
// calculate maturity amount
|
||||||
final BigDecimal maturityAmount = null;// calculated and updated in
|
final BigDecimal maturityAmount = null;// calculated and updated in
|
||||||
@@ -319,7 +321,7 @@ public class DepositAccountAssembler {
|
|||||||
final LocalDate maturityDate = null;// calculated and updated in account
|
final LocalDate maturityDate = null;// calculated and updated in account
|
||||||
final DepositAccountOnClosureType accountOnClosureType = null;
|
final DepositAccountOnClosureType accountOnClosureType = null;
|
||||||
return DepositAccountTermAndPreClosure.createNew(updatedProductPreClosure, updatedProductTerm, account, depositAmount,
|
return DepositAccountTermAndPreClosure.createNew(updatedProductPreClosure, updatedProductTerm, account, depositAmount,
|
||||||
maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, accountOnClosureType);
|
maturityAmount, maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DepositAccountRecurringDetail assembleAccountRecurringDetail(final JsonCommand command,
|
public DepositAccountRecurringDetail assembleAccountRecurringDetail(final JsonCommand command,
|
||||||
|
|||||||
+9
-2
@@ -179,8 +179,15 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
|
|||||||
final LocalDate transactionDate = withdrawal.transactionLocalDate();
|
final LocalDate transactionDate = withdrawal.transactionLocalDate();
|
||||||
if (rdAccount.isReinvestOnClosure()) {
|
if (rdAccount.isReinvestOnClosure()) {
|
||||||
RecurringDepositAccount reinvestedDeposit = rdAccount.reInvest(transactionAmount);
|
RecurringDepositAccount reinvestedDeposit = rdAccount.reInvest(transactionAmount);
|
||||||
final LocalDate transactionStartDate = rdAccount.depositStartDate();
|
depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
|
||||||
rdAccount.updateMaturityDateAndAmount(mc, transactionStartDate);
|
final Locale locale = command.extractLocale();
|
||||||
|
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
|
||||||
|
final LocalDate transactionStartDate = reinvestedDeposit.getActivationLocalDate();
|
||||||
|
final LocalDate nextTransactionStartDate = reinvestedDeposit.nextDepositDate(transactionStartDate);
|
||||||
|
reinvestedDeposit.updateMaturityDateAndAmount(mc, nextTransactionStartDate);
|
||||||
|
reinvestedDeposit.processAccountUponActivation(fmt);
|
||||||
|
reinvestedDeposit.updateMaturityDateAndAmount(mc, nextTransactionStartDate);
|
||||||
|
|
||||||
this.savingsAccountRepository.save(reinvestedDeposit);
|
this.savingsAccountRepository.save(reinvestedDeposit);
|
||||||
autoGenerateAccountNumber(reinvestedDeposit);
|
autoGenerateAccountNumber(reinvestedDeposit);
|
||||||
} else if (rdAccount.isTransferToSavingsOnClosure()) {
|
} else if (rdAccount.isTransferToSavingsOnClosure()) {
|
||||||
|
|||||||
+2
-2
@@ -119,10 +119,10 @@ public class DepositAccountInterestRateChart extends AbstractPersistable<Long> {
|
|||||||
this.account = account;
|
this.account = account;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getApplicableInterestRate(@SuppressWarnings("unused") final BigDecimal depositAmount, final LocalDate periodStartDate, final LocalDate periodEndDate){
|
public BigDecimal getApplicableInterestRate(final BigDecimal depositAmount, final LocalDate periodStartDate, final LocalDate periodEndDate){
|
||||||
BigDecimal effectiveInterestRate = BigDecimal.ZERO;
|
BigDecimal effectiveInterestRate = BigDecimal.ZERO;
|
||||||
for (DepositAccountInterestRateChartSlabs slab : setOfChartSlabs()) {
|
for (DepositAccountInterestRateChartSlabs slab : setOfChartSlabs()) {
|
||||||
if(slab.slabFields().isBetweenPeriod(periodStartDate, periodEndDate)){
|
if(slab.slabFields().isBetweenPeriod(periodStartDate, periodEndDate) && slab.slabFields().isAmountBetween(depositAmount)){
|
||||||
effectiveInterestRate = slab.slabFields().annualInterestRate();
|
effectiveInterestRate = slab.slabFields().annualInterestRate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-6
@@ -50,6 +50,10 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "maturity_date", nullable = true)
|
@Column(name = "maturity_date", nullable = true)
|
||||||
private Date maturityDate;
|
private Date maturityDate;
|
||||||
|
|
||||||
|
@Temporal(TemporalType.DATE)
|
||||||
|
@Column(name = "expected_firstdepositon_date")
|
||||||
|
private Date expectedFirstDepositOnDate;
|
||||||
|
|
||||||
@Column(name = "deposit_period", nullable = true)
|
@Column(name = "deposit_period", nullable = true)
|
||||||
private Integer depositPeriod;
|
private Integer depositPeriod;
|
||||||
|
|
||||||
@@ -75,16 +79,16 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
public static DepositAccountTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
public static DepositAccountTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
||||||
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
||||||
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency,
|
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
|
||||||
final DepositAccountOnClosureType accountOnClosureType) {
|
final DepositAccountOnClosureType accountOnClosureType) {
|
||||||
|
|
||||||
return new DepositAccountTermAndPreClosure(preClosureDetail, depositTermDetail, account, depositAmount, maturityAmount,
|
return new DepositAccountTermAndPreClosure(preClosureDetail, depositTermDetail, account, depositAmount, maturityAmount,
|
||||||
maturityDate, depositPeriod, depositPeriodFrequency, accountOnClosureType);
|
maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DepositAccountTermAndPreClosure(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
private DepositAccountTermAndPreClosure(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
||||||
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
SavingsAccount account, BigDecimal depositAmount, BigDecimal maturityAmount, final LocalDate maturityDate,
|
||||||
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency,
|
Integer depositPeriod, final SavingsPeriodFrequencyType depositPeriodFrequency, final LocalDate expectedFirstDepositOnDate,
|
||||||
final DepositAccountOnClosureType accountOnClosureType) {
|
final DepositAccountOnClosureType accountOnClosureType) {
|
||||||
this.depositAmount = depositAmount;
|
this.depositAmount = depositAmount;
|
||||||
this.maturityAmount = maturityAmount;
|
this.maturityAmount = maturityAmount;
|
||||||
@@ -94,6 +98,7 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
this.preClosureDetail = preClosureDetail;
|
this.preClosureDetail = preClosureDetail;
|
||||||
this.depositTermDetail = depositTermDetail;
|
this.depositTermDetail = depositTermDetail;
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate == null ? null : expectedFirstDepositOnDate.toDate();
|
||||||
this.onAccountClosureType = (accountOnClosureType == null) ? null : accountOnClosureType.getValue();
|
this.onAccountClosureType = (accountOnClosureType == null) ? null : accountOnClosureType.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,13 +180,25 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
return maturityLocalDate;
|
return maturityLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LocalDate getExpectedFirstDepositOnDate() {
|
||||||
|
LocalDate expectedFirstDepositOnLocalDate = null;
|
||||||
|
if (this.expectedFirstDepositOnDate != null) {
|
||||||
|
expectedFirstDepositOnLocalDate = new LocalDate(this.expectedFirstDepositOnDate);
|
||||||
|
}
|
||||||
|
return expectedFirstDepositOnLocalDate;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPreClosurePenalApplicable() {
|
public boolean isPreClosurePenalApplicable() {
|
||||||
if (this.preClosureDetail != null) { return this.preClosureDetail.preClosurePenalApplicable(); }
|
if (this.preClosureDetail != null) { return this.preClosureDetail.preClosurePenalApplicable(); }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getActualDepositPeriod(final LocalDate interestPostingUpToDate, final SavingsPeriodFrequencyType periodFrequencyType) {
|
public Integer getActualDepositPeriod(final LocalDate interestPostingUpToDate, final SavingsPeriodFrequencyType periodFrequencyType) {
|
||||||
final LocalDate depositFromDate = this.account.accountSubmittedOrActivationDate();
|
LocalDate depositFromDate = getExpectedFirstDepositOnDate();
|
||||||
|
|
||||||
|
if(depositFromDate == null)
|
||||||
|
depositFromDate = this.account.accountSubmittedOrActivationDate();
|
||||||
|
|
||||||
Integer actualDepositPeriod = this.depositPeriod;
|
Integer actualDepositPeriod = this.depositPeriod;
|
||||||
if (depositFromDate == null || getMaturityLocalDate() == null || interestPostingUpToDate.isEqual(getMaturityLocalDate())) { return actualDepositPeriod; }
|
if (depositFromDate == null || getMaturityLocalDate() == null || interestPostingUpToDate.isEqual(getMaturityLocalDate())) { return actualDepositPeriod; }
|
||||||
|
|
||||||
@@ -225,14 +242,20 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
public DepositAccountTermAndPreClosure deepCopy(Money depositAmount) {
|
public DepositAccountTermAndPreClosure deepCopy(Money depositAmount) {
|
||||||
final SavingsAccount account = null;
|
final SavingsAccount account = null;
|
||||||
final BigDecimal maturityAmount = null;
|
final BigDecimal maturityAmount = null;
|
||||||
|
final BigDecimal actualDepositAmount = null;
|
||||||
final LocalDate maturityDate = null;
|
final LocalDate maturityDate = null;
|
||||||
final Integer depositPeriod = this.depositPeriod;
|
final Integer depositPeriod = this.depositPeriod;
|
||||||
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(this.depositPeriodFrequency);
|
final SavingsPeriodFrequencyType depositPeriodFrequency = SavingsPeriodFrequencyType.fromInt(this.depositPeriodFrequency);
|
||||||
final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy();
|
final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy();
|
||||||
final DepositTermDetail depositTermDetail = this.depositTermDetail.copy();
|
final DepositTermDetail depositTermDetail = this.depositTermDetail.copy();
|
||||||
|
final LocalDate expectedFirstDepositOnDate = null;
|
||||||
|
|
||||||
final DepositAccountOnClosureType accountOnClosureType = null;
|
final DepositAccountOnClosureType accountOnClosureType = null;
|
||||||
return DepositAccountTermAndPreClosure.createNew(preClosureDetail, depositTermDetail, account, depositAmount.getAmount(), maturityAmount,
|
return DepositAccountTermAndPreClosure.createNew(preClosureDetail, depositTermDetail, account, actualDepositAmount, maturityAmount,
|
||||||
maturityDate, depositPeriod, depositPeriodFrequency, accountOnClosureType);
|
maturityDate, depositPeriod, depositPeriodFrequency, expectedFirstDepositOnDate, accountOnClosureType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateExpectedFirstDepositDate(final LocalDate expectedFirstDepositOnDate) {
|
||||||
|
this.expectedFirstDepositOnDate = expectedFirstDepositOnDate.toDate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+98
@@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
package org.mifosplatform.portfolio.savings.domain;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Embeddable;
|
||||||
|
|
||||||
|
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||||
|
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RecurringDepositProductAmountDetails encapsulates all recurring Deposit Amount of a
|
||||||
|
* {@link RecurringDepositProduct}.
|
||||||
|
*/
|
||||||
|
@Embeddable
|
||||||
|
public class DepositProductAmountDetails {
|
||||||
|
|
||||||
|
@Column(name = "min_deposit_amount", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal minDepositAmount;
|
||||||
|
|
||||||
|
@Column(name = "max_deposit_amount", scale = 6, precision = 19, nullable = true)
|
||||||
|
private BigDecimal maxDepositAmount;
|
||||||
|
|
||||||
|
@Column(name = "deposit_amount", scale = 6, precision = 19, nullable = false)
|
||||||
|
private BigDecimal depositAmount;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static DepositProductAmountDetails createFrom(final BigDecimal minDepositAmount,
|
||||||
|
final BigDecimal depositAmount, final BigDecimal maxDepositAmount) {
|
||||||
|
|
||||||
|
return new DepositProductAmountDetails(minDepositAmount, depositAmount, maxDepositAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DepositProductAmountDetails() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
public DepositProductAmountDetails(final BigDecimal minDepositAmount, final BigDecimal depositAmount, final BigDecimal maxDepositAmount) {
|
||||||
|
this.minDepositAmount = minDepositAmount;
|
||||||
|
this.depositAmount = depositAmount;
|
||||||
|
this.maxDepositAmount = maxDepositAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> update(final JsonCommand command, final DataValidatorBuilder baseDataValidator) {
|
||||||
|
|
||||||
|
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(20);
|
||||||
|
|
||||||
|
final String localeAsInput = command.locale();
|
||||||
|
|
||||||
|
final String minDepositAmountParamName = "minDepositAmount";
|
||||||
|
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(minDepositAmountParamName, this.minDepositAmount)) {
|
||||||
|
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(minDepositAmountParamName);
|
||||||
|
actualChanges.put(minDepositAmountParamName, newValue);
|
||||||
|
actualChanges.put("locale", localeAsInput);
|
||||||
|
this.minDepositAmount = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String maxDepositAmountParamName = "maxDepositAmount";
|
||||||
|
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(maxDepositAmountParamName, this.maxDepositAmount)) {
|
||||||
|
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(maxDepositAmountParamName);
|
||||||
|
actualChanges.put(maxDepositAmountParamName, newValue);
|
||||||
|
actualChanges.put("locale", localeAsInput);
|
||||||
|
this.maxDepositAmount = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String depositAmountParamName = "depositAmount";
|
||||||
|
if (command.isChangeInBigDecimalParameterNamedWithNullCheck(depositAmountParamName, this.depositAmount)) {
|
||||||
|
final BigDecimal newValue = command.bigDecimalValueOfParameterNamed(depositAmountParamName);
|
||||||
|
actualChanges.put(depositAmountParamName, newValue);
|
||||||
|
actualChanges.put("locale", localeAsInput);
|
||||||
|
this.depositAmount = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getMinDepositAmount() {
|
||||||
|
return this.minDepositAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getMaxDepositAmount() {
|
||||||
|
return this.maxDepositAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getDepositAmount() {
|
||||||
|
return this.depositAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+32
-3
@@ -24,6 +24,9 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.preClosur
|
|||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositFrequencyTypeIdParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.recurringDepositTypeIdParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositAmountParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositMinAmountParamName;
|
||||||
|
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.depositMaxAmountParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargesParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargesParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.currencyCodeParamName;
|
||||||
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.descriptionParamName;
|
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.descriptionParamName;
|
||||||
@@ -133,8 +136,9 @@ public class DepositProductAssembler {
|
|||||||
|
|
||||||
final DepositPreClosureDetail preClosureDetail = this.assemblePreClosureDetail(command);
|
final DepositPreClosureDetail preClosureDetail = this.assemblePreClosureDetail(command);
|
||||||
final DepositTermDetail depositTermDetail = this.assembleDepositTermDetail(command);
|
final DepositTermDetail depositTermDetail = this.assembleDepositTermDetail(command);
|
||||||
|
final DepositProductAmountDetails depositProductAmountDetails = this.assembleDepositAmountDetails(command);
|
||||||
final DepositProductTermAndPreClosure productTermAndPreClosure = DepositProductTermAndPreClosure.createNew(preClosureDetail,
|
final DepositProductTermAndPreClosure productTermAndPreClosure = DepositProductTermAndPreClosure.createNew(preClosureDetail,
|
||||||
depositTermDetail, null);
|
depositTermDetail, depositProductAmountDetails, null);
|
||||||
|
|
||||||
// Savings product charges
|
// Savings product charges
|
||||||
final Set<Charge> charges = assembleListOfSavingsProductCharges(command, currencyCode);
|
final Set<Charge> charges = assembleListOfSavingsProductCharges(command, currencyCode);
|
||||||
@@ -167,7 +171,7 @@ public class DepositProductAssembler {
|
|||||||
.failWithCodeNoParameterAddedToErrorCode("max.term.lessthan.min.term");
|
.failWithCodeNoParameterAddedToErrorCode("max.term.lessthan.min.term");
|
||||||
}
|
}
|
||||||
fixedDepositProduct.validateCharts(baseDataValidator);
|
fixedDepositProduct.validateCharts(baseDataValidator);
|
||||||
|
fixedDepositProduct.validateInterestPostingAndCompoundingPeriodTypes(baseDataValidator);
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,8 +224,9 @@ public class DepositProductAssembler {
|
|||||||
|
|
||||||
final DepositPreClosureDetail preClosureDetail = this.assemblePreClosureDetail(command);
|
final DepositPreClosureDetail preClosureDetail = this.assemblePreClosureDetail(command);
|
||||||
final DepositTermDetail depositTermDetail = this.assembleDepositTermDetail(command);
|
final DepositTermDetail depositTermDetail = this.assembleDepositTermDetail(command);
|
||||||
|
final DepositProductAmountDetails depositProductAmountDetails = this.assembleDepositAmountDetails(command);
|
||||||
final DepositProductTermAndPreClosure productTermAndPreClosure = DepositProductTermAndPreClosure.createNew(preClosureDetail,
|
final DepositProductTermAndPreClosure productTermAndPreClosure = DepositProductTermAndPreClosure.createNew(preClosureDetail,
|
||||||
depositTermDetail, null);
|
depositTermDetail, depositProductAmountDetails, null);
|
||||||
final DepositRecurringDetail recurringDetail = this.assembleRecurringDetail(command);
|
final DepositRecurringDetail recurringDetail = this.assembleRecurringDetail(command);
|
||||||
final DepositProductRecurringDetail productRecurringDetail = DepositProductRecurringDetail.createNew(recurringDetail, null);
|
final DepositProductRecurringDetail productRecurringDetail = DepositProductRecurringDetail.createNew(recurringDetail, null);
|
||||||
|
|
||||||
@@ -260,6 +265,7 @@ public class DepositProductAssembler {
|
|||||||
.failWithCodeNoParameterAddedToErrorCode("max.term.lessthan.min.term");
|
.failWithCodeNoParameterAddedToErrorCode("max.term.lessthan.min.term");
|
||||||
}
|
}
|
||||||
recurringDepositProduct.validateCharts(baseDataValidator);
|
recurringDepositProduct.validateCharts(baseDataValidator);
|
||||||
|
recurringDepositProduct.validateInterestPostingAndCompoundingPeriodTypes(baseDataValidator);
|
||||||
|
|
||||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||||
}
|
}
|
||||||
@@ -535,4 +541,27 @@ public class DepositProductAssembler {
|
|||||||
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
|
||||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DepositProductAmountDetails assembleDepositAmountDetails(final JsonCommand command) {
|
||||||
|
|
||||||
|
BigDecimal minDepositAmount = null;
|
||||||
|
if(command.parameterExists(depositMinAmountParamName)) {
|
||||||
|
minDepositAmount = command.bigDecimalValueOfParameterNamed(depositMinAmountParamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal maxDepositAmount = null;
|
||||||
|
if(command.parameterExists(depositMaxAmountParamName)) {
|
||||||
|
maxDepositAmount = command.bigDecimalValueOfParameterNamed(depositMaxAmountParamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal depositAmount = null;
|
||||||
|
if(command.parameterExists(depositAmountParamName)) {
|
||||||
|
depositAmount = command.bigDecimalValueOfParameterNamed(depositAmountParamName);
|
||||||
|
}
|
||||||
|
|
||||||
|
final DepositProductAmountDetails depositRecurringDetail = new DepositProductAmountDetails(minDepositAmount,
|
||||||
|
depositAmount, maxDepositAmount);
|
||||||
|
|
||||||
|
return depositRecurringDetail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+15
-2
@@ -32,20 +32,25 @@ public class DepositProductTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
@JoinColumn(name = "savings_product_id", nullable = false)
|
@JoinColumn(name = "savings_product_id", nullable = false)
|
||||||
private FixedDepositProduct product;
|
private FixedDepositProduct product;
|
||||||
|
|
||||||
|
@Embedded
|
||||||
|
private DepositProductAmountDetails depositProductAmountDetails;
|
||||||
|
|
||||||
protected DepositProductTermAndPreClosure() {
|
protected DepositProductTermAndPreClosure() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DepositProductTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
public static DepositProductTermAndPreClosure createNew(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
||||||
|
DepositProductAmountDetails depositProductMinMaxAmountDetails,
|
||||||
SavingsProduct product) {
|
SavingsProduct product) {
|
||||||
|
|
||||||
return new DepositProductTermAndPreClosure(preClosureDetail, depositTermDetail, product);
|
return new DepositProductTermAndPreClosure(preClosureDetail, depositTermDetail, depositProductMinMaxAmountDetails, product);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DepositProductTermAndPreClosure(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
private DepositProductTermAndPreClosure(DepositPreClosureDetail preClosureDetail, DepositTermDetail depositTermDetail,
|
||||||
SavingsProduct product) {
|
DepositProductAmountDetails depositProductMinMaxAmountDetails, SavingsProduct product) {
|
||||||
this.preClosureDetail = preClosureDetail;
|
this.preClosureDetail = preClosureDetail;
|
||||||
this.depositTermDetail = depositTermDetail;
|
this.depositTermDetail = depositTermDetail;
|
||||||
|
this.depositProductAmountDetails = depositProductMinMaxAmountDetails;
|
||||||
this.product = (FixedDepositProduct)product;
|
this.product = (FixedDepositProduct)product;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +63,10 @@ public class DepositProductTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
if (this.depositTermDetail != null) {
|
if (this.depositTermDetail != null) {
|
||||||
actualChanges.putAll(this.depositTermDetail.update(command, baseDataValidator));
|
actualChanges.putAll(this.depositTermDetail.update(command, baseDataValidator));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.depositProductAmountDetails != null) {
|
||||||
|
actualChanges.putAll(this.depositProductAmountDetails.update(command, baseDataValidator));
|
||||||
|
}
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +78,10 @@ public class DepositProductTermAndPreClosure extends AbstractPersistable<Long> {
|
|||||||
return this.depositTermDetail;
|
return this.depositTermDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DepositProductAmountDetails depositProductAmountDetails() {
|
||||||
|
return this.depositProductAmountDetails;
|
||||||
|
}
|
||||||
|
|
||||||
public void updateProductReference(final SavingsProduct product){
|
public void updateProductReference(final SavingsProduct product){
|
||||||
this.product = (FixedDepositProduct)product;
|
this.product = (FixedDepositProduct)product;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
@@ -11,6 +11,7 @@ import static org.mifosplatform.portfolio.savings.DepositsApiConstants.FIXED_DEP
|
|||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -261,4 +262,36 @@ public class FixedDepositProduct extends SavingsProduct {
|
|||||||
return this.productTermAndPreClosure;
|
return this.productTermAndPreClosure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void validateInterestPostingAndCompoundingPeriodTypes(final DataValidatorBuilder baseDataValidator) {
|
||||||
|
Map<SavingsPostingInterestPeriodType, List<SavingsCompoundingInterestPeriodType>> postingtoCompoundMap =
|
||||||
|
new HashMap<SavingsPostingInterestPeriodType, List<SavingsCompoundingInterestPeriodType>>();
|
||||||
|
postingtoCompoundMap.put(SavingsPostingInterestPeriodType.MONTHLY,
|
||||||
|
Arrays.asList(new SavingsCompoundingInterestPeriodType[]{SavingsCompoundingInterestPeriodType.DAILY,SavingsCompoundingInterestPeriodType.MONTHLY}));
|
||||||
|
|
||||||
|
postingtoCompoundMap.put(SavingsPostingInterestPeriodType.QUATERLY,
|
||||||
|
Arrays.asList(new SavingsCompoundingInterestPeriodType[]{SavingsCompoundingInterestPeriodType.DAILY
|
||||||
|
,SavingsCompoundingInterestPeriodType.MONTHLY,SavingsCompoundingInterestPeriodType.QUATERLY}));
|
||||||
|
|
||||||
|
postingtoCompoundMap.put(SavingsPostingInterestPeriodType.BIANNUAL,
|
||||||
|
Arrays.asList(new SavingsCompoundingInterestPeriodType[]{SavingsCompoundingInterestPeriodType.DAILY,
|
||||||
|
SavingsCompoundingInterestPeriodType.MONTHLY,SavingsCompoundingInterestPeriodType.QUATERLY,SavingsCompoundingInterestPeriodType.BI_ANNUAL}));
|
||||||
|
|
||||||
|
postingtoCompoundMap.put(SavingsPostingInterestPeriodType.ANNUAL,
|
||||||
|
Arrays.asList(new SavingsCompoundingInterestPeriodType[]{SavingsCompoundingInterestPeriodType.DAILY,
|
||||||
|
SavingsCompoundingInterestPeriodType.MONTHLY,SavingsCompoundingInterestPeriodType.QUATERLY
|
||||||
|
,SavingsCompoundingInterestPeriodType.BI_ANNUAL,SavingsCompoundingInterestPeriodType.ANNUAL}));
|
||||||
|
|
||||||
|
SavingsPostingInterestPeriodType savingsPostingInterestPeriodType = SavingsPostingInterestPeriodType.fromInt(interestPostingPeriodType);
|
||||||
|
SavingsCompoundingInterestPeriodType savingsCompoundingInterestPeriodType = SavingsCompoundingInterestPeriodType.fromInt(interestCompoundingPeriodType);
|
||||||
|
|
||||||
|
if(postingtoCompoundMap.get(savingsPostingInterestPeriodType) == null ||
|
||||||
|
!postingtoCompoundMap.get(savingsPostingInterestPeriodType).contains(savingsCompoundingInterestPeriodType)) {
|
||||||
|
baseDataValidator.failWithCodeNoParameterAddedToErrorCode("posting.period.type.is.less.than.compound.period.type",
|
||||||
|
savingsPostingInterestPeriodType.name(),savingsCompoundingInterestPeriodType.name());
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+118
-13
@@ -100,6 +100,28 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
recurringDetail, chart, allowOverdraft, overdraftLimit);
|
recurringDetail, chart, allowOverdraft, overdraftLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static RecurringDepositAccount createNewActivatedAccount(final Client client, final Group group,
|
||||||
|
final SavingsProduct product, final Staff fieldOfficer, final String accountNo, final String externalId,
|
||||||
|
final AccountType accountType, final LocalDate submittedOnDate, final AppUser submittedBy, final BigDecimal interestRate,
|
||||||
|
final SavingsCompoundingInterestPeriodType interestCompoundingPeriodType,
|
||||||
|
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||||
|
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||||
|
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
||||||
|
final boolean withdrawalFeeApplicableForTransfer, final Set<SavingsAccountCharge> savingsAccountCharges,
|
||||||
|
final DepositAccountTermAndPreClosure accountTermAndPreClosure, final DepositAccountRecurringDetail recurringDetail,
|
||||||
|
final DepositAccountInterestRateChart chart) {
|
||||||
|
|
||||||
|
final boolean allowOverdraft = false;
|
||||||
|
final BigDecimal overdraftLimit = new BigDecimal(0);
|
||||||
|
|
||||||
|
final SavingsAccountStatusType status = SavingsAccountStatusType.ACTIVE;
|
||||||
|
return new RecurringDepositAccount(client, group, product, fieldOfficer, accountNo, externalId, status, accountType,
|
||||||
|
submittedOnDate, submittedBy, interestRate, interestCompoundingPeriodType, interestPostingPeriodType,
|
||||||
|
interestCalculationType, interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency,
|
||||||
|
lockinPeriodFrequencyType, withdrawalFeeApplicableForTransfer, savingsAccountCharges, accountTermAndPreClosure,
|
||||||
|
recurringDetail, chart, allowOverdraft, overdraftLimit);
|
||||||
|
}
|
||||||
|
|
||||||
private RecurringDepositAccount(final Client client, final Group group, final SavingsProduct product, final Staff fieldOfficer,
|
private RecurringDepositAccount(final Client client, final Group group, final SavingsProduct product, final Staff fieldOfficer,
|
||||||
final String accountNo, final String externalId, final SavingsAccountStatusType status, final AccountType accountType,
|
final String accountNo, final String externalId, final SavingsAccountStatusType status, final AccountType accountType,
|
||||||
final LocalDate submittedOnDate, final AppUser submittedBy, final BigDecimal nominalAnnualInterestRate,
|
final LocalDate submittedOnDate, final AppUser submittedBy, final BigDecimal nominalAnnualInterestRate,
|
||||||
@@ -159,7 +181,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount();
|
final BigDecimal depositAmount = recurringDetail.recurringDepositAmount();
|
||||||
|
|
||||||
BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), depositCloseDate);
|
BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), depositCloseDate);
|
||||||
|
|
||||||
@@ -251,7 +273,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
.fromInt(this.interestCalculationDaysInYearType);
|
.fromInt(this.interestCalculationDaysInYearType);
|
||||||
|
|
||||||
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(
|
final List<LocalDateInterval> postingPeriodIntervals = this.savingsHelper.determineInterestPostingPeriods(
|
||||||
accountSubmittedOrActivationDate(), maturityDate, postingPeriodType);
|
depositStartDate(), maturityDate, postingPeriodType);
|
||||||
|
|
||||||
final List<PostingPeriod> allPostingPeriods = new ArrayList<PostingPeriod>();
|
final List<PostingPeriod> allPostingPeriods = new ArrayList<PostingPeriod>();
|
||||||
|
|
||||||
@@ -321,7 +343,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
return allTransactions;
|
return allTransactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate nextDepositDate(LocalDate depositDate) {
|
public LocalDate nextDepositDate(LocalDate depositDate) {
|
||||||
final LocalDate depositStartDate = depositStartDate();
|
final LocalDate depositStartDate = depositStartDate();
|
||||||
LocalDate nextDepositDate = depositStartDate;
|
LocalDate nextDepositDate = depositStartDate;
|
||||||
while (!depositDate.isBefore(nextDepositDate)) {
|
while (!depositDate.isBefore(nextDepositDate)) {
|
||||||
@@ -357,7 +379,9 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
public LocalDate depositStartDate() {
|
public LocalDate depositStartDate() {
|
||||||
// TODO: Support to add deposit start date which can be a date after
|
// TODO: Support to add deposit start date which can be a date after
|
||||||
// account activation date.
|
// account activation date.
|
||||||
final LocalDate depositStartDate = accountSubmittedOrActivationDate();
|
final LocalDate depositStartDate = accountTermAndPreClosure.getExpectedFirstDepositOnDate();
|
||||||
|
if(depositStartDate == null)
|
||||||
|
return accountSubmittedOrActivationDate();
|
||||||
return depositStartDate;
|
return depositStartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,17 +461,18 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processAccountUponActivation(final DateTimeFormatter fmt) {
|
protected void processAccountUponActivation(final DateTimeFormatter fmt) {
|
||||||
final Money recurringDepositAmount = Money.of(this.currency, this.recurringDetail.recurringDepositAmount());
|
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
|
||||||
if (recurringDepositAmount.isGreaterThanZero()) {
|
|
||||||
|
|
||||||
|
if (minRequiredOpeningBalance.isGreaterThanZero()) {
|
||||||
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, getActivationLocalDate(),
|
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, getActivationLocalDate(),
|
||||||
recurringDepositAmount.getAmount(), null, new Date());
|
minRequiredOpeningBalance.getAmount(), null, new Date());
|
||||||
deposit(transactionDTO);
|
deposit(transactionDTO);
|
||||||
final LocalDate interestPostingUpToDate = interestPostingUpToDate(DateUtils.getLocalDateOfTenant());
|
|
||||||
// update existing transactions so derived balance fields are
|
// update existing transactions so derived balance fields are
|
||||||
// correct.
|
// correct.
|
||||||
recalculateDailyBalances(Money.zero(this.currency), interestPostingUpToDate);
|
recalculateDailyBalances(Money.zero(this.currency), DateUtils.getLocalDateOfTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingsAccountTransaction close(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
|
public SavingsAccountTransaction close(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
|
||||||
@@ -778,6 +803,25 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
if (!chartInterval.contains(accountSubmittedOrActivationDate())) {
|
if (!chartInterval.contains(accountSubmittedOrActivationDate())) {
|
||||||
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("no.valid.interest.rate.slab.available.for.date.range");
|
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("no.valid.interest.rate.slab.available.for.date.range");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean firstDepositDateBeforeMaturityAndOnOrAfterActivationDate = firstDepositDateBeforeMaturityAndOnOrAfterActivationDate();
|
||||||
|
|
||||||
|
if(!firstDepositDateBeforeMaturityAndOnOrAfterActivationDate) {
|
||||||
|
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("expected.first.deposit.date.is.not.between.maturity.date.and.activation.or.submitted.date");
|
||||||
|
}
|
||||||
|
|
||||||
|
final BigDecimal recurringDepositAmount = recurringDetail.recurringDepositAmount();
|
||||||
|
BigDecimal applicableInterestRate = this.chart.getApplicableInterestRate(recurringDepositAmount, depositStartDate(), calculateMaturityDate());
|
||||||
|
|
||||||
|
if(applicableInterestRate.equals(BigDecimal.ZERO)) {
|
||||||
|
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("no.applicable.interest.rate.is.found.based.on.amount.and.deposit.period");
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean recurringFrequencyBeforeDepositPeriod = recurringFrequencyBeforeDepositPeriod();
|
||||||
|
|
||||||
|
if(!recurringFrequencyBeforeDepositPeriod) {
|
||||||
|
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("recurring.frequency.not.before.deposit.period");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReinvestOnClosure() {
|
public boolean isReinvestOnClosure() {
|
||||||
@@ -795,7 +839,7 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
final SavingsProduct product = this.product;
|
final SavingsProduct product = this.product;
|
||||||
final InterestRateChart productChart = product.applicableChart(getClosedOnDate());
|
final InterestRateChart productChart = product.applicableChart(getClosedOnDate());
|
||||||
final DepositAccountInterestRateChart newChart = DepositAccountInterestRateChart.from(productChart);
|
final DepositAccountInterestRateChart newChart = DepositAccountInterestRateChart.from(productChart);
|
||||||
final String accountNumber = this.accountNumber;
|
final String accountNumber = null;
|
||||||
final String externalId = this.externalId;
|
final String externalId = this.externalId;
|
||||||
final AccountType accountType = AccountType.fromInt(this.accountType);
|
final AccountType accountType = AccountType.fromInt(this.accountType);
|
||||||
final SavingsPostingInterestPeriodType postingPeriodType = SavingsPostingInterestPeriodType.fromInt(this.interestPostingPeriodType);
|
final SavingsPostingInterestPeriodType postingPeriodType = SavingsPostingInterestPeriodType.fromInt(this.interestPostingPeriodType);
|
||||||
@@ -804,17 +848,78 @@ public class RecurringDepositAccount extends SavingsAccount {
|
|||||||
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
final SavingsInterestCalculationType interestCalculationType = SavingsInterestCalculationType.fromInt(this.interestCalculationType);
|
||||||
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
|
final SavingsInterestCalculationDaysInYearType daysInYearType = SavingsInterestCalculationDaysInYearType
|
||||||
.fromInt(this.interestCalculationDaysInYearType);
|
.fromInt(this.interestCalculationDaysInYearType);
|
||||||
final BigDecimal minRequiredOpeningBalance = null;
|
final BigDecimal minRequiredOpeningBalance = depositAmount.getAmount();
|
||||||
final BigDecimal interestRate = null;
|
final BigDecimal interestRate = BigDecimal.ZERO;
|
||||||
final Set<SavingsAccountCharge> savingsAccountCharges = null;
|
final Set<SavingsAccountCharge> savingsAccountCharges = null;
|
||||||
final SavingsPeriodFrequencyType lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(this.lockinPeriodFrequencyType);
|
final SavingsPeriodFrequencyType lockinPeriodFrequencyType = SavingsPeriodFrequencyType.fromInt(this.lockinPeriodFrequencyType);
|
||||||
final Integer lockinPeriodFrequency = this.lockinPeriodFrequency;
|
final Integer lockinPeriodFrequency = this.lockinPeriodFrequency;
|
||||||
final boolean withdrawalFeeApplicableForTransfer = false;
|
final boolean withdrawalFeeApplicableForTransfer = false;
|
||||||
|
|
||||||
return RecurringDepositAccount.createNewApplicationForSubmittal(client, group, product, fieldOfficer, accountNumber, externalId,
|
LocalDate now = LocalDate.now();
|
||||||
|
|
||||||
|
newAccountTermAndPreClosure.updateExpectedFirstDepositDate(now);
|
||||||
|
|
||||||
|
RecurringDepositAccount rdAccount = RecurringDepositAccount.createNewActivatedAccount(client, group, product, fieldOfficer, accountNumber, externalId,
|
||||||
accountType, getClosedOnDate(), closedBy, interestRate, compoundingPeriodType, postingPeriodType, interestCalculationType,
|
accountType, getClosedOnDate(), closedBy, interestRate, compoundingPeriodType, postingPeriodType, interestCalculationType,
|
||||||
daysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
daysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||||
withdrawalFeeApplicableForTransfer, savingsAccountCharges, newAccountTermAndPreClosure, recurringDetail, newChart);
|
withdrawalFeeApplicableForTransfer, savingsAccountCharges, newAccountTermAndPreClosure, recurringDetail, newChart);
|
||||||
|
|
||||||
|
rdAccount.setDatesFrom(now);
|
||||||
|
newAccountTermAndPreClosure.updateAccountReference(rdAccount);
|
||||||
|
recurringDetail.updateAccountReference(rdAccount);
|
||||||
|
|
||||||
|
return rdAccount;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean firstDepositDateBeforeMaturityAndOnOrAfterActivationDate() {
|
||||||
|
LocalDate expectedFirstDepositLocalDate = accountTermAndPreClosure.getExpectedFirstDepositOnDate();
|
||||||
|
LocalDate maturityLocalDate = calculateMaturityDate();
|
||||||
|
LocalDate activateOnSubmittedLocalDate = accountSubmittedOrActivationDate();
|
||||||
|
|
||||||
|
return expectedFirstDepositLocalDate.isBefore(maturityLocalDate) &&
|
||||||
|
(activateOnSubmittedLocalDate.isEqual(expectedFirstDepositLocalDate) || activateOnSubmittedLocalDate.isBefore(expectedFirstDepositLocalDate));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDatesFrom(final LocalDate now) {
|
||||||
|
this.rejectedOnDate = null;
|
||||||
|
this.rejectedBy = null;
|
||||||
|
this.withdrawnOnDate = null;
|
||||||
|
this.withdrawnBy = null;
|
||||||
|
this.closedOnDate = null;
|
||||||
|
this.closedBy = null;
|
||||||
|
|
||||||
|
this.activatedBy = null;
|
||||||
|
this.lockedInUntilDate = null;
|
||||||
|
|
||||||
|
this.activatedOnDate = now.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean recurringFrequencyBeforeDepositPeriod() {
|
||||||
|
final int recurringFrequency = recurringDetail.recurringDepositFrequency();
|
||||||
|
final SavingsPeriodFrequencyType recurringfrequencyType = recurringDetail.recurringDepositFrequencyType();
|
||||||
|
|
||||||
|
LocalDate depositStartDate = accountTermAndPreClosure.getExpectedFirstDepositOnDate();
|
||||||
|
|
||||||
|
LocalDate endDateWithFirstRecurringFrequency = null;
|
||||||
|
|
||||||
|
switch (recurringfrequencyType) {
|
||||||
|
case DAYS:
|
||||||
|
endDateWithFirstRecurringFrequency = depositStartDate.plusDays(recurringFrequency);
|
||||||
|
break;
|
||||||
|
case MONTHS:
|
||||||
|
endDateWithFirstRecurringFrequency = depositStartDate.plusMonths(recurringFrequency);
|
||||||
|
break;
|
||||||
|
case WEEKS:
|
||||||
|
endDateWithFirstRecurringFrequency = depositStartDate.plusWeeks(recurringFrequency);
|
||||||
|
break;
|
||||||
|
case YEARS:
|
||||||
|
endDateWithFirstRecurringFrequency = depositStartDate.plusYears(recurringFrequency);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return endDateWithFirstRecurringFrequency != null && endDateWithFirstRecurringFrequency.isBefore(calculateMaturityDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
@@ -69,6 +69,15 @@ public final class SavingsHelper {
|
|||||||
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case BIANNUAL:
|
||||||
|
final int byear = periodStartDate.getYearOfEra();
|
||||||
|
final int bmonthofYear = periodStartDate.getMonthOfYear();
|
||||||
|
if (bmonthofYear <= 6) {
|
||||||
|
periodEndDate = new DateTime().withDate(byear, 6, 30).toLocalDate();
|
||||||
|
} else if (bmonthofYear <= 12) {
|
||||||
|
periodEndDate = new DateTime().withDate(byear, 12, 31).toLocalDate();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ANNUAL:
|
case ANNUAL:
|
||||||
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||||
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
||||||
|
|||||||
+154
@@ -0,0 +1,154 @@
|
|||||||
|
package org.mifosplatform.portfolio.savings.domain.interest;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
||||||
|
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||||
|
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
|
||||||
|
|
||||||
|
public class AnnualCompoundingPeriod implements CompoundingPeriod {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final LocalDateInterval periodInterval;
|
||||||
|
private final List<EndOfDayBalance> endOfDayBalances;
|
||||||
|
|
||||||
|
public static AnnualCompoundingPeriod create(final LocalDateInterval periodInterval, final List<EndOfDayBalance> allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
|
||||||
|
|
||||||
|
final List<EndOfDayBalance> endOfDayBalancesWithinPeriod = endOfDayBalancesWithinPeriodInterval(periodInterval, allEndOfDayBalances, upToInterestCalculationDate);
|
||||||
|
|
||||||
|
return new AnnualCompoundingPeriod(periodInterval, endOfDayBalancesWithinPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal calculateInterest(final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
final BigDecimal interestOnBalanceUnrounded = balance.calculateInterestOnBalance(BigDecimal.ZERO, interestRateAsFraction,
|
||||||
|
daysInYear);
|
||||||
|
interestEarned = interestEarned.add(interestOnBalanceUnrounded);
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal calculateInterest(final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
||||||
|
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestToCompound,
|
||||||
|
final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
switch (interestCalculationType) {
|
||||||
|
case DAILY_BALANCE:
|
||||||
|
interestEarned = calculateUsingDailyBalanceMethod(compoundingInterestPeriodType, interestToCompound,
|
||||||
|
interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case AVERAGE_DAILY_BALANCE:
|
||||||
|
interestEarned = calculateUsingAverageDailyBalanceMethod(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateUsingAverageDailyBalanceMethod(final BigDecimal interestToCompound,
|
||||||
|
final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal cumulativeBalance = BigDecimal.ZERO;
|
||||||
|
Integer numberOfDays = Integer.valueOf(0);
|
||||||
|
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
final BigDecimal endOfDayCumulativeBalance = balance.cumulativeBalance(interestToCompound);
|
||||||
|
cumulativeBalance = cumulativeBalance.add(endOfDayCumulativeBalance);
|
||||||
|
|
||||||
|
final Integer balanceExistsForNumberOfDays = balance.getNumberOfDays();
|
||||||
|
numberOfDays = numberOfDays + balanceExistsForNumberOfDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
if (cumulativeBalance.compareTo(BigDecimal.ZERO) != 0 && numberOfDays > 0) {
|
||||||
|
final BigDecimal averageDailyBalance = cumulativeBalance.divide(BigDecimal.valueOf(numberOfDays), MathContext.DECIMAL64)
|
||||||
|
.setScale(9, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
final BigDecimal multiplicand = BigDecimal.ONE.divide(BigDecimal.valueOf(daysInYear), MathContext.DECIMAL64);
|
||||||
|
final BigDecimal dailyInterestRate = interestRateAsFraction.multiply(multiplicand, MathContext.DECIMAL64);
|
||||||
|
final BigDecimal periodicInterestRate = dailyInterestRate.multiply(BigDecimal.valueOf(numberOfDays), MathContext.DECIMAL64);
|
||||||
|
|
||||||
|
interestEarned = averageDailyBalance.multiply(periodicInterestRate, MathContext.DECIMAL64).setScale(9, RoundingMode.HALF_EVEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateUsingDailyBalanceMethod(final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
||||||
|
final BigDecimal interestToCompound, final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
BigDecimal interestOnBalanceUnrounded = BigDecimal.ZERO;
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
|
||||||
|
switch (compoundingInterestPeriodType) {
|
||||||
|
case DAILY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalanceAndInterest(interestToCompound, interestRateAsFraction,
|
||||||
|
daysInYear);
|
||||||
|
break;
|
||||||
|
case MONTHLY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case QUATERLY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
// case WEEKLY:
|
||||||
|
// break;
|
||||||
|
// case BIWEEKLY:
|
||||||
|
// break;
|
||||||
|
case BI_ANNUAL:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case ANNUAL:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
|
// break;
|
||||||
|
case INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
interestEarned = interestEarned.add(interestOnBalanceUnrounded);
|
||||||
|
}
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<EndOfDayBalance> endOfDayBalancesWithinPeriodInterval(final LocalDateInterval compoundingPeriodInterval,
|
||||||
|
final List<EndOfDayBalance> allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
|
||||||
|
|
||||||
|
final List<EndOfDayBalance> endOfDayBalancesForPeriodInterval = new ArrayList<EndOfDayBalance>();
|
||||||
|
|
||||||
|
for (final EndOfDayBalance endOfDayBalance : allEndOfDayBalances) {
|
||||||
|
|
||||||
|
if (compoundingPeriodInterval.contains(endOfDayBalance.date())) {
|
||||||
|
final EndOfDayBalance cappedToPeriodEndDate = endOfDayBalance.upTo(compoundingPeriodInterval, upToInterestCalculationDate);
|
||||||
|
endOfDayBalancesForPeriodInterval.add(cappedToPeriodEndDate);
|
||||||
|
} else if (endOfDayBalance.contains(compoundingPeriodInterval)) {
|
||||||
|
final EndOfDayBalance cappedToPeriodEndDate = endOfDayBalance.upTo(compoundingPeriodInterval, upToInterestCalculationDate);
|
||||||
|
endOfDayBalancesForPeriodInterval.add(cappedToPeriodEndDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return endOfDayBalancesForPeriodInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AnnualCompoundingPeriod(final LocalDateInterval periodInterval, final List<EndOfDayBalance> endOfDayBalances) {
|
||||||
|
this.periodInterval = periodInterval;
|
||||||
|
this.endOfDayBalances = endOfDayBalances;
|
||||||
|
}
|
||||||
|
}
|
||||||
+154
@@ -0,0 +1,154 @@
|
|||||||
|
package org.mifosplatform.portfolio.savings.domain.interest;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
||||||
|
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||||
|
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
|
||||||
|
|
||||||
|
public class BiAnnualCompoundingPeriod implements CompoundingPeriod {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final LocalDateInterval periodInterval;
|
||||||
|
private final List<EndOfDayBalance> endOfDayBalances;
|
||||||
|
|
||||||
|
public static BiAnnualCompoundingPeriod create(final LocalDateInterval periodInterval, final List<EndOfDayBalance> allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
|
||||||
|
|
||||||
|
final List<EndOfDayBalance> endOfDayBalancesWithinPeriod = endOfDayBalancesWithinPeriodInterval(periodInterval, allEndOfDayBalances, upToInterestCalculationDate);
|
||||||
|
|
||||||
|
return new BiAnnualCompoundingPeriod(periodInterval, endOfDayBalancesWithinPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal calculateInterest(final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
final BigDecimal interestOnBalanceUnrounded = balance.calculateInterestOnBalance(BigDecimal.ZERO, interestRateAsFraction,
|
||||||
|
daysInYear);
|
||||||
|
interestEarned = interestEarned.add(interestOnBalanceUnrounded);
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal calculateInterest(final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
||||||
|
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestToCompound,
|
||||||
|
final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
switch (interestCalculationType) {
|
||||||
|
case DAILY_BALANCE:
|
||||||
|
interestEarned = calculateUsingDailyBalanceMethod(compoundingInterestPeriodType, interestToCompound,
|
||||||
|
interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case AVERAGE_DAILY_BALANCE:
|
||||||
|
interestEarned = calculateUsingAverageDailyBalanceMethod(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateUsingAverageDailyBalanceMethod(final BigDecimal interestToCompound,
|
||||||
|
final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal cumulativeBalance = BigDecimal.ZERO;
|
||||||
|
Integer numberOfDays = Integer.valueOf(0);
|
||||||
|
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
final BigDecimal endOfDayCumulativeBalance = balance.cumulativeBalance(interestToCompound);
|
||||||
|
cumulativeBalance = cumulativeBalance.add(endOfDayCumulativeBalance);
|
||||||
|
|
||||||
|
final Integer balanceExistsForNumberOfDays = balance.getNumberOfDays();
|
||||||
|
numberOfDays = numberOfDays + balanceExistsForNumberOfDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
if (cumulativeBalance.compareTo(BigDecimal.ZERO) != 0 && numberOfDays > 0) {
|
||||||
|
final BigDecimal averageDailyBalance = cumulativeBalance.divide(BigDecimal.valueOf(numberOfDays), MathContext.DECIMAL64)
|
||||||
|
.setScale(9, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
final BigDecimal multiplicand = BigDecimal.ONE.divide(BigDecimal.valueOf(daysInYear), MathContext.DECIMAL64);
|
||||||
|
final BigDecimal dailyInterestRate = interestRateAsFraction.multiply(multiplicand, MathContext.DECIMAL64);
|
||||||
|
final BigDecimal periodicInterestRate = dailyInterestRate.multiply(BigDecimal.valueOf(numberOfDays), MathContext.DECIMAL64);
|
||||||
|
|
||||||
|
interestEarned = averageDailyBalance.multiply(periodicInterestRate, MathContext.DECIMAL64).setScale(9, RoundingMode.HALF_EVEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateUsingDailyBalanceMethod(final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
||||||
|
final BigDecimal interestToCompound, final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
BigDecimal interestOnBalanceUnrounded = BigDecimal.ZERO;
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
|
||||||
|
switch (compoundingInterestPeriodType) {
|
||||||
|
case DAILY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalanceAndInterest(interestToCompound, interestRateAsFraction,
|
||||||
|
daysInYear);
|
||||||
|
break;
|
||||||
|
case MONTHLY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case QUATERLY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
// case WEEKLY:
|
||||||
|
// break;
|
||||||
|
// case BIWEEKLY:
|
||||||
|
// break;
|
||||||
|
case BI_ANNUAL:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case ANNUAL:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
|
// break;
|
||||||
|
case INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
interestEarned = interestEarned.add(interestOnBalanceUnrounded);
|
||||||
|
}
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<EndOfDayBalance> endOfDayBalancesWithinPeriodInterval(final LocalDateInterval compoundingPeriodInterval,
|
||||||
|
final List<EndOfDayBalance> allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
|
||||||
|
|
||||||
|
final List<EndOfDayBalance> endOfDayBalancesForPeriodInterval = new ArrayList<EndOfDayBalance>();
|
||||||
|
|
||||||
|
for (final EndOfDayBalance endOfDayBalance : allEndOfDayBalances) {
|
||||||
|
|
||||||
|
if (compoundingPeriodInterval.contains(endOfDayBalance.date())) {
|
||||||
|
final EndOfDayBalance cappedToPeriodEndDate = endOfDayBalance.upTo(compoundingPeriodInterval, upToInterestCalculationDate);
|
||||||
|
endOfDayBalancesForPeriodInterval.add(cappedToPeriodEndDate);
|
||||||
|
} else if (endOfDayBalance.contains(compoundingPeriodInterval)) {
|
||||||
|
final EndOfDayBalance cappedToPeriodEndDate = endOfDayBalance.upTo(compoundingPeriodInterval, upToInterestCalculationDate);
|
||||||
|
endOfDayBalancesForPeriodInterval.add(cappedToPeriodEndDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return endOfDayBalancesForPeriodInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BiAnnualCompoundingPeriod(final LocalDateInterval periodInterval, final List<EndOfDayBalance> endOfDayBalances) {
|
||||||
|
this.periodInterval = periodInterval;
|
||||||
|
this.endOfDayBalances = endOfDayBalances;
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-3
@@ -6,6 +6,7 @@ import java.math.RoundingMode;
|
|||||||
|
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
||||||
|
import org.mifosplatform.infrastructure.core.service.DateUtils;
|
||||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||||
|
|
||||||
public class EndOfDayBalance {
|
public class EndOfDayBalance {
|
||||||
@@ -90,13 +91,18 @@ public class EndOfDayBalance {
|
|||||||
Money startingBalance = this.openingBalance;
|
Money startingBalance = this.openingBalance;
|
||||||
LocalDate balanceStartDate = this.date;
|
LocalDate balanceStartDate = this.date;
|
||||||
|
|
||||||
|
LocalDate oldBalanceEndDate = this.date.plusDays(this.numberOfDays - 1);
|
||||||
|
|
||||||
|
int daysOfBalance = this.numberOfDays;
|
||||||
|
|
||||||
if (this.date.isBefore(compoundingPeriodInterval.startDate())) {
|
if (this.date.isBefore(compoundingPeriodInterval.startDate())) {
|
||||||
balanceStartDate = compoundingPeriodInterval.startDate();
|
balanceStartDate = compoundingPeriodInterval.startDate();
|
||||||
startingBalance = this.endOfDayBalance;
|
startingBalance = this.endOfDayBalance;
|
||||||
|
final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate, oldBalanceEndDate);
|
||||||
|
daysOfBalance = balancePeriodInterval.daysInPeriodInclusiveOfEndDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
int daysOfBalance = this.numberOfDays;
|
LocalDate balanceEndDate = balanceStartDate.plusDays(daysOfBalance - 1);
|
||||||
LocalDate balanceEndDate = balanceStartDate.plusDays(this.numberOfDays);
|
|
||||||
if (balanceEndDate.isAfter(compoundingPeriodInterval.endDate())) {
|
if (balanceEndDate.isAfter(compoundingPeriodInterval.endDate())) {
|
||||||
balanceEndDate = compoundingPeriodInterval.endDate();
|
balanceEndDate = compoundingPeriodInterval.endDate();
|
||||||
final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
final LocalDateInterval balancePeriodInterval = LocalDateInterval.create(balanceStartDate, balanceEndDate);
|
||||||
@@ -113,7 +119,7 @@ public class EndOfDayBalance {
|
|||||||
|
|
||||||
public boolean contains(final LocalDateInterval compoundingPeriodInterval) {
|
public boolean contains(final LocalDateInterval compoundingPeriodInterval) {
|
||||||
|
|
||||||
final LocalDate balanceUpToDate = this.date.plusDays(this.numberOfDays);
|
final LocalDate balanceUpToDate = this.date.plusDays(this.numberOfDays - 1);
|
||||||
|
|
||||||
final LocalDateInterval balanceInterval = LocalDateInterval.create(this.date, balanceUpToDate);
|
final LocalDateInterval balanceInterval = LocalDateInterval.create(this.date, balanceUpToDate);
|
||||||
return balanceInterval.containsPortionOf(compoundingPeriodInterval);
|
return balanceInterval.containsPortionOf(compoundingPeriodInterval);
|
||||||
|
|||||||
+113
-41
@@ -4,6 +4,7 @@ import java.math.BigDecimal;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.LocalDate;
|
import org.joda.time.LocalDate;
|
||||||
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
@@ -185,14 +186,83 @@ public class PostingPeriod {
|
|||||||
// break;
|
// break;
|
||||||
// case BIWEEKLY:
|
// case BIWEEKLY:
|
||||||
// break;
|
// break;
|
||||||
// case QUATERLY:
|
case QUATERLY:
|
||||||
// break;
|
final LocalDate qPostingPeriodEndDate = postingPeriodInterval.endDate();
|
||||||
// case BI_ANNUAL:
|
|
||||||
// break;
|
periodStartDate = postingPeriodInterval.startDate();
|
||||||
// case ANNUAL:
|
periodEndDate = periodStartDate;
|
||||||
// break;
|
|
||||||
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
while (!periodStartDate.isAfter(qPostingPeriodEndDate) && !periodEndDate.isAfter(qPostingPeriodEndDate)) {
|
||||||
// break;
|
|
||||||
|
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate);
|
||||||
|
if (periodEndDate.isAfter(qPostingPeriodEndDate)) {
|
||||||
|
periodEndDate = qPostingPeriodEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
|
||||||
|
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
|
||||||
|
|
||||||
|
compoundingPeriod = QuarterlyCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances,
|
||||||
|
upToInterestCalculationDate);
|
||||||
|
compoundingPeriods.add(compoundingPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move periodStartDate forward to day after this period
|
||||||
|
periodStartDate = periodEndDate.plusDays(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BI_ANNUAL:
|
||||||
|
final LocalDate bPostingPeriodEndDate = postingPeriodInterval.endDate();
|
||||||
|
|
||||||
|
periodStartDate = postingPeriodInterval.startDate();
|
||||||
|
periodEndDate = periodStartDate;
|
||||||
|
|
||||||
|
while (!periodStartDate.isAfter(bPostingPeriodEndDate) && !periodEndDate.isAfter(bPostingPeriodEndDate)) {
|
||||||
|
|
||||||
|
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate);
|
||||||
|
if (periodEndDate.isAfter(bPostingPeriodEndDate)) {
|
||||||
|
periodEndDate = bPostingPeriodEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
|
||||||
|
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
|
||||||
|
|
||||||
|
compoundingPeriod = BiAnnualCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances,
|
||||||
|
upToInterestCalculationDate);
|
||||||
|
compoundingPeriods.add(compoundingPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move periodStartDate forward to day after this period
|
||||||
|
periodStartDate = periodEndDate.plusDays(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ANNUAL:
|
||||||
|
final LocalDate aPostingPeriodEndDate = postingPeriodInterval.endDate();
|
||||||
|
|
||||||
|
periodStartDate = postingPeriodInterval.startDate();
|
||||||
|
periodEndDate = periodStartDate;
|
||||||
|
|
||||||
|
while (!periodStartDate.isAfter(aPostingPeriodEndDate) && !periodEndDate.isAfter(aPostingPeriodEndDate)) {
|
||||||
|
|
||||||
|
periodEndDate = determineInterestPeriodEndDateFrom(periodStartDate, interestPeriodType, upToInterestCalculationDate);
|
||||||
|
if (periodEndDate.isAfter(aPostingPeriodEndDate)) {
|
||||||
|
periodEndDate = aPostingPeriodEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocalDateInterval compoundingPeriodInterval = LocalDateInterval.create(periodStartDate, periodEndDate);
|
||||||
|
if (postingPeriodInterval.contains(compoundingPeriodInterval)) {
|
||||||
|
|
||||||
|
compoundingPeriod = AnnualCompoundingPeriod.create(compoundingPeriodInterval, allEndOfDayBalances,
|
||||||
|
upToInterestCalculationDate);
|
||||||
|
compoundingPeriods.add(compoundingPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move periodStartDate forward to day after this period
|
||||||
|
periodStartDate = periodEndDate.plusDays(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compoundingPeriods;
|
return compoundingPeriods;
|
||||||
@@ -221,39 +291,41 @@ public class PostingPeriod {
|
|||||||
// produce period end date on last day of current month
|
// produce period end date on last day of current month
|
||||||
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
|
periodEndDate = periodStartDate.dayOfMonth().withMaximumValue();
|
||||||
break;
|
break;
|
||||||
// case QUATERLY:
|
case QUATERLY:
|
||||||
// // jan 1st to mar 31st, 1st apr to jun 30, jul 1st to sept 30,
|
// // jan 1st to mar 31st, 1st apr to jun 30, jul 1st to sept
|
||||||
// // oct 1st to dec 31
|
// 30,
|
||||||
// int year = periodStartDate.getYearOfEra();
|
// // oct 1st to dec 31
|
||||||
// int monthofYear = periodStartDate.getMonthOfYear();
|
int year = periodStartDate.getYearOfEra();
|
||||||
// if (monthofYear <= 3) {
|
int monthofYear = periodStartDate.getMonthOfYear();
|
||||||
// periodEndDate = new DateTime().withDate(year, 3, 31).toLocalDate();
|
if (monthofYear <= 3) {
|
||||||
// } else if (monthofYear <= 6) {
|
periodEndDate = new DateTime().withDate(year, 3, 31).toLocalDate();
|
||||||
// periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
|
} else if (monthofYear <= 6) {
|
||||||
// } else if (monthofYear <= 9) {
|
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
|
||||||
// periodEndDate = new DateTime().withDate(year, 9, 30).toLocalDate();
|
} else if (monthofYear <= 9) {
|
||||||
// } else if (monthofYear <= 12) {
|
periodEndDate = new DateTime().withDate(year, 9, 30).toLocalDate();
|
||||||
// periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
} else if (monthofYear <= 12) {
|
||||||
// }
|
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
||||||
// break;
|
}
|
||||||
// case BI_ANNUAL:
|
break;
|
||||||
// // jan 1st to 30, jul 1st to dec 31
|
case BI_ANNUAL:
|
||||||
// year = periodStartDate.getYearOfEra();
|
// // jan 1st to 30, jul 1st to dec 31
|
||||||
// monthofYear = periodStartDate.getMonthOfYear();
|
year = periodStartDate.getYearOfEra();
|
||||||
// if (monthofYear <= 6) {
|
monthofYear = periodStartDate.getMonthOfYear();
|
||||||
// periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
|
if (monthofYear <= 6) {
|
||||||
// } else if (monthofYear <= 12) {
|
periodEndDate = new DateTime().withDate(year, 6, 30).toLocalDate();
|
||||||
// periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
} else if (monthofYear <= 12) {
|
||||||
// }
|
periodEndDate = new DateTime().withDate(year, 12, 31).toLocalDate();
|
||||||
// break;
|
}
|
||||||
// case ANNUAL:
|
break;
|
||||||
// periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
case ANNUAL:
|
||||||
// periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||||
// break;
|
periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
||||||
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
break;
|
||||||
// periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
|
||||||
// periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
// break;
|
// periodEndDate = periodStartDate.monthOfYear().withMaximumValue();
|
||||||
|
// periodEndDate = periodEndDate.dayOfMonth().withMaximumValue();
|
||||||
|
// break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return periodEndDate;
|
return periodEndDate;
|
||||||
|
|||||||
+154
@@ -0,0 +1,154 @@
|
|||||||
|
package org.mifosplatform.portfolio.savings.domain.interest;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.MathContext;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
|
||||||
|
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||||
|
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
|
||||||
|
|
||||||
|
public class QuarterlyCompoundingPeriod implements CompoundingPeriod {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private final LocalDateInterval periodInterval;
|
||||||
|
private final List<EndOfDayBalance> endOfDayBalances;
|
||||||
|
|
||||||
|
public static QuarterlyCompoundingPeriod create(final LocalDateInterval periodInterval, final List<EndOfDayBalance> allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
|
||||||
|
|
||||||
|
final List<EndOfDayBalance> endOfDayBalancesWithinPeriod = endOfDayBalancesWithinPeriodInterval(periodInterval, allEndOfDayBalances, upToInterestCalculationDate);
|
||||||
|
|
||||||
|
return new QuarterlyCompoundingPeriod(periodInterval, endOfDayBalancesWithinPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal calculateInterest(final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
final BigDecimal interestOnBalanceUnrounded = balance.calculateInterestOnBalance(BigDecimal.ZERO, interestRateAsFraction,
|
||||||
|
daysInYear);
|
||||||
|
interestEarned = interestEarned.add(interestOnBalanceUnrounded);
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal calculateInterest(final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
||||||
|
final SavingsInterestCalculationType interestCalculationType, final BigDecimal interestToCompound,
|
||||||
|
final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
switch (interestCalculationType) {
|
||||||
|
case DAILY_BALANCE:
|
||||||
|
interestEarned = calculateUsingDailyBalanceMethod(compoundingInterestPeriodType, interestToCompound,
|
||||||
|
interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case AVERAGE_DAILY_BALANCE:
|
||||||
|
interestEarned = calculateUsingAverageDailyBalanceMethod(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateUsingAverageDailyBalanceMethod(final BigDecimal interestToCompound,
|
||||||
|
final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal cumulativeBalance = BigDecimal.ZERO;
|
||||||
|
Integer numberOfDays = Integer.valueOf(0);
|
||||||
|
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
final BigDecimal endOfDayCumulativeBalance = balance.cumulativeBalance(interestToCompound);
|
||||||
|
cumulativeBalance = cumulativeBalance.add(endOfDayCumulativeBalance);
|
||||||
|
|
||||||
|
final Integer balanceExistsForNumberOfDays = balance.getNumberOfDays();
|
||||||
|
numberOfDays = numberOfDays + balanceExistsForNumberOfDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
if (cumulativeBalance.compareTo(BigDecimal.ZERO) != 0 && numberOfDays > 0) {
|
||||||
|
final BigDecimal averageDailyBalance = cumulativeBalance.divide(BigDecimal.valueOf(numberOfDays), MathContext.DECIMAL64)
|
||||||
|
.setScale(9, RoundingMode.HALF_EVEN);
|
||||||
|
|
||||||
|
final BigDecimal multiplicand = BigDecimal.ONE.divide(BigDecimal.valueOf(daysInYear), MathContext.DECIMAL64);
|
||||||
|
final BigDecimal dailyInterestRate = interestRateAsFraction.multiply(multiplicand, MathContext.DECIMAL64);
|
||||||
|
final BigDecimal periodicInterestRate = dailyInterestRate.multiply(BigDecimal.valueOf(numberOfDays), MathContext.DECIMAL64);
|
||||||
|
|
||||||
|
interestEarned = averageDailyBalance.multiply(periodicInterestRate, MathContext.DECIMAL64).setScale(9, RoundingMode.HALF_EVEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal calculateUsingDailyBalanceMethod(final SavingsCompoundingInterestPeriodType compoundingInterestPeriodType,
|
||||||
|
final BigDecimal interestToCompound, final BigDecimal interestRateAsFraction, final long daysInYear) {
|
||||||
|
|
||||||
|
BigDecimal interestEarned = BigDecimal.ZERO;
|
||||||
|
BigDecimal interestOnBalanceUnrounded = BigDecimal.ZERO;
|
||||||
|
for (final EndOfDayBalance balance : this.endOfDayBalances) {
|
||||||
|
|
||||||
|
switch (compoundingInterestPeriodType) {
|
||||||
|
case DAILY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalanceAndInterest(interestToCompound, interestRateAsFraction,
|
||||||
|
daysInYear);
|
||||||
|
break;
|
||||||
|
case MONTHLY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case QUATERLY:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
// case WEEKLY:
|
||||||
|
// break;
|
||||||
|
// case BIWEEKLY:
|
||||||
|
// break;
|
||||||
|
case BI_ANNUAL:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
case ANNUAL:
|
||||||
|
interestOnBalanceUnrounded = balance.calculateInterestOnBalance(interestToCompound, interestRateAsFraction, daysInYear);
|
||||||
|
break;
|
||||||
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
|
// break;
|
||||||
|
case INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
interestEarned = interestEarned.add(interestOnBalanceUnrounded);
|
||||||
|
}
|
||||||
|
return interestEarned;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<EndOfDayBalance> endOfDayBalancesWithinPeriodInterval(final LocalDateInterval compoundingPeriodInterval,
|
||||||
|
final List<EndOfDayBalance> allEndOfDayBalances, final LocalDate upToInterestCalculationDate) {
|
||||||
|
|
||||||
|
final List<EndOfDayBalance> endOfDayBalancesForPeriodInterval = new ArrayList<EndOfDayBalance>();
|
||||||
|
|
||||||
|
for (final EndOfDayBalance endOfDayBalance : allEndOfDayBalances) {
|
||||||
|
|
||||||
|
if (compoundingPeriodInterval.contains(endOfDayBalance.date())) {
|
||||||
|
final EndOfDayBalance cappedToPeriodEndDate = endOfDayBalance.upTo(compoundingPeriodInterval, upToInterestCalculationDate);
|
||||||
|
endOfDayBalancesForPeriodInterval.add(cappedToPeriodEndDate);
|
||||||
|
} else if (endOfDayBalance.contains(compoundingPeriodInterval)) {
|
||||||
|
final EndOfDayBalance cappedToPeriodEndDate = endOfDayBalance.upTo(compoundingPeriodInterval, upToInterestCalculationDate);
|
||||||
|
endOfDayBalancesForPeriodInterval.add(cappedToPeriodEndDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return endOfDayBalancesForPeriodInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
private QuarterlyCompoundingPeriod(final LocalDateInterval periodInterval, final List<EndOfDayBalance> endOfDayBalances) {
|
||||||
|
this.periodInterval = periodInterval;
|
||||||
|
this.endOfDayBalances = endOfDayBalances;
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-2
@@ -783,6 +783,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
|||||||
sqlBuilder.append("datp.in_multiples_of_deposit_term_type_enum as inMultiplesOfDepositTermTypeId, ");
|
sqlBuilder.append("datp.in_multiples_of_deposit_term_type_enum as inMultiplesOfDepositTermTypeId, ");
|
||||||
sqlBuilder.append("datp.deposit_amount as depositAmount, ");
|
sqlBuilder.append("datp.deposit_amount as depositAmount, ");
|
||||||
sqlBuilder.append("datp.maturity_amount as maturityAmount, ");
|
sqlBuilder.append("datp.maturity_amount as maturityAmount, ");
|
||||||
|
sqlBuilder.append("datp.expected_firstdepositon_date as expectedFirstDepositOnDate, ");
|
||||||
sqlBuilder.append("datp.maturity_date as maturityDate, ");
|
sqlBuilder.append("datp.maturity_date as maturityDate, ");
|
||||||
sqlBuilder.append("datp.deposit_period as depositPeriod, ");
|
sqlBuilder.append("datp.deposit_period as depositPeriod, ");
|
||||||
sqlBuilder.append("datp.deposit_period_frequency_enum as depositPeriodFrequencyTypeId, ");
|
sqlBuilder.append("datp.deposit_period_frequency_enum as depositPeriodFrequencyTypeId, ");
|
||||||
@@ -847,12 +848,13 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
|||||||
final Integer onAccountClosureId = JdbcSupport.getInteger(rs, "onAccountClosureId");
|
final Integer onAccountClosureId = JdbcSupport.getInteger(rs, "onAccountClosureId");
|
||||||
final EnumOptionData onAccountClosureType = (onAccountClosureId == null) ? null : SavingsEnumerations
|
final EnumOptionData onAccountClosureType = (onAccountClosureId == null) ? null : SavingsEnumerations
|
||||||
.depositAccountOnClosureType(onAccountClosureId);
|
.depositAccountOnClosureType(onAccountClosureId);
|
||||||
|
final LocalDate expectedFirstDepositOnDate = JdbcSupport.getLocalDate(rs, "expectedFirstDepositOnDate");
|
||||||
return RecurringDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
return RecurringDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
||||||
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
||||||
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
||||||
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
||||||
depositPeriodFrequencyType, recurringDepositAmount, recurringDepositType, recurringDepositFrequency,
|
depositPeriodFrequencyType, recurringDepositAmount, recurringDepositType, recurringDepositFrequency,
|
||||||
recurringDepositFrequencyType, onAccountClosureType);
|
recurringDepositFrequencyType, onAccountClosureType, expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1266,13 +1268,14 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
|||||||
final Integer depositPeriod = null;
|
final Integer depositPeriod = null;
|
||||||
final EnumOptionData depositPeriodFrequencyType = null;
|
final EnumOptionData depositPeriodFrequencyType = null;
|
||||||
final BigDecimal recurringDepositAmount = null;
|
final BigDecimal recurringDepositAmount = null;
|
||||||
|
final LocalDate expectedFirstDepositOnDate = null;
|
||||||
final EnumOptionData onAccountClosureType = null;
|
final EnumOptionData onAccountClosureType = null;
|
||||||
return RecurringDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
return RecurringDepositAccountData.instance(depositAccountData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
||||||
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
||||||
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType,
|
||||||
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
inMultiplesOfDepositTerm, inMultiplesOfDepositTermType, depositAmount, maturityAmount, maturityDate, depositPeriod,
|
||||||
depositPeriodFrequencyType, recurringDepositAmount, recurringDepositType, recurringDepositFrequency,
|
depositPeriodFrequencyType, recurringDepositAmount, recurringDepositType, recurringDepositFrequency,
|
||||||
recurringDepositFrequencyType, onAccountClosureType);
|
recurringDepositFrequencyType, onAccountClosureType, expectedFirstDepositOnDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -151,7 +151,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
|||||||
((FixedDepositAccount) account).updateMaturityDateAndAmountBeforeAccountActivation(mc);
|
((FixedDepositAccount) account).updateMaturityDateAndAmountBeforeAccountActivation(mc);
|
||||||
this.fixedDepositAccountRepository.saveAndFlush((FixedDepositAccount) account);
|
this.fixedDepositAccountRepository.saveAndFlush((FixedDepositAccount) account);
|
||||||
} else if (depositAccountType.isRecurringDeposit()) {
|
} else if (depositAccountType.isRecurringDeposit()) {
|
||||||
final LocalDate transactionStartDate = account.accountSubmittedOrActivationDate();
|
final LocalDate transactionStartDate = ((RecurringDepositAccount) account).depositStartDate();
|
||||||
((RecurringDepositAccount) account).updateMaturityDateAndAmount(mc, transactionStartDate);
|
((RecurringDepositAccount) account).updateMaturityDateAndAmount(mc, transactionStartDate);
|
||||||
this.recurringDepositAccountRepository.save((RecurringDepositAccount) account);
|
this.recurringDepositAccountRepository.save((RecurringDepositAccount) account);
|
||||||
}
|
}
|
||||||
@@ -254,7 +254,7 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
|
|||||||
if (depositAccountType.isFixedDeposit()) {
|
if (depositAccountType.isFixedDeposit()) {
|
||||||
((FixedDepositAccount) account).updateMaturityDateAndAmountBeforeAccountActivation(mc);
|
((FixedDepositAccount) account).updateMaturityDateAndAmountBeforeAccountActivation(mc);
|
||||||
} else if (depositAccountType.isRecurringDeposit()) {
|
} else if (depositAccountType.isRecurringDeposit()) {
|
||||||
final LocalDate transactionStartDate = account.accountSubmittedOrActivationDate();
|
final LocalDate transactionStartDate = ((RecurringDepositAccount) account).depositStartDate();
|
||||||
((RecurringDepositAccount) account).updateMaturityDateAndAmount(mc, transactionStartDate);
|
((RecurringDepositAccount) account).updateMaturityDateAndAmount(mc, transactionStartDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-1
@@ -275,6 +275,9 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
|
|||||||
sqlBuilder.append("dprd.recurring_deposit_type_enum as recurringDepositTypeId, ");
|
sqlBuilder.append("dprd.recurring_deposit_type_enum as recurringDepositTypeId, ");
|
||||||
sqlBuilder.append("dprd.recurring_deposit_frequency as recurringDepositFrequency, ");
|
sqlBuilder.append("dprd.recurring_deposit_frequency as recurringDepositFrequency, ");
|
||||||
sqlBuilder.append("dprd.recurring_deposit_frequency_type_enum as recurringDepositFrequencyTypeId, ");
|
sqlBuilder.append("dprd.recurring_deposit_frequency_type_enum as recurringDepositFrequencyTypeId, ");
|
||||||
|
sqlBuilder.append("dptp.min_deposit_amount as minDepositAmount, ");
|
||||||
|
sqlBuilder.append("dptp.deposit_amount as depositAmount, ");
|
||||||
|
sqlBuilder.append("dptp.max_deposit_amount as maxDepositAmount, ");
|
||||||
sqlBuilder.append("dptp.min_deposit_term as minDepositTerm, ");
|
sqlBuilder.append("dptp.min_deposit_term as minDepositTerm, ");
|
||||||
sqlBuilder.append("dptp.max_deposit_term as maxDepositTerm, ");
|
sqlBuilder.append("dptp.max_deposit_term as maxDepositTerm, ");
|
||||||
sqlBuilder.append("dptp.min_deposit_term_type_enum as minDepositTermTypeId, ");
|
sqlBuilder.append("dptp.min_deposit_term_type_enum as minDepositTermTypeId, ");
|
||||||
@@ -315,6 +318,9 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
|
|||||||
.recurringDepositType(recurringDepositTypeId);
|
.recurringDepositType(recurringDepositTypeId);
|
||||||
final Integer recurringDepositFrequency = JdbcSupport.getInteger(rs, "recurringDepositFrequency");
|
final Integer recurringDepositFrequency = JdbcSupport.getInteger(rs, "recurringDepositFrequency");
|
||||||
final Integer recurringDepositFrequencyTypeId = JdbcSupport.getInteger(rs, "recurringDepositFrequencyTypeId");
|
final Integer recurringDepositFrequencyTypeId = JdbcSupport.getInteger(rs, "recurringDepositFrequencyTypeId");
|
||||||
|
final BigDecimal minDepositAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "minDepositAmount");
|
||||||
|
final BigDecimal depositAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "depositAmount");
|
||||||
|
final BigDecimal maxDepositAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "maxDepositAmount");
|
||||||
final EnumOptionData recurringDepositFrequencyType = (recurringDepositFrequencyTypeId == null) ? null : SavingsEnumerations
|
final EnumOptionData recurringDepositFrequencyType = (recurringDepositFrequencyTypeId == null) ? null : SavingsEnumerations
|
||||||
.recurringDepositFrequencyType(recurringDepositFrequencyTypeId);
|
.recurringDepositFrequencyType(recurringDepositFrequencyTypeId);
|
||||||
|
|
||||||
@@ -334,7 +340,8 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
|
|||||||
return RecurringDepositProductData.instance(depositProductData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
return RecurringDepositProductData.instance(depositProductData, interestFreePeriodApplicable, interestFreeFromPeriod,
|
||||||
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
interestFreeToPeriod, interestFreePeriodFrequencyType, preClosurePenalApplicable, preClosurePenalInterest,
|
||||||
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
|
preClosurePenalInterestOnType, minDepositTerm, maxDepositTerm, minDepositTermType, maxDepositTermType, inMultiplesOfDepositTerm,
|
||||||
inMultiplesOfDepositTermType, recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType);
|
inMultiplesOfDepositTermType, recurringDepositType, recurringDepositFrequency, recurringDepositFrequencyType,
|
||||||
|
minDepositAmount, depositAmount, maxDepositAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-6
@@ -51,12 +51,10 @@ public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownRe
|
|||||||
// //
|
// //
|
||||||
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.BIWEEKLY),
|
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.BIWEEKLY),
|
||||||
// //
|
// //
|
||||||
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.MONTHLY)
|
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.MONTHLY),
|
||||||
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.QUATERLY),
|
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.QUATERLY),
|
||||||
// //
|
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.BI_ANNUAL),
|
||||||
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.BI_ANNUAL),
|
SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.ANNUAL)
|
||||||
// //
|
|
||||||
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.ANNUAL),
|
|
||||||
// //
|
// //
|
||||||
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST)
|
// SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST)
|
||||||
// //
|
// //
|
||||||
@@ -70,6 +68,7 @@ public class SavingsDropdownReadPlatformServiceImpl implements SavingsDropdownRe
|
|||||||
final List<EnumOptionData> allowedOptions = Arrays.asList( //
|
final List<EnumOptionData> allowedOptions = Arrays.asList( //
|
||||||
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.MONTHLY), //
|
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.MONTHLY), //
|
||||||
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.QUATERLY), //
|
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.QUATERLY), //
|
||||||
|
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.BIANNUAL), //
|
||||||
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNUAL) //
|
SavingsEnumerations.interestPostingPeriodType(SavingsPostingInterestPeriodType.ANNUAL) //
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+16
-20
@@ -232,6 +232,10 @@ public class SavingsEnumerations {
|
|||||||
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.QUATERLY.getValue().longValue(), codePrefix
|
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.QUATERLY.getValue().longValue(), codePrefix
|
||||||
+ SavingsPostingInterestPeriodType.QUATERLY.getCode(), "Quarterly");
|
+ SavingsPostingInterestPeriodType.QUATERLY.getCode(), "Quarterly");
|
||||||
break;
|
break;
|
||||||
|
case BIANNUAL:
|
||||||
|
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.BIANNUAL.getValue().longValue(), codePrefix
|
||||||
|
+ SavingsPostingInterestPeriodType.BIANNUAL.getCode(), "BiAnnual");
|
||||||
|
break;
|
||||||
case ANNUAL:
|
case ANNUAL:
|
||||||
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.ANNUAL.getValue().longValue(), codePrefix
|
optionData = new EnumOptionData(SavingsPostingInterestPeriodType.ANNUAL.getValue().longValue(), codePrefix
|
||||||
+ SavingsPostingInterestPeriodType.ANNUAL.getCode(), "Annually");
|
+ SavingsPostingInterestPeriodType.ANNUAL.getCode(), "Annually");
|
||||||
@@ -276,26 +280,18 @@ public class SavingsEnumerations {
|
|||||||
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.MONTHLY.getValue().longValue(), codePrefix
|
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.MONTHLY.getValue().longValue(), codePrefix
|
||||||
+ SavingsCompoundingInterestPeriodType.MONTHLY.getCode(), "Monthly");
|
+ SavingsCompoundingInterestPeriodType.MONTHLY.getCode(), "Monthly");
|
||||||
break;
|
break;
|
||||||
// case QUATERLY:
|
case QUATERLY:
|
||||||
// optionData = new
|
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.QUATERLY.getValue().longValue(), codePrefix
|
||||||
// EnumOptionData(SavingsCompoundingInterestPeriodType.QUATERLY.getValue().longValue(),
|
+ SavingsCompoundingInterestPeriodType.QUATERLY.getCode(), "Quarterly");
|
||||||
// codePrefix
|
break;
|
||||||
// + SavingsCompoundingInterestPeriodType.QUATERLY.getCode(),
|
case BI_ANNUAL:
|
||||||
// "Quarterly");
|
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.BI_ANNUAL.getValue().longValue(), codePrefix
|
||||||
// break;
|
+ SavingsCompoundingInterestPeriodType.BI_ANNUAL.getCode(), "Semi-Annual");
|
||||||
// case BI_ANNUAL:
|
break;
|
||||||
// optionData = new
|
case ANNUAL:
|
||||||
// EnumOptionData(SavingsCompoundingInterestPeriodType.BI_ANNUAL.getValue().longValue(),
|
optionData = new EnumOptionData(SavingsCompoundingInterestPeriodType.ANNUAL.getValue().longValue(), codePrefix
|
||||||
// codePrefix
|
+ SavingsCompoundingInterestPeriodType.ANNUAL.getCode(), "Annually");
|
||||||
// + SavingsCompoundingInterestPeriodType.BI_ANNUAL.getCode(),
|
break;
|
||||||
// "Semi-Annual");
|
|
||||||
// break;
|
|
||||||
// case ANNUAL:
|
|
||||||
// optionData = new
|
|
||||||
// EnumOptionData(SavingsCompoundingInterestPeriodType.ANNUAL.getValue().longValue(),
|
|
||||||
// codePrefix
|
|
||||||
// + SavingsCompoundingInterestPeriodType.ANNUAL.getCode(), "Annually");
|
|
||||||
// break;
|
|
||||||
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
// case NO_COMPOUNDING_SIMPLE_INTEREST:
|
||||||
// optionData = new
|
// optionData = new
|
||||||
// EnumOptionData(SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST.getValue().longValue(),
|
// EnumOptionData(SavingsCompoundingInterestPeriodType.NO_COMPOUNDING_SIMPLE_INTEREST.getValue().longValue(),
|
||||||
|
|||||||
Reference in New Issue
Block a user