package org.mifos.clientportfolio.newloan.domain;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import org.mifos.accounts.loan.business.LoanScheduleEntity;
import org.mifos.accounts.productdefinition.util.helpers.GraceType;
import org.mifos.accounts.productdefinition.util.helpers.InterestType;
import org.mifos.framework.util.helpers.Money;
public class VariableInstallmentLoanScheduleRounder implements LoanScheduleRounder {
@Override
public List<LoanScheduleEntity> round(GraceType graceType, Short gracePeriodDuration, Money loanAmount,
InterestType interestType, List<LoanScheduleEntity> unroundedLoanSchedules,
List<LoanScheduleEntity> allExistingLoanSchedules) {
// for variable installments - want to round all installments total amount values except for the last installment.
Money totalDue = new Money(loanAmount.getCurrency(), Double.valueOf("0"));
for (LoanScheduleEntity loanScheduleEntity : unroundedLoanSchedules) {
totalDue = totalDue.add(loanScheduleEntity.getPrincipalDue()).add(loanScheduleEntity.getInterestDue()).add(loanScheduleEntity.getTotalFeesDue());
}
BigDecimal installmentAmount = totalDue.getAmount().divide(BigDecimal.valueOf(Integer.valueOf(unroundedLoanSchedules.size())), RoundingMode.HALF_UP);
long roundedValue = Math.round(installmentAmount.doubleValue());
Money totalInstallmentMonetaryAmount = new Money(loanAmount.getCurrency(), BigDecimal.valueOf(roundedValue));
Money totalPrincipalToDate = new Money(loanAmount.getCurrency(), BigDecimal.ZERO);
int index = 0;
for (LoanScheduleEntity loanScheduleEntity : unroundedLoanSchedules) {
if (index == unroundedLoanSchedules.size()-1) {
// last installment
loanScheduleEntity.setPrincipal(loanAmount.subtract(totalPrincipalToDate));
} else {
Money principal = totalInstallmentMonetaryAmount.subtract(loanScheduleEntity.getInterest());
loanScheduleEntity.setPrincipal(principal);
totalPrincipalToDate = totalPrincipalToDate.add(principal);
}
index++;
}
return unroundedLoanSchedules;
}
}