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    
022    import org.apache.commons.collections.CollectionUtils;
023    import org.apache.commons.lang.StringUtils;
024    import org.apache.log4j.Logger;
025    import org.kuali.hr.job.Job;
026    import org.kuali.hr.lm.LMConstants;
027    import org.kuali.hr.lm.earncodesec.EarnCodeSecurity;
028    import org.kuali.hr.lm.leaveblock.LeaveBlock;
029    import org.kuali.hr.lm.timeoff.SystemScheduledTimeOff;
030    import org.kuali.hr.lm.workflow.LeaveRequestDocument;
031    import org.kuali.hr.time.assignment.Assignment;
032    import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
033    import org.kuali.hr.time.authorization.DepartmentalRule;
034    import org.kuali.hr.time.authorization.DepartmentalRuleAuthorizer;
035    import org.kuali.hr.time.calendar.CalendarEntries;
036    import org.kuali.hr.time.collection.rule.TimeCollectionRule;
037    import org.kuali.hr.time.paytype.PayType;
038    import org.kuali.hr.time.principal.PrincipalHRAttributes;
039    import org.kuali.hr.time.roles.TkUserRoles;
040    import org.kuali.hr.time.roles.UserRoles;
041    import org.kuali.hr.time.service.base.TkServiceLocator;
042    import org.kuali.hr.time.timeblock.TimeBlock;
043    import org.kuali.hr.time.timesheet.TimesheetDocument;
044    import org.kuali.hr.time.util.TKContext;
045    import org.kuali.hr.time.util.TKUser;
046    import org.kuali.hr.time.util.TKUtils;
047    import org.kuali.hr.time.util.TkConstants;
048    import org.kuali.hr.time.workarea.WorkArea;
049    import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
050    import org.kuali.rice.kew.api.KewApiConstants;
051    import org.kuali.rice.kew.doctype.SecuritySession;
052    import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
053    import org.kuali.rice.kew.service.KEWServiceLocator;
054    import org.kuali.rice.krad.util.GlobalVariables;
055    
056    public class TkPermissionsServiceImpl implements TkPermissionsService {
057        private static final Logger LOG = Logger
058                .getLogger(DepartmentalRuleAuthorizer.class);
059    
060        @Override
061        public boolean canAddTimeBlock() {
062            boolean addTimeBlock = false;
063    
064            if (TKUser.isSystemAdmin()) {
065                addTimeBlock = true;
066            } else {
067                boolean docFinal = TKContext.getCurrentTimesheetDocument()
068                        .getDocumentHeader().getDocumentStatus()
069                        .equals(TkConstants.ROUTE_STATUS.FINAL);
070                if (!docFinal) {
071                    if (StringUtils
072                            .equals(TKContext.getCurrentTimesheetDocument().getPrincipalId(),
073                                            GlobalVariables.getUserSession().getPrincipalId())
074                            || TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).isSystemAdmin()
075                            || TKUser.isLocationAdmin()
076    //                        || TKUser.isDepartmentAdmin()
077                            || TKUser.isReviewer()
078                            || TKUser.isApprover()) {
079                        addTimeBlock = true;
080                    }
081                }
082            }
083            return addTimeBlock;
084        }
085    
086        @Override
087        public boolean canEditTimeBlockAllFields(TimeBlock tb) {
088            String userId = GlobalVariables.getUserSession().getPrincipalId();
089    
090            if (userId != null) {
091    
092                if (TKUser.isSystemAdmin()) {
093                    return true;
094                }
095    
096                Job job = TkServiceLocator.getJobService().getJob(
097                        TKContext.getTargetPrincipalId(), tb.getJobNumber(),
098                        tb.getEndDate());
099                PayType payType = TkServiceLocator.getPayTypeService().getPayType(
100                        job.getHrPayType(), tb.getEndDate());
101    
102                if (TKUser.isTimesheetApprover()
103                        && TKUser.getApproverWorkAreas().contains(tb.getWorkArea())
104                        || TKUser.isTimesheetReviewer()
105                        && TKUser.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 (TKUser.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 (TKUser.isTimesheetApprover()
172                        && TKUser.getApproverWorkAreas().contains(tb.getWorkArea())
173                        || TKUser.isTimesheetReviewer()
174                        && TKUser.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 (TKUser.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 (TKUser.isTimesheetApprover()
253                        && TKUser.getApproverWorkAreas().contains(tb.getWorkArea())
254                        || TKUser.isTimesheetReviewer()
255                        && TKUser.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                //KPME-2264 -
305                // EE's should be able to remove timeblocks added via the time detail calendar only after checking prior conditions,
306                            if (userId.equals(TKContext.getTargetPrincipalId())) {
307                                    return true;
308                            } 
309                
310                List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator
311                        .getEarnCodeSecurityService().getEarnCodeSecurities(
312                                job.getDept(), job.getHrSalGroup(),
313                                job.getLocation(), tb.getEndDate());
314                for (EarnCodeSecurity dec : deptEarnCodes) {
315                    if (dec.isEmployee()
316                            && StringUtils.equals(dec.getEarnCode(),
317                            tb.getEarnCode())
318                            && hasManagerialRolesOnWorkArea(tb)) {
319                        return true;
320                    }
321                }
322    
323            }
324    
325            return false;
326        }
327    
328        @Override
329        public boolean canEditLeaveBlock(LeaveBlock lb) {
330            String userId = GlobalVariables.getUserSession().getPrincipalId();
331            
332            if (userId != null) {
333                String blockType = lb.getLeaveBlockType();
334                String requestStatus = lb.getRequestStatus();
335                if (StringUtils.equals(LMConstants.REQUEST_STATUS.DISAPPROVED, requestStatus)) {
336                    return false;
337                }
338                if (StringUtils.equals(LMConstants.REQUEST_STATUS.APPROVED, requestStatus)) {
339                    List<LeaveRequestDocument> docList= TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocumentsByLeaveBlockId(lb.getLmLeaveBlockId());
340                    if(CollectionUtils.isEmpty(docList)) {
341                            return false;   // not a leave request. if this is a leave request, do further checking on it
342                    }               
343                }
344                if (StringUtils.isBlank(blockType)
345                        || StringUtils.equals(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR, blockType)
346                        || StringUtils.equals(LMConstants.LEAVE_BLOCK_TYPE.TIME_CALENDAR, blockType)) {
347                    if (!TKUser.isDepartmentAdmin()) {
348                            return true;
349                    }
350                } else if (LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER.equals(blockType)
351                        || LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT.equals(blockType)
352                        || LMConstants.LEAVE_BLOCK_TYPE.DONATION_MAINT.equals(blockType)
353                        || LMConstants.LEAVE_BLOCK_TYPE.LEAVE_ADJUSTMENT_MAINT.equals(blockType)) {
354                    if (TKUser.isSystemAdmin()) {
355                        return true;
356                    }
357                }
358                // kpme-1689
359                if(StringUtils.equals(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE, blockType)
360                            && StringUtils.isNotEmpty(lb.getScheduleTimeOffId())
361                            && lb.getLeaveAmount().compareTo(BigDecimal.ZERO) == -1) {
362                    if(TKUser.isSystemAdmin()) {
363                            return true;
364                    }
365                    SystemScheduledTimeOff ssto = TkServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOff(lb.getScheduleTimeOffId());
366                    if(ssto != null && !StringUtils.equals(LMConstants.UNUSED_TIME.NO_UNUSED, ssto.getUnusedTime())) {
367                            return true;
368                    }
369                }
370            }
371    
372            return false;
373        }
374    
375        @Override
376        public boolean canDeleteLeaveBlock(LeaveBlock lb) {
377            if(StringUtils.equals(LMConstants.REQUEST_STATUS.DISAPPROVED, lb.getRequestStatus()))  {
378                return false;
379            }
380            if(canBankOrTransferSSTOUsage(lb)) {
381                    return true;
382            }
383            if (StringUtils.equals(LMConstants.REQUEST_STATUS.APPROVED, lb.getRequestStatus())) {
384                    List<LeaveRequestDocument> docList= TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocumentsByLeaveBlockId(lb.getLmLeaveBlockId());
385                    if(CollectionUtils.isEmpty(docList)) {
386                            return false;   // not a leave request
387                    }
388            }
389           
390            return canEditLeaveBlock(lb);
391        }
392    
393        @Override
394            public boolean canBankOrTransferSSTOUsage(LeaveBlock lb) {
395                    // if it's an accrual generated ssto usage leave block which can be banked or transferred, and on a current leave calendar,
396                // it can be deleted so the accrualed amount can be banked
397                return canBankSSTOUsage(lb) || canTransferSSTOUsage(lb);
398            }
399        
400        @Override
401            public boolean canBankSSTOUsage(LeaveBlock lb) {
402               if(lb.getAccrualGenerated() 
403                               && StringUtils.isNotEmpty(lb.getScheduleTimeOffId()) 
404                               && lb.getLeaveAmount().compareTo(BigDecimal.ZERO) < 0) {
405                       SystemScheduledTimeOff ssto = TkServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOff(lb.getScheduleTimeOffId());
406                       if(ssto != null && StringUtils.equals(ssto.getUnusedTime(), LMConstants.UNUSED_TIME.BANK)) {
407                               Date currentDate = TKUtils.getTimelessDate(null);
408                               String viewPrincipal = TKUser.getCurrentTargetPersonId();
409                               CalendarEntries ce = TkServiceLocator.getCalendarService()
410                                                    .getCurrentCalendarDatesForLeaveCalendar(viewPrincipal, currentDate);
411                               if(ce != null) {
412                                       if(!lb.getLeaveDate().before(ce.getBeginPeriodDate()) && !lb.getLeaveDate().after(ce.getEndPeriodDate())) {
413                                               return true;
414                                       }
415                               }
416                              
417                       }
418               }
419               return false;
420            }
421        @Override
422            public boolean canTransferSSTOUsage(LeaveBlock lb) {
423               if(lb.getAccrualGenerated() 
424                               && StringUtils.isNotEmpty(lb.getScheduleTimeOffId()) 
425                               && lb.getLeaveAmount().compareTo(BigDecimal.ZERO) < 0) {
426                       SystemScheduledTimeOff ssto = TkServiceLocator.getSysSchTimeOffService().getSystemScheduledTimeOff(lb.getScheduleTimeOffId());
427                       if(ssto != null && StringUtils.equals(ssto.getUnusedTime(), LMConstants.UNUSED_TIME.TRANSFER)) {
428                               Date currentDate = TKUtils.getTimelessDate(null);
429                               String viewPrincipal = TKUser.getCurrentTargetPersonId();
430                               CalendarEntries ce = TkServiceLocator.getCalendarService()
431                                                    .getCurrentCalendarDatesForLeaveCalendar(viewPrincipal, currentDate);
432                               if(ce != null) {
433                                       if(!lb.getLeaveDate().before(ce.getBeginPeriodDate()) && !lb.getLeaveDate().after(ce.getEndPeriodDate())) {
434                                               return true;
435                                       }
436                               }
437                              
438                       }
439               }
440               return false;
441            }
442    
443        @Override
444        public boolean canViewAdminTab() {
445            UserRoles ur = TKUser.getCurrentTargetRoles();
446    
447            boolean viewAdminTab = ur.isSystemAdmin() || ur.isLocationAdmin()
448                    || ur.isDepartmentAdmin() || ur.isGlobalViewOnly();
449    
450            return viewAdminTab;
451        }
452    
453        @Override
454        public boolean canViewApproverTab() {
455            UserRoles ur = TKUser.getCurrentTargetRoles();
456    
457            boolean viewApproverTab = ur.isSystemAdmin()
458                    || ur.isTimesheetApprover() || ur.isTimesheetReviewer();
459    
460            return viewApproverTab;
461        }
462    
463        @Override
464        public boolean canViewClockTab() {
465            UserRoles ur = TKUser.getCurrentTargetRoles();
466    
467            return ur.isActiveEmployee() && ur.isSynchronous();
468        }
469    
470        @Override
471        public boolean canViewBatchJobsTab() {
472            UserRoles ur = TKUser.getCurrentTargetRoles();
473    
474            return ur.isSystemAdmin();
475        }
476    
477        @Override
478        public boolean canViewPersonInfoTab() {
479            return true;
480        }
481    
482        @Override
483        public boolean canViewTimeDetailTab() {
484            UserRoles ur = TKUser.getCurrentTargetRoles();
485    
486            return ur.isActiveEmployee();
487        }
488    
489        @Override
490        public boolean canViewLeaveAccrualTab() {
491            UserRoles ur = TKUser.getCurrentTargetRoles();
492    
493            return ur.isActiveEmployee();
494        }
495    
496        @Override
497        public boolean canViewTimesheet(String documentId) {
498            boolean viewTimeSheet = false;
499    
500            if (documentId != null) {
501                return canViewTimesheet(TkServiceLocator.getTimesheetService()
502                        .getTimesheetDocument(documentId));
503            }
504    
505            return viewTimeSheet;
506        }
507    
508        @Override
509        public boolean canViewTimesheet(TimesheetDocument document) {
510            boolean viewTimeSheet = false;
511            UserRoles ur = TKUser.getCurrentTargetRoles();
512    
513            if (document == null)
514                return viewTimeSheet;
515    
516            // Sysadmin
517            viewTimeSheet = ur.isSystemAdmin();
518            // Owner
519            viewTimeSheet |= StringUtils.equals(ur.getPrincipalId(),
520                    document.getPrincipalId());
521            // Global VO
522            viewTimeSheet |= ur.isGlobalViewOnly();
523    
524            if (!viewTimeSheet) {
525                // Departmental View Only? || Reviewer || Org Admin || Approver
526                // (document object iteration)
527                List<Assignment> assignments = document.getAssignments();
528                for (Assignment assignment : assignments) {
529                    String dept = assignment.getDept();
530                    Long wa = assignment.getWorkArea();
531    
532                    viewTimeSheet |= ur.getOrgAdminDepartments().contains(dept);
533                    viewTimeSheet |= ur.getApproverWorkAreas().contains(wa);
534                    viewTimeSheet |= ur.getReviewerWorkAreas().contains(wa);
535                    viewTimeSheet |= ur.getDepartmentViewOnlyDepartments()
536                            .contains(dept);
537                }
538            }
539    
540            return viewTimeSheet;
541        }
542    
543        @Override
544        public boolean canEditTimesheet(TimesheetDocument document) {
545            boolean editTimeSheet = false;
546            UserRoles ur = TKUser.getCurrentTargetRoles();
547    
548            // Quick escape.
549            if (document == null)
550                return editTimeSheet;
551    
552            // Sysadmin
553            editTimeSheet = ur.isSystemAdmin();
554            // Owner (and not enroute/final)
555            editTimeSheet |= (StringUtils.equals(ur.getPrincipalId(),
556                    document.getPrincipalId()) && (StringUtils.equals(
557                    TkConstants.ROUTE_STATUS.INITIATED, document
558                    .getDocumentHeader().getDocumentStatus())
559                    || StringUtils.equals(TkConstants.ROUTE_STATUS.SAVED, document
560                    .getDocumentHeader().getDocumentStatus()) || (StringUtils
561                    .equals(TkConstants.ROUTE_STATUS.ENROUTE, document
562                            .getDocumentHeader().getDocumentStatus()))));
563    
564            if (!editTimeSheet) {
565                // Departmental View Only? || Reviewer || Org Admin || Approver
566                // (document object iteration)
567                List<Assignment> assignments = document.getAssignments();
568                for (Assignment assignment : assignments) {
569                    String dept = assignment.getDept();
570                    Long wa = assignment.getWorkArea();
571    
572                    editTimeSheet |= ur.getOrgAdminDepartments().contains(dept);
573                    editTimeSheet |= ur.getApproverWorkAreas().contains(wa);
574                    editTimeSheet |= ur.getReviewerWorkAreas().contains(wa);
575                }
576            }
577    
578            return editTimeSheet;
579        }
580    
581        @Override
582        public boolean canEditTimesheet(String documentId) {
583            return canEditTimesheet(TkServiceLocator.getTimesheetService()
584                    .getTimesheetDocument(documentId));
585        }
586    
587        @Override
588        public boolean canApproveTimesheet(TimesheetDocument doc) {
589    
590            TimesheetDocumentHeader docHeader = TkServiceLocator
591                    .getTimesheetDocumentHeaderService().getDocumentHeader(
592                            doc.getDocumentId());
593            boolean isEnroute = StringUtils.equals(docHeader.getDocumentStatus(),
594                    "ENROUTE");
595    
596            if (isEnroute) {
597                DocumentRouteHeaderValue routeHeader = KEWServiceLocator
598                        .getRouteHeaderService().getRouteHeader(doc.getDocumentId());
599                boolean authorized = KEWServiceLocator.getDocumentSecurityService()
600                        .routeLogAuthorized(TKContext.getPrincipalId(),
601                                routeHeader,
602                                new SecuritySession(TKContext.getPrincipalId()));
603                if (authorized) {
604                    List<String> principalsToApprove = KEWServiceLocator
605                            .getActionRequestService()
606                            .getPrincipalIdsWithPendingActionRequestByActionRequestedAndDocId(
607                                    KewApiConstants.ACTION_REQUEST_APPROVE_REQ,
608                                    routeHeader.getDocumentId());
609                    if (!principalsToApprove.isEmpty()
610                            && principalsToApprove.contains(TKContext
611                            .getPrincipalId())) {
612                        return true;
613                    }
614                }
615            }
616            return false;
617        }
618    
619        @Override
620        public boolean canSubmitTimesheet(TimesheetDocument doc) {
621            UserRoles ur = TKUser.getCurrentTargetRoles();
622    
623            if (StringUtils
624                    .equals(TKContext.getPrincipalId(), doc.getPrincipalId())) {
625                return true;
626            }
627    
628            if (ur.isApproverForTimesheet(doc)) {
629                return true;
630            }
631    
632            // System admins can route the document as well as the employee
633            if (ur.isSystemAdmin()) {
634                return true;
635            }
636            return false;
637        }
638    
639        @Override
640        public boolean canSubmitTimesheet(String docId) {
641            TimesheetDocument doc = TkServiceLocator.getTimesheetService()
642                    .getTimesheetDocument(docId);
643            return canSubmitTimesheet(doc);
644        }
645    
646        @Override
647        public boolean canViewLinkOnMaintPages() {
648            return TKUser.isSystemAdmin()
649                    || TKUser.isGlobalViewOnly();
650        }
651    
652        @Override
653        public boolean canViewDeptMaintPages() {
654            UserRoles ur = TKUser.getCurrentTargetRoles();
655    
656            return ur.isSystemAdmin() || ur.isGlobalViewOnly()
657                    || ur.getOrgAdminCharts().size() > 0
658                    || ur.getOrgAdminDepartments().size() > 0
659                    || ur.getDepartmentViewOnlyDepartments().size() > 0
660                    || ur.isAnyApproverActive();
661        }
662    
663        @Override
664        public boolean canViewDeptMaintPages(DepartmentalRule dr) {
665            boolean ret = false;
666            if (TKUser.isSystemAdmin() || TKUser.isGlobalViewOnly())
667                return true;
668    
669            if (dr != null) {
670                // dept | workArea | meaning
671                // ---------|------------|
672                // 1: % , -1 , any dept/work area valid roles
673                // *2: % , <defined> , must have work area <-- *
674                // 3: <defined>, -1 , must have dept, any work area
675                // 4: <defined>, <defined> , must have work area or department
676                // defined
677                //
678                // * Not permitted.
679    
680                if (StringUtils
681                        .equals(dr.getDept(), TkConstants.WILDCARD_CHARACTER)
682                        && dr.getWorkArea().equals(TkConstants.WILDCARD_LONG)) {
683                    // case 1
684                    ret = TKUser.isApprover()
685                            || TKUser.getLocationAdminAreas().size() > 0
686                            || TKUser.getDepartmentAdminAreas().size() > 0;
687                } else if (StringUtils.equals(dr.getDept(),
688                        TkConstants.WILDCARD_CHARACTER)) {
689                    // case 2 *
690                    // Should not encounter this case.
691                    LOG.error("Invalid case encountered while scanning business objects: Wildcard Department & Defined workArea.");
692                } else if (dr.getWorkArea().equals(TkConstants.WILDCARD_LONG)) {
693                    // case 3
694                    ret = TKUser.getDepartmentAdminAreas().contains(dr.getDept());
695                } else {
696                    ret = TKUser.getApproverWorkAreas().contains(dr.getWorkArea())
697                            || TKUser.getDepartmentAdminAreas().contains(dr.getDept());
698                }
699            }
700    
701            return ret;
702        }
703    
704        @Override
705        public boolean canEditDeptMaintPages() {
706            UserRoles ur = TKUser.getCurrentTargetRoles();
707            return ur.isSystemAdmin() || ur.getOrgAdminCharts().size() > 0
708                    || ur.getOrgAdminDepartments().size() > 0;
709        }
710    
711        @Override
712        public boolean canEditDeptMaintPages(DepartmentalRule dr) {
713            boolean ret = false;
714            if (TKUser.isSystemAdmin())
715                return true;
716    
717            if (dr != null && TKUser.getDepartmentAdminAreas().size() > 0) {
718                String dept = dr.getDept();
719                if (StringUtils.equals(dept, TkConstants.WILDCARD_CHARACTER)) {
720                    // Must be system administrator
721                    ret = false;
722                } else {
723                    // Must have parent Department
724                    ret = TKUser.getDepartmentAdminAreas().contains(dr.getDept());
725                }
726            }
727    
728            return ret;
729        }
730    
731        @Override
732        public boolean canWildcardWorkAreaInDeptRule(DepartmentalRule dr) {
733            // Sysadmins and (Departmental OrgAdmins for their Department)
734            if (TKUser.isSystemAdmin())
735                return true;
736    
737            String dept = dr.getDept();
738            if (StringUtils.equals(dept, TkConstants.WILDCARD_CHARACTER)) {
739                // Only system administrators can wildcard the work area if the
740                // department also has a wildcard.
741                return TKUser.isSystemAdmin();
742            } else {
743                return TKUser.getDepartmentAdminAreas().contains(dept);
744            }
745        }
746    
747        @Override
748        public boolean canWildcardDeptInDeptRule(DepartmentalRule dr) {
749            return TKUser.isSystemAdmin();
750        }
751    
752        @Override
753        public boolean canEditOvertimeEarnCode(TimeBlock tb) {
754            WorkArea workArea = TkServiceLocator.getWorkAreaService().getWorkArea(tb.getWorkArea(), new java.sql.Date(tb.getEndTimestamp().getTime()));
755            if (StringUtils.equals(workArea.getOvertimeEditRole(), TkConstants.ROLE_TK_EMPLOYEE)) {
756                return true;
757            } else if (StringUtils.equals(workArea.getOvertimeEditRole(), TkConstants.ROLE_TK_APPROVER) ||
758                    StringUtils.equals(workArea.getOvertimeEditRole(), TkConstants.ROLE_TK_APPROVER_DELEGATE)) {
759                return TKUser.getApproverWorkAreas().contains(workArea.getWorkArea());
760            } else {
761                return TKUser.getDepartmentAdminAreas().contains(workArea.getDepartment().getDept());
762            }
763        }
764        
765        /*
766         * @see org.kuali.hr.time.permissions.TkPermissionsService#canEditRegEarnCode(org.kuali.hr.time.timeblock.TimeBlock)
767         * this method is used in calendar.tag
768         * it's only used when a user is working on its own timesheet, regular earn code cannot be editable on clock entered time block
769         */
770        @Override
771        public boolean canEditRegEarnCode(TimeBlock tb) {
772            AssignmentDescriptionKey adk = new AssignmentDescriptionKey(tb.getJobNumber().toString(), tb.getWorkArea().toString(), tb.getTask().toString());
773            Assignment anAssignment = TkServiceLocator.getAssignmentService().getAssignment(adk, tb.getBeginDate());
774            if(anAssignment != null) {
775                    // use timesheet's end date to get Time Collection Rule
776                    TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(tb.getDocumentId());
777                    Date aDate =  tb.getBeginDate();
778                    if(tdh != null && tdh.getEndDate() != null) {
779                            aDate = new java.sql.Date(tdh.getEndDate().getTime());
780                    }
781                    
782                    TimeCollectionRule tcr = TkServiceLocator.getTimeCollectionRuleService().getTimeCollectionRule(anAssignment.getDept(), anAssignment.getWorkArea(), anAssignment.getJob().getHrPayType(), aDate);
783                    if (tcr == null || tcr.isClockUserFl()) {
784                            // use assignment to get the payType object, then check if the regEarnCode of the paytyep matches the earn code of the timeblock
785                            // if they do match, then return false
786                            PayType pt = TkServiceLocator.getPayTypeService().getPayType(anAssignment.getJob().getHrPayType(), anAssignment.getJob().getEffectiveDate());
787                            if(pt != null && pt.getRegEarnCode().equals(tb.getEarnCode())) {
788                                    return false;
789                            }
790                    }
791            }
792            return true;
793        }
794    
795        @Override
796        public boolean canDeleteDeptLunchDeduction() {
797            return TKUser.isAnyApproverActive();
798        }
799    
800        @Override
801        public boolean canAddSystemLevelRole() {
802            // TODO Auto-generated method stub
803            return false;
804        }
805    
806        @Override
807        public boolean canAddLocationLevelRoles() {
808            // TODO Auto-generated method stub
809            return false;
810        }
811    
812        @Override
813        public boolean canAddDepartmentLevelRoles() {
814            // TODO Auto-generated method stub
815            return false;
816        }
817    
818        @Override
819        public boolean canAddWorkareaLevelRoles() {
820            // TODO Auto-generated method stub
821            return false;
822        }
823    
824        public boolean hasManagerialRolesOnWorkArea(TimeBlock tb) {
825            return TKUser.getApproverWorkAreas().contains(tb.getWorkArea())
826                   || TKUser.getReviewerWorkAreas().contains(tb.getWorkArea());
827        }
828        
829        @Override
830        public boolean canViewTimeTabs() {
831            boolean canViewTimeTabs = false;
832            Date asOfDate = TKUtils.getTimelessDate(null);
833            String flsaStatus = TkConstants.FLSA_STATUS_NON_EXEMPT;
834            // find active assignments as of currentDate
835            String principalId = TKUser.getCurrentTargetPersonId();
836            if(isActiveAssignmentFoundOnJobFlsaStatus(principalId, flsaStatus, false)) {
837                    //find timecalendar defined
838                    canViewTimeTabs = isCalendarDefined("payCalendar", principalId, asOfDate, false);
839            }
840            return canViewTimeTabs;
841        }
842        
843        private boolean isActiveAssignmentFoundOnJobFlsaStatus(String principalId, String flsaStatus, boolean chkForLeaveEligible) {
844            boolean isActiveAssFound = false;
845            Date asOfDate = TKUtils.getTimelessDate(null);
846            List<Assignment> activeAssignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, asOfDate);
847            if(activeAssignments != null && !activeAssignments.isEmpty()) {
848                    for(Assignment assignment : activeAssignments) {
849                            if(assignment != null && assignment.getJob() != null && assignment.getJob().getFlsaStatus() != null && assignment.getJob().getFlsaStatus().equalsIgnoreCase(flsaStatus)) {
850                                    if(chkForLeaveEligible) {
851                                            isActiveAssFound = assignment.getJob().isEligibleForLeave();
852                                            if(!isActiveAssFound){
853                                                    continue;
854                                            }
855                                    }
856                                    isActiveAssFound = true;
857                                    break;
858                            }  
859                    }
860            }
861            return isActiveAssFound;
862        }
863        
864        private boolean isCalendarDefined(String calendarType, String principalId, Date asOfDate, boolean chkForLeavePlan){
865            boolean calDefined = false;
866            PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, asOfDate);
867            if(principalHRAttributes != null) {
868                    if(calendarType.equalsIgnoreCase("payCalendar")) {
869                            calDefined = principalHRAttributes.getPayCalendar() != null ? true : false;
870                    } else if(calendarType.equalsIgnoreCase("leaveCalendar")) {
871                            calDefined = principalHRAttributes.getLeaveCalendar() != null ? true : false;
872                            if(calDefined && chkForLeavePlan) {
873                                    calDefined = principalHRAttributes.getLeavePlan() != null ? true : false;
874                            }
875                    } 
876            }
877            return calDefined;
878        }
879        
880        @Override
881        public boolean canViewLeaveTabsWithEStatus() {
882            boolean canViewLeaveTabs = false;
883            String principalId = TKUser.getCurrentTargetPersonId();
884            Date asOfDate = TKUtils.getTimelessDate(null);
885            boolean leaveCalNPlanDefined = isCalendarDefined("leaveCalendar", principalId, asOfDate, true);
886            String flsaStatus = TkConstants.FLSA_STATUS_EXEMPT;
887            boolean activeAss = isActiveAssignmentFoundOnJobFlsaStatus(principalId, flsaStatus, true);
888            canViewLeaveTabs = activeAss && leaveCalNPlanDefined;
889            return canViewLeaveTabs;
890        }
891        
892        @Override
893        public boolean canViewLeaveTabsWithNEStatus() {
894            boolean canViewLeaveTabs = false;
895            Date asOfDate = TKUtils.getTimelessDate(null);
896            String flsaStatus = TkConstants.FLSA_STATUS_NON_EXEMPT;
897            // find active assignments as of currentDate
898            String principalId = TKUser.getCurrentTargetPersonId();
899            boolean activeAss = isActiveAssignmentFoundOnJobFlsaStatus(principalId, flsaStatus, true);
900            // chk leave plan defined
901            boolean leaveCalNPlanDefined = isCalendarDefined("leaveCalendar", principalId, asOfDate, true);
902            boolean timeCalDefined = isCalendarDefined("payCalendar", principalId, asOfDate, false);
903            canViewLeaveTabs = activeAss && leaveCalNPlanDefined && timeCalDefined;
904            return canViewLeaveTabs;
905        }
906    
907    }