View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.time.roles;
17  
18  import java.util.HashMap;
19  import java.util.HashSet;
20  import java.util.List;
21  import java.util.Map;
22  import java.util.Set;
23  
24  import org.apache.commons.collections.CollectionUtils;
25  import org.apache.commons.collections.MapUtils;
26  import org.apache.commons.lang.StringUtils;
27  import org.kuali.hr.core.document.calendar.CalendarDocumentContract;
28  import org.kuali.hr.job.Job;
29  import org.kuali.hr.time.assignment.Assignment;
30  import org.kuali.hr.time.department.Department;
31  import org.kuali.hr.time.service.base.TkServiceLocator;
32  import org.kuali.hr.time.timesheet.TimesheetDocument;
33  import org.kuali.hr.time.util.TKContext;
34  import org.kuali.hr.time.util.TKUtils;
35  import org.kuali.hr.time.util.TkConstants;
36  import org.kuali.rice.krad.util.GlobalVariables;
37  
38  /**
39   * TkUserRoles encapsulates the concept of roles for a single user and provides
40   * lookup methods for quick Role checking. This object will be stored in TkUser.
41   */
42  public class TkUserRoles implements UserRoles {
43      private boolean synchronousAssignments = false;
44      private TkRole globalViewOnly;
45      private TkRole systemAdmin;
46      private String principalId;
47  
48      private Map<String, TkRole> orgAdminRolesDept = new HashMap<String, TkRole>();
49      private Map<String, TkRole> orgAdminRolesChart = new HashMap<String, TkRole>();
50      private Map<Long, TkRole> approverRoles = new HashMap<Long, TkRole>();
51      private Map<Long, TkRole> approverDelegateRoles = new HashMap<Long, TkRole>();
52      private Map<Long, TkRole> reviewerRoles = new HashMap<Long, TkRole>();
53  
54      private Map<String, TkRole> deptViewOnlyRoles = new HashMap<String, TkRole>();
55      private Set<String> activeAssignmentIds = new HashSet<String>();
56      
57      public static TkUserRoles getUserRoles(String principalId) {
58      	List<TkRole> roles = TkServiceLocator.getTkRoleService().getRoles(principalId, TKUtils.getCurrentDate());
59  		List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, TKUtils.getCurrentDate());
60  		
61  		return new TkUserRoles(principalId, roles, assignments);
62      }
63  
64      /**
65       * Does not keep reference to the assignment objects.  We just need the IDs,
66       * so in future refactoring, if we have a lighter weight call to obtain
67       * assignments, we could use that and modify this code.
68       *
69       * @param roles
70       * @param assignments
71       */
72      private TkUserRoles(String principalId, List<TkRole> roles, List<Assignment> assignments) {
73          this.principalId = principalId;
74          setRoles(roles);
75          setAssignments(assignments);
76      }
77  
78      @Override
79      public boolean isLocationAdmin() {
80          return CollectionUtils.isNotEmpty(getOrgAdminCharts());
81      }
82  
83      @Override
84      public boolean isDepartmentAdmin() {
85          return CollectionUtils.isNotEmpty(getOrgAdminDepartments());
86      }
87  
88      public String getPrincipalId() {
89          return principalId;
90      }
91  
92      public void setPrincipalId(String principalId) {
93          this.principalId = principalId;
94      }
95  
96      @Override
97      public Set<Long> getApproverWorkAreas() {
98          Set<Long> workAreas = new HashSet<Long>();
99          workAreas.addAll(approverRoles.keySet());
100         workAreas.addAll(approverDelegateRoles.keySet());
101         return workAreas;
102     }
103 
104     @Override
105     public Set<Long> getReviewerWorkAreas() {
106         return reviewerRoles.keySet();
107     }
108 
109     @Override
110     public Set<String> getOrgAdminDepartments() {
111         return orgAdminRolesDept.keySet();
112     }
113 
114     @Override
115     public Set<String> getOrgAdminCharts() {
116         return orgAdminRolesChart.keySet();
117     }
118 
119     @Override
120     public Set<String> getDepartmentViewOnlyDepartments() {
121         return deptViewOnlyRoles.keySet();
122     }
123 
124     /**
125      * Accessor method to obtain the Set of active Assignment ids for the
126      * current employee.
127      *
128      * @return a Set of active assignment IDs
129      */
130     @Override
131     public Set<String> getActiveAssignmentIds() {
132         return activeAssignmentIds;
133     }
134 
135     @Override
136     public boolean isSystemAdmin() {
137         return systemAdmin != null;
138     }
139 
140     @Override
141     public boolean isGlobalViewOnly() {
142         return globalViewOnly != null;
143     }
144 
145     public boolean isDeptViewOnly() {
146         return MapUtils.isNotEmpty(deptViewOnlyRoles);
147     }
148 
149     @Override
150     public boolean isSynchronous() {
151         return synchronousAssignments;
152     }
153     
154 	public boolean isReviewer() {
155 		return CollectionUtils.isNotEmpty(TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getReviewerWorkAreas());
156 	}
157 
158 	public boolean isApprover() {
159 		return CollectionUtils.isNotEmpty(TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas());
160 	}
161 
162     /**
163      * Place the TkRole objects in the provided List into their appropriate
164      * buckets for fast lookup.
165      *
166      * @param roles A List of TkRole objects for the current user.
167      */
168     public void setRoles(List<TkRole> roles) {
169         for (TkRole role : roles) {
170             if (role.getRoleName().equals(TkConstants.ROLE_TK_APPROVER)) {
171                 approverRoles.put(role.getWorkArea(), role);
172             } else if (role.getRoleName().equals(TkConstants.ROLE_TK_APPROVER_DELEGATE)) {
173                 approverDelegateRoles.put(role.getWorkArea(), role);
174             } else if (role.getRoleName().equals(TkConstants.ROLE_TK_LOCATION_ADMIN) ||
175             			role.getRoleName().equals(TkConstants.ROLE_LV_DEPT_ADMIN)) {
176                 if (!StringUtils.isEmpty(role.getChart())) {
177                     orgAdminRolesChart.put(role.getChart(), role);
178                     List<Department> ds = TkServiceLocator.getDepartmentService().getDepartments(role.getChart(), TKUtils.getCurrentDate());
179                     for (Department d : ds) {
180                         orgAdminRolesDept.put(d.getDept(), role);
181                     }
182                 }
183             } else if (StringUtils.equals(role.getRoleName(), TkConstants.ROLE_TK_LOCATION_VO)) {
184                 if (!StringUtils.isEmpty(role.getChart())) {
185                     List<Department> ds = TkServiceLocator.getDepartmentService().getDepartments(role.getChart(), TKUtils.getCurrentDate());
186                     for (Department dept : ds) {
187                         deptViewOnlyRoles.put(dept.getDept(), role);
188                     }
189 
190                 }
191             } else if (role.getRoleName().equals(TkConstants.ROLE_TK_SYS_ADMIN)) {
192                 systemAdmin = role;
193             } else if (role.getRoleName().equals(TkConstants.ROLE_TK_DEPT_VO)) {
194                 deptViewOnlyRoles.put(role.getDepartment(), role);
195             } else if (role.getRoleName().equals(TkConstants.ROLE_TK_DEPT_ADMIN)) {
196                 orgAdminRolesDept.put(role.getDepartment(), role);
197             } else if (role.getRoleName().equals(TkConstants.ROLE_TK_GLOBAL_VO)) {
198                 globalViewOnly = role;
199             } else if (role.getRoleName().equals(TkConstants.ROLE_TK_REVIEWER)) {
200                 reviewerRoles.put(role.getWorkArea(), role);
201             }
202         }
203     }
204 
205     public void setAssignments(List<Assignment> assignments) {
206         for (Assignment a : assignments) {
207             activeAssignmentIds.add(a.getTkAssignmentId());
208             if (a.isSynchronous())
209                 synchronousAssignments = true;
210         }
211     }
212 
213     @Override
214     public boolean isActiveEmployee() {
215         return CollectionUtils.isNotEmpty(this.activeAssignmentIds);
216     }
217 
218     @Override
219     public boolean isTimesheetApprover() {
220         return MapUtils.isNotEmpty(this.approverRoles) || MapUtils.isNotEmpty(this.approverDelegateRoles);
221     }
222 
223     public boolean isTimesheetReviewer() {
224         return CollectionUtils.isNotEmpty(this.getReviewerWorkAreas());
225     }
226 
227     @Override
228     public boolean isAnyApproverActive() {
229         return MapUtils.isNotEmpty(this.approverRoles) || MapUtils.isNotEmpty(this.approverDelegateRoles);
230     }
231 
232     //Todo: rename method.  this is also used for leave calendar
233     @Override
234     public boolean isApproverForTimesheet(CalendarDocumentContract doc) {
235         boolean approver = false;
236 
237         if (this.isSystemAdmin()) {
238             return true;
239         }
240 
241         List<Assignment> assignments = doc.getAssignments();
242         for (Assignment assignment : assignments) {
243             if (this.approverRoles.containsKey(assignment.getWorkArea()) || this.approverDelegateRoles.containsKey(assignment.getWorkArea())) {
244                 return true;
245             }
246         }
247 
248         return approver;
249     }
250 
251     //Todo: rename method.  this is also used for leave calendar
252     @Override
253     public boolean isApproverForTimesheet(String docId) {
254         boolean approver = false;
255 
256         TimesheetDocument doc = TkServiceLocator.getTimesheetService().getTimesheetDocument(docId);
257         if (doc != null)
258             approver = isApproverForTimesheet(doc);
259 
260         return approver;
261     }
262 
263     @Override
264     public boolean isDocumentWritable(CalendarDocumentContract document) {
265         boolean writable = false;
266 
267         // Quick escape.
268         if (document == null)
269             return writable;
270 
271         // Sysadmin
272         writable = this.isSystemAdmin();
273         // Owner (and not enroute/final)
274         writable |= (StringUtils.equals(this.principalId, document.getDocumentHeader().getPrincipalId())
275                 && (StringUtils.equals(TkConstants.ROUTE_STATUS.INITIATED, document.getDocumentHeader().getDocumentStatus()) ||
276                 StringUtils.equals(TkConstants.ROUTE_STATUS.SAVED, document.getDocumentHeader().getDocumentStatus()) ||
277                 (StringUtils.equals(TkConstants.ROUTE_STATUS.ENROUTE, document.getDocumentHeader().getDocumentStatus()))));
278 
279 
280         if (!writable) {
281             // Departmental View Only? || Reviewer || Org Admin || Approver
282             // (document object iteration)
283             List<Assignment> assignments = document.getAssignments();
284             for (Assignment assignment : assignments) {
285                 String dept = assignment.getDept();
286                 Long wa = assignment.getWorkArea();
287                 // Dept admins should not have write access
288                 //writable |= this.orgAdminRolesDept.containsKey(dept);
289                 writable |= this.approverRoles.containsKey(wa);
290                 writable |= this.approverDelegateRoles.containsKey(wa);
291                 writable |= this.reviewerRoles.containsKey(wa);
292             }
293         }
294 
295         return writable;
296     }
297 
298     @Override
299     public boolean isDocumentWritable(String documentId) {
300         return isDocumentWritable(TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId));
301     }
302 
303     @Override
304     public boolean isDocumentReadable(String documentId) {
305         boolean readable = false;
306 
307         if (documentId != null) {
308             return isDocumentReadable(TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId));
309         }
310 
311         return readable;
312     }
313 
314     @Override
315     public boolean isDocumentReadable(CalendarDocumentContract document) {
316         boolean readable = false;
317 
318         // Quick escape.
319         if (document == null)
320             return readable;
321 
322         // Sysadmin
323         readable = this.isSystemAdmin();
324         // Owner
325         readable |= StringUtils.equals(this.principalId, document.getDocumentHeader().getPrincipalId());
326         // Global VO
327         readable |= this.isGlobalViewOnly();
328 
329         if (!readable) {
330             // Departmental View Only? || Reviewer || Org Admin || Approver
331             // (document object iteration)
332             List<Assignment> assignments = document.getAssignments();
333             for (Assignment assignment : assignments) {
334                 String dept = assignment.getDept();
335                 Long wa = assignment.getWorkArea();
336 
337                 readable |= this.orgAdminRolesDept.containsKey(dept);
338                 readable |= this.approverRoles.containsKey(wa);
339                 readable |= this.approverDelegateRoles.containsKey(wa);
340                 readable |= this.reviewerRoles.containsKey(wa);
341                 readable |= this.deptViewOnlyRoles.containsKey(dept);
342                 readable |= this.reviewerRoles.containsKey(wa);
343             }
344         }
345 
346         return readable;
347     }
348 
349     private boolean isLocationAdmin(CalendarDocumentContract doc) {
350         for (Assignment assign : doc.getAssignments()) {
351             String location = assign.getJob().getLocation();
352             return this.orgAdminRolesChart.containsKey(location);
353         }
354         return false;
355     }
356 
357     private boolean isDepartmentAdmin(CalendarDocumentContract doc) {
358         for (Assignment assign : doc.getAssignments()) {
359             String dept = assign.getDept();
360             return this.orgAdminRolesDept.containsKey(dept);
361         }
362         return false;
363     }
364 
365     @Override
366     public boolean canSubmitTimesheet(CalendarDocumentContract doc) {
367         if (StringUtils.equals(TKContext.getPrincipalId(), doc.getDocumentHeader().getPrincipalId())) {
368             return true;
369         }
370 
371         if (this.isApproverForTimesheet(doc)) {
372             return true;
373         }
374 
375         //System admins can route the document as well as the employee
376         if (this.isSystemAdmin()) {
377             return true;
378         }
379         return false;
380     }
381 
382     @Override
383     public boolean canSubmitTimesheet(String docId) {
384         TimesheetDocument doc = TkServiceLocator.getTimesheetService().getTimesheetDocument(docId);
385         return canSubmitTimesheet(doc);
386     }
387 
388     @Override
389     public boolean isApproverForPerson(String principalId) {
390         List<Assignment> lstAssignment = TkServiceLocator.getAssignmentService().getAssignments(principalId, TKUtils.getCurrentDate());
391 
392         Set<Long> workAreas = getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).getApproverWorkAreas();
393         for (Assignment assignment : lstAssignment) {
394             if (workAreas.contains(assignment.getWorkArea())) {
395                 return true;
396             }
397         }
398 
399         return false;
400 
401     }
402 
403     @Override
404     public boolean isDepartmentAdminForPerson(String principalId) {
405     	List<Job> jobs = TkServiceLocator.getJobService().getJobs(principalId,TKUtils.getCurrentDate());
406         for (Job job : jobs) {
407             if (getOrgAdminDepartments().contains(job.getDept())) {
408                 return true;
409             }
410         }
411         return false;
412     }
413 
414     @Override
415     public boolean isDeptViewOnlyForPerson(String principalId) {
416     	List<Job> jobs = TkServiceLocator.getJobService().getJobs(principalId,TKUtils.getCurrentDate());
417         for (Job job : jobs) {
418             if (getDepartmentViewOnlyDepartments().contains(job.getDept())) {
419                 return true;
420             }
421         }
422         return false;
423     }
424 
425     @Override
426     public boolean isLocationAdminForPerson(String principalId) {
427         List<TkRole> roles = TkServiceLocator.getTkRoleService().getRoles(principalId, TKUtils.getCurrentDate());
428 
429         if (CollectionUtils.isNotEmpty(roles)) {
430             for (TkRole role : roles) {
431                 if (this.getOrgAdminCharts().contains(role.getChart())) {
432                     return true;
433                 }
434             }
435         }
436 
437         return false;
438     }
439 
440     @Override
441     public boolean isTimesheetReviewerForPerson(String principalId) {
442         List<Assignment> lstAssignment = TkServiceLocator.getAssignmentService().getAssignments(principalId, TKUtils.getCurrentDate());
443 
444         for (Assignment assignment : lstAssignment) {
445             if (getReviewerWorkAreas().contains(assignment.getWorkArea())) {
446                 return true;
447             }
448         }
449         return false;
450     }
451 }