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; 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() }; 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()); 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); final ChargeAppliesTo appliesTo = ChargeAppliesTo.fromInt(chargeAppliesTo);
if (appliesTo.isLoanCharge()) { if (appliesTo.isLoanCharge()) {
// loan applicable validation // loan applicable validation
@@ -82,6 +85,10 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("chargePaymentMode").value(chargePaymentMode).isOneOfTheseValues(ChargePaymentMode.validValues()); 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()) { } else if (appliesTo.isSavingsCharge()) {
// savings applicable validation // savings applicable validation
final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed("chargeTimeType", element); final Integer chargeTimeType = this.fromApiJsonHelper.extractIntegerSansLocaleNamed("chargeTimeType", element);
@@ -103,6 +110,10 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed("feeOnMonthDay", element); final MonthDay monthDay = this.fromApiJsonHelper.extractMonthDayNamed("feeOnMonthDay", element);
baseDataValidator.reset().parameter("feeOnMonthDay").value(monthDay).notNull(); 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); final String name = this.fromApiJsonHelper.extractStringNamed("name", element);
@@ -124,12 +135,6 @@ public final class ChargeDefinitionCommandFromApiJsonDeserializer {
baseDataValidator.reset().parameter("active").value(active).notNull(); 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)) { if (this.fromApiJsonHelper.parameterExists("minCap", element)) {
final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minCap", element.getAsJsonObject()); final BigDecimal minCap = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed("minCap", element.getAsJsonObject());
baseDataValidator.reset().parameter("minCap").value(minCap).notNull().positiveAmount(); baseDataValidator.reset().parameter("minCap").value(minCap).notNull().positiveAmount();
@@ -691,12 +691,11 @@ public class Loan extends AbstractPersistable<Long> {
amount = getPrincpal().getAmount(); amount = getPrincpal().getAmount();
break; break;
case PERCENT_OF_AMOUNT_AND_INTEREST: case PERCENT_OF_AMOUNT_AND_INTEREST:
final BigDecimal totalInterestCharged = this.loanSummaryWrapper.calculateTotalInterestCharged( final BigDecimal totalInterestCharged = getTotalInterest();
this.repaymentScheduleInstallments, getCurrency()).getAmount();
amount = getPrincpal().getAmount().add(totalInterestCharged); amount = getPrincpal().getAmount().add(totalInterestCharged);
break; break;
case PERCENT_OF_INTEREST: case PERCENT_OF_INTEREST:
amount = getSummary().getTotalInterestCharged(); amount = getTotalInterest();
break; break;
default: default:
break; break;
@@ -704,6 +703,14 @@ public class Loan extends AbstractPersistable<Long> {
return amount; return amount;
} }
/**
* @return
*/
public BigDecimal getTotalInterest() {
return this.loanSummaryWrapper.calculateTotalInterestCharged(
this.repaymentScheduleInstallments, getCurrency()).getAmount();
}
private BigDecimal calculatePerInstallmentChargeAmount(final LoanCharge loanCharge) { private BigDecimal calculatePerInstallmentChargeAmount(final LoanCharge loanCharge) {
return calculatePerInstallmentChargeAmount(loanCharge.getChargeCalculation(), loanCharge.getPercentage()); 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) @Column(name = "calculation_on_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal amountPercentageAppliedTo; private BigDecimal amountPercentageAppliedTo;
@SuppressWarnings("unused")
@Column(name = "charge_amount_or_percentage", scale = 6, precision = 19, nullable = false) @Column(name = "charge_amount_or_percentage", scale = 6, precision = 19, nullable = false)
private BigDecimal amountOrPercentage; private BigDecimal amountOrPercentage;
@@ -123,10 +124,10 @@ public class LoanCharge extends AbstractPersistable<Long> {
amountPercentageAppliedTo = loan.getPrincpal().getAmount(); amountPercentageAppliedTo = loan.getPrincpal().getAmount();
break; break;
case PERCENT_OF_AMOUNT_AND_INTEREST: case PERCENT_OF_AMOUNT_AND_INTEREST:
amountPercentageAppliedTo = loan.getPrincpal().getAmount().add(loan.getSummary().getTotalInterestCharged()); amountPercentageAppliedTo = loan.getPrincpal().getAmount().add(loan.getTotalInterest());
break; break;
case PERCENT_OF_INTEREST: case PERCENT_OF_INTEREST:
amountPercentageAppliedTo = loan.getSummary().getTotalInterestCharged(); amountPercentageAppliedTo = loan.getTotalInterest();
break; break;
default: default:
break; break;
@@ -368,6 +369,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) { public Map<String, Object> update(final JsonCommand command, final BigDecimal amount) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7); final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
@@ -22,18 +22,22 @@ public class LoanRepaymentScheduleProcessingWrapper {
public void reprocess(final MonetaryCurrency currency, final LocalDate disbursementDate, public void reprocess(final MonetaryCurrency currency, final LocalDate disbursementDate,
final List<LoanRepaymentScheduleInstallment> repaymentPeriods, final Set<LoanCharge> loanCharges) { 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; LocalDate startDate = disbursementDate;
for (final LoanRepaymentScheduleInstallment period : repaymentPeriods) { for (final LoanRepaymentScheduleInstallment period : repaymentPeriods) {
final Money feeChargesDueForRepaymentPeriod = cumulativeFeeChargesDueWithin(startDate, period.getDueDate(), loanCharges, 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, final Money feeChargesWaivedForRepaymentPeriod = cumulativeFeeChargesWaivedWithin(startDate, period.getDueDate(), loanCharges,
currency); currency);
final Money feeChargesWrittenOffForRepaymentPeriod = cumulativeFeeChargesWrittenOffWithin(startDate, period.getDueDate(), final Money feeChargesWrittenOffForRepaymentPeriod = cumulativeFeeChargesWrittenOffWithin(startDate, period.getDueDate(),
loanCharges, currency); loanCharges, currency);
final Money penaltyChargesDueForRepaymentPeriod = cumulativePenaltyChargesDueWithin(startDate, period.getDueDate(), 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(), final Money penaltyChargesWaivedForRepaymentPeriod = cumulativePenaltyChargesWaivedWithin(startDate, period.getDueDate(),
loanCharges, currency); loanCharges, currency);
final Money penaltyChargesWrittenOffForRepaymentPeriod = cumulativePenaltyChargesWrittenOffWithin(startDate, 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, 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); Money cumulative = Money.zero(monetaryCurrency);
@@ -74,11 +78,11 @@ public class LoanRepaymentScheduleProcessingWrapper {
loanCharge.getChargeCalculation().isPercentageBased()) { loanCharge.getChargeCalculation().isPercentageBased()) {
BigDecimal amount = BigDecimal.ZERO; BigDecimal amount = BigDecimal.ZERO;
if (loanCharge.getChargeCalculation().isPercentageOfAmountAndInterest()) { 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()) { } else if (loanCharge.getChargeCalculation().isPercentageOfInterest()) {
amount = amount.add(period.getLoan().getSummary().getTotalInterestCharged()); amount = amount.add(totalInterest.getAmount());
} else { } 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)); BigDecimal loanChargeAmt = amount.multiply(loanCharge.getPercentage()).divide(BigDecimal.valueOf(100));
cumulative = cumulative.plus(loanChargeAmt); cumulative = cumulative.plus(loanChargeAmt);
@@ -130,7 +134,7 @@ public class LoanRepaymentScheduleProcessingWrapper {
} }
private Money cumulativePenaltyChargesDueWithin(final LocalDate periodStart, final LocalDate periodEnd, 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); Money cumulative = Money.zero(currency);
@@ -156,11 +160,11 @@ public class LoanRepaymentScheduleProcessingWrapper {
loanCharge.getChargeCalculation().isPercentageBased()) { loanCharge.getChargeCalculation().isPercentageBased()) {
BigDecimal amount = BigDecimal.ZERO; BigDecimal amount = BigDecimal.ZERO;
if (loanCharge.getChargeCalculation().isPercentageOfAmountAndInterest()) { 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()) { } else if (loanCharge.getChargeCalculation().isPercentageOfInterest()) {
amount = amount.add(period.getLoan().getSummary().getTotalInterestCharged()); amount = amount.add(totalInterest.getAmount());
} else { } 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)); BigDecimal loanChargeAmt = amount.multiply(loanCharge.getPercentage()).divide(BigDecimal.valueOf(100));
cumulative = cumulative.plus(loanChargeAmt); cumulative = cumulative.plus(loanChargeAmt);
@@ -91,7 +91,7 @@ public class LoanChargeAssembler {
final LoanCharge loanCharge = this.loanChargeRepository.findOne(loanChargeId); final LoanCharge loanCharge = this.loanChargeRepository.findOne(loanChargeId);
if (loanCharge == null) { throw new LoanChargeNotFoundException(loanChargeId); } if (loanCharge == null) { throw new LoanChargeNotFoundException(loanChargeId); }
loanCharge.update(amount, dueDate, principal, numberOfRepayments, BigDecimal.ZERO); loanCharge.update(amount, dueDate, numberOfRepayments);
loanCharges.add(loanCharge); loanCharges.add(loanCharge);
} }