List of usage examples for org.joda.time LocalDate isEqual
public boolean isEqual(ReadablePartial partial)
From source file:cz.krtinec.birthday.dto.Zodiac.java
License:Open Source License
public static Zodiac toZodiac(LocalDate birthday) { for (Zodiac zodiac : values()) { LocalDate fromWithYear = zodiac.from.withYear(birthday.getYear()); LocalDate toWithYear = zodiac.to.withYear(birthday.getYear()); if (birthday.getMonthOfYear() == 12 && Zodiac.CAPRICORN.equals(zodiac)) { toWithYear = toWithYear.plusYears(1); } else if (birthday.getMonthOfYear() == 1 && Zodiac.CAPRICORN.equals(zodiac)) { fromWithYear = fromWithYear.minusYears(1); }/*from w ww. j a v a 2s.c o m*/ if ((fromWithYear.isBefore(birthday) || fromWithYear.isEqual(birthday)) && (toWithYear.isAfter(birthday) || toWithYear.isEqual(birthday))) { return zodiac; } } throw new IllegalArgumentException("Cannot find zodiac sign for date: " + birthday); }
From source file:energy.usef.agr.workflow.operate.identifychangeforecast.AgrIdentifyChangeInForecastCoordinator.java
License:Apache License
private void triggerNextSteps(LocalDate period, List<PtuContainerDto> changedPtus) { final LocalDate today = DateTimeUtil.getCurrentDate(); if (today.isEqual(period)) { List<PtuContainerDto> changedPtusForToday = changedPtus.stream() .filter(changedPtu -> today.equals(changedPtu.getPtuDate())).collect(Collectors.toList()); triggerNextStepsForToday(today, changedPtusForToday); } else if (changedPtus.stream().map(PtuContainerDto::getPtuDate).distinct().anyMatch(period::isEqual)) { reOptimizePortfolioEventManager.fire(new ReOptimizePortfolioEvent(period)); }/*w w w . j a va 2 s .c om*/ }
From source file:me.vertretungsplan.parser.IphisParser.java
License:Mozilla Public License
void parseIphis(SubstitutionSchedule substitutionSchedule, JSONArray changes, JSONArray grades, JSONArray teachers, JSONArray messages) throws IOException, JSONException { if (changes == null) { return;/*w w w . jav a 2 s .c o m*/ } // Link course IDs to their names HashMap<String, String> coursesHashMap = null; if (grades != null) { coursesHashMap = new HashMap<>(); for (int i = 0; i < grades.length(); i++) { JSONObject grade = grades.getJSONObject(i); coursesHashMap.put(grade.getString("id"), grade.getString("name")); } } // Link teacher IDs to their names HashMap<String, String> teachersHashMap = null; if (teachers != null) { teachersHashMap = new HashMap<>(); for (int i = 0; i < teachers.length(); i++) { JSONObject teacher = teachers.getJSONObject(i); teachersHashMap.put(teacher.getString("id"), teacher.getString("name")); } } // Add Messages List<AdditionalInfo> infos = new ArrayList<>(messages.length()); for (int i = 0; i < messages.length(); i++) { JSONObject message = messages.getJSONObject(i); AdditionalInfo info = new AdditionalInfo(); info.setHasInformation(message.getBoolean("notification")); info.setTitle(message.getString("titel").trim()); info.setText(message.getString("nachricht").trim()); info.setFromSchedule(true); infos.add(info); } substitutionSchedule.getAdditionalInfos().addAll(infos); substitutionSchedule.setLastChange(lastUpdate); // Add changes to SubstitutionSchedule LocalDate currentDate = LocalDate.now(); SubstitutionScheduleDay substitutionScheduleDay = new SubstitutionScheduleDay(); substitutionScheduleDay.setDate(currentDate); for (int i = 0; i < changes.length(); i++) { final JSONObject change = changes.getJSONObject(i); final LocalDate substitutionDate = new LocalDate(change.getString("datum")); // If starting date of change does not equal date of SubstitutionScheduleDay if (!substitutionDate.isEqual(currentDate)) { if (!substitutionScheduleDay.getSubstitutions().isEmpty() || !substitutionScheduleDay.getMessages().isEmpty()) { substitutionSchedule.addDay(substitutionScheduleDay); } substitutionScheduleDay = new SubstitutionScheduleDay(); substitutionScheduleDay.setDate(substitutionDate); currentDate = substitutionDate; } if (change.getInt("id") > 0) { final Substitution substitution = getSubstitution(change, coursesHashMap, teachersHashMap); substitutionScheduleDay.addSubstitution(substitution); } else if (!change.optString("nachricht").isEmpty()) { substitutionScheduleDay.addMessage(change.optString("nachricht")); } } substitutionSchedule.addDay(substitutionScheduleDay); }
From source file:me.vertretungsplan.parser.LegionBoardParser.java
License:Mozilla Public License
void parseLegionBoard(SubstitutionSchedule substitutionSchedule, JSONArray changes, JSONArray courses, JSONArray teachers) throws IOException, JSONException { if (changes == null) { return;/* w w w. j av a 2s . c om*/ } // Link course IDs to their names HashMap<String, String> coursesHashMap = null; if (courses != null) { coursesHashMap = new HashMap<>(); for (int i = 0; i < courses.length(); i++) { JSONObject course = courses.getJSONObject(i); coursesHashMap.put(course.getString("id"), course.getString("name")); } } // Link teacher IDs to their names HashMap<String, String> teachersHashMap = null; if (teachers != null) { teachersHashMap = new HashMap<>(); for (int i = 0; i < teachers.length(); i++) { JSONObject teacher = teachers.getJSONObject(i); teachersHashMap.put(teacher.getString("id"), teacher.getString("name")); } } // Add changes to SubstitutionSchedule LocalDate currentDate = LocalDate.now(); SubstitutionScheduleDay substitutionScheduleDay = new SubstitutionScheduleDay(); substitutionScheduleDay.setDate(currentDate); for (int i = 0; i < changes.length(); i++) { final JSONObject change = changes.getJSONObject(i); final Substitution substitution = getSubstitution(change, coursesHashMap, teachersHashMap); final LocalDate startingDate = new LocalDate(change.getString("startingDate")); final LocalDate endingDate = new LocalDate(change.getString("endingDate")); // Handle multi-day changes if (!startingDate.isEqual(endingDate)) { if (!substitutionScheduleDay.getSubstitutions().isEmpty()) { substitutionSchedule.addDay(substitutionScheduleDay); } for (int k = 0; k < 8; k++) { final LocalDate date = LocalDate.now().plusDays(k); if ((date.isAfter(startingDate) || date.isEqual(startingDate)) && (date.isBefore(endingDate) || date.isEqual(endingDate))) { substitutionScheduleDay = new SubstitutionScheduleDay(); substitutionScheduleDay.setDate(date); substitutionScheduleDay.addSubstitution(substitution); substitutionSchedule.addDay(substitutionScheduleDay); currentDate = date; } } continue; } // If starting date of change does not equal date of SubstitutionScheduleDay if (!startingDate.isEqual(currentDate)) { if (!substitutionScheduleDay.getSubstitutions().isEmpty()) { substitutionSchedule.addDay(substitutionScheduleDay); } substitutionScheduleDay = new SubstitutionScheduleDay(); substitutionScheduleDay.setDate(startingDate); currentDate = startingDate; } substitutionScheduleDay.addSubstitution(substitution); } substitutionSchedule.addDay(substitutionScheduleDay); }
From source file:org.angnysa.yaba.service.impl.DefaultTransactionService.java
License:Open Source License
@Override public List<Transaction> computeTransactions(TransactionDefinition td, LocalDate start, LocalDate end) { if (start.isAfter(end)) { throw new IllegalArgumentException("start is after end"); }//from w w w. j a va2 s . com List<Transaction> result = new ArrayList<Transaction>(); if (td.getPeriod() == null) { // non repeating if ((td.getDate().isAfter(start) || td.getDate().isEqual(start)) && (td.getDate().isBefore(end) || td.getDate().isEqual(end))) { Transaction at = new Transaction(); at.setTransactionId(td.getId()); at.setDate(td.getDate()); at.setAmount(td.getAmount()); result.add(at); } } else { // repeating // get first valid date LocalDate current = td.getDate(); while (current.isBefore(start)) { current = current.plus(td.getPeriod()); } // get true last limit if (td.getEnd() != null && td.getEnd().isBefore(end)) { end = td.getEnd(); } // list occurrences while (current.isBefore(end) || current.isEqual(end)) { Transaction at = new Transaction(); at.setTransactionId(td.getId()); at.setDate(current); if (td.getReconciliation(current) == null) { at.setAmount(td.getAmount()); } else { at.setAmount(td.getReconciliation(current)); } result.add(at); current = current.plus(td.getPeriod()); } } Collections.sort(result, new Comparator<Transaction>() { @Override public int compare(Transaction t1, Transaction t2) { return t1.getDate().compareTo(t2.getDate()); } }); return result; }
From source file:org.apache.fineract.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) { // first repayment's from date is same as disbursement date. /*//from w ww . j ava 2 s .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; for (final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment : this.repaymentScheduleInstallments) { 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); } 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:org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AbstractLoanScheduleGenerator.java
License:Apache License
private void handleRecalculationForNonDueDateTransactions(final MathContext mc, final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final HolidayDetailDTO holidayDetailDTO, LoanScheduleParams scheduleParams, final Collection<LoanScheduleModelPeriod> periods, final Money totalInterestChargedForFullLoanTerm, final LocalDate idealDisbursementDate, LocalDate firstRepaymentdate, final LocalDate lastRestDate, final LocalDate scheduledDueDate, final LocalDate periodStartDateForInterest, final Collection<RecalculationDetail> applicableTransactions, final ScheduleCurrentPeriodParams currentPeriodParams) { if (scheduleParams.applyInterestRecalculation()) { final MonetaryCurrency currency = scheduleParams.getCurrency(); final Collection<LoanTermVariationsData> interestRates = loanApplicationTerms.getLoanTermVariations() .getInterestRateChanges(); boolean checkForOutstanding = true; List<RecalculationDetail> unprocessedTransactions = new ArrayList<>(); LoanScheduleModelPeriod installment = null; LocalDate periodStartDateApplicableForInterest = periodStartDateForInterest; for (RecalculationDetail detail : applicableTransactions) { if (detail.isProcessed()) { continue; }//from w w w. j av a 2 s . c o m boolean updateLatePaymentMap = false; final LocalDate transactionDate = detail.getTransactionDate(); if (transactionDate.isBefore(scheduledDueDate)) { if (scheduleParams.getLoanRepaymentScheduleTransactionProcessor() != null && scheduleParams.getLoanRepaymentScheduleTransactionProcessor() .isInterestFirstRepaymentScheduleTransactionProcessor()) { List<LoanTransaction> currentTransactions = createCurrentTransactionList(detail); if (!transactionDate.isEqual(scheduleParams.getPeriodStartDate()) || scheduleParams.getInstalmentNumber() == 1) { int periodDays = Days.daysBetween(scheduleParams.getPeriodStartDate(), transactionDate) .getDays(); // calculates period start date for interest // calculation as per the configuration periodStartDateApplicableForInterest = calculateInterestStartDateForPeriod( loanApplicationTerms, scheduleParams.getPeriodStartDate(), idealDisbursementDate, firstRepaymentdate); int daysInPeriodApplicable = Days .daysBetween(periodStartDateApplicableForInterest, transactionDate).getDays(); Money interestForThisinstallment = Money.zero(currency); if (daysInPeriodApplicable > 0) { // 5 determine interest till the transaction // date if (!scheduleParams.getCompoundingDateVariations() .containsKey(periodStartDateApplicableForInterest)) { scheduleParams.getCompoundingDateVariations().put( periodStartDateApplicableForInterest, new TreeMap<>(scheduleParams.getCompoundingMap())); } 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, transactionDate, interestRates); interestForThisinstallment = principalInterestForThisPeriod.interest(); scheduleParams.setTotalOutstandingInterestPaymentDueToGrace( principalInterestForThisPeriod.interestPaymentDueToGrace()); } Money principalForThisPeriod = Money.zero(currency); // applies all the applicable charges to the // newly // created installment PrincipalInterest principalInterest = new PrincipalInterest(principalForThisPeriod, interestForThisinstallment, null); Money feeChargesForInstallment = cumulativeFeeChargesDueWithin( scheduleParams.getPeriodStartDate(), transactionDate, loanCharges, currency, principalInterest, scheduleParams.getPrincipalToBeScheduled(), scheduleParams.getTotalCumulativeInterest(), false); Money penaltyChargesForInstallment = cumulativePenaltyChargesDueWithin( scheduleParams.getPeriodStartDate(), transactionDate, loanCharges, currency, principalInterest, scheduleParams.getPrincipalToBeScheduled(), scheduleParams.getTotalCumulativeInterest(), false); // sum up real totalInstallmentDue from // components final Money totalInstallmentDue = principalForThisPeriod .plus(interestForThisinstallment).plus(feeChargesForInstallment) .plus(penaltyChargesForInstallment); // create repayment period from parts installment = LoanScheduleModelRepaymentPeriod.repayment( scheduleParams.getInstalmentNumber(), scheduleParams.getPeriodStartDate(), transactionDate, principalForThisPeriod, scheduleParams.getOutstandingBalance(), interestForThisinstallment, feeChargesForInstallment, penaltyChargesForInstallment, totalInstallmentDue, true); periods.add(installment); // update outstanding balance for interest // calculation as per the rest updateOutstandingBalanceAsPerRest(scheduleParams, transactionDate); // handle cumulative fields scheduleParams.addLoanTermInDays(periodDays); scheduleParams.addTotalRepaymentExpected(totalInstallmentDue); scheduleParams.addTotalCumulativeInterest(interestForThisinstallment); scheduleParams.addTotalFeeChargesCharged(feeChargesForInstallment); scheduleParams.addTotalPenaltyChargesCharged(penaltyChargesForInstallment); scheduleParams.setPeriodStartDate(transactionDate); periodStartDateApplicableForInterest = scheduleParams.getPeriodStartDate(); updateLatePaymentMap = true; scheduleParams.incrementInstalmentNumber(); // creates and insert Loan repayment schedule // for // the period addLoanRepaymentScheduleInstallment(scheduleParams.getInstallments(), installment); } else if (installment == null) { installment = ((List<LoanScheduleModelPeriod>) periods).get(periods.size() - 1); } // applies the transaction as per transaction // strategy // on scheduled installments to identify the // unprocessed(early payment ) amounts Money unprocessed = scheduleParams.getLoanRepaymentScheduleTransactionProcessor() .handleRepaymentSchedule(currentTransactions, currency, scheduleParams.getInstallments()); if (unprocessed.isGreaterThanZero()) { if (loanApplicationTerms.getPreClosureInterestCalculationStrategy() .calculateTillRestFrequencyEnabled()) { LocalDate applicableDate = getNextRestScheduleDate(transactionDate.minusDays(1), loanApplicationTerms, holidayDetailDTO); checkForOutstanding = transactionDate.isEqual(applicableDate); } // reduces actual outstanding balance scheduleParams.reduceOutstandingBalance(unprocessed); // if outstanding balance becomes less than zero // then adjusts the princiapal Money addToPrinciapal = Money.zero(currency); if (!scheduleParams.getOutstandingBalance().isGreaterThanZero()) { addToPrinciapal = addToPrinciapal.plus(scheduleParams.getOutstandingBalance()); scheduleParams.setOutstandingBalance(Money.zero(currency)); currentPeriodParams.setLastInstallment(installment); } // updates principal portion map with the early // payment amounts and applicable date as per // rest updateAmountsBasedOnEarlyPayment(loanApplicationTerms, holidayDetailDTO, scheduleParams, installment, detail, unprocessed, addToPrinciapal); // method applies early payment strategy scheduleParams.addReducePrincipal(unprocessed); scheduleParams.setReducePrincipal(applyEarlyPaymentStrategy(loanApplicationTerms, scheduleParams.getReducePrincipal(), scheduleParams.getTotalCumulativePrincipal(), scheduleParams.getPeriodNumber(), mc)); } // identify late payments and add compounding // details to // map for interest calculation handleLatePayments(loanApplicationTerms, holidayDetailDTO, currency, scheduleParams, lastRestDate, periodStartDateApplicableForInterest, detail); if (updateLatePaymentMap) { updateLatePaymentsToMap(loanApplicationTerms, holidayDetailDTO, currency, scheduleParams.getLatePaymentMap(), scheduledDueDate, scheduleParams.getInstallments(), true, lastRestDate, scheduleParams.getCompoundingMap()); } } else if (scheduleParams.getLoanRepaymentScheduleTransactionProcessor() != null) { LocalDate applicableDate = getNextRestScheduleDate(transactionDate.minusDays(1), loanApplicationTerms, holidayDetailDTO); if (applicableDate.isBefore(scheduledDueDate)) { List<LoanTransaction> currentTransactions = createCurrentTransactionList(detail); Money unprocessed = scheduleParams.getLoanRepaymentScheduleTransactionProcessor() .handleRepaymentSchedule(currentTransactions, currency, scheduleParams.getInstallments()); Money arrears = fetchCompoundedArrears(loanApplicationTerms, currency, detail.getTransaction()); if (unprocessed.isGreaterThanZero()) { arrears = getTotalAmount(scheduleParams.getLatePaymentMap(), currency); updateMapWithAmount(scheduleParams.getPrincipalPortionMap(), unprocessed, applicableDate); currentPeriodParams.plusEarlyPaidAmount(unprocessed); // this check is to identify pre-closure and // apply interest calculation as per // configuration for non due date payments if (!scheduleParams.getOutstandingBalance().isGreaterThan(unprocessed) && !loanApplicationTerms.getPreClosureInterestCalculationStrategy() .calculateTillRestFrequencyEnabled()) { LocalDate calculateTill = transactionDate; if (!scheduleParams.getCompoundingDateVariations() .containsKey(periodStartDateApplicableForInterest)) { scheduleParams.getCompoundingDateVariations().put( periodStartDateApplicableForInterest, new TreeMap<>(scheduleParams.getCompoundingMap())); } 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, calculateTill, interestRates); if (!principalInterestForThisPeriod.interest() .plus(principalInterestForThisPeriod.interestPaymentDueToGrace()) .plus(scheduleParams.getOutstandingBalance()) .isGreaterThan(unprocessed)) { currentPeriodParams.minusEarlyPaidAmount(unprocessed); updateMapWithAmount(scheduleParams.getPrincipalPortionMap(), unprocessed.negated(), applicableDate); LoanTransaction loanTransaction = LoanTransaction.repayment(null, unprocessed, null, transactionDate, null, DateUtils.getLocalDateTimeOfTenant(), null); RecalculationDetail recalculationDetail = new RecalculationDetail( transactionDate, loanTransaction); unprocessedTransactions.add(recalculationDetail); break; } } LoanTransaction loanTransaction = LoanTransaction.repayment(null, unprocessed, null, scheduledDueDate, null, DateUtils.getLocalDateTimeOfTenant(), null); RecalculationDetail recalculationDetail = new RecalculationDetail(scheduledDueDate, loanTransaction); unprocessedTransactions.add(recalculationDetail); checkForOutstanding = false; scheduleParams.reduceOutstandingBalance(unprocessed); // if outstanding balance becomes less than // zero // then adjusts the princiapal Money addToPrinciapal = Money.zero(currency); if (scheduleParams.getOutstandingBalance().isLessThanZero()) { addToPrinciapal = addToPrinciapal.plus(scheduleParams.getOutstandingBalance()); scheduleParams.setOutstandingBalance(Money.zero(currency)); updateMapWithAmount(scheduleParams.getPrincipalPortionMap(), addToPrinciapal, applicableDate); currentPeriodParams.plusEarlyPaidAmount(addToPrinciapal); } } if (arrears.isGreaterThanZero() && applicableDate.isBefore(lastRestDate)) { handleLatePayments(loanApplicationTerms, holidayDetailDTO, currency, scheduleParams, lastRestDate, periodStartDateApplicableForInterest, detail); } } } } } applicableTransactions.addAll(unprocessedTransactions); if (checkForOutstanding && scheduleParams.getOutstandingBalance().isZero() && scheduleParams.getDisburseDetailMap().isEmpty()) { currentPeriodParams.setSkipCurrentLoop(true); } } }
From source file:org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AbstractLoanScheduleGenerator.java
License:Apache License
/** * calculates Interest stating date as per the settings * //from w w w . jav a2 s .c o m * @param firstRepaymentdate * TODO */ private LocalDate calculateInterestStartDateForPeriod(final LoanApplicationTerms loanApplicationTerms, LocalDate periodStartDate, final LocalDate idealDisbursementDate, final LocalDate firstRepaymentdate) { LocalDate periodStartDateApplicableForInterest = periodStartDate; if (periodStartDate.isBefore(idealDisbursementDate) || firstRepaymentdate.isAfter(periodStartDate)) { if (loanApplicationTerms.getInterestChargedFromLocalDate() != null) { if (periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate()) || loanApplicationTerms.getInterestChargedFromLocalDate().isAfter(periodStartDate)) { periodStartDateApplicableForInterest = loanApplicationTerms.getInterestChargedFromLocalDate(); } } else if (periodStartDate.isEqual(loanApplicationTerms.getExpectedDisbursementDate())) { periodStartDateApplicableForInterest = idealDisbursementDate; } } return periodStartDateApplicableForInterest; }
From source file:org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AbstractLoanScheduleGenerator.java
License:Apache License
private LoanScheduleDTO rescheduleNextInstallments(final MathContext mc, final LoanApplicationTerms loanApplicationTerms, final Set<LoanCharge> loanCharges, final HolidayDetailDTO holidayDetailDTO, final List<LoanTransaction> transactions, final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments, final LocalDate rescheduleFrom, final LocalDate scheduleTillDate) { // Loan transactions to process and find the variation on payments Collection<RecalculationDetail> recalculationDetails = new ArrayList<>(); for (LoanTransaction loanTransaction : transactions) { recalculationDetails.add(new RecalculationDetail(loanTransaction.getTransactionDate(), LoanTransaction.copyTransactionProperties(loanTransaction))); }// w w w. j a v a 2 s.c o m final boolean applyInterestRecalculation = loanApplicationTerms.isInterestRecalculationEnabled(); LoanScheduleParams loanScheduleParams = null; Collection<LoanScheduleModelPeriod> periods = new ArrayList<>(); final List<LoanRepaymentScheduleInstallment> retainedInstallments = new ArrayList<>(); // this block is to retain the schedule installments prior to the // provided date and creates late and early payment details for further // calculations if (rescheduleFrom != null) { Money principalToBeScheduled = getPrincipalToBeScheduled(loanApplicationTerms); // actual outstanding balance for interest calculation Money outstandingBalance = principalToBeScheduled; // total outstanding balance as per rest for interest calculation. Money outstandingBalanceAsPerRest = outstandingBalance; // this is required to update total fee amounts in the // LoanScheduleModel final BigDecimal chargesDueAtTimeOfDisbursement = deriveTotalChargesDueAtTimeOfDisbursement( loanCharges); periods = createNewLoanScheduleListWithDisbursementDetails( loanApplicationTerms.fetchNumberOfRepaymentsAfterExceptions(), loanApplicationTerms, chargesDueAtTimeOfDisbursement); final List<LoanRepaymentScheduleInstallment> newRepaymentScheduleInstallments = new ArrayList<>(); MonetaryCurrency currency = outstandingBalance.getCurrency(); // early payments will be added here and as per the selected // strategy // action will be performed on this value Money reducePrincipal = outstandingBalanceAsPerRest.zero(); // principal changes will be added along with date(after applying // rest) // from when these amounts will effect the outstanding balance for // interest calculation final Map<LocalDate, Money> principalPortionMap = new HashMap<>(); // compounding(principal) amounts will be added along with // date(after applying compounding frequency) // from when these amounts will effect the outstanding balance for // interest calculation final Map<LocalDate, Money> latePaymentMap = new HashMap<>(); // compounding(interest/Fee) amounts will be added along with // date(after applying compounding frequency) // from when these amounts will effect the outstanding balance for // interest calculation final TreeMap<LocalDate, Money> compoundingMap = new TreeMap<>(); LocalDate currentDate = DateUtils.getLocalDateOfTenant(); LocalDate lastRestDate = currentDate; if (loanApplicationTerms.getRestCalendarInstance() != null) { lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO); } LocalDate actualRepaymentDate = loanApplicationTerms.getExpectedDisbursementDate(); boolean isFirstRepayment = true; // cumulative fields Money totalCumulativePrincipal = principalToBeScheduled.zero(); Money totalCumulativeInterest = principalToBeScheduled.zero(); Money totalFeeChargesCharged = principalToBeScheduled.zero().plus(chargesDueAtTimeOfDisbursement); Money totalPenaltyChargesCharged = principalToBeScheduled.zero(); Money totalRepaymentExpected = principalToBeScheduled.zero(); // Actual period Number as per the schedule int periodNumber = 1; // Actual period Number plus interest only repayments int instalmentNumber = 1; LocalDate lastInstallmentDate = actualRepaymentDate; LocalDate periodStartDate = loanApplicationTerms.getExpectedDisbursementDate(); // Set fixed Amortization Amounts(either EMI or Principal ) updateAmortization(mc, loanApplicationTerms, periodNumber, outstandingBalance); final Map<LocalDate, Money> disburseDetailMap = new HashMap<>(); if (loanApplicationTerms.isMultiDisburseLoan()) { // fetches the first tranche amount and also updates other // tranche // details to map BigDecimal disburseAmt = getDisbursementAmount(loanApplicationTerms, loanApplicationTerms.getExpectedDisbursementDate(), periods, chargesDueAtTimeOfDisbursement, disburseDetailMap, true); outstandingBalance = outstandingBalance.zero().plus(disburseAmt); outstandingBalanceAsPerRest = outstandingBalance; principalToBeScheduled = principalToBeScheduled.zero().plus(disburseAmt); } int loanTermInDays = 0; // Block process the installment and creates the period if it falls // before reschedule from date // This will create the recalculation details by applying the // transactions for (LoanRepaymentScheduleInstallment installment : repaymentScheduleInstallments) { // this will generate the next schedule due date and allows to // process the installment only if recalculate from date is // greater than due date if (installment.getDueDate().isAfter(lastInstallmentDate)) { LocalDate previousRepaymentDate = actualRepaymentDate; actualRepaymentDate = this.scheduledDateGenerator.generateNextRepaymentDate(actualRepaymentDate, loanApplicationTerms, isFirstRepayment, holidayDetailDTO); isFirstRepayment = false; lastInstallmentDate = this.scheduledDateGenerator.adjustRepaymentDate(actualRepaymentDate, loanApplicationTerms, holidayDetailDTO); if (!lastInstallmentDate.isBefore(rescheduleFrom)) { actualRepaymentDate = previousRepaymentDate; break; } periodNumber++; // check for date changes while (loanApplicationTerms.getLoanTermVariations().hasDueDateVariation(lastInstallmentDate)) { LoanTermVariationsData variation = loanApplicationTerms.getLoanTermVariations() .nextDueDateVariation(); if (!variation.isSpecificToInstallment()) { actualRepaymentDate = variation.getDateValue(); } variation.setProcessed(true); } } for (Map.Entry<LocalDate, Money> disburseDetail : disburseDetailMap.entrySet()) { if (disburseDetail.getKey().isAfter(installment.getFromDate()) && !disburseDetail.getKey().isAfter(installment.getDueDate())) { // creates and add disbursement detail to the repayments // period final LoanScheduleModelDisbursementPeriod disbursementPeriod = LoanScheduleModelDisbursementPeriod .disbursement(disburseDetail.getKey(), disburseDetail.getValue(), chargesDueAtTimeOfDisbursement); periods.add(disbursementPeriod); // updates actual outstanding balance with new // disbursement detail outstandingBalance = outstandingBalance.plus(disburseDetail.getValue()); principalToBeScheduled = principalToBeScheduled.plus(disburseDetail.getValue()); } } // calculation of basic fields to start the schedule generation // from the middle periodStartDate = installment.getDueDate(); installment.resetDerivedComponents(); newRepaymentScheduleInstallments.add(installment); outstandingBalance = outstandingBalance.minus(installment.getPrincipal(currency)); final LoanScheduleModelPeriod loanScheduleModelPeriod = createLoanScheduleModelPeriod(installment, outstandingBalance); periods.add(loanScheduleModelPeriod); totalCumulativePrincipal = totalCumulativePrincipal.plus(installment.getPrincipal(currency)); totalCumulativeInterest = totalCumulativeInterest.plus(installment.getInterestCharged(currency)); totalFeeChargesCharged = totalFeeChargesCharged.plus(installment.getFeeChargesCharged(currency)); totalPenaltyChargesCharged = totalPenaltyChargesCharged .plus(installment.getPenaltyChargesCharged(currency)); instalmentNumber++; loanTermInDays = Days.daysBetween(installment.getFromDate(), installment.getDueDate()).getDays(); // populates the collection with transactions till the due date // of // the period for interest recalculation enabled loans Collection<RecalculationDetail> applicableTransactions = getApplicableTransactionsForPeriod( applyInterestRecalculation, installment.getDueDate(), recalculationDetails); // calculates the expected principal value for this repayment // schedule Money principalPortionCalculated = principalToBeScheduled.zero(); if (!installment.isRecalculatedInterestComponent()) { principalPortionCalculated = calculateExpectedPrincipalPortion( installment.getInterestCharged(currency), loanApplicationTerms); } // expected principal considering the previously paid excess // amount Money actualPrincipalPortion = principalPortionCalculated.minus(reducePrincipal); if (actualPrincipalPortion.isLessThanZero()) { actualPrincipalPortion = principalPortionCalculated.zero(); } Money unprocessed = updateEarlyPaidAmountsToMap(loanApplicationTerms, holidayDetailDTO, loanRepaymentScheduleTransactionProcessor, newRepaymentScheduleInstallments, currency, principalPortionMap, installment, applicableTransactions, actualPrincipalPortion); // this block is to adjust the period number based on the actual // schedule due date and installment due date // recalculatedInterestComponent installment shouldn't be // considered while calculating fixed EMI amounts int period = periodNumber; if (!lastInstallmentDate.isEqual(installment.getDueDate())) { period--; } reducePrincipal = fetchEarlyPaidAmount(installment.getPrincipal(currency), principalPortionCalculated, reducePrincipal, loanApplicationTerms, totalCumulativePrincipal, period, mc); // Updates principal paid map with efective date for reducing // the amount from outstanding balance(interest calculation) LocalDate amountApplicableDate = getNextRestScheduleDate(installment.getDueDate().minusDays(1), loanApplicationTerms, holidayDetailDTO); // updates map with the installment principal amount excluding // unprocessed amount since this amount is already accounted. updateMapWithAmount(principalPortionMap, installment.getPrincipal(currency).minus(unprocessed), amountApplicableDate); // update outstanding balance for interest calculation outstandingBalanceAsPerRest = updateBalanceForInterestCalculation(principalPortionMap, installment.getDueDate(), outstandingBalanceAsPerRest, false); outstandingBalanceAsPerRest = updateBalanceForInterestCalculation(disburseDetailMap, installment.getDueDate(), outstandingBalanceAsPerRest, true); } totalRepaymentExpected = totalCumulativePrincipal.plus(totalCumulativeInterest) .plus(totalFeeChargesCharged).plus(totalPenaltyChargesCharged); // updates the map with over due amounts updateLatePaymentsToMap(loanApplicationTerms, holidayDetailDTO, currency, latePaymentMap, lastInstallmentDate, newRepaymentScheduleInstallments, true, lastRestDate, compoundingMap); // for partial schedule generation if (!newRepaymentScheduleInstallments.isEmpty() && totalCumulativeInterest.isGreaterThanZero()) { Money totalOutstandingInterestPaymentDueToGrace = Money.zero(currency); loanScheduleParams = LoanScheduleParams.createLoanScheduleParamsForPartialUpdate(periodNumber, instalmentNumber, loanTermInDays, periodStartDate, actualRepaymentDate, totalCumulativePrincipal, totalCumulativeInterest, totalFeeChargesCharged, totalPenaltyChargesCharged, totalRepaymentExpected, totalOutstandingInterestPaymentDueToGrace, reducePrincipal, principalPortionMap, latePaymentMap, compoundingMap, disburseDetailMap, principalToBeScheduled, outstandingBalance, outstandingBalanceAsPerRest, newRepaymentScheduleInstallments, recalculationDetails, loanRepaymentScheduleTransactionProcessor, scheduleTillDate, currency, applyInterestRecalculation); retainedInstallments.addAll(newRepaymentScheduleInstallments); } } // for complete schedule generation if (loanScheduleParams == null) { loanScheduleParams = LoanScheduleParams.createLoanScheduleParamsForCompleteUpdate(recalculationDetails, loanRepaymentScheduleTransactionProcessor, scheduleTillDate, applyInterestRecalculation); } LoanScheduleModel loanScheduleModel = generate(mc, loanApplicationTerms, loanCharges, holidayDetailDTO, loanScheduleParams); for (LoanScheduleModelPeriod loanScheduleModelPeriod : loanScheduleModel.getPeriods()) { if (loanScheduleModelPeriod.isRepaymentPeriod()) { // adding newly created repayment periods to installments addLoanRepaymentScheduleInstallment(retainedInstallments, loanScheduleModelPeriod); } } periods.addAll(loanScheduleModel.getPeriods()); LoanScheduleModel loanScheduleModelwithPeriodChanges = LoanScheduleModel .withLoanScheduleModelPeriods(periods, loanScheduleModel); return LoanScheduleDTO.from(retainedInstallments, loanScheduleModelwithPeriodChanges); }
From source file:org.datacleaner.beans.DateAndTimeAnalyzerColumnDelegate.java
License:Open Source License
public synchronized void run(final Date value, final InputRow row, final int distinctCount) { _numRows += distinctCount;/* w w w . j a va 2 s . c om*/ if (value == null) { _annotationFactory.annotate(row, distinctCount, _nullAnnotation); } else { final long timestamp = value.getTime(); for (int i = 0; i < distinctCount; i++) { if (_statistics instanceof DescriptiveStatistics) { ((DescriptiveStatistics) _statistics).addValue(timestamp); } else { ((SummaryStatistics) _statistics).addValue(timestamp); } } LocalDate localDate = new LocalDate(value); LocalTime localTime = new LocalTime(value); if (_minDate == null) { // first non-null value _minDate = localDate; _maxDate = localDate; _minTime = localTime; _maxTime = localTime; } else { if (localDate.isAfter(_maxDate)) { _maxDate = localDate; _annotationFactory.resetAnnotation(_maxDateAnnotation); } else if (localDate.isBefore(_minDate)) { _minDate = localDate; _annotationFactory.resetAnnotation(_minDateAnnotation); } if (localTime.isAfter(_maxTime)) { _maxTime = localTime; _annotationFactory.resetAnnotation(_maxTimeAnnotation); } else if (localTime.isBefore(_minTime)) { _minTime = localTime; _annotationFactory.resetAnnotation(_minTimeAnnotation); } } if (localDate.isEqual(_maxDate)) { _annotationFactory.annotate(row, distinctCount, _maxDateAnnotation); } if (localDate.isEqual(_minDate)) { _annotationFactory.annotate(row, distinctCount, _minDateAnnotation); } if (localTime.isEqual(_maxTime)) { _annotationFactory.annotate(row, distinctCount, _maxTimeAnnotation); } if (localTime.isEqual(_minTime)) { _annotationFactory.annotate(row, distinctCount, _minTimeAnnotation); } } }