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;
17  
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertNotNull;
20  import static org.junit.Assert.assertTrue;
21  
22  import java.math.BigDecimal;
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import org.joda.time.Interval;
29  import org.joda.time.LocalDate;
30  import org.junit.After;
31  import org.junit.Before;
32  import org.junit.Test;
33  import org.kuali.kpme.core.IntegrationTest;
34  import org.kuali.kpme.core.accrualcategory.rule.AccrualCategoryRule;
35  import org.kuali.kpme.core.calendar.entry.CalendarEntry;
36  import org.kuali.kpme.core.service.HrServiceLocator;
37  import org.kuali.kpme.core.util.HrConstants;
38  import org.kuali.kpme.core.util.TKUtils;
39  import org.kuali.kpme.tklm.TKLMIntegrationTestCase;
40  import org.kuali.kpme.tklm.common.LMConstants;
41  import org.kuali.kpme.tklm.leave.block.LeaveBlock;
42  import org.kuali.kpme.tklm.leave.calendar.LeaveCalendarDocument;
43  import org.kuali.kpme.tklm.leave.override.EmployeeOverride;
44  import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
45  import org.kuali.kpme.tklm.leave.summary.LeaveSummary;
46  import org.kuali.kpme.tklm.leave.summary.LeaveSummaryRow;
47  import org.kuali.kpme.tklm.time.service.TkServiceLocator;
48  import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
49  import org.kuali.rice.krad.util.ObjectUtils;
50  
51  @IntegrationTest
52  public class AccrualCategoryMaxBalanceServiceTest extends TKLMIntegrationTestCase {
53  
54  
55  	/**
56  	 * Leave Calendar Document Test data
57  	 */
58  	private final String USER_ID = "testUser1";
59  	
60  	private LeaveCalendarDocument janLCD;
61  	private CalendarEntry janEntry;
62  	private LeaveCalendarDocument decLCD;
63  	private CalendarEntry decEntry;
64  	
65  	private final String JAN_ID = "5001";
66  	private final String DEC_ID = "5000";
67  	
68  	/**
69  	 * Timesheet Document Test Data;
70  	 */
71  	
72  	private final String TS_USER_ID = "testUser2";	
73  	
74  	private TimesheetDocument endJanTSD;
75  	private CalendarEntry endJanTSDEntry;
76  	private TimesheetDocument midJanTSD;
77  	private CalendarEntry midJanTSDEntry;
78  	private TimesheetDocument endDecTSD;
79  	private CalendarEntry endDecTSDEntry;
80  	private TimesheetDocument midDecTSD;
81  	private CalendarEntry midDecTSDEntry;
82  	
83  	private final String TSD_MID_DEC_PERIOD_ID = "5000";
84  	private final String TSD_END_DEC_PERIOD_ID = "5001";
85  	private final String TSD_MID_JAN_PERIOD_ID = "5002";
86  	private final String TSD_END_JAN_PERIOD_ID = "5003";
87  
88  	/**
89  	 *  Common data
90  	 */
91  	
92  	private final String OD_XFER = "5000";
93  	private final String YE_XFER = "5001";
94  	private final String LA_XFER = "5002";
95  	private final String OD_XFER_MAC = "5003";
96  	private final String YE_XFER_MAC = "5004";
97  	private final String LA_XFER_MAC = "5005";
98  	private final String OD_LOSE = "5006";
99  	private final String YE_LOSE = "5007";
100 	private final String LA_LOSE = "5008";
101 	private final String OD_LOSE_MAC = "5009";
102 	private final String YE_LOSE_MAC = "5010";
103 	private final String LA_LOSE_MAC = "5011";
104 	private final String YE_XFER_EO = "5012";
105 	private final LocalDate LM_FROM = TKUtils.formatDateString("11/01/2012");
106 	private final LocalDate LM_TO = TKUtils.formatDateString("02/01/2013");
107 	private final LocalDate TK_FROM = TKUtils.formatDateString("11/01/2011");
108 	private final LocalDate TK_TO = TKUtils.formatDateString("02/01/2012");
109 	
110 	@Before
111 	public void setUp() throws Exception {
112 		super.setUp();
113 		LmServiceLocator.getAccrualService().runAccrual(USER_ID,LM_FROM.toDateTimeAtStartOfDay(),LM_TO.toDateTimeAtStartOfDay(),true,USER_ID);
114 		janLCD = LmServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(JAN_ID);
115 		janEntry = janLCD.getCalendarEntry();
116 		decLCD = LmServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(DEC_ID);
117 		decEntry = decLCD.getCalendarEntry();
118 	}
119 	
120 	@After
121 	public void tearDown() throws Exception {
122 		super.tearDown();
123 	}
124 	
125 	@Test
126 	public void testGetMaxBalanceViolationsLeaveApprove() throws Exception {
127 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(janEntry, USER_ID);
128 		List<LeaveBlock> eligibleTransfers = new ArrayList<LeaveBlock>();
129 		Interval interval = new Interval(janEntry.getBeginPeriodDate().getTime(),janEntry.getEndPeriodDate().getTime());
130 		
131 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE)) {
132 			if(interval.contains(violation.getLeaveDate().getTime()))
133 				eligibleTransfers.add(violation);
134 		}
135 		// 6 accrual categories over max balance * 3 leave blocks ( 2 created on leave period end date + 1 created on calendar
136 		// year end date )
137 		assertEquals(6, eligibleTransfers.size());
138 		//assertEquals(8, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
139 		//assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
140 	}
141 
142 	@Test
143 	public void testGetMaxBalanceViolationsYearEnd() throws Exception {
144 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(janEntry, USER_ID);
145 		//assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
146 		assertEquals(8, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
147 		//assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
148 		List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
149 		for(LeaveBlock eligibleTransfer : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
150 			rules.add(eligibleTransfer.getAccrualCategoryRule());
151 		
152 		// Set should contain an accrual category whose rule's max balance is trumped by an employee override.
153 		// Comparing accrued balance to a rule's defined max balance is insufficient for testing
154 		// whether or not an accrual category is indeed over it's balance limit. Same can be said for FTE-proration.
155 		LeaveSummary summary = LmServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
156 		for(AccrualCategoryRule aRule : rules) {
157 			LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
158 			BigDecimal maxBalance = aRule.getMaxBalance();
159 			EmployeeOverride mbOverride = LmServiceLocator.getEmployeeOverrideService().getEmployeeOverride(USER_ID,
160 					"testLP",
161 					row.getAccrualCategory(),
162 					"MB",
163 					janEntry.getBeginPeriodFullDateTime().toLocalDate());
164 			if(ObjectUtils.isNotNull(mbOverride))
165 				maxBalance = new BigDecimal(mbOverride.getOverrideValue());
166 			assertNotNull("eligible accrual category has no balance limit",maxBalance);
167 			assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(maxBalance) > 0);
168 		}
169 	}
170 	
171 	@Test
172 	public void testGetMaxBalanceViolationsOnDemand() throws Exception {
173 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(janEntry, USER_ID);
174 		
175 		assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
176 
177 		List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
178 		for(LeaveBlock eligibleTransfer : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
179 			rules.add(eligibleTransfer.getAccrualCategoryRule());
180 
181 		LeaveSummary summary = LmServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
182 		for(AccrualCategoryRule aRule : rules) {
183 			LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
184 			assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
185 			assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
186 		}
187 	}
188 	
189 	@Test
190 	public void testGetMaxBalanceViolationsOnYearEndCaseOne() throws Exception {
191 		//calendar entry is not the last calendar entry of the leave plan's calendar year.
192 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(decEntry, USER_ID);
193 		//assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
194 		assertEquals(8, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
195 		//assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
196 		
197 		LeaveBlock usage = new LeaveBlock();
198 		
199 		usage.setAccrualCategory("ye-xfer");
200 		usage.setAccrualGenerated(true);
201 		usage.setLeaveAmount(new BigDecimal(-34));
202 		usage.setLeaveLocalDate(TKUtils.formatDateString("12/28/2012"));
203 		usage.setDocumentId(DEC_ID);
204 		usage.setPrincipalId(USER_ID);
205 		usage.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
206 		usage.setEarnCode("EC2");
207 		usage.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
208 		usage.setBlockId(0L);
209 		
210 		/*KRADServiceLocator.getBusinessObjectService().save(usage);*/
211 		LmServiceLocator.getLeaveBlockService().saveLeaveBlock(usage, TS_USER_ID);
212 		
213 		maxBalanceViolations = eligibilityTestHelper(decEntry, USER_ID);
214 
215 		//The above leave block should reduce balance of ye-xfer under max limit, reducing the number of violations by 1.
216 		assertEquals(7, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
217 		
218 		// adding an accrual block beyond the underlying leave calendar end date, but still within the
219 		// bounds of the time period, should not re-mark this accrual category over max balance.
220 /*		usage = new LeaveBlock();
221 		
222 		usage.setAccrualCategory("la-xfer");
223 		usage.setAccrualGenerated(false);
224 		usage.setLeaveAmount(new BigDecimal(10));
225 		usage.setLeaveDate(TKUtils.formatDateString("01/01/2012"));
226 		usage.setDocumentId(TSD_END_DEC_PERIOD_ID);
227 		usage.setPrincipalId(TS_USER_ID);
228 		usage.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
229 		usage.setEarnCode("EC1");
230 		usage.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
231 		usage.setBlockId(0L);
232 		
233 		KRADServiceLocator.getBusinessObjectService().save(usage);
234 		
235 		assertEquals(5, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());*/
236 		
237 	}
238 	
239 	@Test
240 	public void testGetMaxBalanceViolationsOnYearEndCaseTwo() throws Exception {
241 		//calendar entry is the last calendar entry of the leave plan's calendar year.
242 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(janEntry, USER_ID);
243 		//assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
244 		assertEquals(8, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
245 		//assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
246 	}
247 	
248 	/**
249 	 * 
250 	 * TIMESHEET ELIGIBLE TESTS
251 	 * 
252 	 */
253 	
254 	@Test
255 	public void testGetMaxBalanceViolationsLeaveApproveForTimesheetCaseOne() throws Exception {
256 		//Timesheet contains leave period ending 12/11/2011
257 		//accruals occur on 12/01/2011
258 		LmServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM.toDateTimeAtStartOfDay(),TK_TO.toDateTimeAtStartOfDay(),true,TS_USER_ID);
259 		midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
260 		midDecTSDEntry = midDecTSD.getCalendarEntry();
261 
262 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(midDecTSDEntry, TS_USER_ID);
263 		
264 		assertEquals(12, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
265 		//Assert correct number of transfer eligible for frequency
266 		List<LeaveBlock> eligibleLeaveApproveActions = new ArrayList<LeaveBlock>();
267 		Interval interval = new Interval(midDecTSDEntry.getBeginPeriodDate().getTime(),midDecTSDEntry.getEndPeriodDate().getTime());
268 		List<CalendarEntry> entries = HrServiceLocator.getCalendarEntryService().getCalendarEntriesEndingBetweenBeginAndEndDate("3", interval.getStart(), interval.getEnd());
269 		assertEquals("There should be one leave entry ending within this timesheet", 1, entries.size());
270 		Interval leaveInterval = new Interval(midDecTSDEntry.getBeginPeriodDate().getTime(),entries.get(0).getEndPeriodDate().getTime());
271 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE)) {
272 			if(leaveInterval.contains(violation.getLeaveDate().getTime())) {
273 				eligibleLeaveApproveActions.add(violation);
274 			}
275 		}
276 		assertEquals(6, eligibleLeaveApproveActions.size());
277 	}
278 	
279 	@Test
280 	public void testGetMaxBalanceViolationsYearEndForTimesheetCaseOne() throws Exception {
281 		//Timesheet contains leave period ending 12/11/2011
282 		//this is not the last leave period of the leave plan's calendar year.
283 		LmServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM.toDateTimeAtStartOfDay(),TK_TO.toDateTimeAtStartOfDay(),true,TS_USER_ID);
284 		midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
285 		midDecTSDEntry = midDecTSD.getCalendarEntry();
286 
287 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(midDecTSDEntry, TS_USER_ID);
288 		//Assert correct number of transfer eligible for frequency
289 		assertEquals(8, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
290 		List<LeaveBlock> eligibleYearEndActions = new ArrayList<LeaveBlock>();
291 		Interval interval = new Interval(midDecTSDEntry.getBeginPeriodDate().getTime(),midDecTSDEntry.getEndPeriodDate().getTime());
292 		List<CalendarEntry> entries = HrServiceLocator.getCalendarEntryService().getCalendarEntriesEndingBetweenBeginAndEndDate("3", interval.getStart(), interval.getEnd());
293 		assertEquals("There should be one leave entry ending within this timesheet", 1, entries.size());
294 		Interval leaveInterval = new Interval(midDecTSDEntry.getBeginPeriodDate().getTime(),entries.get(0).getEndPeriodDate().getTime());
295 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
296 			if(leaveInterval.contains(violation.getLeaveDate().getTime())
297 				&& HrServiceLocator.getLeavePlanService().isLastCalendarPeriodOfLeavePlan(entries.get(0), "testLP", TK_TO)) {
298 				eligibleYearEndActions.add(violation);
299 			}
300 		}
301 		assertEquals(0, eligibleYearEndActions.size());
302 	}
303 	
304 	@Test
305 	public void testGetMaxBalanceViolationsOnDemandForTimesheetCaseOne() throws Exception {
306 		//Timesheet contains leave period ending 12/11/2011
307 		LmServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM.toDateTimeAtStartOfDay(),TK_TO.toDateTimeAtStartOfDay(),true,TS_USER_ID);
308 		midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
309 		midDecTSDEntry = midDecTSD.getCalendarEntry();
310 
311 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(midDecTSDEntry, TS_USER_ID);
312 		//Assert correct number of transfer eligible for frequency
313 		assertEquals(6, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
314 	}
315 	
316 	@Test
317 	public void testGetMaxBalanceViolationsLeaveApproveForTimesheetCaseThree() throws Exception {
318 		//Timesheet contains leave period ending 12/25/2011
319 		LmServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM.toDateTimeAtStartOfDay(),TK_TO.toDateTimeAtStartOfDay(),true,TS_USER_ID);
320 		endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
321 		endDecTSDEntry = endDecTSD.getCalendarEntry();
322 
323 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(endDecTSDEntry, TS_USER_ID);
324 
325 		assertEquals("Incorrect number of max balance violations", 18, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
326 		//Assert correct base number of transfer eligible for frequency
327 		List<LeaveBlock> eligibleLeaveApproveActions = new ArrayList<LeaveBlock>();
328 		Interval interval = new Interval(endDecTSDEntry.getBeginPeriodDate().getTime(),endDecTSDEntry.getEndPeriodDate().getTime());
329 		List<CalendarEntry> entries = HrServiceLocator.getCalendarEntryService().getCalendarEntriesEndingBetweenBeginAndEndDate("3", interval.getStart(), interval.getEnd());
330 		assertTrue("There should only be one leave period that ends within any given time calendar", entries.size() == 1);
331 		CalendarEntry leaveEntry = entries.get(0);
332 		Interval leaveInterval = new Interval(endDecTSDEntry.getBeginPeriodDate().getTime(),leaveEntry.getEndPeriodDate().getTime());
333 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE)) {
334 			if(leaveInterval.contains(violation.getLeaveDate().getTime())) {
335 				eligibleLeaveApproveActions.add(violation);
336 			}
337 		}
338 		assertEquals("Incorrect number of eligible leave approve actions", 6, eligibleLeaveApproveActions.size());
339 
340 		LeaveBlock usage = new LeaveBlock();
341 		
342 		usage.setAccrualCategory("la-xfer");
343 		usage.setAccrualGenerated(false);
344 		usage.setLeaveAmount(new BigDecimal(-30));
345 		// 12/15/2011 <= leave date < 12/25/2011
346 		usage.setLeaveLocalDate(TKUtils.formatDateString("12/23/2011"));
347 		usage.setDocumentId(TSD_END_DEC_PERIOD_ID);
348 		usage.setPrincipalId(TS_USER_ID);
349 		usage.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
350 		usage.setEarnCode("EC1");
351 		usage.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
352 		usage.setBlockId(0L);
353 		
354 		//KRADServiceLocator.getBusinessObjectService().save(usage);
355         LmServiceLocator.getLeaveBlockService().saveLeaveBlock(usage, TS_USER_ID);
356 		
357 		
358 		
359 		maxBalanceViolations = eligibilityTestHelper(endDecTSDEntry, TS_USER_ID);
360 		assertEquals("Incorrect number of max balance violation", 15, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
361 
362 		//The above leave block should remove la-xfer from eligibility, reducing the number of eligibilities by 1.
363 		List<LeaveBlock> eligibleTransfers = new ArrayList<LeaveBlock>();
364 		
365 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE)) {
366 			if(leaveInterval.contains(violation.getLeaveDate().getTime())) {
367 				eligibleTransfers.add(violation);
368 			}
369 		}
370 		//actual reduction is by 2...
371 		assertEquals(5, eligibleTransfers.size());
372 		
373 		// adding an accrual block beyond the underlying leave calendar end date, but still within the
374 		// bounds of the time period, should re-mark this accrual category over max balance, but should not be eligible for action
375 		usage = new LeaveBlock();
376 		
377 		usage.setAccrualCategory("la-xfer");
378 		usage.setAccrualGenerated(false);
379 		usage.setLeaveAmount(new BigDecimal(30));
380 		usage.setLeaveLocalDate(TKUtils.formatDateString("12/28/2011"));
381 		usage.setDocumentId(TSD_END_DEC_PERIOD_ID);
382 		usage.setPrincipalId(TS_USER_ID);
383 		usage.setRequestStatus(HrConstants.REQUEST_STATUS.APPROVED);
384 		usage.setEarnCode("EC1");
385 		usage.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
386 		usage.setBlockId(0L);
387 		
388 	 //KRADServiceLocator.getBusinessObjectService().save(usage);
389         LmServiceLocator.getLeaveBlockService().saveLeaveBlock(usage, TS_USER_ID);
390 		
391 		maxBalanceViolations = eligibilityTestHelper(endDecTSDEntry, TS_USER_ID);
392 		assertEquals("Incorrect number of leave approve violations", 18, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
393 		eligibleTransfers = new ArrayList<LeaveBlock>();
394 		
395 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE)) {
396 			if(leaveInterval.contains(violation.getLeaveDate().getTime())) {
397 				eligibleTransfers.add(violation);
398 			}
399 		}
400 		assertEquals(5, eligibleTransfers.size());
401 	}
402 	
403 	@Test
404 	public void testGetMaxBalanceViolationsLeaveApproveForTimesheetCaseTwo() throws Exception {
405 		//Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
406 		LmServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM.toDateTimeAtStartOfDay(),TK_TO.toDateTimeAtStartOfDay(),true,TS_USER_ID);
407 		endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
408 		endDecTSDEntry = endDecTSD.getCalendarEntry();
409 
410 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(endDecTSDEntry, TS_USER_ID);
411 		//Assert correct number of violations
412 		assertEquals("Incorrect number of leave approve violations", 18, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
413 
414 		List<LeaveBlock> eligibleTransfers = new ArrayList<LeaveBlock>();
415 		Interval interval = new Interval(endDecTSDEntry.getBeginPeriodDate().getTime(),endDecTSDEntry.getEndPeriodDate().getTime());
416 		List<CalendarEntry> entries = HrServiceLocator.getCalendarEntryService().getCalendarEntriesEndingBetweenBeginAndEndDate("3", interval.getStart(), interval.getEnd());
417 		assertTrue("There should only be one leave period that ends within any given time calendar", entries.size() == 1);
418 		CalendarEntry leaveEntry = entries.get(0);
419 		Interval leaveInterval = new Interval(endDecTSDEntry.getBeginPeriodDate().getTime(),leaveEntry.getEndPeriodDate().getTime());
420 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE)) {
421 			if(leaveInterval.contains(violation.getLeaveDate().getTime())) {
422 				eligibleTransfers.add(violation);
423 			}
424 		}
425 		//Assert correct number of actions eligible for frequency
426 		assertEquals(6, eligibleTransfers.size());
427 	}
428 	
429 	@Test
430 	public void testGetMaxBalanceViolationsYearEndForTimesheetCaseTwo() throws Exception {
431 		//Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
432 		LmServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM.toDateTimeAtStartOfDay(),TK_TO.toDateTimeAtStartOfDay(),true,TS_USER_ID);
433 		endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
434 		endDecTSDEntry = endDecTSD.getCalendarEntry();
435 
436 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(endDecTSDEntry, TS_USER_ID);
437 		//Assert correct number of transfer eligible for frequency
438 		assertEquals(8, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
439 		
440 		List<LeaveBlock> eligibleTransfers = new ArrayList<LeaveBlock>();
441 		Interval interval = new Interval(endDecTSDEntry.getBeginPeriodDate().getTime(),endDecTSDEntry.getEndPeriodDate().getTime());
442 		List<CalendarEntry> entries = HrServiceLocator.getCalendarEntryService().getCalendarEntriesEndingBetweenBeginAndEndDate("3", interval.getStart(), interval.getEnd());
443 		assertTrue("There should only be one leave period that ends within any given time calendar", entries.size() == 1);
444 		CalendarEntry leaveEntry = entries.get(0);
445 		Interval leaveInterval = new Interval(endDecTSDEntry.getBeginPeriodDate().getTime(),leaveEntry.getEndPeriodDate().getTime());
446 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
447 			if(leaveInterval.contains(violation.getLeaveDate().getTime())) {
448 				eligibleTransfers.add(violation);
449 			}
450 		}
451 		
452 		assertEquals("There should be no eligible max balance actions", 0, eligibleTransfers.size());
453 	}
454 	
455 	@Test
456 	public void testGetMaxBalanceViolationsYearEndForTimesheetCaseThree() throws Exception {
457 		//Timesheet includes the leave calendar end period, which is the leave plan's final period.
458 		LmServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM.toDateTimeAtStartOfDay(),TK_TO.toDateTimeAtStartOfDay(),true,TS_USER_ID);
459 		endJanTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_JAN_PERIOD_ID);
460 		endJanTSDEntry = endJanTSD.getCalendarEntry();
461 
462 		Map<String, Set<LeaveBlock>> maxBalanceViolations = eligibilityTestHelper(endJanTSDEntry, TS_USER_ID);
463 
464 		assertEquals(24, maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
465 
466 		//Assert correct number of transfer eligible for frequency
467 		List<LeaveBlock> eligibleTransfers = new ArrayList<LeaveBlock>();
468 		Interval interval = new Interval(endJanTSDEntry.getBeginPeriodDate().getTime(),endJanTSDEntry.getEndPeriodDate().getTime());
469 		List<CalendarEntry> entries = HrServiceLocator.getCalendarEntryService().getCalendarEntriesEndingBetweenBeginAndEndDate("3", interval.getStart(), interval.getEnd());
470 		assertTrue("There should only be one leave period that ends within any given time calendar", entries.size() == 1);
471 		CalendarEntry leaveEntry = entries.get(0);
472 		Interval leaveInterval = new Interval(endJanTSDEntry.getBeginPeriodDate().getTime(),leaveEntry.getEndPeriodDate().getTime());
473 		for(LeaveBlock violation : maxBalanceViolations.get(HrConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
474 			if(leaveInterval.contains(violation.getLeaveDate().getTime())) {
475 				eligibleTransfers.add(violation);
476 			}
477 		}
478 		
479 		assertEquals(8, eligibleTransfers.size());
480 	}
481 	
482 	
483 	private Map<String, Set<LeaveBlock>> eligibilityTestHelper(
484 			CalendarEntry entry, String principalId) throws Exception {
485 		return LmServiceLocator.getAccrualCategoryMaxBalanceService().getMaxBalanceViolations(entry, principalId);
486 	}
487 }