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