001 /** 002 * Copyright 2004-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.hr.lm.leavecalendar.validation; 017 018 import org.apache.commons.collections.CollectionUtils; 019 import org.apache.commons.lang.StringUtils; 020 import org.joda.time.DateMidnight; 021 import org.joda.time.DateTime; 022 import org.joda.time.DateTimeConstants; 023 import org.joda.time.DateTimeZone; 024 import org.joda.time.Hours; 025 import org.joda.time.Interval; 026 import org.joda.time.LocalDateTime; 027 import org.kuali.hr.lm.LMConstants; 028 import org.kuali.hr.lm.accrual.AccrualCategory; 029 import org.kuali.hr.lm.employeeoverride.EmployeeOverride; 030 import org.kuali.hr.lm.leave.web.LeaveCalendarWSForm; 031 import org.kuali.hr.lm.leaveSummary.LeaveSummary; 032 import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow; 033 import org.kuali.hr.lm.leaveblock.LeaveBlock; 034 import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument; 035 import org.kuali.hr.time.assignment.Assignment; 036 import org.kuali.hr.time.assignment.AssignmentDescriptionKey; 037 import org.kuali.hr.time.base.web.TkCommonCalendarForm; 038 import org.kuali.hr.time.calendar.CalendarEntries; 039 import org.kuali.hr.time.earncode.EarnCode; 040 import org.kuali.hr.time.earncodegroup.EarnCodeGroup; 041 import org.kuali.hr.time.service.base.TkServiceLocator; 042 import org.kuali.hr.time.util.TKContext; 043 import org.kuali.hr.time.util.TKUser; 044 import org.kuali.hr.time.util.TKUtils; 045 import org.kuali.hr.time.util.TkConstants; 046 047 import java.math.BigDecimal; 048 import java.sql.Date; 049 import java.sql.Timestamp; 050 import java.util.*; 051 052 import org.kuali.rice.kew.api.KewApiServiceLocator; 053 import org.kuali.rice.kew.api.document.DocumentStatus; 054 import org.kuali.rice.krad.util.ObjectUtils; 055 056 public class LeaveCalendarValidationUtil { 057 058 //begin KPME-1263 059 public static List<String> validateLeaveAccrualRuleMaxUsage(LeaveCalendarWSForm lcf) { 060 LeaveBlock updatedLeaveBlock = null; 061 if(lcf.getLeaveBlockId() != null) { 062 updatedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lcf.getLeaveBlockId()); 063 } 064 return validateLeaveAccrualRuleMaxUsage(lcf.getLeaveSummary(), lcf.getSelectedEarnCode(), lcf.getStartDate(), 065 lcf.getEndDate(), lcf.getLeaveAmount(), updatedLeaveBlock); 066 } 067 068 public static List<String> validateLeaveAccrualRuleMaxUsage(LeaveSummary ls, String selectedEarnCode, String leaveStartDateString, 069 String leaveEndDateString, BigDecimal leaveAmount, LeaveBlock updatedLeaveBlock) { 070 List<String> errors = new ArrayList<String>(); 071 String principalId = TKContext.getTargetPrincipalId(); 072 long daysSpan = TKUtils.getDaysBetween(TKUtils.formatDateString(leaveStartDateString), TKUtils.formatDateString(leaveEndDateString)); 073 if(leaveAmount == null) { 074 leaveAmount = TKUtils.getHoursBetween(TKUtils.formatDateString(leaveStartDateString).getTime(), TKUtils.formatDateString(leaveEndDateString).getTime()); 075 } 076 if(ls != null && CollectionUtils.isNotEmpty(ls.getLeaveSummaryRows())) { 077 BigDecimal oldLeaveAmount = null; 078 boolean earnCodeChanged = false; 079 if(updatedLeaveBlock != null) { 080 if(!updatedLeaveBlock.getEarnCode().equals(selectedEarnCode)) { 081 earnCodeChanged = true; 082 } 083 if(!updatedLeaveBlock.getLeaveAmount().equals(leaveAmount)) { 084 oldLeaveAmount = updatedLeaveBlock.getLeaveAmount(); 085 } 086 } 087 Date aDate = TKUtils.formatDateString(leaveEndDateString); 088 EarnCode earnCodeObj = TkServiceLocator.getEarnCodeService().getEarnCode(selectedEarnCode, aDate); 089 if(earnCodeObj != null) { 090 AccrualCategory accrualCategory = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(earnCodeObj.getAccrualCategory(), aDate); 091 if(accrualCategory != null) { 092 List<LeaveSummaryRow> rows = ls.getLeaveSummaryRows(); 093 for(LeaveSummaryRow aRow : rows) { 094 if(aRow.getAccrualCategory().equals(accrualCategory.getAccrualCategory())) { 095 //Does employee have overrides in place? 096 List<EmployeeOverride> employeeOverrides = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverrides(principalId,TKUtils.formatDateString(leaveEndDateString)); 097 String leavePlan = accrualCategory.getLeavePlan(); 098 BigDecimal maxUsage = aRow.getUsageLimit(); 099 for(EmployeeOverride eo : employeeOverrides) { 100 if(eo.getLeavePlan().equals(leavePlan) && eo.getAccrualCategory().equals(aRow.getAccrualCategory())) { 101 if(eo.getOverrideType().equals("MU") && eo.isActive()) { 102 if(eo.getOverrideValue()!=null) { 103 maxUsage = new BigDecimal(eo.getOverrideValue()); 104 } else { // no limit flag 105 maxUsage = null; 106 } 107 } 108 } 109 } 110 BigDecimal ytdUsage = aRow.getYtdApprovedUsage(); 111 BigDecimal pendingLeaveBalance = aRow.getPendingLeaveRequests(); 112 BigDecimal desiredUsage = new BigDecimal(0); 113 if(pendingLeaveBalance!=null) { 114 if(oldLeaveAmount!=null) { 115 116 if(!earnCodeChanged || 117 updatedLeaveBlock.getAccrualCategory().equals(accrualCategory.getAccrualCategory())) { 118 pendingLeaveBalance = pendingLeaveBalance.subtract(oldLeaveAmount.abs()); 119 } 120 } 121 122 desiredUsage = desiredUsage.add(pendingLeaveBalance); 123 } 124 125 desiredUsage = desiredUsage.add(leaveAmount.multiply(new BigDecimal(daysSpan+1))); 126 127 if(ytdUsage!=null) { 128 desiredUsage = desiredUsage.add(ytdUsage); 129 } 130 if(maxUsage!=null) { 131 if(desiredUsage.compareTo(maxUsage) > 0 ) { 132 errors.add("This leave request would exceed the usage limit for " + aRow.getAccrualCategory()); //errorMessages 133 } 134 } 135 } 136 } 137 } 138 } 139 } 140 return errors; 141 } 142 //End KPME-1263 143 144 //TODO: Move to WarningService 145 public static Map<String, Set<String>> validatePendingTransactions(String principalId, Date fromDate, Date toDate) { 146 Map<String, Set<String>> allMessages = new HashMap<String, Set<String>>(); 147 148 Set<String> actionMessages = new HashSet<String>(); 149 Set<String> infoMessages = new HashSet<String>(); 150 Set<String> warningMessages = new HashSet<String>(); 151 152 List<LeaveBlock> leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocksWithType(principalId, fromDate, toDate, LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER); 153 Set<String> workflowDocIds = new HashSet<String>(); 154 for(LeaveBlock lb : leaveBlocks) { 155 if(lb.getTransactionalDocId() != null) { 156 workflowDocIds.add(lb.getTransactionalDocId()); 157 } else { 158 if(StringUtils.contains(lb.getDescription(), "Forfeited balance transfer amount")) { 159 infoMessages.add("A max balance action that forfeited accrued leave occurred on this calendar"); 160 } 161 } 162 } 163 for(String workflowDocId : workflowDocIds) { 164 DocumentStatus status = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(workflowDocId); 165 166 if(StringUtils.equals(status.getCode(), TkConstants.ROUTE_STATUS.FINAL)) { 167 infoMessages.add("A transfer action occurred on this calendar"); 168 } 169 else if(StringUtils.equals(status.getCode(), TkConstants.ROUTE_STATUS.ENROUTE)) { 170 actionMessages.add("A pending balance transfer exists on this calendar. It must be finalized before this calendar can be approved"); 171 } 172 else { 173 warningMessages.add("A balance transfer document exists for this calendar with status neither final nor enroute"); 174 } 175 } 176 177 leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocksWithType(principalId, fromDate, toDate, LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT); 178 workflowDocIds = new HashSet<String>(); 179 for(LeaveBlock lb : leaveBlocks) { 180 if(lb.getTransactionalDocId() != null) { 181 workflowDocIds.add(lb.getTransactionalDocId()); 182 } 183 } 184 for(String workflowDocId : workflowDocIds) { 185 DocumentStatus status = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(workflowDocId); 186 187 if(StringUtils.equals(status.getCode(), TkConstants.ROUTE_STATUS.FINAL)) { 188 infoMessages.add("A payout action occurred on this calendar"); 189 } 190 else if(StringUtils.equals(status.getCode(), TkConstants.ROUTE_STATUS.ENROUTE)) { 191 actionMessages.add("A pending payout exists on this calendar. It must be finalized before this calendar can be approved"); 192 } 193 else { 194 warningMessages.add("A payout document exists for this calendar with status neither final or enroute"); 195 } 196 } 197 allMessages.put("actionMessages", actionMessages); 198 allMessages.put("infoMessages", infoMessages); 199 allMessages.put("warningMessages", warningMessages); 200 201 return allMessages; 202 } 203 204 // get warning messages associated with earn codes of leave blocks 205 public static Map<String, Set<String>> getWarningMessagesForLeaveBlocks(List<LeaveBlock> leaveBlocks) { 206 // List<String> warningMessages = new ArrayList<String>(); 207 Map<String, Set<String>> allMessages = new HashMap<String, Set<String>>(); 208 209 Set<String> actionMessages = new HashSet<String>(); 210 Set<String> infoMessages = new HashSet<String>(); 211 Set<String> warningMessages = new HashSet<String>(); 212 213 if (CollectionUtils.isNotEmpty(leaveBlocks)) { 214 for(LeaveBlock lb : leaveBlocks) { 215 EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(lb.getEarnCode(), lb.getLeaveDate()); 216 if(ec != null) { 217 EarnCodeGroup eg = TkServiceLocator.getEarnCodeGroupService().getEarnCodeGroupForEarnCode(lb.getEarnCode(), lb.getLeaveDate()); 218 if(eg != null && !StringUtils.isEmpty(eg.getWarningText())) { 219 warningMessages.add(eg.getWarningText()); 220 } 221 } 222 } 223 } 224 allMessages.put("actionMessages", actionMessages); 225 allMessages.put("infoMessages", infoMessages); 226 allMessages.put("warningMessages", warningMessages); 227 228 // warningMessages.addAll(aSet); 229 return allMessages; 230 } 231 232 public static List<String> validateAvailableLeaveBalance(LeaveCalendarWSForm lcf) { 233 LeaveBlock updatedLeaveBlock = null; 234 if(lcf.getLeaveBlockId() != null) { 235 updatedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lcf.getLeaveBlockId()); 236 } 237 return validateAvailableLeaveBalanceForUsage(lcf.getSelectedEarnCode(), lcf.getStartDate(), lcf.getEndDate(), lcf.getLeaveAmount(), updatedLeaveBlock); 238 } 239 240 public static List<String> validateAvailableLeaveBalanceForUsage(String earnCode, String leaveStartDateString, String leaveEndDateString, 241 BigDecimal leaveAmount, LeaveBlock updatedLeaveBlock) { 242 List<String> errors = new ArrayList<String>(); 243 boolean earnCodeChanged = false; 244 BigDecimal oldAmount = null; 245 246 if(leaveAmount == null) { 247 leaveAmount = TKUtils.getHoursBetween(TKUtils.formatDateString(leaveStartDateString).getTime(), TKUtils.formatDateString(leaveEndDateString).getTime()); 248 } 249 if(updatedLeaveBlock != null) { 250 if(!updatedLeaveBlock.getEarnCode().equals(earnCode)) { 251 earnCodeChanged = true; 252 } 253 if(!updatedLeaveBlock.getLeaveAmount().equals(leaveAmount)) { 254 oldAmount = updatedLeaveBlock.getLeaveAmount(); 255 } 256 } 257 Date startDate = TKUtils.formatDateString(leaveStartDateString); 258 Date endDate = TKUtils.formatDateString(leaveEndDateString); 259 long daysSpan = TKUtils.getDaysBetween(startDate,endDate); 260 EarnCode earnCodeObj = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, endDate); 261 if(earnCodeObj != null && earnCodeObj.getAllowNegativeAccrualBalance().equals("N")) { 262 AccrualCategory accrualCategory = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(earnCodeObj.getAccrualCategory(), endDate); 263 if(accrualCategory != null) { 264 java.util.Date nextIntervalDate = TkServiceLocator.getAccrualService().getNextAccrualIntervalDate(accrualCategory.getAccrualEarnInterval(), endDate); 265 // get the usage checking cut off Date, normally it's the day before the next interval date 266 java.util.Date usageEndDate = nextIntervalDate; 267 if(nextIntervalDate.compareTo(endDate) > 0) { 268 Calendar aCal = Calendar.getInstance(); 269 aCal.setTime(nextIntervalDate); 270 aCal.add(Calendar.DAY_OF_YEAR, -1); 271 usageEndDate = aCal.getTime(); 272 } 273 // use the end of the year as the interval date for usage checking of no-accrual hours, 274 // normally no-accrual hours are from banked/transferred system scheduled time offs 275 if(accrualCategory.getAccrualEarnInterval().equals(LMConstants.ACCRUAL_EARN_INTERVAL_CODE.NO_ACCRUAL)) { 276 Calendar aCal = Calendar.getInstance(); 277 aCal.setTime(endDate); 278 aCal.set(Calendar.MONTH, Calendar.DECEMBER); 279 aCal.set(Calendar.DAY_OF_MONTH, 31); 280 nextIntervalDate = aCal.getTime(); 281 usageEndDate = nextIntervalDate; 282 } 283 BigDecimal availableBalance = TkServiceLocator.getLeaveSummaryService() 284 .getLeaveBalanceForAccrCatUpToDate(TKContext.getTargetPrincipalId(), startDate, endDate, accrualCategory.getAccrualCategory(), usageEndDate); 285 286 if(oldAmount!=null) { 287 if(!earnCodeChanged || 288 updatedLeaveBlock.getAccrualCategory().equals(accrualCategory.getAccrualCategory())) { 289 availableBalance = availableBalance.add(oldAmount.abs()); 290 } 291 } 292 //multiply by days in span in case the user has also edited the start/end dates. 293 BigDecimal desiredUsage =null; 294 if(!TkConstants.EARN_CODE_TIME.equals(earnCodeObj.getRecordMethod())) { 295 desiredUsage = leaveAmount.multiply(new BigDecimal(daysSpan+1)); 296 } else { 297 desiredUsage = leaveAmount.multiply(new BigDecimal(daysSpan)); 298 } 299 300 if(desiredUsage.compareTo(availableBalance) > 0 ) { 301 errors.add("Requested leave amount " + desiredUsage.toString() + " is greater than available leave balance " + availableBalance.toString()); //errorMessages 302 } 303 } 304 } 305 306 return errors; 307 } 308 309 public static List<String> validateDates(String startDateS, String endDateS) { 310 List<String> errors = new ArrayList<String>(); 311 if (errors.size() == 0 && StringUtils.isEmpty(startDateS)) errors.add("The start date is blank."); 312 if (errors.size() == 0 && StringUtils.isEmpty(endDateS)) errors.add("The end date is blank."); 313 return errors; 314 } 315 316 public static List<String> validateTimes(String startTimeS, String endTimeS) { 317 List<String> errors = new ArrayList<String>(); 318 if (errors.size() == 0 && startTimeS == null) errors.add("The start time is blank."); 319 if (errors.size() == 0 && endTimeS == null) errors.add("The end time is blank."); 320 return errors; 321 } 322 323 324 // public static List<String> validateAvailableLeaveBalance(LeaveSummary ls, String earnCode, String leaveStartDateString, String leaveEndDateString, 325 // BigDecimal leaveAmount, LeaveBlock updatedLeaveBlock) { 326 // List<String> errors = new ArrayList<String>(); 327 // CalendarEntries calendarEntries = new CalendarEntries(); 328 // boolean earnCodeChanged = false; 329 // BigDecimal oldAmount = null; 330 // if(ls != null && CollectionUtils.isNotEmpty(ls.getLeaveSummaryRows())) { 331 // if(updatedLeaveBlock != null) { 332 // if(!updatedLeaveBlock.getEarnCode().equals(earnCode)) { 333 // earnCodeChanged = true; 334 // } 335 // if(!updatedLeaveBlock.getLeaveAmount().equals(leaveAmount)) { 336 // oldAmount = updatedLeaveBlock.getLeaveAmount(); 337 // } 338 // } 339 // Date startDate = TKUtils.formatDateString(leaveStartDateString); 340 // Date endDate = TKUtils.formatDateString(leaveEndDateString); 341 // long daysSpan = TKUtils.getDaysBetween(startDate,endDate); 342 // EarnCode earnCodeObj = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, endDate); 343 // if(earnCodeObj != null && earnCodeObj.getAllowNegativeAccrualBalance().equals("N")) { 344 // AccrualCategory accrualCategory = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(earnCodeObj.getAccrualCategory(), endDate); 345 // if(accrualCategory != null) { 346 // LeaveSummaryRow validationRow = ls.getLeaveSummaryRowForAccrualCategory(accrualCategory.getLmAccrualCategoryId()); 347 // if(ObjectUtils.isNotNull(validationRow)) { 348 // BigDecimal availableBalance = validationRow.getLeaveBalance(); 349 // LeaveSummary ytdSummary = TkServiceLocator.getLeaveSummaryService().getLeaveSummaryAsOfDateForAccrualCategory(TKContext.getTargetPrincipalId(), startDate, accrualCategory.getAccrualCategory()); 350 // if(ytdSummary != null) { 351 // LeaveSummaryRow ytdSummaryRow = ytdSummary.getLeaveSummaryRowForAccrualCategory(accrualCategory.getLmAccrualCategoryId()); 352 // if(ytdSummaryRow != null) 353 // availableBalance = ytdSummaryRow.getLeaveBalance(); 354 // } 355 // 356 // if(oldAmount!=null) { 357 // 358 // if(!earnCodeChanged || 359 // updatedLeaveBlock.getAccrualCategory().equals(accrualCategory.getAccrualCategory())) { 360 // availableBalance = availableBalance.add(oldAmount.abs()); 361 // } 362 // 363 // } 364 // //multiply by days in span in case the user has also edited the start/end dates. 365 // BigDecimal desiredUsage = leaveAmount.multiply(new BigDecimal(daysSpan+1)); 366 // 367 // if(desiredUsage.compareTo(availableBalance) > 0 ) { 368 // errors.add("Requested leave amount is greater than available leave balance."); //errorMessages 369 // } 370 // } 371 // } 372 // } 373 // } 374 // 375 // return errors; 376 // } 377 378 379 // KPME-2010 380 public static List<String> validateSpanningWeeks(LeaveCalendarWSForm lcf) { 381 boolean spanningWeeks = lcf.getSpanningWeeks().equalsIgnoreCase("y"); 382 Date startDate = TKUtils.formatDateString(lcf.getStartDate()); 383 EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(lcf.getSelectedEarnCode(), startDate); 384 DateTime startTemp, endTemp; 385 386 if (ec != null && !ec.getRecordMethod().equals(LMConstants.RECORD_METHOD.TIME)) { 387 startTemp = new DateTime(startDate); 388 endTemp = new DateTime(TKUtils.formatDateString(lcf.getEndDate())); 389 } else { 390 startTemp = new DateTime(TKUtils.convertDateStringToTimestamp(lcf.getStartDate()).getTime()); 391 endTemp = new DateTime(TKUtils.convertDateStringToTimestamp(lcf.getEndDate()).getTime()); 392 } 393 394 List<String> errors = new ArrayList<String>(); 395 boolean valid = true; 396 while ((startTemp.isBefore(endTemp) || startTemp.isEqual(endTemp)) && valid) { 397 if (!spanningWeeks && 398 (startTemp.getDayOfWeek() == DateTimeConstants.SATURDAY || startTemp.getDayOfWeek() == DateTimeConstants.SUNDAY)) { 399 valid = false; 400 } 401 startTemp = startTemp.plusDays(1); 402 } 403 if (!valid) { 404 errors.add("Weekend day is selected, but include weekends checkbox is not checked"); //errorMessages 405 } 406 return errors; 407 } 408 409 public static List<String> validateParametersAccordingToSelectedEarnCodeRecordMethod(LeaveCalendarWSForm lcf) { 410 return validateParametersForLeaveEntry(lcf.getSelectedEarnCode(), lcf.getCalendarEntry(), lcf.getStartDate(), lcf.getEndDate(), lcf.getStartTime(), lcf.getEndTime(), lcf.getSelectedAssignment(), lcf.getLeaveCalendarDocument(), lcf.getLeaveBlockId()); 411 } 412 413 public static List<String> validateParametersForLeaveEntry(String selectedEarnCode, CalendarEntries leaveCalEntry, String startDateS, String endDateS, String startTimeS, String endTimeS, String selectedAssignment, LeaveCalendarDocument leaveCalendarDocument, String leaveBlockId) { 414 415 java.sql.Date asOfDate = leaveCalEntry.getEndPeriodDate(); 416 417 List<String> errors = new ArrayList<String>(); 418 if (StringUtils.isNotBlank(selectedEarnCode)) { 419 EarnCode earnCode = TkServiceLocator.getEarnCodeService().getEarnCode(selectedEarnCode, asOfDate); 420 421 if(earnCode != null && earnCode.getRecordMethod().equalsIgnoreCase(TkConstants.EARN_CODE_TIME)) { 422 423 errors.addAll(LeaveCalendarValidationUtil.validateDates(startDateS, endDateS)); 424 errors.addAll(LeaveCalendarValidationUtil.validateTimes(startTimeS, endTimeS)); 425 if (errors.size() > 0) return errors; 426 427 Long startTime; 428 Long endTime; 429 430 startTime = TKUtils.convertDateStringToTimestampWithoutZone(startDateS, startTimeS).getTime(); 431 endTime = TKUtils.convertDateStringToTimestampWithoutZone(endDateS, endTimeS).getTime(); 432 433 errors.addAll(validateInterval(leaveCalEntry, startTime, endTime)); 434 if (errors.size() > 0) return errors; 435 436 if (startTimeS == null) errors.add("The start time is blank."); 437 if (endTimeS == null) errors.add("The end time is blank."); 438 if (startTime - endTime == 0) errors.add("Start time and end time cannot be equivalent"); 439 440 if (errors.size() > 0) return errors; 441 442 DateTime startTemp = new DateTime(startTime); 443 DateTime endTemp = new DateTime(endTime); 444 445 if (errors.size() == 0) { 446 Hours hrs = Hours.hoursBetween(startTemp, endTemp); 447 if (hrs.getHours() >= 24) errors.add("One leaveblock cannot exceed 24 hours"); 448 } 449 if (errors.size() > 0) return errors; 450 451 //Check that assignment is valid for both days 452 AssignmentDescriptionKey assignKey = TkServiceLocator.getAssignmentService().getAssignmentDescriptionKey(selectedAssignment); 453 Assignment assign = TkServiceLocator.getAssignmentService().getAssignment(assignKey, new Date(startTime)); 454 455 if ((startTime.compareTo(endTime) > 0 || endTime.compareTo(startTime) < 0)) { 456 errors.add("The time or date is not valid."); 457 } 458 if (errors.size() > 0) return errors; 459 460 // boolean isRegularEarnCode = StringUtils.equals(assign.getJob().getPayTypeObj().getRegEarnCode(),selectedEarnCode); 461 boolean isRegularEarnCode = true; 462 errors.addAll(validateOverlap(startTime, endTime, startDateS, endTimeS,startTemp, endTemp, leaveCalEntry, leaveBlockId, isRegularEarnCode, earnCode.getRecordMethod())); 463 if (errors.size() > 0) return errors; 464 } 465 } 466 return errors; 467 } 468 469 public static List<String> validateInterval(CalendarEntries payCalEntry, Long startTime, Long endTime) { 470 List<String> errors = new ArrayList<String>(); 471 LocalDateTime pcb_ldt = payCalEntry.getBeginLocalDateTime(); 472 LocalDateTime pce_ldt = payCalEntry.getEndLocalDateTime(); 473 DateTimeZone utz = TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback(); 474 DateTime p_cal_b_dt = pcb_ldt.toDateTime(utz); 475 DateTime p_cal_e_dt = pce_ldt.toDateTime(utz); 476 477 Interval payInterval = new Interval(p_cal_b_dt, p_cal_e_dt); 478 if (errors.size() == 0 && !payInterval.contains(startTime)) { 479 errors.add("The start date/time is outside the pay period"); 480 } 481 if (errors.size() == 0 && !payInterval.contains(endTime) && p_cal_e_dt.getMillis() != endTime) { 482 errors.add("The end date/time is outside the pay period"); 483 } 484 return errors; 485 } 486 487 public static List<String> validateOverlap(Long startTime, Long endTime, String startDateS, String endTimeS, DateTime startTemp, DateTime endTemp, CalendarEntries calendarEntry, String lmLeaveBlockId, boolean isRegularEarnCode, String earnCodeType) { 488 List<String> errors = new ArrayList<String>(); 489 Interval addedTimeblockInterval = new Interval(startTime, endTime); 490 List<Interval> dayInt = new ArrayList<Interval>(); 491 String viewPrincipal = TKUser.getCurrentTargetPersonId(); 492 493 dayInt.add(addedTimeblockInterval); 494 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(viewPrincipal, calendarEntry); 495 List<String> assignmentKeys = new ArrayList<String>(); 496 for(Assignment assign : assignments) { 497 assignmentKeys.add(assign.getAssignmentKey()); 498 } 499 500 List<LeaveBlock> leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocksForLeaveCalendar(viewPrincipal, calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate(), assignmentKeys); 501 for (LeaveBlock leaveBlock : leaveBlocks) { 502 if (errors.size() == 0 && StringUtils.equals(earnCodeType, TkConstants.EARN_CODE_TIME) && leaveBlock.getBeginTimestamp() != null && leaveBlock.getEndTimestamp()!= null) { 503 Interval leaveBlockInterval = new Interval(leaveBlock.getBeginTimestamp().getTime(), leaveBlock.getEndTimestamp().getTime()); 504 for (Interval intv : dayInt) { 505 if (isRegularEarnCode && leaveBlockInterval.overlaps(intv) && (lmLeaveBlockId == null || lmLeaveBlockId.compareTo(leaveBlock.getLmLeaveBlockId()) != 0)) { 506 errors.add("The leave block you are trying to add overlaps with an existing time block."); 507 } 508 } 509 } 510 } 511 512 return errors; 513 } 514 }