1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.tklm.time.approval.web;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Comparator;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Set;
26
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpServletResponse;
29
30 import org.apache.commons.lang.ObjectUtils;
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.commons.lang.math.NumberUtils;
33 import org.apache.struts.action.ActionForm;
34 import org.apache.struts.action.ActionForward;
35 import org.apache.struts.action.ActionMapping;
36 import org.apache.struts.action.ActionRedirect;
37 import org.displaytag.tags.TableTagParameters;
38 import org.displaytag.util.ParamEncoder;
39 import org.hsqldb.lib.StringUtil;
40 import org.joda.time.LocalDate;
41 import org.kuali.kpme.core.api.calendar.Calendar;
42 import org.kuali.kpme.core.api.calendar.entry.CalendarEntry;
43 import org.kuali.kpme.core.api.namespace.KPMENamespace;
44 import org.kuali.kpme.core.permission.KPMEPermissionTemplate;
45 import org.kuali.kpme.core.role.KPMERoleMemberAttribute;
46 import org.kuali.kpme.core.service.HrServiceLocator;
47 import org.kuali.kpme.core.util.HrConstants;
48 import org.kuali.kpme.core.util.HrContext;
49 import org.kuali.kpme.tklm.api.time.missedpunch.MissedPunch;
50 import org.kuali.kpme.tklm.common.CalendarApprovalFormAction;
51 import org.kuali.kpme.tklm.time.approval.summaryrow.ApprovalTimeSummaryRow;
52 import org.kuali.kpme.tklm.time.missedpunch.MissedPunchDocument;
53 import org.kuali.kpme.tklm.time.missedpunch.document.MissedPunchDocumentService;
54 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
55 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
56 import org.kuali.rice.core.api.config.property.ConfigContext;
57 import org.kuali.rice.kim.api.KimConstants;
58 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
59 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
60 import org.springframework.util.CollectionUtils;
61
62 public class TimeApprovalAction extends CalendarApprovalFormAction {
63
64 @Override
65 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
66 ActionForward actionForward = super.execute(mapping, form, request, response);
67
68 TimeApprovalActionForm timeApprovalActionForm = (TimeApprovalActionForm) form;
69 String documentId = timeApprovalActionForm.getDocumentId();
70
71 setSearchFields(timeApprovalActionForm);
72
73 CalendarEntry calendarEntry = null;
74 if (StringUtils.isNotBlank(documentId)) {
75 TimesheetDocument timesheetDocument = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentId);
76
77 if (timesheetDocument != null) {
78 calendarEntry = timesheetDocument.getCalendarEntry();
79 timeApprovalActionForm.setCalendarDocument(timesheetDocument);
80 }
81 } else if (StringUtils.isNotBlank(timeApprovalActionForm.getHrCalendarEntryId())) {
82 calendarEntry = HrServiceLocator.getCalendarEntryService().getCalendarEntry(timeApprovalActionForm.getHrCalendarEntryId());
83 } else if (StringUtils.isNotBlank(timeApprovalActionForm.getSelectedPayPeriod())) {
84 calendarEntry = HrServiceLocator.getCalendarEntryService().getCalendarEntry(timeApprovalActionForm.getSelectedPayPeriod());
85 } else {
86 Calendar calendar = HrServiceLocator.getCalendarService().getCalendarByGroup(timeApprovalActionForm.getSelectedPayCalendarGroup());
87 if (calendar != null) {
88 calendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarEntryByCalendarId(calendar.getHrCalendarId(), LocalDate.now().toDateTimeAtStartOfDay());
89 }
90 }
91
92 if (calendarEntry != null) {
93 timeApprovalActionForm.setHrCalendarEntryId(calendarEntry.getHrCalendarEntryId());
94 timeApprovalActionForm.setCalendarEntry(calendarEntry);
95 timeApprovalActionForm.setBeginCalendarEntryDate(calendarEntry.getBeginPeriodFullDateTime().toDate());
96 timeApprovalActionForm.setEndCalendarEntryDate(calendarEntry.getEndPeriodFullDateTime().minusMillis(-1).toDate());
97
98 CalendarEntry prevCalendarEntry = HrServiceLocator.getCalendarEntryService().getPreviousCalendarEntryByCalendarId(calendarEntry.getHrCalendarId(), calendarEntry);
99 timeApprovalActionForm.setPrevHrCalendarEntryId(prevCalendarEntry != null ? prevCalendarEntry.getHrCalendarEntryId() : null);
100
101 CalendarEntry nextCalendarEntry = HrServiceLocator.getCalendarEntryService().getNextCalendarEntryByCalendarId(calendarEntry.getHrCalendarId(), calendarEntry);
102 timeApprovalActionForm.setNextHrCalendarEntryId(nextCalendarEntry != null ? nextCalendarEntry.getHrCalendarEntryId() : null);
103
104 setCalendarFields(timeApprovalActionForm);
105
106 timeApprovalActionForm.setPayCalendarLabels(TkServiceLocator.getTimeSummaryService().getHeaderForSummary(timeApprovalActionForm.getCalendarEntry(), new ArrayList<Boolean>()));
107
108
109
110
111 List<String> allPIdsList = getPrincipalIds(timeApprovalActionForm);
112 List<String> pidList = new ArrayList<String>();
113 pidList.addAll(allPIdsList);
114
115 String docIdSearchTerm = "";
116 if(StringUtils.equals(timeApprovalActionForm.getMethodToCall(), "searchResult") ) {
117 if(StringUtils.equals(timeApprovalActionForm.getSearchField(), "principalName") ) {
118 if (StringUtils.isNotBlank(timeApprovalActionForm.getSearchTerm())) {
119 String searchTerm = timeApprovalActionForm.getSearchTerm();
120 pidList = new ArrayList<String>();
121 for(String anId : allPIdsList) {
122 if(anId.contains(searchTerm)) {
123 pidList.add(anId);
124 }
125 }
126 }
127 }
128
129 if(StringUtils.equals(timeApprovalActionForm.getSearchField(), "documentId") )
130 docIdSearchTerm = timeApprovalActionForm.getSearchTerm();
131 }
132
133 setApprovalTables(timeApprovalActionForm, request, pidList, docIdSearchTerm);
134 }
135 setMessages(timeApprovalActionForm);
136 return actionForward;
137 }
138
139 @Override
140 protected List<String> getCalendars(List<String> principalIds) {
141 return HrServiceLocator.getPrincipalHRAttributeService().getUniquePayCalendars(principalIds);
142 }
143
144 public ActionForward selectNewPayCalendar(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
145 TimeApprovalActionForm timeApprovalActionForm = (TimeApprovalActionForm) form;
146 CalendarEntry calendarEntry = null;
147 Calendar calendar = HrServiceLocator.getCalendarService().getCalendarByGroup(timeApprovalActionForm.getSelectedPayCalendarGroup());
148
149 if (calendar != null) {
150 calendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarEntryByCalendarId(calendar.getHrCalendarId(), LocalDate.now().toDateTimeAtStartOfDay());
151 }
152
153 if (calendarEntry != null) {
154 timeApprovalActionForm.setHrCalendarEntryId(calendarEntry.getHrCalendarEntryId());
155 timeApprovalActionForm.setCalendarEntry(calendarEntry);
156
157 this.setCalendarFields(timeApprovalActionForm);
158 }
159
160 timeApprovalActionForm.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
161
162 return mapping.findForward("basic");
163 }
164
165 public ActionForward selectNewDept(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
166 TimeApprovalActionForm timeApprovalActionForm = (TimeApprovalActionForm) form;
167 setApprovalTables(timeApprovalActionForm, request, getPrincipalIds(timeApprovalActionForm), "");
168
169 return mapping.findForward("basic");
170 }
171
172 public ActionForward selectNewWorkArea(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
173 TimeApprovalActionForm timeApprovalActionForm = (TimeApprovalActionForm) form;
174 setApprovalTables(timeApprovalActionForm, request, getPrincipalIds(timeApprovalActionForm), "");
175
176 return mapping.findForward("basic");
177 }
178
179
180 public ActionForward searchResult(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
181 TimeApprovalActionForm timeApprovalActionForm = (TimeApprovalActionForm) form;
182
183 if(StringUtils.isBlank(timeApprovalActionForm.getSearchField())
184 && StringUtils.isNotBlank(request.getParameter("searchField"))) {
185 timeApprovalActionForm.setSearchField(request.getParameter("searchField"));
186 }
187 if(StringUtils.isBlank(timeApprovalActionForm.getSearchTerm())
188 && StringUtils.isNotBlank(request.getParameter("searchValue"))) {
189 timeApprovalActionForm.setSearchTerm(request.getParameter("searchValue"));
190 }
191 if(StringUtils.isBlank(timeApprovalActionForm.getSelectedPayPeriod())
192 && StringUtils.isNotBlank(request.getParameter("selectedPayPeriod"))) {
193 timeApprovalActionForm.setSelectedPayPeriod(request.getParameter("selectedPayPeriod"));
194 }
195 return mapping.findForward("basic");
196 }
197
198 public ActionForward resetSearch(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
199 TimeApprovalActionForm timeApprovalActionForm = (TimeApprovalActionForm) form;
200 timeApprovalActionForm.setSearchField("");
201 timeApprovalActionForm.setSearchTerm("");
202 return mapping.findForward("basic");
203 }
204
205 public ActionForward goToCurrentPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
206 TimeApprovalActionForm timeApprovalActionForm = (TimeApprovalActionForm) form;
207 timeApprovalActionForm.setSearchField("");
208 timeApprovalActionForm.setSearchTerm("");
209 timeApprovalActionForm.setSelectedPayPeriod("");
210 timeApprovalActionForm.setHrCalendarEntryId("");
211 return mapping.findForward("basic");
212 }
213
214 private List<String> getPrincipalIds(TimeApprovalActionForm timeApprovalActionForm) {
215 List<String> workAreas = new ArrayList<String>();
216 if (StringUtil.isEmpty(timeApprovalActionForm.getSelectedWorkArea())) {
217 for (Long workAreaKey : timeApprovalActionForm.getWorkAreaDescr().keySet()) {
218 workAreas.add(workAreaKey.toString());
219 }
220 } else {
221 workAreas.add(timeApprovalActionForm.getSelectedWorkArea());
222 }
223 String calendar = timeApprovalActionForm.getSelectedPayCalendarGroup();
224 if (timeApprovalActionForm.getCalendarEntry() == null) {
225 return Collections.emptyList();
226 }
227
228 LocalDate endDate = timeApprovalActionForm.getCalendarEntry().getEndPeriodFullDateTime().toLocalDate();
229 LocalDate beginDate = timeApprovalActionForm.getCalendarEntry().getBeginPeriodFullDateTime().toLocalDate();
230
231 List<String> pList1 = TkServiceLocator.getTimeApproveService().getTimePrincipalIdsWithSearchCriteria(workAreas, calendar, beginDate, beginDate, endDate);
232 List<String> pList2 = TkServiceLocator.getTimeApproveService().getTimePrincipalIdsWithSearchCriteria(workAreas, calendar, endDate, beginDate, endDate);
233 Set<String> pIdSet = new HashSet<String>();
234 pIdSet.addAll(pList1);
235 pIdSet.addAll(pList2);
236 List<String> finalList = new ArrayList<String>(pIdSet);
237 return finalList;
238
239
240 }
241
242 protected void setApprovalTables(TimeApprovalActionForm timeApprovalActionForm, HttpServletRequest request, List<String> principalIds, String docIdSearchTerm) {
243 if (principalIds.isEmpty()) {
244 timeApprovalActionForm.setApprovalRows(new ArrayList<ApprovalTimeSummaryRow>());
245 timeApprovalActionForm.setResultSize(0);
246 timeApprovalActionForm.setOutputString(null);
247 } else {
248 List<ApprovalTimeSummaryRow> approvalRows = getApprovalRows(timeApprovalActionForm, principalIds, docIdSearchTerm);
249 timeApprovalActionForm.setOutputString(!CollectionUtils.isEmpty(approvalRows) ? approvalRows.get(0).getOutputString() : null);
250 final String sortField = getSortField(request);
251 if (StringUtils.isEmpty(sortField) || StringUtils.equals(sortField, "name")) {
252 final boolean sortNameAscending = getAscending(request);
253 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() {
254 @Override
255 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) {
256 if (sortNameAscending) {
257 return ObjectUtils.compare(StringUtils.lowerCase(row1.getName()), StringUtils.lowerCase(row2.getName()));
258 } else {
259 return ObjectUtils.compare(StringUtils.lowerCase(row2.getName()), StringUtils.lowerCase(row1.getName()));
260 }
261 }
262 });
263 } else if (StringUtils.equals(sortField, "documentID")) {
264 final boolean sortDocumentIdAscending = getAscending(request);
265 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() {
266 @Override
267 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) {
268 if (sortDocumentIdAscending) {
269 return ObjectUtils.compare(NumberUtils.toInt(row1.getDocumentId()), NumberUtils.toInt(row2.getDocumentId()));
270 } else {
271 return ObjectUtils.compare(NumberUtils.toInt(row2.getDocumentId()), NumberUtils.toInt(row1.getDocumentId()));
272 }
273 }
274 });
275 } else if (StringUtils.equals(sortField, "status")) {
276 final boolean sortStatusIdAscending = getAscending(request);;
277 Collections.sort(approvalRows, new Comparator<ApprovalTimeSummaryRow>() {
278 @Override
279 public int compare(ApprovalTimeSummaryRow row1, ApprovalTimeSummaryRow row2) {
280 if (sortStatusIdAscending) {
281 return ObjectUtils.compare(StringUtils.lowerCase(row1.getApprovalStatus()), StringUtils.lowerCase(row2.getApprovalStatus()));
282 } else {
283 return ObjectUtils.compare(StringUtils.lowerCase(row2.getApprovalStatus()), StringUtils.lowerCase(row1.getApprovalStatus()));
284 }
285 }
286 });
287 }
288
289 String page = request.getParameter((new ParamEncoder(HrConstants.APPROVAL_TABLE_ID).encodeParameterName(TableTagParameters.PARAMETER_PAGE)));
290 Integer beginIndex = StringUtils.isBlank(page) || StringUtils.equals(page, "1") ? 0 : (Integer.parseInt(page) - 1) * timeApprovalActionForm.getPageSize();
291 Integer endIndex = beginIndex + timeApprovalActionForm.getPageSize() > approvalRows.size() ? approvalRows.size() : beginIndex + timeApprovalActionForm.getPageSize();
292 for (ApprovalTimeSummaryRow approvalTimeSummaryRow : approvalRows) {
293 approvalTimeSummaryRow.setMissedPunchList(getMissedPunches(approvalTimeSummaryRow.getDocumentId()));
294 }
295
296 MissedPunchDocumentService mpds;
297 mpds = TkServiceLocator.getMissedPunchDocumentService();
298
299 Map<String, Boolean> missedPunchPermissions = new HashMap<String, Boolean>();
300
301 for (ApprovalTimeSummaryRow approvalTimeSummaryRow : approvalRows) {
302 for (MissedPunch mp: approvalTimeSummaryRow.getMissedPunchList()) {
303 MissedPunchDocument mpd = (MissedPunchDocument) mpds.getMissedPunchDocumentByMissedPunchId(mp.getTkMissedPunchId());
304
305 String groupKey = mpd.getGroupKeyCode();
306 Long workArea = mpd.getWorkArea();
307 String department = mpd.getDepartment();
308 String location = mpd.getGroupKey() != null ? mpd.getGroupKey().getLocationId() : HrServiceLocator.getHrGroupKeyService().getHrGroupKey(mpd.getGroupKeyCode(), mpd.getMissedPunch().getActionLocalDate()).getLocationId();
309
310 String principalId = HrContext.getPrincipalId();
311 Map<String, String> roleQualification = new HashMap<String, String>();
312 roleQualification.put(KimConstants.AttributeConstants.PRINCIPAL_ID, principalId);
313 roleQualification.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), department);
314 roleQualification.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), workArea.toString());
315 roleQualification.put(KPMERoleMemberAttribute.GROUP_KEY_CODE.getRoleMemberAttributeName(), groupKey);
316 roleQualification.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), location);
317
318 Map<String, String> permissionDetails = new HashMap<String, String>();
319 permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME, KRADServiceLocatorWeb.getDocumentDictionaryService().getDocumentTypeByClass(MissedPunchDocument.class));
320
321 boolean canView = (KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(principalId, KPMENamespace.KPME_WKFLW.getNamespaceCode(),
322 KPMEPermissionTemplate.VIEW_KPME_RECORD.getPermissionTemplateName(), permissionDetails, roleQualification));
323
324 missedPunchPermissions.put(mp.getMissedPunchDocId(), canView);
325 }
326 }
327
328 timeApprovalActionForm.setMissedPunchPermissions(missedPunchPermissions);
329
330 List<ApprovalTimeSummaryRow> sublist = new ArrayList<ApprovalTimeSummaryRow>();
331 sublist.addAll(approvalRows.subList(beginIndex, endIndex));
332 timeApprovalActionForm.setApprovalRows(sublist);
333 timeApprovalActionForm.setResultSize(approvalRows.size());
334 }
335 }
336
337 private List<MissedPunch> getMissedPunches(String documentId) {
338 return TkServiceLocator.getMissedPunchService().getMissedPunchByTimesheetDocumentId(documentId);
339 }
340
341 protected List<ApprovalTimeSummaryRow> getApprovalRows(TimeApprovalActionForm timeApprovalActionForm, List<String> assignmentPrincipalIds, String docIdSearchTerm) {
342 return (List<ApprovalTimeSummaryRow>)TkServiceLocator.getTimeApproveService().getApprovalSummaryRows(timeApprovalActionForm.getSelectedPayCalendarGroup(), assignmentPrincipalIds, timeApprovalActionForm.getPayCalendarLabels(), timeApprovalActionForm.getCalendarEntry(), docIdSearchTerm);
343 }
344
345 public ActionForward approve(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
346 TimeApprovalActionForm taaf = (TimeApprovalActionForm) form;
347 List<ApprovalTimeSummaryRow> lstApprovalRows = taaf.getApprovalRows();
348 List<String> errorList = new ArrayList<String>();
349 for (ApprovalTimeSummaryRow ar : lstApprovalRows) {
350 if (ar.isApprovable() && StringUtils.equals(ar.getSelected(), "on")) {
351 String documentNumber = ar.getDocumentId();
352 TimesheetDocument tDoc = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentNumber);
353 if (tDoc != null) {
354 if(TkServiceLocator.getTimesheetService().isTimesheetValid(tDoc)) {
355 TkServiceLocator.getTimesheetService().approveTimesheet(HrContext.getPrincipalId(), tDoc);
356 } else {
357 errorList.add( "Timesheet " + tDoc.getDocumentId() + " could not be approved as it contains errors, see time detail for more info");
358 }
359 }
360 }
361 }
362 ActionRedirect redirect = new ActionRedirect(mapping.findForward("basicRedirect"));
363 redirect.addParameter("selectedDept", taaf.getSelectedDept());
364 redirect.addParameter("selectedPayCalendarGroup", taaf.getSelectedPayCalendarGroup());
365 redirect.addParameter("selectedWorkArea", taaf.getSelectedWorkArea());
366 redirect.addParameter("selectedPayPeriod", taaf.getSelectedPayPeriod());
367 redirect.addParameter("errorMessageList", errorList);
368
369 return redirect;
370 }
371
372 protected void setMessages(TimeApprovalActionForm taaf) {
373 List<ApprovalTimeSummaryRow> lstApprovalRows = taaf.getApprovalRows();
374 List<String> errorList = new ArrayList<String>();
375 for (ApprovalTimeSummaryRow ar : lstApprovalRows) {
376 String documentNumber = ar.getDocumentId();
377 TimesheetDocument tDoc = TkServiceLocator.getTimesheetService().getTimesheetDocument(documentNumber);
378 if (tDoc != null && !TkServiceLocator.getTimesheetService().isTimesheetValid(tDoc)) {
379 errorList.add("Timesheet " + tDoc.getDocumentId() + " could not be approved as it contains errors, see time detail for more info");
380 }
381 }
382 taaf.setErrorMessageList(errorList);
383 }
384 }