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