removed unused deprecated code. small experiment with rounding monetary amounts to multiples of a given value like 50.

This commit is contained in:
Keith Woodlock
2013-06-07 15:18:24 +01:00
parent ed0bbff7ee
commit ac9c6a792b
3 changed files with 46 additions and 153 deletions
@@ -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) {
@@ -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).
@@ -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;
}
}