001/**
002 * Copyright 2004-2014 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 */
016package org.kuali.kpme.tklm.leave.payout.web;
017
018import org.apache.commons.collections.CollectionUtils;
019import org.apache.commons.lang.StringUtils;
020import org.kuali.kpme.core.bo.HrBusinessObject;
021import org.kuali.kpme.core.bo.HrBusinessObjectMaintainableImpl;
022import org.kuali.kpme.core.util.HrConstants;
023import org.kuali.kpme.core.util.TKUtils;
024import org.kuali.kpme.tklm.api.leave.block.LeaveBlock;
025import org.kuali.kpme.tklm.common.LMConstants;
026import org.kuali.kpme.tklm.leave.payout.LeavePayout;
027import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
028import org.kuali.rice.kew.api.document.DocumentStatus;
029import org.kuali.rice.kew.api.exception.WorkflowException;
030import org.kuali.rice.kns.document.MaintenanceDocument;
031import org.kuali.rice.krad.bo.DocumentHeader;
032import org.kuali.rice.krad.service.DocumentService;
033import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
034import org.kuali.rice.krad.util.ObjectUtils;
035
036import java.math.BigDecimal;
037import java.util.List;
038
039public class LeavePayoutMaintainableImpl extends
040        HrBusinessObjectMaintainableImpl {
041
042    private static final long serialVersionUID = 1L;
043
044    @Override
045    public HrBusinessObject getObjectById(String id) {
046        return LmServiceLocator.getLeavePayoutService().getLeavePayoutById(id);
047    }
048
049    @Override
050    public void doRouteStatusChange(DocumentHeader documentHeader) {
051        //ProcessDocReport pdr = new ProcessDocReport(true, "");
052        String documentId = documentHeader.getDocumentNumber();
053        LeavePayout payout = (LeavePayout)this.getDataObject();
054        DocumentService documentService = KRADServiceLocatorWeb.getDocumentService();
055        payout.setDocumentHeaderId(documentId);
056        DocumentStatus newDocumentStatus = documentHeader.getWorkflowDocument().getStatus();
057        String routedByPrincipalId = documentHeader.getWorkflowDocument().getRoutedByPrincipalId();
058        if (DocumentStatus.ENROUTE.equals(newDocumentStatus)
059                && CollectionUtils.isEmpty(payout.getLeaveBlocks())) {
060            //when payout document is routed, initiate the leave payout - creating the leave blocks
061            try {
062                MaintenanceDocument md = (MaintenanceDocument)KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentId);
063                payout = LmServiceLocator.getLeavePayoutService().payout(payout);
064                md.getDocumentHeader().setDocumentDescription(TKUtils.getDocumentDescription(payout.getPrincipalId(), payout.getEffectiveLocalDate()));
065                md.getNewMaintainableObject().setDataObject(payout);
066                documentService.saveDocument(md);
067            }
068            catch (WorkflowException e) {
069                LOG.error("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
070                throw new RuntimeException("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
071            }
072        } else if (DocumentStatus.DISAPPROVED.equals(newDocumentStatus)) {
073            //When payout document is disapproved, set all leave block's request statuses to disapproved.
074            for(LeaveBlock lb : payout.getLeaveBlocks()) {
075                if(ObjectUtils.isNotNull(lb)) {
076                    LeaveBlock.Builder builder = LeaveBlock.Builder.create(lb);
077                    builder.setRequestStatus(HrConstants.REQUEST_STATUS.DISAPPROVED);
078                    LmServiceLocator.getLeaveBlockService().deleteLeaveBlock(builder.getLmLeaveBlockId(), routedByPrincipalId);
079                }
080            }
081            //update status of document and associated leave blocks.
082        } else if (DocumentStatus.FINAL.equals(newDocumentStatus)) {
083            //When payout document moves to final, set all leave block's request statuses to approved.
084            for(LeaveBlock lb : payout.getLeaveBlocks()) {
085                if(ObjectUtils.isNotNull(lb)) {
086                    LeaveBlock.Builder builder = LeaveBlock.Builder.create(lb);
087                    builder.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
088                    LmServiceLocator.getLeaveBlockService().updateLeaveBlock(builder.build(), routedByPrincipalId);
089                }
090            }
091            
092            List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksForDocumentId(payout.getLeaveCalendarDocumentId());
093            for(LeaveBlock lb : leaveBlocks) {
094                if(StringUtils.equals(lb.getAccrualCategory(),payout.getFromAccrualCategory())
095                                && StringUtils.equals(lb.getLeaveBlockType(), LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER_ADJUSTMENT)) {
096                        BigDecimal adjustment = new BigDecimal(0);
097                        if(payout.getPayoutAmount() != null)
098                                adjustment = adjustment.add(payout.getPayoutAmount().abs());
099                        if(payout.getForfeitedAmount() != null)
100                                adjustment = adjustment.add(payout.getForfeitedAmount().abs());
101                        BigDecimal adjustedLeaveAmount = lb.getLeaveAmount().abs().subtract(adjustment);
102                    LeaveBlock.Builder builder = LeaveBlock.Builder.create(lb);
103                        builder.setLeaveAmount(adjustedLeaveAmount.negate());
104                        LmServiceLocator.getLeaveBlockService().updateLeaveBlock(builder.build(), routedByPrincipalId);
105                }
106            }
107        } else if (DocumentStatus.CANCELED.equals(newDocumentStatus)) {
108            //When payout document is canceled, set all leave block's request statuses to deferred
109            for(LeaveBlock lb : payout.getLeaveBlocks()) {
110                if(ObjectUtils.isNotNull(lb)) {
111                    LeaveBlock.Builder builder = LeaveBlock.Builder.create(lb);
112                    builder.setRequestStatus(HrConstants.REQUEST_STATUS.DEFERRED);
113                    LmServiceLocator.getLeaveBlockService().updateLeaveBlock(builder.build(), routedByPrincipalId);
114                }
115            }
116        }
117    }
118
119}