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 }