View Javadoc
1   /**
2    * Copyright 2004-2014 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.kpme.tklm.time.missedpunch.web;
17  
18  import java.text.ParseException;
19  import java.text.SimpleDateFormat;
20  import java.util.ArrayList;
21  import java.util.Date;
22  import java.util.HashMap;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Properties;
27  
28  import org.apache.commons.lang.StringUtils;
29  import org.apache.log4j.Logger;
30  import org.joda.time.Interval;
31  import org.joda.time.LocalDate;
32  import org.kuali.kpme.core.KPMENamespace;
33  import org.kuali.kpme.core.department.Department;
34  import org.kuali.kpme.core.job.Job;
35  import org.kuali.kpme.core.lookup.KPMELookupableImpl;
36  import org.kuali.kpme.core.permission.KPMEPermissionTemplate;
37  import org.kuali.kpme.core.role.KPMERoleMemberAttribute;
38  import org.kuali.kpme.core.service.HrServiceLocator;
39  import org.kuali.kpme.core.util.TKUtils;
40  import org.kuali.kpme.tklm.time.missedpunch.MissedPunch;
41  import org.kuali.kpme.tklm.time.missedpunch.MissedPunchDocument;
42  import org.kuali.kpme.tklm.time.service.TkServiceLocator;
43  import org.kuali.kpme.tklm.time.timeblock.TimeBlock;
44  import org.kuali.rice.core.api.config.property.ConfigContext;
45  import org.kuali.rice.core.api.search.Range;
46  import org.kuali.rice.core.api.search.SearchExpressionUtils;
47  import org.kuali.rice.kim.api.KimConstants;
48  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
49  import org.kuali.rice.krad.uif.UifParameters;
50  import org.kuali.rice.krad.uif.view.LookupView;
51  import org.kuali.rice.krad.util.GlobalVariables;
52  import org.kuali.rice.krad.util.KRADConstants;
53  import org.kuali.rice.krad.util.ObjectUtils;
54  import org.kuali.rice.krad.util.UrlFactory;
55  import org.kuali.rice.krad.web.form.LookupForm;
56  
57  public class MissedPunchLookupableImpl extends KPMELookupableImpl {
58  
59  	private static final long serialVersionUID = 6521192698205632171L;
60  	
61  	private static final Logger LOG = Logger.getLogger(MissedPunchLookupableImpl.class);
62  	
63  	@Override
64  	public List<?> getSearchResults(LookupForm form, Map<String, String> searchCriteria, boolean unbounded) {
65  		List<MissedPunch> results = new ArrayList<MissedPunch>();
66  		
67  		LocalDate fromDate = null;
68  		LocalDate toDate = null;
69  		String toDateString = TKUtils.getToDateString(searchCriteria.get("actionDate"));
70  		String fromDateString = TKUtils.getFromDateString(searchCriteria.get("actionDate"));
71  		String actionTimeString = searchCriteria.get("actionTime");
72  		searchCriteria.remove("actionTime");
73  
74  		if(StringUtils.isNotBlank(searchCriteria.get("actionDate"))) {
75  			Range range = SearchExpressionUtils.parseRange(searchCriteria.get("actionDate"));
76  			boolean invalid = false;
77  			if(range.getLowerBoundValue() != null && range.getUpperBoundValue() != null) {
78  				fromDate = TKUtils.formatDateString(fromDateString);
79  				if(fromDate == null) {
80  					GlobalVariables.getMessageMap().putError("lookupCriteria[rangeLowerBoundKeyPrefix_actionDate]", "error.invalidLookupDate", range.getLowerBoundValue());
81  					invalid = true;
82  				}
83  
84  				toDate = TKUtils.formatDateString(toDateString);
85  				if(toDate == null) {
86  					GlobalVariables.getMessageMap().putError("lookupCriteria[actionDate]", "error.invalidLookupDate", range.getUpperBoundValue());
87  					invalid = true;
88  				}
89  			}
90  			else if(range.getLowerBoundValue() != null) {
91  				fromDate = TKUtils.formatDateString(fromDateString);
92  				if(fromDate == null) {
93  					GlobalVariables.getMessageMap().putError("lookupCriteria[rangeLowerBoundKeyPrefix_actionDate]", "error.invalidLookupDate", range.getLowerBoundValue());
94  					invalid = true;
95  				}
96  			}
97  			else if(range.getUpperBoundValue() != null) {
98  				toDate = TKUtils.formatDateString(toDateString);
99  				if(toDate == null) {
100 					GlobalVariables.getMessageMap().putError("lookupCriteria[actionDate]", "error.invalidLookupDate", range.getUpperBoundValue());
101 					invalid = true;
102 				}
103 			}
104 			if(invalid) {
105 				return new ArrayList<TimeBlock>();
106 			}
107 		}
108 		searchCriteria.remove("actionDate");
109 		List<?> searchResults = super.getSearchResults(form, searchCriteria, unbounded);
110 		//clear result messages, these will be re-added with the correct number of retrieved objects once filtering has been completed.
111 		if(ObjectUtils.isNotNull(GlobalVariables.getMessageMap().getInfoMessagesForProperty("LookupResultMessages"))) {
112 			GlobalVariables.getMessageMap().getInfoMessagesForProperty("LookupResultMessages").clear();
113 		}
114 		for (Object searchResult : searchResults) {
115 			MissedPunch missedPunch = (MissedPunch) searchResult;
116 			results.add(missedPunch);
117 		}
118 		
119 		results = filterByPrincipalId(results, GlobalVariables.getUserSession().getPrincipalId());
120 		results = filterByActionDateRange(results,fromDate,toDate);
121 		if(!StringUtils.isBlank(actionTimeString)) {
122 			try {
123 				results = filterByActionTime(results,actionTimeString);
124 			} catch (ParseException e) {
125 				LOG.warn("caught ParseException while filtering results by Missed Action Time. Cause: " + e.getCause());
126 			}
127 		}
128 		//LookupableImpl sets an info message with the number of results it found.
129 		//locate the position of this specific message and replace it with the number of filtered results.
130 /*		AutoPopulatingList<ErrorMessage> infos = GlobalVariables.getMessageMap().getInfoMessagesForProperty("LookupResultMessages");
131 		AutoPopulatingList<ErrorMessage> correctedInfos = new AutoPopulatingList(ErrorMessage.class);*/
132 		//copy alll but the 
133 /*		for(ErrorMessage info : infos) {
134 			if(!info.getErrorKey().equalsIgnoreCase(RiceKeyConstants.INFO_LOOKUP_RESULTS_DISPLAY_ALL)) {
135 				correctedInfos.add(info);
136 			}
137 		}*/
138 /*		for(ErrorMessage info : correctedInfos) {
139 			GlobalVariables.getMessageMap().putError("LookupResultMessages", info);			
140 		}*/
141 		
142 		super.generateLookupResultsMessages(form, searchCriteria, results, unbounded);
143 		return results;
144 	}
145 	
146 	
147 	
148 	private List<MissedPunch> filterByActionTime(List<MissedPunch> results,	String actionTimeString) throws ParseException {
149 		List<MissedPunch> resultList = new LinkedList<MissedPunch>();
150 
151 		SimpleDateFormat sdf = new SimpleDateFormat("h:mm a");
152 		Date actionDateTime = null;
153 		try {
154 			actionDateTime = sdf.parse(actionTimeString);
155 		} catch (ParseException e) {
156 			GlobalVariables.getMessageMap().putError("lookupCriteria[actionTime]", "error.invalidTime", actionTimeString);
157 			throw e;
158 		}
159 
160 		for(MissedPunch mp : results) {
161 			String mpActionTime = mp.getActionTime();
162 			Date mpActionTimeDate = sdf.parse(mpActionTime);
163 			boolean added = actionDateTime.compareTo(mpActionTimeDate) == 0 ? resultList.add(mp) : false;
164 		}
165 		return resultList;
166 	}
167 
168 
169 
170 	private List<MissedPunch> filterByActionDateRange(List<MissedPunch> results, LocalDate fromDate, LocalDate toDate) {
171 		
172 		List<MissedPunch> filteredResults = new LinkedList<MissedPunch>();
173 		for(MissedPunch mp : results) {
174 			boolean added;
175 			if(fromDate != null && toDate != null) {
176 				Interval actionInterval = new Interval(fromDate.toDate().getTime(),toDate.toDate().getTime());
177 				added = actionInterval.contains(mp.getActionDate().getTime()) ? filteredResults.add(mp) : false;
178 			}
179 			else if(fromDate != null) {
180 				added = mp.getActionDate().before(fromDate.toDate()) ? false : filteredResults.add(mp);
181 			}
182 			else if(toDate != null) {
183 				added = mp.getActionDate().after(toDate.toDate()) ? false : filteredResults.add(mp);
184 			}
185 			else {
186 				added = filteredResults.add(mp);
187 			}
188 		}
189 		return filteredResults;
190 		
191 	}
192 
193 
194 
195 	private List<MissedPunch> filterByPrincipalId(List<MissedPunch> missedPunches, String principalId) {
196 		List<MissedPunch> results = new ArrayList<MissedPunch>();
197 
198         //TODO - performance  too many db calls in loop
199 		for (MissedPunch missedPunch : missedPunches) {
200 			Job jobObj = HrServiceLocator.getJobService().getJob(missedPunch.getPrincipalId(), missedPunch.getJobNumber(), LocalDate.fromDateFields(missedPunch.getActionDate()));
201 			String department = jobObj != null ? jobObj.getDept() : null;
202 			
203 			Department departmentObj = jobObj != null ? HrServiceLocator.getDepartmentService().getDepartmentWithoutRoles(department, LocalDate.fromDateFields(missedPunch.getActionDate())) : null;
204 			String location = departmentObj != null ? departmentObj.getLocation() : null;
205 			
206 			Map<String, String> roleQualification = new HashMap<String, String>();
207         	roleQualification.put(KimConstants.AttributeConstants.PRINCIPAL_ID, GlobalVariables.getUserSession().getPrincipalId());
208         	roleQualification.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), department);
209         	roleQualification.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), location);
210         	
211         	if (!KimApiServiceLocator.getPermissionService().isPermissionDefinedByTemplate(KPMENamespace.KPME_WKFLW.getNamespaceCode(),
212     				KPMEPermissionTemplate.VIEW_KPME_RECORD.getPermissionTemplateName(), new HashMap<String, String>())
213     		  || KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(principalId, KPMENamespace.KPME_WKFLW.getNamespaceCode(),
214     				  KPMEPermissionTemplate.VIEW_KPME_RECORD.getPermissionTemplateName(), new HashMap<String, String>(), roleQualification)) {
215 					results.add(missedPunch);
216 			}
217 		}
218 		
219 		return results;
220 	}
221 
222 	@Override
223 	public void initSuppressAction(LookupForm lookupForm) {
224 /*
225  * lookupAuthorizer.canInitiateDocument(lookupForm, user) returns false in this instance, because no
226  * documentTypeName can be obtained within LookupViewAuthorizeBase.canInitiateDocument(LookupForm, Person).
227  * This effectively suppresses view actions.
228  * 
229  *      LookupViewAuthorizerBase lookupAuthorizer = (LookupViewAuthorizerBase) lookupForm.getView().getAuthorizer();
230         Person user = GlobalVariables.getUserSession().getPerson();
231         ((LookupView) lookupForm.getView()).setSuppressActions(!lookupAuthorizer.canInitiateDocument(lookupForm, user));*/
232         ((LookupView) lookupForm.getView()).setSuppressActions(false);
233 	}
234 
235 
236 
237 	@Override
238 	protected String getActionUrlHref(LookupForm lookupForm, Object dataObject,
239 			String methodToCall, List<String> pkNames) {
240 		if (!StringUtils.equals(methodToCall, "maintenanceView")) {
241 			return super.getActionUrlHref(lookupForm, dataObject, methodToCall, pkNames);
242 		} else {
243 			Properties urlParameters = new Properties();
244 
245 	        MissedPunch mp = (MissedPunch) dataObject;
246 	        MissedPunchDocument mpDoc = TkServiceLocator.getMissedPunchService().getMissedPunchDocumentByMissedPunchId(mp.getTkMissedPunchId());
247 
248 	        urlParameters.setProperty("command", "displayDocSearchView");
249 	        
250 	        if(mpDoc != null) {
251 	        	urlParameters.setProperty("docId", mpDoc.getDocumentNumber());
252 	        }
253 	        else {
254 	        	urlParameters.setProperty(UifParameters.DOC_NUM, null);
255 	        }
256 
257 	        //return  HrServiceLocator.CONTEXT.getget"/kpme-dev/kew/DocHandler.do?command=displayDocSearchView&docId="+mpDoc.getDocumentNumber();
258 	        String url = ConfigContext.getCurrentContextConfig().getProperty("kew.url") +
259 	        		"/" +
260 	        		UrlFactory.parameterizeUrl(KRADConstants.DOC_HANDLER_ACTION, urlParameters);
261 	        
262 	        return url;
263 	        //KRADConstants.DOCHANDLER_DO_URL;
264 	        //UifParameters.
265 		}
266 	}
267 	
268 }