View Javadoc

1   /**
2    * Copyright 2004-2013 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.hr.lm.balancetransfer.service;
17  
18  import java.math.BigDecimal;
19  import java.util.ArrayList;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.commons.collections.CollectionUtils;
24  import org.apache.commons.lang3.StringUtils;
25  import org.kuali.hr.lm.LMConstants;
26  import org.kuali.hr.lm.accrual.AccrualCategory;
27  import org.kuali.hr.lm.balancetransfer.BalanceTransfer;
28  import org.kuali.hr.lm.leaveblock.LeaveBlock;
29  import org.kuali.hr.time.HrBusinessObject;
30  import org.kuali.hr.time.service.base.TkServiceLocator;
31  import org.kuali.hr.time.util.HrBusinessObjectMaintainableImpl;
32  import org.kuali.hr.time.util.TKContext;
33  import org.kuali.hr.time.util.TKUtils;
34  import org.kuali.rice.kew.api.document.DocumentStatus;
35  import org.kuali.rice.kew.api.exception.WorkflowException;
36  import org.kuali.rice.kns.document.MaintenanceDocument;
37  import org.kuali.rice.krad.bo.DocumentHeader;
38  import org.kuali.rice.krad.service.DocumentService;
39  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
40  import org.kuali.rice.krad.util.ObjectUtils;
41  
42  @SuppressWarnings("deprecation")
43  public class BalanceTransferMaintainableImpl extends
44  		HrBusinessObjectMaintainableImpl {
45  
46  	private static final long serialVersionUID = -789218061798169466L;
47  
48  	@Override
49  	public void saveBusinessObject() {
50  		// TODO Auto-generated method stub
51  		super.saveBusinessObject();
52  	}
53  	
54  	@Override
55  	public HrBusinessObject getObjectById(String id) {
56  		return TkServiceLocator.getBalanceTransferService().getBalanceTransferById(id);
57  	}
58  
59  
60  	@Override
61      public void doRouteStatusChange(DocumentHeader documentHeader) {
62          //ProcessDocReport pdr = new ProcessDocReport(true, "");
63          String documentId = documentHeader.getDocumentNumber();
64          BalanceTransfer balanceTransfer = (BalanceTransfer)this.getDataObject();
65          DocumentService documentService = KRADServiceLocatorWeb.getDocumentService();
66  
67          DocumentStatus newDocumentStatus = documentHeader.getWorkflowDocument().getStatus();
68          String routedByPrincipalId = documentHeader.getWorkflowDocument().getRoutedByPrincipalId();
69          if (DocumentStatus.ENROUTE.equals(newDocumentStatus)
70                  && CollectionUtils.isEmpty(balanceTransfer.getLeaveBlocks())) {
71          	// this is a balance transfer on a system scheduled time off leave block
72          	if(StringUtils.isNotEmpty(balanceTransfer.getSstoId())) {
73          		try {
74  	                MaintenanceDocument md = (MaintenanceDocument)KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentId);
75  	                balanceTransfer = TkServiceLocator.getBalanceTransferService().transferSsto(balanceTransfer);
76  	                md.getNewMaintainableObject().setDataObject(balanceTransfer);
77  	                documentService.saveDocument(md);
78  	            }
79  	            catch (WorkflowException e) {
80  	                LOG.error("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
81  	                throw new RuntimeException("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
82  	            }	
83          	} else {
84                  //when transfer document is routed, initiate the balance transfer - creating the leave blocks
85  	            try {
86  	                MaintenanceDocument md = (MaintenanceDocument)KRADServiceLocatorWeb.getDocumentService().getByDocumentHeaderId(documentId);
87  	
88  	                balanceTransfer = TkServiceLocator.getBalanceTransferService().transfer(balanceTransfer);
89  	                md.getNewMaintainableObject().setDataObject(balanceTransfer);
90  	                documentService.saveDocument(md);
91  	            }
92  	            catch (WorkflowException e) {
93  	                LOG.error("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
94  	                throw new RuntimeException("caught exception while handling doRouteStatusChange -> documentService.getByDocumentHeaderId(" + documentHeader.getDocumentNumber() + "). ", e);
95  	            }
96          	}
97          } else if (DocumentStatus.DISAPPROVED.equals(newDocumentStatus)) {
98          	/**
99          	 * 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             List<LeaveBlock> leaveBlocks = TkServiceLocator.getLeaveBlockService().getLeaveBlocksForDate(balanceTransfer.getPrincipalId(), balanceTransfer.getEffectiveDate());
126             LeaveBlock carryOverBlock = null;
127             for(LeaveBlock lb : leaveBlocks) {
128             	if(StringUtils.equals(lb.getAccrualCategory(),balanceTransfer.getFromAccrualCategory())
129             			&& StringUtils.equals(lb.getDescription(),"Max carry over adjustment")) {
130             		carryOverBlock = lb;
131             	}
132             }
133             if(carryOverBlock != null) {
134             	BigDecimal adjustment = new BigDecimal(0);
135             	if(balanceTransfer.getTransferAmount() != null)
136             		adjustment = adjustment.add(balanceTransfer.getTransferAmount().abs());
137             	if(balanceTransfer.getForfeitedAmount() != null)
138             		adjustment = adjustment.add(balanceTransfer.getForfeitedAmount().abs());
139             	BigDecimal adjustedLeaveAmount = carryOverBlock.getLeaveAmount().abs().subtract(adjustment);
140             	carryOverBlock.setLeaveAmount(adjustedLeaveAmount.negate());
141         		TkServiceLocator.getLeaveBlockService().updateLeaveBlock(carryOverBlock, routedByPrincipalId);
142             }
143         } else if (DocumentStatus.CANCELED.equals(newDocumentStatus)) {
144             //When transfer document is canceled, set all leave block's request statuses to deferred
145 
146             for(LeaveBlock lb : balanceTransfer.getLeaveBlocks()) {
147                 if(ObjectUtils.isNotNull(lb)) {
148                     lb.setRequestStatus(LMConstants.REQUEST_STATUS.DEFERRED);
149                     TkServiceLocator.getLeaveBlockService().updateLeaveBlock(lb, routedByPrincipalId);
150                 }
151             }
152         }
153     }
154 
155 	private List<LeaveBlock> buildSstoLeaveBlockList(BalanceTransfer bt) {
156 		String leaveDocId = CollectionUtils.isNotEmpty(bt.getLeaveBlocks())? bt.getLeaveBlocks().get(0).getDocumentId() : "";
157 		List<LeaveBlock> lbList = new ArrayList<LeaveBlock>();
158 		AccrualCategory fromAC = TkServiceLocator.getAccrualCategoryService().getAccrualCategory(bt.getFromAccrualCategory(), bt.getEffectiveDate());
159 		
160 		LeaveBlock accruedLeaveBlock = new LeaveBlock();
161 		accruedLeaveBlock.setAccrualCategory(bt.getFromAccrualCategory());
162 		accruedLeaveBlock.setLeaveDate(bt.getEffectiveDate());
163 		accruedLeaveBlock.setPrincipalId(bt.getPrincipalId());
164 		accruedLeaveBlock.setEarnCode(fromAC.getEarnCode());
165 		accruedLeaveBlock.setDateAndTime(TKUtils.getCurrentTimestamp());
166 		accruedLeaveBlock.setAccrualGenerated(true);
167 		accruedLeaveBlock.setBlockId(0L);
168 		accruedLeaveBlock.setScheduleTimeOffId(bt.getSstoId());
169 		accruedLeaveBlock.setLeaveAmount(bt.getTransferAmount());
170 		accruedLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE);
171 		accruedLeaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
172 		accruedLeaveBlock.setDocumentId(leaveDocId);
173 		accruedLeaveBlock.setPrincipalIdModified(TKContext.getPrincipalId());
174 		lbList.add(accruedLeaveBlock);
175 		
176 		LeaveBlock usageLeaveBlock = new LeaveBlock();
177 		usageLeaveBlock.setAccrualCategory(bt.getFromAccrualCategory());
178 		usageLeaveBlock.setLeaveDate(bt.getEffectiveDate());
179 		usageLeaveBlock.setPrincipalId(bt.getPrincipalId());
180 		usageLeaveBlock.setEarnCode(fromAC.getEarnCode());
181 		usageLeaveBlock.setDateAndTime(TKUtils.getCurrentTimestamp());
182 		usageLeaveBlock.setAccrualGenerated(true);
183 		usageLeaveBlock.setBlockId(0L);
184 		usageLeaveBlock.setScheduleTimeOffId(bt.getSstoId());
185 		usageLeaveBlock.setLeaveAmount(bt.getTransferAmount().negate());
186 		usageLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE);
187 		usageLeaveBlock.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
188 		usageLeaveBlock.setDocumentId(leaveDocId);
189 		usageLeaveBlock.setPrincipalIdModified(TKContext.getPrincipalId());
190 		lbList.add(usageLeaveBlock);
191 		
192 		return lbList;
193 	}
194 }