1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.lm.leavecalendar.web;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.commons.lang.SystemUtils;
21 import org.apache.commons.lang.time.DateUtils;
22 import org.apache.log4j.Logger;
23 import org.apache.struts.action.ActionForm;
24 import org.apache.struts.action.ActionForward;
25 import org.apache.struts.action.ActionMapping;
26 import org.apache.struts.action.ActionRedirect;
27 import org.joda.time.DateTime;
28 import org.joda.time.Interval;
29 import org.joda.time.LocalDateTime;
30 import org.joda.time.format.DateTimeFormat;
31 import org.joda.time.format.DateTimeFormatter;
32 import org.kuali.hr.lm.LMConstants;
33 import org.kuali.hr.lm.accrual.AccrualCategory;
34 import org.kuali.hr.lm.accrual.AccrualCategoryRule;
35 import org.kuali.hr.lm.balancetransfer.BalanceTransfer;
36 import org.kuali.hr.lm.balancetransfer.validation.BalanceTransferValidationUtils;
37 import org.kuali.hr.lm.leaveSummary.LeaveSummary;
38 import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
39 import org.kuali.hr.lm.leaveblock.LeaveBlock;
40 import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
41 import org.kuali.hr.lm.leavecalendar.validation.LeaveCalendarValidationUtil;
42 import org.kuali.hr.lm.util.LeaveBlockAggregate;
43 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
44 import org.kuali.hr.lm.workflow.LeaveRequestDocument;
45 import org.kuali.hr.time.assignment.Assignment;
46 import org.kuali.hr.time.base.web.TkAction;
47 import org.kuali.hr.time.calendar.Calendar;
48 import org.kuali.hr.time.calendar.CalendarEntries;
49 import org.kuali.hr.time.calendar.LeaveCalendar;
50 import org.kuali.hr.time.detail.web.ActionFormUtils;
51 import org.kuali.hr.time.earncode.EarnCode;
52 import org.kuali.hr.time.principal.PrincipalHRAttributes;
53 import org.kuali.hr.time.roles.TkUserRoles;
54 import org.kuali.hr.time.roles.UserRoles;
55 import org.kuali.hr.time.service.base.TkServiceLocator;
56 import org.kuali.hr.time.util.TKContext;
57 import org.kuali.hr.time.util.TKUser;
58 import org.kuali.hr.time.util.TKUtils;
59 import org.kuali.hr.time.util.TkConstants;
60 import org.kuali.rice.core.api.config.property.ConfigContext;
61 import org.kuali.rice.kew.api.KewApiServiceLocator;
62 import org.kuali.rice.kew.api.document.DocumentStatus;
63 import org.kuali.rice.kew.service.KEWServiceLocator;
64 import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
65 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
66 import org.kuali.rice.krad.exception.AuthorizationException;
67 import org.kuali.rice.krad.util.GlobalVariables;
68 import org.kuali.rice.krad.util.ObjectUtils;
69 import org.kuali.rice.krad.util.UrlFactory;
70
71 import javax.servlet.http.HttpServletRequest;
72 import javax.servlet.http.HttpServletResponse;
73 import java.math.BigDecimal;
74 import java.sql.Date;
75 import java.sql.Timestamp;
76 import java.text.DateFormat;
77 import java.text.SimpleDateFormat;
78 import java.util.*;
79 import java.util.Map.Entry;
80
81 public class LeaveCalendarAction extends TkAction {
82
83 private static final Logger LOG = Logger.getLogger(LeaveCalendarAction.class);
84
85 @Override
86 protected void checkTKAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
87 UserRoles roles = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId());
88 LeaveCalendarDocument doc = TKContext.getCurrentLeaveCalendarDocument();
89
90 if (doc != null && !roles.isDocumentReadable(doc)) {
91 throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalId(), "LeaveCalendarAction: docid: " + (doc == null ? "" : doc.getDocumentId()), "");
92 }
93 }
94
95 @Override
96 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
97 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
98 String documentId = lcf.getDocumentId();
99
100 if (StringUtils.equals(request.getParameter("command"), "displayDocSearchView")
101 || StringUtils.equals(request.getParameter("command"), "displayActionListView") ) {
102 documentId = (String) request.getParameter("docId");
103 }
104
105 LOG.debug("DOCID: " + documentId);
106
107
108 String calendarEntryId = StringUtils.isNotBlank(request.getParameter("selectedPP")) ? request.getParameter("selectedPP") : lcf.getCalEntryId();
109
110
111
112 String viewPrincipal = TKUser.getCurrentTargetPersonId();
113 CalendarEntries calendarEntry = null;
114
115 LeaveCalendarDocument lcd = null;
116 LeaveCalendarDocumentHeader lcdh = null;
117
118
119
120
121
122 if (StringUtils.isNotBlank(documentId)) {
123 lcd = TkServiceLocator.getLeaveCalendarService()
124 .getLeaveCalendarDocument(documentId);
125 calendarEntry = lcd.getCalendarEntry();
126 } else if (StringUtils.isNotBlank(calendarEntryId)) {
127
128 calendarEntry = TkServiceLocator.getCalendarEntriesService()
129 .getCalendarEntries(calendarEntryId);
130 } else {
131
132 Date currentDate = TKUtils.getTimelessDate(null);
133 calendarEntry = TkServiceLocator.getCalendarService()
134 .getCurrentCalendarDatesForLeaveCalendar(viewPrincipal, currentDate);
135 }
136 lcf.setCalendarEntry(calendarEntry);
137 if(calendarEntry != null) {
138 lcf.setCalEntryId(calendarEntry.getHrCalendarEntriesId());
139 }
140
141 String runAccrualFlag = ConfigContext.getCurrentContextConfig().getProperty(LMConstants.RUN_ACCRUAL_FROM_CALENDAR);
142 if(StringUtils.equals(runAccrualFlag, "true")) {
143
144
145 if(calendarEntry != null && calendarEntry.getEndPeriodDate().after(TKUtils.getCurrentDate())) {
146 if(TkServiceLocator.getLeaveAccrualService().statusChangedSinceLastRun(viewPrincipal)) {
147 TkServiceLocator.getLeaveAccrualService().calculateFutureAccrualUsingPlanningMonth(viewPrincipal, calendarEntry.getBeginPeriodDate());
148 }
149 }
150 }
151
152 if(lcd == null) {
153
154 boolean createFlag = TkServiceLocator.getLeaveCalendarService().shouldCreateLeaveDocument(viewPrincipal, calendarEntry);
155 if(createFlag) {
156 lcd = TkServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(viewPrincipal, calendarEntry);
157 } else {
158 LeaveCalendarDocumentHeader header = TkServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(viewPrincipal, calendarEntry.getBeginPeriodDateTime(), calendarEntry.getEndPeriodDateTime());
159 if(header != null) {
160 lcd = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(header.getDocumentId());
161 }
162 }
163 }
164 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(viewPrincipal, calendarEntry);
165 List<String> assignmentKeys = new ArrayList<String>();
166 for(Assignment assign : assignments) {
167 assignmentKeys.add(assign.getAssignmentKey());
168 }
169 if (lcd != null) {
170 lcf.setDocumentId(lcd.getDocumentId());
171 lcf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptions(lcd));
172 lcdh = lcd.getDocumentHeader();
173 } else {
174 lcf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptionsForAssignments(assignments));
175 }
176 setupDocumentOnFormContext(lcf, lcd);
177 ActionForward forward = super.execute(mapping, form, request, response);
178
179 if (forward.getRedirect()) {
180 return forward;
181 }
182
183 LeaveCalendar calendar = null;
184 if (calendarEntry != null) {
185 calendar = new LeaveCalendar(viewPrincipal, calendarEntry, assignmentKeys);
186 lcf.setLeaveCalendar(calendar);
187 }
188
189 this.populateCalendarAndPayPeriodLists(request, lcf);
190
191
192 List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>();
193 if (lcdh != null && lcdh.getPrincipalId() != null && lcdh.getBeginDate() != null && lcdh.getEndDate() != null) {
194 leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocksForLeaveCalendar(lcdh.getPrincipalId(), lcdh.getBeginDate(), lcdh.getEndDate(), assignmentKeys);
195 } else if(calendarEntry != null){
196 leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocksForLeaveCalendar(viewPrincipal, calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate(), assignmentKeys);
197 }
198
199
200 if (calendarEntry != null) {
201
202 PrincipalHRAttributes principalCal = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(viewPrincipal, calendarEntry.getEndPeriodDate());
203 if(principalCal != null) {
204
205 DateTime currentYearBeginDate = TkServiceLocator.getLeavePlanService().getFirstDayOfLeavePlan(principalCal.getLeavePlan(), TKUtils.getCurrentDate());
206 DateTime calEntryEndDate = new DateTime(calendarEntry.getEndPeriodDate());
207 if (calEntryEndDate.getMillis() > currentYearBeginDate.getMillis()) {
208
209 LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(viewPrincipal, calendarEntry);
210 lcf.setLeaveSummary(ls);
211 } else {
212
213 DateTime effDate = TkServiceLocator.getLeavePlanService().getRolloverDayOfLeavePlan(principalCal.getLeavePlan(), calEntryEndDate.toDate()).minus(1);
214 LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummaryAsOfDateWithoutFuture(viewPrincipal, new java.sql.Date(effDate.getMillis()));
215
216 DateFormat formatter = new SimpleDateFormat("MMMM d");
217 DateFormat formatter2 = new SimpleDateFormat("MMMM d yyyy");
218 DateTime entryEndDate = new LocalDateTime(calendarEntry.getEndPeriodDate()).toDateTime();
219 if (entryEndDate.getHourOfDay() == 0) {
220 entryEndDate = entryEndDate.minusDays(1);
221 }
222 String aString = formatter.format(calendarEntry.getBeginPeriodDate()) + " - " + formatter2.format(entryEndDate.toDate());
223 ls.setPendingDatesString(aString);
224 DateTimeFormatter fmt = DateTimeFormat.forPattern("MMM d, yyyy");
225 ls.setNote("Values as of: " + fmt.print(effDate));
226 lcf.setLeaveSummary(ls);
227 }
228
229 }
230 }
231
232
233 Map<String, Set<String>> allMessages = LeaveCalendarValidationUtil.getWarningMessagesForLeaveBlocks(leaveBlocks);
234
235
236
237
238
239
240 if(ObjectUtils.isNotNull(calendarEntry)) {
241 PrincipalHRAttributes principalCalendar = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(viewPrincipal, calendarEntry.getEndPeriodDate());
242 List<BalanceTransfer> losses = new ArrayList<BalanceTransfer>();
243
244 Interval calendarInterval = new Interval(calendarEntry.getBeginPeriodDate().getTime(), calendarEntry.getEndPeriodDate().getTime());
245 Map<String,Set<LeaveBlock>> maxBalInfractions = new HashMap<String,Set<LeaveBlock>>();
246
247 Date effectiveDate = TKUtils.getCurrentDate();
248 if(!calendarInterval.contains(TKUtils.getCurrentDate().getTime()))
249 effectiveDate = calendarEntry.getEndPeriodDate();
250
251 if(ObjectUtils.isNotNull(principalCalendar)) {
252 maxBalInfractions = TkServiceLocator.getAccrualCategoryMaxBalanceService().getMaxBalanceViolations(calendarEntry, viewPrincipal);
253
254 LeaveSummary summary = lcf.getLeaveSummary();
255 for(Entry<String,Set<LeaveBlock>> entry : maxBalInfractions.entrySet()) {
256 for(LeaveBlock lb : entry.getValue()) {
257 AccrualCategory accrualCat = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(lb.getAccrualCategory(), lb.getLeaveDate());
258 AccrualCategoryRule aRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(lb.getAccrualCategoryRuleId());
259 if(StringUtils.equals(aRule.getActionAtMaxBalance(),LMConstants.ACTION_AT_MAX_BAL.LOSE)) {
260 DateTime aDate = null;
261 if(StringUtils.equals(aRule.getMaxBalanceActionFrequency(), LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
262 aDate = TkServiceLocator.getLeavePlanService().getRolloverDayOfLeavePlan(principalCalendar.getLeavePlan(), lb.getLeaveDate());
263 }
264 else {
265 Calendar cal = TkServiceLocator.getCalendarService().getCalendarByPrincipalIdAndDate(viewPrincipal, lb.getLeaveDate(), true);
266 CalendarEntries leaveEntry = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(cal.getHrCalendarId(), lb.getLeaveDate());
267 aDate = new DateTime(leaveEntry.getEndPeriodDate());
268 }
269 aDate = aDate.minusDays(1);
270 if(calendarInterval.contains(aDate.getMillis()) && aDate.toDate().compareTo(calendarEntry.getEndPeriodDate()) <= 0) {
271
272 AccrualCategory accrualCategory = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(aRule.getLmAccrualCategoryId());
273 BigDecimal accruedBalance = TkServiceLocator.getAccrualCategoryService().getAccruedBalanceForPrincipal(viewPrincipal, accrualCategory, lb.getLeaveDate());
274
275 BalanceTransfer loseTransfer = TkServiceLocator.getBalanceTransferService().initializeTransfer(viewPrincipal, lb.getAccrualCategoryRuleId(), accruedBalance, lb.getLeaveDate());
276 boolean valid = BalanceTransferValidationUtils.validateTransfer(loseTransfer);
277 if(valid)
278 losses.add(loseTransfer);
279 }
280 }
281 else if(StringUtils.equals(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND, aRule.getMaxBalanceActionFrequency())) {
282 if(calendarInterval.contains(lb.getLeaveDate().getTime())) {
283
284 List<LeaveSummaryRow> summaryRows = summary.getLeaveSummaryRows();
285 List<LeaveSummaryRow> updatedSummaryRows = new ArrayList<LeaveSummaryRow>(summaryRows.size());
286
287 for(LeaveSummaryRow summaryRow : summaryRows) {
288 if(StringUtils.equals(summaryRow.getAccrualCategory(),accrualCat.getAccrualCategory())) {
289 if(StringUtils.equals(aRule.getActionAtMaxBalance(),LMConstants.ACTION_AT_MAX_BAL.PAYOUT))
290 summaryRow.setPayoutable(true);
291 else
292 if(StringUtils.equals(aRule.getActionAtMaxBalance(),LMConstants.ACTION_AT_MAX_BAL.TRANSFER))
293 summaryRow.setTransferable(true);
294
295 summaryRow.setInfractingLeaveBlockId(lb.getLmLeaveBlockId());
296 }
297 updatedSummaryRows.add(summaryRow);
298 }
299 summary.setLeaveSummaryRows(updatedSummaryRows);
300 }
301 }
302
303 if(calendarInterval.contains(lb.getLeaveDate().getTime())) {
304
305 String message = "You have exceeded the maximum balance limit for '" + accrualCat.getAccrualCategory() + "' as of " + lb.getLeaveDate() + ". "+
306 "Depending upon the accrual category rules, leave over this limit may be forfeited.";
307
308 if(!StringUtils.contains(allMessages.get("warningMessages").toString(),"You have exceeded the maximum balance limit for '"+accrualCat.getAccrualCategory())) {
309 allMessages.get("warningMessages").add(message);
310 }
311 }
312 }
313 }
314 lcf.setLeaveSummary(summary);
315 }
316 lcf.setForfeitures(losses);
317
318 Map<String,Set<String>> transactions = LeaveCalendarValidationUtil.validatePendingTransactions(viewPrincipal, calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate());
319
320 allMessages.get("infoMessages").addAll(transactions.get("infoMessages"));
321 allMessages.get("warningMessages").addAll(transactions.get("warningMessages"));
322 allMessages.get("actionMessages").addAll(transactions.get("actionMessages"));
323 }
324
325
326
327
328
329 if(calendarEntry != null) {
330 PrincipalHRAttributes principalCalendar = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(viewPrincipal, calendarEntry.getEndPeriodDate());
331 if (principalCalendar != null) {
332 List<AccrualCategory> accrualCategories = TkServiceLocator.getAccrualCategoryService().getActiveLeaveAccrualCategoriesForLeavePlan(principalCalendar.getLeavePlan(), new java.sql.Date(calendarEntry.getEndPeriodDate().getTime()));
333 for (AccrualCategory accrualCategory : accrualCategories) {
334 if (TkServiceLocator.getAccrualCategoryMaxCarryOverService().exceedsAccrualCategoryMaxCarryOver(accrualCategory.getAccrualCategory(), viewPrincipal, calendarEntry, calendarEntry.getEndPeriodDate())) {
335 String message = "Your pending leave balance is greater than the annual max carry over for accrual category '" + accrualCategory.getAccrualCategory() + "' and upon approval, the excess balance will be lost.";
336 if (!allMessages.get("warningMessages").contains(message)) {
337 allMessages.get("warningMessages").add(message);
338 }
339 }
340 }
341 }
342 }
343
344 List<String> warningMessages = new ArrayList<String>();
345 List<String> infoMessages = new ArrayList<String>();
346 List<String> actionMessages = new ArrayList<String>();
347
348 warningMessages.addAll(allMessages.get("warningMessages"));
349 infoMessages.addAll(allMessages.get("infoMessages"));
350 actionMessages.addAll(allMessages.get("actionMessages"));
351
352 lcf.setWarningMessages(warningMessages);
353 lcf.setInfoMessages(infoMessages);
354 lcf.setActionMessages(actionMessages);
355
356
357
358 if (calendarEntry != null) {
359 LeaveBlockAggregate aggregate = new LeaveBlockAggregate(leaveBlocks, calendarEntry, calendar);
360 lcf.setLeaveBlockString(LeaveActionFormUtils.getLeaveBlocksJson(aggregate.getFlattenedLeaveBlockList()));
361 }
362
363
364
365 return forward;
366 }
367
368 private void populateCalendarAndPayPeriodLists(HttpServletRequest request, LeaveCalendarForm lcf) {
369 String viewPrincipal = TKUser.getCurrentTargetPersonId();
370 SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
371
372 List<CalendarEntries> ceList = lcf.getCalendarEntry() == null ? new ArrayList<CalendarEntries>() : TkServiceLocator.getCalendarEntriesService()
373 .getAllCalendarEntriesForCalendarIdUpToPlanningMonths(lcf.getCalendarEntry().getHrCalendarId(), TKUser.getCurrentTargetPersonId());
374
375 if(lcf.getCalendarYears().isEmpty()) {
376
377 Set<String> yearSet = new HashSet<String>();
378 for(CalendarEntries ce : ceList) {
379 yearSet.add(sdf.format(ce.getBeginPeriodDate()));
380 }
381 List<String> yearList = new ArrayList<String>(yearSet);
382 Collections.sort(yearList);
383 Collections.reverse(yearList);
384 lcf.setCalendarYears(yearList);
385 }
386
387 if(request.getParameter("selectedCY")!= null) {
388 lcf.setSelectedCalendarYear(request.getParameter("selectedCY").toString());
389 }
390
391 if(StringUtils.isEmpty(lcf.getSelectedCalendarYear())
392 && lcf.getCalendarEntry() != null) {
393 lcf.setSelectedCalendarYear(sdf.format(lcf.getCalendarEntry().getBeginPeriodDate()));
394 }
395
396 if(lcf.getPayPeriodsMap().isEmpty()) {
397 List<CalendarEntries> yearCEList = ActionFormUtils.getAllCalendarEntriesForYear(ceList, lcf.getSelectedCalendarYear());
398 lcf.setPayPeriodsMap(ActionFormUtils.getPayPeriodsMap(yearCEList, viewPrincipal));
399 }
400
401 if(request.getParameter("selectedPP")!= null) {
402 lcf.setSelectedPayPeriod(request.getParameter("selectedPP").toString());
403 }
404 if(StringUtils.isEmpty(lcf.getSelectedPayPeriod())
405 && lcf.getCalendarEntry() != null) {
406 lcf.setSelectedPayPeriod(lcf.getCalendarEntry().getHrCalendarEntriesId());
407 }
408 }
409
410 public ActionForward addLeaveBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
411 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
412 LeaveCalendarDocument lcd = lcf.getLeaveCalendarDocument();
413
414 String principalId = TKContext.getPrincipalId();
415 String targetPrincipalId = TKContext.getTargetPrincipalId();
416 CalendarEntries calendarEntry = lcf.getCalendarEntry();
417 String selectedAssignment = lcf.getSelectedAssignment();
418
419 DateTime beginDate = null;
420 DateTime endDate = null;
421
422
423
424
425 LOG.debug("Start time is "+lcf.getStartTime());
426 LOG.debug("Emnd time is "+lcf.getEndTime());
427 if(lcf.getStartTime() != null && lcf.getEndTime() != null) {
428 beginDate = new DateTime(TKUtils.convertDateStringToTimestampWithoutZone(lcf.getStartDate(), lcf.getStartTime()).getTime());
429 endDate = new DateTime(TKUtils.convertDateStringToTimestampWithoutZone(lcf.getEndDate(), lcf.getEndTime()).getTime());
430 } else {
431 beginDate = new DateTime(TKUtils.convertDateStringToTimestampNoTimezone(lcf.getStartDate()));
432 endDate = new DateTime(TKUtils.convertDateStringToTimestampNoTimezone(lcf.getEndDate()));
433 }
434 LOG.debug("Begin Date is>> "+beginDate);
435 LOG.debug("End Date is>> "+endDate);
436
437
438
439
440
441
442 String selectedEarnCode = lcf.getSelectedEarnCode();
443 BigDecimal hours = lcf.getLeaveAmount();
444 String desc = lcf.getDescription();
445 String spanningWeeks = lcf.getSpanningWeeks();
446
447 String documentId = lcd != null ? lcd.getDocumentId() : "";
448
449 Assignment assignment = null;
450 if(lcd != null) {
451 assignment = TkServiceLocator.getAssignmentService().getAssignment(lcd, selectedAssignment);
452 } else {
453 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(targetPrincipalId, calendarEntry);
454 assignment = TkServiceLocator.getAssignmentService().getAssignment(assignments, selectedAssignment, calendarEntry.getBeginPeriodDate());
455 }
456
457 TkServiceLocator.getLeaveBlockService().addLeaveBlocks(beginDate, endDate, calendarEntry, selectedEarnCode, hours, desc, assignment, spanningWeeks,
458 LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR, targetPrincipalId);
459
460 generateLeaveCalendarChangedNotification(principalId, targetPrincipalId, documentId, calendarEntry.getHrCalendarEntriesId());
461
462
463 lcf.setLeaveAmount(null);
464 lcf.setDescription(null);
465
466
467 if(calendarEntry != null) {
468 java.sql.Date sqlDate = new java.sql.Date(endDate.getMillis());
469 this.rerunAccrualForNotEligibleForAccrualChanges(selectedEarnCode, sqlDate, calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate());
470 }
471
472 if (calendarEntry != null) {
473 LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(targetPrincipalId, calendarEntry);
474 lcf.setLeaveSummary(ls);
475 }
476
477 return mapping.findForward("basic");
478 }
479
480
481 public ActionForward deleteLeaveBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
482 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
483 LeaveCalendarDocument lcd = lcf.getLeaveCalendarDocument();
484
485 String principalId = TKContext.getPrincipalId();
486 String targetPrincipalId = TKContext.getTargetPrincipalId();
487 CalendarEntries calendarEntry = lcf.getCalendarEntry();
488 String leaveBlockId = lcf.getLeaveBlockId();
489
490 String documentId = lcd != null ? lcd.getDocumentId() : "";
491
492 LeaveBlock blockToDelete = TkServiceLocator.getLeaveBlockService().getLeaveBlock(leaveBlockId);
493 if (blockToDelete != null && TkServiceLocator.getPermissionsService().canDeleteLeaveBlock(blockToDelete)) {
494
495 if(blockToDelete.getRequestStatus().equals(LMConstants.REQUEST_STATUS.REQUESTED)) {
496 List<LeaveRequestDocument> lrdList = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocumentsByLeaveBlockId(blockToDelete.getLmLeaveBlockId());
497 if(CollectionUtils.isNotEmpty(lrdList)) {
498 for(LeaveRequestDocument lrd : lrdList) {
499 DocumentStatus status = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(lrd.getDocumentNumber());
500 if(DocumentStatus.ENROUTE.getCode().equals(status.getCode())) {
501
502 TkServiceLocator.getLeaveRequestDocumentService().recallAndCancelLeave(lrd.getDocumentNumber(), targetPrincipalId, "Leave block deleted by user " + principalId);
503 }
504 }
505 }
506 }
507
508 List<String> approverList = new ArrayList<String>();
509
510 if(blockToDelete.getRequestStatus().equals(LMConstants.REQUEST_STATUS.APPROVED)) {
511 List<LeaveRequestDocument> lrdList = TkServiceLocator.getLeaveRequestDocumentService().getLeaveRequestDocumentsByLeaveBlockId(blockToDelete.getLmLeaveBlockId());
512 if(CollectionUtils.isNotEmpty(lrdList)) {
513 for(LeaveRequestDocument lrd : lrdList) {
514 DocumentStatus status = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(lrd.getDocumentNumber());
515 if(DocumentStatus.FINAL.getCode().equals(status.getCode())) {
516
517 approverList = TkServiceLocator.getLeaveRequestDocumentService().getApproverIdList(lrd.getDocumentNumber());
518 }
519 }
520 }
521 }
522
523 TkServiceLocator.getLeaveBlockService().deleteLeaveBlock(leaveBlockId, principalId);
524 generateLeaveCalendarChangedNotification(principalId, targetPrincipalId, documentId, calendarEntry.getHrCalendarEntriesId());
525 if(CollectionUtils.isNotEmpty(approverList)) {
526 this.generateLeaveBlockDeletionNotification(approverList, targetPrincipalId, principalId, TKUtils.formatDate(blockToDelete.getLeaveDate()), blockToDelete.getLeaveAmount().toString());
527 }
528
529
530 if(lcf.getCalendarEntry() != null) {
531 rerunAccrualForNotEligibleForAccrualChanges(blockToDelete.getEarnCode(), blockToDelete.getLeaveDate(), calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate());
532 }
533 }
534
535 if(lcf.getCalendarEntry() != null) {
536 LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(targetPrincipalId, calendarEntry);
537 lcf.setLeaveSummary(ls);
538 }
539 return mapping.findForward("basic");
540 }
541
542
543
544
545
546
547
548
549
550 private void rerunAccrualForNotEligibleForAccrualChanges(String earnCode, Date asOfDate, Date startDate, Date endDate) {
551 EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, asOfDate);
552 if(ec != null && ec.getEligibleForAccrual().equals("N")) {
553 if(startDate != null && endDate != null) {
554
555 TkServiceLocator.getLeaveAccrualService().runAccrual(TKContext.getTargetPrincipalId(), startDate, endDate, false);
556 }
557 }
558 }
559
560
561 public ActionForward updateLeaveBlock(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
562 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
563 LeaveCalendarDocument lcd = lcf.getLeaveCalendarDocument();
564
565 String principalId = TKContext.getPrincipalId();
566 String targetPrincipalId = TKContext.getTargetPrincipalId();
567 CalendarEntries calendarEntry = lcf.getCalendarEntry();
568 String selectedEarnCode = lcf.getSelectedEarnCode();
569 String leaveBlockId = lcf.getLeaveBlockId();
570
571 String documentId = lcd != null ? lcd.getDocumentId() : "";
572
573 LeaveBlock updatedLeaveBlock = null;
574 updatedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(leaveBlockId);
575 if (updatedLeaveBlock.isEditable()) {
576 if (StringUtils.isNotBlank(lcf.getDescription())) {
577 updatedLeaveBlock.setDescription(lcf.getDescription().trim());
578 }
579 if (!updatedLeaveBlock.getLeaveAmount().equals(lcf.getLeaveAmount())) {
580 updatedLeaveBlock.setLeaveAmount(lcf.getLeaveAmount());
581 }
582
583 DateTime beginDate = null;
584 DateTime endDate = null;
585
586 EarnCode earnCode = TkServiceLocator.getEarnCodeService().getEarnCode(selectedEarnCode, updatedLeaveBlock.getLeaveDate());
587 if(earnCode != null && earnCode.getRecordMethod().equalsIgnoreCase(TkConstants.EARN_CODE_TIME)) {
588 if(lcf.getStartTime() != null && lcf.getEndTime() != null) {
589 beginDate = new DateTime(TKUtils.convertDateStringToTimestampWithoutZone(lcf.getStartDate(), lcf.getStartTime()).getTime());
590 endDate = new DateTime(TKUtils.convertDateStringToTimestampWithoutZone(lcf.getEndDate(), lcf.getEndTime()).getTime());
591 } else {
592 beginDate = new DateTime(TKUtils.convertDateStringToTimestampNoTimezone(lcf.getStartDate()));
593 endDate = new DateTime(TKUtils.convertDateStringToTimestampNoTimezone(lcf.getEndDate()));
594 }
595 updatedLeaveBlock.setBeginTimestamp(new Timestamp(beginDate.getMillis()));
596 updatedLeaveBlock.setEndTimestamp(new Timestamp(endDate.getMillis()));
597 updatedLeaveBlock.setLeaveAmount(TKUtils.getHoursBetween(beginDate.getMillis(), endDate.getMillis()));
598 }
599
600 if (!updatedLeaveBlock.getEarnCode().equals(earnCode.getEarnCode())) {
601 updatedLeaveBlock.setEarnCode(earnCode.getEarnCode());
602 }
603
604 TkServiceLocator.getLeaveBlockService().updateLeaveBlock(updatedLeaveBlock, principalId);
605 generateLeaveCalendarChangedNotification(principalId, targetPrincipalId, documentId, calendarEntry.getHrCalendarEntriesId());
606
607 lcf.setLeaveAmount(null);
608 lcf.setDescription(null);
609 lcf.setSelectedEarnCode(null);
610
611 if(lcf.getCalendarEntry() != null) {
612 LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(targetPrincipalId, calendarEntry);
613 lcf.setLeaveSummary(ls);
614 }
615 }
616 return mapping.findForward("basic");
617 }
618 protected void setupDocumentOnFormContext(LeaveCalendarForm leaveForm,
619 LeaveCalendarDocument lcd) {
620 CalendarEntries futureCalEntry = null;
621 String viewPrincipal = TKUser.getCurrentTargetPersonId();
622 CalendarEntries calEntry = leaveForm.getCalendarEntry();
623
624 Date startCalDate = null;
625
626
627 if(lcd != null) {
628 if (lcd.getDocumentHeader() != null) {
629 TKContext.setCurrentLeaveCalendarDocumentId(lcd.getDocumentId());
630 leaveForm.setDocumentId(lcd.getDocumentId());
631 }
632 TKContext.setCurrentLeaveCalendarDocument(lcd);
633 TKContext.setCurrentLeaveCalendarDocumentId(lcd.getDocumentId());
634 leaveForm.setLeaveCalendarDocument(lcd);
635 leaveForm.setDocumentId(lcd.getDocumentId());
636 calEntry = lcd.getCalendarEntry();
637 }
638
639 boolean isFutureDate = calEntry != null && TKUtils.getTimelessDate(null).compareTo(calEntry.getEndPeriodDateTime()) <= 0;
640
641
642 if (calEntry != null) {
643 CalendarEntries calPreEntry = TkServiceLocator
644 .getCalendarEntriesService()
645 .getPreviousCalendarEntriesByCalendarId(
646 calEntry.getHrCalendarId(),
647 calEntry);
648 if (calPreEntry != null) {
649
650
651 Date asOfDate = new Date(DateUtils.addDays(calPreEntry.getEndPeriodDate(),-1).getTime());;
652 PrincipalHRAttributes principalHRAttributes = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(viewPrincipal, asOfDate);
653
654 if(principalHRAttributes != null) {
655 startCalDate = principalHRAttributes.getServiceDate();
656 if(startCalDate != null) {
657 if(!(calPreEntry.getBeginPeriodDate().compareTo(startCalDate) < 0)) {
658 leaveForm.setPrevCalEntryId(calPreEntry
659 .getHrCalendarEntriesId());
660 }
661 } else {
662 leaveForm.setPrevCalEntryId(calPreEntry
663 .getHrCalendarEntriesId());
664 }
665 }
666 }
667
668 int planningMonths = ActionFormUtils.getPlanningMonthsForEmployee(viewPrincipal);
669 if(planningMonths != 0) {
670 List<CalendarEntries> futureCalEntries = TkServiceLocator
671 .getCalendarEntriesService()
672 .getFutureCalendarEntries(
673 calEntry.getHrCalendarId(),
674 TKUtils.getTimelessDate(null),
675 planningMonths);
676
677 if (futureCalEntries != null && !futureCalEntries.isEmpty()) {
678 futureCalEntry = futureCalEntries.get(futureCalEntries
679 .size() - 1);
680
681 CalendarEntries calNextEntry = TkServiceLocator
682 .getCalendarEntriesService()
683 .getNextCalendarEntriesByCalendarId(
684 calEntry.getHrCalendarId(),
685 calEntry);
686
687 if (calNextEntry != null
688 && futureCalEntries != null
689 && calNextEntry
690 .getBeginPeriodDateTime()
691 .compareTo(
692 futureCalEntry
693 .getBeginPeriodDateTime()) <= 0) {
694 leaveForm.setNextCalEntryId(calNextEntry
695 .getHrCalendarEntriesId());
696 }
697 }
698 }
699 }
700 if(leaveForm.getViewLeaveTabsWithNEStatus()) {
701 if(isFutureDate) {
702 setDocEditable(leaveForm, lcd);
703 } else {
704
705 Date currentDate = TKUtils.getTimelessDate(null);
706 CalendarEntries calendarEntry = TkServiceLocator.getCalendarService()
707 .getCurrentCalendarDatesForLeaveCalendar(viewPrincipal, currentDate);
708 if(calendarEntry != null) {
709 leaveForm.setCurrentPayCalStart(calendarEntry.getBeginLocalDateTime().toDateTime(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback()));
710 leaveForm.setCurrentPayCalEnd(calendarEntry.getEndLocalDateTime().toDateTime(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback()));
711 }
712 }
713 } else {
714 setDocEditable(leaveForm, lcd);
715 }
716 leaveForm.setCalendarEntry(calEntry);
717 if(calEntry != null) {
718 leaveForm.setCalEntryId(calEntry.getHrCalendarEntriesId());
719 }
720 leaveForm.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(calEntry));
721
722 }
723
724 private void setDocEditable(LeaveCalendarForm leaveForm, LeaveCalendarDocument lcd) {
725 leaveForm.setDocEditable(false);
726 if(lcd == null) {
727
728 if(TKUser.getCurrentTargetPersonId().equals(GlobalVariables.getUserSession().getPrincipalId())) {
729 leaveForm.setDocEditable(true);
730 } else {
731 if(TKUser.isSystemAdmin()
732 || TKUser.isLocationAdmin()
733 || TKUser.isReviewer()
734 || TKUser.isApprover()) {
735 leaveForm.setDocEditable(true);
736 }
737 }
738 } else {
739 if (TKUser.isSystemAdmin() && !StringUtils.equals(lcd.getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())) {
740 leaveForm.setDocEditable(true);
741 } else {
742 boolean docFinal = lcd.getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.FINAL);
743 if (!docFinal) {
744 if(StringUtils.equals(lcd.getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())
745 || TKUser.isSystemAdmin()
746 || TKUser.isLocationAdmin()
747 || TKUser.isReviewer()
748 || TKUser.isApprover()) {
749 leaveForm.setDocEditable(true);
750 }
751
752
753 if (StringUtils.equals(lcd.getPrincipalId(), GlobalVariables.getUserSession().getPrincipalId())
754 && lcd.getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.ENROUTE)) {
755 Collection actions = KEWServiceLocator.getActionTakenService().findByDocIdAndAction(lcd.getDocumentHeader().getDocumentId(), TkConstants.DOCUMENT_ACTIONS.APPROVE);
756 if(!actions.isEmpty()) {
757 leaveForm.setDocEditable(false);
758 }
759 }
760 }
761 }
762 }
763 }
764
765 public ActionForward gotoCurrentPayPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
766 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
767 String viewPrincipal = TKUser.getCurrentTargetPersonId();
768 Date currentDate = TKUtils.getTimelessDate(null);
769 CalendarEntries calendarEntry = TkServiceLocator.getCalendarService().getCurrentCalendarDatesForLeaveCalendar(viewPrincipal, currentDate);
770 lcf.setCalendarEntry(calendarEntry);
771 if(calendarEntry != null) {
772 lcf.setCalEntryId(calendarEntry.getHrCalendarEntriesId());
773 }
774 lcf.setOnCurrentPeriod(ActionFormUtils.getOnCurrentPeriodFlag(calendarEntry));
775
776 LeaveCalendarDocument lcd = null;
777
778 boolean createFlag = TkServiceLocator.getLeaveCalendarService().shouldCreateLeaveDocument(viewPrincipal, calendarEntry);
779 if(createFlag) {
780 lcd = TkServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(viewPrincipal, calendarEntry);
781 }
782 if (lcd != null) {
783 lcf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptions(lcd));
784 } else {
785 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(viewPrincipal, calendarEntry);
786 lcf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptionsForAssignments(assignments));
787 }
788 setupDocumentOnFormContext(lcf, lcd);
789 return mapping.findForward("basic");
790 }
791
792
793 public ActionForward changeCalendarYear(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
794
795 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
796 if(request.getParameter("selectedCY") != null) {
797 lcf.setSelectedCalendarYear(request.getParameter("selectedCY").toString());
798 }
799 return mapping.findForward("basic");
800 }
801
802
803 public ActionForward changePayPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
804 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
805 if(request.getParameter("selectedPP") != null) {
806 lcf.setSelectedPayPeriod(request.getParameter("selectedPP").toString());
807 CalendarEntries ce = TkServiceLocator.getCalendarEntriesService()
808 .getCalendarEntries(request.getParameter("selectedPP").toString());
809 if(ce != null) {
810 String viewPrincipal = TKUser.getCurrentTargetPersonId();
811 lcf.setCalEntryId(ce.getHrCalendarEntriesId());
812 LeaveCalendarDocument lcd = null;
813
814 boolean createFlag = TkServiceLocator.getLeaveCalendarService().shouldCreateLeaveDocument(viewPrincipal, ce);
815 if(createFlag) {
816 lcd = TkServiceLocator.getLeaveCalendarService().openLeaveCalendarDocument(viewPrincipal, ce);
817 }
818 if(lcd != null) {
819 lcf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptions(lcd));
820 } else {
821 List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignmentsByCalEntryForLeaveCalendar(viewPrincipal, ce);
822 lcf.setAssignmentDescriptions(TkServiceLocator.getAssignmentService().getAssignmentDescriptionsForAssignments(assignments));
823 }
824 setupDocumentOnFormContext(lcf, lcd);
825 }
826 }
827 return mapping.findForward("basic");
828 }
829
830 private void generateLeaveCalendarChangedNotification(String principalId, String targetPrincipalId, String documentId, String hrCalendarEntryId) {
831 if (!StringUtils.equals(principalId, targetPrincipalId)) {
832 EntityNamePrincipalName person = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(principalId);
833 if (person != null && person.getDefaultName() != null) {
834 String subject = "Leave Calendar Modification Notice";
835 StringBuilder message = new StringBuilder();
836 message.append("Your Leave Calendar was changed by ");
837 message.append(person.getDefaultName().getCompositeNameUnmasked());
838 message.append(" on your behalf.");
839 message.append(SystemUtils.LINE_SEPARATOR);
840 message.append(getLeaveCalendarURL(documentId, hrCalendarEntryId));
841
842 TkServiceLocator.getKPMENotificationService().sendNotification(subject, message.toString(), targetPrincipalId);
843 }
844 }
845 }
846
847 private void generateLeaveBlockDeletionNotification(List<String> approverIdList, String employeeId, String userId, String dateString, String hrString) {
848 EntityNamePrincipalName employee = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(employeeId);
849 EntityNamePrincipalName user = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(userId);
850 if (employee != null
851 && user != null
852 && employee.getDefaultName() != null
853 && user.getDefaultName() != null) {
854 String subject = "Leave Request Deletion Notice";
855 StringBuilder message = new StringBuilder();
856 message.append("An Approved leave request of ").append(hrString).append(" hours on Date ").append(dateString);
857 message.append(" for ").append(employee.getDefaultName().getCompositeNameUnmasked()).append(" was deleted by ");
858 message.append(user.getDefaultName().getCompositeNameUnmasked());
859 for(String anId : approverIdList) {
860 TkServiceLocator.getKPMENotificationService().sendNotification(subject, message.toString(), anId);
861 }
862 }
863 }
864
865 @SuppressWarnings("deprecation")
866 private String getLeaveCalendarURL(String documentId, String hrCalendarEntryId) {
867 Properties params = new Properties();
868 params.put("documentId", documentId);
869 params.put("calEntryId", hrCalendarEntryId);
870 return UrlFactory.parameterizeUrl(getApplicationBaseUrl() + "/LeaveCalendar.do", params);
871 }
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891 public ActionForward payoutOnDemandBalanceTransfer(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
892
893
894
895
896
897
898
899 return mapping.findForward("basic");
900 }
901
902
903
904
905
906
907
908
909
910
911 public ActionForward leavePayout(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
912
913 return mapping.findForward("basic");
914 }
915
916 public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
917 ActionForward forward = mapping.findForward("basic");
918 String command = request.getParameter("command");
919
920 if (StringUtils.equals(command, "displayDocSearchView") || StringUtils.equals(command, "displayActionListView")) {
921 String docId = (String) request.getParameter("docId");
922 LeaveCalendarDocument leaveCalendarDocument = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(docId);
923 String timesheetPrincipalName = KimApiServiceLocator.getPersonService().getPerson(leaveCalendarDocument.getPrincipalId()).getPrincipalName();
924
925 String principalId = TKUser.getCurrentTargetPersonId();
926 String principalName = KimApiServiceLocator.getPersonService().getPerson(principalId).getPrincipalName();
927
928 StringBuilder builder = new StringBuilder();
929 if (!StringUtils.equals(principalName, timesheetPrincipalName)) {
930 if (StringUtils.equals(command, "displayDocSearchView")) {
931 builder.append("changeTargetPerson.do?methodToCall=changeTargetPerson");
932 builder.append("&documentId=");
933 builder.append(docId);
934 builder.append("&principalName=");
935 builder.append(timesheetPrincipalName);
936 builder.append("&targetUrl=LeaveCalendar.do");
937 builder.append("?docmentId=" + docId);
938 builder.append("&returnUrl=LeaveApproval.do");
939 } else {
940 builder.append("LeaveApproval.do");
941 }
942 } else {
943 builder.append("LeaveCalendar.do");
944 builder.append("?docmentId=" + docId);
945 }
946
947 forward = new ActionRedirect(builder.toString());
948 }
949
950 return forward;
951 }
952
953 }