Example usage for org.joda.time LocalDate isEqual

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

Introduction

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

Prototype

public boolean isEqual(ReadablePartial partial) 

Source Link

Document

Is this partial the same as the specified partial.

Usage

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);
        }
    }
}