Search in sources :

Example 6 with InstallmentPrincipalAndInterest

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

the class DecliningBalancePrincipalWithInterestGenerator method generateDecliningInstallmentsInterestOnly_v2.

//for M5193
private List<InstallmentPrincipalAndInterest> generateDecliningInstallmentsInterestOnly_v2(Money loanAmount, Integer gracePeriodDuration, Double interestFractionalRatePerInstallment, Integer days, Integer durationInDays) {
    List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
    Money zero = MoneyUtils.zero(loanAmount.getCurrency());
    for (int i = 0; i < gracePeriodDuration; i++) {
        if (i < 1) {
            int noOfDaysBetweenDisbursaldateAndNextMeetingDate = days;
            InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(zero, loanAmount.multiply(interestFractionalRatePerInstallment, noOfDaysBetweenDisbursaldateAndNextMeetingDate, durationInDays));
            emiInstallments.add(installment);
        } else {
            InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(zero, loanAmount.multiply(interestFractionalRatePerInstallment));
            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 7 with InstallmentPrincipalAndInterest

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

the class DecliningBalancePrincipalWithInterestGenerator method generateDecliningInstallmentsNoGrace_v2.

/**
     * Return the list if payment installments for declining interest method, for the number of installments specified.
     */
private List<InstallmentPrincipalAndInterest> generateDecliningInstallmentsNoGrace_v2(final int numberOfInstallments, Money loanAmount, Double interestFractionalRatePerInstallment, Money paymentPerPeriod) {
    List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
    Money decliningPrincipalBalance = loanAmount;
    for (int i = 0; i < numberOfInstallments; i++) {
        Money interestThisPeriod = decliningPrincipalBalance.multiply(interestFractionalRatePerInstallment);
        Money principalThisPeriod = paymentPerPeriod.subtract(interestThisPeriod);
        InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(principalThisPeriod, interestThisPeriod);
        emiInstallments.add(installment);
        decliningPrincipalBalance = decliningPrincipalBalance.subtract(principalThisPeriod);
    }
    return emiInstallments;
}
Also used : Money(org.mifos.framework.util.helpers.Money) ArrayList(java.util.ArrayList) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest)

Example 8 with InstallmentPrincipalAndInterest

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

the class DecliningBalanceEqualPrincipalWithInterestGenerator method generateDecliningEPIInstallmentsNoGrace_v2.

private List<InstallmentPrincipalAndInterest> generateDecliningEPIInstallmentsNoGrace_v2(final int numInstallments, Money loanAmount, Double interestFractionalRatePerInstallment) {
    List<InstallmentPrincipalAndInterest> emiInstallments = new ArrayList<InstallmentPrincipalAndInterest>();
    Money principalBalance = loanAmount;
    Money principalPerPeriod = principalBalance.divide(new BigDecimal(numInstallments));
    double interestRate = interestFractionalRatePerInstallment;
    for (int i = 0; i < numInstallments; i++) {
        Money interestThisPeriod = principalBalance.multiply(interestRate);
        InstallmentPrincipalAndInterest installment = new InstallmentPrincipalAndInterest(principalPerPeriod, interestThisPeriod);
        emiInstallments.add(installment);
        principalBalance = principalBalance.subtract(principalPerPeriod);
    }
    return emiInstallments;
}
Also used : Money(org.mifos.framework.util.helpers.Money) ArrayList(java.util.ArrayList) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest) BigDecimal(java.math.BigDecimal)

Example 9 with InstallmentPrincipalAndInterest

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

the class DecliningBalanceEqualPrincipalWithInterestGenerator method generateEqualInstallments.

@Override
public List<InstallmentPrincipalAndInterest> generateEqualInstallments(LoanInterestCalculationDetails loanInterestCalculationDetails) {
    Money loanAmount = loanInterestCalculationDetails.getLoanAmount();
    Integer numberOfInstallments = loanInterestCalculationDetails.getNumberOfInstallments();
    Double interestFractionalRatePerInstallment = loanInterestCalculationDetails.getInterestFractionalRatePerInstallment();
    GraceType graceType = loanInterestCalculationDetails.getGraceType();
    Integer gracePeriodDuration = loanInterestCalculationDetails.getGracePeriodDuration();
    //For M5193
    int prorateValue = 0;
    List<InstallmentPrincipalAndInterest> lstInstallmntPricplIntrst = null;
    LocalDate disbursalDateInLocalDate = loanInterestCalculationDetails.getDisbursementDate();
    DateTime disbursalDate = disbursalDateInLocalDate.toDateTimeAtStartOfDay();
    List<DateTime> scheduledDates = loanInterestCalculationDetails.getLoanScheduleDates();
    if (scheduledDates.size() > 2) {
        //chek whether loanscheduledDates are there
        DateTime firstRepaymentDay = scheduledDates.get(0);
        long differenceOfTwoDatesinMilliseconds = (firstRepaymentDay.toDate().getTime() - disbursalDate.toDate().getTime());
        long noOfDays = differenceOfTwoDatesinMilliseconds / (1000 * 60 * 60 * 24);
        int noOfDaysBetweenFirstRepaymentDayAndDisbursalDate = (int) noOfDays;
        DateTime secondRepaymentDay = scheduledDates.get(1);
        long duration = (secondRepaymentDay.toDate().getTime() - firstRepaymentDay.toDate().getTime()) / (1000 * 60 * 60 * 24);
        int noOfDaysInOneSchedule = (int) duration;
        prorateValue = new ConfigurationPersistence().getConfigurationValueInteger(PRORATE_RULE);
        if (prorateValue == 1)
            lstInstallmntPricplIntrst = allDecliningEPIInstallments_v2(loanAmount, numberOfInstallments, interestFractionalRatePerInstallment, graceType, gracePeriodDuration, noOfDaysBetweenFirstRepaymentDayAndDisbursalDate, noOfDaysInOneSchedule);
    }
    if (prorateValue != 1) {
        lstInstallmntPricplIntrst = allDecliningEPIInstallments_v2(loanAmount, numberOfInstallments, interestFractionalRatePerInstallment, graceType, gracePeriodDuration);
    }
    return lstInstallmntPricplIntrst;
}
Also used : Money(org.mifos.framework.util.helpers.Money) GraceType(org.mifos.accounts.productdefinition.util.helpers.GraceType) ConfigurationPersistence(org.mifos.config.persistence.ConfigurationPersistence) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest) LocalDate(org.joda.time.LocalDate) DateTime(org.joda.time.DateTime)

Example 10 with InstallmentPrincipalAndInterest

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

the class IndividualLoanScheduleFactory method create.

@Override
public LoanSchedule create(LocalDate disbursementDate, List<DateTime> loanScheduleDates, List<Number> totalInstallmentAmounts, LoanOfferingBO loanProduct, CustomerBO customer, MeetingBO loanMeeting, Money loanAmount, Double interestRate, Integer interestDays, Integer gracePeriodDuration, List<AccountFeesEntity> accountFees) {
    GraceType graceType = loanProduct.getGraceType();
    InterestType interestType = loanProduct.getInterestType();
    boolean variableInstallmentLoanProduct = loanProduct.isVariableInstallmentsAllowed();
    boolean roundingDifferenceInFirstPayment = loanProduct.isRoundingDifferenceInFirstPayment();
    Integer numberOfInstallments = loanScheduleDates.size();
    RecurringScheduledEventFactory scheduledEventFactory = new RecurringScheduledEventFactoryImpl();
    ScheduledEvent meetingScheduledEvent = scheduledEventFactory.createScheduledEventFrom(loanMeeting);
    Integer installmentNumber = 1;
    List<InstallmentDate> dueInstallmentDates = new ArrayList<InstallmentDate>();
    for (DateTime scheduledDate : loanScheduleDates) {
        dueInstallmentDates.add(new InstallmentDate(installmentNumber.shortValue(), scheduledDate.toLocalDate().toDateMidnight().toDate()));
        installmentNumber++;
    }
    if (loanProduct.isPrinDueLastInst()) {
        // Principal due on last installment has been cut, so throw an exception if we reach this code.
        throw new BusinessRuleException(AccountConstants.NOT_SUPPORTED_EMI_GENERATION);
    }
    // loan interest calculation for various interest calculation algorithms
    LoanDecliningInterestAnnualPeriodCalculator decliningInterestAnnualPeriodCalculator = new LoanDecliningInterestAnnualPeriodCalculatorFactory().create(loanMeeting.getRecurrenceType());
    Double decliningInterestAnnualPeriod = decliningInterestAnnualPeriodCalculator.calculate(loanMeeting.getRecurAfter().intValue(), interestDays);
    Double interestFractionalRatePerInstallment = interestRate / decliningInterestAnnualPeriod / 100;
    LoanDurationInAccountingYearsCalculator loanDurationInAccountingYearsCalculator = new LoanDurationInAccountingYearsCalculatorFactory().create(loanMeeting.getRecurrenceType());
    Double durationInYears = loanDurationInAccountingYearsCalculator.calculate(loanMeeting.getRecurAfter().intValue(), numberOfInstallments, interestDays);
    List<Money> totalInstallmentAmountsAsMoney = new ArrayList<Money>();
    for (Number totalInstallmentAmount : totalInstallmentAmounts) {
        Money totalAmount = new Money(loanAmount.getCurrency(), BigDecimal.valueOf(totalInstallmentAmount.doubleValue()));
        totalInstallmentAmountsAsMoney.add(totalAmount);
    }
    LoanInterestCalculationDetails loanInterestCalculationDetails = new LoanInterestCalculationDetails(loanAmount, interestRate, graceType, gracePeriodDuration, numberOfInstallments, durationInYears, interestFractionalRatePerInstallment, disbursementDate, loanScheduleDates);
    loanInterestCalculationDetails.setTotalInstallmentAmounts(totalInstallmentAmountsAsMoney);
    LoanInterestCalculatorFactory loanInterestCalculatorFactory = new LoanInterestCalculatorFactoryImpl();
    LoanInterestCalculator loanInterestCalculator = loanInterestCalculatorFactory.create(interestType, variableInstallmentLoanProduct);
    Money loanInterest = loanInterestCalculator.calculate(loanInterestCalculationDetails);
    // end of loan Interest creation
    EqualInstallmentGeneratorFactory equalInstallmentGeneratorFactory = new EqualInstallmentGeneratorFactoryImpl();
    PrincipalWithInterestGenerator equalInstallmentGenerator = equalInstallmentGeneratorFactory.create(interestType, loanInterest, variableInstallmentLoanProduct);
    List<InstallmentPrincipalAndInterest> EMIInstallments = equalInstallmentGenerator.generateEqualInstallments(loanInterestCalculationDetails);
    List<LoanScheduleEntity> unroundedLoanSchedules = createUnroundedLoanSchedulesFromInstallments(dueInstallmentDates, loanInterest, loanAmount, meetingScheduledEvent, EMIInstallments, accountFees, customer);
    Money rawAmount = calculateTotalFeesAndInterestForLoanSchedules(unroundedLoanSchedules, loanAmount.getCurrency(), accountFees);
    List<LoanScheduleEntity> allExistingLoanSchedules = new ArrayList<LoanScheduleEntity>();
    List<LoanScheduleEntity> finalisedLoanSchedules = new ArrayList<LoanScheduleEntity>(unroundedLoanSchedules);
    if (variableInstallmentLoanProduct && totalInstallmentAmounts.isEmpty()) {
        // only round inital loan schedule of variable installments product.
        LoanScheduleRounder loanScheduleInstallmentRounder = new VariableInstallmentLoanScheduleRounder();
        finalisedLoanSchedules = loanScheduleInstallmentRounder.round(graceType, gracePeriodDuration.shortValue(), loanAmount, interestType, unroundedLoanSchedules, allExistingLoanSchedules);
    } else if (!variableInstallmentLoanProduct && roundingDifferenceInFirstPayment) {
        LoanScheduleRounderHelper loanScheduleRounderHelper = new DefaultLoanScheduleRounderHelper();
        LoanScheduleRounder loanScheduleInstallmentRounder = new FirstInstallmentRoudingDifferenceLoanScheduleRounder(loanScheduleRounderHelper);
        finalisedLoanSchedules = loanScheduleInstallmentRounder.round(graceType, gracePeriodDuration.shortValue(), loanAmount, interestType, unroundedLoanSchedules, allExistingLoanSchedules);
    } else if (!variableInstallmentLoanProduct) {
        LoanScheduleRounderHelper loanScheduleRounderHelper = new DefaultLoanScheduleRounderHelper();
        LoanScheduleRounder loanScheduleInstallmentRounder = new DefaultLoanScheduleRounder(loanScheduleRounderHelper);
        finalisedLoanSchedules = loanScheduleInstallmentRounder.round(graceType, gracePeriodDuration.shortValue(), loanAmount, interestType, unroundedLoanSchedules, allExistingLoanSchedules);
    }
    return new LoanSchedule(finalisedLoanSchedules, rawAmount);
}
Also used : LoanScheduleEntity(org.mifos.accounts.loan.business.LoanScheduleEntity) ArrayList(java.util.ArrayList) DateTime(org.joda.time.DateTime) InstallmentDate(org.mifos.accounts.util.helpers.InstallmentDate) Money(org.mifos.framework.util.helpers.Money) BusinessRuleException(org.mifos.service.BusinessRuleException) GraceType(org.mifos.accounts.productdefinition.util.helpers.GraceType) ScheduledEvent(org.mifos.schedule.ScheduledEvent) InterestType(org.mifos.accounts.productdefinition.util.helpers.InterestType) InstallmentPrincipalAndInterest(org.mifos.accounts.loan.util.helpers.InstallmentPrincipalAndInterest)

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