List of usage examples for org.joda.time LocalDate plusDays
public LocalDate plusDays(int days)
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; } } } }