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