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 }