Search in sources :

Example 11 with InstallmentPrincipalAndInterest

use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.

the class IndividualLoanScheduleFactory method createUnroundedLoanSchedulesFromInstallments.

private List<LoanScheduleEntity> createUnroundedLoanSchedulesFromInstallments(List<InstallmentDate> installmentDates, Money loanInterest, Money loanAmount, ScheduledEvent meetingScheduledEvent, List<InstallmentPrincipalAndInterest> principalWithInterestInstallments, List<AccountFeesEntity> accountFees, CustomerBO customer) {
    List<LoanScheduleEntity> unroundedLoanSchedules = new ArrayList<LoanScheduleEntity>();
    List<AccountFeesEntity> accountFeesWithNoTimeOfDibursementFees = new ArrayList<AccountFeesEntity>();
    List<FeeInstallment> feeInstallments = new ArrayList<FeeInstallment>();
    if (!accountFees.isEmpty()) {
        InstallmentFeeCalculatorFactory installmentFeeCalculatorFactory = new InstallmentFeeCalculatorFactoryImpl();
        for (AccountFeesEntity accountFeesEntity : accountFees) {
            RateAmountFlag feeType = accountFeesEntity.getFees().getFeeType();
            InstallmentFeeCalculator installmentFeeCalculator = installmentFeeCalculatorFactory.create(this.feeDao, feeType);
            Double feeAmountOrRate = accountFeesEntity.getFeeAmount();
            Money accountFeeAmount = installmentFeeCalculator.calculate(feeAmountOrRate, loanAmount, loanInterest, accountFeesEntity.getFees());
            accountFeesEntity.setAccountFeeAmount(accountFeeAmount);
            if (!accountFeesEntity.isTimeOfDisbursement()) {
                accountFeesWithNoTimeOfDibursementFees.add(accountFeesEntity);
            }
        }
        feeInstallments = FeeInstallment.createMergedFeeInstallments(meetingScheduledEvent, accountFeesWithNoTimeOfDibursementFees, installmentDates.size());
    }
    int installmentIndex = 0;
    for (InstallmentDate installmentDate1 : installmentDates) {
        InstallmentPrincipalAndInterest em = principalWithInterestInstallments.get(installmentIndex);
        LoanScheduleEntity loanScheduleEntity = new LoanScheduleEntity(null, customer, installmentDate1.getInstallmentId(), new java.sql.Date(installmentDate1.getInstallmentDueDate().getTime()), PaymentStatus.UNPAID, em.getPrincipal(), em.getInterest());
        for (FeeInstallment feeInstallment : feeInstallments) {
            if (feeInstallment.getInstallmentId().equals(installmentDate1.getInstallmentId())) {
                LoanFeeScheduleEntity loanFeeScheduleEntity = new LoanFeeScheduleEntity(loanScheduleEntity, feeInstallment.getAccountFeesEntity().getFees(), feeInstallment.getAccountFeesEntity(), feeInstallment.getAccountFee());
                loanScheduleEntity.addAccountFeesAction(loanFeeScheduleEntity);
            }
        }
        unroundedLoanSchedules.add(loanScheduleEntity);
        installmentIndex++;
    }
    return unroundedLoanSchedules;
}
Also used : LoanScheduleEntity(org.mifos.accounts.loan.business.LoanScheduleEntity) RateAmountFlag(org.mifos.accounts.fees.util.helpers.RateAmountFlag) ArrayList(java.util.ArrayList) InstallmentDate(org.mifos.accounts.util.helpers.InstallmentDate) Money(org.mifos.framework.util.helpers.Money) FeeInstallment(org.mifos.accounts.util.helpers.FeeInstallment) LoanFeeScheduleEntity(org.mifos.accounts.loan.business.LoanFeeScheduleEntity) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest) AccountFeesEntity(org.mifos.accounts.business.AccountFeesEntity)

Example 12 with InstallmentPrincipalAndInterest

use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.

the class FlatLoanPrincipalWithInterestGenerator method generateFlatInstallmentsNoGrace_v2.

/**
     * Divide principal and interest evenly among all installments, no grace period
     */
private List<InstallmentPrincipalAndInterest> generateFlatInstallmentsNoGrace_v2(Money principalPerInstallment, Money interestPerInstallment, Integer numberOfInstallments) {
    List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
    for (int i = 0; i < numberOfInstallments; i++) {
        InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(principalPerInstallment, interestPerInstallment);
        emiInstallments.add(installment);
    }
    return emiInstallments;
}
Also used : ArrayList(java.util.ArrayList) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest)

Example 13 with InstallmentPrincipalAndInterest

use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.

the class FlatLoanPrincipalWithInterestGenerator method allFlatInstallments_v2.

/**
     * Generate flat-interest installment variants based on the type of grace period.
     * <ul>
     * <li>If grace period is none, or applies to both principal and interest, the loan calculations are the same.
     * <li>If grace period is for principal only, don't add new installments. The first grace installments are
     * interest-only, and principal is paid off with the remaining installments. NOTE: Principal-only grace period
     * should be disable for release 1.1.
     * </ul>
     */
private List<InstallmentPrincipalAndInterest> allFlatInstallments_v2(final Money loanInterest, GraceType graceType, Money loanAmount, Integer numberOfInstallments, Integer gracePeriodDuration) {
    List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
    Money principalPerInstallment = loanAmount.divide(numberOfInstallments);
    Money interestPerInstallment = loanInterest.divide(numberOfInstallments);
    if (graceType == GraceType.NONE || graceType == GraceType.GRACEONALLREPAYMENTS) {
        emiInstallments = generateFlatInstallmentsNoGrace_v2(principalPerInstallment, interestPerInstallment, numberOfInstallments);
    } else {
        // getGraceType() == GraceType.PRINCIPALONLYGRACE which is disabled.
        emiInstallments = generateFlatInstallmentsInterestOnly_v2(loanInterest, numberOfInstallments, gracePeriodDuration);
        emiInstallments.addAll(generateFlatInstallmentsAfterInterestOnlyGraceInstallments_v2(loanInterest, loanAmount, numberOfInstallments, gracePeriodDuration));
    }
    return emiInstallments;
}
Also used : Money(org.mifos.framework.util.helpers.Money) ArrayList(java.util.ArrayList) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest)

Example 14 with InstallmentPrincipalAndInterest

use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.

the class FlatLoanPrincipalWithInterestGenerator method generateFlatInstallmentsInterestOnly_v2.

/**
     * Generate interest-only payments for the duration of the grace period. Interest is divided evenly among all
     * installments, but only interest is paid during the grace period.
     */
private List<InstallmentPrincipalAndInterest> generateFlatInstallmentsInterestOnly_v2(final Money loanInterest, Integer numberOfInstallments, Integer gracePeriodDuration) {
    List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
    Money zeroPrincipal = MoneyUtils.zero(loanInterest.getCurrency());
    Money interestPerInstallment = loanInterest.divide(numberOfInstallments);
    for (int i = 0; i < gracePeriodDuration; i++) {
        InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(zeroPrincipal, interestPerInstallment);
        emiInstallments.add(installment);
    }
    return emiInstallments;
}
Also used : Money(org.mifos.framework.util.helpers.Money) ArrayList(java.util.ArrayList) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest)

Example 15 with InstallmentPrincipalAndInterest

use of org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest in project head by mifos.

the class FlatVariableInstallmentPrincipalWithInterestGenerator method generateEqualInstallments.

@Override
public List<InstallmentPrincipalAndInterest> generateEqualInstallments(LoanInterestCalculationDetails loanInterestCalculationDetails) {
    List<InstallmentPrincipalAndInterest> principalAndInterestDetails = new ArrayList<InstallmentPrincipalAndInterest>();
    Double interestRate = loanInterestCalculationDetails.getInterestRate();
    Money loanAmount = loanInterestCalculationDetails.getLoanAmount();
    LocalDate interestPeriodStartDate = loanInterestCalculationDetails.getDisbursementDate();
    Money totalPrincipal = new Money(loanAmount.getCurrency(), Double.valueOf("0"));
    if (loanInterestCalculationDetails.getTotalInstallmentAmounts().isEmpty()) {
        // if empty just divide loan amount by number of installments to get principal due per installment
        Money installmentPrincipalDue = loanAmount.divide(loanInterestCalculationDetails.getNumberOfInstallments());
        int index = 0;
        for (DateTime installmentDueDate : loanInterestCalculationDetails.getLoanScheduleDates()) {
            Money interestForInstallment = formula.calculate(loanAmount, interestRate, interestPeriodStartDate, new LocalDate(installmentDueDate));
            interestPeriodStartDate = new LocalDate(installmentDueDate);
            totalPrincipal = totalPrincipal.add(installmentPrincipalDue);
            if (index == loanInterestCalculationDetails.getLoanScheduleDates().size() - 1) {
                // last installment
                Money realTotalPrincipal = new Money(totalPrincipal.getCurrency(), totalPrincipal.toString());
                if (realTotalPrincipal.isLessThan(loanInterestCalculationDetails.getLoanAmount())) {
                    Money difference = loanInterestCalculationDetails.getLoanAmount().subtract(realTotalPrincipal);
                    installmentPrincipalDue = installmentPrincipalDue.add(difference);
                } else if (realTotalPrincipal.isGreaterThan(loanInterestCalculationDetails.getLoanAmount())) {
                    Money difference = realTotalPrincipal.subtract(loanInterestCalculationDetails.getLoanAmount());
                    installmentPrincipalDue = installmentPrincipalDue.subtract(difference);
                }
            }
            principalAndInterestDetails.add(new InstallmentPrincipalAndInterest(installmentPrincipalDue, interestForInstallment));
            index++;
        }
    } else {
        int index = 0;
        List<Money> totalInstallmentAmounts = loanInterestCalculationDetails.getTotalInstallmentAmounts();
        for (DateTime installmentDueDate : loanInterestCalculationDetails.getLoanScheduleDates()) {
            Money totalInstallmentPayment = totalInstallmentAmounts.get(index);
            Money interestForInstallment = formula.calculate(loanAmount, interestRate, interestPeriodStartDate, new LocalDate(installmentDueDate));
            interestPeriodStartDate = new LocalDate(installmentDueDate);
            Money installmentPrincipalDue = totalInstallmentPayment.subtract(interestForInstallment);
            totalPrincipal = totalPrincipal.add(installmentPrincipalDue);
            if (index == loanInterestCalculationDetails.getLoanScheduleDates().size() - 1) {
                // last installment
                Money realTotalPrincipal = new Money(totalPrincipal.getCurrency(), totalPrincipal.toString());
                if (realTotalPrincipal.isLessThan(loanInterestCalculationDetails.getLoanAmount())) {
                    Money difference = loanInterestCalculationDetails.getLoanAmount().subtract(realTotalPrincipal);
                    installmentPrincipalDue = installmentPrincipalDue.add(difference);
                } else if (realTotalPrincipal.isGreaterThan(loanInterestCalculationDetails.getLoanAmount())) {
                    Money difference = realTotalPrincipal.subtract(loanInterestCalculationDetails.getLoanAmount());
                    installmentPrincipalDue = installmentPrincipalDue.subtract(difference);
                }
            }
            principalAndInterestDetails.add(new InstallmentPrincipalAndInterest(installmentPrincipalDue, interestForInstallment));
            index++;
        }
    }
    return principalAndInterestDetails;
}
Also used : Money(org.mifos.framework.util.helpers.Money) ArrayList(java.util.ArrayList) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime)

Aggregations

InstallmentPrincipalAndInterest (org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest)17 Money (org.mifos.framework.util.helpers.Money)16 ArrayList (java.util.ArrayList)15 DateTime (org.joda.time.DateTime)6 LocalDate (org.joda.time.LocalDate)5 GraceType (org.mifos.accounts.productdefinition.util.helpers.GraceType)4 InstallmentDate (org.mifos.accounts.util.helpers.InstallmentDate)4 AccountFeesEntity (org.mifos.accounts.business.AccountFeesEntity)2 RateAmountFlag (org.mifos.accounts.fees.util.helpers.RateAmountFlag)2 LoanScheduleEntity (org.mifos.accounts.loan.business.LoanScheduleEntity)2 InterestType (org.mifos.accounts.productdefinition.util.helpers.InterestType)2 FeeInstallment (org.mifos.accounts.util.helpers.FeeInstallment)2 ConfigurationPersistence (org.mifos.config.persistence.ConfigurationPersistence)2 ScheduledEvent (org.mifos.schedule.ScheduledEvent)2 BigDecimal (java.math.BigDecimal)1 AccountActionDateEntity (org.mifos.accounts.business.AccountActionDateEntity)1 AccountException (org.mifos.accounts.exceptions.AccountException)1 LoanFeeScheduleEntity (org.mifos.accounts.loan.business.LoanFeeScheduleEntity)1 DefaultLoanScheduleRounder (org.mifos.clientportfolio.newloan.domain.DefaultLoanScheduleRounder)1 DefaultLoanScheduleRounderHelper (org.mifos.clientportfolio.newloan.domain.DefaultLoanScheduleRounderHelper)1