List of usage examples for org.joda.time LocalDate minusDays
public LocalDate minusDays(int days)
From source file:hudson.plugins.karma.portlet.KarmaLoadData.java
License:Open Source License
/** * Get Karma coverage results of all jobs and store into a sorted * HashMap by date.//from w ww . j ava2s.c o m * * @param jobs * jobs of Dashboard view * @param daysNumber * number of days * @return Map The sorted summaries */ public static Map<LocalDate, KarmaCoverageResultSummary> loadChartDataWithinRange(List<Job> jobs, int daysNumber) { Map<LocalDate, KarmaCoverageResultSummary> summaries = new HashMap<LocalDate, KarmaCoverageResultSummary>(); // Get the last build (last date) of the all jobs LocalDate lastDate = Utils.getLastDate(jobs); // No builds if (lastDate == null) { return null; } // Get the first date from last build date minus number of days LocalDate firstDate = lastDate.minusDays(daysNumber); // For each job, get Karma coverage results according with // date range (last build date minus number of days) for (Job job : jobs) { Run run = job.getLastBuild(); if (null != run) { LocalDate runDate = new LocalDate(run.getTimestamp()); while (runDate.isAfter(firstDate)) { summarize(summaries, run, runDate, job); run = run.getPreviousBuild(); if (null == run) { break; } runDate = new LocalDate(run.getTimestamp()); } } } // Sorting by date, ascending order Map<LocalDate, KarmaCoverageResultSummary> sortedSummaries = new TreeMap(summaries); return sortedSummaries; }
From source file:module.organization.domain.Accountability.java
License:Open Source License
/** * //from w w w . ja v a 2 s .com * @param start start * @param end end * @return true if the given start and end date overlap in more than one day * with this accountability (exclusively, i.e. if the end date of * this accountability equals the begin date passed as argument, it * returns false) */ public boolean overlaps(final LocalDate start, final LocalDate end) { LocalDate startDateToUse = start == null ? start : start.plusDays(1); LocalDate endDateToUse = end == null ? end : end.minusDays(1); return intersects(startDateToUse, endDateToUse); }
From source file:module.organization.domain.FunctionDelegation.java
License:Open Source License
@Atomic public void edit(final LocalDate beginDate, final LocalDate endDate) { new FunctionDelegationLog(this, "Edit"); final Accountability accountabilityDelegatee = getAccountabilityDelegatee(); // This avoids detecting intersections with itself accountabilityDelegatee.editDates(beginDate.minusDays(2), endDate.minusDays(1)); final Unit unit = (Unit) getAccountabilityDelegatee().getParent(); if (unit.hasAnyIntersectingChildAccountability(accountabilityDelegatee.getChild(), accountabilityDelegatee.getAccountabilityType(), beginDate, endDate, accountabilityDelegatee)) { throw OrganizationDomainException.functionDelegationAlreadyAssigned(); }/*from w w w .j a va2 s. co m*/ accountabilityDelegatee.editDates(beginDate, endDate); }
From source file:net.objectlab.kit.datecalc.joda.LocalDateForwardUnlessNegativeHandler.java
License:Apache License
public LocalDate adjustDate(LocalDate startDate, int increment, NonWorkingDayChecker<LocalDate> checker) { LocalDate date = startDate; while (checker.isNonWorkingDay(date)) { if (increment < 0) { // act as a Backward calendar date = date.minusDays(1); } else {/*from w ww . jav a2s .c o m*/ // move forward by a day! date = date.plusDays(1); } } return date; }
From source file:net.objectlab.kit.datecalc.joda.LocalDateIMMDateCalculator.java
License:Apache License
/** * Checks if a given date is an official IMM Date (3rd Wednesdays of * March/June/Sept/Dec./*w w w .j ava 2s . co m*/ * * @param date * @return true if that date is an IMM date. */ public boolean isIMMDate(final LocalDate date) { boolean same = false; final List<LocalDate> dates = getIMMDates(date.minusDays(1), date, QUARTERLY); if (!dates.isEmpty()) { same = date.equals(dates.get(0)); } return same; }
From source file:net.sourceforge.fenixedu.presentationTier.Action.directiveCouncil.SummariesControlAction.java
License:Open Source License
private List<DetailSummaryElement> getExecutionCourseResume(final ExecutionSemester executionSemester, Collection<Professorship> professorships) { List<DetailSummaryElement> allListElements = new ArrayList<DetailSummaryElement>(); LocalDate today = new LocalDate(); LocalDate oneWeekBeforeToday = today.minusDays(8); for (Professorship professorship : professorships) { BigDecimal summariesGiven = EMPTY, lessonsDeclared = EMPTY; BigDecimal givenSumariesPercentage = EMPTY; BigDecimal notTaughtSummaries = EMPTY; BigDecimal notTaughtSummariesPercentage = EMPTY; if (professorship.belongsToExecutionPeriod(executionSemester) && !professorship.getExecutionCourse().isMasterDegreeDFAOrDEAOnly()) { for (Shift shift : professorship.getExecutionCourse().getAssociatedShifts()) { DegreeTeachingService degreeTeachingService = professorship .getDegreeTeachingServiceByShift(shift); if (degreeTeachingService != null) { // Get the number of declared lessons lessonsDeclared = getDeclaredLesson(degreeTeachingService.getPercentage(), shift, lessonsDeclared, oneWeekBeforeToday); }/* w w w . ja v a2s . co m*/ // Get the number of summaries given summariesGiven = getSummariesGiven(professorship, shift, summariesGiven, oneWeekBeforeToday); // Get the number of not taught summaries notTaughtSummaries = getNotTaughtSummaries(professorship, shift, notTaughtSummaries, oneWeekBeforeToday); } summariesGiven = summariesGiven.setScale(1, RoundingMode.HALF_UP); notTaughtSummaries = notTaughtSummaries.setScale(1, RoundingMode.HALF_UP); lessonsDeclared = lessonsDeclared.setScale(1, RoundingMode.HALF_UP); givenSumariesPercentage = getDifference(lessonsDeclared, summariesGiven); notTaughtSummariesPercentage = getDifference(lessonsDeclared, notTaughtSummaries); Teacher teacher = professorship.getTeacher(); String categoryName = teacher != null && teacher.getCategory() != null ? teacher.getCategory().getName().getContent() : null; String siglas = getSiglas(professorship); String teacherEmail = professorship.getPerson().getDefaultEmailAddress() != null ? professorship.getPerson().getDefaultEmailAddress().getPresentationValue() : null; DetailSummaryElement listElementDTO = new DetailSummaryElement(professorship.getPerson().getName(), professorship.getExecutionCourse().getNome(), teacher != null ? teacher.getTeacherId() : null, teacherEmail, categoryName, lessonsDeclared, summariesGiven, givenSumariesPercentage, notTaughtSummaries, notTaughtSummariesPercentage, siglas); allListElements.add(listElementDTO); } } return allListElements; }
From source file:net.sourceforge.fenixedu.presentationTier.Action.directiveCouncil.SummariesControlAction.java
License:Open Source License
private void setAllDepartmentsSummaryResume(HttpServletRequest request, String executionPeriodOID) throws FenixServiceException { final ExecutionSemester executionSemester = FenixFramework.getDomainObject(executionPeriodOID); List<DepartmentSummaryElement> allDepartmentsSummariesResume = new ArrayList<DepartmentSummaryElement>(); for (Department department : rootDomainObject.getDepartmentsSet()) { DepartmentSummaryElement departmentSummariesElement = getDepartmentSummaryResume(executionSemester, department);// w w w .java2 s . c o m allDepartmentsSummariesResume.add(departmentSummariesElement); } if (executionSemester.isCurrent()) { LocalDate oneWeekBeforeDate = new LocalDate(); request.setAttribute("currentSemester", "true"); request.setAttribute("oneWeekBeforeDate", oneWeekBeforeDate.minusDays(8)); } Collections.sort(allDepartmentsSummariesResume, new BeanComparator("department.realName")); request.setAttribute("summariesResumeMap", allDepartmentsSummariesResume); }
From source file:net.sourceforge.fenixedu.presentationTier.Action.directiveCouncil.SummariesControlAction.java
License:Open Source License
private DepartmentSummaryElement getDepartmentSummaryResume(final ExecutionSemester executionSemester, final Department department) { DepartmentSummaryElement departmentSummariesElement = new DepartmentSummaryElement(department, executionSemester);/*from ww w . j av a 2s . c om*/ Set<ExecutionCourse> allDepartmentExecutionCourses = getDepartmentExecutionCourses(department, executionSemester); if (allDepartmentExecutionCourses != null) { LocalDate today = new LocalDate(); LocalDate oneWeekBeforeToday = today.minusDays(8); for (ExecutionCourse executionCourse : allDepartmentExecutionCourses) { int instanceLessonsTotal[] = { 0, 0, 0 }; for (Shift shift : executionCourse.getAssociatedShifts()) { getInstanceLessonsTotalsByShift(shift, instanceLessonsTotal, oneWeekBeforeToday); } BigDecimal result = BigDecimal.valueOf(0); BigDecimal numberOfLessonInstances = BigDecimal.valueOf(instanceLessonsTotal[0]); BigDecimal numberOfLessonInstancesWithSummary = BigDecimal.valueOf(0); BigDecimal percentageOfLessonsWithNotTaughtSummary = BigDecimal.valueOf(0); BigDecimal numberOfLessonInstancesWithNotTaughtSummary = BigDecimal.valueOf(0); if (instanceLessonsTotal[0] == 0) { continue; } if (instanceLessonsTotal[1] != 0) { numberOfLessonInstancesWithSummary = BigDecimal.valueOf(instanceLessonsTotal[1]); result = numberOfLessonInstancesWithSummary .divide(numberOfLessonInstances, 3, BigDecimal.ROUND_CEILING) .multiply(BigDecimal.valueOf(100)); } if (instanceLessonsTotal[2] != 0) { numberOfLessonInstancesWithNotTaughtSummary = BigDecimal.valueOf(instanceLessonsTotal[2]); percentageOfLessonsWithNotTaughtSummary = numberOfLessonInstancesWithNotTaughtSummary .divide(numberOfLessonInstances, 3, BigDecimal.ROUND_CEILING) .multiply(BigDecimal.valueOf(100)); } SummaryControlCategory resumeClassification = getResumeClassification(result); Map<SummaryControlCategory, List<ExecutionCourseSummaryElement>> departmentResumeMap = departmentSummariesElement .getExecutionCoursesResume(); List<ExecutionCourseSummaryElement> executionCoursesSummary = null; if (departmentResumeMap == null) { departmentResumeMap = new HashMap<SummaryControlCategory, List<ExecutionCourseSummaryElement>>(); executionCoursesSummary = new ArrayList<ExecutionCourseSummaryElement>(); ExecutionCourseSummaryElement executionCourseSummaryElement = new ExecutionCourseSummaryElement( executionCourse, numberOfLessonInstances, numberOfLessonInstancesWithSummary, result, numberOfLessonInstancesWithNotTaughtSummary, percentageOfLessonsWithNotTaughtSummary); executionCoursesSummary.add(executionCourseSummaryElement); departmentResumeMap.put(resumeClassification, executionCoursesSummary); departmentSummariesElement.setExecutionCoursesResume(departmentResumeMap); } else { executionCoursesSummary = departmentResumeMap.get(resumeClassification); if (executionCoursesSummary == null) { executionCoursesSummary = new ArrayList<ExecutionCourseSummaryElement>(); ExecutionCourseSummaryElement executionCourseSummaryElement = new ExecutionCourseSummaryElement( executionCourse, numberOfLessonInstances, numberOfLessonInstancesWithSummary, result, numberOfLessonInstancesWithNotTaughtSummary, percentageOfLessonsWithNotTaughtSummary); executionCoursesSummary.add(executionCourseSummaryElement); departmentResumeMap.put(resumeClassification, executionCoursesSummary); } else { ExecutionCourseSummaryElement executionCourseSummaryElement = new ExecutionCourseSummaryElement( executionCourse, numberOfLessonInstances, numberOfLessonInstancesWithSummary, result, numberOfLessonInstancesWithNotTaughtSummary, percentageOfLessonsWithNotTaughtSummary); executionCoursesSummary.add(executionCourseSummaryElement); } } } } return departmentSummariesElement; }
From source file:org.activiti.dmn.engine.impl.mvel.extension.DateUtil.java
License:Apache License
public static Date subtractDate(Date startDate, Integer years, Integer months, Integer days) { LocalDate currentDate = new LocalDate(startDate); currentDate = currentDate.minusYears(years); currentDate = currentDate.minusMonths(months); currentDate = currentDate.minusDays(days); return currentDate.toDate(); }
From source file:org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AbstractLoanScheduleGenerator.java
License:Apache License
private LoanScheduleModel generate(final MathContext mc, final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final HolidayDetailDTO holidayDetailDTO, final LoanScheduleParams loanScheduleParams) { final ApplicationCurrency applicationCurrency = loanApplicationTerms.getApplicationCurrency(); // generate list of proposed schedule due dates LocalDate loanEndDate = this.scheduledDateGenerator.getLastRepaymentDate(loanApplicationTerms, holidayDetailDTO);/*from www. ja va 2 s.c om*/ LoanTermVariationsData lastDueDateVariation = loanApplicationTerms.getLoanTermVariations() .fetchLoanTermDueDateVariationsData(loanEndDate); if (lastDueDateVariation != null) { loanEndDate = lastDueDateVariation.getDateValue(); } loanApplicationTerms.updateLoanEndDate(loanEndDate); // determine the total charges due at time of disbursement final BigDecimal chargesDueAtTimeOfDisbursement = deriveTotalChargesDueAtTimeOfDisbursement(loanCharges); // setup variables for tracking important facts required for loan // schedule generation. final MonetaryCurrency currency = loanApplicationTerms.getCurrency(); final int numberOfRepayments = loanApplicationTerms.fetchNumberOfRepaymentsAfterExceptions(); LoanScheduleParams scheduleParams = null; if (loanScheduleParams == null) { scheduleParams = LoanScheduleParams.createLoanScheduleParams(currency, Money.of(currency, chargesDueAtTimeOfDisbursement), loanApplicationTerms.getExpectedDisbursementDate(), getPrincipalToBeScheduled(loanApplicationTerms)); } else if (!loanScheduleParams.isPartialUpdate()) { scheduleParams = LoanScheduleParams.createLoanScheduleParams(currency, Money.of(currency, chargesDueAtTimeOfDisbursement), loanApplicationTerms.getExpectedDisbursementDate(), getPrincipalToBeScheduled(loanApplicationTerms), loanScheduleParams); } else { scheduleParams = loanScheduleParams; } final Collection<RecalculationDetail> transactions = scheduleParams.getRecalculationDetails(); final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = scheduleParams .getLoanRepaymentScheduleTransactionProcessor(); final Collection<LoanScheduleModelPeriod> periods = createNewLoanScheduleListWithDisbursementDetails( numberOfRepayments, loanApplicationTerms, chargesDueAtTimeOfDisbursement); // Determine the total interest owed over the full loan for FLAT // interest method . final Money totalInterestChargedForFullLoanTerm = loanApplicationTerms .calculateTotalInterestCharged(this.paymentPeriodsInOneYearCalculator, mc); boolean isFirstRepayment = true; LocalDate firstRepaymentdate = this.scheduledDateGenerator.generateNextRepaymentDate( loanApplicationTerms.getExpectedDisbursementDate(), loanApplicationTerms, isFirstRepayment, holidayDetailDTO); final LocalDate idealDisbursementDate = this.scheduledDateGenerator .idealDisbursementDateBasedOnFirstRepaymentDate( loanApplicationTerms.getLoanTermPeriodFrequencyType(), loanApplicationTerms.getRepaymentEvery(), firstRepaymentdate); if (!scheduleParams.isPartialUpdate()) { // Set Fixed Principal Amount updateAmortization(mc, loanApplicationTerms, scheduleParams.getPeriodNumber(), scheduleParams.getOutstandingBalance()); if (loanApplicationTerms.isMultiDisburseLoan()) { // fetches the first tranche amount and also updates other // tranche // details to map BigDecimal disburseAmt = getDisbursementAmount(loanApplicationTerms, scheduleParams.getPeriodStartDate(), periods, chargesDueAtTimeOfDisbursement, scheduleParams.getDisburseDetailMap(), scheduleParams.applyInterestRecalculation()); scheduleParams.setPrincipalToBeScheduled(Money.of(currency, disburseAmt)); loanApplicationTerms.setPrincipal(loanApplicationTerms.getPrincipal().zero().plus(disburseAmt)); scheduleParams.setOutstandingBalance(Money.of(currency, disburseAmt)); scheduleParams.setOutstandingBalanceAsPerRest(Money.of(currency, disburseAmt)); } } // charges which depends on total loan interest will be added to this // set and handled separately after all installments generated final Set<LoanCharge> nonCompoundingCharges = seperateTotalCompoundingPercentageCharges(loanCharges); LocalDate currentDate = DateUtils.getLocalDateOfTenant(); LocalDate lastRestDate = currentDate; if (loanApplicationTerms.getRestCalendarInstance() != null) { lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO); } boolean isNextRepaymentAvailable = true; Boolean extendTermForDailyRepayments = false; if (holidayDetailDTO.getWorkingDays().getExtendTermForDailyRepayments() == true && loanApplicationTerms.getRepaymentPeriodFrequencyType() == PeriodFrequencyType.DAYS && loanApplicationTerms.getRepaymentEvery() == 1) { holidayDetailDTO.getWorkingDays() .setRepaymentReschedulingType(RepaymentRescheduleType.MOVE_TO_NEXT_WORKING_DAY.getValue()); extendTermForDailyRepayments = true; } final Collection<LoanTermVariationsData> interestRates = loanApplicationTerms.getLoanTermVariations() .getInterestRateChanges(); // this block is to start the schedule generation from specified date if (scheduleParams.isPartialUpdate()) { if (loanApplicationTerms.isMultiDisburseLoan()) { loanApplicationTerms.setPrincipal(scheduleParams.getPrincipalToBeScheduled()); } applyLoanVariationsForPartialScheduleGenerate(loanApplicationTerms, scheduleParams, interestRates); isFirstRepayment = false; } while (!scheduleParams.getOutstandingBalance().isZero() || !scheduleParams.getDisburseDetailMap().isEmpty()) { LocalDate previousRepaymentDate = scheduleParams.getActualRepaymentDate(); scheduleParams.setActualRepaymentDate( this.scheduledDateGenerator.generateNextRepaymentDate(scheduleParams.getActualRepaymentDate(), loanApplicationTerms, isFirstRepayment, holidayDetailDTO)); isFirstRepayment = false; LocalDate scheduledDueDate = this.scheduledDateGenerator.adjustRepaymentDate( scheduleParams.getActualRepaymentDate(), loanApplicationTerms, holidayDetailDTO); // calculated interest start date for the period LocalDate periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod( loanApplicationTerms, scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate); // Loan Schedule Exceptions that need to be applied for Loan Account LoanTermVariationParams termVariationParams = applyLoanTermVariations(loanApplicationTerms, scheduleParams, previousRepaymentDate, scheduledDueDate); scheduledDueDate = termVariationParams.getScheduledDueDate(); // Updates total days in term scheduleParams.addLoanTermInDays( Days.daysBetween(scheduleParams.getPeriodStartDate(), scheduledDueDate).getDays()); if (termVariationParams.isSkipPeriod()) { continue; } if (scheduleParams.getPeriodStartDate().isAfter(scheduledDueDate)) { throw new ScheduleDateException("Due date can't be before period start date", scheduledDueDate); } if (!scheduleParams.getLatePaymentMap().isEmpty()) { populateCompoundingDatesInPeriod(scheduleParams.getPeriodStartDate(), scheduledDueDate, currentDate, loanApplicationTerms, holidayDetailDTO, scheduleParams.getCompoundingMap(), loanCharges, currency); scheduleParams.getCompoundingDateVariations().put(scheduleParams.getPeriodStartDate(), new TreeMap<>(scheduleParams.getCompoundingMap())); } if (extendTermForDailyRepayments) { scheduleParams.setActualRepaymentDate(scheduledDueDate); } // this block is to generate the schedule till the specified // date(used for calculating preclosure) if (scheduleParams.getScheduleTillDate() != null && !scheduledDueDate.isBefore(scheduleParams.getScheduleTillDate())) { scheduledDueDate = scheduleParams.getScheduleTillDate(); isNextRepaymentAvailable = false; } // populates the collection with transactions till the due date of // the period for interest recalculation enabled loans Collection<RecalculationDetail> applicableTransactions = getApplicableTransactionsForPeriod( scheduleParams.applyInterestRecalculation(), scheduledDueDate, transactions); final double interestCalculationGraceOnRepaymentPeriodFraction = this.paymentPeriodsInOneYearCalculator .calculatePortionOfRepaymentPeriodInterestChargingGrace(periodStartDateApplicableForInterest, scheduledDueDate, loanApplicationTerms.getInterestChargedFromLocalDate(), loanApplicationTerms.getLoanTermPeriodFrequencyType(), loanApplicationTerms.getRepaymentEvery()); ScheduleCurrentPeriodParams currentPeriodParams = new ScheduleCurrentPeriodParams(currency, interestCalculationGraceOnRepaymentPeriodFraction); if (loanApplicationTerms.isMultiDisburseLoan()) { updateBalanceBasedOnDisbursement(loanApplicationTerms, chargesDueAtTimeOfDisbursement, scheduleParams, periods, scheduledDueDate); } // process repayments to the schedule as per the repayment // transaction processor configuration // will add a new schedule with interest till the transaction date // for a loan repayment which falls between the // two periods for interest first repayment strategies handleRecalculationForNonDueDateTransactions(mc, loanApplicationTerms, loanCharges, holidayDetailDTO, scheduleParams, periods, totalInterestChargedForFullLoanTerm, idealDisbursementDate, firstRepaymentdate, lastRestDate, scheduledDueDate, periodStartDateApplicableForInterest, applicableTransactions, currentPeriodParams); if (currentPeriodParams.isSkipCurrentLoop()) { continue; } periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod(loanApplicationTerms, scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate); // backup for pre-close transaction updateCompoundingDetails(scheduleParams, periodStartDateApplicableForInterest); // 5 determine principal,interest of repayment period PrincipalInterest principalInterestForThisPeriod = calculatePrincipalInterestComponentsForPeriod( this.paymentPeriodsInOneYearCalculator, currentPeriodParams.getInterestCalculationGraceOnRepaymentPeriodFraction(), scheduleParams.getTotalCumulativePrincipal().minus(scheduleParams.getReducePrincipal()), scheduleParams.getTotalCumulativeInterest(), totalInterestChargedForFullLoanTerm, scheduleParams.getTotalOutstandingInterestPaymentDueToGrace(), scheduleParams.getOutstandingBalanceAsPerRest(), loanApplicationTerms, scheduleParams.getPeriodNumber(), mc, mergeVariationsToMap(scheduleParams), scheduleParams.getCompoundingMap(), periodStartDateApplicableForInterest, scheduledDueDate, interestRates); // will check for EMI amount greater than interest calculated if (loanApplicationTerms.getFixedEmiAmount() != null && loanApplicationTerms.getFixedEmiAmount() .compareTo(principalInterestForThisPeriod.interest().getAmount()) == -1) { String errorMsg = "EMI amount must be greater than : " + principalInterestForThisPeriod.interest().getAmount(); throw new MultiDisbursementEmiAmountException(errorMsg, principalInterestForThisPeriod.interest().getAmount(), loanApplicationTerms.getFixedEmiAmount()); } // update cumulative fields for principal & interest currentPeriodParams.setInterestForThisPeriod(principalInterestForThisPeriod.interest()); Money lastTotalOutstandingInterestPaymentDueToGrace = scheduleParams .getTotalOutstandingInterestPaymentDueToGrace(); scheduleParams.setTotalOutstandingInterestPaymentDueToGrace( principalInterestForThisPeriod.interestPaymentDueToGrace()); currentPeriodParams.setPrincipalForThisPeriod(principalInterestForThisPeriod.principal()); // applies early payments on principal portion updatePrincipalPortionBasedOnPreviousEarlyPayments(currency, scheduleParams, currentPeriodParams); // updates amounts with current earlyPaidAmount updateAmountsBasedOnCurrentEarlyPayments(mc, loanApplicationTerms, scheduleParams, currentPeriodParams); if (scheduleParams.getOutstandingBalance().isLessThanZero() || !isNextRepaymentAvailable) { currentPeriodParams.plusPrincipalForThisPeriod(scheduleParams.getOutstandingBalance()); scheduleParams.setOutstandingBalance(Money.zero(currency)); } if (!isNextRepaymentAvailable) { scheduleParams.getDisburseDetailMap().clear(); } // applies charges for the period applyChargesForCurrentPeriod(loanCharges, currency, scheduleParams, scheduledDueDate, currentPeriodParams); // sum up real totalInstallmentDue from components final Money totalInstallmentDue = currentPeriodParams.fetchTotalAmountForPeriod(); // if previous installment is last then add interest to same // installment if (currentPeriodParams.getLastInstallment() != null && currentPeriodParams.getPrincipalForThisPeriod().isZero()) { currentPeriodParams.getLastInstallment() .addInterestAmount(currentPeriodParams.getInterestForThisPeriod()); continue; } // create repayment period from parts LoanScheduleModelPeriod installment = LoanScheduleModelRepaymentPeriod.repayment( scheduleParams.getInstalmentNumber(), scheduleParams.getPeriodStartDate(), scheduledDueDate, currentPeriodParams.getPrincipalForThisPeriod(), scheduleParams.getOutstandingBalance(), currentPeriodParams.getInterestForThisPeriod(), currentPeriodParams.getFeeChargesForInstallment(), currentPeriodParams.getPenaltyChargesForInstallment(), totalInstallmentDue, false); // apply loan transactions on installments to identify early/late // payments for interest recalculation installment = handleRecalculationForTransactions(mc, loanApplicationTerms, holidayDetailDTO, currency, scheduleParams, loanRepaymentScheduleTransactionProcessor, totalInterestChargedForFullLoanTerm, lastRestDate, scheduledDueDate, periodStartDateApplicableForInterest, applicableTransactions, currentPeriodParams, lastTotalOutstandingInterestPaymentDueToGrace, installment, loanCharges); periods.add(installment); // Updates principal paid map with efective date for reducing // the amount from outstanding balance(interest calculation) updateAmountsWithEffectiveDate(loanApplicationTerms, holidayDetailDTO, scheduleParams, scheduledDueDate, currentPeriodParams, installment); // handle cumulative fields scheduleParams.addTotalCumulativePrincipal(currentPeriodParams.getPrincipalForThisPeriod()); scheduleParams.addTotalRepaymentExpected(totalInstallmentDue); scheduleParams.addTotalCumulativeInterest(currentPeriodParams.getInterestForThisPeriod()); scheduleParams.setPeriodStartDate(scheduledDueDate); scheduleParams.incrementInstalmentNumber(); scheduleParams.incrementPeriodNumber(); scheduleParams.getCompoundingDateVariations().clear(); if (termVariationParams.isRecalculateAmounts()) { loanApplicationTerms.setCurrentPeriodFixedEmiAmount(null); loanApplicationTerms.setCurrentPeriodFixedPrincipalAmount(null); adjustInstallmentOrPrincipalAmount(loanApplicationTerms, scheduleParams.getTotalCumulativePrincipal(), scheduleParams.getPeriodNumber(), mc); } } // this condition is to add the interest from grace period if not // already applied. if (scheduleParams.getTotalOutstandingInterestPaymentDueToGrace().isGreaterThanZero()) { LoanScheduleModelPeriod installment = ((List<LoanScheduleModelPeriod>) periods).get(periods.size() - 1); installment.addInterestAmount(scheduleParams.getTotalOutstandingInterestPaymentDueToGrace()); scheduleParams.addTotalRepaymentExpected(scheduleParams.getTotalOutstandingInterestPaymentDueToGrace()); scheduleParams .addTotalCumulativeInterest(scheduleParams.getTotalOutstandingInterestPaymentDueToGrace()); scheduleParams.setTotalOutstandingInterestPaymentDueToGrace(Money.zero(currency)); } // determine fees and penalties for charges which depends on total // loan interest updatePeriodsWithCharges(currency, scheduleParams, periods, nonCompoundingCharges); // this block is to add extra re-payment schedules with interest portion // if the loan not paid with in loan term if (scheduleParams.getScheduleTillDate() != null) { currentDate = scheduleParams.getScheduleTillDate(); } if (scheduleParams.applyInterestRecalculation() && scheduleParams.getLatePaymentMap().size() > 0 && currentDate.isAfter(scheduleParams.getPeriodStartDate())) { Money totalInterest = addInterestOnlyRepaymentScheduleForCurrentdate(mc, loanApplicationTerms, holidayDetailDTO, currency, periods, currentDate, loanRepaymentScheduleTransactionProcessor, transactions, loanCharges, scheduleParams); scheduleParams.addTotalCumulativeInterest(totalInterest); } loanApplicationTerms.resetFixedEmiAmount(); final BigDecimal totalPrincipalPaid = BigDecimal.ZERO; final BigDecimal totalOutstanding = BigDecimal.ZERO; return LoanScheduleModel.from(periods, applicationCurrency, scheduleParams.getLoanTermInDays(), scheduleParams.getPrincipalToBeScheduled(), scheduleParams.getTotalCumulativePrincipal().getAmount(), totalPrincipalPaid, scheduleParams.getTotalCumulativeInterest().getAmount(), scheduleParams.getTotalFeeChargesCharged().getAmount(), scheduleParams.getTotalPenaltyChargesCharged().getAmount(), scheduleParams.getTotalRepaymentExpected().getAmount(), totalOutstanding); }