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.math.BigDecimal;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.joda.time.DateTime;
23  import org.joda.time.LocalDate;
24  import org.kuali.kpme.core.accrualcategory.AccrualCategory;
25  import org.kuali.kpme.core.accrualcategory.rule.AccrualCategoryRule;
26  import org.kuali.kpme.core.earncode.EarnCode;
27  import org.kuali.kpme.core.principal.PrincipalHRAttributes;
28  import org.kuali.kpme.core.service.HrServiceLocator;
29  import org.kuali.kpme.core.util.HrConstants;
30  import org.kuali.kpme.tklm.api.leave.accrual.bucket.YearToDateUsageLeaveBalanceContract;
31  import org.kuali.kpme.tklm.leave.accrual.bucket.exception.MaximumBalanceException;
32  import org.kuali.kpme.tklm.leave.accrual.bucket.exception.NegativeBalanceException;
33  import org.kuali.kpme.tklm.leave.accrual.bucket.exception.UsageLimitException;
34  import org.kuali.kpme.tklm.leave.block.LeaveBlock;
35  import org.kuali.kpme.tklm.leave.override.EmployeeOverride;
36  import org.kuali.rice.krad.util.ObjectUtils;
37  
38  public class YearToDateUsageLeaveBalance extends LeaveBalance implements YearToDateUsageLeaveBalanceContract {
39  
40  	private List<LeaveBlock> leaveBlocks;
41  
42  	public YearToDateUsageLeaveBalance(AccrualCategory accrualCategory, PrincipalHRAttributes principalCalendar) {
43  		super(accrualCategory, principalCalendar);
44  		asOfDate = LocalDate.now();
45  		leaveBlocks = new ArrayList<LeaveBlock>();
46  	}
47  
48  	private final static String BALANCE_TYPE = "YTD_USAGE_BALANCE";
49  	
50  	@Override
51  	public void add(LeaveBlock leaveBlock) throws UsageLimitException {
52  
53  		DateTime rolloverDate = HrServiceLocator.getLeavePlanService().getFirstDayOfLeavePlan(principalCalendar.getLeavePlan(), asOfDate);
54  		
55  		if(leaveBlock.getLeaveDate().compareTo(asOfDate.toDate()) <= 0 
56  				&& leaveBlock.getLeaveDate().compareTo(rolloverDate.toDate()) >= 0) {
57  		
58  			if(leaveBlock.getLeaveAmount().signum() < 0) {
59  				EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(leaveBlock.getEarnCode(), LocalDate.fromDateFields(leaveBlock.getLeaveDate()));
60  				if(earnCode != null) {
61  					if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.USAGE)){
62  			
63  						AccrualCategoryRule accrualRule = getAccrualCategoryRuleForDate(leaveBlock.getLeaveLocalDate());
64  						
65  						if(accrualRule != null
66  								&& ObjectUtils.isNotNull(accrualRule.getMaxUsage())) {
67  							
68  							BigDecimal maxUsage = new BigDecimal(accrualRule.getMaxUsage());
69  							BigDecimal fteSum = HrServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(leaveBlock.getPrincipalId(), leaveBlock.getLeaveLocalDate());
70  							maxUsage = maxUsage.multiply(fteSum).setScale(HrConstants.BIG_DECIMAL_SCALE, HrConstants.BIG_DECIMAL_SCALE_ROUNDING);
71  							
72  							EmployeeOverride employeeOverride = getEmployeeOverride(leaveBlock, "MU");
73  							if(employeeOverride != null)
74  								maxUsage = new BigDecimal(employeeOverride.getOverrideValue());
75  							
76  							if(maxUsage.compareTo(this.balance.add(leaveBlock.getLeaveAmount().negate())) <= 0) {
77  								add(leaveBlock.getLeaveAmount().negate());
78  								leaveBlocks.add(leaveBlock);
79  								//throw new UsageLimitException();
80  							}
81  							else {
82  								add(leaveBlock.getLeaveAmount().negate());
83  								leaveBlocks.add(leaveBlock);
84  							}
85  						}
86  						else {
87  							//no usage limit
88  							add(leaveBlock.getLeaveAmount().negate());
89  							leaveBlocks.add(leaveBlock);
90  						}
91  		
92  					}
93  					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.ADJUSTMENT)) {
94  						//does not validate against balances
95  						add(leaveBlock.getLeaveAmount().negate());
96  						leaveBlocks.add(leaveBlock);
97  					}
98  					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.NONE)) {
99  						//no balance validations, does not affect balances
100 						leaveBlocks.add(leaveBlock);
101 					}
102 				}
103 			}
104 		}
105 	}
106 
107 	@Override
108 	public void remove(LeaveBlock leaveBlock) throws NegativeBalanceException {
109 		
110 		DateTime rolloverDate = HrServiceLocator.getLeavePlanService().getFirstDayOfLeavePlan(principalCalendar.getLeavePlan(), asOfDate);
111 		
112 		if(leaveBlock.getLeaveDate().compareTo(asOfDate.toDate()) <= 0 
113 				&& leaveBlock.getLeaveDate().compareTo(rolloverDate.toDate()) >= 0) {
114 			
115 			if(leaveBlock.getLeaveAmount().signum() < 0) {
116 				EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(leaveBlock.getEarnCode(), LocalDate.fromDateFields(leaveBlock.getLeaveDate()));
117 				if(earnCode != null) {
118 					if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.USAGE)){
119 	
120 						AccrualCategoryRule accrualRule = getAccrualCategoryRuleForDate(leaveBlock.getLeaveLocalDate());
121 						
122 						if(accrualRule != null
123 								&& ObjectUtils.isNotNull(accrualRule.getMaxUsage())) {
124 							
125 							BigDecimal maxUsage = new BigDecimal(accrualRule.getMaxUsage());
126 							BigDecimal fteSum = HrServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(leaveBlock.getPrincipalId(), leaveBlock.getLeaveLocalDate());
127 							maxUsage = maxUsage.multiply(fteSum).setScale(HrConstants.BIG_DECIMAL_SCALE, HrConstants.BIG_DECIMAL_SCALE_ROUNDING);
128 							
129 							EmployeeOverride employeeOverride = getEmployeeOverride(leaveBlock, "MU");
130 							if(employeeOverride != null)
131 								maxUsage = new BigDecimal(employeeOverride.getOverrideValue());
132 							
133 							if(BigDecimal.ZERO.compareTo(this.balance.subtract(leaveBlock.getLeaveAmount().negate())) > 0) {
134 								remove(leaveBlock.getLeaveAmount().negate());
135 								leaveBlocks.remove(leaveBlock);
136 								//throw new NegativeBalanceException();
137 							}
138 							else {
139 								remove(leaveBlock.getLeaveAmount().negate());
140 								leaveBlocks.remove(leaveBlock);
141 							}
142 						}
143 						else {
144 							//no usage limit
145 							remove(leaveBlock.getLeaveAmount().negate());
146 							leaveBlocks.remove(leaveBlock);
147 						}
148 		
149 					}
150 					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.ADJUSTMENT)) {
151 						//does not validate against balances
152 						remove(leaveBlock.getLeaveAmount().negate());
153 						leaveBlocks.remove(leaveBlock);
154 					}
155 					else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.NONE)) {
156 						//no balance validations, does not affect balances
157 						leaveBlocks.remove(leaveBlock);
158 					}
159 				}
160 			}
161 		}
162 	}
163 
164 	@Override
165 	public String getBalanceType() {
166 		return BALANCE_TYPE;
167 	}
168 
169 	@Override
170 	public void adjust(LeaveBlock leaveBlock) throws UsageLimitException,
171 			MaximumBalanceException, NegativeBalanceException {
172 		// TODO Auto-generated method stub
173 		
174 	}
175 
176 	@Override
177 	public void clear() {
178 		leaveBlocks.clear();
179 		super.clear();
180 	}
181 
182 }