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.timeblock.web;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.kpme.core.assignment.AssignmentDescriptionKey;
20  import org.kuali.kpme.core.util.TKUtils;
21  import org.kuali.kpme.tklm.common.TkConstants;
22  import org.kuali.kpme.tklm.time.service.TkServiceLocator;
23  import org.kuali.kpme.tklm.time.timehourdetail.TimeHourDetail;
24  import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
25  import org.kuali.rice.kew.api.document.DocumentStatus;
26  import org.kuali.rice.kew.api.document.DocumentStatusCategory;
27  import org.kuali.rice.krad.inquiry.Inquirable;
28  import org.kuali.rice.krad.uif.widget.Inquiry;
29  import org.kuali.rice.krad.util.KRADConstants;
30  import org.kuali.rice.krad.util.ObjectUtils;
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.tklm.leave.block.LeaveBlockHistory;
40  import org.kuali.kpme.tklm.time.timeblock.TimeBlockHistory;
41  import org.kuali.kpme.tklm.time.timeblock.TimeBlockHistoryDetail;
42  import org.kuali.rice.kim.api.KimConstants;
43  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
44  import org.kuali.rice.krad.lookup.LookupUtils;
45  import org.kuali.rice.krad.uif.view.LookupView;
46  import org.kuali.rice.krad.util.GlobalVariables;
47  import org.kuali.rice.krad.web.form.LookupForm;
48  
49  import java.util.*;
50  
51  public class TimeBlockHistoryLookupableHelperServiceImpl extends KPMELookupableImpl {
52  
53  	private static final long serialVersionUID = -4201048176986460032L;
54  
55  	private static final String BEGIN_DATE = "beginDate";
56  	private static final String BEGIN_TIMESTAMP = "beginTimestamp";
57  	private static final String DOC_STATUS_ID = "timesheetDocumentHeader.documentStatus";
58  	private static final String DOC_ID = "documentId";
59      private static final String BEGIN_DATE_LOWER = KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX + "beginDate";
60      private static final String BEGIN_DATE_UPPER = KRADConstants.LOOKUP_RANGE_UPPER_BOUND_PROPERTY_PREFIX + "beginDate";
61  
62  
63  /*	@Override
64  	public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) {
65  
66  	}*/
67  	
68  	private List<TimeBlockHistory> filterByPrincipalId(List<TimeBlockHistory> timeBlockHistories, String principalId) {
69  		List<TimeBlockHistory> results = new ArrayList<TimeBlockHistory>();
70  
71          //TODO - performance  too many db calls in loop
72  		for (TimeBlockHistory timeBlockHistory : timeBlockHistories) {
73  			Job jobObj = HrServiceLocator.getJobService().getJob(timeBlockHistory.getPrincipalId(), timeBlockHistory.getJobNumber(), LocalDate.fromDateFields(timeBlockHistory.getBeginDate()), false);
74  			String department = jobObj != null ? jobObj.getDept() : null;
75  
76  			Department departmentObj = jobObj != null ? HrServiceLocator.getDepartmentService().getDepartmentWithoutRoles(department, LocalDate.fromDateFields(timeBlockHistory.getBeginDate())) : null;
77  			String location = departmentObj != null ? departmentObj.getLocation() : null;
78  
79  			Map<String, String> roleQualification = new HashMap<String, String>();
80  			roleQualification.put(KimConstants.AttributeConstants.PRINCIPAL_ID, GlobalVariables.getUserSession().getPrincipalId());
81  			roleQualification.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), department);
82  			roleQualification.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), location);
83  
84  			if (!KimApiServiceLocator.getPermissionService().isPermissionDefinedByTemplate(KPMENamespace.KPME_WKFLW.getNamespaceCode(),
85  					KPMEPermissionTemplate.VIEW_KPME_RECORD.getPermissionTemplateName(), new HashMap<String, String>())
86  					|| KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(principalId, KPMENamespace.KPME_WKFLW.getNamespaceCode(),
87  							KPMEPermissionTemplate.VIEW_KPME_RECORD.getPermissionTemplateName(), new HashMap<String, String>(), roleQualification)) {
88  				results.add(timeBlockHistory);
89  			}
90  		}
91  		
92  		return results;
93  	}
94  
95  	private List<TimeBlockHistory> addDetails(List<TimeBlockHistory> timeBlockHistories) {
96  		List<TimeBlockHistory> results = new ArrayList<TimeBlockHistory>(timeBlockHistories);
97  
98  		for (TimeBlockHistory timeBlockHistory : timeBlockHistories) {
99  			List<TimeBlockHistoryDetail> timeBlockHistoryDetails = timeBlockHistory.getTimeBlockHistoryDetails();
100 
101 			for (TimeBlockHistoryDetail timeBlockHistoryDetail : timeBlockHistoryDetails) {
102 				if (!timeBlockHistoryDetail.getEarnCode().equalsIgnoreCase(timeBlockHistory.getEarnCode())) {
103 					TimeBlockHistory newTimeBlockHistory = timeBlockHistory.copy();
104 					newTimeBlockHistory.setEarnCode(timeBlockHistoryDetail.getEarnCode());
105 					newTimeBlockHistory.setHours(timeBlockHistoryDetail.getHours());
106 					newTimeBlockHistory.setAmount(timeBlockHistoryDetail.getAmount());
107 					results.add(newTimeBlockHistory);
108 				}
109 			}
110 		}
111 
112 		return results;
113 	}
114 
115     public void buildInquiryLink(Object dataObject, String propertyName, Inquiry inquiry) {
116         Class inquirableClass = dataObject.getClass();
117         if(dataObject instanceof TimeBlockHistory) {
118             TimeBlockHistory tb = (TimeBlockHistory) dataObject;
119             if (tb.getConcreteBlockType() != null
120                     && tb.getConcreteBlockType().equals(LeaveBlockHistory.class.getName())) {
121                 inquirableClass = LeaveBlockHistory.class;
122             }
123         }
124 
125         Inquirable inquirable = getViewDictionaryService().getInquirable(inquirableClass, inquiry.getViewName());
126         if (inquirable != null) {
127             if(!inquirableClass.equals(LeaveBlockHistory.class)) {
128                 inquirable.buildInquirableLink(dataObject, propertyName, inquiry);
129             }
130         } else {
131             // TODO: should we really not render the inquiry just because the top parent doesn't have an inquirable?
132             // it is possible the path is nested and there does exist an inquiry for the property
133             // inquirable not found, no inquiry link can be set
134             inquiry.setRender(false);
135         }
136     }
137 
138 	@Override
139 	protected String getActionUrlHref(LookupForm lookupForm, Object dataObject,
140 			String methodToCall, List<String> pkNames) {
141 
142 
143 		String actionUrlHref = super.getActionUrlHref(lookupForm, dataObject, methodToCall, pkNames);
144 		String concreteBlockId = null;
145 		if(dataObject instanceof TimeBlockHistory) {
146 			TimeBlockHistory tb = (TimeBlockHistory) dataObject;
147 			concreteBlockId = tb.getTkTimeBlockHistoryId();
148             if (tb.getConcreteBlockType() != null
149                     && tb.getConcreteBlockType().equals(LeaveBlockHistory.class.getName())) {
150                 actionUrlHref = actionUrlHref.replace("tkTimeBlockHistoryId", "lmLeaveBlockHistoryId");
151                 actionUrlHref = actionUrlHref.replace(TimeBlockHistory.class.getName(), LeaveBlockHistory.class.getName());
152             }
153 
154 		}
155 		if(concreteBlockId == null) {
156 			return null;
157 		}
158 
159 		return actionUrlHref;
160 	}
161 
162 	@Override
163 	public void initSuppressAction(LookupForm lookupForm) {
164 		((LookupView) lookupForm.getView()).setSuppressActions(false);
165 	}
166 
167     @Override
168     protected List<?> getSearchResults(LookupForm form,
169                                        Map<String, String> searchCriteria, boolean unbounded) {
170         List<TimeBlockHistory> results = new ArrayList<TimeBlockHistory>();
171 
172         if (searchCriteria.containsKey(BEGIN_DATE)) {
173             searchCriteria.put(BEGIN_TIMESTAMP, searchCriteria.get(BEGIN_DATE));
174             searchCriteria.remove(BEGIN_DATE);
175         }
176         if (searchCriteria.containsKey(DOC_STATUS_ID)) {
177             searchCriteria.put(DOC_STATUS_ID, resolveDocumentStatus(searchCriteria.get(DOC_STATUS_ID)));
178         }
179         //List<TimeBlockHistory> searchResults = new ArrayList<TimeBlockHistory>();
180         List<TimeBlockHistory> searchResults = (List<TimeBlockHistory>)super.getSearchResults(form, searchCriteria, unbounded);
181 
182         //convert lookup criteria for LeaveBlockHistory
183         Map<String, String> leaveCriteria = new HashMap<String, String>();
184         leaveCriteria.putAll(searchCriteria);
185         leaveCriteria.put("accrualGenerated", "N");
186         if (leaveCriteria.containsKey(DOC_ID)) {
187             TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(leaveCriteria.get(DOC_ID));
188             if (tdh != null) {
189                 leaveCriteria.put(KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX + "leaveDate", TKUtils.formatDate(tdh.getBeginDateTime().toLocalDate()));
190                 leaveCriteria.put(KRADConstants.LOOKUP_RANGE_UPPER_BOUND_PROPERTY_PREFIX +"leaveDate", TKUtils.formatDate(tdh.getEndDateTime().toLocalDate()));
191             }
192         }
193         if (leaveCriteria.containsKey(BEGIN_DATE_LOWER)) {
194             leaveCriteria.put(KRADConstants.LOOKUP_RANGE_LOWER_BOUND_PROPERTY_PREFIX + "leaveDate", leaveCriteria.get(BEGIN_DATE_LOWER));
195             leaveCriteria.remove(BEGIN_DATE_LOWER);
196         }
197         if (leaveCriteria.containsKey(BEGIN_DATE_UPPER)) {
198             leaveCriteria.put(KRADConstants.LOOKUP_RANGE_UPPER_BOUND_PROPERTY_PREFIX + "leaveDate", leaveCriteria.get(BEGIN_DATE_UPPER));
199             leaveCriteria.remove(BEGIN_DATE_UPPER);
200         }
201         if (leaveCriteria.containsKey(DOC_STATUS_ID)) {
202             leaveCriteria.put("leaveCalendarDocumentHeader.documentStatus", leaveCriteria.get(DOC_STATUS_ID));
203             leaveCriteria.remove(DOC_STATUS_ID);
204         }
205         LookupForm leaveBlockForm = (LookupForm)ObjectUtils.deepCopy(form);
206         leaveBlockForm.setDataObjectClassName(LeaveBlockHistory.class.getName());
207         setDataObjectClass(LeaveBlockHistory.class);
208         List<LeaveBlockHistory> leaveBlocks = (List<LeaveBlockHistory>)super.getSearchResults(leaveBlockForm, LookupUtils.forceUppercase(LeaveBlockHistory.class, leaveCriteria), unbounded);
209         List<TimeBlockHistory> convertedLeaveBlocks = convertLeaveBlockHistories(leaveBlocks);
210         searchResults.addAll(convertedLeaveBlocks);
211         for ( TimeBlockHistory searchResult : searchResults) {
212             TimeBlockHistory timeBlockHistory = (TimeBlockHistory) searchResult;
213             results.add(timeBlockHistory);
214         }
215 
216         results = filterByPrincipalId(results, GlobalVariables.getUserSession().getPrincipalId());
217         results = addDetails(results);
218         sortSearchResults(form, searchResults);
219 
220         return results;
221     }
222 
223     protected List<TimeBlockHistory> convertLeaveBlockHistories(List<LeaveBlockHistory> leaveBlockHistories) {
224         List<TimeBlockHistory> histories = new ArrayList<TimeBlockHistory>();
225         for(LeaveBlockHistory history : leaveBlockHistories) {
226 
227             TimeBlockHistory tBlock = new TimeBlockHistory();
228             tBlock.setAmount(history.getLeaveAmount());
229             tBlock.setHours(history.getHours());
230 
231             tBlock.setEarnCode(history.getEarnCode());
232             tBlock.setPrincipalId(history.getPrincipalId());
233             tBlock.setUserPrincipalId(history.getPrincipalIdModified());
234             tBlock.setPrincipalIdModified(history.getPrincipalIdModified());
235             tBlock.setWorkArea(history.getWorkArea());
236             AssignmentDescriptionKey assignKey = AssignmentDescriptionKey.get(history.getAssignmentKey());
237             tBlock.setWorkArea(assignKey.getWorkArea());
238             tBlock.setJobNumber(assignKey.getJobNumber());
239             tBlock.setTask(assignKey.getTask());
240             tBlock.setOvertimePref(history.getOvertimePref());
241             tBlock.setLunchDeleted(history.getLunchDeleted());
242             tBlock.setDocumentId(history.getDocumentId());
243             tBlock.setBeginDate(history.getLeaveDate());
244             tBlock.setEndDate(history.getLeaveDate());
245             tBlock.setTimeHourDetails(new ArrayList<TimeHourDetail>());
246             tBlock.setTimestampModified(history.getTimestamp());
247             tBlock.setTimestamp(history.getTimestamp());
248             tBlock.setActionHistory(TkConstants.ACTION_HISTORY_CODES.get(history.getAction()));
249             tBlock.setClockLogCreated(false);
250             tBlock.setTkTimeBlockId(history.getLmLeaveBlockId());
251             tBlock.setTkTimeBlockHistoryId(history.getLmLeaveBlockHistoryId());
252             tBlock.setConcreteBlockType(history.getClass().getName());
253 
254             histories.add(tBlock);
255 
256         }
257         return histories;
258     }
259 
260     protected String resolveDocumentStatus(String selectedStatus) {
261         if (StringUtils.isNotBlank(selectedStatus)) {
262             if (StringUtils.contains(selectedStatus, "category:")) {
263                 String[] category = selectedStatus.split(":");
264                 DocumentStatusCategory statusCategory = DocumentStatusCategory.fromCode(category[1]);
265                 Set<DocumentStatus> categoryStatuses = DocumentStatus.getStatusesForCategory(statusCategory);
266                 StringBuffer status = new StringBuffer();
267                 for (DocumentStatus docStatus : categoryStatuses) {
268                     status.append(docStatus.getCode()).append("|");
269                 }
270                 return status.toString();
271             } else {
272                 return selectedStatus;
273             }
274         }
275         return StringUtils.EMPTY;
276     }
277 
278 }