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