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