Example usage for org.joda.time LocalDate plusDays

List of usage examples for org.joda.time LocalDate plusDays

Introduction

In this page you can find the example usage for org.joda.time LocalDate plusDays.

Prototype

public LocalDate plusDays(int days) 

Source Link

Document

Returns a copy of this date plus the specified number of days.

Usage

From source file:com.gst.portfolio.calendar.service.CalendarUtils.java

License:Apache License

public static LocalDate adjustRecurringDate(final LocalDate recuringDate, final Integer numberOfDays) {
    if (recuringDate.getDayOfMonth() == 1) {
        LocalDate adjustedRecurringDate = recuringDate.plusDays(numberOfDays);
        return adjustedRecurringDate;
    }// w  w w  .j  a v a  2  s.c  om
    return recuringDate;
}

From source file:com.gst.portfolio.calendar.service.CalendarUtils.java

License:Apache License

public static boolean isValidRecurringDate(final Recur recur, final LocalDate seedDate, final LocalDate date,
        boolean isSkipRepaymentonFirstDayOfMonth, final int numberOfDays) {
    LocalDate startDate = date;/*from   w  w  w . j  a v a2 s .  co  m*/
    if (isSkipRepaymentonFirstDayOfMonth && date.getDayOfMonth() == (numberOfDays + 1)) {
        startDate = startDate.minusDays(numberOfDays);
    }
    final Collection<LocalDate> recurDate = getRecurringDates(recur, seedDate, startDate, date.plusDays(1), 1,
            isSkipRepaymentonFirstDayOfMonth, numberOfDays);

    return (recurDate == null || recurDate.isEmpty()) ? false : recurDate.contains(date);
}

From source file:com.gst.portfolio.calendar.service.CalendarUtils.java

License:Apache License

public static LocalDate getFirstRepaymentMeetingDate(final Calendar calendar, final LocalDate disbursementDate,
        final Integer loanRepaymentInterval, final String frequency, boolean isSkipRepaymentOnFirstDayOfMonth,
        final Integer numberOfDays) {
    final Recur recur = CalendarUtils.getICalRecur(calendar.getRecurrence());
    if (recur == null) {
        return null;
    }//w  w w . j  a  va  2 s.  co  m
    LocalDate startDate = disbursementDate;
    final LocalDate seedDate = calendar.getStartDateLocalDate();
    if (isValidRedurringDate(calendar.getRecurrence(), seedDate, startDate, isSkipRepaymentOnFirstDayOfMonth,
            numberOfDays)) {
        startDate = startDate.plusDays(1);
    }
    // Recurring dates should follow loanRepaymentInterval.
    // e.g.
    // for weekly meeting interval is 1
    // where as for loan product with fortnightly frequency interval is 2
    // to generate currect set of meeting dates reset interval same as loan
    // repayment interval.
    recur.setInterval(loanRepaymentInterval);

    // Recurring dates should follow loanRepayment frequency.
    // e.g.
    // daily meeting frequency should support all loan products with any
    // frequency type.
    // to generate currect set of meeting dates reset frequency same as loan
    // repayment frequency.
    if (recur.getFrequency().equals(Recur.DAILY)) {
        recur.setFrequency(frequency);
    }

    final LocalDate firstRepaymentDate = getNextRecurringDate(recur, seedDate, startDate);
    if (isSkipRepaymentOnFirstDayOfMonth && firstRepaymentDate.getDayOfMonth() == 1) {
        return adjustRecurringDate(firstRepaymentDate, numberOfDays);
    }

    return firstRepaymentDate;
}

From source file:com.gst.portfolio.calendar.service.CalendarUtils.java

License:Apache License

public static LocalDate getNextRepaymentMeetingDate(final String recurringRule, final LocalDate seedDate,
        final LocalDate repaymentDate, final Integer loanRepaymentInterval, final String frequency,
        final WorkingDays workingDays, boolean isSkipRepaymentOnFirstDayOfMonth, final Integer numberOfDays) {

    final Recur recur = CalendarUtils.getICalRecur(recurringRule);
    if (recur == null) {
        return null;
    }// w  w  w . jav  a  2  s  .  c  o m
    LocalDate tmpDate = repaymentDate;
    if (isValidRecurringDate(recur, seedDate, repaymentDate, isSkipRepaymentOnFirstDayOfMonth, numberOfDays)) {
        tmpDate = repaymentDate.plusDays(1);
    }
    /*
     * Recurring dates should follow loanRepaymentInterval.
     * 
     * e.g. The weekly meeting will have interval of 1, if the loan product
     * with fortnightly frequency will have interval of 2, to generate right
     * set of meeting dates reset interval same as loan repayment interval.
     */
    recur.setInterval(loanRepaymentInterval);

    /*
     * Recurring dates should follow loanRepayment frequency. //e.g. daily
     * meeting frequency should support all loan products with any type of
     * frequency. to generate right set of meeting dates reset frequency
     * same as loan repayment frequency.
     */
    if (recur.getFrequency().equals(Recur.DAILY)) {
        recur.setFrequency(frequency);
    }

    LocalDate newRepaymentDate = getNextRecurringDate(recur, seedDate, tmpDate);
    final LocalDate nextRepaymentDate = getNextRecurringDate(recur, seedDate, newRepaymentDate);

    newRepaymentDate = WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDate, nextRepaymentDate,
            workingDays);
    if (isSkipRepaymentOnFirstDayOfMonth) {
        LocalDate newRepaymentDateTemp = adjustRecurringDate(newRepaymentDate, numberOfDays);
        return WorkingDaysUtil.getOffSetDateIfNonWorkingDay(newRepaymentDateTemp, nextRepaymentDate,
                workingDays);
    }

    return newRepaymentDate;
}

From source file:com.gst.portfolio.calendar.service.CalendarUtils.java

License:Apache License

public static LocalDate getRecentEligibleMeetingDate(final String recurringRule, final LocalDate seedDate,
        final boolean isSkipMeetingOnFirstDay, final Integer numberOfDays) {
    LocalDate currentDate = DateUtils.getLocalDateOfTenant();
    final Recur recur = CalendarUtils.getICalRecur(recurringRule);
    if (recur == null) {
        return null;
    }/*from w  w w .j av a 2  s.  c  om*/

    if (isValidRecurringDate(recur, seedDate, currentDate, isSkipMeetingOnFirstDay, numberOfDays)) {
        return currentDate;
    }

    if (recur.getFrequency().equals(Recur.DAILY)) {
        currentDate = currentDate.plusDays(recur.getInterval());
    } else if (recur.getFrequency().equals(Recur.WEEKLY)) {
        currentDate = currentDate.plusWeeks(recur.getInterval());
    } else if (recur.getFrequency().equals(Recur.MONTHLY)) {
        currentDate = currentDate.plusMonths(recur.getInterval());
    } else if (recur.getFrequency().equals(Recur.YEARLY)) {
        currentDate = currentDate.plusYears(recur.getInterval());
    }

    return getNextRecurringDate(recur, seedDate, currentDate);
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

public void regenerateScheduleOnDisbursement(final ScheduleGeneratorDTO scheduleGeneratorDTO,
        final boolean recalculateSchedule, final LocalDate actualDisbursementDate, BigDecimal emiAmount,
        final AppUser currentUser, LocalDate nextPossibleRepaymentDate, Date rescheduledRepaymentDate) {
    boolean isEmiAmountChanged = false;
    if ((this.loanProduct.isMultiDisburseLoan() || this.loanProduct.canDefineInstallmentAmount())
            && emiAmount != null && emiAmount.compareTo(retriveLastEmiAmount()) != 0) {
        if (this.loanProduct.isMultiDisburseLoan()) {
            final Date dateValue = null;
            final boolean isSpecificToInstallment = false;
            final Boolean isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled = scheduleGeneratorDTO
                    .isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled();
            Date effectiveDateFrom = actualDisbursementDate.toDate();
            if (!isChangeEmiIfRepaymentDateSameAsDisbursementDateEnabled
                    && actualDisbursementDate.equals(nextPossibleRepaymentDate)) {
                effectiveDateFrom = nextPossibleRepaymentDate.plusDays(1).toDate();
            }//w  w  w . j av a 2  s.c  om
            LoanTermVariations loanVariationTerms = new LoanTermVariations(
                    LoanTermVariationType.EMI_AMOUNT.getValue(), effectiveDateFrom, emiAmount, dateValue,
                    isSpecificToInstallment, this, LoanStatus.ACTIVE.getValue());
            this.loanTermVariations.add(loanVariationTerms);
        } else {
            this.fixedEmiAmount = emiAmount;
        }
        isEmiAmountChanged = true;
    }
    if (rescheduledRepaymentDate != null && this.loanProduct.isMultiDisburseLoan()) {
        final boolean isSpecificToInstallment = false;
        LoanTermVariations loanVariationTerms = new LoanTermVariations(
                LoanTermVariationType.DUE_DATE.getValue(), nextPossibleRepaymentDate.toDate(), emiAmount,
                rescheduledRepaymentDate, isSpecificToInstallment, this, LoanStatus.ACTIVE.getValue());
        this.loanTermVariations.add(loanVariationTerms);
    }

    if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || recalculateSchedule
            || isEmiAmountChanged || rescheduledRepaymentDate != null) {
        if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
            regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
        } else {
            regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
        }
    }
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

public void updateLoanRepaymentScheduleDates(final LocalDate meetingStartDate, final String recuringRule,
        final boolean isHolidayEnabled, final List<Holiday> holidays, final WorkingDays workingDays,
        final Boolean reschedulebasedOnMeetingDates, final LocalDate presentMeetingDate,
        final LocalDate newMeetingDate, final boolean isSkipRepaymentonfirstdayofmonth,
        final Integer numberofDays) {

    // first repayment's from date is same as disbursement date.
    /*/*from   w w w  . j a  v  a  2s  .c  o  m*/
     * meetingStartDate is used as seedDate Capture the seedDate from user
     * and use the seedDate as meetingStart date
     */

    LocalDate tmpFromDate = getDisbursementDate();
    final PeriodFrequencyType repaymentPeriodFrequencyType = this.loanRepaymentScheduleDetail
            .getRepaymentPeriodFrequencyType();
    final Integer loanRepaymentInterval = this.loanRepaymentScheduleDetail.getRepayEvery();
    final String frequency = CalendarUtils
            .getMeetingFrequencyFromPeriodFrequencyType(repaymentPeriodFrequencyType);

    LocalDate newRepaymentDate = null;
    Boolean isFirstTime = true;
    LocalDate latestRepaymentDate = null;
    List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
    for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : installments) {

        LocalDate oldDueDate = loanRepaymentScheduleInstallment.getDueDate();

        if (oldDueDate.isEqual(presentMeetingDate) || oldDueDate.isAfter(presentMeetingDate)) {

            if (isFirstTime) {

                isFirstTime = false;
                newRepaymentDate = newMeetingDate;

            } else {
                // tmpFromDate.plusDays(1) is done to make sure
                // getNewRepaymentMeetingDate method returns next meeting
                // date and not the same as tmpFromDate
                newRepaymentDate = CalendarUtils.getNewRepaymentMeetingDate(recuringRule, tmpFromDate,
                        tmpFromDate.plusDays(1), loanRepaymentInterval, frequency, workingDays,
                        isSkipRepaymentonfirstdayofmonth, numberofDays);
            }

            if (isHolidayEnabled) {
                newRepaymentDate = HolidayUtil.getRepaymentRescheduleDateToIfHoliday(newRepaymentDate,
                        holidays);
            }
            if (latestRepaymentDate == null || latestRepaymentDate.isBefore(newRepaymentDate)) {
                latestRepaymentDate = newRepaymentDate;
            }
            loanRepaymentScheduleInstallment.updateDueDate(newRepaymentDate);
            // reset from date to get actual daysInPeriod

            if (!isFirstTime) {
                loanRepaymentScheduleInstallment.updateFromDate(tmpFromDate);
            }

            tmpFromDate = newRepaymentDate;// update with new repayment
            // date
        } else {
            tmpFromDate = oldDueDate;
        }
    }
    if (latestRepaymentDate != null) {
        this.expectedMaturityDate = latestRepaymentDate.toDate();
    }
}

From source file:com.gst.portfolio.loanaccount.domain.Loan.java

License:Apache License

private LocalDate getMaxDateLimitForNewRepayment(final PeriodFrequencyType periodFrequencyType,
        final Integer loanRepaymentInterval, final LocalDate startDate) {
    LocalDate dueRepaymentPeriodDate = startDate;
    final Integer repaidEvery = 2 * loanRepaymentInterval;
    switch (periodFrequencyType) {
    case DAYS:/*from  w  w w. j ava 2  s  .c o m*/
        dueRepaymentPeriodDate = startDate.plusDays(repaidEvery);
        break;
    case WEEKS:
        dueRepaymentPeriodDate = startDate.plusWeeks(repaidEvery);
        break;
    case MONTHS:
        dueRepaymentPeriodDate = startDate.plusMonths(repaidEvery);
        break;
    case YEARS:
        dueRepaymentPeriodDate = startDate.plusYears(repaidEvery);
        break;
    case INVALID:
        break;
    }
    return dueRepaymentPeriodDate.minusDays(1);// get 2n-1 range date from
                                               // startDate
}

From source file:com.gst.portfolio.loanaccount.loanschedule.domain.AbstractLoanScheduleGenerator.java

License:Apache License

/**
 * Method calculates interest on not paid outstanding principal and interest
 * (if compounding is enabled) till current date and adds new repayment
 * schedule detail/*from  w w w .ja v  a 2  s.com*/
 * 
 * @param compoundingMap
 *            TODO
 * @param loanCharges
 *            TODO
 * @param principalPortioMap
 *            TODO
 * 
 */
private Money addInterestOnlyRepaymentScheduleForCurrentdate(final MathContext mc,
        final LoanApplicationTerms loanApplicationTerms, final HolidayDetailDTO holidayDetailDTO,
        final MonetaryCurrency currency, final Collection<LoanScheduleModelPeriod> periods,
        final LocalDate currentDate,
        LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor,
        final Collection<RecalculationDetail> transactions, final Set<LoanCharge> loanCharges,
        final LoanScheduleParams params) {
    boolean isFirstRepayment = false;
    LocalDate startDate = params.getPeriodStartDate();
    Money outstanding = params.getOutstandingBalanceAsPerRest();
    Money totalInterest = Money.zero(currency);
    Money totalCumulativeInterest = Money.zero(currency);
    double interestCalculationGraceOnRepaymentPeriodFraction = Double.valueOf(0);
    int periodNumberTemp = 1;
    LocalDate lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms,
            holidayDetailDTO);
    Collection<LoanTermVariationsData> applicableVariations = loanApplicationTerms.getLoanTermVariations()
            .getInterestRateChanges();
    Money uncompoundedFromLastInstallment = params.getUnCompoundedAmount();
    LocalDate additionalPeriodsStartDate = params.getPeriodStartDate();

    do {

        params.setActualRepaymentDate(this.scheduledDateGenerator.generateNextRepaymentDate(
                params.getActualRepaymentDate(), loanApplicationTerms, isFirstRepayment, holidayDetailDTO));
        if (params.getActualRepaymentDate().isAfter(currentDate)) {
            params.setActualRepaymentDate(currentDate);
        }

        Collection<RecalculationDetail> applicableTransactions = getApplicableTransactionsForPeriod(
                params.applyInterestRecalculation(), params.getActualRepaymentDate(), transactions);

        populateCompoundingDatesInPeriod(params.getPeriodStartDate(), params.getActualRepaymentDate(),
                loanApplicationTerms, holidayDetailDTO, params, loanCharges, currency);

        for (RecalculationDetail detail : applicableTransactions) {
            if (detail.isProcessed()) {
                continue;
            }
            LocalDate transactionDate = detail.getTransactionDate();
            List<LoanTransaction> currentTransactions = createCurrentTransactionList(detail);

            if (!params.getPeriodStartDate().isEqual(transactionDate)) {
                PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod(
                        this.paymentPeriodsInOneYearCalculator,
                        interestCalculationGraceOnRepaymentPeriodFraction, totalInterest.zero(),
                        totalInterest.zero(), totalInterest.zero(), totalInterest.zero(), outstanding,
                        loanApplicationTerms, periodNumberTemp, mc, mergeVariationsToMap(params),
                        params.getCompoundingMap(), params.getPeriodStartDate(), transactionDate,
                        applicableVariations);

                Money interest = principalInterestForThisPeriod.interest();
                totalInterest = totalInterest.plus(interest);

                LoanScheduleModelRepaymentPeriod installment = LoanScheduleModelRepaymentPeriod.repayment(
                        params.getInstalmentNumber(), startDate, transactionDate, totalInterest.zero(),
                        totalInterest.zero(), totalInterest, totalInterest.zero(), totalInterest.zero(),
                        totalInterest, true);
                params.incrementInstalmentNumber();
                periods.add(installment);
                totalCumulativeInterest = totalCumulativeInterest.plus(totalInterest);
                totalInterest = totalInterest.zero();
                addLoanRepaymentScheduleInstallment(params.getInstallments(), installment);
                updateCompoundingMap(loanApplicationTerms, holidayDetailDTO, params, lastRestDate,
                        transactionDate);
                populateCompoundingDatesInPeriod(installment.periodDueDate(), params.getActualRepaymentDate(),
                        loanApplicationTerms, holidayDetailDTO, params, loanCharges, currency);
                uncompoundedFromLastInstallment = params.getUnCompoundedAmount();
                params.setPeriodStartDate(transactionDate);
                startDate = transactionDate;
                additionalPeriodsStartDate = startDate;
            }
            loanRepaymentScheduleTransactionProcessor.handleRepaymentSchedule(currentTransactions, currency,
                    params.getInstallments());
            updateLatePaidAmountsToPrincipalMap(detail.getTransaction(), loanApplicationTerms, currency,
                    holidayDetailDTO, lastRestDate, params);
            updateLatePaymentsToMap(loanApplicationTerms, holidayDetailDTO, currency,
                    params.getLatePaymentMap(), currentDate, params.getInstallments(), false, lastRestDate);
            if (params.getLatePaymentMap().isEmpty() && isCompleted(params.getInstallments())) {
                outstanding = outstanding.zero();
            } else {
                outstanding = updateBalanceForInterestCalculation(params.getPrincipalPortionMap(),
                        params.getPeriodStartDate(), outstanding, false);
            }
            if (params.getLatePaymentMap().isEmpty() && outstanding.isZero()) {
                break;
            }
        }

        if (!outstanding.isZero()) {
            PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod(
                    this.paymentPeriodsInOneYearCalculator, interestCalculationGraceOnRepaymentPeriodFraction,
                    totalInterest.zero(), totalInterest.zero(), totalInterest.zero(), totalInterest.zero(),
                    outstanding, loanApplicationTerms, periodNumberTemp, mc, mergeVariationsToMap(params),
                    params.getCompoundingMap(), params.getPeriodStartDate(), params.getActualRepaymentDate(),
                    applicableVariations);
            Money interest = principalInterestForThisPeriod.interest();
            totalInterest = totalInterest.plus(interest);

            if (loanApplicationTerms.getInterestRecalculationCompoundingMethod().isCompoundingEnabled()) {
                Money uncompounded = params.getUnCompoundedAmount();
                Money compounded = uncompounded.zero();
                for (Map.Entry<LocalDate, Money> mapEntry : params.getCompoundingMap().entrySet()) {
                    if (mapEntry.getKey().isAfter(params.getPeriodStartDate())) {
                        compounded = compounded.plus(mapEntry.getValue());
                    }
                }
                if (compounded.isGreaterThanZero() && startDate.isEqual(additionalPeriodsStartDate)) {
                    params.setCompoundedInLastInstallment(uncompoundedFromLastInstallment);// uncompounded in last installment
                    additionalPeriodsStartDate = additionalPeriodsStartDate.plusDays(1);
                }
                Money compoundedForThisPeriod = compounded.minus(uncompounded);
                Money uncompoundedForThisPeriod = interest.minus(compoundedForThisPeriod);
                params.setUnCompoundedAmount(uncompoundedForThisPeriod);
                LocalDate compoundingDate = params.getPeriodStartDate();
                if (loanApplicationTerms.allowCompoundingOnEod()) {
                    compoundingDate = compoundingDate.minusDays(1);
                }
                compoundingDate = getNextCompoundScheduleDate(compoundingDate, loanApplicationTerms,
                        holidayDetailDTO);
                if (compoundingDate.isEqual(params.getActualRepaymentDate())) {
                    params.getCompoundingMap().put(compoundingDate, uncompoundedForThisPeriod);
                    params.setUnCompoundedAmount(uncompoundedForThisPeriod.zero());
                }
            }
        }
        params.setPeriodStartDate(params.getActualRepaymentDate());
    } while (params.getActualRepaymentDate().isBefore(currentDate) && !outstanding.isZero());

    if (totalInterest.isGreaterThanZero()) {
        LoanScheduleModelRepaymentPeriod installment = LoanScheduleModelRepaymentPeriod.repayment(
                params.getInstalmentNumber(), startDate, params.getActualRepaymentDate(), totalInterest.zero(),
                totalInterest.zero(), totalInterest, totalInterest.zero(), totalInterest.zero(), totalInterest,
                true);
        params.incrementInstalmentNumber();
        periods.add(installment);
        params.getCompoundingDateVariations().put(startDate, new TreeMap<>(params.getCompoundingMap()));
        totalCumulativeInterest = totalCumulativeInterest.plus(totalInterest);
    }
    return totalCumulativeInterest;
}

From source file:com.gst.portfolio.loanaccount.loanschedule.domain.AbstractLoanScheduleGenerator.java

License:Apache License

private void updateCompoundingMap(final LoanApplicationTerms loanApplicationTerms,
        final HolidayDetailDTO holidayDetailDTO, final LoanScheduleParams params, final LocalDate lastRestDate,
        final LocalDate scheduledDueDate) {
    if (loanApplicationTerms.isInterestRecalculationEnabled()
            && loanApplicationTerms.getInterestRecalculationCompoundingMethod().isCompoundingEnabled()) {
        final MonetaryCurrency currency = params.getCurrency();
        Money totalCompoundedAmount = Money.zero(currency);
        boolean lastInstallmentIsPastDate = false;
        for (LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : params.getInstallments()) {
            if (params.getCompoundingDateVariations()
                    .containsKey(loanRepaymentScheduleInstallment.getFromDate())) {
                lastInstallmentIsPastDate = params.applyInterestRecalculation()
                        && loanRepaymentScheduleInstallment.getDueDate()
                                .isBefore(DateUtils.getLocalDateOfTenant());
            } else {
                final boolean isPastDate = params.applyInterestRecalculation()
                        && loanRepaymentScheduleInstallment.getDueDate()
                                .isBefore(DateUtils.getLocalDateOfTenant());
                boolean periodHasCompoundingDate = false;
                Money amountCharged = Money.zero(currency);
                if (loanApplicationTerms.getInterestRecalculationCompoundingMethod() != null) {
                    amountCharged = getIncomeForCompounding(loanApplicationTerms, currency,
                            loanRepaymentScheduleInstallment);
                }//from  w  w w .j a v a  2 s.c o  m
                final Map<LocalDate, Money> compoundingMap = params.getCompoundingMap();
                LocalDate effectiveStartDate = loanRepaymentScheduleInstallment.getFromDate();
                if (loanApplicationTerms.allowCompoundingOnEod()) {
                    effectiveStartDate = loanRepaymentScheduleInstallment.getFromDate().minusDays(1);
                }
                LocalDate compoundingEffectiveDate = getNextCompoundScheduleDate(effectiveStartDate,
                        loanApplicationTerms, holidayDetailDTO);
                final LocalDate restDate = getNextRestScheduleDate(scheduledDueDate.minusDays(1),
                        loanApplicationTerms, holidayDetailDTO);
                if (!compoundingEffectiveDate.isAfter(loanRepaymentScheduleInstallment.getDueDate())) {
                    Money amountCompoundedFromLastPeriod = params.getCompoundedInLastInstallment();
                    if (amountCompoundedFromLastPeriod.isZero()) {
                        amountCompoundedFromLastPeriod = params.getUnCompoundedAmount();
                    }
                    totalCompoundedAmount = totalCompoundedAmount.minus(amountCompoundedFromLastPeriod);
                    periodHasCompoundingDate = true;
                }
                while (!compoundingEffectiveDate.isAfter(loanRepaymentScheduleInstallment.getDueDate())) {
                    if (compoundingEffectiveDate.isEqual(loanRepaymentScheduleInstallment.getDueDate())) {
                        Money amountToBeCompounding = amountCharged.minus(totalCompoundedAmount);
                        updateMapWithAmount(compoundingMap, amountToBeCompounding, compoundingEffectiveDate);
                        totalCompoundedAmount = totalCompoundedAmount.plus(amountToBeCompounding);

                    } else if (compoundingMap.containsKey(compoundingEffectiveDate)) {
                        Money compounedAmount = compoundingMap.get(compoundingEffectiveDate);
                        totalCompoundedAmount = totalCompoundedAmount.plus(compounedAmount);
                    }

                    if (!loanApplicationTerms.allowCompoundingOnEod()) {
                        compoundingEffectiveDate = compoundingEffectiveDate.plusDays(1);
                    }
                    compoundingEffectiveDate = getNextCompoundScheduleDate(compoundingEffectiveDate,
                            loanApplicationTerms, holidayDetailDTO);
                }
                if (periodHasCompoundingDate) {
                    if (isPastDate) {
                        updateMapWithAmount(params.getPrincipalPortionMap(),
                                totalCompoundedAmount.plus(params.getUnCompoundedAmount()), lastRestDate);
                    } else {
                        Money amountToBeEffected = amountCharged;
                        if (lastInstallmentIsPastDate) {
                            amountToBeEffected = amountToBeEffected.plus(params.getUnCompoundedAmount());
                        }
                        updateMapWithAmount(params.getPrincipalPortionMap(), amountToBeEffected, restDate);
                    }
                }
                if (totalCompoundedAmount.isGreaterThanZero()) {
                    params.getCompoundingDateVariations().put(loanRepaymentScheduleInstallment.getFromDate(),
                            new TreeMap<>(params.getCompoundingMap()));
                    for (Map.Entry<LocalDate, Money> mapEntry : params.getCompoundingMap().entrySet()) {
                        if (!mapEntry.getKey().isAfter(loanRepaymentScheduleInstallment.getDueDate())) {
                            updateMapWithAmount(params.getPrincipalPortionMap(), mapEntry.getValue().negated(),
                                    mapEntry.getKey());
                        }
                    }
                    params.minusUnCompoundedAmount(params.getUnCompoundedAmount());
                    params.getCompoundingMap().clear();
                    params.addUnCompoundedAmount(amountCharged.minus(totalCompoundedAmount));
                } else {
                    params.getCompoundingMap().clear();
                    params.getCompoundingDateVariations().put(loanRepaymentScheduleInstallment.getFromDate(),
                            new TreeMap<>(params.getCompoundingMap()));
                    params.addUnCompoundedAmount(amountCharged);
                }
                params.setCompoundedInLastInstallment(amountCharged.zero());
                lastInstallmentIsPastDate = isPastDate;
            }

        }
    }

}