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.dao;
17  
18  import java.sql.Date;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.List;
22  
23  import org.apache.commons.collections.CollectionUtils;
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.ojb.broker.query.Criteria;
26  import org.apache.ojb.broker.query.Query;
27  import org.apache.ojb.broker.query.QueryFactory;
28  import org.apache.ojb.broker.query.ReportQueryByCriteria;
29  import org.kuali.hr.job.Job;
30  import org.kuali.hr.time.roles.TkRole;
31  import org.kuali.hr.time.service.base.TkServiceLocator;
32  import org.kuali.hr.time.util.TKUtils;
33  import org.kuali.hr.time.util.TkConstants;
34  import org.kuali.hr.time.workarea.WorkArea;
35  import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
36  import org.kuali.rice.krad.service.KRADServiceLocator;
37  
38  public class TkRoleDaoSpringOjbImpl extends PlatformAwareDaoBaseOjb implements TkRoleDao {
39  
40      public List<TkRole> findAllRoles(String principalId, Date asOfDate) {
41          return findRoles(principalId, asOfDate, null, null, null, null);
42      }
43  
44      @SuppressWarnings("unchecked")
45      @Override
46      public List<TkRole> findPositionRoles(String positionNumber, Date asOfDate, String roleName, Long workArea, String department, String chart) {
47          List<TkRole> roles = new ArrayList<TkRole>();
48  
49          Criteria root = new Criteria();
50          Criteria effdt = new Criteria();
51          Criteria timestamp = new Criteria();
52          ReportQueryByCriteria effdtSubQuery;
53          ReportQueryByCriteria timestampSubQuery;
54  
55          effdt.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
56          effdt.addEqualToField("positionNumber", Criteria.PARENT_QUERY_PREFIX + "positionNumber");
57          effdt.addLessOrEqualThan("effectiveDate", asOfDate);
58  
59          // EFFECTIVE DATE --
60  
61          // Adding criteria to nest an AND that has multiple ORs to select
62          // the correct ID / date combination.
63          Criteria orWrapperEd = new Criteria();
64          Criteria nstWaEd = new Criteria();
65          Criteria nstDptEd = new Criteria();
66          Criteria nstChrEd = new Criteria();
67  
68          // Inner AND to allow for all null chart/dept/work area
69          Criteria nullAndWrapper = new Criteria();
70          nullAndWrapper.addIsNull("workArea");
71          nullAndWrapper.addIsNull("department");
72          nullAndWrapper.addIsNull("chart");
73  
74          nstWaEd.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea"); // OR
75          nstDptEd.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department"); // OR
76          nstChrEd.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart"); // OR
77          orWrapperEd.addOrCriteria(nstWaEd);
78          orWrapperEd.addOrCriteria(nstDptEd);
79          orWrapperEd.addOrCriteria(nstChrEd);
80  
81          // Inner AND to allow for all null chart/dept/work area
82          orWrapperEd.addOrCriteria(nullAndWrapper);
83  
84          // Add the inner OR criteria to effective date
85          effdt.addAndCriteria(orWrapperEd);
86  
87          effdtSubQuery = QueryFactory.newReportQuery(TkRole.class, effdt);
88          effdtSubQuery.setAttributes(new String[]{"max(effectiveDate)"});
89  
90  
91          // TIMESTAMP --
92  
93          //Configure the actual "criteria" in the where clause
94          timestamp.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
95          timestamp.addEqualToField("positionNumber", Criteria.PARENT_QUERY_PREFIX + "positionNumber");
96          timestamp.addEqualToField("effectiveDate", Criteria.PARENT_QUERY_PREFIX + "effectiveDate");
97  
98          // Adding criteria to nest an AND that has multiple ORs to select
99          // the correct ID / date combination.
100         orWrapperEd = new Criteria();
101         nstWaEd = new Criteria();
102         nstDptEd = new Criteria();
103         nstChrEd = new Criteria();
104 
105         // Inner AND to allow for all null chart/dept/work area
106         nullAndWrapper = new Criteria();
107         nullAndWrapper.addIsNull("workArea");
108         nullAndWrapper.addIsNull("department");
109         nullAndWrapper.addIsNull("chart");
110 
111         nstWaEd.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea"); // OR
112         nstDptEd.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department"); // OR
113         nstChrEd.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart"); // OR
114         orWrapperEd.addOrCriteria(nstWaEd);
115         orWrapperEd.addOrCriteria(nstDptEd);
116         orWrapperEd.addOrCriteria(nstChrEd);
117 
118         // Inner AND to allow for all null chart/dept/work area
119         orWrapperEd.addOrCriteria(nullAndWrapper);
120 
121         // Add the inner OR criteria to effective date
122         timestamp.addAndCriteria(orWrapperEd);
123 
124         timestampSubQuery = QueryFactory.newReportQuery(TkRole.class, timestamp);
125         timestampSubQuery.setAttributes(new String[]{"max(timestamp)"});
126 
127 
128         // Filter by Max(EffDt) / Max(Timestamp)
129         root.addEqualTo("effectiveDate", effdtSubQuery);
130         root.addEqualTo("timestamp", timestampSubQuery);
131 
132         // Optional ROOT criteria added :
133         if (workArea != null)
134             root.addEqualTo("workArea", workArea);
135         if (StringUtils.isNotEmpty(department))
136             root.addEqualTo("department", department);
137         if (chart != null)
138             root.addEqualTo("chart", chart);
139         if (roleName != null)
140             root.addEqualTo("roleName", roleName);
141         if (positionNumber != null)
142             root.addEqualTo("positionNumber", positionNumber);
143 
144         // Filter for ACTIVE = 'Y'
145         Criteria activeFilter = new Criteria();
146         activeFilter.addEqualTo("active", true);
147         root.addAndCriteria(activeFilter);
148 
149         Query query = QueryFactory.newQuery(TkRole.class, root);
150         Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
151 
152         if (c != null) {
153             roles.addAll(c);
154         }
155 
156         return roles;
157     }
158 
159     @SuppressWarnings("unchecked")
160     @Override
161     public List<TkRole> findRoles(String principalId, Date asOfDate, String roleName, Long workArea, String department, String chart) {
162         List<TkRole> roles = new ArrayList<TkRole>();
163 
164         Criteria root = new Criteria();
165 
166         if (StringUtils.isNotEmpty(principalId)) {
167             root.addEqualTo("principalId", principalId);
168         }
169 
170         if (asOfDate != null) {
171         	Criteria effdt = new Criteria();
172 	        effdt.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
173 	        effdt.addEqualToField("principalId", Criteria.PARENT_QUERY_PREFIX + "principalId");
174 	        effdt.addLessOrEqualThan("effectiveDate", asOfDate);
175 	        if (workArea != null || StringUtils.isNotEmpty(department) || StringUtils.isNotEmpty(chart)) {
176 	            if (workArea != null)
177 	                effdt.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea");
178 	            if (department != null)
179 	                effdt.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department");
180 	            if (chart != null)
181 	                effdt.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart");
182 	        }
183 	
184             Criteria timestamp = new Criteria();
185 	        timestamp.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
186 	        timestamp.addEqualToField("principalId", Criteria.PARENT_QUERY_PREFIX + "principalId");
187 	        timestamp.addEqualToField("effectiveDate", Criteria.PARENT_QUERY_PREFIX + "effectiveDate");
188 	        if (workArea != null || StringUtils.isNotEmpty(department) || StringUtils.isNotEmpty(chart)) {
189 	            if (workArea != null)
190 	                timestamp.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea");
191 	            if (department != null)
192 	                timestamp.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department");
193 	            if (chart != null)
194 	                timestamp.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart");
195 	        }
196 	
197 	        ReportQueryByCriteria timestampSubQuery;
198 	        timestampSubQuery = QueryFactory.newReportQuery(TkRole.class, timestamp);
199 	        timestampSubQuery.setAttributes(new String[]{"max(timestamp)"});
200 	
201 	        effdt.addEqualTo("timestamp", timestampSubQuery);
202 	
203 	        ReportQueryByCriteria effdtSubQuery;
204 	        effdtSubQuery = QueryFactory.newReportQuery(TkRole.class, effdt);
205 	        effdtSubQuery.setAttributes(new String[]{"max(effectiveDate)"});
206 	
207 	        root.addEqualTo("effectiveDate", effdtSubQuery);
208         }
209         
210         if (StringUtils.isNotEmpty(roleName)) {
211             root.addEqualTo("roleName", roleName);
212         }
213         
214         if (workArea != null) {
215             root.addEqualTo("workArea", workArea);
216         }
217 
218         if (StringUtils.isNotEmpty(department)) {
219             Criteria departmentCriteria = new Criteria();
220             departmentCriteria.addEqualTo("department", department);
221             Collection<WorkArea> collectionWorkAreas = TkServiceLocator.getWorkAreaService().getWorkAreas(department, asOfDate);
222             if (CollectionUtils.isNotEmpty(collectionWorkAreas)) {
223                 List<Long> longWorkAreas = new ArrayList<Long>();
224                 for(WorkArea cwa : collectionWorkAreas){
225                     longWorkAreas.add(cwa.getWorkArea());
226                 }
227                 Criteria workAreaCriteria = new Criteria();
228                 workAreaCriteria.addIn("workArea", longWorkAreas);
229                 departmentCriteria.addOrCriteria(workAreaCriteria);
230             }
231             root.addAndCriteria(departmentCriteria);
232         }
233         
234         if (StringUtils.isNotEmpty(chart)) {
235             root.addEqualTo("chart", chart);
236         }
237 
238         root.addEqualTo("active", true);
239 
240         Query query = QueryFactory.newQuery(TkRole.class, root);
241         // limit the number of the resultset
242         // TODO: hard coding the limits?  probably not the most user friendly of ways to do this
243         query.setStartAtIndex(0);
244         query.setEndAtIndex(299);
245         Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
246 
247         if (c != null) {
248             roles.addAll(c);
249         }
250 
251         if (StringUtils.isNotBlank(principalId)) {
252             //Fetch all the jobs and grab any position roles for this persons jobs
253             List<Job> lstActiveJobs = TkServiceLocator.getJobService().getJobs(principalId, asOfDate);
254             for (Job job : lstActiveJobs) {
255                 if (job.getPositionNumber() != null) {
256                     List<TkRole> lstRoles = findPositionRoles(job.getPositionNumber(),
257                             asOfDate, roleName, workArea, department, chart);
258                     roles.addAll(lstRoles);
259                 }
260             }
261         } else if (workArea != null) {
262             List<TkRole> lstPosRoles = getPositionRolesForWorkArea(workArea, asOfDate);
263             for (TkRole tkRole : lstPosRoles) {
264                 roles.add(tkRole);
265             }
266         }
267         return roles;
268     }
269 
270     @SuppressWarnings("unchecked")
271     @Override
272     public List<TkRole> findInActiveRoles(String principalId, Date asOfDate, String roleName, Long workArea, String department, String chart) {
273         List<TkRole> roles = new ArrayList<TkRole>();
274 
275         Criteria root = new Criteria();
276         
277         if (StringUtils.isNotEmpty(principalId)) {
278             root.addEqualTo("principalId", principalId);
279         }
280 
281         if (asOfDate != null) {
282             Criteria effdt = new Criteria();
283             Criteria timestamp = new Criteria();
284             ReportQueryByCriteria effdtSubQuery;
285             ReportQueryByCriteria timestampSubQuery;
286 
287 	        effdt.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
288 	        effdt.addEqualToField("principalId", Criteria.PARENT_QUERY_PREFIX + "principalId");
289 	        effdt.addLessOrEqualThan("effectiveDate", asOfDate);
290 	
291 	        // EFFECTIVE DATE --
292 	
293 	        // Adding criteria to nest an AND that has multiple ORs to select
294 	        // the correct ID / date combination.
295 	        Criteria orWrapperEd = new Criteria();
296 	        Criteria nstWaEd = new Criteria();
297 	        Criteria nstDptEd = new Criteria();
298 	        Criteria nstChrEd = new Criteria();
299 	
300 	        // Inner AND to allow for all null chart/dept/work area
301 	        Criteria nullAndWrapper = new Criteria();
302 	        nullAndWrapper.addIsNull("workArea");
303 	        nullAndWrapper.addIsNull("department");
304 	        nullAndWrapper.addIsNull("chart");
305 	
306 	        nstWaEd.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea"); // OR
307 	        nstDptEd.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department"); // OR
308 	        nstChrEd.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart"); // OR
309 	        orWrapperEd.addOrCriteria(nstWaEd);
310 	        orWrapperEd.addOrCriteria(nstDptEd);
311 	        orWrapperEd.addOrCriteria(nstChrEd);
312 	
313 	        // Inner AND to allow for all null chart/dept/work area
314 	        orWrapperEd.addOrCriteria(nullAndWrapper);
315 	
316 	        // Add the inner OR criteria to effective date
317 	        effdt.addAndCriteria(orWrapperEd);
318 	
319 	        effdtSubQuery = QueryFactory.newReportQuery(TkRole.class, effdt);
320 	        effdtSubQuery.setAttributes(new String[]{"max(effectiveDate)"});
321 	
322 	
323 	        // TIMESTAMP --
324 	
325 	        //Configure the actual "criteria" in the where clause
326 	        timestamp.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
327 	        timestamp.addEqualToField("principalId", Criteria.PARENT_QUERY_PREFIX + "principalId");
328 	        timestamp.addEqualToField("effectiveDate", Criteria.PARENT_QUERY_PREFIX + "effectiveDate");
329 	
330 	        // Adding criteria to nest an AND that has multiple ORs to select
331 	        // the correct ID / date combination.
332 	        orWrapperEd = new Criteria();
333 	        nstWaEd = new Criteria();
334 	        nstDptEd = new Criteria();
335 	        nstChrEd = new Criteria();
336 	
337 	        // Inner AND to allow for all null chart/dept/work area
338 	        nullAndWrapper = new Criteria();
339 	        nullAndWrapper.addIsNull("workArea");
340 	        nullAndWrapper.addIsNull("department");
341 	        nullAndWrapper.addIsNull("chart");
342 	
343 	        nstWaEd.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea"); // OR
344 	        nstDptEd.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department"); // OR
345 	        nstChrEd.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart"); // OR
346 	        orWrapperEd.addOrCriteria(nstWaEd);
347 	        orWrapperEd.addOrCriteria(nstDptEd);
348 	        orWrapperEd.addOrCriteria(nstChrEd);
349 	
350 	        // Inner AND to allow for all null chart/dept/work area
351 	        orWrapperEd.addOrCriteria(nullAndWrapper);
352 	
353 	        // Add the inner OR criteria to effective date
354 	        timestamp.addAndCriteria(orWrapperEd);
355 	
356 	        timestampSubQuery = QueryFactory.newReportQuery(TkRole.class, timestamp);
357 	        timestampSubQuery.setAttributes(new String[]{"max(timestamp)"});
358 	
359 	        // Filter by Max(EffDt) / Max(Timestamp)
360 	        //root.addEqualTo("effectiveDate", effdtSubQuery);
361 	        root.addEqualTo("timestamp", timestampSubQuery);
362         }
363         
364         
365         if (StringUtils.isNotEmpty(roleName)) {
366             root.addEqualTo("roleName", roleName);
367         }
368         
369         if (workArea != null) {
370             root.addEqualTo("workArea", workArea);
371         }
372         
373         if (StringUtils.isNotEmpty(department)) {
374             root.addEqualTo("department", department);
375         }
376         
377         if (StringUtils.isNotEmpty(chart)) {
378             root.addEqualTo("chart", chart);
379         }
380 
381         root.addEqualTo("active", false);
382 
383         Query query = QueryFactory.newQuery(TkRole.class, root);
384         Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
385 
386         if (c != null) {
387             roles.addAll(c);
388         }
389 
390         return roles;
391     }
392 
393     @Override
394     public void saveOrUpdateRole(TkRole role) {
395         KRADServiceLocator.getBusinessObjectService().save(role);
396     }
397 
398     @Override
399     public void saveOrUpdateRoles(List<TkRole> roles) {
400         if (roles != null) {
401             for (TkRole role : roles) {
402                 saveOrUpdateRole(role);
403             }
404         }
405     }
406 
407     @Override
408     public TkRole getRole(String tkRoleId) {
409         Criteria currentRecordCriteria = new Criteria();
410         currentRecordCriteria.addEqualTo("hrRolesId", tkRoleId);
411 
412         return (TkRole) this.getPersistenceBrokerTemplate().getObjectByQuery(QueryFactory.newQuery(TkRole.class, currentRecordCriteria));
413     }
414 
415     @Override
416     public TkRole getRolesByPosition(String positionNumber) {
417         Criteria currentRecordCriteria = new Criteria();
418         Criteria effdt = new Criteria();
419         currentRecordCriteria.addEqualTo("positionNumber", positionNumber);
420 
421         effdt.addEqualToField("positionNumber", Criteria.PARENT_QUERY_PREFIX + "positionNumber");
422         effdt.addLessOrEqualThan("effectiveDate", TKUtils.getCurrentDate());
423         ReportQueryByCriteria effdtSubQuery = QueryFactory.newReportQuery(TkRole.class, effdt);
424         effdtSubQuery.setAttributes(new String[]{"max(effectiveDate)"});
425         currentRecordCriteria.addEqualTo("effectiveDate", effdtSubQuery);
426 
427         // Filter for ACTIVE = 'Y'
428         Criteria activeFilter = new Criteria();
429         activeFilter.addEqualTo("active", true);
430         currentRecordCriteria.addAndCriteria(activeFilter);
431 
432 
433         TkRole tkRole = (TkRole) this.getPersistenceBrokerTemplate().getObjectByQuery(QueryFactory.newQuery(TkRole.class, currentRecordCriteria));
434         return tkRole;
435     }
436 
437     @Override
438     public TkRole getInactiveRolesByPosition(String positionNumber) {
439         Criteria currentRecordCriteria = new Criteria();
440         Criteria effdt = new Criteria();
441         currentRecordCriteria.addEqualTo("positionNumber", positionNumber);
442 
443         effdt.addEqualToField("positionNumber", Criteria.PARENT_QUERY_PREFIX + "positionNumber");
444         effdt.addLessOrEqualThan("effectiveDate", TKUtils.getCurrentDate());
445         ReportQueryByCriteria effdtSubQuery = QueryFactory.newReportQuery(TkRole.class, effdt);
446         effdtSubQuery.setAttributes(new String[]{"max(effectiveDate)"});
447         currentRecordCriteria.addEqualTo("effectiveDate", effdtSubQuery);
448 
449         // Filter for ACTIVE = 'N'
450         Criteria activeFilter = new Criteria();
451         activeFilter.addEqualTo("active", false);
452         currentRecordCriteria.addAndCriteria(activeFilter);
453 
454 
455         TkRole tkRole = (TkRole) this.getPersistenceBrokerTemplate().getObjectByQuery(QueryFactory.newQuery(TkRole.class, currentRecordCriteria));
456         return tkRole;
457     }
458 
459 
460     @Override
461     public List<TkRole> getPositionRolesForWorkArea(Long workArea, Date asOfDate) {
462         List<TkRole> roles = new ArrayList<TkRole>();
463 
464         Criteria root = new Criteria();
465         Criteria effdt = new Criteria();
466         Criteria timestamp = new Criteria();
467         ReportQueryByCriteria effdtSubQuery;
468         ReportQueryByCriteria timestampSubQuery;
469 
470         effdt.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
471         effdt.addEqualToField("positionNumber", Criteria.PARENT_QUERY_PREFIX + "positionNumber");
472         effdt.addLessOrEqualThan("effectiveDate", asOfDate);
473 
474         // EFFECTIVE DATE --
475 
476         // Adding criteria to nest an AND that has multiple ORs to select
477         // the correct ID / date combination.
478         Criteria orWrapperEd = new Criteria();
479         Criteria nstWaEd = new Criteria();
480         Criteria nstDptEd = new Criteria();
481         Criteria nstChrEd = new Criteria();
482 
483         // Inner AND to allow for all null chart/dept/work area
484         Criteria nullAndWrapper = new Criteria();
485         nullAndWrapper.addIsNull("department");
486         nullAndWrapper.addIsNull("chart");
487 
488         nstWaEd.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea"); // OR
489         nstDptEd.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department"); // OR
490         nstChrEd.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart"); // OR
491         orWrapperEd.addOrCriteria(nstWaEd);
492         orWrapperEd.addOrCriteria(nstDptEd);
493         orWrapperEd.addOrCriteria(nstChrEd);
494 
495         // Inner AND to allow for all null chart/dept/work area
496         orWrapperEd.addOrCriteria(nullAndWrapper);
497 
498         // Add the inner OR criteria to effective date
499         effdt.addAndCriteria(orWrapperEd);
500 
501         effdtSubQuery = QueryFactory.newReportQuery(TkRole.class, effdt);
502         effdtSubQuery.setAttributes(new String[]{"max(effectiveDate)"});
503 
504 
505         // TIMESTAMP --
506 
507         //Configure the actual "criteria" in the where clause
508         timestamp.addEqualToField("roleName", Criteria.PARENT_QUERY_PREFIX + "roleName");
509         //timestamp.addEqualToField("principalId", Criteria.PARENT_QUERY_PREFIX + "principalId");
510         timestamp.addEqualToField("effectiveDate", Criteria.PARENT_QUERY_PREFIX + "effectiveDate");
511 
512         // Adding criteria to nest an AND that has multiple ORs to select
513         // the correct ID / date combination.
514         orWrapperEd = new Criteria();
515         nstWaEd = new Criteria();
516         nstDptEd = new Criteria();
517         nstChrEd = new Criteria();
518 
519         // Inner AND to allow for all null chart/dept/work area
520         nullAndWrapper = new Criteria();
521         nullAndWrapper.addIsNull("department");
522         nullAndWrapper.addIsNull("chart");
523 
524         nstWaEd.addEqualToField("workArea", Criteria.PARENT_QUERY_PREFIX + "workArea"); // OR
525         nstDptEd.addEqualToField("department", Criteria.PARENT_QUERY_PREFIX + "department"); // OR
526         nstChrEd.addEqualToField("chart", Criteria.PARENT_QUERY_PREFIX + "chart"); // OR
527         orWrapperEd.addOrCriteria(nstWaEd);
528         orWrapperEd.addOrCriteria(nstDptEd);
529         orWrapperEd.addOrCriteria(nstChrEd);
530 
531         // Inner AND to allow for all null chart/dept/work area
532         orWrapperEd.addOrCriteria(nullAndWrapper);
533 
534         // Add the inner OR criteria to effective date
535         timestamp.addAndCriteria(orWrapperEd);
536 
537         timestampSubQuery = QueryFactory.newReportQuery(TkRole.class, timestamp);
538         timestampSubQuery.setAttributes(new String[]{"max(timestamp)"});
539 
540 
541         // Filter by Max(EffDt) / Max(Timestamp)
542         root.addEqualTo("effectiveDate", effdtSubQuery);
543         root.addEqualTo("timestamp", timestampSubQuery);
544 
545         // Optional ROOT criteria added :
546         if (workArea != null)
547             root.addEqualTo("workArea", workArea);
548         root.addEqualTo("roleName", TkConstants.ROLE_TK_APPROVER);
549 
550         // Filter for ACTIVE = 'Y'
551         Criteria activeFilter = new Criteria();
552         activeFilter.addEqualTo("active", true);
553         root.addAndCriteria(activeFilter);
554 
555         Query query = QueryFactory.newQuery(TkRole.class, root);
556         Collection c = this.getPersistenceBrokerTemplate().getCollectionByQuery(query);
557 
558         if (c != null) {
559             roles.addAll(c);
560         }
561 
562         return roles;
563     }
564 }