Example usage for org.joda.time DateTime minusDays

List of usage examples for org.joda.time DateTime minusDays

Introduction

In this page you can find the example usage for org.joda.time DateTime minusDays.

Prototype

public DateTime minusDays(int days) 

Source Link

Document

Returns a copy of this datetime minus the specified number of days.

Usage

From source file:org.kuali.kpme.tklm.time.batch.EndReportingPeriodJob.java

License:Educational Community License

public void execute(JobExecutionContext context) throws JobExecutionException {
    JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();

    String hrCalendarEntryId = jobDataMap.getString("hrCalendarEntryId");
    String principalId = jobDataMap.getString("principalId");

    CalendarEntry calendarEntry = HrServiceLocator.getCalendarEntryService()
            .getCalendarEntry(hrCalendarEntryId);
    DateTime endPeriodDateTime = calendarEntry.getEndPeriodFullDateTime();

    String subject = "End of Reporting Period Reminder";
    StringBuilder message = new StringBuilder();
    message.append("Please submit your Leave Calendar for the period ending on ");
    message.append(DateFormat.getDateInstance(DateFormat.LONG).format(endPeriodDateTime.minusDays(1).toDate()));
    message.append(", so it can be reviewed and approved by your supervisor.");

    HrServiceLocator.getKPMENotificationService().sendNotification(subject, message.toString(), principalId);
}

From source file:org.kuali.kpme.tklm.time.detail.web.ActionFormUtils.java

License:Educational Community License

/**
 * This method will build the JSON data structure needed for calendar
 * manipulation and processing on the client side. Start and End times here
 * are based on the pre-timezone adjusted times startDisplayTime, and
 * endDisplayTime./*from ww w. jav  a2  s.co  m*/
 *
 * @param timeBlocks
 * @return
 */
public static String getTimeBlocksJson(List<TimeBlock> timeBlocks) {

    if (timeBlocks == null || timeBlocks.size() == 0) {
        return "";
    }

    List<Map<String, Object>> timeBlockList = new LinkedList<Map<String, Object>>();
    String timezone = HrServiceLocator.getTimezoneService().getUserTimezone();

    for (TimeBlock timeBlock : timeBlocks) {
        Map<String, Object> timeBlockMap = new LinkedHashMap<String, Object>();

        WorkArea workArea = HrServiceLocator.getWorkAreaService().getWorkArea(timeBlock.getWorkArea(),
                timeBlock.getEndDateTime().toLocalDate());
        String workAreaDesc = workArea.getDescription();

        String principalId = GlobalVariables.getUserSession().getPrincipalId();

        boolean isAnyApprover = HrServiceLocator.getKPMERoleService().principalHasRole(principalId,
                KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER.getRoleName(), new DateTime())
                || HrServiceLocator.getKPMERoleService().principalHasRole(principalId,
                        KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER_DELEGATE.getRoleName(),
                        new DateTime());
        timeBlockMap.put("isApprover", isAnyApprover);
        timeBlockMap.put("isSynchronousUser", timeBlock.getClockLogCreated());

        timeBlockMap.put("canEditTb",
                TkServiceLocator.getTKPermissionService().canEditTimeBlock(principalId, timeBlock));
        timeBlockMap.put("canEditTBOvt",
                TkServiceLocator.getTKPermissionService().canEditOvertimeEarnCode(timeBlock));

        if (TkServiceLocator.getTKPermissionService().canEditTimeBlockAllFields(principalId, timeBlock)) {
            timeBlockMap.put("canEditTBAll", true);
            timeBlockMap.put("canEditTBAssgOnly", false);
        } else {
            timeBlockMap.put("canEditTBAll", false);
            timeBlockMap.put("canEditTBAssgOnly", true);
        }

        //    tracking any kind of 'mutating' state with this object, it's just a one off modification under a specific circumstance.
        DateTime start = timeBlock.getBeginTimeDisplay();
        DateTime end = timeBlock.getEndTimeDisplay();

        /**
         * This is the timeblock backward pushing logic.
         * the purpose of this is to accommodate the virtual day mode where the start/end period time is not from 12a to 12a.
         * A timeblock will be pushed back if the timeblock is still within the previous interval
         */
        if (timeBlock.getPushBackward()) {
            start = start.minusDays(1);
            end = end.minusDays(1);
        }

        timeBlockMap.put("documentId", timeBlock.getDocumentId());
        timeBlockMap.put("title", workAreaDesc);
        EarnCode ec = HrServiceLocator.getEarnCodeService().getEarnCode(timeBlock.getEarnCode(),
                timeBlock.getBeginDateTime().toLocalDate());
        timeBlockMap.put("earnCode", timeBlock.getEarnCode());
        timeBlockMap.put("earnCodeDesc", ec != null ? ec.getDescription() : StringUtils.EMPTY);
        //TODO: need to cache this or pre-load it when the app boots up
        // EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(timeBlock.getEarnCode(), timeBlock.getBeginDateTime().toLocalDate());
        timeBlockMap.put("earnCodeType", timeBlock.getEarnCodeType());

        // TODO: Cleanup the start / end time related properties. We certainly don't need all of them.
        // The ones which are used by the javascript are startDate, endDate, startTime, endTime, startTimeHourMinute, and endTimeHourMinute
        timeBlockMap.put("start", start.toString(ISODateTimeFormat.dateTimeNoMillis()));
        timeBlockMap.put("end", end.toString(ISODateTimeFormat.dateTimeNoMillis()));
        timeBlockMap.put("startDate", start.toString(HrConstants.DT_BASIC_DATE_FORMAT));
        timeBlockMap.put("endDate", end.toString(HrConstants.DT_BASIC_DATE_FORMAT));
        timeBlockMap.put("startNoTz", start.toString(ISODateTimeFormat.dateHourMinuteSecond()));
        timeBlockMap.put("endNoTz", end.toString(ISODateTimeFormat.dateHourMinuteSecond()));
        // start / endTimeHourMinute fields are for only for the display purpose
        timeBlockMap.put("startTimeHourMinute", start.toString(TkConstants.DT_BASIC_TIME_FORMAT));
        timeBlockMap.put("endTimeHourMinute", end.toString(TkConstants.DT_BASIC_TIME_FORMAT));
        // start / endTime are the actual fields used by the adding / editing timeblocks
        timeBlockMap.put("startTime", start.toString(TkConstants.DT_MILITARY_TIME_FORMAT));
        timeBlockMap.put("endTime", end.toString(TkConstants.DT_MILITARY_TIME_FORMAT));
        timeBlockMap.put("id",
                timeBlock.getTkTimeBlockId() == null ? null : timeBlock.getTkTimeBlockId().toString());
        timeBlockMap.put("hours", timeBlock.getHours());
        timeBlockMap.put("amount", timeBlock.getAmount());
        timeBlockMap.put("timezone", timezone);
        timeBlockMap.put("assignment", new AssignmentDescriptionKey(timeBlock.getJobNumber(),
                timeBlock.getWorkArea(), timeBlock.getTask()).toAssignmentKeyString());
        timeBlockMap.put("tkTimeBlockId",
                timeBlock.getTkTimeBlockId() != null ? timeBlock.getTkTimeBlockId() : "");
        timeBlockMap.put("lunchDeleted", timeBlock.isLunchDeleted());

        List<Map<String, Object>> timeHourDetailList = new LinkedList<Map<String, Object>>();
        for (TimeHourDetail timeHourDetail : timeBlock.getTimeHourDetails()) {
            Map<String, Object> timeHourDetailMap = new LinkedHashMap<String, Object>();
            timeHourDetailMap.put("earnCode", timeHourDetail.getEarnCode());
            timeHourDetailMap.put("hours", timeHourDetail.getHours());
            timeHourDetailMap.put("amount", timeHourDetail.getAmount());

            // if there is a lunch hour deduction, add a flag to the timeBlockMap
            if (StringUtils.equals(timeHourDetail.getEarnCode(), "LUN")) {
                timeBlockMap.put("lunchDeduction", true);
            }

            timeHourDetailList.add(timeHourDetailMap);
        }
        timeBlockMap.put("timeHourDetails", JSONValue.toJSONString(timeHourDetailList));

        timeBlockList.add(timeBlockMap);
    }

    //        Map<String, Map<String, Object>> jsonMappedList = new HashMap<String, Map<String, Object>>();
    //        for (Map<String, Object> tbm : timeBlockList) {
    //            String id = (String) tbm.get("id");
    //            jsonMappedList.put(id, tbm);
    //        }
    return JSONValue.toJSONString(timeBlockList);
}

From source file:org.kuali.kpme.tklm.time.detail.web.TimeDetailAction.java

License:Educational Community License

protected void setMessages(TimeDetailActionForm timeDetailActionForm) {
    String principalId = HrContext.getTargetPrincipalId();
    TimesheetDocument timesheetDocument = timeDetailActionForm.getTimesheetDocument();
    CalendarEntry calendarEntry = timeDetailActionForm.getCalendarEntry();

    List<LeaveBlock> balanceTransferLeaveBlocks = LmServiceLocator.getLeaveBlockService()
            .getLeaveBlocksWithType(timesheetDocument.getPrincipalId(),
                    calendarEntry.getBeginPeriodFullDateTime().toLocalDate(),
                    calendarEntry.getEndPeriodFullDateTime().toLocalDate(),
                    LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);

    Map<String, Set<String>> allMessages = LeaveCalendarValidationUtil
            .getWarningMessagesForLeaveBlocks(balanceTransferLeaveBlocks);

    // add warning messages based on max carry over balances for each accrual category for non-exempt leave users
    List<BalanceTransfer> losses = new ArrayList<BalanceTransfer>();
    if (LmServiceLocator.getLeaveApprovalService().isActiveAssignmentFoundOnJobFlsaStatus(principalId,
            HrConstants.FLSA_STATUS_NON_EXEMPT, true)) {
        PrincipalHRAttributes principalCalendar = HrServiceLocator.getPrincipalHRAttributeService()
                .getPrincipalCalendar(principalId, calendarEntry.getEndPeriodFullDateTime().toLocalDate());

        Interval calendarInterval = new Interval(calendarEntry.getBeginPeriodDate().getTime(),
                calendarEntry.getEndPeriodDate().getTime());
        Map<String, Set<LeaveBlock>> maxBalInfractions = new HashMap<String, Set<LeaveBlock>>();

        if (principalCalendar != null) {
            maxBalInfractions = LmServiceLocator.getAccrualCategoryMaxBalanceService()
                    .getMaxBalanceViolations(calendarEntry, principalId);

            for (Entry<String, Set<LeaveBlock>> entry : maxBalInfractions.entrySet()) {
                for (LeaveBlock lb : entry.getValue()) {
                    if (calendarInterval.contains(lb.getLeaveDate().getTime())) {
                        AccrualCategory accrualCat = HrServiceLocator.getAccrualCategoryService()
                                .getAccrualCategory(lb.getAccrualCategory(), lb.getLeaveLocalDate());
                        AccrualCategoryRule aRule = HrServiceLocator.getAccrualCategoryRuleService()
                                .getAccrualCategoryRule(lb.getAccrualCategoryRuleId());
                        if (StringUtils.equals(aRule.getActionAtMaxBalance(),
                                HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
                            DateTime aDate = null;
                            if (StringUtils.equals(aRule.getMaxBalanceActionFrequency(),
                                    HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
                                aDate = HrServiceLocator.getLeavePlanService().getRolloverDayOfLeavePlan(
                                        principalCalendar.getLeavePlan(), lb.getLeaveLocalDate());
                            } else {
                                Calendar cal = HrServiceLocator.getCalendarService()
                                        .getCalendarByPrincipalIdAndDate(principalId,
                                                new LocalDate(lb.getLeaveDate()), true);
                                CalendarEntry leaveEntry = HrServiceLocator.getCalendarEntryService()
                                        .getCurrentCalendarEntryByCalendarId(cal.getHrCalendarId(),
                                                new DateTime(lb.getLeaveDate()));
                                aDate = new DateTime(leaveEntry.getEndPeriodDate());
                            }//from w  w w .ja  v  a  2  s .  c o m
                            aDate = aDate.minusDays(1);
                            if (calendarInterval.contains(aDate.getMillis())
                                    && aDate.toDate().compareTo(calendarEntry.getEndPeriodDate()) <= 0) {
                                //may want to calculate summary for all rows, displayable or not, and determine displayability via tags.
                                AccrualCategory accrualCategory = HrServiceLocator.getAccrualCategoryService()
                                        .getAccrualCategory(aRule.getLmAccrualCategoryId());
                                BigDecimal accruedBalance = LmServiceLocator.getAccrualService()
                                        .getAccruedBalanceForPrincipal(principalId, accrualCategory,
                                                lb.getLeaveLocalDate());

                                BalanceTransfer loseTransfer = LmServiceLocator.getBalanceTransferService()
                                        .initializeTransfer(principalId, lb.getAccrualCategoryRuleId(),
                                                accruedBalance, lb.getLeaveLocalDate());
                                boolean valid = BalanceTransferValidationUtils.validateTransfer(loseTransfer);
                                if (valid) {
                                    losses.add(loseTransfer);
                                }
                            }
                        }

                        // accrual categories within the leave plan that are hidden from the leave summary WILL appear.
                        String message = "You have exceeded the maximum balance limit for '"
                                + accrualCat.getAccrualCategory() + "' as of " + lb.getLeaveDate() + ". "
                                + "Depending upon the accrual category rules, leave over this limit may be forfeited.";
                        //  leave blocks are sorted in getMaxBalanceViolations() method, so we just take the one with the earliest leave date for an accrual category.
                        if (!StringUtils.contains(allMessages.get("warningMessages").toString(),
                                "You have exceeded the maximum balance limit for '"
                                        + accrualCat.getAccrualCategory())) {
                            allMessages.get("warningMessages").add(message);
                        }
                    }
                }
            }
        }
        timeDetailActionForm.setForfeitures(losses);

        Map<String, Set<String>> transactionalMessages = LeaveCalendarValidationUtil
                .validatePendingTransactions(HrContext.getTargetPrincipalId(),
                        calendarEntry.getBeginPeriodFullDateTime().toLocalDate(),
                        calendarEntry.getEndPeriodFullDateTime().toLocalDate());
        allMessages.get("infoMessages").addAll(transactionalMessages.get("infoMessages"));
        allMessages.get("warningMessages").addAll(transactionalMessages.get("warningMessages"));
        allMessages.get("actionMessages").addAll(transactionalMessages.get("actionMessages"));

        if (principalCalendar != null) {
            Calendar calendar = HrServiceLocator.getCalendarService().getCalendarByPrincipalIdAndDate(
                    principalId, calendarEntry.getEndPeriodFullDateTime().toLocalDate(), true);

            if (calendar != null) {
                List<CalendarEntry> leaveCalendarEntries = HrServiceLocator.getCalendarEntryService()
                        .getCalendarEntriesEndingBetweenBeginAndEndDate(calendar.getHrCalendarId(),
                                calendarEntry.getBeginPeriodFullDateTime(),
                                calendarEntry.getEndPeriodFullDateTime());

                List<AccrualCategory> accrualCategories = HrServiceLocator.getAccrualCategoryService()
                        .getActiveLeaveAccrualCategoriesForLeavePlan(principalCalendar.getLeavePlan(),
                                calendarEntry.getEndPeriodFullDateTime().toLocalDate());
                for (AccrualCategory accrualCategory : accrualCategories) {
                    if (LmServiceLocator.getAccrualCategoryMaxCarryOverService()
                            .exceedsAccrualCategoryMaxCarryOver(accrualCategory.getAccrualCategory(),
                                    principalId, leaveCalendarEntries,
                                    calendarEntry.getEndPeriodFullDateTime().toLocalDate())) {
                        String message = "Your pending leave balance is greater than the annual max carry over for accrual category '"
                                + accrualCategory.getAccrualCategory()
                                + "' and upon approval, the excess balance will be lost.";
                        if (!allMessages.get("warningMessages").contains(message)) {
                            allMessages.get("warningMessages").add(message);
                        }
                    }
                }
            }
        }
    }

    List<String> infoMessages = timeDetailActionForm.getInfoMessages();
    infoMessages.addAll(allMessages.get("infoMessages"));

    List<String> warningMessages = timeDetailActionForm.getWarningMessages();
    warningMessages.addAll(allMessages.get("warningMessages"));

    List<String> actionMessages = timeDetailActionForm.getActionMessages();
    actionMessages.addAll(allMessages.get("actionMessages"));

    timeDetailActionForm.setInfoMessages(infoMessages);
    timeDetailActionForm.setWarningMessages(warningMessages);
    timeDetailActionForm.setActionMessages(actionMessages);
}

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);//from  w  w  w  .  j a v a  2 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;
    }

}

From source file:org.kuali.kpme.tklm.time.timesheet.web.TimesheetSubmitAction.java

License:Educational Community License

public ActionForward approveTimesheet(ActionMapping mapping, ActionForm form, HttpServletRequest request,
        HttpServletResponse response) throws Exception {
    TimesheetSubmitActionForm tsaf = (TimesheetSubmitActionForm) form;
    TimesheetDocument document = TkServiceLocator.getTimesheetService()
            .getTimesheetDocument(tsaf.getDocumentId());

    // Switched to grab the target (chain, resolution: target -> backdoor -> actual) user.
    // Approvals still using backdoor > actual
    if (StringUtils.equals(tsaf.getAction(), HrConstants.DOCUMENT_ACTIONS.ROUTE)) {
        if (DocumentStatus.INITIATED.getCode().equals(document.getDocumentHeader().getDocumentStatus())
                || DocumentStatus.SAVED.getCode().equals(document.getDocumentHeader().getDocumentStatus())) {

            boolean nonExemptLE = LmServiceLocator.getLeaveApprovalService()
                    .isActiveAssignmentFoundOnJobFlsaStatus(document.getPrincipalId(),
                            HrConstants.FLSA_STATUS_NON_EXEMPT, true);
            if (nonExemptLE) {
                Map<String, Set<LeaveBlock>> eligibilities = LmServiceLocator
                        .getAccrualCategoryMaxBalanceService()
                        .getMaxBalanceViolations(document.getCalendarEntry(), document.getPrincipalId());
                PrincipalHRAttributes pha = HrServiceLocator.getPrincipalHRAttributeService()
                        .getPrincipalCalendar(document.getPrincipalId(),
                                document.getCalendarEntry().getEndPeriodFullDateTime().toLocalDate());
                Calendar cal = pha.getLeaveCalObj();
                if (cal == null) {
                    //non exempt leave eligible employee without a leave calendar?
                    LOG.error("Principal is without a leave calendar");
                    GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS,
                            "principal.without.leavecal");
                    return mapping.findForward("basic");
                    //                  throw new RuntimeException("Principal is without a leave calendar");
                }// w ww. java  2  s . co  m
                List<LeaveBlock> eligibleTransfers = new ArrayList<LeaveBlock>();
                List<LeaveBlock> eligiblePayouts = new ArrayList<LeaveBlock>();
                Interval interval = new Interval(document.getCalendarEntry().getBeginPeriodDate().getTime(),
                        document.getCalendarEntry().getEndPeriodDate().getTime());

                for (Entry<String, Set<LeaveBlock>> entry : eligibilities.entrySet()) {

                    for (LeaveBlock lb : entry.getValue()) {
                        if (interval.contains(lb.getLeaveDate().getTime())) {
                            //maxBalanceViolations should, if a violation exists, return a leave block with leave date either current date, or the end period date - 1 days.
                            AccrualCategoryRule aRule = HrServiceLocator.getAccrualCategoryRuleService()
                                    .getAccrualCategoryRule(lb.getAccrualCategoryRuleId());

                            if (ObjectUtils.isNotNull(aRule)
                                    && !StringUtils.equals(aRule.getMaxBalanceActionFrequency(),
                                            HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND)) {
                                if (StringUtils.equals(aRule.getMaxBalanceActionFrequency(),
                                        HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
                                    DateTime rollOverDate = HrServiceLocator.getLeavePlanService()
                                            .getRolloverDayOfLeavePlan(pha.getLeavePlan(),
                                                    document.getCalendarEntry().getBeginPeriodFullDateTime()
                                                            .toLocalDate());
                                    //the final calendar period of the leave plan should end within this time sheet 
                                    if (interval.contains(rollOverDate.minusDays(1).getMillis())) {
                                        //only leave blocks belonging to the calendar entry being submitted may reach this point
                                        //if the infraction occurs before the relative end date of the leave plan year, then action will be executed.
                                        if (lb.getLeaveDate().before(rollOverDate.toDate())) {
                                            if (StringUtils.equals(aRule.getActionAtMaxBalance(),
                                                    HrConstants.ACTION_AT_MAX_BALANCE.PAYOUT)) {
                                                eligiblePayouts.add(lb);
                                            } else if (StringUtils.equals(aRule.getActionAtMaxBalance(),
                                                    HrConstants.ACTION_AT_MAX_BALANCE.TRANSFER)
                                                    || StringUtils.equals(aRule.getActionAtMaxBalance(),
                                                            HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
                                                eligibleTransfers.add(lb);
                                            }
                                        }
                                    }
                                }
                                if (StringUtils.equals(aRule.getMaxBalanceActionFrequency(),
                                        HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE)) {
                                    //a leave period should end within the time period.
                                    CalendarEntry leaveEntry = HrServiceLocator.getCalendarEntryService()
                                            .getCurrentCalendarEntryByCalendarId(cal.getHrCalendarId(),
                                                    lb.getLeaveLocalDate().toDateTimeAtStartOfDay());
                                    if (ObjectUtils.isNotNull(leaveEntry)) {
                                        //only leave blocks belonging to the calendar entry being submitted may reach this point.
                                        //if the infraction occurs before the end of the leave calendar entry, then action will be executed.
                                        if (interval.contains(DateUtils
                                                .addDays(leaveEntry.getEndPeriodDate(), -1).getTime())) {

                                            if (StringUtils.equals(aRule.getActionAtMaxBalance(),
                                                    HrConstants.ACTION_AT_MAX_BALANCE.PAYOUT)) {
                                                eligiblePayouts.add(lb);
                                            } else if (StringUtils.equals(aRule.getActionAtMaxBalance(),
                                                    HrConstants.ACTION_AT_MAX_BALANCE.TRANSFER)
                                                    || StringUtils.equals(aRule.getActionAtMaxBalance(),
                                                            HrConstants.ACTION_AT_MAX_BALANCE.LOSE)) {
                                                eligibleTransfers.add(lb);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                ActionRedirect transferRedirect = new ActionRedirect();
                ActionRedirect payoutRedirect = new ActionRedirect();
                if (!eligibleTransfers.isEmpty()) {
                    transferRedirect.setPath("/BalanceTransfer.do?" + request.getQueryString());
                    request.getSession().setAttribute("eligibilities", eligibleTransfers);
                    return transferRedirect;
                }
                if (!eligiblePayouts.isEmpty()) {
                    payoutRedirect.setPath("/LeavePayout.do?" + request.getQueryString());
                    request.getSession().setAttribute("eligibilities", eligiblePayouts);
                    return payoutRedirect;
                }
            }
            TkServiceLocator.getTimesheetService().routeTimesheet(HrContext.getTargetPrincipalId(), document);
        }
    } else if (StringUtils.equals(tsaf.getAction(), HrConstants.DOCUMENT_ACTIONS.APPROVE)) {
        if (TkServiceLocator.getTimesheetService().isReadyToApprove(document)) {
            if (document.getDocumentHeader().getDocumentStatus().equals(DocumentStatus.ENROUTE.getCode())) {
                TkServiceLocator.getTimesheetService().approveTimesheet(HrContext.getPrincipalId(), document);
            }
        } else {
            //ERROR!!!
        }
    } else if (StringUtils.equals(tsaf.getAction(), HrConstants.DOCUMENT_ACTIONS.DISAPPROVE)) {
        if (document.getDocumentHeader().getDocumentStatus().equals(DocumentStatus.ENROUTE.getCode())) {
            TkServiceLocator.getTimesheetService().disapproveTimesheet(HrContext.getPrincipalId(), document);
        }
    }

    TkServiceLocator.getTkSearchableAttributeService().updateSearchableAttribute(document,
            document.getAsOfDate());
    ActionRedirect rd = new ActionRedirect(mapping.findForward("timesheetRedirect"));
    rd.addParameter("documentId", tsaf.getDocumentId());

    return rd;
}

From source file:org.mifos.test.acceptance.framework.loan.CreateLoanAccountReviewInstallmentPage.java

License:Open Source License

private DateTime getValidDate(DateTime disbursalDate, int minGap, boolean isGapIsMinimumGap) {
    DateTime dateTime = disbursalDate.plusDays(minGap);
    if (dateTime.getDayOfWeek() == 7) {
        if (isGapIsMinimumGap) {
            dateTime = dateTime.plusDays(1);
        } else {/*from  ww w  .  jav a  2  s .  c o  m*/
            dateTime = dateTime.minusDays(1);
        }
    }
    return dateTime;
}

From source file:org.mifos.test.acceptance.framework.loan.CreateLoanAccountReviewInstallmentPage.java

License:Open Source License

private void validateGapForFirstDateAndDisbursalDate(DateTime disbursalDate) {
    setInstallmentDate("0", dateTimeFormatter.print(disbursalDate));
    clickValidateAndWaitForPageToLoad();
    isTextPresentInPage("Installment 1 has due date which falls on the disbursal date");

    setInstallmentDate("0", dateTimeFormatter.print(disbursalDate.minusDays(1)));
    clickValidateAndWaitForPageToLoad();
    isTextPresentInPage("Installment 1 has due date which falls before the disbursal date");
}

From source file:org.mifos.test.acceptance.framework.loan.RedoLoanDisbursalSchedulePreviewPage.java

License:Open Source License

private DateTime getValidDate(DateTime date, int minimumGap, boolean isGapIsMinimumGap) {
    DateTime dateTime = date.plusDays(minimumGap);
    if (dateTime.getDayOfWeek() == 7) {
        if (isGapIsMinimumGap) {
            dateTime = dateTime.plusDays(1);
        } else {//from w  w w  .ja  va  2  s .c om
            dateTime = dateTime.minusDays(1);
        }
    }
    return dateTime;
}

From source file:org.mifos.test.acceptance.framework.loan.RedoLoanDisbursalSchedulePreviewPage.java

License:Open Source License

private void validateGapForFirstDateAndDisbursalDate(DateTime disbursalDate) {
    setInstallmentDate("0", dateFormatter.print(disbursalDate));
    clickPreviewButtonAndWaitForPageToLoad();
    isTextPresentInPage("Installment 1 has due date which falls on the disbursal date");

    setInstallmentDate("0", dateFormatter.print(disbursalDate.minusDays(1)));
    clickPreviewButtonAndWaitForPageToLoad();
    isTextPresentInPage("Installment 1 has due date which falls before the disbursal date");
}

From source file:org.n52.io.PreRenderingJob.java

License:Open Source License

public IntervalWithTimeZone createTimespanFromInterval(String timeseriesId, String period) {
    DateTime now = new DateTime();
    if (period.equals("lastDay")) {
        Interval interval = new Interval(now.minusDays(1), now);
        return new IntervalWithTimeZone(interval.toString());
    } else if (period.equals("lastWeek")) {
        Interval interval = new Interval(now.minusWeeks(1), now);
        return new IntervalWithTimeZone(interval.toString());
    } else if (period.equals("lastMonth")) {
        Interval interval = new Interval(now.minusMonths(1), now);
        return new IntervalWithTimeZone(interval.toString());
    } else {//from  w  ww .  j  a v  a2s. c o m
        throw new ResourceNotFoundException(
                "Unknown interval definition '" + period + "' for timeseriesId " + timeseriesId);
    }
}