removed unused deprecated code. small experiment with rounding monetary amounts to multiples of a given value like 50.
This commit is contained in:
+46
-2
@@ -62,8 +62,52 @@ public class Money implements Comparable<Money> {
|
||||
this.currencyDigitsAfterDecimal = digitsAfterDecimal;
|
||||
|
||||
final BigDecimal amountZeroed = defaultToZeroIfNull(amount);
|
||||
BigDecimal amountStripped = amountZeroed.stripTrailingZeros();
|
||||
this.amount = amountStripped.setScale(this.currencyDigitsAfterDecimal, RoundingMode.HALF_EVEN);
|
||||
final BigDecimal amountStripped = amountZeroed.stripTrailingZeros();
|
||||
final BigDecimal amountScaled = amountStripped.setScale(this.currencyDigitsAfterDecimal, RoundingMode.HALF_EVEN);
|
||||
this.amount = amountScaled;
|
||||
|
||||
// TODO - KW - below was test of using floor/ceil functions to support
|
||||
// round monetary amounts into multiples of say 20/50.
|
||||
// if (this.currencyDigitsAfterDecimal == 0) {
|
||||
// double existingVal = amountScaled.doubleValue();
|
||||
// double ceilingOfValue = ceiling(existingVal, Double.valueOf("20.0"));
|
||||
// double floorOfValue = floor(existingVal, Double.valueOf("20.0"));
|
||||
//
|
||||
// double floorDiff = existingVal - floorOfValue;
|
||||
// double ceilDiff = ceilingOfValue - existingVal;
|
||||
//
|
||||
// if (ceilDiff > floorDiff) {
|
||||
// this.amount = BigDecimal.valueOf(floorOfValue);
|
||||
// } else {
|
||||
// this.amount = BigDecimal.valueOf(ceilingOfValue);
|
||||
// }
|
||||
// } else {
|
||||
// this.amount = amountScaled;
|
||||
// }
|
||||
}
|
||||
|
||||
public static double ceiling(final double n, final double s) {
|
||||
double c;
|
||||
|
||||
if ((n < 0 && s > 0) || (n > 0 && s < 0)) {
|
||||
c = Double.NaN;
|
||||
} else {
|
||||
c = (n == 0 || s == 0) ? 0 : Math.ceil(n / s) * s;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public static double floor(final double n, final double s) {
|
||||
double f;
|
||||
|
||||
if ((n < 0 && s > 0) || (n > 0 && s < 0) || (s == 0 && n != 0)) {
|
||||
f = Double.NaN;
|
||||
} else {
|
||||
f = (n == 0 || s == 0) ? 0 : Math.floor(n / s) * s;
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
private static BigDecimal defaultToZeroIfNull(final BigDecimal value) {
|
||||
|
||||
-65
@@ -5,73 +5,8 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
|
||||
public class FinanicalFunctions {
|
||||
|
||||
@Deprecated
|
||||
public Money calculatePaymentForOnePeriodFrom(final LoanProductRelatedDetail loanScheduleInfo,
|
||||
final BigDecimal periodInterestRateForRepaymentPeriod, final MonetaryCurrency monetaryCurrency) {
|
||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||
|
||||
double futureValue = 0;
|
||||
double numberOfPeriods = loanScheduleInfo.getNumberOfRepayments().doubleValue();
|
||||
double principal = loanScheduleInfo.getPrincipal().getAmount().multiply(BigDecimal.valueOf(-1)).doubleValue();
|
||||
|
||||
// work out the total payment (principal + interest components) for each
|
||||
// installment due.
|
||||
// use the period type and interest as expressed e.g. 2% per month or
|
||||
// 24% per year even is 'daily' interest calculation is selected
|
||||
double paymentPerInstallment = pmt(interestRateFraction, numberOfPeriods, principal, futureValue, false);
|
||||
|
||||
return Money.of(monetaryCurrency, BigDecimal.valueOf(paymentPerInstallment));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Money calculateTotalRepaymentFrom(final LoanProductRelatedDetail loanScheduleInfo,
|
||||
final BigDecimal periodInterestRateForRepaymentPeriod, final MonetaryCurrency monetaryCurrency) {
|
||||
double interestRateFraction = periodInterestRateForRepaymentPeriod.doubleValue();
|
||||
|
||||
double futureValue = 0;
|
||||
double numberOfPeriods = loanScheduleInfo.getNumberOfRepayments().doubleValue();
|
||||
double principal = loanScheduleInfo.getPrincipal().getAmount().multiply(BigDecimal.valueOf(-1)).doubleValue();
|
||||
|
||||
// work out the total payment (principal + interest components) for each
|
||||
// installment due.
|
||||
// use the period type and interest as expressed e.g. 2% per month or
|
||||
// 24% per year even is 'daily' interest calculation is selected
|
||||
double paymentPerInstallment = pmt(interestRateFraction, numberOfPeriods, principal, futureValue, false);
|
||||
|
||||
double totalRepayment = paymentPerInstallment * loanScheduleInfo.getNumberOfRepayments();
|
||||
|
||||
return Money.of(monetaryCurrency, BigDecimal.valueOf(totalRepayment));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Money calculateTotalRepaymentFrom(final Money principal, final Integer loanTermFrequency,
|
||||
final BigDecimal periodInterestRateForLoanTermPeriod, final MonetaryCurrency monetaryCurrency) {
|
||||
|
||||
double interestRateFraction = periodInterestRateForLoanTermPeriod.doubleValue();
|
||||
|
||||
double futureValue = 0;
|
||||
double numberOfPeriods = loanTermFrequency.doubleValue();
|
||||
double principalAmount = principal.getAmount().multiply(BigDecimal.valueOf(-1)).doubleValue();
|
||||
|
||||
// work out the total payment (principal + interest components) for each
|
||||
// installment due.
|
||||
// use the period type and interest as expressed e.g. 2% per month or
|
||||
// 24% per year even is 'daily' interest calculation is selected
|
||||
double paymentPerInstallment = pmt(interestRateFraction, numberOfPeriods, principalAmount, futureValue, false);
|
||||
|
||||
double totalRepayment = paymentPerInstallment * loanTermFrequency;
|
||||
|
||||
return Money.of(monetaryCurrency, BigDecimal.valueOf(totalRepayment));
|
||||
}
|
||||
|
||||
/**
|
||||
* PMT calculates a fixed monthly payment to be paid by borrower every
|
||||
* 'period' to ensure loan is paid off in full (with interest).
|
||||
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
/**
|
||||
* 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.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
|
||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||
|
||||
@Deprecated
|
||||
public class PeriodicInterestRateCalculator {
|
||||
|
||||
private final PaymentPeriodsInOneYearCalculator paymentPeriodsInOneYearCalculator = new DefaultPaymentPeriodsInOneYearCalculator();
|
||||
|
||||
public BigDecimal calculateFrom(final PeriodFrequencyType loanTermFrequencyType, final BigDecimal annualNominalInterestRate) {
|
||||
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
|
||||
Integer paymentPeriodsInOneYear = this.paymentPeriodsInOneYearCalculator.calculate(loanTermFrequencyType);
|
||||
|
||||
BigDecimal divisor = BigDecimal.valueOf(paymentPeriodsInOneYear * 100);
|
||||
return annualNominalInterestRate.divide(divisor, mc);
|
||||
}
|
||||
|
||||
public BigDecimal calculateFrom(final LoanProductRelatedDetail loanScheduleInfo) {
|
||||
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
|
||||
Integer paymentPeriodsInOneYear = this.paymentPeriodsInOneYearCalculator.calculate(loanScheduleInfo
|
||||
.getRepaymentPeriodFrequencyType());
|
||||
|
||||
BigDecimal divisor = BigDecimal.valueOf(paymentPeriodsInOneYear * 100);
|
||||
BigDecimal numberOfPeriods = BigDecimal.valueOf(loanScheduleInfo.getRepayEvery());
|
||||
|
||||
return loanScheduleInfo.getAnnualNominalInterestRate().divide(divisor, mc).multiply(numberOfPeriods);
|
||||
}
|
||||
|
||||
public Money calculateInterestOn(final Money outstandingBalance, final BigDecimal periodInterestRateForRepaymentPeriod,
|
||||
final int daysInPeriod, final LoanProductRelatedDetail loanScheduleInfo) {
|
||||
|
||||
MathContext mc = new MathContext(8, RoundingMode.HALF_EVEN);
|
||||
Money interestDue = Money.zero(outstandingBalance.getCurrency());
|
||||
|
||||
switch (loanScheduleInfo.getInterestCalculationPeriodMethod()) {
|
||||
case DAILY:
|
||||
BigDecimal dailyInterestRate = loanScheduleInfo.getAnnualNominalInterestRate()
|
||||
.divide(BigDecimal.valueOf(Long.valueOf(365)), mc).divide(BigDecimal.valueOf(Double.valueOf("100.0")), mc)
|
||||
.multiply(BigDecimal.valueOf(loanScheduleInfo.getRepayEvery()));
|
||||
|
||||
BigDecimal equivalentInterestRateForPeriod = dailyInterestRate.multiply(BigDecimal.valueOf(Long.valueOf(daysInPeriod)));
|
||||
|
||||
interestDue = outstandingBalance.multiplyRetainScale(equivalentInterestRateForPeriod, RoundingMode.HALF_EVEN);
|
||||
break;
|
||||
default:
|
||||
interestDue = outstandingBalance.multiplyRetainScale(periodInterestRateForRepaymentPeriod, RoundingMode.HALF_EVEN);
|
||||
break;
|
||||
}
|
||||
|
||||
return interestDue;
|
||||
}
|
||||
|
||||
public Money calculatePrincipalOn(final Money totalDuePerInstallment, final Money interestForInstallment,
|
||||
final LoanProductRelatedDetail loanScheduleInfo) {
|
||||
|
||||
Money principalDue = Money.zero(totalDuePerInstallment.getCurrency());
|
||||
|
||||
switch (loanScheduleInfo.getAmortizationMethod()) {
|
||||
case EQUAL_PRINCIPAL:
|
||||
principalDue = loanScheduleInfo.getPrincipal().dividedBy(loanScheduleInfo.getNumberOfRepayments(), RoundingMode.HALF_EVEN);
|
||||
break;
|
||||
case EQUAL_INSTALLMENTS:
|
||||
principalDue = totalDuePerInstallment.minus(interestForInstallment);
|
||||
break;
|
||||
case INVALID:
|
||||
break;
|
||||
}
|
||||
|
||||
return principalDue;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user