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