001 /**
002 * Copyright 2004-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.hr.lm.leavecalendar.web;
017
018 import org.apache.commons.collections.CollectionUtils;
019 import org.apache.commons.lang.StringUtils;
020 import org.apache.commons.lang.SystemUtils;
021 import org.apache.commons.lang.time.DateUtils;
022 import org.apache.log4j.Logger;
023 import org.apache.struts.action.ActionForm;
024 import org.apache.struts.action.ActionForward;
025 import org.apache.struts.action.ActionMapping;
026 import org.apache.struts.action.ActionRedirect;
027 import org.joda.time.DateTime;
028 import org.joda.time.Interval;
029 import org.joda.time.LocalDateTime;
030 import org.joda.time.format.DateTimeFormat;
031 import org.joda.time.format.DateTimeFormatter;
032 import org.kuali.hr.lm.LMConstants;
033 import org.kuali.hr.lm.accrual.AccrualCategory;
034 import org.kuali.hr.lm.accrual.AccrualCategoryRule;
035 import org.kuali.hr.lm.balancetransfer.BalanceTransfer;
036 import org.kuali.hr.lm.balancetransfer.validation.BalanceTransferValidationUtils;
037 import org.kuali.hr.lm.leaveSummary.LeaveSummary;
038 import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
039 import org.kuali.hr.lm.leaveblock.LeaveBlock;
040 import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
041 import org.kuali.hr.lm.leavecalendar.validation.LeaveCalendarValidationUtil;
042 import org.kuali.hr.lm.util.LeaveBlockAggregate;
043 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
044 import org.kuali.hr.lm.workflow.LeaveRequestDocument;
045 import org.kuali.hr.time.assignment.Assignment;
046 import org.kuali.hr.time.base.web.TkAction;
047 import org.kuali.hr.time.calendar.Calendar;
048 import org.kuali.hr.time.calendar.CalendarEntries;
049 import org.kuali.hr.time.calendar.LeaveCalendar;
050 import org.kuali.hr.time.detail.web.ActionFormUtils;
051 import org.kuali.hr.time.earncode.EarnCode;
052 import org.kuali.hr.time.principal.PrincipalHRAttributes;
053 import org.kuali.hr.time.roles.TkUserRoles;
054 import org.kuali.hr.time.roles.UserRoles;
055 import org.kuali.hr.time.service.base.TkServiceLocator;
056 import org.kuali.hr.time.util.TKContext;
057 import org.kuali.hr.time.util.TKUser;
058 import org.kuali.hr.time.util.TKUtils;
059 import org.kuali.hr.time.util.TkConstants;
060 import org.kuali.rice.core.api.config.property.ConfigContext;
061 import org.kuali.rice.kew.api.KewApiServiceLocator;
062 import org.kuali.rice.kew.api.document.DocumentStatus;
063 import org.kuali.rice.kew.service.KEWServiceLocator;
064 import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
065 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
066 import org.kuali.rice.krad.exception.AuthorizationException;
067 import org.kuali.rice.krad.util.GlobalVariables;
068 import org.kuali.rice.krad.util.ObjectUtils;
069 import org.kuali.rice.krad.util.UrlFactory;
070
071 import javax.servlet.http.HttpServletRequest;
072 import javax.servlet.http.HttpServletResponse;
073 import java.math.BigDecimal;
074 import java.sql.Date;
075 import java.sql.Timestamp;
076 import java.text.DateFormat;
077 import java.text.SimpleDateFormat;
078 import java.util.*;
079 import java.util.Map.Entry;
080
081 public class LeaveCalendarAction extends TkAction {
082
083 private static final Logger LOG = Logger.getLogger(LeaveCalendarAction.class);
084
085 @Override
086 protected void checkTKAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
087 UserRoles roles = TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId());
088 LeaveCalendarDocument doc = TKContext.getCurrentLeaveCalendarDocument();
089
090 if (doc != null && !roles.isDocumentReadable(doc)) {
091 throw new AuthorizationException(GlobalVariables.getUserSession().getPrincipalId(), "LeaveCalendarAction: docid: " + (doc == null ? "" : doc.getDocumentId()), "");
092 }
093 }
094
095 @Override
096 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
097 LeaveCalendarForm lcf = (LeaveCalendarForm) form;
098 String documentId = lcf.getDocumentId();
099
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 // if the reload was trigger by changing of the selectedPayPeriod, use the passed in parameter as the calendar entry id
108 String calendarEntryId = StringUtils.isNotBlank(request.getParameter("selectedPP")) ? request.getParameter("selectedPP") : lcf.getCalEntryId();
109
110 // Here - viewPrincipal will be the principal of the user we intend to
111 // view, be it target user, backdoor or otherwise.
112 String viewPrincipal = TKUser.getCurrentTargetPersonId();
113 CalendarEntries calendarEntry = null;
114
115 LeaveCalendarDocument lcd = null;
116 LeaveCalendarDocumentHeader lcdh = null;
117
118 // By handling the prev/next in the execute method, we are saving one
119 // fetch/construction of a LeaveCalendarDocument. If it were broken out into
120 // methods, we would first fetch the current document, and then fetch
121 // the next one instead of doing it in the single action.
122 if (StringUtils.isNotBlank(documentId)) {
123 lcd = TkServiceLocator.getLeaveCalendarService()
124 .getLeaveCalendarDocument(documentId);
125 calendarEntry = lcd.getCalendarEntry();
126 } else if (StringUtils.isNotBlank(calendarEntryId)) {
127 // do further procedure
128 calendarEntry = TkServiceLocator.getCalendarEntriesService()
129 .getCalendarEntries(calendarEntryId);
130 } else {
131 // Default to whatever is active for "today".
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 // check configuration setting for allowing accrual service to be ran from leave calendar
141 String runAccrualFlag = ConfigContext.getCurrentContextConfig().getProperty(LMConstants.RUN_ACCRUAL_FROM_CALENDAR);
142 if(StringUtils.equals(runAccrualFlag, "true")) {
143 // run accrual for future dates only, use planning month of leave plan for accrual period
144 // only run the accrual if the calendar entry contains future dates
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 // use jobs to find out if this leave calendar should have a document created or not
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 //no window exists if mapping->forward = closeBalanceTransferDoc.
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 // KPME-1447
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 // leave summary
200 if (calendarEntry != null) {
201 //check to see if we are on a previous leave plan
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 //current or future year
209 LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(viewPrincipal, calendarEntry);
210 lcf.setLeaveSummary(ls);
211 } else {
212 //current year roll over date has been passed, all previous calendars belong to the previous leave plan calendar year.
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 //override title element (based on date passed in)
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 // add warning messages based on earn codes of leave blocks
233 Map<String, Set<String>> allMessages = LeaveCalendarValidationUtil.getWarningMessagesForLeaveBlocks(leaveBlocks);
234
235 // add warning message for accrual categories that have exceeded max balance.
236
237 // Could set a flag on the transferable rows here so that LeaveCalendarSubmit.do knows
238 // which row(s) to transfer when user submits the calendar for approval.
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 //may want to calculate summary for all rows, displayable or not, and determine displayability via tags.
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 // accrual categories within the leave plan that are hidden from the leave summary will not appear.
284 List<LeaveSummaryRow> summaryRows = summary.getLeaveSummaryRows();
285 List<LeaveSummaryRow> updatedSummaryRows = new ArrayList<LeaveSummaryRow>(summaryRows.size());
286 //AccrualCategoryRule currentRule = TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRuleForDate(accrualCat, effectiveDate, principalCalendar.getServiceDate());
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 // accrual categories within the leave plan that are hidden from the leave summary WILL appear.
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 // leave blocks are sorted in getMaxBalanceViolations() method, so we just take the one with the earliest leave date for an accrual category.
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 // add warning messages based on max carry over balances for each accrual category
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 // KPME-1690
357 // LeaveCalendar leaveCalender = new LeaveCalendar(viewPrincipal, calendarEntry);
358 if (calendarEntry != null) {
359 LeaveBlockAggregate aggregate = new LeaveBlockAggregate(leaveBlocks, calendarEntry, calendar);
360 lcf.setLeaveBlockString(LeaveActionFormUtils.getLeaveBlocksJson(aggregate.getFlattenedLeaveBlockList()));
361 }
362 //lcf.setLeaveBlockString(ActionFormUtils.getLeaveBlocksJson(aggregate.getFlattenedLeaveBlockList()));
363
364 // System.out.println("Leave block string : "+lcf.getLeaveBlockString());
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 // find all the calendar entries up to the planning months of this employee
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 // get calendar year drop down list contents
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); // newest on top
384 lcf.setCalendarYears(yearList);
385 }
386 // if selected calendar year is passed in
387 if(request.getParameter("selectedCY")!= null) {
388 lcf.setSelectedCalendarYear(request.getParameter("selectedCY").toString());
389 }
390 // if there is no selected calendr year, use the year of current pay calendar entry
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 /** -- Jignasha : if earchcode type is 'T' then change the date and time with timezone.
423 // Surgery point - Need to construct a Date/Time with Appropriate Timezone.
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 /** Old Code
438 DateTime beginDate = new DateTime(TKUtils.convertDateStringToTimestampNoTimezone(lcf.getStartDate()));
439 DateTime endDate = new DateTime(TKUtils.convertDateStringToTimestampNoTimezone(lcf.getEndDate()));
440 */
441
442 String selectedEarnCode = lcf.getSelectedEarnCode();
443 BigDecimal hours = lcf.getLeaveAmount();
444 String desc = lcf.getDescription();
445 String spanningWeeks = lcf.getSpanningWeeks(); // KPME-1446
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 // after adding the leave block, set the fields of this form to null for future new leave blocks
463 lcf.setLeaveAmount(null);
464 lcf.setDescription(null);
465
466 // call accrual service if earn code is not eligible for accrual
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 // recalculate summary
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 //if leave block is a pending leave request, cancel the leave request document
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 // cancel the leave request document as the employee.
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 //if leave block is an approved leave request, get list of approver's id
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 // get approver's id for sending out email notification later
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 // recalculate accruals
530 if(lcf.getCalendarEntry() != null) {
531 rerunAccrualForNotEligibleForAccrualChanges(blockToDelete.getEarnCode(), blockToDelete.getLeaveDate(), calendarEntry.getBeginPeriodDate(), calendarEntry.getEndPeriodDate());
532 }
533 }
534 // recalculate summary
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 * Recalculate accrual when a leave block with not-eligible-for-accrual earn code is added or deleted
544 * calculate accrual only for the calendar entry period
545 * @param earnCode
546 * @param asOfDate
547 * @param startDate
548 * @param endDate
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 // since we are only recalculating accrual for this pay period, we use "false" to not record the accrual run data
555 TkServiceLocator.getLeaveAccrualService().runAccrual(TKContext.getTargetPrincipalId(), startDate, endDate, false);
556 }
557 }
558 }
559
560 // KPME-1447
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()); // selectedEarnCode = hrEarnCodeId
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 // recalculate summary
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 // some leave calendar may not have leaveCalendarDocument created based on the jobs status of this employee
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 // -- put condition if it is after current period
639 boolean isFutureDate = calEntry != null && TKUtils.getTimelessDate(null).compareTo(calEntry.getEndPeriodDateTime()) <= 0;
640
641 // fetch previous entry
642 if (calEntry != null) {
643 CalendarEntries calPreEntry = TkServiceLocator
644 .getCalendarEntriesService()
645 .getPreviousCalendarEntriesByCalendarId(
646 calEntry.getHrCalendarId(),
647 calEntry);
648 if (calPreEntry != null) {
649
650 // Check if service date of user is after the Calendar entry
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 // retrieve current pay calendar date
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 // working on own calendar
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 //if the leave Calendar has been approved by at least one of the approvers, the employee should not be able to edit it
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 // use jobs to find out if this leave calendar should have a document created or not
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 //Triggered by changes of pay period drop down list, reload the whole page based on the selected pay period
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 //Triggered by changes of pay period drop down list, reload the whole page based on the selected pay period
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 // use jobs to find out if this leave calendar should have a document created or not
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 * Handles the PAYOUT action of balance transfers issued from the leave calendar with frequency "on demand".
875 *
876 * This action should be triggered after the user submits to a prompt generated by clicking a "PAYOUT" button on the leave
877 * calendar. This button should only be displayed if, for the current pay period, a max balance has been reached
878 * and the max balance action frequency is set to "On-Demand". The prompt must allow the user to edit the transfer amount.
879 * It may or may not need to show the "to" and "from" accrual categories in the initial prompt, but could on a confirmation
880 * prompt - along with the transfer amount adjusted by the max balance conversion factor.
881 *
882 * Balance transfers with frequency of leave approval should be handled during the submission of the
883 * leave calendar document for approval and should be automated.
884 *
885 * @param mapping
886 * @param form
887 * @param request
888 * @param response
889 * @return
890 */
891 public ActionForward payoutOnDemandBalanceTransfer(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
892 /**
893 * TODO: create one new leave block, if applicable; the amount forfeited by this transfer action.
894 *
895 * The amount transfered, pending adjustment via the max balance conversion factor, will be put into a pay out earn code
896 * that can be redeemed/used by the employee at a later time.
897 */
898
899 return mapping.findForward("basic");
900 }
901
902 /**
903 * Leave Payout
904 *
905 * @param mapping
906 * @param form
907 * @param request
908 * @param response
909 * @return
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 }