001 /**
002 * Copyright 2004-2013 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.kpme.tklm.leave.accrual.bucket;
017
018 import java.math.BigDecimal;
019 import java.util.ArrayList;
020 import java.util.List;
021
022 import org.joda.time.DateTime;
023 import org.joda.time.LocalDate;
024 import org.kuali.kpme.core.accrualcategory.AccrualCategory;
025 import org.kuali.kpme.core.accrualcategory.rule.AccrualCategoryRule;
026 import org.kuali.kpme.core.earncode.EarnCode;
027 import org.kuali.kpme.core.principal.PrincipalHRAttributes;
028 import org.kuali.kpme.core.service.HrServiceLocator;
029 import org.kuali.kpme.core.util.HrConstants;
030 import org.kuali.kpme.tklm.api.leave.accrual.bucket.YearToDateUsageLeaveBalanceContract;
031 import org.kuali.kpme.tklm.leave.accrual.bucket.exception.MaximumBalanceException;
032 import org.kuali.kpme.tklm.leave.accrual.bucket.exception.NegativeBalanceException;
033 import org.kuali.kpme.tklm.leave.accrual.bucket.exception.UsageLimitException;
034 import org.kuali.kpme.tklm.leave.block.LeaveBlock;
035 import org.kuali.kpme.tklm.leave.override.EmployeeOverride;
036 import org.kuali.rice.krad.util.ObjectUtils;
037
038 public class YearToDateUsageLeaveBalance extends LeaveBalance implements YearToDateUsageLeaveBalanceContract {
039
040 private List<LeaveBlock> leaveBlocks;
041
042 public YearToDateUsageLeaveBalance(AccrualCategory accrualCategory, PrincipalHRAttributes principalCalendar) {
043 super(accrualCategory, principalCalendar);
044 asOfDate = LocalDate.now();
045 leaveBlocks = new ArrayList<LeaveBlock>();
046 }
047
048 private final static String BALANCE_TYPE = "YTD_USAGE_BALANCE";
049
050 @Override
051 public void add(LeaveBlock leaveBlock) throws UsageLimitException {
052
053 DateTime rolloverDate = HrServiceLocator.getLeavePlanService().getFirstDayOfLeavePlan(principalCalendar.getLeavePlan(), asOfDate);
054
055 if(leaveBlock.getLeaveDate().compareTo(asOfDate.toDate()) <= 0
056 && leaveBlock.getLeaveDate().compareTo(rolloverDate.toDate()) >= 0) {
057
058 if(leaveBlock.getLeaveAmount().signum() < 0) {
059 EarnCode earnCode = HrServiceLocator.getEarnCodeService().getEarnCode(leaveBlock.getEarnCode(), LocalDate.fromDateFields(leaveBlock.getLeaveDate()));
060 if(earnCode != null) {
061 if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.USAGE)){
062
063 AccrualCategoryRule accrualRule = getAccrualCategoryRuleForDate(leaveBlock.getLeaveLocalDate());
064
065 if(accrualRule != null
066 && ObjectUtils.isNotNull(accrualRule.getMaxUsage())) {
067
068 BigDecimal maxUsage = new BigDecimal(accrualRule.getMaxUsage());
069 BigDecimal fteSum = HrServiceLocator.getJobService().getFteSumForAllActiveLeaveEligibleJobs(leaveBlock.getPrincipalId(), leaveBlock.getLeaveLocalDate());
070 maxUsage = maxUsage.multiply(fteSum).setScale(HrConstants.BIG_DECIMAL_SCALE, HrConstants.BIG_DECIMAL_SCALE_ROUNDING);
071
072 EmployeeOverride employeeOverride = getEmployeeOverride(leaveBlock, "MU");
073 if(employeeOverride != null)
074 maxUsage = new BigDecimal(employeeOverride.getOverrideValue());
075
076 if(maxUsage.compareTo(this.balance.add(leaveBlock.getLeaveAmount().negate())) <= 0) {
077 add(leaveBlock.getLeaveAmount().negate());
078 leaveBlocks.add(leaveBlock);
079 //throw new UsageLimitException();
080 }
081 else {
082 add(leaveBlock.getLeaveAmount().negate());
083 leaveBlocks.add(leaveBlock);
084 }
085 }
086 else {
087 //no usage limit
088 add(leaveBlock.getLeaveAmount().negate());
089 leaveBlocks.add(leaveBlock);
090 }
091
092 }
093 else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.ADJUSTMENT)) {
094 //does not validate against balances
095 add(leaveBlock.getLeaveAmount().negate());
096 leaveBlocks.add(leaveBlock);
097 }
098 else if(earnCode.getAccrualBalanceAction().equals(HrConstants.ACCRUAL_BALANCE_ACTION.NONE)) {
099 //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 }