List of usage examples for org.joda.time DateTime minusDays
public DateTime minusDays(int days)
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); } }