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