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