View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.permissions;
17  
18  import java.math.BigDecimal;
19  import java.sql.Date;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.commons.collections.CollectionUtils;
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.log4j.Logger;
26  import org.kuali.hr.job.Job;
27  import org.kuali.hr.lm.LMConstants;
28  import org.kuali.hr.lm.earncodesec.EarnCodeSecurity;
29  import org.kuali.hr.lm.leaveblock.LeaveBlock;
30  import org.kuali.hr.lm.timeoff.SystemScheduledTimeOff;
31  import org.kuali.hr.lm.workflow.LeaveRequestDocument;
32  import org.kuali.hr.time.assignment.Assignment;
33  import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
34  import org.kuali.hr.time.authorization.DepartmentalRule;
35  import org.kuali.hr.time.authorization.DepartmentalRuleAuthorizer;
36  import org.kuali.hr.time.calendar.CalendarEntries;
37  import org.kuali.hr.time.collection.rule.TimeCollectionRule;
38  import org.kuali.hr.time.paytype.PayType;
39  import org.kuali.hr.time.principal.PrincipalHRAttributes;
40  import org.kuali.hr.time.roles.TkUserRoles;
41  import org.kuali.hr.time.roles.UserRoles;
42  import org.kuali.hr.time.service.base.TkServiceLocator;
43  import org.kuali.hr.time.timeblock.TimeBlock;
44  import org.kuali.hr.time.timesheet.TimesheetDocument;
45  import org.kuali.hr.time.util.TKContext;
46  import org.kuali.hr.time.util.TKUser;
47  import org.kuali.hr.time.util.TKUtils;
48  import org.kuali.hr.time.util.TkConstants;
49  import org.kuali.hr.time.workarea.WorkArea;
50  import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
51  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
52  import org.kuali.rice.kew.api.KewApiConstants;
53  import org.kuali.rice.kew.api.KewApiServiceLocator;
54  import org.kuali.rice.kew.api.document.DocumentStatus;
55  import org.kuali.rice.kew.doctype.SecuritySession;
56  import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
57  import org.kuali.rice.kew.service.KEWServiceLocator;
58  import org.kuali.rice.krad.util.GlobalVariables;
59  
60  public class TkPermissionsServiceImpl implements TkPermissionsService {
61      private static final Logger LOG = Logger
62              .getLogger(DepartmentalRuleAuthorizer.class);
63  
64      @Override
65      public boolean canAddTimeBlock() {
66          boolean addTimeBlock = false;
67          boolean isUsersTimesheet = StringUtils.equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId());
68  
69          TkUserRoles roles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
70          if (!isUsersTimesheet && roles.isSystemAdmin()) {
71              addTimeBlock = true;
72          } else {
73          	String documentStatus = TKContext.getCurrentTimesheetDocument().getDocumentHeader().getDocumentStatus();
74              boolean docFinal = DocumentStatus.FINAL.getCode().equals(documentStatus)
75                      || DocumentStatus.CANCELED.getCode().equals(documentStatus)
76                      || DocumentStatus.DISAPPROVED.getCode().equals(documentStatus);
77              if (!docFinal) {
78                  if (isUsersTimesheet
79                          || roles.isSystemAdmin()
80                          || roles.isLocationAdmin()
81                          || roles.isReviewer()
82                          || roles.isApprover()) {
83                      addTimeBlock = true;
84                  }
85              }
86          }
87          return addTimeBlock;
88      }
89  
90      @Override
91      public boolean canEditTimeBlockAllFields(TimeBlock tb) {
92          String userId = GlobalVariables.getUserSession().getPrincipalId();
93  
94          if (userId != null) {
95              boolean isUsersTimesheet = StringUtils.equals(userId,tb.getPrincipalId());
96              TkUserRoles roles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
97              //Check if the user is a system admin and not on their own timesheet.
98              if (!isUsersTimesheet && roles.isSystemAdmin()) {
99                  return true;
100             }
101             
102             if (StringUtils.isNotBlank(tb.getDocumentId())) {
103                 DocumentStatus documentStatus = null;
104                 try {
105                     documentStatus = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(tb.getDocumentId());
106                 } catch (RiceIllegalStateException ex) {
107                     LOG.error("Unable to find timesheet document with id: " + tb.getDocumentId());
108                 }
109                 if (documentStatus != null && DocumentStatus.CANCELED.getCode().equals(documentStatus)
110                             || DocumentStatus.DISAPPROVED.getCode().equals(documentStatus)) {
111 	            	return false;
112 	            }
113             }
114             
115             Job job = TkServiceLocator.getJobService().getJob(
116                     TKContext.getTargetPrincipalId(), tb.getJobNumber(),
117                     tb.getEndDate());
118             PayType payType = job.getPayTypeObj();
119 
120             if (!isUsersTimesheet && ((roles.isTimesheetApprover()
121                     && roles.getApproverWorkAreas().contains(tb.getWorkArea()))
122                  || (roles.isTimesheetReviewer()
123                     && roles.getReviewerWorkAreas().contains(tb.getWorkArea())))) {
124 
125                 if (StringUtils.equals(payType.getRegEarnCode(),
126                         tb.getEarnCode())) {
127                     return true;
128                 }
129 
130                 List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator
131                         .getEarnCodeSecurityService().getEarnCodeSecurities(
132                                 job.getDept(), job.getHrSalGroup(),
133                                 job.getLocation(), tb.getEndDate());
134 
135                 for (EarnCodeSecurity dec : deptEarnCodes) {
136                     if (dec.isApprover()
137                             && StringUtils.equals(dec.getEarnCode(), tb.getEarnCode())
138                             && (roles.getApproverWorkAreas().contains(tb.getWorkArea())
139                             || roles.getReviewerWorkAreas().contains(tb.getWorkArea()))) {
140                         return true;
141                     }
142                 }
143             }
144 
145             if (StringUtils.equals(payType.getRegEarnCode(), tb.getEarnCode())) {
146                 TimeCollectionRule tcr = TkServiceLocator.getTimeCollectionRuleService().getTimeCollectionRule(job.getDept(),tb.getWorkArea(),job.getHrPayType(),tb.getBeginDate());
147 
148                 //and the user is a clock user and this is the users timesheet do not allow to be deleted
149                 if (tcr == null || tcr.isClockUserFl()) {
150                     return !isUsersTimesheet;
151                 }
152             }
153 
154             if (isUsersTimesheet && tb.getClockLogCreated()) {
155                 if (StringUtils.equals(payType.getRegEarnCode(),
156                         tb.getEarnCode())) {
157                     return false;
158                 }
159             }
160 
161             if (isUsersTimesheet && !tb.getClockLogCreated()) {
162                 if (StringUtils.equals(payType.getRegEarnCode(), tb.getEarnCode())) {
163                     return true;
164                 }
165 
166                 List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator
167                         .getEarnCodeSecurityService().getEarnCodeSecurities(
168                                 job.getDept(), job.getHrSalGroup(),
169                                 job.getLocation(), tb.getEndDate());
170                 for (EarnCodeSecurity dec : deptEarnCodes) {
171                     if (dec.isEmployee()
172                             && StringUtils.equals(dec.getEarnCode(),
173                             tb.getEarnCode())) {
174                         return true;
175                     }
176                 }
177             }
178 
179         }
180 
181         return false;
182     }
183 
184     @Override
185     public boolean canEditTimeBlock(TimeBlock tb) {
186         String userId = GlobalVariables.getUserSession().getPrincipalId();
187 
188         if (userId != null) {
189 
190             boolean isUsersTimesheet = StringUtils.equals(userId,tb.getPrincipalId());
191             TkUserRoles roles = TkUserRoles.getUserRoles(userId);
192             // if the sys admin user is working on his own time block, do not grant edit permission without further checking
193             if (roles.isSystemAdmin() && !isUsersTimesheet) {
194             	return true;
195             }
196             
197             //Check if the user is a location admin and not on their own timesheet.
198             WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(tb.getWorkArea(), tb.getBeginDate());
199 
200             if (workArea != null
201                         && StringUtils.isNotEmpty(workArea.getDept())
202                         && roles.isLocationAdmin()
203                         && roles.getOrgAdminDepartments().contains(workArea.getDept())) {
204                 return true;
205             }
206 
207             if (StringUtils.isNotBlank(tb.getDocumentId())) {
208                 DocumentStatus documentStatus = null;
209                 try {
210                     documentStatus = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(tb.getDocumentId());
211                 } catch (RiceIllegalStateException ex) {
212                     //Unable to find document.
213                 }
214 
215                 if (documentStatus != null && DocumentStatus.CANCELED.getCode().equals(documentStatus)
216                             || DocumentStatus.DISAPPROVED.getCode().equals(documentStatus)) {
217 	            	return false;
218 	            }
219             }
220             
221             Job job = TkServiceLocator.getJobService().getJob(
222                     TKContext.getTargetPrincipalId(), tb.getJobNumber(),
223                     tb.getEndDate());
224             PayType payType = TkServiceLocator.getPayTypeService().getPayType(
225                     job.getHrPayType(), tb.getEndDate());
226             
227             if (!isUsersTimesheet && ((roles.isTimesheetApprover()
228                     && roles.getApproverWorkAreas().contains(tb.getWorkArea()))
229                 ||  (roles.isTimesheetReviewer()
230                     && roles.getReviewerWorkAreas().contains(tb.getWorkArea())))) {
231 
232                 if (StringUtils.equals(payType.getRegEarnCode(),
233                         tb.getEarnCode())) {
234                     return true;
235                 }
236 
237                 List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator
238                         .getEarnCodeSecurityService().getEarnCodeSecurities(
239                                 job.getDept(), job.getHrSalGroup(),
240                                 job.getLocation(), tb.getEndDate());
241                 for (EarnCodeSecurity dec : deptEarnCodes) {
242                     if (dec.isApprover()
243                             && StringUtils.equals(dec.getEarnCode(), tb.getEarnCode())
244                             && (roles.getApproverWorkAreas().contains(tb.getWorkArea())
245                             || roles.getReviewerWorkAreas().contains(tb.getWorkArea()))) {
246                         return true;
247                     }
248                 }
249             }
250 
251             //Taking out for KPME-2427
252             // if the time block is generated by clock actions, do not allow it to be edited/deleted
253 			//if(tb.getClockLogCreated()) {
254 		    //    return false;
255 			//}
256 
257             if (isUsersTimesheet) {
258 
259                 if (StringUtils.equals(payType.getRegEarnCode(), tb.getEarnCode())) {
260                     //If you are a clock user and you have only one assignment you should not be allowed to change the assignment
261                     //TODO eventually move this logic to one concise place for editable portions of the timeblock
262                     List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(TKContext.getPrincipalId(),tb.getBeginDate());
263                     if (assignments.size() == 1) {
264                     	TimeCollectionRule tcr = TkServiceLocator.getTimeCollectionRuleService().getTimeCollectionRule(job.getDept(),tb.getWorkArea(),job.getHrPayType(),tb.getBeginDate());
265                     	
266                     	return tcr != null && !tcr.isClockUserFl();
267                     } else {
268                         return true;
269                     }
270                 }
271 
272                 List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator
273                         .getEarnCodeSecurityService().getEarnCodeSecurities(
274                                 job.getDept(), job.getHrSalGroup(),
275                                 job.getLocation(), tb.getEndDate());
276                 for (EarnCodeSecurity dec : deptEarnCodes) {
277                     if (dec.isEmployee()
278                             && StringUtils.equals(dec.getEarnCode(),
279                             tb.getEarnCode())) {
280                         return true;
281                     }
282                 }
283             }
284 
285         }
286 
287         return false;
288     }
289 
290     @Override
291     public boolean canDeleteTimeBlock(TimeBlock tb) {
292         String userId = GlobalVariables.getUserSession().getPrincipalId();
293 
294         if (userId != null) {
295 
296             boolean isUsersTimesheet = StringUtils.equals(userId,tb.getPrincipalId());
297 
298         	// if the sys admin user is working on his own time block, do not grant delete permission without further checking
299             TkUserRoles roles = TkUserRoles.getUserRoles(userId);
300             if (roles.isSystemAdmin()&& !isUsersTimesheet) {
301             	return true;
302             }
303             
304             //Check if the user is a location admin and not on their own timesheet.
305             WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(tb.getWorkArea(), tb.getBeginDate());
306 
307 
308             if (workArea != null
309                         && StringUtils.isNotEmpty(workArea.getDept())
310                         && roles.isLocationAdmin()
311                         && roles.getOrgAdminDepartments().contains(workArea.getDept())) {
312                 return true;
313             }
314 
315             if (StringUtils.isNotBlank(tb.getDocumentId())) {
316                 DocumentStatus documentStatus = null;
317                 try {
318                     documentStatus = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(tb.getDocumentId());
319                 } catch (RiceIllegalStateException ex) {
320                     //Unable to find document.
321                 }
322 
323                 if (documentStatus != null && DocumentStatus.CANCELED.getCode().equals(documentStatus)
324                             || DocumentStatus.DISAPPROVED.getCode().equals(documentStatus)) {
325 	            	return false;
326 	            }
327             }
328             
329             Job job = TkServiceLocator.getJobService().getJob(
330                     TKContext.getTargetPrincipalId(), tb.getJobNumber(),
331                     tb.getEndDate());
332             PayType payType = TkServiceLocator.getPayTypeService().getPayType(
333                     job.getHrPayType(), tb.getEndDate());
334 
335             TimeCollectionRule tcr = TkServiceLocator.getTimeCollectionRuleService().getTimeCollectionRule(job.getDept(),tb.getWorkArea(),payType.getPayType(),tb.getEndDate());
336 
337             if (!isUsersTimesheet && ((roles.isTimesheetApprover()
338                     && roles.getApproverWorkAreas().contains(tb.getWorkArea()))
339                     || (roles.isTimesheetReviewer()
340                     && roles.getReviewerWorkAreas().contains(tb.getWorkArea())))){
341 
342                 if (StringUtils.equals(payType.getRegEarnCode(),
343                         tb.getEarnCode())) {
344                     return true;
345                 }
346 
347                 List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator
348                         .getEarnCodeSecurityService().getEarnCodeSecurities(
349                                 job.getDept(), job.getHrSalGroup(),
350                                 job.getLocation(), tb.getEndDate());
351                 for (EarnCodeSecurity dec : deptEarnCodes) {
352                     if (dec.isApprover()
353                             && StringUtils.equals(dec.getEarnCode(), tb.getEarnCode())
354                             && (roles.getApproverWorkAreas().contains(tb.getWorkArea())
355                             || roles.getReviewerWorkAreas().contains(tb.getWorkArea()))) {
356                         return true;
357                     }
358 
359                 }
360             }
361 
362 //            // If the timeblock was created by the employee himeself and is a sync timeblock,
363 //            // the user can't delete the timeblock
364 //            if (userId.equals(TKContext.getTargetPrincipalId())
365 //                    && tb.getClockLogCreated()) {
366 //                return false;
367 //            // But if the timeblock was created by the employee himeself and is an async timeblock,
368 //            // the user should be able to delete that timeblock
369             //if (userId.equals(TKContext.getTargetPrincipalId()) && !tb.getClockLogCreated() ) {
370 //                return true;
371 //            } else {
372             
373             // if the time block is generated by clock actions, do not allow it to be edited/deleted
374 			if(tb.getClockLogCreated()) {
375 					return false;
376 			}
377 
378             //if on a regular earncode
379             if (StringUtils.equals(payType.getRegEarnCode(),
380                     tb.getEarnCode())) {
381                 //and the user is a clock user and this is the users timesheet do not allow to be deleted
382             	if (tcr == null || tcr.isClockUserFl()) {
383                     if (isUsersTimesheet) {
384 	                    return false;
385 	                }  else {
386 	                    return true;
387 	                }
388                 }
389             }
390             
391             //KPME-2264 -
392             // EE's should be able to remove timeblocks added via the time detail calendar only after checking prior conditions,
393 			if (userId.equals(TKContext.getTargetPrincipalId())) {
394 				return true;
395 			} 
396             
397             List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator
398                     .getEarnCodeSecurityService().getEarnCodeSecurities(
399                             job.getDept(), job.getHrSalGroup(),
400                             job.getLocation(), tb.getEndDate());
401             for (EarnCodeSecurity dec : deptEarnCodes) {
402                 if (dec.isEmployee()
403                         && StringUtils.equals(dec.getEarnCode(),
404                         tb.getEarnCode())
405                         && hasManagerialRolesOnWorkArea(tb)) {
406                     return true;
407                 }
408             }
409 
410         }
411 
412         return false;
413     }
414 
415     @Override
416     public boolean canEditLeaveBlock(LeaveBlock lb) {
417         String userId = GlobalVariables.getUserSession().getPrincipalId();
418         
419         if (userId != null) {
420 
421         	String documentId = lb.getDocumentId();
422         	if (StringUtils.isBlank(documentId)) {
423         		TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeaderForDate(userId, lb.getLeaveDate());
424         		if (timesheetDocumentHeader != null) {
425         			documentId = timesheetDocumentHeader.getDocumentId();
426         		}
427         	}
428         	if (StringUtils.isNotBlank(documentId)) {
429 	        	DocumentStatus documentStatus = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(documentId);
430 	            if (DocumentStatus.CANCELED.equals(documentStatus) || DocumentStatus.DISAPPROVED.equals(documentStatus)) {
431 	            	return false;
432 	            }
433         	}
434             
435             String blockType = lb.getLeaveBlockType();
436             String requestStatus = lb.getRequestStatus();
437             if (StringUtils.equals(LMConstants.REQUEST_STATUS.DISAPPROVED, requestStatus)) {
438                 return false;
439             }
440             if (StringUtils.equals(LMConstants.REQUEST_STATUS.APPROVED, requestStatus)) {
441             	List<LeaveRequestDocument> docList= TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocumentsByLeaveBlockId(lb.getLmLeaveBlockId());
442             	if(CollectionUtils.isEmpty(docList)) {
443             		return false;	// not a leave request. if this is a leave request, do further checking on it
444             	}            	
445             }
446             TkUserRoles roles = TkUserRoles.getUserRoles(userId);
447             if (StringUtils.isBlank(blockType)
448                     || StringUtils.equals(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR, blockType)
449                     || StringUtils.equals(LMConstants.LEAVE_BLOCK_TYPE.TIME_CALENDAR, blockType)) {
450             	if (!roles.isDepartmentAdmin()
451                         || roles.getApproverWorkAreas().contains(lb.getWorkArea())) {
452             		return true;
453             	}
454             } else if (LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT.equals(blockType)
455                     || LMConstants.LEAVE_BLOCK_TYPE.DONATION_MAINT.equals(blockType)
456                     || LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER.equals(blockType)
457                     || LMConstants.LEAVE_BLOCK_TYPE.LEAVE_ADJUSTMENT_MAINT.equals(blockType)) {
458                 if (roles.isSystemAdmin()) {
459                     return true;
460                 }
461             }
462             // kpme-1689
463             if(StringUtils.equals(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE, blockType)
464             		&& StringUtils.isNotEmpty(lb.getScheduleTimeOffId())
465             		&& lb.getLeaveAmount().compareTo(BigDecimal.ZERO) == -1) {
466             	if(roles.isSystemAdmin()) {
467             		return true;
468             	}
469             	SystemScheduledTimeOff ssto = TkServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOff(lb.getScheduleTimeOffId());
470             	if(ssto != null && !StringUtils.equals(LMConstants.UNUSED_TIME.NO_UNUSED, ssto.getUnusedTime())) {
471             		return true;
472             	}
473             }
474         }
475 
476         return false;
477     }
478 
479     @Override
480     public boolean canDeleteLeaveBlock(LeaveBlock lb) {
481     	String userId = GlobalVariables.getUserSession().getPrincipalId();
482         
483         if (userId != null) {
484 	    	String documentId = lb.getDocumentId();
485 	    	if (StringUtils.isBlank(documentId)) {
486 	    		TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeaderForDate(userId, lb.getLeaveDate());
487 	    		if (timesheetDocumentHeader != null) {
488 	    			documentId = timesheetDocumentHeader.getDocumentId();
489 	    		}
490 	    	}
491 	    	if (StringUtils.isNotBlank(documentId)) {
492 	        	DocumentStatus documentStatus = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(documentId);
493 	            if (DocumentStatus.CANCELED.equals(documentStatus) || DocumentStatus.DISAPPROVED.equals(documentStatus)) {
494 	            	return false;
495 	            }
496 	    	}
497         }
498         
499     	if(StringUtils.equals(LMConstants.REQUEST_STATUS.DISAPPROVED, lb.getRequestStatus()))  {
500             return false;
501         }
502     	if(canBankOrTransferSSTOUsage(lb)) {
503     		return true;
504     	}
505         if (StringUtils.equals(LMConstants.REQUEST_STATUS.APPROVED, lb.getRequestStatus())) {
506         	List<LeaveRequestDocument> docList= TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocumentsByLeaveBlockId(lb.getLmLeaveBlockId());
507         	if(CollectionUtils.isEmpty(docList)) {
508         		return false;	// not a leave request
509         	}
510         }
511        
512         return canEditLeaveBlock(lb);
513     }
514 
515     @Override
516 	public boolean canBankOrTransferSSTOUsage(LeaveBlock lb) {
517 		// if it's an accrual generated ssto usage leave block which can be banked or transferred, and on a current leave calendar,
518 	    // it can be deleted so the accrualed amount can be banked
519 	    return canBankSSTOUsage(lb) || canTransferSSTOUsage(lb);
520 	}
521     
522     @Override
523 	public boolean canBankSSTOUsage(LeaveBlock lb) {
524 	   if(lb.getAccrualGenerated() 
525 			   && StringUtils.isNotEmpty(lb.getScheduleTimeOffId()) 
526 			   && lb.getLeaveAmount().compareTo(BigDecimal.ZERO) < 0) {
527 		   SystemScheduledTimeOff ssto = TkServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOff(lb.getScheduleTimeOffId());
528 		   if(ssto != null && StringUtils.equals(ssto.getUnusedTime(), LMConstants.UNUSED_TIME.BANK)) {
529 			   Date currentDate = TKUtils.getTimelessDate(null);
530 			   String viewPrincipal = TKUser.getCurrentTargetPersonId();
531 			   CalendarEntries ce = TkServiceLocator.getCalendarService()
532 						.getCurrentCalendarDatesForLeaveCalendar(viewPrincipal, currentDate);
533 			   if(ce != null) {
534 				   if(!lb.getLeaveDate().before(ce.getBeginPeriodDate()) && !lb.getLeaveDate().after(ce.getEndPeriodDate())) {
535 					   return true;
536 				   }
537 			   }
538 			  
539 		   }
540 	   }
541 	   return false;
542 	}
543     @Override
544 	public boolean canTransferSSTOUsage(LeaveBlock lb) {
545 	   if(lb.getAccrualGenerated() 
546 			   && StringUtils.isNotEmpty(lb.getScheduleTimeOffId()) 
547 			   && lb.getLeaveAmount().compareTo(BigDecimal.ZERO) < 0) {
548 		   SystemScheduledTimeOff ssto = TkServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOff(lb.getScheduleTimeOffId());
549 		   if(ssto != null && StringUtils.equals(ssto.getUnusedTime(), LMConstants.UNUSED_TIME.TRANSFER)) {
550 			   Date currentDate = TKUtils.getTimelessDate(null);
551 			   String viewPrincipal = TKUser.getCurrentTargetPersonId();
552 			   CalendarEntries ce = TkServiceLocator.getCalendarService()
553 						.getCurrentCalendarDatesForLeaveCalendar(viewPrincipal, currentDate);
554 			   if(ce != null) {
555 				   if(!lb.getLeaveDate().before(ce.getBeginPeriodDate()) && !lb.getLeaveDate().after(ce.getEndPeriodDate())) {
556 					   return true;
557 				   }
558 			   }
559 			  
560 		   }
561 	   }
562 	   return false;
563 	}
564 
565     @Override
566     public boolean canViewAdminTab() {
567         UserRoles ur = TKUser.getCurrentTargetRoles();
568 
569         boolean viewAdminTab = ur.isSystemAdmin() || ur.isLocationAdmin()
570                 || ur.isDepartmentAdmin() || ur.isGlobalViewOnly();
571 
572         return viewAdminTab;
573     }
574 
575     @Override
576     public boolean canViewApproverTab() {
577         UserRoles ur = TKUser.getCurrentTargetRoles();
578 
579         boolean viewApproverTab = ur.isSystemAdmin()
580                 || ur.isTimesheetApprover() || ur.isTimesheetReviewer();
581 
582         return viewApproverTab;
583     }
584 
585     @Override
586     public boolean canViewClockTab() {
587         UserRoles ur = TKUser.getCurrentTargetRoles();
588 
589         return ur.isActiveEmployee() && ur.isSynchronous();
590     }
591 
592     @Override
593     public boolean canViewBatchJobsTab() {
594         UserRoles ur = TKUser.getCurrentTargetRoles();
595 
596         return ur.isSystemAdmin();
597     }
598 
599     @Override
600     public boolean canViewPersonInfoTab() {
601         return true;
602     }
603 
604     @Override
605     public boolean canViewTimeDetailTab() {
606         UserRoles ur = TKUser.getCurrentTargetRoles();
607 
608         return ur.isActiveEmployee();
609     }
610 
611     @Override
612     public boolean canViewLeaveAccrualTab() {
613         UserRoles ur = TKUser.getCurrentTargetRoles();
614 
615         return ur.isActiveEmployee();
616     }
617 
618     @Override
619     public boolean canViewTimesheet(String documentId) {
620         boolean viewTimeSheet = false;
621 
622         if (documentId != null) {
623             return canViewTimesheet(TkServiceLocator.getTimesheetService()
624                     .getTimesheetDocument(documentId));
625         }
626 
627         return viewTimeSheet;
628     }
629 
630     @Override
631     public boolean canViewTimesheet(TimesheetDocument document) {
632         boolean viewTimeSheet = false;
633         UserRoles ur = TKUser.getCurrentTargetRoles();
634 
635         if (document == null)
636             return viewTimeSheet;
637 
638         // Sysadmin
639         viewTimeSheet = ur.isSystemAdmin();
640         // Owner
641         viewTimeSheet |= StringUtils.equals(ur.getPrincipalId(),
642                 document.getPrincipalId());
643         // Global VO
644         viewTimeSheet |= ur.isGlobalViewOnly();
645 
646         if (!viewTimeSheet) {
647             // Departmental View Only? || Reviewer || Org Admin || Approver
648             // (document object iteration)
649             List<Assignment> assignments = document.getAssignments();
650             for (Assignment assignment : assignments) {
651                 String dept = assignment.getDept();
652                 Long wa = assignment.getWorkArea();
653 
654                 viewTimeSheet |= ur.getOrgAdminDepartments().contains(dept);
655                 viewTimeSheet |= ur.getApproverWorkAreas().contains(wa);
656                 viewTimeSheet |= ur.getReviewerWorkAreas().contains(wa);
657                 viewTimeSheet |= ur.getDepartmentViewOnlyDepartments().contains(dept);
658             }
659         }
660 
661         return viewTimeSheet;
662     }
663 
664     @Override
665     public boolean canEditTimesheet(TimesheetDocument document) {
666         boolean editTimeSheet = false;
667         UserRoles ur = TKUser.getCurrentTargetRoles();
668 
669         // Quick escape.
670         if (document == null)
671             return editTimeSheet;
672 
673         // Sysadmin
674         editTimeSheet = ur.isSystemAdmin();
675         // Owner (and not enroute/final)
676         editTimeSheet |= (StringUtils.equals(ur.getPrincipalId(),
677                 document.getPrincipalId()) && (StringUtils.equals(
678                 TkConstants.ROUTE_STATUS.INITIATED, document
679                 .getDocumentHeader().getDocumentStatus())
680                 || StringUtils.equals(TkConstants.ROUTE_STATUS.SAVED, document
681                 .getDocumentHeader().getDocumentStatus()) || (StringUtils
682                 .equals(TkConstants.ROUTE_STATUS.ENROUTE, document
683                         .getDocumentHeader().getDocumentStatus()))));
684 
685         if (!editTimeSheet) {
686             // Departmental View Only? || Reviewer || Org Admin || Approver
687             // (document object iteration)
688             List<Assignment> assignments = document.getAssignments();
689             for (Assignment assignment : assignments) {
690                 String dept = assignment.getDept();
691                 Long wa = assignment.getWorkArea();
692 
693                 editTimeSheet |= ur.getOrgAdminDepartments().contains(dept);
694                 editTimeSheet |= ur.getApproverWorkAreas().contains(wa);
695                 editTimeSheet |= ur.getReviewerWorkAreas().contains(wa);
696             }
697         }
698 
699         return editTimeSheet;
700     }
701 
702     @Override
703     public boolean canEditTimesheet(String documentId) {
704         return canEditTimesheet(TkServiceLocator.getTimesheetService()
705                 .getTimesheetDocument(documentId));
706     }
707 
708     @Override
709     public boolean canApproveTimesheet(TimesheetDocument doc) {
710 
711         TimesheetDocumentHeader docHeader = TkServiceLocator
712                 .getTimesheetDocumentHeaderService().getDocumentHeader(
713                         doc.getDocumentId());
714         boolean isEnroute = StringUtils.equals(docHeader.getDocumentStatus(),
715                 "ENROUTE");
716 
717         if (isEnroute) {
718             DocumentRouteHeaderValue routeHeader = KEWServiceLocator
719                     .getRouteHeaderService().getRouteHeader(doc.getDocumentId());
720             boolean authorized = KEWServiceLocator.getDocumentSecurityService()
721                     .routeLogAuthorized(TKContext.getPrincipalId(),
722                             routeHeader,
723                             new SecuritySession(TKContext.getPrincipalId()));
724             if (authorized) {
725                 List<String> principalsToApprove = KEWServiceLocator
726                         .getActionRequestService()
727                         .getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(
728                                 KewApiConstants.ACTION_REQUEST_APPROVE_REQ,
729                                 routeHeader.getDocumentId());
730                 if (!principalsToApprove.isEmpty()
731                         && principalsToApprove.contains(TKContext
732                         .getPrincipalId())) {
733                     return true;
734                 }
735             }
736         }
737         return false;
738     }
739 
740     @Override
741     public boolean canSubmitTimesheet(TimesheetDocument doc) {
742         UserRoles ur = TKUser.getCurrentTargetRoles();
743 
744         if (StringUtils
745                 .equals(TKContext.getPrincipalId(), doc.getPrincipalId())) {
746             return true;
747         }
748 
749         if (ur.isApproverForTimesheet(doc)) {
750             return true;
751         }
752 
753         // System admins can route the document as well as the employee
754         if (ur.isSystemAdmin()) {
755             return true;
756         }
757         return false;
758     }
759 
760     @Override
761     public boolean canSubmitTimesheet(String docId) {
762         TimesheetDocument doc = TkServiceLocator.getTimesheetService()
763                 .getTimesheetDocument(docId);
764         return canSubmitTimesheet(doc);
765     }
766 
767     @Override
768     public boolean canViewLinkOnMaintPages() {
769         TkUserRoles roles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
770         return roles.isSystemAdmin()
771                 || roles.isGlobalViewOnly();
772     }
773 
774     @Override
775     public boolean canViewDeptMaintPages() {
776         UserRoles ur = TKUser.getCurrentTargetRoles();
777 
778         return ur.isSystemAdmin() || ur.isGlobalViewOnly()
779                 || ur.getOrgAdminCharts().size() > 0
780                 || ur.getOrgAdminDepartments().size() > 0
781                 || ur.getDepartmentViewOnlyDepartments().size() > 0
782                 || ur.isAnyApproverActive();
783     }
784 
785     @Override
786     public boolean canViewDeptMaintPages(DepartmentalRule dr) {
787         boolean ret = false;
788         TkUserRoles roles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
789         if (roles.isSystemAdmin() || roles.isGlobalViewOnly())
790             return true;
791 
792         if (dr != null) {
793             // dept | workArea | meaning
794             // ---------|------------|
795             // 1: % , -1 , any dept/work area valid roles
796             // *2: % , <defined> , must have work area <-- *
797             // 3: <defined>, -1 , must have dept, any work area
798             // 4: <defined>, <defined> , must have work area or department
799             // defined
800             //
801             // * Not permitted.
802 
803             if (StringUtils
804                     .equals(dr.getDept(), TkConstants.WILDCARD_CHARACTER)
805                     && dr.getWorkArea().equals(TkConstants.WILDCARD_LONG)) {
806                 // case 1
807                 ret = roles.isApprover()
808                         || TKUser.getLocationAdminAreas(roles).size() > 0
809                         || TKUser.getDepartmentAdminAreas(roles).size() > 0;
810             } else if (StringUtils.equals(dr.getDept(),
811                     TkConstants.WILDCARD_CHARACTER)) {
812                 // case 2 *
813                 // Should not encounter this case.
814                 LOG.error("Invalid case encountered while scanning business objects: Wildcard Department & Defined workArea.");
815             } else if (dr.getWorkArea().equals(TkConstants.WILDCARD_LONG)) {
816                 // case 3
817                 ret = TKUser.getDepartmentAdminAreas(roles).contains(dr.getDept());
818             } else {
819                 ret = roles.getApproverWorkAreas().contains(dr.getWorkArea())
820                         || TKUser.getDepartmentAdminAreas(roles).contains(dr.getDept());
821             }
822         }
823 
824         return ret;
825     }
826 
827     @Override
828     public boolean canEditDeptMaintPages() {
829         UserRoles ur = TKUser.getCurrentTargetRoles();
830         return ur.isSystemAdmin() || ur.getOrgAdminCharts().size() > 0
831                 || ur.getOrgAdminDepartments().size() > 0;
832     }
833 
834     @Override
835     public boolean canEditDeptMaintPages(DepartmentalRule dr) {
836         boolean ret = false;
837         TkUserRoles roles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
838         if (roles.isSystemAdmin())
839             return true;
840 
841         if (dr != null && TKUser.getDepartmentAdminAreas(roles).size() > 0) {
842             String dept = dr.getDept();
843             if (StringUtils.equals(dept, TkConstants.WILDCARD_CHARACTER)) {
844                 // Must be system administrator
845                 ret = false;
846             } else {
847                 // Must have parent Department
848                 ret = TKUser.getDepartmentAdminAreas(roles).contains(dr.getDept());
849             }
850         }
851 
852         return ret;
853     }
854 
855     @Override
856     public boolean canWildcardWorkAreaInDeptRule(DepartmentalRule dr) {
857         // Sysadmins and (Departmental OrgAdmins for their Department)
858         TkUserRoles roles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
859         if (roles.isSystemAdmin())
860             return true;
861 
862         String dept = dr.getDept();
863         if (StringUtils.equals(dept, TkConstants.WILDCARD_CHARACTER)) {
864             // Only system administrators can wildcard the work area if the
865             // department also has a wildcard.
866             return roles.isSystemAdmin();
867         } else {
868             return TKUser.getDepartmentAdminAreas(roles).contains(dept);
869         }
870     }
871 
872     @Override
873     public boolean canWildcardDeptInDeptRule(DepartmentalRule dr) {
874         return TKUser.isSystemAdmin();
875     }
876 
877     @Override
878     public boolean canEditOvertimeEarnCode(TimeBlock tb) {
879         WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(tb.getWorkArea(), new java.sql.Date(tb.getEndTimestamp().getTime()));
880         TkUserRoles userRoles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
881         Job job = TkServiceLocator.getJobService().getJob(tb.getPrincipalId(), tb.getJobNumber(), TKUtils.getTimelessDate(tb.getBeginDate()));
882         boolean isUserTimeblock = StringUtils.equals(TKContext.getPrincipalId(), tb.getPrincipalId());
883 
884         if (userRoles.isSystemAdmin()) {
885             return true;
886             } else if (StringUtils.equals(workArea.getOvertimeEditRole(), TkConstants.ROLE_TK_EMPLOYEE)) {
887                 return true;
888         } else if (StringUtils.equals(workArea.getOvertimeEditRole(), TkConstants.ROLE_TK_APPROVER) ||
889                     StringUtils.equals(workArea.getOvertimeEditRole(), TkConstants.ROLE_TK_APPROVER_DELEGATE)){
890             return !isUserTimeblock && (userRoles.getApproverWorkAreas().contains(workArea.getWorkArea()));
891         } else {
892             return false;
893         }
894     }
895 
896     /*
897      * @see org.kuali.hr.time.permissions.TkPermissionsService#canEditRegEarnCode(org.kuali.hr.time.timeblock.TimeBlock)
898      * this method is used in calendar.tag
899      * it's only used when a user is working on its own timesheet, regular earn code cannot be editable on clock entered time block
900      */
901     @Override
902     public boolean canEditRegEarnCode(TimeBlock tb) {
903     	AssignmentDescriptionKey adk = new AssignmentDescriptionKey(tb.getJobNumber().toString(), tb.getWorkArea().toString(), tb.getTask().toString());
904         Assignment anAssignment = TkServiceLocator.getAssignmentService().getAssignment(adk, tb.getBeginDate());
905         if(anAssignment != null) {
906         	// use timesheet's end date to get Time Collection Rule
907         	TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(tb.getDocumentId());
908         	Date aDate =  tb.getBeginDate();
909         	if(tdh != null && tdh.getEndDate() != null) {
910         		aDate = new java.sql.Date(tdh.getEndDate().getTime());
911         	}
912         	
913         	TimeCollectionRule tcr = TkServiceLocator.getTimeCollectionRuleService().getTimeCollectionRule(anAssignment.getDept(), anAssignment.getWorkArea(), anAssignment.getJob().getHrPayType(), aDate);
914         	if (tcr != null && tcr.isClockUserFl()) {
915         		// use assignment to get the payType object, then check if the regEarnCode of the paytyep matches the earn code of the timeblock
916         		// if they do match, then return false
917         		PayType pt = TkServiceLocator.getPayTypeService().getPayType(anAssignment.getJob().getHrPayType(), anAssignment.getJob().getEffectiveDate());
918         		if(pt != null && pt.getRegEarnCode().equals(tb.getEarnCode())) {
919         			return false;
920         		}
921         	}
922         }
923     	return true;
924     }
925 
926     @Override
927     public boolean canDeleteDeptLunchDeduction() {
928         return TKUser.isAnyApproverActive();
929     }
930 
931     @Override
932     public boolean canAddSystemLevelRole() {
933         // TODO Auto-generated method stub
934         return false;
935     }
936 
937     @Override
938     public boolean canAddLocationLevelRoles() {
939         // TODO Auto-generated method stub
940         return false;
941     }
942 
943     @Override
944     public boolean canAddDepartmentLevelRoles() {
945         // TODO Auto-generated method stub
946         return false;
947     }
948 
949     @Override
950     public boolean canAddWorkareaLevelRoles() {
951         // TODO Auto-generated method stub
952         return false;
953     }
954 
955     public boolean hasManagerialRolesOnWorkArea(TimeBlock tb) {
956         TkUserRoles roles = TkUserRoles.getUserRoles(TKContext.getPrincipalId());
957         return roles.getApproverWorkAreas().contains(tb.getWorkArea())
958                || roles.getReviewerWorkAreas().contains(tb.getWorkArea());
959     }
960     
961     @Override
962     public boolean canViewTimeTabs() {
963     	boolean canViewTimeTabs = false;
964     	Date asOfDate = TKUtils.getTimelessDate(null);
965     	String flsaStatus = TkConstants.FLSA_STATUS_NON_EXEMPT;
966     	// find active assignments as of currentDate
967     	String principalId = TKUser.getCurrentTargetPersonId();
968     	if(isActiveAssignmentFoundOnJobFlsaStatus(principalId, flsaStatus, false)) {
969     		//find timecalendar defined
970     		canViewTimeTabs = isCalendarDefined("payCalendar", principalId, asOfDate, false);
971     	}
972     	return canViewTimeTabs;
973     }
974     
975     private boolean isActiveAssignmentFoundOnJobFlsaStatus(String principalId, String flsaStatus, boolean chkForLeaveEligible) {
976     	boolean isActiveAssFound = false;
977     	Date asOfDate = TKUtils.getTimelessDate(null);
978      	List<Assignment> activeAssignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, asOfDate);
979      	if(activeAssignments != null && !activeAssignments.isEmpty()) {
980      		for(Assignment assignment : activeAssignments) {
981      			if(assignment != null && assignment.getJob() != null && assignment.getJob().getFlsaStatus() != null && assignment.getJob().getFlsaStatus().equalsIgnoreCase(flsaStatus)) {
982      				if(chkForLeaveEligible) {
983      					isActiveAssFound = assignment.getJob().isEligibleForLeave();
984      					if(!isActiveAssFound){
985      						continue;
986      					}
987      				}
988      				isActiveAssFound = true;
989      				break;
990      			}  
991      		}
992      	}
993     	return isActiveAssFound;
994     }
995     
996     private boolean isCalendarDefined(String calendarType, String principalId, Date asOfDate, boolean chkForLeavePlan){
997     	boolean calDefined = false;
998     	PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, asOfDate);
999     	if(principalHRAttributes != null) {
1000     		if(calendarType.equalsIgnoreCase("payCalendar")) {
1001     			calDefined = principalHRAttributes.getPayCalendar() != null ? true : false;
1002     		} else if(calendarType.equalsIgnoreCase("leaveCalendar")) {
1003     			calDefined = principalHRAttributes.getLeaveCalendar() != null ? true : false;
1004     			if(calDefined && chkForLeavePlan) {
1005     				calDefined = principalHRAttributes.getLeavePlan() != null ? true : false;
1006     			}
1007     		} 
1008     	}
1009     	return calDefined;
1010     }
1011     
1012     @Override
1013     public boolean canViewLeaveTabsWithEStatus() {
1014     	boolean canViewLeaveTabs = false;
1015     	String principalId = TKUser.getCurrentTargetPersonId();
1016     	Date asOfDate = TKUtils.getTimelessDate(null);
1017     	boolean leaveCalNPlanDefined = isCalendarDefined("leaveCalendar", principalId, asOfDate, true);
1018     	String flsaStatus = TkConstants.FLSA_STATUS_EXEMPT;
1019     	boolean activeAss = isActiveAssignmentFoundOnJobFlsaStatus(principalId, flsaStatus, true);
1020     	canViewLeaveTabs = activeAss && leaveCalNPlanDefined;
1021     	return canViewLeaveTabs;
1022     }
1023     
1024     @Override
1025     public boolean canViewLeaveTabsWithNEStatus() {
1026     	boolean canViewLeaveTabs = false;
1027     	Date asOfDate = TKUtils.getTimelessDate(null);
1028     	String flsaStatus = TkConstants.FLSA_STATUS_NON_EXEMPT;
1029     	// find active assignments as of currentDate
1030     	String principalId = TKUser.getCurrentTargetPersonId();
1031     	boolean activeAss = isActiveAssignmentFoundOnJobFlsaStatus(principalId, flsaStatus, true);
1032     	// chk leave plan defined
1033     	boolean leaveCalNPlanDefined = isCalendarDefined("leaveCalendar", principalId, asOfDate, true);
1034     	boolean timeCalDefined = isCalendarDefined("payCalendar", principalId, asOfDate, false);
1035     	canViewLeaveTabs = activeAss && leaveCalNPlanDefined && timeCalDefined;
1036     	return canViewLeaveTabs;
1037     }
1038 
1039 }