Example usage for org.joda.time Interval getEnd

List of usage examples for org.joda.time Interval getEnd

Introduction

In this page you can find the example usage for org.joda.time Interval getEnd.

Prototype

public DateTime getEnd() 

Source Link

Document

Gets the end of this time interval, which is exclusive, as a DateTime.

Usage

From source file:org.jevis.commons.dataprocessing.processor.ImpulsProcessor.java

License:Open Source License

@Override
public List<JEVisSample> getResult(Task mainTask) {
    List<JEVisSample> result = new ArrayList<>();

    if (mainTask.getSubTasks().size() > 1) {
        System.out.println("Impuscleaner cannot work with more than one imput, using first only.");
    } else if (mainTask.getSubTasks().size() < 1) {
        System.out.println("Impuscleaner, no input nothing to do");
    }/*from ww  w . j ava  2  s.  c om*/

    List<JEVisSample> samples = mainTask.getSubTasks().get(0).getResult();

    DateTime firstTS = DateTime.now();
    DateTime lastTS = DateTime.now();
    try {
        firstTS = samples.get(0).getTimestamp();
        lastTS = samples.get(samples.size()).getTimestamp();
    } catch (JEVisException ex) {
        Logger.getLogger(ImpulsProcessor.class.getName()).log(Level.SEVERE, null, ex);
    }

    List<Interval> intervals = Options.getIntervals(mainTask, firstTS, lastTS);

    int lastPos = 0;
    for (Interval interval : intervals) {
        List<JEVisSample> samplesInPeriod = new ArrayList<>();

        for (int i = lastPos; i < samples.size(); i++) {
            try {
                if (interval.contains(samples.get(i).getTimestamp())) {
                    //                        System.out.println("add sample: " + samples.get(i));
                    samplesInPeriod.add(samples.get(i));
                } else if (samples.get(i).getTimestamp().isAfter(interval.getEnd())) {
                    lastPos = i;
                    break;
                }
            } catch (JEVisException ex) {
                System.out.println("JEVisExeption while going trou sample: " + ex.getMessage());
            }
        }

        //TODO: thi sis an dummy for 
        JEVisSample bestmatch = null;
        for (JEVisSample sample : samplesInPeriod) {

            long bestDiff = 99999999999999999l;
            try {
                long middelMili = ((interval.getEndMillis() - interval.getStartMillis()) / 2)
                        + interval.getStartMillis();
                long diff = Math.abs(sample.getTimestamp().getMillis() - middelMili);
                //                    System.out.println("Diff for: " + sample.getTimestamp() + "      -> " + diff);

                if (bestmatch != null) {
                    if (bestDiff < diff) {
                        bestDiff = diff;
                        bestmatch = sample;
                    }
                } else {
                    bestmatch = sample;
                    bestDiff = diff;
                }

            } catch (JEVisException ex) {
                System.out.println("JEVisExeption while going trou sample2: " + ex.getMessage());
            }
        }
        if (bestmatch != null) {
            System.out.println("Best match: " + bestmatch);
            result.add(bestmatch);
        }
    }

    return result;
}

From source file:org.jevis.commons.dataprocessing.processor.ImpulsProcessor.java

License:Open Source License

public List<JEVisSample> getResult(Options options, List<List<JEVisSample>> allSamples) {
    List<JEVisSample> result = new ArrayList<>();
    for (List<JEVisSample> samples : allSamples) {

        try {/*w ww. j  a  v a  2s . c  om*/
            _durations = Options.buildIntervals(Period.minutes(15), _offset, samples.get(0).getTimestamp(),
                    samples.get(samples.size() - 1).getTimestamp());
        } catch (JEVisException ex) {
            Logger.getLogger(ImpulsProcessor.class.getName()).log(Level.SEVERE, null, ex);
        }

        //Samples list is sorted by default
        int lastPos = 0;
        for (Interval interval : _durations) {
            //            System.out.println("Interval: " + interval);
            List<JEVisSample> samplesInPeriod = new ArrayList<>();

            for (int i = lastPos; i < samples.size(); i++) {
                try {
                    if (interval.contains(samples.get(i).getTimestamp())) {
                        //                        System.out.println("add sample: " + samples.get(i));
                        samplesInPeriod.add(samples.get(i));
                    } else if (samples.get(i).getTimestamp().isAfter(interval.getEnd())) {
                        lastPos = i;
                        break;
                    }
                } catch (JEVisException ex) {
                    System.out.println("JEVisExeption while going trou sample: " + ex.getMessage());
                }
            }

            //TODO: thi sis an dummy for 
            JEVisSample bestmatch = null;
            for (JEVisSample sample : samplesInPeriod) {

                long bestDiff = 99999999999999999l;
                try {
                    long middelMili = ((interval.getEndMillis() - interval.getStartMillis()) / 2)
                            + interval.getStartMillis();
                    long diff = Math.abs(sample.getTimestamp().getMillis() - middelMili);
                    //                    System.out.println("Diff for: " + sample.getTimestamp() + "      -> " + diff);

                    if (bestmatch != null) {
                        if (bestDiff < diff) {
                            bestDiff = diff;
                            bestmatch = sample;
                        }
                    } else {
                        bestmatch = sample;
                        bestDiff = diff;
                    }

                } catch (JEVisException ex) {
                    System.out.println("JEVisExeption while going trou sample2: " + ex.getMessage());
                }
            }
            if (bestmatch != null) {
                System.out.println("Best match: " + bestmatch);
                result.add(bestmatch);
            }

        }

    }
    return result;
}

From source file:org.kalypso.ogc.sensor.filter.filters.interval.IntervalAxesValues.java

License:Open Source License

public Object[] asValueTuple(final IntervalData data, final ITupleModel model) throws SensorException {
    final Object[] tuple = new Object[m_axes.length];
    final Interval interval = data.getInterval();
    final Date key = interval.getEnd().toDate();

    final int datePos = model.getPosition(m_dateAxis);
    tuple[datePos] = key;//from   w  w  w.j  a  v a2s . co  m

    final TupleModelDataSet[] dataSets = data.getDataSets();
    for (final TupleModelDataSet dataSet : dataSets) {
        final IAxis valueAxis = dataSet.getValueAxis();
        final int valuePosition = model.getPosition(valueAxis);
        tuple[valuePosition] = dataSet.getValue();

        final IAxis statusAxis = getStatusAxis(valueAxis);
        setModelValue(statusAxis, model, tuple, dataSet.getStatus());

        final IAxis dataSourcesAxes = getDataSourcesAxes(valueAxis);
        final int dataSourceIndex = m_sourceHandler.addDataSource(dataSet.getSource(), dataSet.getSource());
        setModelValue(dataSourcesAxes, model, tuple, dataSourceIndex);
    }

    return tuple;
}

From source file:org.kalypso.ui.rrm.internal.calccase.MultiCatchmentModelRunner.java

License:Open Source License

/**
 * This function runs the linear sum generator.
 * /*from   w  ww. ja  v a2  s . co  m*/
 * @param prefix
 *          This prefix is used when writing the timeseries.
 * @param simulation
 *          The simulation.
 * @param control
 *          The na control.
 * @param model
 *          The na model.
 * @param generator
 *          The rainfall generator.
 * @param targetLink
 *          The target link.
 * @param parameterType
 *          The parameter type.
 * @param hash
 *          The hash.
 * @param monitor
 *          A progress monitor.
 */
private void runGenerator(final String prefix, final RrmSimulation simulation, final NAControl control,
        final NaModell model, final ILinearSumGenerator generator, final QName targetLink,
        final String parameterType, final CatchmentTimeseriesHash hash, final IProgressMonitor monitor)
        throws Exception {
    try {
        /* Monitor. */
        monitor.beginTask(
                String.format(Messages.getString("MultiCatchmentModelRunner_7"), generator.getDescription()), //$NON-NLS-1$
                1000);
        monitor.subTask(Messages.getString("MultiCatchmentModelRunner_8")); //$NON-NLS-1$

        /* This object can calculate some values. */
        final LinearSumCatchmentModelInfo linearInfo = new LinearSumCatchmentModelInfo(simulation, control,
                model, generator, targetLink, parameterType);

        /* Get the timestep and timestamp. */
        final Period timestep = linearInfo.getTimestep();
        final LocalTime timestamp = linearInfo.getTimestamp();

        /* HINT: The range is the adjusted simulation range. */
        final DateRange simulationRange = linearInfo.getSimulationRange();

        /* Intersect adjusted simulation range with validity range of generator. */
        final Interval simulationInterval = new Interval(new DateTime(simulationRange.getFrom()),
                new DateTime(simulationRange.getTo()));

        /* Calculate range of current generator. */
        final Interval validityInterval = new Interval(new DateTime(generator.getValidFrom()),
                new DateTime(generator.getValidTo()));

        /* Intersect complete simulation with this generator, only this range will be calculated. */
        final Interval interval = validityInterval.overlap(simulationInterval);

        // FIXME: The intersected interval does now NOT cover the extended range (3 steps before, 1 step after).
        // So the complete result does NOT cover the extended range.

        final DateRange range = new DateRange(interval.getStart().toDate(), interval.getEnd().toDate());

        /* The catchment model runner should be executed with this generic info. */
        final ICatchmentModelInfo genericInfo = new GenericCatchmentModelInfo(simulation, control, model,
                generator, targetLink, parameterType, timestep, timestamp, range, range);

        /* Create the linear sum catchment model runner. */
        final LinearSumCatchmentModelRunner runner = new LinearSumCatchmentModelRunner(prefix);

        /* Calculate the catchment model. */
        runner.executeCatchmentModel(genericInfo, new SubProgressMonitor(monitor, 500));

        /* Get the catchments. */
        final IFeatureBindingCollection<Catchment> catchments = model.getCatchments();
        for (final Catchment catchment : catchments) {
            /* The feature id of the catchment must be unique. */
            final String id = catchment.getId();

            /* Get the link of the timeseries. */
            ZmlLink link = null;
            if (parameterType.equals(ITimeseriesConstants.TYPE_RAINFALL))
                link = catchment.getPrecipitationLink();
            else if (parameterType.equals(ITimeseriesConstants.TYPE_EVAPORATION_LAND_BASED))
                link = catchment.getEvaporationLink();
            else if (parameterType.equals(ITimeseriesConstants.TYPE_MEAN_TEMPERATURE))
                link = catchment.getTemperatureLink();
            else
                throw new IllegalArgumentException(Messages.getString("MultiCatchmentModelRunner_9")); //$NON-NLS-1$

            /* Store the timeseries link. */
            hash.put(id, link.getTimeseriesLink());
        }

        /* Monitor. */
        monitor.worked(500);
    } finally {
        /* Monitor. */
        monitor.done();
    }
}

From source file:org.kalypso.ui.rrm.internal.timeseries.view.actions.MergeTimeseriesOperation.java

License:Open Source License

private void validateTimeseries(final DateRange baseRange, final Period baseTimestep,
        final DateRange importRange, final Period importTimestep) throws CoreException {
    /* The timesteps must be equal. */
    final Minutes baseMinutes = baseTimestep.toStandardMinutes();
    final Minutes importMinutes = importTimestep.toStandardMinutes();
    if (baseMinutes.getMinutes() != importMinutes.getMinutes())
        throw new CoreException(new Status(IStatus.ERROR, KalypsoUIRRMPlugin.getID(),
                String.format(Messages.getString("MergeTimeseriesOperation.0"), baseTimestep.toString(), //$NON-NLS-1$
                        importTimestep.toString())));

    /* Create the intervals. */
    final Interval baseInterval = new Interval(new DateTime(baseRange.getFrom()),
            new DateTime(baseRange.getTo()));
    final Interval importInterval = new Interval(new DateTime(importRange.getFrom()),
            new DateTime(importRange.getTo()));

    /* Is the base range before the import range? */
    /* Only a gap with one timestep is allowed. */
    if (baseInterval.isBefore(importInterval)) {
        final DateTime baseEnd = baseInterval.getEnd();
        final DateTime importStart = importInterval.getStart();

        final Period gap = new Period(baseEnd, importStart);
        final Minutes gapMinutes = gap.toStandardMinutes();
        if (gapMinutes.getMinutes() > 0 && baseMinutes.getMinutes() != gapMinutes.getMinutes())
            throw new CoreException(new Status(IStatus.ERROR, KalypsoUIRRMPlugin.getID(),
                    String.format(Messages.getString("MergeTimeseriesOperation.1"), baseMinutes.toString(), //$NON-NLS-1$
                            gapMinutes.toString())));
    }//  ww w.j  a  v a  2 s  . co  m

    /* Is the base range after the import range? */
    /* Only a gap with one timestep is allowed. */
    if (baseInterval.isAfter(importInterval)) {
        final DateTime importEnd = importInterval.getEnd();
        final DateTime baseStart = baseInterval.getStart();

        final Period gap = new Period(importEnd, baseStart);
        final Minutes gapMinutes = gap.toStandardMinutes();
        if (gapMinutes.getMinutes() > 0 && baseMinutes.getMinutes() != gapMinutes.getMinutes())
            throw new CoreException(new Status(IStatus.ERROR, KalypsoUIRRMPlugin.getID(),
                    String.format(Messages.getString("MergeTimeseriesOperation.1"), baseMinutes.toString(), //$NON-NLS-1$
                            gapMinutes.toString())));
    }

    /* Here the intervals touch or overlap. */
}

From source file:org.kuali.kpme.tklm.leave.accrual.bucket.KPMEAccrualCategoryBucket.java

License:Educational Community License

private void adjustAsOfDates(CalendarEntry calendarEntry, List<CalendarEntry> calendarEntries) {

    LocalDate newAsOfDate = null;

    //determine if the bucket is being switched to the current leave year
    //also compute max end date to determine if the bucket is being switched to a future leave year. ( could use leave plan service's getRollOverDate )
    boolean switchingToCurrentLeaveYear = false;
    LocalDate maxEndDate = LocalDate.now();
    for (CalendarEntry entry : calendarEntries) {
        if (entry.getHrCalendarEntryId().equals(calendarEntry.getHrCalendarEntryId())
                && entry.getHrCalendarId().equals(calendarEntry.getHrCalendarId())) {
            switchingToCurrentLeaveYear = true;
        }/*from   w  ww  .j  ava 2  s . com*/
        if (entry.getEndPeriodDate().after(maxEndDate.toDate()))
            maxEndDate = LocalDate.fromDateFields(entry.getEndPeriodDate());
    }

    if (switchingToCurrentLeaveYear) {
        Interval otherCalendarInterval = new Interval(calendarEntry.getBeginPeriodDate().getTime(),
                calendarEntry.getEndPeriodDate().getTime());
        if (otherCalendarInterval.contains(LocalDate.now().toDate().getTime())) {
            //switching to the present calendar.
            newAsOfDate = LocalDate.now();
        } else if (otherCalendarInterval.getEnd().isBefore(LocalDate.now().toDate().getTime())) {
            //switching to a historical calendar in the current leave plan year, use calendar end date
            newAsOfDate = otherCalendarInterval.getEnd().toLocalDate().minusDays(1);
        } else {
            //switching to a future/planning calendar in the current leave plan year, use calendar start date.
            newAsOfDate = otherCalendarInterval.getStart().toLocalDate().minusDays(1);
        }
    } else if (calendarEntry.getEndPeriodDate().after(maxEndDate.toDate())) {
        //switching to a leave year beyond the current leave year, same as future/planning calendar in current leave year.
        newAsOfDate = LocalDate.fromDateFields(calendarEntry.getBeginPeriodDate()).minusDays(1);
    } else {
        //switching to a calendar period within a past leave calendar year.
        DateTime otherCalendarRolloverDate = HrServiceLocator.getLeavePlanService().getRolloverDayOfLeavePlan(
                principalCalendar.getLeavePlan(), LocalDate.fromDateFields(calendarEntry.getEndPeriodDate()));
        //for past leave calendar years, regardless of calendar period, we require values as of the rollover day.
        newAsOfDate = LocalDate.fromDateFields(otherCalendarRolloverDate.toDate()).minusDays(1);
    }

    //update asOfDates and calendar period end point dates for all leave balance objects
    for (Entry<String, List<LeaveBalance>> entry : leaveBalances.entrySet()) {
        for (LeaveBalance leaveBalance : entry.getValue()) {
            leaveBalance.asOfDate = newAsOfDate;
            leaveBalance.calendarPeriodBeginDate = LocalDate.fromDateFields(calendarEntry.getBeginPeriodDate());
            leaveBalance.calendarPeriodEndDate = LocalDate.fromDateFields(calendarEntry.getEndPeriodDate());
        }
    }

    //reset this buckets asOfDate
    asOfDate = newAsOfDate;

}

From source file:org.kuali.kpme.tklm.leave.block.LeaveBlockAggregate.java

License:Educational Community License

/**
 *  build leaveBlockAggregate with given leaveBlocks, calendarEntry and dayIntervals
 *  dayIntervals with full week span is for Time Calendar
 * @param LeaveBlocks//from   w ww .j  a v a 2s . c  o  m
 * @param leaveCalendarEntry
 * @param dayIntervals
 */
public LeaveBlockAggregate(List<LeaveBlock> leaveBlocks, CalendarEntry leaveCalendarEntry,
        List<Interval> dayIntervals) {
    this.leaveCalendarEntry = leaveCalendarEntry;
    for (Interval dayInt : dayIntervals) {
        List<LeaveBlock> dayLeaveBlocks = new ArrayList<LeaveBlock>();
        DateTime localTime = dayInt.getStart().toLocalDateTime().toDateTime();
        String intervalStartDateString = localTime.toLocalDate().toString();

        for (LeaveBlock leaveBlock : leaveBlocks) {
            // if the interval end time is 0, ie the beginning of a day, use the date string of the interval start time
            // to check if the leave block should go into this interval. Leave blocks only have leaveDate, there's no leave time
            if (dayInt.getEnd().getHourOfDay() == 0) {
                String lbDateString = leaveBlock.getLeaveLocalDate().toString();
                if (intervalStartDateString.equals(lbDateString)) {
                    dayLeaveBlocks.add(leaveBlock);
                }
            } else {
                LocalDate localDate = leaveBlock.getLeaveLocalDate();
                LocalDate dayIntBegin = dayInt.getStart().toLocalDate();
                if (localDate.equals(dayIntBegin)) {
                    dayLeaveBlocks.add(leaveBlock);
                }
            }
        }
        dayLeaveBlockList.add(dayLeaveBlocks);
    }
}

From source file:org.kuali.kpme.tklm.leave.block.service.LeaveBlockServiceImpl.java

License:Educational Community License

@Override
public void addLeaveBlocks(DateTime beginDate, DateTime endDate, CalendarEntry ce, String selectedEarnCode,
        BigDecimal hours, String description, Assignment selectedAssignment, String spanningWeeks,
        String leaveBlockType, String principalId) {

    DateTimeZone timezone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
    DateTime calBeginDateTime = beginDate;
    DateTime calEndDateTime = endDate;// w  ww.  j a  va2s .  c om

    if (ce != null) {
        calBeginDateTime = ce.getBeginPeriodLocalDateTime().toDateTime();
        calEndDateTime = ce.getEndPeriodLocalDateTime().toDateTime();
    } else {
        LOG.error("Calendar Entry parameter is null.");
        return;
        //          throw new RuntimeException("Calendar Entry parameter is null.");
    }

    Interval calendarInterval = new Interval(calBeginDateTime, calEndDateTime);

    // To create the correct interval by the given begin and end dates,
    // we need to plus one day on the end date to include that date
    List<Interval> leaveBlockIntervals = TKUtils.createDaySpan(beginDate.toLocalDate().toDateTimeAtStartOfDay(),
            endDate.toLocalDate().toDateTimeAtStartOfDay().plusDays(1), TKUtils.getSystemDateTimeZone());

    // need to use beginDate and endDate of the calendar to find all leaveBlocks since LeaveCalendarDocument Id is not always available
    List<LeaveBlock> currentLeaveBlocks = getLeaveBlocks(principalId, calBeginDateTime.toLocalDate(),
            calEndDateTime.toLocalDate());

    // use the current calendar's begin and end date to figure out if this pay period has a leaveDocument
    LeaveCalendarDocumentHeader lcdh = LmServiceLocator.getLeaveCalendarDocumentHeaderService()
            .getDocumentHeader(principalId, ce.getBeginPeriodLocalDateTime().toDateTime(),
                    ce.getEndPeriodLocalDateTime().toDateTime());
    String docId = lcdh == null ? null : lcdh.getDocumentId();

    // TODO: need to integrate with the scheduled timeoff.
    Interval firstDay = null;
    DateTime currentDate = beginDate;
    for (Interval leaveBlockInt : leaveBlockIntervals) {
        if (calendarInterval.contains(leaveBlockInt)) {
            // KPME-1446 if "Include weekends" check box is checked, don't add Sat and Sun to the leaveblock list
            if (StringUtils.isEmpty(spanningWeeks)
                    && (leaveBlockInt.getStart().getDayOfWeek() == DateTimeConstants.SATURDAY
                            || leaveBlockInt.getStart().getDayOfWeek() == DateTimeConstants.SUNDAY)) {

                // do nothing
            } else {

                // Currently, we store the accrual category value in the leave code table, but store accrual category id in the leaveBlock.
                // That's why there is a two step server call to get the id. This might be changed in the future.

                CalendarEntry calendarEntry = HrServiceLocator.getCalendarEntryService()
                        .getCurrentCalendarEntryByCalendarId(ce.getHrCalendarId(),
                                new LocalDate().toDateTimeAtStartOfDay());
                DateTime leaveBlockDate = leaveBlockInt.getStart();

                String requestStatus = HrConstants.REQUEST_STATUS.USAGE;
                if (LmServiceLocator.getLeaveApprovalService().isActiveAssignmentFoundOnJobFlsaStatus(
                        principalId, HrConstants.FLSA_STATUS_NON_EXEMPT, true)) {
                    TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService()
                            .getDocumentHeaderForDate(principalId, leaveBlockDate);
                    if (tdh != null) {
                        if (DateUtils.isSameDay(leaveBlockDate.toDate(), tdh.getEndDate())
                                || leaveBlockDate.isAfter(tdh.getEndDateTime())) {
                            requestStatus = HrConstants.REQUEST_STATUS.PLANNED;
                        }
                    } else {
                        requestStatus = HrConstants.REQUEST_STATUS.PLANNED;
                    }
                } else {
                    if (DateUtils.isSameDay(leaveBlockDate.toDate(), calendarEntry.getEndPeriodDateTime())
                            || leaveBlockDate.isAfter(calendarEntry.getEndPeriodFullDateTime())) {
                        requestStatus = HrConstants.REQUEST_STATUS.PLANNED;
                    }
                }

                EarnCode earnCodeObj = HrServiceLocator.getEarnCodeService().getEarnCode(selectedEarnCode,
                        ce.getEndPeriodLocalDateTime().toDateTime().toLocalDate());

                if (earnCodeObj != null
                        && earnCodeObj.getRecordMethod().equals(HrConstants.RECORD_METHOD.TIME)) {
                    if (firstDay != null) {
                        if (!leaveBlockInt.contains(endDate)) {
                            currentDate = leaveBlockInt.getStart();
                        } else if ((leaveBlockInt.getStartMillis() - endDate.getMillis()) != 0) {

                            hours = TKUtils.getHoursBetween(leaveBlockInt.getStartMillis(),
                                    endDate.getMillis());
                            hours = negateHoursIfNecessary(leaveBlockType, hours);

                            LeaveBlock leaveBlock = buildLeaveBlock(leaveBlockInt.getStart().toLocalDate(),
                                    docId, principalId, selectedEarnCode, hours, description,
                                    earnCodeObj.getAccrualCategory(), selectedAssignment, requestStatus,
                                    leaveBlockType, leaveBlockInt.getStart(), endDate);

                            if (!currentLeaveBlocks.contains(leaveBlock)) {
                                currentLeaveBlocks.add(leaveBlock);
                            }
                            break;
                        }
                    }
                    if (leaveBlockInt.contains(currentDate)) {

                        firstDay = leaveBlockInt;

                        if (leaveBlockInt.contains(endDate)
                                || (endDate.getMillis() == leaveBlockInt.getEnd().getMillis())) {

                            hours = TKUtils.getHoursBetween(currentDate.getMillis(), endDate.getMillis());
                            hours = negateHoursIfNecessary(leaveBlockType, hours);

                            LeaveBlock leaveBlock = buildLeaveBlock(leaveBlockInt.getStart().toLocalDate(),
                                    docId, principalId, selectedEarnCode, hours, description,
                                    earnCodeObj.getAccrualCategory(), selectedAssignment, requestStatus,
                                    leaveBlockType, currentDate, endDate);

                            if (!currentLeaveBlocks.contains(leaveBlock)) {
                                currentLeaveBlocks.add(leaveBlock);
                            }

                            break;

                        } else {
                            // create a leave block that wraps the 24 hr day
                            hours = TKUtils.getHoursBetween(currentDate.getMillis(), firstDay.getEndMillis());
                            hours = negateHoursIfNecessary(leaveBlockType, hours);

                            LeaveBlock leaveBlock = buildLeaveBlock(leaveBlockInt.getStart().toLocalDate(),
                                    docId, principalId, selectedEarnCode, hours, description,
                                    earnCodeObj.getAccrualCategory(), selectedAssignment, requestStatus,
                                    leaveBlockType, currentDate, firstDay.getEnd());

                            if (!currentLeaveBlocks.contains(leaveBlock)) {
                                currentLeaveBlocks.add(leaveBlock);
                            }

                        }
                    }
                } else {
                    hours = negateHoursIfNecessary(leaveBlockType, hours);
                    LeaveBlock leaveBlock = buildLeaveBlock(leaveBlockInt.getStart().toLocalDate(), docId,
                            principalId, selectedEarnCode, hours, description, earnCodeObj.getAccrualCategory(),
                            selectedAssignment, requestStatus, leaveBlockType, null, null);
                    if (!currentLeaveBlocks.contains(leaveBlock)) {
                        currentLeaveBlocks.add(leaveBlock);
                    }
                }
            }
        }
    }
    saveLeaveBlocks(currentLeaveBlocks);
}

From source file:org.kuali.kpme.tklm.leave.summary.service.LeaveSummaryServiceImpl.java

License:Educational Community License

@Override
public List<Date> getLeaveSummaryDates(CalendarEntry calendarEntry) {
    List<Date> leaveSummaryDates = new ArrayList<Date>();

    DateTime start = calendarEntry.getBeginPeriodLocalDateTime().toDateTime();
    DateTime end = calendarEntry.getEndPeriodLocalDateTime().toDateTime();
    Interval interval = new Interval(start, end);

    for (DateTime day = interval.getStart(); day.isBefore(interval.getEnd()); day = day.plusDays(1)) {
        leaveSummaryDates.add(day.toLocalDate().toDateTimeAtStartOfDay().toDate());
    }// w  w  w .  j av a 2s  . com

    return leaveSummaryDates;
}

From source file:org.kuali.kpme.tklm.time.rules.shiftdifferential.service.ShiftDifferentialRuleServiceImpl.java

License:Educational Community License

@Override
public void processShiftDifferentialRules(TimesheetDocument timesheetDocument, TkTimeBlockAggregate aggregate) {
    DateTimeZone zone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
    List<List<TimeBlock>> blockDays = aggregate.getDayTimeBlockList();
    DateTime periodStartDateTime = timesheetDocument.getCalendarEntry().getBeginPeriodLocalDateTime()
            .toDateTime(zone);//ww w  . ja va2 s.  c om
    Map<Long, Set<ShiftDifferentialRule>> jobNumberToShifts = getJobNumberToShiftRuleMap(timesheetDocument);

    // If there are no shift differential rules, we have an early exit.
    if (jobNumberToShifts.isEmpty()) {
        return;
    }

    // Get the last day of the previous pay period. We need this to determine
    // if there are hours from the previous pay period that will effect the
    // shift rule on the first day of the currently-being-processed pay period.
    //
    // Will be set to null if not applicable.
    boolean previousPayPeriodPrevDay = true;
    Map<Long, List<TimeBlock>> jobNumberToTimeBlocksPreviousDay = getPreviousPayPeriodLastDayJobToTimeBlockMap(
            timesheetDocument, jobNumberToShifts);

    // We are going to look at the time blocks grouped by Days.
    //
    // This is a very large outer loop.
    for (int pos = 0; pos < blockDays.size(); pos++) {
        List<TimeBlock> blocks = blockDays.get(pos); // Timeblocks for this day.
        if (blocks.isEmpty())
            continue; // No Time blocks, no worries.

        DateTime currentDay = periodStartDateTime.plusDays(pos);
        Interval virtualDay = new Interval(currentDay, currentDay.plusHours(24));

        // Builds our JobNumber to TimeBlock for Current Day List.
        //
        // Shift Differential Rules are also grouped by Job number, this
        // provides a quick way to do the lookup / reference.
        // We don't need every time block, only the ones that will be
        // applicable to the shift rules.
        Map<Long, List<TimeBlock>> jobNumberToTimeBlocks = new HashMap<Long, List<TimeBlock>>();
        for (TimeBlock block : blocks) {
            Long jobNumber = block.getJobNumber();
            if (jobNumberToShifts.containsKey(jobNumber)) {
                List<TimeBlock> jblist = jobNumberToTimeBlocks.get(jobNumber);
                if (jblist == null) {
                    jblist = new ArrayList<TimeBlock>();
                    jobNumberToTimeBlocks.put(jobNumber, jblist);
                }
                jblist.add(block);
            }
        }

        // Large Outer Loop to look at applying the Shift Rules based on
        // the current JobNumber.
        //
        // This loop will handle previous day boundary time as well as the
        // current day.
        //
        // There is room for refactoring here!
        for (Map.Entry<Long, Set<ShiftDifferentialRule>> entry : jobNumberToShifts.entrySet()) {
            Set<ShiftDifferentialRule> shiftDifferentialRules = entry.getValue();
            // Obtain and sort our previous and current time blocks.
            List<TimeBlock> ruleTimeBlocksPrev = null;
            List<TimeBlock> ruleTimeBlocksCurr = jobNumberToTimeBlocks.get(entry.getKey());
            if (ruleTimeBlocksCurr != null && ruleTimeBlocksCurr.size() > 0) {
                if (jobNumberToTimeBlocksPreviousDay != null)
                    ruleTimeBlocksPrev = jobNumberToTimeBlocksPreviousDay.get(entry.getKey());
                if (ruleTimeBlocksPrev != null && ruleTimeBlocksPrev.size() > 0)
                    this.sortTimeBlocksInverse(ruleTimeBlocksPrev);
                this.sortTimeBlocksNatural(ruleTimeBlocksCurr);
            } else {
                // Skip to next job, there is nothing for this job
                // on this day, and because of this we don't care
                // about the previous day either.
                continue;
            }

            for (ShiftDifferentialRule rule : shiftDifferentialRules) {
                Set<String> fromEarnGroup = HrServiceLocator.getEarnCodeGroupService()
                        .getEarnCodeListForEarnCodeGroup(rule.getFromEarnGroup(), timesheetDocument
                                .getCalendarEntry().getBeginPeriodFullDateTime().toLocalDate());

                LocalTime ruleStart = new LocalTime(rule.getBeginTime(), zone);
                LocalTime ruleEnd = new LocalTime(rule.getEndTime(), zone);

                DateTime shiftEnd = ruleEnd.toDateTime(currentDay);
                DateTime shiftStart = ruleStart.toDateTime(currentDay);

                if (shiftEnd.isBefore(shiftStart) || shiftEnd.isEqual(shiftStart)) {
                    shiftEnd = shiftEnd.plusDays(1);
                }
                Interval shiftInterval = new Interval(shiftStart, shiftEnd);

                // Set up buckets to handle previous days time accumulations
                BigDecimal hoursBeforeVirtualDay = BigDecimal.ZERO;

                // Check current day first block to see if start time gap from virtual day start is greater than max gap
                // if so, we can skip the previous day checks.
                TimeBlock firstBlockOfCurrentDay = null;
                for (TimeBlock b : ruleTimeBlocksCurr) {
                    if (timeBlockHasEarnCode(fromEarnGroup, b)) {
                        firstBlockOfCurrentDay = b;
                        break;
                    }
                }

                // Previous Day :: We have prior block container of nonzero size, and the previous day is active.
                Interval previousDayShiftInterval = new Interval(shiftStart.minusDays(1),
                        shiftEnd.minusDays(1));

                // Blank initialization pointer for picking which interval to pass to applyPremium()
                Interval evalInterval = null;
                if (ruleTimeBlocksPrev != null && ruleTimeBlocksPrev.size() > 0
                        && dayIsRuleActive(currentDay.minusDays(1), rule)) {
                    // Simple heuristic to see if we even need to worry about
                    // the Shift rule for this set of data.
                    if (shiftEnd.isAfter(virtualDay.getEnd())) {
                        // Compare first block of previous day with first block of current day for max gaptitude.
                        TimeBlock firstBlockOfPreviousDay = null;
                        for (TimeBlock b : ruleTimeBlocksPrev) {
                            if (timeBlockHasEarnCode(fromEarnGroup, b)) {
                                firstBlockOfPreviousDay = b;
                                break;
                            }
                        }
                        // Only if we actually have at least one block.
                        // Adding Assumption: We must have both a valid current and previous block. Max Gap can not be more than a virtual day.
                        // If this assumption does not hold, additional logic will be needed to iteratively go back in time to figure out which
                        // blocks are valid.
                        if ((firstBlockOfPreviousDay != null) && (firstBlockOfCurrentDay != null)) {
                            Interval previousBlockInterval = new Interval(
                                    firstBlockOfPreviousDay.getEndDateTime().withZone(zone),
                                    firstBlockOfCurrentDay.getBeginDateTime().withZone(zone));
                            Duration blockGapDuration = previousBlockInterval.toDuration();
                            BigDecimal bgdHours = TKUtils.convertMillisToHours(blockGapDuration.getMillis());
                            // if maxGap is 0, ignore gaps and assign shift to time blocks within the hours
                            if (rule.getMaxGap().compareTo(BigDecimal.ZERO) == 0
                                    || bgdHours.compareTo(rule.getMaxGap()) <= 0) {
                                // If we are here, we know we have at least one valid time block to pull some hours forward from.

                                // These are inversely sorted.
                                for (int i = 0; i < ruleTimeBlocksPrev.size(); i++) {
                                    TimeBlock b = ruleTimeBlocksPrev.get(i);
                                    if (timeBlockHasEarnCode(fromEarnGroup, b)) {
                                        Interval blockInterval = new Interval(
                                                b.getBeginDateTime().withZone(zone),
                                                b.getEndDateTime().withZone(zone));

                                        // Calculate Block Gap, the duration between clock outs and clock ins of adjacent time blocks.
                                        if (previousBlockInterval != null) {
                                            blockGapDuration = new Duration(b.getEndDateTime().withZone(zone),
                                                    previousBlockInterval.getStart());
                                            bgdHours = TKUtils
                                                    .convertMillisToHours(blockGapDuration.getMillis());
                                        }

                                        // Check Gap, if good, sum hours, if maxGap is 0, ignore gaps
                                        if (rule.getMaxGap().compareTo(BigDecimal.ZERO) == 0
                                                || bgdHours.compareTo(rule.getMaxGap()) <= 0) {
                                            // Calculate Overlap and add it to hours before virtual day bucket.
                                            if (blockInterval.overlaps(previousDayShiftInterval)) {
                                                BigDecimal hrs = TKUtils.convertMillisToHours(blockInterval
                                                        .overlap(previousDayShiftInterval).toDurationMillis());
                                                hoursBeforeVirtualDay = hoursBeforeVirtualDay.add(hrs);
                                            }

                                        } else {
                                            // Time blocks are reverse sorted, we can jump out as soon as the max gap is exceeded.
                                            break;
                                        }

                                        previousBlockInterval = blockInterval;

                                    }
                                }
                            } else {
                                // DO NOTHING!
                            }
                        }
                    }
                }

                BigDecimal hoursToApply = BigDecimal.ZERO;
                BigDecimal hoursToApplyPrevious = BigDecimal.ZERO;
                // If the hours before virtual day are less than or equal to
                // min hours, we have already applied the time, so we don't
                // set hoursToApplyPrevious
                if (hoursBeforeVirtualDay.compareTo(rule.getMinHours()) <= 0) {
                    // we need to apply these hours.
                    hoursToApplyPrevious = hoursBeforeVirtualDay;
                }

                //  Current Day

                TimeBlock previous = null; // Previous Time Block
                List<TimeBlock> accumulatedBlocks = new ArrayList<TimeBlock>(); // TimeBlocks we MAY or MAY NOT apply Shift Premium to.
                List<Interval> accumulatedBlockIntervals = new ArrayList<Interval>(); // To save recompute time when checking timeblocks for application we store them as we create them.
                // Iterate over sorted list, checking time boundaries vs Shift Intervals.
                long accumulatedMillis = TKUtils.convertHoursToMillis(hoursBeforeVirtualDay);

                boolean previousDayOnly = false; // IF the rule is not active today, but was on the previous day, we need to still look at time blocks.
                if (!dayIsRuleActive(currentDay, rule)) {
                    if (dayIsRuleActive(currentDay.minusDays(1), rule)) {
                        previousDayOnly = true;
                    } else {
                        // Nothing to see here, move to next rule.
                        continue;
                    }

                }

                /*
                 * We will touch each time block and accumulate time blocks that are applicable to
                 * the current rule we are on.
                 */

                // These blocks are only used for detail application
                // We don't want to pass along the previous pay period,
                // because we don't want to modify the time blocks on that
                // period. If null is passed, time will be placed on the
                // first block of the first period if the previous period
                // block had influence.
                List<TimeBlock> previousBlocksFiltered = (previousPayPeriodPrevDay) ? null
                        : filterBlocksByApplicableEarnGroup(fromEarnGroup, ruleTimeBlocksPrev);

                for (TimeBlock current : ruleTimeBlocksCurr) {
                    if (!timeBlockHasEarnCode(fromEarnGroup, current)) {
                        // TODO: WorkSchedule considerations somewhere in here?
                        continue;
                    }

                    Interval blockInterval = new Interval(current.getBeginDateTime().withZone(zone),
                            current.getEndDateTime().withZone(zone));

                    // Check both Intervals, since the time blocks could still
                    // be applicable to the previous day.  These two intervals should
                    // not have any overlap.
                    if (previousDayShiftInterval.overlaps(shiftInterval)) {
                        LOG.error("Interval of greater than 24 hours created in the rules processing.");
                        return;
                        //                     throw new RuntimeException("Interval of greater than 24 hours created in the rules processing.");
                    }

                    // This block of code handles cases where you have time
                    // that spills to multiple days and a shift rule that
                    // has a valid window on multiple consecutive days. Time
                    // must be applied with the correct shift interval.
                    Interval overlap = previousDayShiftInterval.overlap(blockInterval);
                    evalInterval = previousDayShiftInterval;
                    if (overlap == null) {
                        if (hoursToApplyPrevious.compareTo(BigDecimal.ZERO) > 0) {
                            // we have hours from previous day, and the shift
                            // window is going to move to current day.
                            // Need to apply this now, and move window forward
                            // for current time block.
                            BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                            this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals,
                                    accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious,
                                    hoursToApply, rule);
                            accumulatedMillis = 0L; // reset accumulated hours..
                            hoursToApply = BigDecimal.ZERO;
                            hoursToApplyPrevious = BigDecimal.ZERO;
                        }

                        // Because of our position in the loop, when we are at this point,
                        // we know we've passed any previous day shift intervals, so we can
                        // determine if we should skip the current day based on the boolean
                        // we set earlier.
                        if (previousDayOnly) {
                            continue;
                        }

                        overlap = shiftInterval.overlap(blockInterval);
                        evalInterval = shiftInterval;
                    }

                    // Time bucketing and application as normal:
                    //
                    if (overlap != null) {
                        // There IS overlap.
                        if (previous != null) {
                            // only check max gap if max gap of rule is not 0
                            if (rule.getMaxGap().compareTo(BigDecimal.ZERO) != 0
                                    && exceedsMaxGap(previous, current, rule.getMaxGap())) {
                                BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                                this.applyAccumulatedWrapper(accumHours, evalInterval,
                                        accumulatedBlockIntervals, accumulatedBlocks, previousBlocksFiltered,
                                        hoursToApplyPrevious, hoursToApply, rule);
                                accumulatedMillis = 0L; // reset accumulated hours..
                                hoursToApply = BigDecimal.ZERO;
                                hoursToApplyPrevious = BigDecimal.ZERO;
                            } else {
                                long millis = overlap.toDurationMillis();
                                accumulatedMillis += millis;
                                hoursToApply = hoursToApply.add(TKUtils.convertMillisToHours(millis));
                            }
                        } else {
                            // Overlap shift at first time block.
                            long millis = overlap.toDurationMillis();
                            accumulatedMillis += millis;
                            hoursToApply = hoursToApply.add(TKUtils.convertMillisToHours(millis));
                        }
                        accumulatedBlocks.add(current);
                        accumulatedBlockIntervals.add(blockInterval);
                        previous = current; // current can still apply to next.
                    } else {
                        // No Overlap / Outside of Rule
                        if (previous != null) {
                            BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                            this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals,
                                    accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious,
                                    hoursToApply, rule);
                            accumulatedMillis = 0L; // reset accumulated hours..
                            hoursToApply = BigDecimal.ZERO;
                            hoursToApplyPrevious = BigDecimal.ZERO;
                        }
                    }

                }

                // All time blocks are iterated over, check for remainders.
                // Check containers for time, and apply if needed.
                BigDecimal accumHours = TKUtils.convertMillisToHours(accumulatedMillis);
                this.applyAccumulatedWrapper(accumHours, evalInterval, accumulatedBlockIntervals,
                        accumulatedBlocks, previousBlocksFiltered, hoursToApplyPrevious, hoursToApply, rule);
            }
        }
        //    Keep track of previous as we move day by day.
        jobNumberToTimeBlocksPreviousDay = jobNumberToTimeBlocks;
        previousPayPeriodPrevDay = false;
    }

}