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.balancetransfer.service;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.apache.commons.collections.CollectionUtils;
023    import org.apache.commons.lang3.StringUtils;
024    import org.kuali.hr.lm.LMConstants;
025    import org.kuali.hr.lm.accrual.AccrualCategory;
026    import org.kuali.hr.lm.balancetransfer.BalanceTransfer;
027    import org.kuali.hr.lm.leaveblock.LeaveBlock;
028    import org.kuali.hr.time.HrBusinessObject;
029    import org.kuali.hr.time.service.base.TkServiceLocator;
030    import org.kuali.hr.time.util.HrBusinessObjectMaintainableImpl;
031    import org.kuali.hr.time.util.TKContext;
032    import org.kuali.hr.time.util.TKUtils;
033    import org.kuali.rice.kew.api.document.DocumentStatus;
034    import org.kuali.rice.kew.api.exception.WorkflowException;
035    import org.kuali.rice.kns.document.MaintenanceDocument;
036    import org.kuali.rice.krad.bo.DocumentHeader;
037    import org.kuali.rice.krad.service.DocumentService;
038    import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
039    import org.kuali.rice.krad.util.ObjectUtils;
040    
041    @SuppressWarnings("deprecation")
042    public class BalanceTransferMaintainableImpl extends
043                    HrBusinessObjectMaintainableImpl {
044    
045            private static final long serialVersionUID = -789218061798169466L;
046    
047            @Override
048            public void saveBusinessObject() {
049                    // TODO Auto-generated method stub
050                    super.saveBusinessObject();
051            }
052            
053            @Override
054            public HrBusinessObject getObjectById(String id) {
055                    return TkServiceLocator.getBalanceTransferService().getBalanceTransferById(id);
056            }
057    
058    
059            @Override
060        public void doRouteStatusChange(DocumentHeader documentHeader) {
061            //ProcessDocReport pdr = new ProcessDocReport(true, "");
062            String documentId = documentHeader.getDocumentNumber();
063            BalanceTransfer balanceTransfer = (BalanceTransfer)this.getDataObject();
064            DocumentService documentService = KRADServiceLocatorWeb.getDocumentService();
065    
066            DocumentStatus newDocumentStatus = documentHeader.getWorkflowDocument().getStatus();
067            String routedByPrincipalId = documentHeader.getWorkflowDocument().getRoutedByPrincipalId();
068    
069            if (DocumentStatus.ENROUTE.equals(newDocumentStatus)
070                    && CollectionUtils.isEmpty(balanceTransfer.getLeaveBlocks())) {
071                    // this is a balance transfer on a system scheduled time off leave block
072                    if(StringUtils.isNotEmpty(balanceTransfer.getSstoId())) {
073                            try {
074                            MaintenanceDocument md = (MaintenanceDocument)KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentId);
075                            balanceTransfer = TkServiceLocator.getBalanceTransferService().transferSsto(balanceTransfer);
076                            md.getNewMaintainableObject().setDataObject(balanceTransfer);
077                            documentService.saveDocument(md);
078                        }
079                        catch (WorkflowException e) {
080                            LOG.error("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
081                            throw new RuntimeException("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
082                        }   
083                    } else {
084                    //when transfer document is routed, initiate the balance transfer - creating the leave blocks
085                        try {
086                            MaintenanceDocument md = (MaintenanceDocument)KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentId);
087            
088                            balanceTransfer = TkServiceLocator.getBalanceTransferService().transfer(balanceTransfer);
089                            md.getNewMaintainableObject().setDataObject(balanceTransfer);
090                            documentService.saveDocument(md);
091                        }
092                        catch (WorkflowException e) {
093                            LOG.error("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
094                            throw new RuntimeException("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
095                        }
096                    }
097            } else if (DocumentStatus.DISAPPROVED.equals(newDocumentStatus)) {
098                    /**
099                     * TODO: Remove disapproval action
100                     */
101                    // this is a balance transfer on a system scheduled time off leave block
102    
103                if(StringUtils.isNotEmpty(balanceTransfer.getSstoId())) {
104                            // put two accrual service generated leave blocks back, one accrued, one usage
105                            List<LeaveBlock> lbList = buildSstoLeaveBlockList(balanceTransfer);                       
106                            TkServiceLocator.getLeaveBlockService().saveLeaveBlocks(lbList);
107                    }
108                //When transfer document is disapproved, set all leave block's request statuses to disapproved.
109                for(LeaveBlock lb : balanceTransfer.getLeaveBlocks()) {
110                    if(ObjectUtils.isNotNull(lb)) {
111                        lb.setRequestStatus(LMConstants.REQUEST_STATUS.DISAPPROVED);
112                        TkServiceLocator.getLeaveBlockService().deleteLeaveBlock(lb.getLmLeaveBlockId(), routedByPrincipalId);
113                    }
114                }
115                //update status of document and associated leave blocks.
116            } else if (DocumentStatus.FINAL.equals(newDocumentStatus)) {
117                //When transfer document moves to final, set all leave block's request statuses to approved.
118                for(LeaveBlock lb : balanceTransfer.getLeaveBlocks()) {
119                    if(ObjectUtils.isNotNull(lb)) {
120                            //TODO: What happens when an approver edits the fields in the transfer doc before approving?
121                        lb.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
122                        TkServiceLocator.getLeaveBlockService().updateLeaveBlock(lb, routedByPrincipalId);
123                    }
124                }
125            } else if (DocumentStatus.CANCELED.equals(newDocumentStatus)) {
126                //When transfer document is canceled, set all leave block's request statuses to deferred
127    
128                for(LeaveBlock lb : balanceTransfer.getLeaveBlocks()) {
129                    if(ObjectUtils.isNotNull(lb)) {
130                        lb.setRequestStatus(LMConstants.REQUEST_STATUS.DEFERRED);
131                        TkServiceLocator.getLeaveBlockService().updateLeaveBlock(lb, routedByPrincipalId);
132                    }
133                }
134            }
135        }
136    
137            private List<LeaveBlock> buildSstoLeaveBlockList(BalanceTransfer bt) {
138                    String leaveDocId = CollectionUtils.isNotEmpty(bt.getLeaveBlocks())? bt.getLeaveBlocks().get(0).getDocumentId() : "";
139                    List<LeaveBlock> lbList = new ArrayList<LeaveBlock>();
140                    AccrualCategory fromAC = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(bt.getFromAccrualCategory(), bt.getEffectiveDate());
141                    
142                    LeaveBlock accruedLeaveBlock = new LeaveBlock();
143                    accruedLeaveBlock.setAccrualCategory(bt.getFromAccrualCategory());
144                    accruedLeaveBlock.setLeaveDate(bt.getEffectiveDate());
145                    accruedLeaveBlock.setPrincipalId(bt.getPrincipalId());
146                    accruedLeaveBlock.setEarnCode(fromAC.getEarnCode());
147                    accruedLeaveBlock.setDateAndTime(TKUtils.getCurrentTimestamp());
148                    accruedLeaveBlock.setAccrualGenerated(true);
149                    accruedLeaveBlock.setBlockId(0L);
150                    accruedLeaveBlock.setScheduleTimeOffId(bt.getSstoId());
151                    accruedLeaveBlock.setLeaveAmount(bt.getTransferAmount());
152                    accruedLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE);
153                    accruedLeaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
154                    accruedLeaveBlock.setDocumentId(leaveDocId);
155                    accruedLeaveBlock.setPrincipalIdModified(TKContext.getPrincipalId());
156                    lbList.add(accruedLeaveBlock);
157                    
158                    LeaveBlock usageLeaveBlock = new LeaveBlock();
159                    usageLeaveBlock.setAccrualCategory(bt.getFromAccrualCategory());
160                    usageLeaveBlock.setLeaveDate(bt.getEffectiveDate());
161                    usageLeaveBlock.setPrincipalId(bt.getPrincipalId());
162                    usageLeaveBlock.setEarnCode(fromAC.getEarnCode());
163                    usageLeaveBlock.setDateAndTime(TKUtils.getCurrentTimestamp());
164                    usageLeaveBlock.setAccrualGenerated(true);
165                    usageLeaveBlock.setBlockId(0L);
166                    usageLeaveBlock.setScheduleTimeOffId(bt.getSstoId());
167                    usageLeaveBlock.setLeaveAmount(bt.getTransferAmount().negate());
168                    usageLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE);
169                    usageLeaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
170                    usageLeaveBlock.setDocumentId(leaveDocId);
171                    usageLeaveBlock.setPrincipalIdModified(TKContext.getPrincipalId());
172                    lbList.add(usageLeaveBlock);
173                    
174                    return lbList;
175            }
176    }