List of usage examples for org.joda.time DateTime plusDays
public DateTime plusDays(int days)
From source file:org.kitesdk.apps.spi.oozie.CronConverter.java
License:Apache License
public static Instant nextInstant(String cronSchedule, Instant current) { DateTime currentTime = new DateTime(current, DateTimeZone.UTC).withSecondOfMinute(0).withMillisOfSecond(0); validate(cronSchedule);/*from www . ja va 2 s .c om*/ String[] splits = cronSchedule.split(" "); String minutePart = splits[0]; String hourPart = splits[1]; String dayPart = splits[2]; // TODO: fold these together like the hour. if (isWildCard(minutePart)) { return currentTime.plusMinutes(1).toInstant(); } if (isInterval(minutePart)) { // Roll minutes forward until we hit a start time // that matches the cron interval. int interval = getInterval(minutePart); DateTime next = currentTime.withSecondOfMinute(0).plusMinutes(1); while (!(next.getMinuteOfHour() % interval == 0)) { next = next.plusMinutes(1); } return next.toInstant(); } assert (isConstant(minutePart)); // The minute part must be a constant, so // simply get the value. int minute = Integer.parseInt(minutePart); // The schedule is based on hours. if (!isConstant(hourPart)) { int hourModulus = isWildCard(hourPart) ? 1 : getInterval(hourPart); DateTime next = currentTime.withMinuteOfHour(minute); while (next.isBefore(current) || !(next.getHourOfDay() % hourModulus == 0)) { next = next.plusHours(1); } return next.toInstant(); } int hour = Integer.parseInt(hourPart); // The schedule is based on days, and therfore the day cannot // be a constant. This is is checked in validation as well. assert (!isConstant(dayPart)); DateTime next = currentTime.withMinuteOfHour(minute).withHourOfDay(hour); while (next.isBefore(current)) { next = next.plusDays(1); } return next.toInstant(); }
From source file:org.kuali.kpme.core.calendar.entry.dao.CalendarEntryDaoOjbImpl.java
License:Educational Community License
public List<CalendarEntry> getCurrentCalendarEntryNeedsScheduled(int thresholdDays, DateTime asOfDate) { DateTime windowStart = asOfDate.minusDays(thresholdDays); DateTime windowEnd = asOfDate.plusDays(thresholdDays); Criteria root = new Criteria(); root.addGreaterOrEqualThan("beginPeriodDateTime", windowStart.toDate()); root.addLessOrEqualThan("beginPeriodDateTime", windowEnd.toDate()); Query query = QueryFactory.newQuery(CalendarEntry.class, root); Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query); List<CalendarEntry> pce = new ArrayList<CalendarEntry>(c.size()); pce.addAll(c);//from w ww . ja v a 2 s . c o m return pce; }
From source file:org.kuali.kpme.core.calendar.entry.service.CalendarEntryServiceImpl.java
License:Educational Community License
private DateTime plusSemiMonth(DateTime date) { //so assuming the common pairs of this are the 1st & 16th, and then 15th and the last day, // and 14th with the last day minus 1 //so we'll peek at the current date and try to figure out the best guesses for addition. if (date.getDayOfMonth() == date.dayOfMonth().getMaximumValue()) { //date is on the last day of the month. Set next date to the 15th return date.plusMonths(1).withDayOfMonth(15); } else if (date.getDayOfMonth() == 15) { //we are on the 15th of the month, so now lets go to the end of the month return date.withDayOfMonth(date.dayOfMonth().getMaximumValue()); } else if (date.getDayOfMonth() == 1) { //first of the month, next would be 16 return date.withDayOfMonth(16); } else if (date.getDayOfMonth() == 16) { //16th, so add a month and set day to '1' return date.plusMonths(1).withDayOfMonth(1); } else if (date.getDayOfMonth() == 14) { //14th day, set next one to last day minus 1 return date.withDayOfMonth(date.dayOfMonth().getMaximumValue() - 1); } else if (date.getDayOfMonth() == date.dayOfMonth().getMaximumValue() - 1) { //date is on the second to last day of the month. Set next date to the 14th return date.plusMonths(1).withDayOfMonth(14); } else {//from w ww.j av a 2 s.c o m // so it isn't one of the common dates... i guess we'll just add 15 days... return date.plusDays(15); } }
From source file:org.kuali.kpme.core.util.TKUtils.java
License:Educational Community License
/** * Constructs a list of Day Spans for the pay calendar entry provided. You * must also provide a DateTimeZone so that we can create relative boundaries. * * @param calendarEntry/* w w w . j a v a 2 s. c om*/ * @param timeZone * @return */ public static List<Interval> getDaySpanForCalendarEntry(CalendarEntry calendarEntry, DateTimeZone timeZone) { DateTime beginDateTime = calendarEntry.getBeginPeriodLocalDateTime().toDateTime(timeZone); DateTime endDateTime = calendarEntry.getEndPeriodLocalDateTime().toDateTime(timeZone); List<Interval> dayIntervals = new ArrayList<Interval>(); DateTime currDateTime = beginDateTime; while (currDateTime.isBefore(endDateTime)) { DateTime prevDateTime = currDateTime; currDateTime = currDateTime.plusDays(1); Interval daySpan = new Interval(prevDateTime, currDateTime); dayIntervals.add(daySpan); } return dayIntervals; }
From source file:org.kuali.kpme.core.util.TKUtils.java
License:Educational Community License
public static List<Interval> createDaySpan(DateTime beginDateTime, DateTime endDateTime, DateTimeZone zone) { beginDateTime = beginDateTime.toDateTime(zone); endDateTime = endDateTime.toDateTime(zone); List<Interval> dayIntervals = new ArrayList<Interval>(); DateTime currDateTime = beginDateTime; while (currDateTime.isBefore(endDateTime)) { DateTime prevDateTime = currDateTime; currDateTime = currDateTime.plusDays(1); Interval daySpan = new Interval(prevDateTime, currDateTime); dayIntervals.add(daySpan);// ww w. j a v a 2 s . c o m } return dayIntervals; }
From source file:org.kuali.kpme.core.util.TKUtils.java
License:Educational Community License
public static List<Interval> getFullWeekDaySpanForCalendarEntry(CalendarEntry calendarEntry, DateTimeZone timeZone) {/*from w w w. j a va 2 s .c o m*/ DateTime beginDateTime = calendarEntry.getBeginPeriodLocalDateTime().toDateTime(timeZone); DateTime endDateTime = calendarEntry.getEndPeriodLocalDateTime().toDateTime(timeZone); List<Interval> dayIntervals = new ArrayList<Interval>(); DateTime currDateTime = beginDateTime; if (beginDateTime.getDayOfWeek() != 7) { currDateTime = beginDateTime.plusDays(0 - beginDateTime.getDayOfWeek()); } int afterEndDate = 6 - endDateTime.getDayOfWeek(); if (endDateTime.getDayOfWeek() == 7 && endDateTime.getHourOfDay() != 0) { afterEndDate = 6; } if (endDateTime.getHourOfDay() == 0) { afterEndDate += 1; } DateTime aDate = endDateTime.plusDays(afterEndDate); while (currDateTime.isBefore(aDate)) { DateTime prevDateTime = currDateTime; currDateTime = currDateTime.plusDays(1); Interval daySpan = new Interval(prevDateTime, currDateTime); dayIntervals.add(daySpan); } return dayIntervals; }
From source file:org.kuali.kpme.core.util.TKUtils.java
License:Educational Community License
public static int getWorkDays(DateTime startDate, DateTime endDate) { int workDays = 0; DateTime currentDate = startDate; while (!currentDate.isAfter(endDate)) { if (!isWeekend(currentDate)) { workDays++;/*from www .j a va 2s . co m*/ } currentDate = currentDate.plusDays(1); } return workDays; }
From source file:org.kuali.kpme.tklm.common.CalendarValidationUtil.java
License:Educational Community License
public static List<String> validateSpanningWeeks(DateTime startDate, DateTime endDate) { List<String> errors = new ArrayList<String>(); boolean isOnlyWeekendSpan = true; while ((startDate.isBefore(endDate) || startDate.isEqual(endDate)) && isOnlyWeekendSpan) { if (startDate.getDayOfWeek() != DateTimeConstants.SATURDAY && startDate.getDayOfWeek() != DateTimeConstants.SUNDAY) { isOnlyWeekendSpan = false;/*from w ww . j a v a 2s. c o m*/ } startDate = startDate.plusDays(1); } if (isOnlyWeekendSpan) { errors.add("Weekend day is selected, but include weekends checkbox is not checked"); //errorMessages } return errors; }
From source file:org.kuali.kpme.tklm.leave.accrual.bucket.KPMEAccrualCategoryBucket.java
License:Educational Community License
private void adjustBalances(CalendarEntry calendarEntry, DateTime rolloverDate, Set<String> assignmentKeys) throws KPMEBalanceException { //fetch calendar entries in this sequence belonging to the current leave year. String dateString = TKUtils.formatDate(LocalDate.now()); List<CalendarEntry> calendarEntries = HrServiceLocator.getCalendarEntryService() .getAllCalendarEntriesForCalendarIdAndYear(calendarEntry.getHrCalendarId(), dateString.substring(6, 10)); //calendar change into a different leave calendar year if (rolloverDate != null) { //clear all balances. clearLeaveBalances();// w w w . jav a2s. com //reset the asOfDate this bucket will go off of, as well as those of the leave balances adjustAsOfDates(calendarEntry, calendarEntries); //TODO: if in current calendar year, use current date + planning months for extent of fetch. List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksSinceCarryOver( principalCalendar.getPrincipalId(), LmServiceLocator.getLeaveBlockService().getLastCarryOverBlocks( principalCalendar.getPrincipalId(), rolloverDate.minusDays(1).toLocalDate()), rolloverDate.plusDays(365).toLocalDate(), true); //retrieve (if any) last carryover blocks given the new asOfDate Map<String, LeaveBlock> carryOverBlocks = LmServiceLocator.getLeaveBlockService() .getLastCarryOverBlocks(principalCalendar.getPrincipalId(), asOfDate); //method taken from leave summary service - map general leave block fetch by accrual category Map<String, List<LeaveBlock>> accrualCategoryMappedLeaveBlocks = mapLeaveBlocksByAccrualCategory( leaveBlocks); //merge carryOverBlock map with accrualCategoryMappedLeaveBlocks. for (Entry<String, LeaveBlock> entry : carryOverBlocks.entrySet()) { //TODO: modify CarryOverLeaveBalance to identify and make use of CARRY_OVER type leave block if (accrualCategoryMappedLeaveBlocks.containsKey(entry.getKey())) accrualCategoryMappedLeaveBlocks.get(entry.getKey()).add(entry.getValue()); else { List<LeaveBlock> carryOverList = new ArrayList<LeaveBlock>(); carryOverList.add(entry.getValue()); accrualCategoryMappedLeaveBlocks.put(entry.getKey(), carryOverList); } } //add leave blocks, accrual category by accrual category, to this bucket. for (Entry<String, List<LeaveBlock>> entry : accrualCategoryMappedLeaveBlocks.entrySet()) { for (LeaveBlock leaveBlock : entry.getValue()) { try { addLeaveBlock(leaveBlock); } catch (KPMEBalanceException e) { InstantiationException ie = new InstantiationException(); ie.setStackTrace(e.getStackTrace()); ie.printStackTrace(); } } } } else { //Calendar change within the same leave year. List<String> assignmentKeyList = new ArrayList<String>(); assignmentKeyList.addAll(assignmentKeys); List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>(); //determine which leave blocks are affected by the calendar change, remove them, and re-add them under the new asOfDate if (calendarEntry.getEndPeriodFullDateTime() .isBefore(viewingCalendarEntry.getEndPeriodFullDateTime().getMillis())) { //need to remove leave blocks from otherLeaveCalendarDocument begin date to thisLeaveCalendarDocument end date leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks( principalCalendar.getPrincipalId(), LocalDate.fromDateFields(calendarEntry.getBeginPeriodDateTime()), LocalDate.fromDateFields(viewingCalendarEntry.getEndPeriodDateTime())); //leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksForLeaveCalendar(principalCalendar.getPrincipalId(), LocalDate.fromDateFields(calendarEntry.getBeginPeriodDateTime()), LocalDate.fromDateFields(viewingCalendarEntry.getEndPeriodDateTime()), assignmentKeyList); } else { //need to remove leave blocks from thisLeaveCalendarDocument begin date to otherLeaveCalendarDocument end date leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks( principalCalendar.getPrincipalId(), LocalDate.fromDateFields(viewingCalendarEntry.getBeginPeriodDateTime()), LocalDate.fromDateFields(calendarEntry.getEndPeriodDateTime())); //leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksForLeaveCalendar(principalCalendar.getPrincipalId(), LocalDate.fromDateFields(viewingCalendarEntry.getBeginPeriodDateTime()), LocalDate.fromDateFields(calendarEntry.getEndPeriodDateTime()), assignmentKeyList); } //remove affected leave blocks for (LeaveBlock block : leaveBlocks) { removeLeaveBlock(block); } //update this bucket and its leave balances with new relative date information LocalDate newAsOfDate = null; DateTime currentLeavePlanStartDate = HrServiceLocator.getLeavePlanService() .getFirstDayOfLeavePlan(principalCalendar.getLeavePlan(), LocalDate.now()); if (calendarEntry.getEndPeriodDate().before(currentLeavePlanStartDate.toDate())) { //require balances as of the final day of the leave calendar year. DateTime calendarEntryLeavePlanRolloverDate = HrServiceLocator.getLeavePlanService() .getRolloverDayOfLeavePlan(principalCalendar.getLeavePlan(), LocalDate.fromDateFields(calendarEntry.getEndPeriodDate())); newAsOfDate = LocalDate.fromDateFields(calendarEntryLeavePlanRolloverDate.toDate()).minusDays(1); } else { Interval interval = new Interval(calendarEntry.getBeginPeriodDateTime().getTime(), calendarEntry.getEndPeriodDateTime().getTime()); if (interval.contains(LocalDate.now().toDate().getTime())) { newAsOfDate = LocalDate.now(); } else if (calendarEntry.getBeginPeriodDate().before(LocalDate.now().toDate())) newAsOfDate = LocalDate.fromDateFields(calendarEntry.getEndPeriodDate()).minusDays(1); else // if it's in the calendar interval above, the equals case is taken care of, begin date must be after today newAsOfDate = LocalDate.fromDateFields(calendarEntry.getBeginPeriodDate()).minusDays(1); } asOfDate = newAsOfDate; for (Entry<String, List<LeaveBalance>> leaveBalance : leaveBalances.entrySet()) { for (LeaveBalance balance : leaveBalance.getValue()) { balance.calendarPeriodBeginDate = LocalDate .fromDateFields(calendarEntry.getBeginPeriodDateTime()); balance.calendarPeriodEndDate = LocalDate.fromDateFields(calendarEntry.getEndPeriodDateTime()); balance.asOfDate = newAsOfDate; } } //re-add the affected leave blocks under the new date / calendar information for (LeaveBlock block : leaveBlocks) { addLeaveBlock(block); } } }
From source file:org.kuali.kpme.tklm.leave.accrual.service.AccrualServiceImpl.java
License:Educational Community License
@SuppressWarnings("unchecked") @Override// ww w . ja va 2 s .c o m public void runAccrual(String principalId, DateTime startDate, DateTime endDate, boolean recordRanData, String runAsPrincipalId) { List<LeaveBlock> accrualLeaveBlocks = new ArrayList<LeaveBlock>(); Map<String, BigDecimal> accumulatedAccrualCatToAccrualAmounts = new HashMap<String, BigDecimal>(); Map<String, BigDecimal> accumulatedAccrualCatToNegativeAccrualAmounts = new HashMap<String, BigDecimal>(); if (startDate != null && endDate != null) { LOG.info("AccrualServiceImpl.runAccrual() STARTED with Principal: " + principalId + " Start: " + startDate.toString() + " End: " + endDate.toString()); } if (startDate.isAfter(endDate)) { LOG.error("Start Date " + startDate.toString() + " should not be later than End Date " + endDate.toString()); return; // throw new RuntimeException("Start Date " + startDate.toString() + " should not be later than End Date " + endDate.toString()); } //Inactivate all previous accrual-generated entries for this span of time deactivateOldAccruals(principalId, startDate, endDate, runAsPrincipalId); //Build a rate range aggregate with appropriate information for this period of time detailing Rate Ranges for job //entries for this range of time RateRangeAggregate rrAggregate = this.buildRateRangeAggregate(principalId, startDate, endDate); PrincipalHRAttributes phra = null; PrincipalHRAttributes endPhra = null; LeavePlan lp = null; List<AccrualCategory> accrCatList = null; //Iterate over every day in span DateTime currentDate = startDate; while (!currentDate.isAfter(endDate)) { RateRange currentRange = rrAggregate.getRateOnDate(currentDate); if (currentRange == null) { currentDate = currentDate.plusDays(1); continue; } phra = currentRange.getPrincipalHRAttributes(); if (phra == null || currentDate.toLocalDate().isBefore(phra.getServiceLocalDate())) { currentDate = currentDate.plusDays(1); continue; } // use the effectiveDate of this principalHRAttribute to search for inactive entries for this principalId // If there's an inactive entry, it means the job is going to end on the effectiveDate of the inactive entry // used for minimumPercentage and proration endPhra = currentRange.getEndPrincipalHRAttributes(); if (endPhra != null && currentDate.toLocalDate().isAfter(endPhra.getEffectiveLocalDate())) { currentDate = currentDate.plusDays(1); continue; } // if the date range is before the service date of this employee, do not calculate accrual if (endDate.toLocalDate().isBefore(phra.getServiceLocalDate())) { return; } lp = currentRange.getLeavePlan(); accrCatList = currentRange.getAcList(); // if the employee status is changed, create an empty leave block on the currentDate if (currentRange.isStatusChanged()) { this.createEmptyLeaveBlockForStatusChange(principalId, accrualLeaveBlocks, currentDate.toLocalDate()); } // if no job found for the employee on the currentDate, do nothing if (CollectionUtils.isEmpty(currentRange.getJobs())) { currentDate = currentDate.plusDays(1); continue; } BigDecimal ftePercentage = currentRange.getAccrualRatePercentageModifier(); BigDecimal totalOfStandardHours = currentRange.getStandardHours(); boolean fullFteGranted = false; for (AccrualCategory anAC : accrCatList) { fullFteGranted = false; if (!currentDate.toLocalDate().isBefore(phra.getEffectiveLocalDate()) && !anAC.getAccrualEarnInterval().equals("N")) { // "N" means no accrual boolean prorationFlag = this.isProrationFlag(anAC.getProration()); // get the accrual rule AccrualCategoryRule currentAcRule = this.getRuleForAccrualCategory(currentRange.getAcRuleList(), anAC); // check if accrual category rule changed if (currentAcRule != null) { DateTime ruleStartDate = getRuleStartDate(currentAcRule.getServiceUnitOfTime(), phra.getServiceLocalDate(), currentAcRule.getStart()); DateTime previousIntervalDay = this.getPrevIntervalDate(ruleStartDate, anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap()); DateTime nextIntervalDay = this.getNextIntervalDate(ruleStartDate, anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap()); RateRange previousRange = rrAggregate.getRateOnDate(previousIntervalDay); AccrualCategoryRule previousAcRule = null; if (previousRange != null) { previousAcRule = this.getRuleForAccrualCategory(previousRange.getAcRuleList(), anAC); } // rule changed if (previousAcRule != null && !previousAcRule.getLmAccrualCategoryRuleId() .equals(currentAcRule.getLmAccrualCategoryRuleId())) { if (currentDate.toLocalDate().compareTo(previousIntervalDay.toLocalDate()) >= 0 && currentDate.toLocalDate().compareTo(nextIntervalDay.toLocalDate()) <= 0) { int workDaysInBetween = TKUtils.getWorkDays(ruleStartDate, nextIntervalDay); boolean minReachedFlag = minimumPercentageReachedForPayPeriod( anAC.getMinPercentWorked(), anAC.getAccrualEarnInterval(), workDaysInBetween, nextIntervalDay, phra.getPayCalendar(), rrAggregate.getCalEntryMap()); if (prorationFlag) { if (minReachedFlag) { // min reached, proration=true, rule changed, then use actual work days of currentRule for calculation // so nothing special needs to be done here } else { //minimum percentage NOT reached, proration = true, rule changed, then use previousRule for the whole pay period currentAcRule = previousAcRule; } } else { if (minReachedFlag) { // min reached, proration = false, rule changed, then accrual the whole fte of the new rule for this pay interval accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), currentAcRule.getAccrualRate()); fullFteGranted = true; } else { //min NOT reached, proration = false, rule changed, then accrual the whole fte of the previous rule for this pay interval accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), previousAcRule.getAccrualRate()); fullFteGranted = true; } } } } } // check for first pay period of principal attributes considering minimum percentage and proration DateTime firstIntervalDate = this.getNextIntervalDate( phra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap()); if (!currentDate.toLocalDate().isBefore(phra.getEffectiveLocalDate()) && !currentDate.toLocalDate().isAfter(firstIntervalDate.toLocalDate())) { int workDaysInBetween = TKUtils.getWorkDays( phra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), firstIntervalDate); boolean minReachedFlag = minimumPercentageReachedForPayPeriod(anAC.getMinPercentWorked(), anAC.getAccrualEarnInterval(), workDaysInBetween, firstIntervalDate, phra.getPayCalendar(), rrAggregate.getCalEntryMap()); if (prorationFlag) { if (minReachedFlag) { // minimum reached, proration = true, first pay period, then use actual work days of currentRule for calculation // so nothing special needs to be done here } else { // min NOT reached, proration = true, first pay period, then no accrual for this pay period accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); continue; } } else { if (minReachedFlag) { // minimum reached, proration = false, first pay period, then accrual the whole fte of current AC rule for this pay interval accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), currentAcRule.getAccrualRate()); fullFteGranted = true; } else { // min NOT reached, proration = false, first pay period, then no accrual for this pay period accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); continue; } } } // last accrual interval if (endPhra != null) { // the employment is going to end on the effectiveDate of enPhra DateTime previousIntervalDate = this.getPrevIntervalDate( endPhra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap()); // currentDate is between the end date and the last interval date, so we are in the last interval if (!currentDate.toLocalDate().isAfter(endPhra.getEffectiveLocalDate()) && currentDate.toLocalDate().isAfter(previousIntervalDate.toLocalDate())) { DateTime lastIntervalDate = this.getNextIntervalDate( endPhra.getEffectiveLocalDate().toDateTimeAtStartOfDay(), anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap()); int workDaysInBetween = TKUtils.getWorkDays(previousIntervalDate, endPhra.getEffectiveLocalDate().toDateTimeAtStartOfDay()); boolean minReachedFlag = minimumPercentageReachedForPayPeriod( anAC.getMinPercentWorked(), anAC.getAccrualEarnInterval(), workDaysInBetween, lastIntervalDate, phra.getPayCalendar(), rrAggregate.getCalEntryMap()); if (prorationFlag) { if (minReachedFlag) { // minimum reached, proration = true, first pay period, then use actual work days of currentRule for calculation // so nothing special needs to be done here } else { // min NOT reached, proration = true, first pay period, then no accrual for this pay period accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); accumulatedAccrualCatToNegativeAccrualAmounts .remove(anAC.getLmAccrualCategoryId()); continue; } } else { if (minReachedFlag) { // minimum reached, proration = false, first pay period, then accrual the whole fte of current AC rule for this pay interval accumulatedAccrualCatToAccrualAmounts.put(anAC.getLmAccrualCategoryId(), currentAcRule.getAccrualRate()); fullFteGranted = true; } else { // min NOT reached, proration = false, first pay period, then no accrual for this pay period accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); accumulatedAccrualCatToNegativeAccrualAmounts .remove(anAC.getLmAccrualCategoryId()); continue; } } } } if (currentAcRule == null) { accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); continue; } // only accrual on work days if (!TKUtils.isWeekend(currentDate) && !fullFteGranted) { BigDecimal accrualRate = currentAcRule.getAccrualRate(); int numberOfWorkDays = this.getWorkDaysInInterval(currentDate, anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap()); BigDecimal dayRate = numberOfWorkDays > 0 ? accrualRate.divide(new BigDecimal(numberOfWorkDays), 6, BigDecimal.ROUND_HALF_UP) : new BigDecimal(0); //Fetch the accural rate based on rate range for today(Rate range is the accumulated list of jobs and accrual rate for today) //Add to total accumulatedAccrualCatToAccrualAmounts //use rule and ftePercentage to calculate the hours this.calculateHours(anAC.getLmAccrualCategoryId(), ftePercentage, dayRate, accumulatedAccrualCatToAccrualAmounts); //get not eligible for accrual hours based on leave block on this day BigDecimal noAccrualHours = getNotEligibleForAccrualHours(principalId, currentDate.toLocalDate()); if (noAccrualHours != null && noAccrualHours.compareTo(BigDecimal.ZERO) != 0 && totalOfStandardHours.compareTo(BigDecimal.ZERO) != 0) { BigDecimal dayHours = totalOfStandardHours.divide(new BigDecimal(5), 6, BigDecimal.ROUND_HALF_UP); BigDecimal noAccrualRate = dayRate.multiply(noAccrualHours.divide(dayHours)); this.calculateHours(anAC.getLmAccrualCategoryId(), ftePercentage, noAccrualRate, accumulatedAccrualCatToNegativeAccrualAmounts); } } //Determine if we are at the accrual earn interval in the span, if so add leave block for accumulated accrual amount to list //and reset accumulatedAccrualCatToAccrualAmounts and accumulatedAccrualCatToNegativeAccrualAmounts for this accrual category if (this.isDateAnIntervalDate(currentDate.toLocalDate(), anAC.getAccrualEarnInterval(), phra.getPayCalendar(), rrAggregate.getCalEntryMap())) { BigDecimal acHours = accumulatedAccrualCatToAccrualAmounts .get(anAC.getLmAccrualCategoryId()); if (acHours != null) { createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), acHours, anAC, null, true, currentRange.getLeaveCalendarDocumentId()); accumulatedAccrualCatToAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); // reset accumulatedAccrualCatToAccrualAmounts fullFteGranted = false; } BigDecimal adjustmentHours = accumulatedAccrualCatToNegativeAccrualAmounts .get(anAC.getLmAccrualCategoryId()); if (adjustmentHours != null && adjustmentHours.compareTo(BigDecimal.ZERO) != 0) { // do not create leave block if the ajustment amount is 0 createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), adjustmentHours, anAC, null, false, currentRange.getLeaveCalendarDocumentId()); accumulatedAccrualCatToNegativeAccrualAmounts.remove(anAC.getLmAccrualCategoryId()); // reset accumulatedAccrualCatToNegativeAccrualAmounts } } } } //Determine if today is a system scheduled time off and accrue holiday if so. SystemScheduledTimeOff ssto = currentRange.getSysScheTimeOff(); if (ssto != null) { AccrualCategory anAC = HrServiceLocator.getAccrualCategoryService() .getAccrualCategory(ssto.getAccrualCategory(), ssto.getEffectiveLocalDate()); if (anAC == null) { LOG.error("Cannot find Accrual Category for system scheduled time off " + ssto.getLmSystemScheduledTimeOffId()); return; // throw new RuntimeException("Cannot find Accrual Category for system scheduled time off " + ssto.getLmSystemScheduledTimeOffId()); } BigDecimal hrs = ssto.getAmountofTime().multiply(ftePercentage); // system scheduled time off leave block createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), hrs, anAC, ssto.getLmSystemScheduledTimeOffId(), true, currentRange.getLeaveCalendarDocumentId()); // usage leave block with negative amount createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), hrs.negate(), anAC, ssto.getLmSystemScheduledTimeOffId(), true, currentRange.getLeaveCalendarDocumentId()); } // if today is the last day of the employment, create leave blocks if there's any hours available if (endPhra != null && currentDate.toLocalDate().equals(endPhra.getEffectiveLocalDate())) { // accumulated accrual amount if (!accumulatedAccrualCatToAccrualAmounts.isEmpty()) { for (Map.Entry<String, BigDecimal> entry : accumulatedAccrualCatToAccrualAmounts.entrySet()) { if (entry.getValue() != null && entry.getValue().compareTo(BigDecimal.ZERO) != 0) { AccrualCategory anAC = HrServiceLocator.getAccrualCategoryService() .getAccrualCategory(entry.getKey()); createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), entry.getValue(), anAC, null, true, currentRange.getLeaveCalendarDocumentId()); } } accumulatedAccrualCatToAccrualAmounts = new HashMap<String, BigDecimal>(); // reset accumulatedAccrualCatToAccrualAmounts } // negative/adjustment accrual amount if (!accumulatedAccrualCatToNegativeAccrualAmounts.isEmpty()) { for (Map.Entry<String, BigDecimal> entry : accumulatedAccrualCatToNegativeAccrualAmounts .entrySet()) { if (entry.getValue() != null && entry.getValue().compareTo(BigDecimal.ZERO) != 0) { AccrualCategory anAC = HrServiceLocator.getAccrualCategoryService() .getAccrualCategory(entry.getKey()); createLeaveBlock(principalId, accrualLeaveBlocks, currentDate.toLocalDate(), entry.getValue(), anAC, null, true, currentRange.getLeaveCalendarDocumentId()); } } accumulatedAccrualCatToNegativeAccrualAmounts = new HashMap<String, BigDecimal>(); // reset accumulatedAccrualCatToNegativeAccrualAmounts } phra = null; // reset principal attribute so new value will be retrieved endPhra = null; // reset end principal attribute so new value will be retrieved } currentDate = currentDate.plusDays(1); } //Save accrual leave blocks at the very end LmServiceLocator.getLeaveBlockService().saveLeaveBlocks(accrualLeaveBlocks); // record timestamp of this accrual run in database if (recordRanData) { LmServiceLocator.getPrincipalAccrualRanService().updatePrincipalAccrualRanInfo(principalId); } }