Java tutorial
/** * Copyright 2004-2013 The Kuali Foundation * * Licensed under the Educational Community License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.opensource.org/licenses/ecl2.php * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kuali.kpme.tklm.leave.calendar.service; import java.util.List; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.kuali.kpme.core.assignment.Assignment; import org.kuali.kpme.core.calendar.entry.CalendarEntry; import org.kuali.kpme.core.document.calendar.CalendarDocument; import org.kuali.kpme.core.job.Job; import org.kuali.kpme.core.service.HrServiceLocator; import org.kuali.kpme.core.util.HrConstants; import org.kuali.kpme.core.util.TKUtils; import org.kuali.kpme.tklm.common.LMConstants; import org.kuali.kpme.tklm.common.TkConstants; import org.kuali.kpme.tklm.leave.block.LeaveBlock; import org.kuali.kpme.tklm.leave.calendar.LeaveCalendarDocument; import org.kuali.kpme.tklm.leave.calendar.dao.LeaveCalendarDao; import org.kuali.kpme.tklm.leave.service.LmServiceLocator; import org.kuali.kpme.tklm.leave.workflow.LeaveCalendarDocumentHeader; import org.kuali.kpme.tklm.leave.workflow.LeaveRequestDocument; import org.kuali.kpme.tklm.time.service.TkServiceLocator; import org.kuali.rice.core.api.config.property.ConfigContext; import org.kuali.rice.kew.api.KewApiServiceLocator; import org.kuali.rice.kew.api.WorkflowDocument; import org.kuali.rice.kew.api.WorkflowDocumentFactory; import org.kuali.rice.kew.api.exception.WorkflowException; import org.kuali.rice.kew.api.note.Note; import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName; import org.kuali.rice.kim.api.identity.principal.Principal; import org.kuali.rice.kim.api.services.KimApiServiceLocator; import org.kuali.rice.krad.service.KRADServiceLocator; import org.kuali.rice.krad.util.GlobalVariables; public class LeaveCalendarServiceImpl implements LeaveCalendarService { private static final Logger LOG = Logger.getLogger(LeaveCalendarServiceImpl.class); private LeaveCalendarDao leaveCalendarDao; @Override public LeaveCalendarDocument getLeaveCalendarDocument(String documentId) { LeaveCalendarDocument lcd = null; LeaveCalendarDocumentHeader lcdh = LmServiceLocator.getLeaveCalendarDocumentHeaderService() .getDocumentHeader(documentId); if (lcdh != null) { lcd = new LeaveCalendarDocument(lcdh); CalendarEntry pce = HrServiceLocator.getCalendarEntryService().getCalendarDatesByPayEndDate( lcdh.getPrincipalId(), lcdh.getEndDateTime(), HrConstants.LEAVE_CALENDAR_TYPE); lcd.setCalendarEntry(pce); } else { LOG.error("Could not find LeaveCalendarDocumentHeader for DocumentID: " + documentId); return null; } List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService() .getLeaveBlocksForDocumentId(documentId); lcd.setLeaveBlocks(leaveBlocks); // Fetching assignments List<Assignment> assignments = HrServiceLocator.getAssignmentService() .getAssignmentsByCalEntryForLeaveCalendar(lcdh.getPrincipalId(), lcd.getCalendarEntry()); lcd.setAssignments(assignments); return lcd; } @Override public LeaveCalendarDocument openLeaveCalendarDocument(String principalId, CalendarEntry calEntry) throws WorkflowException { LeaveCalendarDocument doc; DateTime begin = calEntry.getBeginPeriodFullDateTime(); DateTime end = calEntry.getEndPeriodFullDateTime(); LeaveCalendarDocumentHeader header = LmServiceLocator.getLeaveCalendarDocumentHeaderService() .getDocumentHeader(principalId, begin, end); if (header == null) { EntityNamePrincipalName person = KimApiServiceLocator.getIdentityService() .getDefaultNamesForPrincipalId(principalId); String principalName = person != null && person.getDefaultName() != null ? person.getDefaultName().getCompositeName() : StringUtils.EMPTY; String beginDateString = TKUtils.formatDate(begin.toLocalDate()); String endDateString = TKUtils.formatDate(end.toLocalDate()); String leaveCalendarDocumentTitle = LeaveCalendarDocument.LEAVE_CALENDAR_DOCUMENT_TYPE + " - " + principalName + " (" + principalId + ") - " + beginDateString + "-" + endDateString; doc = initiateWorkflowDocument(principalId, begin, end, calEntry, LeaveCalendarDocument.LEAVE_CALENDAR_DOCUMENT_TYPE, leaveCalendarDocumentTitle); } else { doc = getLeaveCalendarDocument(header.getDocumentId()); } if (doc != null) { doc.setCalendarEntry(calEntry); } // TODO: need to set the summary return doc; } //Should only create leave calendar document if active jobs were found with flsa elig = no and ben elg = yes public boolean shouldCreateLeaveDocument(String principalId, CalendarEntry calEntry) { if (StringUtils.isEmpty(principalId) || calEntry == null) { return false; } boolean isPlanningCalendar = LmServiceLocator.getLeaveCalendarService().isLeavePlanningCalendar(principalId, calEntry.getBeginPeriodFullDateTime().toLocalDate(), calEntry.getEndPeriodFullDateTime().toLocalDate()); if (isPlanningCalendar) { return false; } List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAssignmentsByPayEntry(principalId, calEntry); List<Assignment> results = HrServiceLocator.getAssignmentService().filterAssignments(assignments, HrConstants.FLSA_STATUS_EXEMPT, true); return CollectionUtils.isNotEmpty(results); } protected LeaveCalendarDocument initiateWorkflowDocument(String principalId, DateTime payBeginDate, DateTime payEndDate, CalendarEntry calendarEntry, String documentType, String title) throws WorkflowException { LeaveCalendarDocument leaveCalendarDocument = null; WorkflowDocument workflowDocument = null; workflowDocument = WorkflowDocumentFactory.createDocument(principalId, documentType, title); String status = workflowDocument.getStatus().getCode(); LeaveCalendarDocumentHeader documentHeader = new LeaveCalendarDocumentHeader( workflowDocument.getDocumentId(), principalId, payBeginDate.toDate(), payEndDate.toDate(), status); documentHeader.setDocumentId(workflowDocument.getDocumentId()); documentHeader.setDocumentStatus(HrConstants.ROUTE_STATUS.INITIATED); KRADServiceLocator.getBusinessObjectService().save(documentHeader); leaveCalendarDocument = new LeaveCalendarDocument(documentHeader); leaveCalendarDocument.setCalendarEntry(calendarEntry); loadLeaveCalendarDocumentData(leaveCalendarDocument, principalId, calendarEntry); TkServiceLocator.getTkSearchableAttributeService().updateSearchableAttribute(leaveCalendarDocument, payEndDate.toLocalDate()); updateLeaveBlockDocumentIds(principalId, payBeginDate.toLocalDate(), payEndDate.toLocalDate(), workflowDocument.getDocumentId()); updatePlannedLeaveBlocks(principalId, payBeginDate.toLocalDate(), payEndDate.toLocalDate()); return leaveCalendarDocument; } private void updateLeaveBlockDocumentIds(String principalId, LocalDate beginDate, LocalDate endDate, String documentId) { List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, beginDate, endDate); for (LeaveBlock leaveBlock : leaveBlocks) { leaveBlock.setDocumentId(documentId); } LmServiceLocator.getLeaveBlockService().saveLeaveBlocks(leaveBlocks); } private void updatePlannedLeaveBlocks(String principalId, LocalDate beginDate, LocalDate endDate) { String batchUserPrincipalId = getBatchUserPrincipalId(); if (batchUserPrincipalId != null) { List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocks(principalId, beginDate, endDate); for (LeaveBlock leaveBlock : leaveBlocks) { if (StringUtils.equals(leaveBlock.getRequestStatus(), HrConstants.REQUEST_STATUS.PLANNED) || StringUtils.equals(leaveBlock.getRequestStatus(), HrConstants.REQUEST_STATUS.DEFERRED)) { LmServiceLocator.getLeaveBlockService().deleteLeaveBlock(leaveBlock.getLmLeaveBlockId(), batchUserPrincipalId); } else if (StringUtils.equals(leaveBlock.getRequestStatus(), HrConstants.REQUEST_STATUS.REQUESTED)) { if (StringUtils.equals(getInitiateLeaveRequestAction(), LMConstants.INITIATE_LEAVE_REQUEST_ACTION_OPTIONS.DELETE)) { LmServiceLocator.getLeaveBlockService().deleteLeaveBlock(leaveBlock.getLmLeaveBlockId(), batchUserPrincipalId); } else if (StringUtils.equals(getInitiateLeaveRequestAction(), LMConstants.INITIATE_LEAVE_REQUEST_ACTION_OPTIONS.APPROVE)) { List<LeaveRequestDocument> leaveRequestDocuments = LmServiceLocator .getLeaveRequestDocumentService() .getLeaveRequestDocumentsByLeaveBlockId(leaveBlock.getLmLeaveBlockId()); for (LeaveRequestDocument leaveRequestDocument : leaveRequestDocuments) { LmServiceLocator.getLeaveRequestDocumentService().suBlanketApproveLeave( leaveRequestDocument.getDocumentNumber(), batchUserPrincipalId); } } } } } else { String principalName = ConfigContext.getCurrentContextConfig() .getProperty(TkConstants.BATCH_USER_PRINCIPAL_NAME); LOG.error("Could not update leave request blocks due to missing batch user " + principalName); } } private String getBatchUserPrincipalId() { String principalName = ConfigContext.getCurrentContextConfig() .getProperty(TkConstants.BATCH_USER_PRINCIPAL_NAME); Principal principal = KimApiServiceLocator.getIdentityService().getPrincipalByPrincipalName(principalName); return principal == null ? null : principal.getPrincipalId(); } private String getInitiateLeaveRequestAction() { return ConfigContext.getCurrentContextConfig().getProperty(LMConstants.INITIATE_LEAVE_REQUEST_ACTION); } /** * Preload the document data. It preloads: * - LeaveBlocks on the document. * @param ldoc * @param principalId * @param calEntry */ protected void loadLeaveCalendarDocumentData(LeaveCalendarDocument ldoc, String principalId, CalendarEntry calEntry) { List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService() .getLeaveBlocksForDocumentId(ldoc.getDocumentId()); ldoc.setLeaveBlocks(leaveBlocks); List<Assignment> assignments = HrServiceLocator.getAssignmentService() .getAssignmentsByCalEntryForLeaveCalendar(principalId, calEntry); ldoc.setAssignments(assignments); } public LeaveCalendarDao getLeaveCalendarDao() { return leaveCalendarDao; } public void setLeaveCalendarDao(LeaveCalendarDao leaveCalendarDao) { this.leaveCalendarDao = leaveCalendarDao; } @Override public LeaveCalendarDocument getLeaveCalendarDocument(String principalId, CalendarEntry calendarEntry) { LeaveCalendarDocument leaveCalendarDocument = new LeaveCalendarDocument(calendarEntry); LeaveCalendarDocumentHeader lcdh = new LeaveCalendarDocumentHeader(); lcdh.setBeginDate(calendarEntry.getBeginPeriodDateTime()); lcdh.setEndDate(calendarEntry.getEndPeriodDateTime()); leaveCalendarDocument.setDocumentHeader(lcdh); // Fetching assignments List<Assignment> assignments = HrServiceLocator.getAssignmentService() .getAssignmentsByCalEntryForLeaveCalendar(principalId, calendarEntry); leaveCalendarDocument.setAssignments(assignments); return leaveCalendarDocument; } @Override public void routeLeaveCalendar(String principalId, LeaveCalendarDocument leaveCalendarDocument) { leaveCalendarDocumentAction(HrConstants.DOCUMENT_ACTIONS.ROUTE, principalId, leaveCalendarDocument); } @Override public void routeLeaveCalendar(String principalId, LeaveCalendarDocument leaveCalendarDocument, String action) { leaveCalendarDocumentAction(action, principalId, leaveCalendarDocument); } @Override public void approveLeaveCalendar(String principalId, LeaveCalendarDocument leaveCalendarDocument) { leaveCalendarDocumentAction(HrConstants.DOCUMENT_ACTIONS.APPROVE, principalId, leaveCalendarDocument); } @Override public void approveLeaveCalendar(String principalId, LeaveCalendarDocument leaveCalendarDocument, String action) { leaveCalendarDocumentAction(action, principalId, leaveCalendarDocument); } @Override public void disapproveLeaveCalendar(String principalId, LeaveCalendarDocument leaveCalendarDocument) { leaveCalendarDocumentAction(HrConstants.DOCUMENT_ACTIONS.DISAPPROVE, principalId, leaveCalendarDocument); } public boolean isReadyToApprove(CalendarDocument document) { if (document == null) { return false; } List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksWithType( document.getPrincipalId(), document.getCalendarEntry().getBeginPeriodFullDateTime().toLocalDate(), document.getCalendarEntry().getEndPeriodFullDateTime().toLocalDate(), LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER); leaveBlocks.addAll(LmServiceLocator.getLeaveBlockService().getLeaveBlocksWithType(document.getPrincipalId(), document.getCalendarEntry().getBeginPeriodFullDateTime().toLocalDate(), document.getCalendarEntry().getEndPeriodFullDateTime().toLocalDate(), LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT)); for (LeaveBlock lb : leaveBlocks) { if (!StringUtils.equals(lb.getRequestStatus(), HrConstants.REQUEST_STATUS.APPROVED) && !StringUtils.equals(lb.getRequestStatus(), HrConstants.REQUEST_STATUS.DISAPPROVED)) return false; } // check if there are any pending calendars are there LeaveCalendarDocumentHeader lcdh = LmServiceLocator.getLeaveCalendarDocumentHeaderService() .getMinBeginDatePendingLeaveCalendar(document.getPrincipalId()); if (lcdh != null) { //if there were any pending document //check to see if it's before the current document. if it is, then this document is not approvable. if (LmServiceLocator.getLeaveCalendarDocumentHeaderService().getDocumentHeader(document.getDocumentId()) .getBeginDate().compareTo(lcdh.getEndDate()) >= 0) { return false; } } return true; /* List<BalanceTransfer> balanceTransfers = LmServiceLocator.getBalanceTransferService().getBalanceTransfers(document.getPrincipalId(), document.getCalendarEntry().getBeginPeriodDate(), document.getCalendarEntry().getEndPeriodDate()); if (!CollectionUtils.isEmpty(balanceTransfers)) { for(BalanceTransfer balanceTransfer : balanceTransfers) { if(StringUtils.equals(HrConstants.DOCUMENT_STATUS.get(balanceTransfer.getStatus()), HrConstants.ROUTE_STATUS.ENROUTE)) return false; if (!StringUtils.equals(HrConstants.REQUEST_STATUS.APPROVED, balanceTransfer.getStatus()) && !StringUtils.equals(HrConstants.REQUEST_STATUS.DISAPPROVED, balanceTransfer.getStatus())) { return false; } } } List<LeavePayout> leavePayouts = LmServiceLocator.getLeavePayoutService().getLeavePayouts(document.getPrincipalId(), document.getCalendarEntry().getBeginPeriodDate(), document.getCalendarEntry().getEndPeriodDate()); if (!CollectionUtils.isEmpty(leavePayouts)) { for(LeavePayout payout : leavePayouts) { if(StringUtils.equals(HrConstants.DOCUMENT_STATUS.get(payout.getStatus()), HrConstants.ROUTE_STATUS.ENROUTE)) return false; if (!StringUtils.equals(HrConstants.REQUEST_STATUS.APPROVED, payout.getStatus()) && !StringUtils.equals(HrConstants.REQUEST_STATUS.DISAPPROVED, payout.getStatus())) { return false; } } } return true;*/ } protected void leaveCalendarDocumentAction(String action, String principalId, LeaveCalendarDocument leaveCalendarDocument) { WorkflowDocument wd = null; if (leaveCalendarDocument != null) { String rhid = leaveCalendarDocument.getDocumentId(); wd = WorkflowDocumentFactory.loadDocument(principalId, rhid); if (StringUtils.equals(action, HrConstants.DOCUMENT_ACTIONS.ROUTE)) { wd.route("Routing for Approval"); } else if (StringUtils.equals(action, HrConstants.BATCH_JOB_ACTIONS.BATCH_JOB_ROUTE)) { Note.Builder builder = Note.Builder.create(rhid, principalId); builder.setCreateDate(new DateTime()); builder.setText("Routed via Employee Approval batch job"); KewApiServiceLocator.getNoteService().createNote(builder.build()); wd.route("Batch job routing leave calendar"); } else if (StringUtils.equals(action, HrConstants.DOCUMENT_ACTIONS.APPROVE)) { if (HrServiceLocator.getHRPermissionService().canSuperUserAdministerCalendarDocument( GlobalVariables.getUserSession().getPrincipalId(), leaveCalendarDocument) && !HrServiceLocator.getHRPermissionService().canApproveCalendarDocument( GlobalVariables.getUserSession().getPrincipalId(), leaveCalendarDocument)) { wd.superUserBlanketApprove("Superuser approving timesheet."); } else { wd.approve("Approving timesheet."); } } else if (StringUtils.equals(action, HrConstants.BATCH_JOB_ACTIONS.BATCH_JOB_APPROVE)) { Note.Builder builder = Note.Builder.create(rhid, principalId); builder.setCreateDate(new DateTime()); builder.setText("Approved via Supervisor Approval batch job"); KewApiServiceLocator.getNoteService().createNote(builder.build()); wd.superUserBlanketApprove("Batch job approving leave calendar"); } else if (StringUtils.equals(action, HrConstants.DOCUMENT_ACTIONS.DISAPPROVE)) { if (HrServiceLocator.getHRPermissionService().canSuperUserAdministerCalendarDocument( GlobalVariables.getUserSession().getPrincipalId(), leaveCalendarDocument) && !HrServiceLocator.getHRPermissionService().canApproveCalendarDocument( GlobalVariables.getUserSession().getPrincipalId(), leaveCalendarDocument)) { wd.superUserDisapprove("Superuser disapproving leave calendar."); } else { wd.disapprove("Disapproving timesheet."); } } } } public boolean isLeavePlanningCalendar(String principalId, LocalDate beginDate, LocalDate endDate) { LocalDate today = LocalDate.now(); List<Job> jobs = HrServiceLocator.getJobService().getJobs(principalId, endDate); for (Job job : jobs) { // Check for Leave eligibility. if (job.isEligibleForLeave()) { // Check for Time (FLSA nonexempt) jobs. If one exists, then the Leave Calendar is always a Leave Planning Calendar if (job.getFlsaStatus().equalsIgnoreCase(HrConstants.FLSA_STATUS_NON_EXEMPT)) { return true; } else { // If leave eligible and FLSA exempt, then report leave in the Leave Calendar. Use the date to determine Planning vs Recording Calendars. if (beginDate.isAfter(today)) { // future period, this is a Planning Calendar. return true; } else { // not a future period, this is a Reporting Calendar. return false; } } } else { // not leave eligible return false; } } return false; } }