View Javadoc
1   /**
2    * Copyright 2004-2014 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.kpme.tklm.leave.transfer;
17  
18  import java.math.BigDecimal;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.kuali.kpme.core.accrualcategory.AccrualCategoryBo;
23  import org.kuali.kpme.core.api.accrualcategory.AccrualCategory;
24  import org.kuali.kpme.core.api.accrualcategory.rule.AccrualCategoryRuleContract;
25  import org.kuali.kpme.core.api.assignment.Assignable;
26  import org.kuali.kpme.core.api.assignment.Assignment;
27  import org.kuali.kpme.core.assignment.AssignmentBo;
28  import org.kuali.kpme.core.assignment.AssignmentBo;
29  import org.kuali.kpme.core.bo.HrBusinessObject;
30  import org.kuali.kpme.core.service.HrServiceLocator;
31  import org.kuali.kpme.core.util.HrConstants;
32  import org.kuali.kpme.tklm.api.leave.block.LeaveBlock;
33  import org.kuali.kpme.tklm.api.leave.transfer.BalanceTransferContract;
34  import org.kuali.kpme.tklm.leave.block.LeaveBlockBo;
35  import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
36  import org.kuali.rice.kim.api.identity.Person;
37  import org.kuali.rice.krad.util.ObjectUtils;
38  
39  import com.google.common.collect.ImmutableMap;
40  
41  public class BalanceTransfer extends HrBusinessObject implements Assignable, BalanceTransferContract {
42  
43  	private static final long serialVersionUID = 6948695780968441016L;
44  	
45  	private String balanceTransferId;
46  	private String documentHeaderId;
47  	private String accrualCategoryRule;
48  	private String principalId;
49  	private String toAccrualCategory;
50  	private String fromAccrualCategory;
51  	private BigDecimal transferAmount;
52  	private BigDecimal amountTransferred;
53  	private BigDecimal forfeitedAmount;
54  	private String leaveCalendarDocumentId;
55  
56  	private String status;
57  	private String forfeitedLeaveBlockId;
58  	private String accruedLeaveBlockId;
59  	private String debitedLeaveBlockId;
60  	private String sstoId;
61  	
62  	private transient Person principal;
63  	
64  	// TODO returning an empty map for the time-being, until the BK is finalized
65  	@Override
66  	public ImmutableMap<String, Object> getBusinessKeyValuesMap() {
67  		return new ImmutableMap.Builder<String, Object>()
68  				.build();
69  	}
70  	
71  	public String getPrincipalId() {
72  		return principalId;
73  	}
74  
75  	public void setPrincipalId(String principalId) {
76  		this.principalId = principalId;
77  	}
78  
79  	public String getToAccrualCategory() {
80  		return toAccrualCategory;
81  	}
82  
83  	public void setToAccrualCategory(String toAccrualCategory) {
84  		this.toAccrualCategory = toAccrualCategory;
85  	}
86  
87  	public String getFromAccrualCategory() {
88  		return fromAccrualCategory;
89  	}
90  
91  	public void setFromAccrualCategory(String fromAccrualCategory) {
92  		this.fromAccrualCategory = fromAccrualCategory;
93  	}
94  
95  	public BigDecimal getTransferAmount() {
96  		return transferAmount;
97  	}
98  
99  	public void setTransferAmount(BigDecimal transferAmount) {
100 		this.transferAmount = transferAmount;
101 	}
102 
103 	public BigDecimal getForfeitedAmount() {
104 		return forfeitedAmount;
105 	}
106 
107 	public void setForfeitedAmount(BigDecimal forfeitedAmount) {
108 		this.forfeitedAmount = forfeitedAmount;
109 	}
110 	
111 	public String getBalanceTransferId() {
112 		return balanceTransferId;
113 	}
114 
115 	public void setBalanceTransferId(String balanceTransferId) {
116 		this.balanceTransferId = balanceTransferId;
117 	}
118 	
119 	public String getAccrualCategoryRule() {
120 		return accrualCategoryRule;
121 	}
122 
123 	public void setAccrualCategoryRule(String accrualCategoryRule) {
124 		this.accrualCategoryRule = accrualCategoryRule;
125 	}
126 
127 	@Override
128 	protected String getUniqueKey() {
129 		return balanceTransferId;
130 	}
131 
132 	@Override
133 	public String getId() {
134 		return getBalanceTransferId();
135 	}
136 
137 	@Override
138 	public void setId(String id) {
139 		setBalanceTransferId(id);
140 	}
141 
142 	public Person getPrincipal() {
143 		return principal;
144 	}
145 
146 	public void setPrincipal(Person principal) {
147 		this.principal = principal;
148 	}
149 
150 	public AccrualCategoryBo getCreditedAccrualCategory() {
151 		return AccrualCategoryBo.from(HrServiceLocator.getAccrualCategoryService().getAccrualCategory(toAccrualCategory, getEffectiveLocalDate()));
152 	}
153 
154 	public AccrualCategoryBo getDebitedAccrualCategory() {
155 		return AccrualCategoryBo.from(HrServiceLocator.getAccrualCategoryService().getAccrualCategory(fromAccrualCategory, getEffectiveLocalDate()));
156 	}
157 
158 	public String getLeaveCalendarDocumentId() {
159 		return leaveCalendarDocumentId;
160 	}
161 
162 	public void setLeaveCalendarDocumentId(String leaveCalendarDocumentId) {
163 		this.leaveCalendarDocumentId = leaveCalendarDocumentId;
164 	}
165 
166 	/**
167 	 * Returns a balance transfer object adjusted for the new transfer amount.
168 	 * 
169 	 * "this" must be a default initialized balance transfer. i.e. transfer amount plus forfeited amount
170 	 * equal to the amount of leave in excess of the from accrual category's max balance for the given principal.
171 	 * 
172 	 * calling this method without first validating the supplied transfer amount via BalanceTransferValidationUtils may produce undesired results.
173 	 *
174 	 * @param transferAmount The desired transfer amount
175 	 * @return A balance transfer object with forfeited and amount transfer amounts adjusted to transferAmount
176 	 */
177 	public BalanceTransfer adjust(BigDecimal transferAmount) {
178 		BigDecimal difference = this.transferAmount.subtract(transferAmount);
179 		AccrualCategoryRuleContract aRule = HrServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(accrualCategoryRule);
180 		//technically if there is forfeiture, then the transfer amount has already been maximized
181 		//via BalanceTransferService::initializeTransfer(...)
182 		//i.o.w. transfer amount cannot be increased.
183 		//this method is written with the intention of eventually allowing end user to adjust the transfer
184 		//amount as many times as they wish before submitting. Currently they cannot.
185 		if(difference.signum() < 0) {
186 			//transfer amount is being increased.
187 			if(forfeitedAmount.compareTo(BigDecimal.ZERO) > 0) {
188 				//transfer amount has already been maximized.
189 				if(forfeitedAmount.compareTo(difference.abs()) >= 0)
190 					// there is enough leave in the forfeited amount to take out the difference.
191 					forfeitedAmount = forfeitedAmount.subtract(difference.abs());
192 				else
193 					// the difference zero's the forfeited amount.
194 					forfeitedAmount = BigDecimal.ZERO;
195 			}
196 			// a forfeited amount equal to zero with an increase in the transfer amount
197 			// does not produce forfeiture.
198 			// forfeiture cannot be negative.
199 		}
200 		else if (difference.signum() > 0) {
201 			//transfer amount is being decreased
202 			forfeitedAmount = forfeitedAmount.add(difference);
203 		}
204 
205 		this.transferAmount = transferAmount;
206 
207 		if(ObjectUtils.isNotNull(aRule.getMaxBalanceTransferConversionFactor()))
208 			this.amountTransferred = transferAmount.multiply(aRule.getMaxBalanceTransferConversionFactor()).setScale(2);
209 		else
210 			this.amountTransferred = transferAmount;
211 		
212 		return this;
213 	}
214 
215 	public List<LeaveBlock> getLeaveBlocks() {
216 		List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>();
217 		if (getForfeitedLeaveBlockId() != null) {
218 		    leaveBlocks.add(LmServiceLocator.getLeaveBlockService().getLeaveBlock(forfeitedLeaveBlockId));
219         }
220         if (getAccruedLeaveBlockId() != null) {
221 		    leaveBlocks.add(LmServiceLocator.getLeaveBlockService().getLeaveBlock(accruedLeaveBlockId));
222         }
223         if (getDebitedLeaveBlockId() != null) {
224 		    leaveBlocks.add(LmServiceLocator.getLeaveBlockService().getLeaveBlock(debitedLeaveBlockId));
225         }
226 
227 		return leaveBlocks;
228 	}
229 
230 	public String getStatus() {
231 		return status;
232 	}
233 
234 	public void setStatus(String status) {
235 		this.status = status;
236 	}
237 
238 	public void disapprove() {
239 		LmServiceLocator.getLeaveBlockService().updateLeaveBlock(null, principalId);
240 		setStatus(HrConstants.ROUTE_STATUS.DISAPPROVED);
241 	}
242 
243 	public void approve() {
244 
245 		setStatus(HrConstants.ROUTE_STATUS.FINAL);
246 	}
247 
248 	public void cancel() {
249 
250 		setStatus(HrConstants.ROUTE_STATUS.CANCEL);
251 	}
252 
253 	public String getAccruedLeaveBlockId() {
254 		return accruedLeaveBlockId;
255 	}
256 
257 	public void setAccruedLeaveBlockId(String accruedLeaveBlockId) {
258 		this.accruedLeaveBlockId = accruedLeaveBlockId;
259 	}
260 
261 	public String getForfeitedLeaveBlockId() {
262 		return forfeitedLeaveBlockId;
263 	}
264 
265 	public void setForfeitedLeaveBlockId(String forfeitedLeaveBlockId) {
266 		this.forfeitedLeaveBlockId = forfeitedLeaveBlockId;
267 	}
268 
269 	public String getDebitedLeaveBlockId() {
270 		return debitedLeaveBlockId;
271 	}
272 
273 	public void setDebitedLeaveBlockId(String debitedLeaveBlockId) {
274 		this.debitedLeaveBlockId = debitedLeaveBlockId;
275 	}
276 
277 	public BigDecimal getAmountTransferred() {
278 		return amountTransferred;
279 	}
280 
281 	public void setAmountTransferred(BigDecimal amountTransferrerd) {
282 		this.amountTransferred = amountTransferrerd;
283 	}
284 	
285 	public String getSstoId() {
286 		return sstoId;
287 	}
288 
289 	public void setSstoId(String sstoId) {
290 		this.sstoId = sstoId;
291 	}
292 
293 	public String getDocumentHeaderId() {
294 		return documentHeaderId;
295 	}
296 
297 	public void setDocumentHeaderId(String documentHeaderId) {
298 		this.documentHeaderId = documentHeaderId;
299 	}
300 
301     @Override
302     public List<Assignment> getAssignments() {
303         return HrServiceLocator.getAssignmentService().getAssignments(getPrincipalId(), getEffectiveLocalDate());
304     }
305 
306     //Comparable for order handling of more than one transfer occurring during the same
307 	//action frequency interval?
308 
309 }