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