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.accrual.bucket;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.joda.time.DateTime;
22  import org.joda.time.LocalDate;
23  import org.kuali.kpme.core.accrualcategory.AccrualCategory;
24  import org.kuali.kpme.core.earncode.EarnCode;
25  import org.kuali.kpme.core.principal.PrincipalHRAttributes;
26  import org.kuali.kpme.core.service.HrServiceLocator;
27  import org.kuali.kpme.core.util.HrConstants;
28  import org.kuali.kpme.tklm.api.leave.accrual.bucket.AvailableLeaveBalanceContract;
29  import org.kuali.kpme.tklm.leave.accrual.bucket.exception.MaximumBalanceException;
30  import org.kuali.kpme.tklm.leave.accrual.bucket.exception.NegativeBalanceException;
31  import org.kuali.kpme.tklm.leave.accrual.bucket.exception.UsageLimitException;
32  import org.kuali.kpme.tklm.leave.block.LeaveBlock;
33  
34  public class AvailableLeaveBalance extends LeaveBalance implements AvailableLeaveBalanceContract {
35  
36  	private List<LeaveBlock> leaveBlocks;
37  	//Future/Planned Usage
38  	private PendingLeaveBalance pendingBalance;
39  	private YearToDateUsageLeaveBalance ytdUsage;
40  
41  	public AvailableLeaveBalance(AccrualCategory accrualCategory, PrincipalHRAttributes principalCalendar) {
42  		super(accrualCategory, principalCalendar);
43  		asOfDate = LocalDate.now();
44  		pendingBalance = new PendingLeaveBalance(accrualCategory,principalCalendar);
45  		ytdUsage = new YearToDateUsageLeaveBalance(accrualCategory,principalCalendar);
46  		leaveBlocks = new ArrayList<LeaveBlock>();
47  	}
48  
49  	private final static String BALANCE_TYPE = "AVAILABLE_BALANCE";
50  	
51  	@Override
52  	public void add(LeaveBlock leaveBlock) throws NegativeBalanceException {
53  		
54  		DateTime rolloverDate = HrServiceLocator.getLeavePlanService().getFirstDayOfLeavePlan(principalCalendar.getLeavePlan(), asOfDate);
55  		
56  		if((leaveBlock.getLeaveDate().compareTo(asOfDate.toDate()) <= 0)/*with any signum*/
57  				|| leaveBlock.getLeaveAmount().signum() < 0 ) {
58  			try {
59  				//AVAILABLE BALANCE = USAGE LIMIT - YTDUSAGE - PENDING/FUTURE USAGE
60  				ytdUsage.add(leaveBlock);
61  				
62  				EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(leaveBlock.getEarnCode(), LocalDate.fromDateFields(leaveBlock.getLeaveDate()));
63  				if(earnCode != null) {
64  					if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.USAGE)){
65  						//available balance is derived from ytdUsage, usage limit ( if any ), and pendingBalance[usage]
66  						add(leaveBlock.getLeaveAmount());
67  						leaveBlocks.add(leaveBlock);
68  					}
69  					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.ADJUSTMENT)) {
70  						//does not validate against balances
71  						add(leaveBlock.getLeaveAmount());
72  						leaveBlocks.add(leaveBlock);
73  					}
74  					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.NONE)) {
75  						//no balance validations, does not affect balances
76  						leaveBlocks.add(leaveBlock);
77  					}
78  					
79  					try {
80  						//pendingBalance should never throw BalanceExceptions, so logic below should always execute.
81  						//If ytdUsage throws UsageLimitException (above), no calculations should be made on this balance.
82  						pendingBalance.add(leaveBlock);
83  						
84  	/*					AccrualCategoryRule accrualRule = getAccrualCategoryRuleForDate(leaveBlock.getLeaveLocalDate());
85  						
86  						if(accrualRule != null
87  								&& ObjectUtils.isNotNull(accrualRule.getMaxUsage())) {
88  							
89  							BigDecimal maxUsage = new BigDecimal(accrualRule.getMaxUsage());
90  							BigDecimal fteSum = HrServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(leaveBlock.getPrincipalId(), leaveBlock.getLeaveLocalDate());
91  							maxUsage = maxUsage.multiply(fteSum).setScale(HrConstants.BIG_DECIMAL_SCALE, HrConstants.BIG_DECIMAL_SCALE_ROUNDING);
92  							
93  							EmployeeOverride employeeOverride = getEmployeeOverride(leaveBlock, "MU");
94  							if(employeeOverride != null
95  									&& ObjectUtils.isNotNull(employeeOverride.getOverrideValue()))
96  								maxUsage = new BigDecimal(employeeOverride.getOverrideValue());
97  							
98  							if(maxUsage == null) {
99  								this.balance = new BigDecimal(Long.MAX_VALUE);
100 								//no usage limit, available balance should be accrued balance!
101 							}
102 							else
103 								this.balance = maxUsage.subtract(ytdUsage.balance.add(pendingBalance.balance));
104 						}
105 						else
106 							this.balance = new BigDecimal(Long.MAX_VALUE);*/
107 					} catch (MaximumBalanceException e) {
108 						e.printStackTrace();
109 					} catch (NegativeBalanceException e) {
110 						e.printStackTrace();
111 					}
112 				}
113 			} catch (UsageLimitException e) {
114 				e.printStackTrace();
115 			}
116 		}
117 	}
118 
119 	@Override
120 	public void remove(LeaveBlock leaveBlock) {
121 		
122 		if((leaveBlock.getLeaveDate().compareTo(asOfDate.toDate()) <= 0)/*any leave amount signum*/
123 				|| leaveBlock.getLeaveAmount().signum() < 0 ) {
124 			try {
125 				//AVAILABLE BALANCE = USAGE LIMIT - YTDUSAGE - PENDING/FUTURE USAGE
126 				ytdUsage.remove(leaveBlock);
127 				
128 				EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(leaveBlock.getEarnCode(), LocalDate.fromDateFields(leaveBlock.getLeaveDate()));
129 				if(earnCode != null) {
130 					if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.USAGE)){
131 						//available balance is derived from ytdUsage, usage limit ( if any ), and pendingBalance[usage]
132 						remove(leaveBlock.getLeaveAmount());
133 						leaveBlocks.remove(leaveBlock);
134 					}
135 					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.ADJUSTMENT)) {
136 						//does not validate against balances
137 						remove(leaveBlock.getLeaveAmount());
138 						leaveBlocks.remove(leaveBlock);
139 					}
140 					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.NONE)) {
141 						//no balance validations, does not affect balances
142 						leaveBlocks.remove(leaveBlock);
143 					}
144 					
145 					try {
146 						//pendingBalance should never throw BalanceExceptions, so logic below should always execute.
147 						//If ytdUsage throws UsageLimitException (above), no calculations should be made on this balance.
148 						pendingBalance.remove(leaveBlock);
149 						
150 	/*					AccrualCategoryRule accrualRule = getAccrualCategoryRuleForDate(leaveBlock.getLeaveLocalDate());
151 						
152 						if(accrualRule != null
153 								&& ObjectUtils.isNotNull(accrualRule.getMaxUsage())) {
154 							
155 							BigDecimal maxUsage = new BigDecimal(accrualRule.getMaxUsage());
156 							BigDecimal fteSum = HrServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(leaveBlock.getPrincipalId(), leaveBlock.getLeaveLocalDate());
157 							maxUsage = maxUsage.multiply(fteSum).setScale(HrConstants.BIG_DECIMAL_SCALE, HrConstants.BIG_DECIMAL_SCALE_ROUNDING);
158 							
159 							EmployeeOverride employeeOverride = getEmployeeOverride(leaveBlock, "MU");
160 							if(employeeOverride != null
161 									&& ObjectUtils.isNotNull(employeeOverride.getOverrideValue()))
162 								maxUsage = new BigDecimal(employeeOverride.getOverrideValue());
163 							
164 							if(maxUsage == null) {
165 								this.balance = new BigDecimal(Long.MAX_VALUE);
166 								//no usage limit, available balance should be accrued balance!
167 							}
168 							else
169 								this.balance = maxUsage.subtract(ytdUsage.balance.add(pendingBalance.balance));
170 						}
171 						else
172 							this.balance = new BigDecimal(Long.MAX_VALUE);*/
173 					} catch (MaximumBalanceException e) {
174 						e.printStackTrace();
175 					} catch (NegativeBalanceException e) {
176 						e.printStackTrace();
177 					}
178 				}
179 			} catch (UsageLimitException e) {
180 				e.printStackTrace();
181 			} catch (NegativeBalanceException e1) {
182 				e1.printStackTrace();
183 			}
184 		}
185 	}
186 
187 	@Override
188 	public String getBalanceType() {
189 		return BALANCE_TYPE;
190 	}
191 
192 	@Override
193 	public void adjust(LeaveBlock leaveBlock) throws UsageLimitException,
194 			MaximumBalanceException, NegativeBalanceException {
195 		// TODO Auto-generated method stub
196 		
197 	}
198 
199 	@Override
200 	public void clear() {
201 		// TODO Auto-generated method stub
202 		pendingBalance.clear();
203 		ytdUsage.clear();
204 		leaveBlocks.clear();
205 		super.clear();
206 	}
207 
208 }