enabled percentage of interrest for loans

This commit is contained in:
Pramod Nuthakki
2013-11-19 01:28:32 +05:30
parent 9ff10edc80
commit f5c91ee28e
6 changed files with 65 additions and 23 deletions
@@ -29,7 +29,12 @@ public enum ChargeCalculationType {
return this.code;
}
public static Object[] validValues() {
public static Object[] validValuesForLoan() {
return new Integer[] { ChargeCalculationType.FLAT.getValue(), ChargeCalculationType.PERCENT_OF_AMOUNT.getValue(),
ChargeCalculationType.PERCENT_OF_AMOUNT_AND_INTEREST.getValue(),ChargeCalculationType.PERCENT_OF_INTEREST.getValue() };
}
public static Object[] validValuesForSavings() {
return new Integer[] { ChargeCalculationType.FLAT.getValue(), ChargeCalculationType.PERCENT_OF_AMOUNT.getValue() };
}
@@ -67,6 +67,9 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("chargeAppliesTo").value(chargeAppliesTo).isOneOfTheseValues(ChargeAppliesTo.validValues());
}
final Integer chargeCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed("chargeCalculationType", element);
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType).notNull();
final ChargeAppliesTo appliesTo = ChargeAppliesTo.fromInt(chargeAppliesTo);
if (appliesTo.isLoanCharge()) {
// loan applicable validation
@@ -81,6 +84,10 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
if (chargePaymentMode != null) {
baseDataValidator.reset().parameter("chargePaymentMode").value(chargePaymentMode).isOneOfTheseValues(ChargePaymentMode.validValues());
}
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType).isOneOfTheseValues(ChargeCalculationType.validValuesForLoan());
}
} else if (appliesTo.isSavingsCharge()) {
// savings applicable validation
@@ -103,6 +110,10 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed("feeOnMonthDay", element);
baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).notNull();
}
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType).isOneOfTheseValues(ChargeCalculationType.validValuesForSavings());
}
}
final String name = this.fromApiJsonHelper.extractStringNamed("name", element);
@@ -124,12 +135,6 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("active").value(active).notNull();
}
final Integer chargeCalculationType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed("chargeCalculationType", element);
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType).notNull();
if (chargeCalculationType != null) {
baseDataValidator.reset().parameter("chargeCalculationType").value(chargeCalculationType).isOneOfTheseValues(ChargeCalculationType.validValues());
}
if (this.fromApiJsonHelper.parameterExists("minCap", element)) {
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("minCap").value(minCap).notNull().positiveAmount();
@@ -691,12 +691,11 @@ public class Loan extends AbstractPersistable<Long> {
amount = getPrincpal().getAmount();
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
final BigDecimal totalInterestCharged = this.loanSummaryWrapper.calculateTotalInterestCharged(
this.repaymentScheduleInstallments, getCurrency()).getAmount();
final BigDecimal totalInterestCharged = getTotalInterest();
amount = getPrincpal().getAmount().add(totalInterestCharged);
break;
case PERCENT_OF_INTEREST:
amount = getSummary().getTotalInterestCharged();
amount = getTotalInterest();
break;
default:
break;
@@ -704,6 +703,14 @@ public class Loan extends AbstractPersistable<Long> {
return amount;
}
/**
* @return
*/
public BigDecimal getTotalInterest() {
return this.loanSummaryWrapper.calculateTotalInterestCharged(
this.repaymentScheduleInstallments, getCurrency()).getAmount();
}
private BigDecimal calculatePerInstallmentChargeAmount(final LoanCharge loanCharge) {
return calculatePerInstallmentChargeAmount(loanCharge.getChargeCalculation(), loanCharge.getPercentage());
}
@@ -72,6 +72,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
@Column(name = "calculation_on_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal amountPercentageAppliedTo;
@SuppressWarnings("unused")
@Column(name = "charge_amount_or_percentage", scale = 6, precision = 19, nullable = false)
private BigDecimal amountOrPercentage;
@@ -123,10 +124,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
amountPercentageAppliedTo = loan.getPrincpal().getAmount();
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
amountPercentageAppliedTo = loan.getPrincpal().getAmount().add(loan.getSummary().getTotalInterestCharged());
amountPercentageAppliedTo = loan.getPrincpal().getAmount().add(loan.getTotalInterest());
break;
case PERCENT_OF_INTEREST:
amountPercentageAppliedTo = loan.getSummary().getTotalInterestCharged();
amountPercentageAppliedTo = loan.getTotalInterest();
break;
default:
break;
@@ -367,6 +368,26 @@ public class LoanCharge extends AbstractPersistable<Long> {
}
}
}
public void update(final BigDecimal amount, final LocalDate dueDate, Integer numberOfRepayments){
BigDecimal amountPercentageAppliedTo = BigDecimal.ZERO;
if(this.loan!=null){
switch (ChargeCalculationType.fromInt(this.chargeCalculation)) {
case PERCENT_OF_AMOUNT:
amountPercentageAppliedTo = loan.getPrincpal().getAmount();
break;
case PERCENT_OF_AMOUNT_AND_INTEREST:
amountPercentageAppliedTo = loan.getPrincpal().getAmount().add(loan.getTotalInterest());
break;
case PERCENT_OF_INTEREST:
amountPercentageAppliedTo = loan.getTotalInterest();
break;
default:
break;
}
}
update(amount, dueDate, amountPercentageAppliedTo, numberOfRepayments, BigDecimal.ZERO);
}
public Map<String, Object> update(final JsonCommand command, final BigDecimal amount) {
@@ -22,18 +22,22 @@ public class LoanRepaymentScheduleProcessingWrapper {
public void reprocess(final MonetaryCurrency currency, final LocalDate disbursementDate,
final List<LoanRepaymentScheduleInstallment> repaymentPeriods, final Set<LoanCharge> loanCharges) {
Money totalInterest = Money.zero(currency);
for (final LoanRepaymentScheduleInstallment installment : repaymentPeriods) {
totalInterest = totalInterest.plus(installment.getInterestCharged(currency));
}
LocalDate startDate = disbursementDate;
for (final LoanRepaymentScheduleInstallment period : repaymentPeriods) {
final Money feeChargesDueForRepaymentPeriod = cumulativeFeeChargesDueWithin(startDate, period.getDueDate(), loanCharges,
currency,period,repaymentPeriods.size());
currency,period,repaymentPeriods.size(), totalInterest);
final Money feeChargesWaivedForRepaymentPeriod = cumulativeFeeChargesWaivedWithin(startDate, period.getDueDate(), loanCharges,
currency);
final Money feeChargesWrittenOffForRepaymentPeriod = cumulativeFeeChargesWrittenOffWithin(startDate, period.getDueDate(),
loanCharges, currency);
final Money penaltyChargesDueForRepaymentPeriod = cumulativePenaltyChargesDueWithin(startDate, period.getDueDate(),
loanCharges, currency,period,repaymentPeriods.size());
loanCharges, currency,period,repaymentPeriods.size(), totalInterest);
final Money penaltyChargesWaivedForRepaymentPeriod = cumulativePenaltyChargesWaivedWithin(startDate, period.getDueDate(),
loanCharges, currency);
final Money penaltyChargesWrittenOffForRepaymentPeriod = cumulativePenaltyChargesWrittenOffWithin(startDate,
@@ -48,7 +52,7 @@ public class LoanRepaymentScheduleProcessingWrapper {
}
private Money cumulativeFeeChargesDueWithin(final LocalDate periodStart, final LocalDate periodEnd, final Set<LoanCharge> loanCharges,
final MonetaryCurrency monetaryCurrency,LoanRepaymentScheduleInstallment period,int numberOfRepayments) {
final MonetaryCurrency monetaryCurrency,LoanRepaymentScheduleInstallment period,int numberOfRepayments,final Money totalInterest) {
Money cumulative = Money.zero(monetaryCurrency);
@@ -74,11 +78,11 @@ public class LoanRepaymentScheduleProcessingWrapper {
loanCharge.getChargeCalculation().isPercentageBased()) {
BigDecimal amount = BigDecimal.ZERO;
if (loanCharge.getChargeCalculation().isPercentageOfAmountAndInterest()) {
amount = amount.add(period.getLoan().getSummary().getTotalPrincipalDisbursed()).add(period.getLoan().getSummary().getTotalInterestCharged());
amount = amount.add(period.getLoan().getPrincpal().getAmount()).add(totalInterest.getAmount());
} else if (loanCharge.getChargeCalculation().isPercentageOfInterest()) {
amount = amount.add(period.getLoan().getSummary().getTotalInterestCharged());
amount = amount.add(totalInterest.getAmount());
} else {
amount = amount.add(period.getLoan().getSummary().getTotalPrincipalDisbursed());
amount = amount.add(period.getLoan().getPrincpal().getAmount());
}
BigDecimal loanChargeAmt = amount.multiply(loanCharge.getPercentage()).divide(BigDecimal.valueOf(100));
cumulative = cumulative.plus(loanChargeAmt);
@@ -130,7 +134,7 @@ public class LoanRepaymentScheduleProcessingWrapper {
}
private Money cumulativePenaltyChargesDueWithin(final LocalDate periodStart, final LocalDate periodEnd,
final Set<LoanCharge> loanCharges, final MonetaryCurrency currency,LoanRepaymentScheduleInstallment period,int numberOfRepayments) {
final Set<LoanCharge> loanCharges, final MonetaryCurrency currency,LoanRepaymentScheduleInstallment period,int numberOfRepayments, Money totalInterest) {
Money cumulative = Money.zero(currency);
@@ -156,11 +160,11 @@ public class LoanRepaymentScheduleProcessingWrapper {
loanCharge.getChargeCalculation().isPercentageBased()) {
BigDecimal amount = BigDecimal.ZERO;
if (loanCharge.getChargeCalculation().isPercentageOfAmountAndInterest()) {
amount = amount.add(period.getLoan().getSummary().getTotalPrincipalDisbursed()).add(period.getLoan().getSummary().getTotalInterestCharged());
amount = amount.add(period.getLoan().getPrincpal().getAmount()).add(totalInterest.getAmount());
} else if (loanCharge.getChargeCalculation().isPercentageOfInterest()) {
amount = amount.add(period.getLoan().getSummary().getTotalInterestCharged());
amount = amount.add(totalInterest.getAmount());
} else {
amount = amount.add(period.getLoan().getSummary().getTotalPrincipalDisbursed());
amount = amount.add(period.getLoan().getPrincpal().getAmount());
}
BigDecimal loanChargeAmt = amount.multiply(loanCharge.getPercentage()).divide(BigDecimal.valueOf(100));
cumulative = cumulative.plus(loanChargeAmt);
@@ -91,7 +91,7 @@ public class LoanChargeAssembler {
final LoanCharge loanCharge = this.loanChargeRepository.findOne(loanChargeId);
if (loanCharge == null) { throw new LoanChargeNotFoundException(loanChargeId); }
loanCharge.update(amount, dueDate, principal, numberOfRepayments, BigDecimal.ZERO);
loanCharge.update(amount, dueDate, numberOfRepayments);
loanCharges.add(loanCharge);
}