squash madhukars pull request into one commit.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
ALTER TABLE `m_product_deposit`
|
||||
ADD COLUMN `is_lock_in_period_allowed` tinyint(1) NOT NULL DEFAULT '0' AFTER `pre_closure_interest_rate`,
|
||||
ADD COLUMN `lock_in_period` bigint(20) DEFAULT NULL AFTER `is_lock_in_period_allowed`,
|
||||
ADD COLUMN `lock_in_period_type` smallint(5) NOT NULL DEFAULT '2' AFTER `lock_in_period`;
|
||||
|
||||
ALTER TABLE `m_deposit_account`
|
||||
ADD COLUMN `is_lock_in_period_allowed` tinyint(1) NOT NULL DEFAULT '0' AFTER `pre_closure_interest_rate`,
|
||||
ADD COLUMN `lock_in_period` bigint(20) DEFAULT NULL AFTER `is_lock_in_period_allowed`,
|
||||
ADD COLUMN `lock_in_period_type` smallint(5) NOT NULL DEFAULT '2' AFTER `lock_in_period`;
|
||||
+2
-1
@@ -73,7 +73,8 @@ public class DepositAccountsApiResource {
|
||||
"interestCompoundedEveryPeriodType", "renewalAllowed",
|
||||
"preClosureAllowed", "preClosureInterestRate",
|
||||
"withdrawnonDate","rejectedonDate","closedonDate","transactions","interestPaid","isInterestWithdrawable",
|
||||
"availableInterestForWithdrawal","availableWithdrawalAmount"));
|
||||
"availableInterestForWithdrawal","availableWithdrawalAmount","todaysDate",
|
||||
"isLockinPeriodAllowed","lockinPeriod","lockinPeriodType"));
|
||||
|
||||
|
||||
@POST
|
||||
|
||||
+6
-3
@@ -100,7 +100,8 @@ public class DepositProductsApiResource {
|
||||
"currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance","tenureInMonths",
|
||||
"maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate",
|
||||
"interestCompoundedEvery", "interestCompoundedEveryPeriodType",
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed"));
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed",
|
||||
"isLockinPeriodAllowed","lockinPeriod","lockinPeriodType"));
|
||||
|
||||
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (responseParameters.isEmpty()) {
|
||||
@@ -123,7 +124,8 @@ public class DepositProductsApiResource {
|
||||
"currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance","tenureInMonths",
|
||||
"maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate",
|
||||
"interestCompoundedEvery", "interestCompoundedEveryPeriodType",
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed"));
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed",
|
||||
"isLockinPeriodAllowed","lockinPeriod","lockinPeriodType"));
|
||||
|
||||
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (responseParameters.isEmpty()) {
|
||||
@@ -153,7 +155,8 @@ public class DepositProductsApiResource {
|
||||
"currencyCode","digitsAfterDecimal","minimumBalance","maximumBalance","tenureInMonths",
|
||||
"maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate",
|
||||
"interestCompoundedEvery", "interestCompoundedEveryPeriodType",
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate"));
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate",
|
||||
"isLockinPeriodAllowed","lockinPeriod","lockinPeriodType"));
|
||||
|
||||
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
|
||||
if (responseParameters.isEmpty()) {
|
||||
|
||||
+26
-1
@@ -20,6 +20,10 @@ public class DepositAccountCommand {
|
||||
private final BigDecimal preClosureInterestRate;
|
||||
private final Integer tenureInMonths;
|
||||
|
||||
private final boolean isLockinPeriodAllowed;
|
||||
private final Integer lockinPeriod;
|
||||
private final Integer lockinPeriodType;
|
||||
|
||||
private final Integer interestCompoundedEvery;
|
||||
private final Integer interestCompoundedEveryPeriodType;
|
||||
private final LocalDate commencementDate;
|
||||
@@ -39,7 +43,8 @@ public class DepositAccountCommand {
|
||||
final BigDecimal depositAmount,
|
||||
final BigDecimal interestRate, final BigDecimal preClosureInterestRate,
|
||||
final Integer tenureInMonths, final Integer compoundingInterestFrequency, final Integer compoundingInterestFrequencyType, final LocalDate commencementDate,
|
||||
final boolean renewalAllowed, final boolean preClosureAllowed,final boolean isInterstWithdrawable, final boolean interestCompoundingAllowed) {
|
||||
final boolean renewalAllowed, final boolean preClosureAllowed,final boolean isInterstWithdrawable, final boolean interestCompoundingAllowed,
|
||||
final boolean isLockinPeriodAllowed, final Integer lockInPeriod, final Integer lockinPeriodType) {
|
||||
this.id = id;
|
||||
this.clientId = clientId;
|
||||
this.productId = productId;
|
||||
@@ -58,6 +63,10 @@ public class DepositAccountCommand {
|
||||
this.preClosureAllowed = preClosureAllowed;
|
||||
this.isInterestWithdrawable = isInterstWithdrawable;
|
||||
this.interestCompoundingAllowed = interestCompoundingAllowed;
|
||||
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockInPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
@@ -120,6 +129,18 @@ public class DepositAccountCommand {
|
||||
return interestCompoundingAllowed;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
public boolean isNoFieldChanged() {
|
||||
return this.modifiedParameters.isEmpty();
|
||||
}
|
||||
@@ -136,6 +157,10 @@ public class DepositAccountCommand {
|
||||
return this.modifiedParameters.contains("tenureInMonths");
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodChanged() {
|
||||
return this.modifiedParameters.contains("lockinPeriod");
|
||||
}
|
||||
|
||||
public boolean isMaturityActualInterestRateChanged() {
|
||||
return this.modifiedParameters.contains("maturityInterestRate");
|
||||
}
|
||||
|
||||
+34
-1
@@ -22,6 +22,9 @@ public class DepositProductCommand {
|
||||
private final BigDecimal maturityMaxInterestRate;
|
||||
private final Integer interestCompoundedEvery;
|
||||
private final Integer interestCompoundedEveryPeriodType;
|
||||
private final boolean isLockinPeriodAllowed;
|
||||
private final Integer lockinPeriod;
|
||||
private final Integer lockinPeriodType;
|
||||
|
||||
private final boolean renewalAllowed;
|
||||
private final boolean preClosureAllowed;
|
||||
@@ -40,7 +43,8 @@ public class DepositProductCommand {
|
||||
final Integer interestCompoundedEvery,
|
||||
final Integer interestCompoundedEveryPeriodType,
|
||||
final boolean renewalAllowed, final boolean preClosureAllowed,
|
||||
final BigDecimal preClosureInterestRate, final boolean interestCompoundingAllowed ) {
|
||||
final BigDecimal preClosureInterestRate, final boolean interestCompoundingAllowed,
|
||||
final boolean isLockinPeriodAllowed,final Integer lockinPeriod,final Integer lockinPeriodType ) {
|
||||
this.id = id;
|
||||
this.externalId = externalId;
|
||||
this.name = name;
|
||||
@@ -63,6 +67,11 @@ public class DepositProductCommand {
|
||||
this.renewalAllowed = renewalAllowed;
|
||||
this.preClosureAllowed = preClosureAllowed;
|
||||
this.interestCompoundingAllowed = interestCompoundingAllowed;
|
||||
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
|
||||
this.modifiedParameters = modifiedParameters;
|
||||
|
||||
}
|
||||
@@ -139,6 +148,18 @@ public class DepositProductCommand {
|
||||
return interestCompoundingAllowed;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
public boolean isExternalIdChanged() {
|
||||
return this.modifiedParameters.contains("externalId");
|
||||
}
|
||||
@@ -214,4 +235,16 @@ public class DepositProductCommand {
|
||||
public boolean interestCompoundingAllowedChanged(){
|
||||
return this.modifiedParameters.contains("interestCompoundingAllowed");
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowedChanged() {
|
||||
return this.modifiedParameters.contains("isLockinPeriodAllowed");
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodChanged() {
|
||||
return this.modifiedParameters.contains("lockinPeriod");
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodTypeChanged() {
|
||||
return this.modifiedParameters.contains("lockinPeriodType");
|
||||
}
|
||||
}
|
||||
+72
-16
@@ -7,6 +7,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
|
||||
@@ -56,6 +57,11 @@ public class DepositAccountData {
|
||||
private final DepositPermissionData permissions;
|
||||
private final BigDecimal availableInterestForWithdrawal;
|
||||
private final BigDecimal availableWithdrawalAmount;
|
||||
private final LocalDate todaysDate;
|
||||
|
||||
private final boolean isLockinPeriodAllowed;
|
||||
private final Integer lockinPeriod;
|
||||
private final EnumOptionData lockinPeriodType;
|
||||
|
||||
/*
|
||||
* used when returning account template data but only a clientId is passed, no selected product.
|
||||
@@ -106,6 +112,11 @@ public class DepositAccountData {
|
||||
this.interestCompoundingAllowed = true;
|
||||
this.availableInterestForWithdrawal = new BigDecimal(0);
|
||||
this.availableWithdrawalAmount= new BigDecimal(0);
|
||||
this.todaysDate = new LocalDate();
|
||||
|
||||
this.isLockinPeriodAllowed =true;
|
||||
this.lockinPeriod = null;
|
||||
this.lockinPeriodType = null;
|
||||
}
|
||||
|
||||
public DepositAccountData(
|
||||
@@ -150,6 +161,11 @@ public class DepositAccountData {
|
||||
this.interestCompoundingAllowed=account.isInterestCompoundingAllowed();
|
||||
this.availableInterestForWithdrawal=determineAvailableInterestForWithdrawal(account);
|
||||
this.availableWithdrawalAmount=determineAvalableWithdrawalAmount(account);
|
||||
this.todaysDate = new LocalDate();
|
||||
|
||||
this.lockinPeriod = account.getLockinPeriod();
|
||||
this.lockinPeriodType = account.getLockinPeriodType();
|
||||
this.isLockinPeriodAllowed = account.isLockinPeriodAllowed();
|
||||
}
|
||||
|
||||
public DepositAccountData(final DepositAccountData account, final DepositPermissionData permissions, final Collection<DepositAccountTransactionData> transactions) {
|
||||
@@ -191,6 +207,11 @@ public class DepositAccountData {
|
||||
this.interestCompoundingAllowed = account.isInterestCompoundingAllowed();
|
||||
this.availableInterestForWithdrawal=determineAvailableInterestForWithdrawal(account);
|
||||
this.availableWithdrawalAmount=determineAvalableWithdrawalAmount(account);
|
||||
this.todaysDate = new LocalDate();
|
||||
|
||||
this.lockinPeriod = account.getLockinPeriod();
|
||||
this.lockinPeriodType = account.getLockinPeriodType();
|
||||
this.isLockinPeriodAllowed = account.isLockinPeriodAllowed();
|
||||
}
|
||||
|
||||
public DepositAccountData(
|
||||
@@ -221,7 +242,10 @@ public class DepositAccountData {
|
||||
final LocalDate closedonDate,
|
||||
final boolean isInterestWithdrawable,
|
||||
final BigDecimal interestPaid,
|
||||
final boolean interestCompoundingAllowed) {
|
||||
final boolean interestCompoundingAllowed,
|
||||
final boolean isLockinPeriodAllowed,
|
||||
final Integer lockinPeriod,
|
||||
final EnumOptionData lockinPeriodType) {
|
||||
this.id=id;
|
||||
this.externalId = externalId;
|
||||
this.status = status;
|
||||
@@ -261,6 +285,11 @@ public class DepositAccountData {
|
||||
this.interestCompoundingAllowed = interestCompoundingAllowed;
|
||||
this.availableInterestForWithdrawal = BigDecimal.ZERO;
|
||||
this.availableWithdrawalAmount = BigDecimal.ZERO;
|
||||
this.todaysDate = new LocalDate();
|
||||
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod =lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
}
|
||||
|
||||
public DepositAccountData(
|
||||
@@ -315,6 +344,12 @@ public class DepositAccountData {
|
||||
this.interestCompoundingAllowed=interestCompoundingAllowed;
|
||||
this.availableInterestForWithdrawal= BigDecimal.ZERO;
|
||||
this.availableWithdrawalAmount = BigDecimal.ZERO;
|
||||
this.todaysDate = new LocalDate();
|
||||
|
||||
//need to update in constructor's call method and update it
|
||||
this.lockinPeriod = Integer.valueOf(0);
|
||||
this.isLockinPeriodAllowed =true;
|
||||
this.lockinPeriodType = interestCompoundedEveryPeriodType;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
@@ -457,26 +492,35 @@ public class DepositAccountData {
|
||||
return availableWithdrawalAmount;
|
||||
}
|
||||
|
||||
public LocalDate getTodaysDate() {
|
||||
return todaysDate;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public EnumOptionData getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
private BigDecimal determineAvailableInterestForWithdrawal(final DepositAccountData account) {
|
||||
BigDecimal availableInterestForWithdrawal = BigDecimal.ZERO;
|
||||
|
||||
if(this.status!=null){
|
||||
if (account.getStatus().getId() == 300) {
|
||||
BigDecimal interestGettingForPeriod = BigDecimal.valueOf(account
|
||||
.getActualInterestAccrued().doubleValue()
|
||||
/ new Double(account.getTenureInMonths()));
|
||||
Integer noOfMonthsforInterestCal = Months.monthsBetween(
|
||||
account.getActualCommencementDate(), new LocalDate())
|
||||
.getMonths();
|
||||
Integer noOfPeriods = noOfMonthsforInterestCal
|
||||
/ account.getInterestCompoundedEvery();
|
||||
BigDecimal interestGettingForPeriod = BigDecimal.valueOf(account.getActualInterestAccrued().doubleValue()/ new Double(account.getTenureInMonths()));
|
||||
LocalDate interestWithdrawingDate= new LocalDate().isAfter(getMaturedOn())?getMaturedOn().plusDays(1):new LocalDate();
|
||||
Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), interestWithdrawingDate).getMonths();
|
||||
Integer noOfPeriods = noOfMonthsforInterestCal/ account.getInterestCompoundedEvery();
|
||||
|
||||
availableInterestForWithdrawal = BigDecimal
|
||||
.valueOf(interestGettingForPeriod.multiply(
|
||||
new BigDecimal(noOfPeriods)).doubleValue()
|
||||
- account.getInterestPaid().doubleValue());
|
||||
availableInterestForWithdrawal = BigDecimal.valueOf(interestGettingForPeriod.multiply(new BigDecimal(noOfPeriods)).doubleValue()- account.getInterestPaid().doubleValue());
|
||||
}else {
|
||||
return new BigDecimal(0);
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}else return BigDecimal.ZERO;
|
||||
|
||||
@@ -494,10 +538,12 @@ public class DepositAccountData {
|
||||
BigDecimal interestRateAsFraction = account.getPreClosureInterestRate().divide(BigDecimal.valueOf(100), mc);
|
||||
BigDecimal interestRateForOneMonth = interestRateAsFraction.divide(BigDecimal.valueOf(monthsInYear.doubleValue()), mc);
|
||||
Integer noOfMonthsforInterestCal = Months.monthsBetween(account.getActualCommencementDate(), new LocalDate()).getMonths();
|
||||
Integer days = Days.daysBetween(account.getActualCommencementDate().plusMonths(noOfMonthsforInterestCal), new LocalDate()).getDays();
|
||||
BigDecimal interest = BigDecimal.valueOf(account.getDeposit().doubleValue()*new Double(noOfMonthsforInterestCal)*interestRateForOneMonth.doubleValue());
|
||||
avalablePreclosureWithdrawalAmount = interest.add(account.getDeposit()).subtract(account.getInterestPaid());
|
||||
avalablePreclosureWithdrawalAmount = interest.add(account.getDeposit()).subtract(account.getInterestPaid()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days));
|
||||
}else if(new LocalDate().isAfter(account.getMaturedOn()) || new LocalDate().isEqual(account.getMaturedOn())){
|
||||
avalablePreclosureWithdrawalAmount=determineAvailableInterestForWithdrawal(account).add(account.getDeposit());
|
||||
Integer days = Days.daysBetween(account.getMaturedOn(), new LocalDate()).getDays();
|
||||
avalablePreclosureWithdrawalAmount=determineAvailableInterestForWithdrawal(account).add(account.getDeposit()).add(determineRemainInerestAmount(account.getDeposit(), account.getPreClosureInterestRate(), days));
|
||||
}
|
||||
}else{
|
||||
avalablePreclosureWithdrawalAmount=account.getDeposit();
|
||||
@@ -505,5 +551,15 @@ public class DepositAccountData {
|
||||
}
|
||||
return avalablePreclosureWithdrawalAmount;
|
||||
}
|
||||
|
||||
private BigDecimal determineRemainInerestAmount(final BigDecimal depsoitAmount, final BigDecimal interstRateApplicable, final Integer days){
|
||||
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
Integer daysInYear = 365;
|
||||
BigDecimal interestRateAsFraction = interstRateApplicable.divide(BigDecimal.valueOf(100), mc);
|
||||
BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc);
|
||||
return BigDecimal.valueOf(depsoitAmount.doubleValue()*days.doubleValue()*interestRateForOneDay.doubleValue());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+33
-1
@@ -31,6 +31,10 @@ public class DepositProductData {
|
||||
private final BigDecimal preClosureInterestRate;
|
||||
private final boolean interestCompoundingAllowed;
|
||||
|
||||
private final boolean isLockinPeriodAllowed;
|
||||
private final Integer lockinPeriod;
|
||||
private final EnumOptionData lockinPeriodType;
|
||||
|
||||
private final DateTime createdOn;
|
||||
private final DateTime lastModifedOn;
|
||||
|
||||
@@ -57,7 +61,10 @@ public class DepositProductData {
|
||||
final boolean renewalAllowed,
|
||||
final boolean preClosureAllowed,
|
||||
final BigDecimal preClosureInterestRate,
|
||||
final boolean interestCompoundingAllowed) {
|
||||
final boolean interestCompoundingAllowed,
|
||||
final boolean isLockinPeriodAllowed,
|
||||
final Integer lockinPeriod,
|
||||
final EnumOptionData lockinPeriodType) {
|
||||
|
||||
this.createdOn=createdOn;
|
||||
this.lastModifedOn=lastModifedOn;
|
||||
@@ -81,6 +88,10 @@ public class DepositProductData {
|
||||
this.preClosureInterestRate=preClosureInterestRate;
|
||||
this.interestCompoundingAllowed=interestCompoundingAllowed;
|
||||
|
||||
this.lockinPeriod=lockinPeriod;
|
||||
this.lockinPeriodType=lockinPeriodType;
|
||||
this.isLockinPeriodAllowed=isLockinPeriodAllowed;
|
||||
|
||||
this.currencyOptions = new ArrayList<CurrencyData>();
|
||||
this.interestCompoundedEveryPeriodTypeOptions = new ArrayList<EnumOptionData>();
|
||||
}
|
||||
@@ -112,6 +123,10 @@ public class DepositProductData {
|
||||
this.preClosureInterestRate=BigDecimal.ZERO;
|
||||
this.interestCompoundingAllowed=true;
|
||||
|
||||
this.isLockinPeriodAllowed=true;
|
||||
this.lockinPeriod=Integer.valueOf(0);
|
||||
this.lockinPeriodType=defaultInterestCompoundedEveryPeriodType;
|
||||
|
||||
this.currencyOptions = currencyOptions;
|
||||
this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions;
|
||||
}
|
||||
@@ -143,6 +158,10 @@ public class DepositProductData {
|
||||
this.preClosureInterestRate=product.getPreClosureInterestRate();
|
||||
this.interestCompoundingAllowed=product.isInterestCompoundingAllowed();
|
||||
|
||||
this.lockinPeriod=product.getLockinPeriod();
|
||||
this.lockinPeriodType=product.getLockinPeriodType();
|
||||
this.isLockinPeriodAllowed=product.isLockinPeriodAllowed();
|
||||
|
||||
this.currencyOptions = currencyOptions;
|
||||
this.interestCompoundedEveryPeriodTypeOptions = interestCompoundedEveryPeriodTypeOptions;
|
||||
}
|
||||
@@ -234,4 +253,17 @@ public class DepositProductData {
|
||||
public boolean isInterestCompoundingAllowed() {
|
||||
return interestCompoundingAllowed;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public EnumOptionData getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
}
|
||||
+16
-5
@@ -1262,7 +1262,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
||||
Arrays.asList("clientId", "productId", "externalId", "deposit", "maturityInterestRate", "preClosureInterestRate",
|
||||
"tenureInMonths", "interestCompoundedEvery", "interestCompoundedEveryPeriodType", "commencementDate",
|
||||
"renewalAllowed", "preClosureAllowed","interestCompoundingAllowed",
|
||||
"locale", "dateFormat","isInterestWithdrawable")
|
||||
"locale", "dateFormat","isInterestWithdrawable","isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")
|
||||
);
|
||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||
Set<String> modifiedParameters = new HashSet<String>();
|
||||
@@ -1275,6 +1275,10 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
||||
BigDecimal preClosureInterestRate = extractBigDecimalParameter("preClosureInterestRate", requestMap, modifiedParameters);
|
||||
Integer tenureInMonths = extractIntegerParameter("tenureInMonths", requestMap, modifiedParameters);
|
||||
|
||||
boolean isLockinPeriodAllowed = extractBooleanParameter("isLockinPeriodAllowed", requestMap, modifiedParameters);
|
||||
Integer lockinPeriod = extractIntegerParameter("lockinPeriod", requestMap, modifiedParameters);
|
||||
Integer lockinPeriodType = extractIntegerParameter("lockinPeriodType", requestMap, modifiedParameters);
|
||||
|
||||
Integer interestCompoundedEvery = extractIntegerParameter("interestCompoundedEvery", requestMap, modifiedParameters);
|
||||
Integer interestCompoundedEveryPeriodType = extractIntegerParameter("interestCompoundedEveryPeriodType", requestMap, modifiedParameters);
|
||||
LocalDate commencementDate = extractLocalDateParameter("commencementDate", requestMap, modifiedParameters);
|
||||
@@ -1285,9 +1289,10 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
||||
boolean interestCompoundingAllowed = extractBooleanParameter("interestCompoundingAllowed", requestMap, modifiedParameters);
|
||||
|
||||
return new DepositAccountCommand(modifiedParameters, resourceIdentifier, clientId, productId,
|
||||
externalId, deposit, interestRate, preClosureInterestRate, tenureInMonths,
|
||||
externalId, deposit, interestRate, preClosureInterestRate, tenureInMonths,
|
||||
interestCompoundedEvery, interestCompoundedEveryPeriodType, commencementDate, renewalAllowed,
|
||||
preClosureAllowed, isInterestWithdrawable, interestCompoundingAllowed);
|
||||
preClosureAllowed, isInterestWithdrawable, interestCompoundingAllowed,
|
||||
isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1304,7 +1309,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
||||
Arrays.asList("locale", "name", "externalId", "description","currencyCode", "digitsAfterDecimal","minimumBalance","maximumBalance","tenureInMonths",
|
||||
"maturityDefaultInterestRate","maturityMinInterestRate","maturityMaxInterestRate",
|
||||
"interestCompoundedEvery", "interestCompoundedEveryPeriodType",
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed")
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate","interestCompoundingAllowed","isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")
|
||||
);
|
||||
checkForUnsupportedParameters(requestMap, supportedParams);
|
||||
Set<String> modifiedParameters = new HashSet<String>();
|
||||
@@ -1330,12 +1335,18 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
|
||||
boolean canRenew = extractBooleanParameter("renewalAllowed", requestMap, modifiedParameters);
|
||||
boolean canPreClose = extractBooleanParameter("preClosureAllowed", requestMap, modifiedParameters);
|
||||
BigDecimal preClosureInterestRate = extractBigDecimalParameter("preClosureInterestRate", requestMap, modifiedParameters);
|
||||
|
||||
boolean isLockinPeriodAllowed = extractBooleanParameter("isLockinPeriodAllowed", requestMap, modifiedParameters);
|
||||
Integer lockinPeriod = extractIntegerParameter("lockinPeriod", requestMap, modifiedParameters);
|
||||
Integer lockinPeriodType = extractIntegerParameter("lockinPeriodType", requestMap, modifiedParameters);
|
||||
|
||||
|
||||
|
||||
return new DepositProductCommand(modifiedParameters, resourceIdentifier, externalId,
|
||||
name, description, currencyCode, digitsAfterDecimalValue, minimumBalance,maximumBalance,
|
||||
tenureMonths, maturityDefaultInterestRate, maturityMinInterestRate, maturityMaxInterestRate,
|
||||
interestCompoundedEvery, interestCompoundedEveryPeriodType,
|
||||
canRenew, canPreClose, preClosureInterestRate, interestCompoundingAllowed);
|
||||
canRenew, canPreClose, preClosureInterestRate, interestCompoundingAllowed,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-2
@@ -103,7 +103,8 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
|
||||
"maturityDefaultInterestRate", "maturityMinInterestRate",
|
||||
"maturityMaxInterestRate", "interestCompoundedEvery",
|
||||
"interestCompoundedEveryPeriodType", "renewalAllowed",
|
||||
"preClosureAllowed", "preClosureInterestRate", "interestCompoundingAllowed"));
|
||||
"preClosureAllowed", "preClosureInterestRate", "interestCompoundingAllowed",
|
||||
"isLockinPeriodAllowed","lockinPeriod","lockinPeriodType"));
|
||||
|
||||
private static final Set<String> SAVINGS_DEPOSIT_ACCOUNT_DATA_PARAMETERS = new HashSet<String>(
|
||||
Arrays.asList("productOptions", "interestCompoundedEveryPeriodTypeOptions",
|
||||
@@ -113,7 +114,8 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
|
||||
"renewalAllowed","preClosureAllowed","preClosureInterestRate",
|
||||
"withdrawnonDate","rejectedonDate","closedonDate","transactions",
|
||||
"permissions","isInterestWithdrawable","interestPaid","interestCompoundingAllowed",
|
||||
"availableInterestForWithdrawal","availableWithdrawalAmount")
|
||||
"availableInterestForWithdrawal","availableWithdrawalAmount","todaysDate",
|
||||
"isLockinPeriodAllowed","lockinPeriod","lockinPeriodType")
|
||||
);
|
||||
|
||||
private static final Set<String> CLIENT_DATA_PARAMETERS = new HashSet<String>(
|
||||
|
||||
+2
-2
@@ -3,8 +3,8 @@ package org.mifosng.platform.exceptions;
|
||||
|
||||
public class DepositAccountTransactionsException extends AbstractPlatformDomainRuleException {
|
||||
|
||||
public DepositAccountTransactionsException(String remainInterestForWithdrawal) {
|
||||
super("deposit.transaction.interest.withdrawal.exception", "You can Withdraw "+remainInterestForWithdrawal+" only", remainInterestForWithdrawal);
|
||||
public DepositAccountTransactionsException(String errorcode, String remainInterestForWithdrawal) {
|
||||
super(errorcode, "You can Withdraw "+remainInterestForWithdrawal+" only", remainInterestForWithdrawal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+65
-22
@@ -22,6 +22,7 @@ import javax.persistence.UniqueConstraint;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.hibernate.annotations.LazyCollection;
|
||||
import org.hibernate.annotations.LazyCollectionOption;
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Months;
|
||||
import org.mifosng.platform.api.commands.DepositStateTransitionApprovalCommand;
|
||||
@@ -106,17 +107,14 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
@Column(name = "status_enum", nullable = false)
|
||||
private Integer depositStatus;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "closedon_date")
|
||||
private Date closedOnDate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "rejectedon_date")
|
||||
private Date rejectedOnDate;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Temporal(TemporalType.DATE)
|
||||
@Column(name = "withdrawnon_date")
|
||||
private Date withdrawnOnDate;
|
||||
@@ -137,10 +135,19 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "depositAccount", orphanRemoval = true)
|
||||
private final List<DepositAccountTransaction> depositaccountTransactions = new ArrayList<DepositAccountTransaction>();
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@OneToOne(optional=true, cascade={CascadeType.PERSIST})
|
||||
@JoinColumn(name = "renewed_account_id")
|
||||
private DepositAccount renewdAccount;
|
||||
|
||||
@Column(name = "is_lock_in_period_allowed", nullable=false)
|
||||
private boolean isLockinPeriodAllowed = false;
|
||||
|
||||
@Column(name = "lock_in_period", nullable=false)
|
||||
private Integer lockinPeriod;
|
||||
|
||||
@Column(name = "lock_in_period_type", nullable=false)
|
||||
private PeriodFrequencyType lockinPeriodType;
|
||||
|
||||
|
||||
public DepositAccount openNew(
|
||||
final Client client, final DepositProduct product,
|
||||
@@ -152,7 +159,8 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final boolean preClosureAllowed,
|
||||
final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,
|
||||
final DepositLifecycleStateMachine depositLifecycleStateMachine,
|
||||
final boolean isInterstWithdrawable,final boolean interestCompoundingAllowed) {
|
||||
final boolean isInterstWithdrawable,final boolean interestCompoundingAllowed,
|
||||
final boolean isLockinPeriodAllowed, final Integer lockinPeriod, final PeriodFrequencyType lockinPeriodType) {
|
||||
|
||||
Money futureValueOnMaturity =null;
|
||||
|
||||
@@ -179,7 +187,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
return new DepositAccount(client, product, externalId, deposit, maturityInterestRate, preClosureInterestRate, tenureInMonths,
|
||||
interestCompoundedEvery, interestCompoundedFrequencyPeriodType, commencementDate, renewalAllowed, preClosureAllowed,
|
||||
futureValueOnMaturity,depositStatus,isInterstWithdrawable, interestCompoundingAllowed);
|
||||
futureValueOnMaturity,depositStatus,isInterstWithdrawable, interestCompoundingAllowed,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
|
||||
}
|
||||
|
||||
public DepositAccount() {
|
||||
@@ -197,7 +205,10 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final Money futureValueOnMaturity,
|
||||
final Integer depositStatus,
|
||||
final boolean isInterestWithdrawable,
|
||||
final boolean interestCompoundingAllowed) {
|
||||
final boolean interestCompoundingAllowed,
|
||||
final boolean isLockinPeriodAllowed,
|
||||
final Integer lockinPeriod,
|
||||
final PeriodFrequencyType lockinPeriodType) {
|
||||
this.client = client;
|
||||
this.product = product;
|
||||
setExternalId(externalId);
|
||||
@@ -213,7 +224,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.interestCompoundedFrequencyType = interestCompoundedFrequencyPeriodType.getValue();
|
||||
if (commencementDate != null) {
|
||||
this.projectedCommencementDate = commencementDate.toDate();
|
||||
this.maturesOnDate = commencementDate.plusMonths(this.tenureInMonths).toDate();
|
||||
this.maturesOnDate = commencementDate.plusMonths(this.tenureInMonths).minusDays(1).toDate();
|
||||
}
|
||||
|
||||
this.renewalAllowed = renewalAllowed;
|
||||
@@ -222,12 +233,15 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.preClosureInterestRate = preClosureInterestRate;
|
||||
this.isInterestWithdrawable = isInterestWithdrawable;
|
||||
this.interestCompoundingAllowed = interestCompoundingAllowed;
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
|
||||
// derived fields
|
||||
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount();
|
||||
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
||||
this.depositStatus=depositStatus;
|
||||
this.interstPaid = new BigDecimal(0);
|
||||
this.interstPaid = BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
private void setExternalId(final String externalId) {
|
||||
@@ -275,12 +289,14 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
}
|
||||
this.product.validateDepositInRange(this.depositAmount);
|
||||
|
||||
this.interestCompoundedEvery = command.getInterestCompoundedEvery();
|
||||
|
||||
if (command.getInterestCompoundedEveryPeriodType() != null) {
|
||||
this.interestCompoundedFrequencyType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType()).getValue();
|
||||
}
|
||||
|
||||
this.actualCommencementDate = actualCommencementDate.toDate();
|
||||
this.maturesOnDate = getActualCommencementDate().plusMonths(this.tenureInMonths).toDate();
|
||||
this.maturesOnDate = getActualCommencementDate().plusMonths(this.tenureInMonths).minusDays(1).toDate();
|
||||
|
||||
Money futureValueOnMaturity =null;
|
||||
|
||||
@@ -354,6 +370,18 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
public boolean isInterestCompoundingAllowed() {
|
||||
return interestCompoundingAllowed;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public PeriodFrequencyType getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
public void reject(final LocalDate rejectedOn,
|
||||
final DepositLifecycleStateMachine depositLifecycleStateMachine) {
|
||||
@@ -425,7 +453,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.actualCommencementDate = null;
|
||||
this.projectedInterestAccruedOnMaturity=this.interestAccrued;
|
||||
this.projectedTotalOnMaturity = this.depositAmount.add(this.projectedInterestAccruedOnMaturity);
|
||||
this.maturesOnDate = getProjectedCommencementDate().plusMonths(this.tenureInMonths).toDate();
|
||||
this.maturesOnDate = getProjectedCommencementDate().plusMonths(this.tenureInMonths).minusDays(1).toDate();
|
||||
this.total=null;
|
||||
this.interestAccrued=null;
|
||||
this.depositaccountTransactions.clear();
|
||||
@@ -509,18 +537,22 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
|
||||
}
|
||||
|
||||
public void withdrawDepositAccountMoney(DepositLifecycleStateMachine depositLifecycleStateMachine) {
|
||||
public void withdrawDepositAccountMoney(DepositLifecycleStateMachine depositLifecycleStateMachine, FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,LocalDate eventDate) {
|
||||
|
||||
if (new LocalDate().isAfter(maturesOnDate()) || new LocalDate().equals(maturesOnDate())) {
|
||||
if (eventDate.isAfter(maturesOnDate()) || eventDate.equals(maturesOnDate())) {
|
||||
|
||||
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_CLOSED, DepositAccountStatus.fromInt(this.depositStatus));
|
||||
this.depositStatus = statusEnum.getValue();
|
||||
|
||||
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), new LocalDate(),getAccuredInterest());
|
||||
Integer days = Days.daysBetween(maturesOnDate(), eventDate).getDays();
|
||||
Money accuredInterestAfterMaturityToTillDate = fixedTermDepositInterestCalculator.calculateRemainInterest(getDeposit(), days, preClosureInterestRate);
|
||||
this.interestAccrued = this.interestAccrued.add(accuredInterestAfterMaturityToTillDate.getAmount());
|
||||
|
||||
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), eventDate,getAccuredInterest());
|
||||
depositaccountTransaction.updateAccount(this);
|
||||
this.depositaccountTransactions.add(depositaccountTransaction);
|
||||
|
||||
this.closedOnDate = new LocalDate().toDate();
|
||||
this.closedOnDate = eventDate.toDate();
|
||||
this.withdrawnOnDate = null;
|
||||
this.rejectedOnDate = null;
|
||||
|
||||
@@ -529,37 +561,42 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
DepositAccountStatus statusEnum = depositLifecycleStateMachine.transition(DepositAccountEvent.DEPOSIT_PRECLOSED, DepositAccountStatus.fromInt(this.depositStatus));
|
||||
this.depositStatus = statusEnum.getValue();
|
||||
|
||||
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), new LocalDate(),getAccuredInterest());
|
||||
DepositAccountTransaction depositaccountTransaction = DepositAccountTransaction.withdraw(getDeposit(), eventDate, getAccuredInterest());
|
||||
depositaccountTransaction.updateAccount(this);
|
||||
this.depositaccountTransactions.add(depositaccountTransaction);
|
||||
|
||||
this.closedOnDate = new LocalDate().toDate();
|
||||
this.closedOnDate = eventDate.toDate();
|
||||
this.withdrawnOnDate = null;
|
||||
this.rejectedOnDate = null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void adjustTotalAmountForPreclosureInterest(DepositAccount account, FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator) {
|
||||
public void adjustTotalAmountForPreclosureInterest(DepositAccount account, FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,LocalDate eventDate) {
|
||||
|
||||
LocalDate commnencementDate = new LocalDate(this.actualCommencementDate);
|
||||
LocalDate preClosedDate = new LocalDate();
|
||||
LocalDate commnencementDate = getActualCommencementDate();
|
||||
LocalDate preClosedDate = eventDate;
|
||||
|
||||
Integer tenure = Months.monthsBetween(commnencementDate, preClosedDate).getMonths();
|
||||
LocalDate actualPrecloseCalculationDate = commnencementDate.plusMonths(tenure);
|
||||
Integer missedDays = Days.daysBetween(actualPrecloseCalculationDate, preClosedDate).getDays();
|
||||
|
||||
Money deposit = Money.of(account.getDeposit().getCurrency(), account.getDeposit().getAmount());
|
||||
Money accuredtotalAmount = null;
|
||||
Money remainDaysAmount = fixedTermDepositInterestCalculator.calculateRemainInterest(deposit, missedDays, preClosureInterestRate);
|
||||
if (account.isInterestCompoundingAllowed()) {
|
||||
accuredtotalAmount = fixedTermDepositInterestCalculator
|
||||
.calculateInterestOnMaturityFor(deposit, tenure,
|
||||
preClosureInterestRate, interestCompoundedEvery,
|
||||
this.product.getInterestCompoundedEveryPeriodType());
|
||||
accuredtotalAmount = accuredtotalAmount.plus(remainDaysAmount);
|
||||
} else {
|
||||
accuredtotalAmount = fixedTermDepositInterestCalculator
|
||||
.calculateInterestOnMaturityForSimpleInterest(deposit,
|
||||
tenure, preClosureInterestRate,
|
||||
interestCompoundedEvery,
|
||||
this.product.getInterestCompoundedEveryPeriodType());
|
||||
accuredtotalAmount = accuredtotalAmount.plus(remainDaysAmount);
|
||||
}
|
||||
this.total = account.isInterestCompoundingAllowed()?accuredtotalAmount.getAmount():BigDecimal.valueOf(accuredtotalAmount.getAmount().doubleValue()-this.interstPaid.doubleValue());
|
||||
this.interestAccrued = accuredtotalAmount.minus(deposit).getAmount();
|
||||
@@ -596,7 +633,10 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final boolean renewalAllowed, final boolean preClosureAllowed,
|
||||
final boolean isInterestWithdrawable, final boolean isInterestCompoundingAllowed,
|
||||
final FixedTermDepositInterestCalculator fixedTermDepositInterestCalculator,
|
||||
final DepositLifecycleStateMachine depositLifecycleStateMachine) {
|
||||
final DepositLifecycleStateMachine depositLifecycleStateMachine,
|
||||
final boolean isLockinPeriodAllowed,
|
||||
final Integer lockinPeriod,
|
||||
final PeriodFrequencyType lockinPeriodType) {
|
||||
|
||||
Money futureValueOnMaturity =null;
|
||||
|
||||
@@ -614,7 +654,7 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
setExternalId(externalId);
|
||||
if (commencementDate != null) {
|
||||
this.projectedCommencementDate = commencementDate.toDate();
|
||||
this.maturesOnDate = commencementDate.plusMonths(this.tenureInMonths).toDate();
|
||||
this.maturesOnDate = commencementDate.plusMonths(this.tenureInMonths).minusDays(1).toDate();
|
||||
}
|
||||
this.product = product;
|
||||
this.depositAmount = deposit.getAmount();
|
||||
@@ -630,6 +670,9 @@ public class DepositAccount extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.interestCompoundingAllowed=isInterestCompoundingAllowed;
|
||||
this.projectedInterestAccruedOnMaturity = futureValueOnMaturity.minus(deposit).getAmount();
|
||||
this.projectedTotalOnMaturity = futureValueOnMaturity.getAmount();
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -82,4 +82,16 @@ public class FixedTermDepositInterestCalculator {
|
||||
|
||||
return Money.of(deposit.getCurrency(), totalAmount);
|
||||
}
|
||||
|
||||
public Money calculateRemainInterest(Money deposit, Integer days, BigDecimal interestRate){
|
||||
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
Integer daysInYear = 365;
|
||||
|
||||
BigDecimal interestRateAsFraction = interestRate.divide(BigDecimal.valueOf(100), mc);
|
||||
BigDecimal interestRateForOneDay = interestRateAsFraction.divide(BigDecimal.valueOf(daysInYear.doubleValue()), mc);
|
||||
BigDecimal interest = BigDecimal.valueOf(deposit.getAmount().doubleValue()*days.doubleValue()*interestRateForOneDay.doubleValue());
|
||||
|
||||
return Money.of(deposit.getCurrency(), interest);
|
||||
}
|
||||
}
|
||||
+52
-6
@@ -101,6 +101,21 @@ public class DepositAccountAssembler {
|
||||
if(command.isInterestCompoundingAllowedChanged()){
|
||||
interestCompoundingAllowed = command.isInterestCompoundingAllowed();
|
||||
}
|
||||
|
||||
boolean isLockinPeriodAllowed = product.isLockinPeriodAllowed();
|
||||
if(command.isLockinPeriodChanged()){
|
||||
isLockinPeriodAllowed = command.isLockinPeriodAllowed();
|
||||
}
|
||||
|
||||
Integer lockinPeriod = product.getLockinPeriod();
|
||||
if(command.getLockinPeriod() != null){
|
||||
lockinPeriod = command.getLockinPeriod();
|
||||
}
|
||||
|
||||
PeriodFrequencyType lockinPeriodType = product.getLockinPeriodType();
|
||||
if(command.getLockinPeriodType() != null){
|
||||
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
|
||||
}
|
||||
// end of details allowed to be overriden from product
|
||||
|
||||
DepositAccount account =new DepositAccount().openNew(client, product, command.getExternalId(),
|
||||
@@ -109,7 +124,8 @@ public class DepositAccountAssembler {
|
||||
tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency,
|
||||
command.getCommencementDate(),
|
||||
renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator,
|
||||
defaultDepositLifecycleStateMachine(),isInterestWithdrawable,interestCompoundingAllowed);
|
||||
defaultDepositLifecycleStateMachine(),isInterestWithdrawable,interestCompoundingAllowed,
|
||||
isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
|
||||
|
||||
return account;
|
||||
}
|
||||
@@ -186,21 +202,36 @@ public class DepositAccountAssembler {
|
||||
isInterestCompoundingAllowed = command.isInterestCompoundingAllowed();
|
||||
}
|
||||
|
||||
boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed();
|
||||
if(command.isLockinPeriodChanged()){
|
||||
isLockinPeriodAllowed = command.isLockinPeriodAllowed();
|
||||
}
|
||||
|
||||
Integer lockinPeriod = account.getLockinPeriod();
|
||||
if(command.getLockinPeriod() != null){
|
||||
lockinPeriod = command.getLockinPeriod();
|
||||
}
|
||||
|
||||
PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType();
|
||||
if(command.getLockinPeriodType() != null){
|
||||
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
|
||||
}
|
||||
|
||||
DepositAccount newAccount =new DepositAccount().openNew(client, product, null,
|
||||
deposit,
|
||||
maturityInterestRate, preClosureInterestRate,
|
||||
tenureInMonths, compoundingInterestEvery, compoundingInterestFrequency,
|
||||
account.maturesOnDate(),
|
||||
account.maturesOnDate().plusDays(1),
|
||||
renewalAllowed, preClosureAllowed, this.fixedTermDepositInterestCalculator, defaultDepositLifecycleStateMachine(),
|
||||
isInterestWithdrawable,isInterestCompoundingAllowed);
|
||||
isInterestWithdrawable,isInterestCompoundingAllowed,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
|
||||
|
||||
newAccount.updateAccount(account);
|
||||
|
||||
return newAccount;
|
||||
}
|
||||
|
||||
public void adjustTotalAmountForPreclosureInterest(DepositAccount account) {
|
||||
account.adjustTotalAmountForPreclosureInterest(account,this.fixedTermDepositInterestCalculator);
|
||||
public void adjustTotalAmountForPreclosureInterest(DepositAccount account,LocalDate eventDate) {
|
||||
account.adjustTotalAmountForPreclosureInterest(account,this.fixedTermDepositInterestCalculator,eventDate);
|
||||
}
|
||||
|
||||
public void assembleUpdatedDepositAccount(DepositAccount account,DepositAccountCommand command) {
|
||||
@@ -276,8 +307,23 @@ public class DepositAccountAssembler {
|
||||
if(command.isInterestCompoundingAllowedChanged()){
|
||||
isInterestCompoundingAllowed = command.isInterestCompoundingAllowed();
|
||||
}
|
||||
|
||||
boolean isLockinPeriodAllowed = account.isLockinPeriodAllowed();
|
||||
if(command.isLockinPeriodChanged()){
|
||||
isLockinPeriodAllowed = command.isLockinPeriodAllowed();
|
||||
}
|
||||
|
||||
Integer lockinPeriod = account.getLockinPeriod();
|
||||
if(command.getLockinPeriod() != null){
|
||||
lockinPeriod = command.getLockinPeriod();
|
||||
}
|
||||
|
||||
PeriodFrequencyType lockinPeriodType = account.getLockinPeriodType();
|
||||
if(command.getLockinPeriodType() != null){
|
||||
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
|
||||
}
|
||||
account.update(product,externalId,commencementDate,deposit,tenureInMonths,maturityInterestRate,preClosureInterestRate,compoundingInterestEvery,compoundingInterestFrequency,renewalAllowed,
|
||||
preClosureAllowed,isInterestWithdrawable,isInterestCompoundingAllowed,this.fixedTermDepositInterestCalculator,defaultDepositLifecycleStateMachine());
|
||||
preClosureAllowed,isInterestWithdrawable,isInterestCompoundingAllowed,this.fixedTermDepositInterestCalculator,defaultDepositLifecycleStateMachine(),isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
|
||||
}
|
||||
|
||||
public void updateApprovedDepositAccount(DepositAccount account, DepositAccountCommand command) {
|
||||
|
||||
+8
-1
@@ -138,6 +138,7 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
+ " da.is_renewal_allowed as renewalAllowed, da.is_preclosure_allowed as preClosureAllowed, da.pre_closure_interest_rate as preClosureInterestRate, "
|
||||
+ " da.withdrawnon_date as withdrawnonDate, da.rejectedon_date as rejectedonDate, da.closedon_date as closedonDate, "
|
||||
+ " da.interest_paid as interestPaid, da.is_interest_withdrawable as isInterestWithdrawable, da.is_compounding_interest_allowed as interestCompoundingAllowed, "
|
||||
+ " da.is_lock_in_period_allowed as isLockinPeriodAllowed, da.lock_in_period as lockinPeriod, da.lock_in_period_type lockinPeriodType, "
|
||||
+ " c.firstname as firstname, c.lastname as lastname, pd.name as productName,"
|
||||
+ " curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol "
|
||||
+ " from m_deposit_account da "
|
||||
@@ -198,12 +199,18 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
|
||||
boolean isInterestWithdrawable = rs.getBoolean("isInterestWithdrawable");
|
||||
BigDecimal interestPaid = rs.getBigDecimal("interestPaid");
|
||||
|
||||
boolean isLockinPeriodAllowed = rs.getBoolean("isLockinPeriodAllowed");
|
||||
Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod");
|
||||
Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType");
|
||||
EnumOptionData lockinPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(lockinPeriodTypeValue);
|
||||
|
||||
return new DepositAccountData(id, externalId, status, clientId, clientName, productId, productName, currencyData, depositAmount,
|
||||
interestRate, termInMonths, projectedCommencementDate, actualCommencementDate, maturedOn,
|
||||
projectedInterestAccrued, actualInterestAccrued, projectedMaturityAmount, actualMaturityAmount,
|
||||
interestCompoundedEvery, interestCompoundedEveryPeriodType,
|
||||
renewalAllowed, preClosureAllowed, preClosureInterestRate,
|
||||
withdrawnonDate,rejectedonDate,closedonDate,isInterestWithdrawable,interestPaid,interestCompoundingAllowed);
|
||||
withdrawnonDate,rejectedonDate,closedonDate,isInterestWithdrawable,interestPaid,interestCompoundingAllowed,
|
||||
isLockinPeriodAllowed, lockinPeriod, lockinPeriodType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-8
@@ -292,12 +292,20 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
throw new DepositAccountNotFoundException(command.getAccountId());
|
||||
}
|
||||
|
||||
if(command.getMaturesOnDate().isBefore(account.maturesOnDate())){
|
||||
this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account);
|
||||
}
|
||||
account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine());
|
||||
this.depositAccountRepository.save(account);
|
||||
LocalDate eventDate = command.getMaturesOnDate();
|
||||
|
||||
Integer lockinPeriod = account.getLockinPeriod();
|
||||
LocalDate lockinPeriodExpDate = account.getActualCommencementDate().plusMonths(Integer.valueOf(lockinPeriod));
|
||||
if(account.isLockinPeriodAllowed()){
|
||||
if(eventDate.isBefore(lockinPeriodExpDate)){
|
||||
throw new DepositAccountTransactionsException("deposit.transaction.canot.withdraw.before.lockinperiod.reached","You can not withdraw your application before maturity date reached");
|
||||
}
|
||||
}
|
||||
if(eventDate.isBefore(account.maturesOnDate())){
|
||||
this.depositAccountAssembler.adjustTotalAmountForPreclosureInterest(account,eventDate);
|
||||
}
|
||||
account.withdrawDepositAccountMoney(defaultDepositLifecycleStateMachine(),fixedTermDepositInterestCalculator,eventDate);
|
||||
this.depositAccountRepository.save(account);
|
||||
String noteText = command.getNote();
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
Note note = Note.depositNote(account, noteText);
|
||||
@@ -331,13 +339,13 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
account.withdrawInterest(Money.of(account.getDeposit().getCurrency(), command.getWithdrawInterest()));
|
||||
this.depositAccountRepository.save(account);
|
||||
}else {
|
||||
throw new DepositAccountTransactionsException("You can Withdraw "+remainInterestForWithdrawal+" only");
|
||||
throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.exceed","You can Withdraw "+remainInterestForWithdrawal+" only");
|
||||
}
|
||||
}else {
|
||||
throw new DepositAccountTransactionsException("You don't have enough money for withdrawal");
|
||||
throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.insufficient.amount","You don't have enough money for withdrawal");
|
||||
}
|
||||
}else{
|
||||
throw new DepositAccountTransactionsException("You can not withdraw interst for this account");
|
||||
throw new DepositAccountTransactionsException("deposit.transaction.interest.withdrawal.cannot.withdraw","You can not withdraw interst for this account");
|
||||
}
|
||||
return new EntityIdentifier(account.getId());
|
||||
}
|
||||
|
||||
+42
-2
@@ -9,6 +9,7 @@ import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.hibernate.metamodel.binding.CollectionElementNature;
|
||||
import org.mifosng.platform.api.commands.DepositProductCommand;
|
||||
import org.mifosng.platform.currency.domain.MonetaryCurrency;
|
||||
import org.mifosng.platform.exceptions.ValueOutsideRangeException;
|
||||
@@ -75,6 +76,15 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
@Column(name = "pre_closure_interest_rate", scale = 6, precision = 19, nullable = false)
|
||||
private BigDecimal preClosureInterestRate;
|
||||
|
||||
@Column(name = "is_lock_in_period_allowed", nullable=false)
|
||||
private boolean isLockinPeriodAllowed = false;
|
||||
|
||||
@Column(name = "lock_in_period", nullable=false)
|
||||
private Integer lockinPeriod;
|
||||
|
||||
@Column(name = "lock_in_period_type", nullable=false)
|
||||
private PeriodFrequencyType lockinPeriodType;
|
||||
|
||||
protected DepositProduct() {
|
||||
//
|
||||
}
|
||||
@@ -91,7 +101,10 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
final boolean canRenew,
|
||||
final boolean canPreClose,
|
||||
final BigDecimal preClosureInterestRate,
|
||||
final boolean isInterestCompoundingAllowed) {
|
||||
final boolean isInterestCompoundingAllowed,
|
||||
final boolean isLockinPeriodAllowed,
|
||||
final Integer lockinPeriod,
|
||||
final PeriodFrequencyType lockinPeriodType) {
|
||||
this.name = name.trim();
|
||||
if (StringUtils.isNotBlank(description)) {
|
||||
this.description = description.trim();
|
||||
@@ -117,6 +130,9 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.preClosureAllowed = canPreClose;
|
||||
this.preClosureInterestRate = preClosureInterestRate;
|
||||
this.interestCompoundingAllowed = isInterestCompoundingAllowed;
|
||||
this.isLockinPeriodAllowed = isLockinPeriodAllowed;
|
||||
this.lockinPeriod = lockinPeriod;
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
}
|
||||
|
||||
public MonetaryCurrency getCurrency() {
|
||||
@@ -159,6 +175,18 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
return interestCompoundingAllowed;
|
||||
}
|
||||
|
||||
public boolean isLockinPeriodAllowed() {
|
||||
return isLockinPeriodAllowed;
|
||||
}
|
||||
|
||||
public Integer getLockinPeriod() {
|
||||
return lockinPeriod;
|
||||
}
|
||||
|
||||
public PeriodFrequencyType getLockinPeriodType() {
|
||||
return lockinPeriodType;
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
@@ -174,7 +202,7 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
this.externalId = this.getId() + "_DELETED_" + this.externalId;
|
||||
}
|
||||
|
||||
public void update(final DepositProductCommand command, final PeriodFrequencyType interestCompoundingFrequency){
|
||||
public void update(final DepositProductCommand command, final PeriodFrequencyType interestCompoundingFrequency, final PeriodFrequencyType lockinPeriodType){
|
||||
|
||||
if (command.isExternalIdChanged()) {
|
||||
this.externalId = command.getExternalId();
|
||||
@@ -249,6 +277,18 @@ public class DepositProduct extends AbstractAuditableCustom<AppUser, Long> {
|
||||
if(command.interestCompoundingAllowedChanged()){
|
||||
this.interestCompoundingAllowed = command.isInterestCompoundingAllowed();
|
||||
}
|
||||
|
||||
if(command.isLockinPeriodAllowedChanged()){
|
||||
this.isLockinPeriodAllowed = command.isLockinPeriodAllowed();
|
||||
}
|
||||
|
||||
if(command.isLockinPeriodChanged()){
|
||||
this.lockinPeriod = command.getLockinPeriod();
|
||||
}
|
||||
|
||||
if(command.isLockinPeriodTypeChanged()){
|
||||
this.lockinPeriodType = lockinPeriodType;
|
||||
}
|
||||
}
|
||||
|
||||
public void validateInterestRateInRange(final BigDecimal interestRate) {
|
||||
|
||||
+8
-1
@@ -74,6 +74,7 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
|
||||
"dp.interest_compounded_every as interestCompoundedEvery, dp.interest_compounded_every_period_enum as interestCompoundedEveryPeriodType, " +
|
||||
"dp.maturity_default_interest_rate as maturityDefaultInterestRate, dp.is_compounding_interest_allowed as interestCompoundingAllowed, " +
|
||||
"dp.maturity_min_interest_rate as maturityMinInterestRate, dp.maturity_max_interest_rate as maturityMaxInterestRate, dp.is_renewal_allowed as canRenew, dp.is_preclosure_allowed as canPreClose, dp.pre_closure_interest_rate as preClosureInterestRate, " +
|
||||
"dp.is_lock_in_period_allowed as isLockinPeriodAllowed, dp.lock_in_period as lockinPeriod, dp.lock_in_period_type as lockinPeriodType, "+
|
||||
"curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, curr.display_symbol as currencyDisplaySymbol " +
|
||||
"from m_product_deposit dp join m_currency curr on curr.code = dp.currency_code ";
|
||||
}
|
||||
@@ -111,10 +112,16 @@ public class DepositProductReadPlatformServiceImpl implements DepositProductRead
|
||||
|
||||
BigDecimal preClosureInterestRate=rs.getBigDecimal("preClosureInterestRate");
|
||||
|
||||
Boolean isLockinPeriodAllowed=rs.getBoolean("isLockinPeriodAllowed");
|
||||
Integer lockinPeriod = JdbcSupport.getInteger(rs, "lockinPeriod");
|
||||
Integer lockinPeriodTypeValue = JdbcSupport.getInteger(rs, "lockinPeriodType");
|
||||
EnumOptionData lockinPeriodType = SavingsDepositEnumerations.interestCompoundingPeriodType(lockinPeriodTypeValue);
|
||||
|
||||
|
||||
return new DepositProductData(createdOn, lastModifedOn, id, exernalId, name, description, currencyCode, currencyDigits, minimumBalance, maximumBalance,
|
||||
tenureMonths, maturityDefaultInterestRate,maturityMinInterestRate,maturityMaxInterestRate,
|
||||
interestCompoundedEvery, interestCompoundedEveryPeriodType,
|
||||
canRenew,canPreClose,preClosureInterestRate,interestCompoundingAllowed);
|
||||
canRenew,canPreClose,preClosureInterestRate,interestCompoundingAllowed,isLockinPeriodAllowed,lockinPeriod,lockinPeriodType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-2
@@ -57,12 +57,14 @@ public class DepositProductWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
validator.validateForCreate();
|
||||
|
||||
PeriodFrequencyType interestCompoundingPeriodType = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType());
|
||||
PeriodFrequencyType lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
|
||||
MonetaryCurrency currency = new MonetaryCurrency(command.getCurrencyCode(), command.getDigitsAfterDecimal());
|
||||
DepositProduct product = new DepositProduct(command.getName(), command.getExternalId(), command.getDescription(),currency,command.getMinimumBalance(),command.getMaximumBalance(),
|
||||
command.getTenureInMonths(),command.getMaturityDefaultInterestRate(),command.getMaturityMinInterestRate(),command.getMaturityMaxInterestRate(),
|
||||
command.getInterestCompoundedEvery(), interestCompoundingPeriodType,
|
||||
command.isRenewalAllowed(), command.isPreClosureAllowed(),
|
||||
command.getPreClosureInterestRate(),command.isInterestCompoundingAllowed());
|
||||
command.getPreClosureInterestRate(),command.isInterestCompoundingAllowed(),
|
||||
command.isLockinPeriodAllowed(),command.getLockinPeriod(),lockinPeriodType);
|
||||
this.depositProductRepository.save(product);
|
||||
|
||||
return new EntityIdentifier(product.getId());
|
||||
@@ -91,7 +93,12 @@ public class DepositProductWritePlatformServiceJpaRepositoryImpl implements Depo
|
||||
interestCompoundingFrequency = PeriodFrequencyType.fromInt(command.getInterestCompoundedEveryPeriodType());
|
||||
}
|
||||
|
||||
product.update(command, interestCompoundingFrequency);
|
||||
PeriodFrequencyType lockinPeriodType = null;
|
||||
if (command.isLockinPeriodTypeChanged()) {
|
||||
lockinPeriodType = PeriodFrequencyType.fromInt(command.getLockinPeriodType());
|
||||
}
|
||||
|
||||
product.update(command, interestCompoundingFrequency, lockinPeriodType);
|
||||
this.depositProductRepository.save(product);
|
||||
return new EntityIdentifier(Long.valueOf(product.getId()));
|
||||
} catch (DataIntegrityViolationException dve) {
|
||||
|
||||
Reference in New Issue
Block a user