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.hr.lm.leavepayout.service;
017    
018    import static org.junit.Assert.*;
019    
020    import java.math.BigDecimal;
021    import java.util.ArrayList;
022    import java.util.Date;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.Map.Entry;
026    
027    import org.apache.commons.lang.time.DateUtils;
028    import org.junit.After;
029    import org.junit.Before;
030    import org.junit.Test;
031    import org.kuali.hr.lm.LMConstants;
032    import org.kuali.hr.lm.accrual.AccrualCategoryRule;
033    import org.kuali.hr.lm.leavepayout.LeavePayout;
034    import org.kuali.hr.lm.employeeoverride.EmployeeOverride;
035    import org.kuali.hr.lm.leaveSummary.LeaveSummary;
036    import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
037    import org.kuali.hr.lm.leaveblock.LeaveBlock;
038    import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
039    import org.kuali.hr.test.KPMETestCase;
040    import org.kuali.hr.time.calendar.CalendarEntries;
041    import org.kuali.hr.time.service.base.TkServiceLocator;
042    import org.kuali.hr.time.timesheet.TimesheetDocument;
043    import org.kuali.hr.time.util.TKUtils;
044    import org.kuali.rice.krad.util.ObjectUtils;
045    
046    public class LeavePayoutServiceTest extends KPMETestCase {
047    
048            /**
049             * Leave Calendar Document Test data
050             */
051            private final String USER_ID = "testUser1";
052            
053            private LeaveCalendarDocument janLCD;
054            private CalendarEntries janEntry;
055            private LeaveCalendarDocument decLCD;
056            private CalendarEntries decEntry;
057            
058            private Date janStart;
059            private Date janEnd;
060            private Date decStart;
061            private Date decEnd;
062            
063            private final String JAN_ID = "5001";
064            private final String DEC_ID = "5000";
065            
066            /**
067             * Timesheet Document Test Data;
068             */
069            
070            private final String TS_USER_ID = "testUser2";  
071            
072            private TimesheetDocument endJanTSD;
073            private CalendarEntries endJanTSDEntry;
074            private TimesheetDocument midJanTSD;
075            private CalendarEntries midJanTSDEntry;
076            private TimesheetDocument endDecTSD;
077            private CalendarEntries endDecTSDEntry;
078            private TimesheetDocument midDecTSD;
079            private CalendarEntries midDecTSDEntry;
080            
081            private Date midJanStart;
082            private Date midJanEnd;
083            private Date endDecStart;
084            private Date endDecEnd;
085            private Date midDecStart;
086            private Date midDecEnd;
087            
088            private final String TSD_MID_DEC_PERIOD_ID = "5000";
089            private final String TSD_END_DEC_PERIOD_ID = "5001";
090            private final String TSD_MID_JAN_PERIOD_ID = "5002";
091            private final String TSD_END_JAN_PERIOD_ID = "5003";
092    
093            /**
094             *  Common data
095             */
096            
097            private final String OD_XFER = "5000";
098            private final String YE_XFER = "5001";
099            private final String LA_XFER = "5002";
100            private final String OD_XFER_MAC = "5003";
101            private final String YE_XFER_MAC = "5004";
102            private final String LA_XFER_MAC = "5005";
103            private final String OD_LOSE = "5006";
104            private final String YE_LOSE = "5007";
105            private final String LA_LOSE = "5008";
106            private final String OD_LOSE_MAC = "5009";
107            private final String YE_LOSE_MAC = "5010";
108            private final String LA_LOSE_MAC = "5011";
109            private final String YE_XFER_EO = "5012";
110            private final java.sql.Date LM_FROM = TKUtils.formatDateString("11/01/2012");
111            private final java.sql.Date LM_TO = TKUtils.formatDateString("02/01/2013");
112            private final java.sql.Date TK_FROM = TKUtils.formatDateString("11/01/2011");
113            private final java.sql.Date TK_TO = TKUtils.formatDateString("02/01/2012");
114            
115            @Before
116            public void setUp() throws Exception {
117                    super.setUp();
118                    TkServiceLocator.getAccrualService().runAccrual(USER_ID,LM_FROM,LM_TO,true,USER_ID);
119                    janLCD = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(JAN_ID);
120                    janEntry = janLCD.getCalendarEntry();
121                    janStart = janEntry.getBeginPeriodDate();
122                    janEnd = janEntry.getEndPeriodDate();
123                    decLCD = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(DEC_ID);
124                    decEntry = decLCD.getCalendarEntry();
125                    decStart = decEntry.getBeginPeriodDate();
126                    decEnd = decEntry.getEndPeriodDate();
127            }
128            
129            @After
130            public void tearDown() throws Exception {
131                    super.tearDown();
132            }
133            
134            /*****************************
135             * Use-case specific testing *
136             ****************************/
137            
138            //
139            // ACTION_AT_MAX_BALANCE = TRANSFER
140            //
141            
142            @Test
143            public void testInitializePayoutNullAccrualRule() throws Exception {
144                    LeavePayout lp = new LeavePayout();
145    
146                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
147                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, null, BigDecimal.ZERO, effectiveDate);
148                    assertNull(lp);
149            }
150            
151            @Test
152            public void testInitializePayoutNullLeaveSummary() throws Exception {
153                    LeavePayout lp = new LeavePayout();
154    
155                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, null, TKUtils.getCurrentDate());
156                    assertNull(lp);
157            }
158            
159            @Test
160            public void testInitializePayoutNullAccrualRuleNullLeaveSummary() {
161                    LeavePayout lp = new LeavePayout();
162                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, null, null, TKUtils.getCurrentDate());
163                    assertNull(lp);
164            }
165            
166            @Test
167            public void testInitializePayoutOnDemand() throws Exception {
168                    LeavePayout lp = new LeavePayout();
169                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
170                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER);
171                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
172                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
173                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
174                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
175                    ////assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
176            }
177            
178            @Test
179            public void testInitializePayoutOnDemandWithForfeiture() throws Exception {
180                    LeavePayout lp = new LeavePayout();
181                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
182                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER);
183                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
184                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
185                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
186                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(7)).longValue(), lp.getForfeitedAmount().longValue());
187                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
188            }
189            
190            @Test
191            public void testInitializePayoutOnYearEnd() throws Exception {
192                    LeavePayout lp = new LeavePayout();
193                    TkServiceLocator.getLeaveBlockService().deleteLeaveBlocksForDocumentId(DEC_ID);
194                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
195                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER);
196                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
197                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
198                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
199                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
200                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
201            }
202            
203            @Test
204            public void testInitializePayoutOnYearEndWithForfeiture() throws Exception {
205                    LeavePayout lp = new LeavePayout();
206                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
207                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER);
208                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
209                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
210                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
211                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(7)).longValue(), lp.getForfeitedAmount().longValue());
212                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
213            }
214            
215            @Test
216            public void testInitializePayoutOnLeaveApprove() throws Exception {
217                    LeavePayout lp = new LeavePayout();
218                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
219                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_XFER);
220                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
221                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, LA_XFER, aRow.getAccruedBalance(), effectiveDate);
222                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
223                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
224                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
225            }
226            
227            @Test
228            public void testInitializePayoutOnLeaveApproveWithForfeiture() throws Exception {
229                    LeavePayout lp = new LeavePayout();
230                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
231                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_XFER);
232                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
233                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, LA_XFER, aRow.getAccruedBalance(), effectiveDate);
234                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
235                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(7)).longValue(), lp.getForfeitedAmount().longValue());
236                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
237            }
238            
239            @Test
240            public void testInitializePayoutOnDemandMaxCarryOver() throws Exception {
241                    //N/A - Max Carry Over on Year End payouts.
242                    LeavePayout lp = new LeavePayout();
243                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
244                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER_MAC);
245                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
246                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
247                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
248                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
249                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
250            }
251            
252            @Test
253            public void testInitializePayoutOnYearEndMaxCarryOver() throws Exception {
254                    /**
255                     * decEntry is not the last calendar entry in the leave plan. Want to check amounts for this action & action frequency
256                     * without exceeding the payout limit.
257                     * 
258                     * max payout amount = 10
259                     * leave balance = 16
260                     * max balance = 15
261                     * max carry over = 10
262                     * 
263                     * all excess should be payoutrable. 1 unit of time for excess over max balance, 5 units of time for
264                     * excess over max carry over.
265                     * 
266                     */
267                    LeavePayout lp = new LeavePayout();
268                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
269                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER_MAC);
270                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
271                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
272                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(6)).longValue(), lp.getPayoutAmount().longValue());
273                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
274                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(3)).longValue(), lp.getAmountPayoutred().longValue());
275            }
276            
277    /*      @Test
278            public void testInitializePayoutUnderMaxBalanceOnYearEndMaxCarryOver() throws Exception {
279                    //Create a leave block that will bring the available balance for january down to 14.
280                    //this balance would be under the max available balance (15), but over the max annual carry over amount.
281                    //i.o.w., this payout would not due to max balance limit, but max annual carry over.
282                    //could also simply change the accrual amount.
283                    LeaveBlock usage = new LeaveBlock();
284                    usage.setAccrualCategory(YE_XFER_MAC);
285                    usage.setLeaveDate(new java.sql.Date(DateUtils.addDays(janStart,5).getTime()));
286                    usage.setLeaveAmount(new BigDecimal(-18));
287                    usage.setPrincipalId(USER_ID);
288                    usage.setAccrualGenerated(false);
289                    usage.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
290                    usage.setDocumentId(janLCD.getDocumentId());
291                    usage.setLmLeaveBlockId("99999");
292                    usage.setEarnCode("EC5");
293                    usage.setBlockId(0L);
294                    usage.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR);
295                    List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>();
296                    leaveBlocks.add(usage);
297                    TkServiceLocator.getLeaveBlockService().saveLeaveBlocks(leaveBlocks);
298                    
299                    LeavePayout lp = new LeavePayout();
300                    janLCD = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(JAN_ID);
301                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janLCD.getCalendarEntry());
302                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
303                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
304                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(4)).longValue(), lp.getPayoutAmount().longValue());
305                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
306                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(2)).longValue(), lp.getAmountPayoutred().longValue());
307            }*/
308            
309            @Test
310            public void testInitializePayoutOnYearEndMaxCarryOverWithForfeiture() throws Exception {
311                    //max bal limit reached and max annual carry over triggererd.
312                    LeavePayout lp = new LeavePayout();
313                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
314                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER_MAC);
315                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
316                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
317                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
318                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(12)).longValue(), lp.getForfeitedAmount().longValue());
319                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
320            }
321            
322            @Test
323            public void testInitializePayoutOnLeaveApproveMaxCarryOver() throws Exception {
324                    LeavePayout lp = new LeavePayout();
325                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
326                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_XFER_MAC);
327                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
328                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, LA_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
329                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
330                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
331                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
332            }
333            
334            @Test
335            public void testInitializePayoutWithOverrides() throws Exception {
336                    LeavePayout lp = new LeavePayout();
337                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
338                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER_EO);
339                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
340                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_EO, aRow.getAccruedBalance(), effectiveDate);
341                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(7)).longValue(), lp.getPayoutAmount().longValue());
342                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(20)).longValue(), lp.getForfeitedAmount().longValue());
343                    // max balance payout conversion factor is undefined for YE_XFER_EO
344                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(7)).longValue(), lp.getAmountPayoutred().longValue());
345            }
346            /**
347             * End Use-case testing
348             */
349            
350            @Test
351            public void testPayoutNullLeavePayout() {
352                    LeavePayout LeavePayout = null;
353                    try {
354                            LeavePayout = TkServiceLocator.getLeavePayoutService().payout(LeavePayout);
355                    } catch (RuntimeException re) {
356                            assertTrue(re.getMessage().contains("did not supply a valid LeavePayout object"));
357                    }
358            }
359            
360            @Test
361            public void testPayoutWithZeroPayoutAmount() throws Exception {
362                    LeavePayout lp = new LeavePayout();
363                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
364                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_LOSE);
365                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
366                    //lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_LOSE, aRow.getAccruedBalance(), effectiveDate);
367                    lp.setPayoutAmount(BigDecimal.ZERO);
368                    lp = TkServiceLocator.getLeavePayoutService().payout(lp);
369                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getForfeitedLeaveBlockId());
370                    LeaveBlock payoutLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutLeaveBlockId());
371                    LeaveBlock payoutFromLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutFromLeaveBlockId());
372                    assertTrue("forfeited leave block should not exist", ObjectUtils.isNull(forfeitedLeaveBlock));
373                    assertTrue("accrued leave block should not exist",ObjectUtils.isNull(payoutLeaveBlock));
374                    assertTrue("debited leave block should not exist",ObjectUtils.isNull(payoutFromLeaveBlock));
375            }
376            
377            @Test
378            public void testPayoutWithZeroForfeiture() throws Exception {
379                    LeavePayout lp = new LeavePayout();
380                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
381                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER);
382                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
383                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
384                    lp = TkServiceLocator.getLeavePayoutService().payout(lp);
385                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getForfeitedLeaveBlockId());
386                    LeaveBlock payoutLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutLeaveBlockId());
387                    LeaveBlock payoutFromLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutFromLeaveBlockId());
388                    assertEquals("accrued leave block leave amount incorrect", (new BigDecimal(1)).longValue(), payoutLeaveBlock.getLeaveAmount().longValue());
389                    assertTrue("forfeited leave block should not exist",ObjectUtils.isNull(forfeitedLeaveBlock));
390                    assertEquals("payouted leave block leave amount incorrect", (new BigDecimal(-1)).longValue(), payoutFromLeaveBlock.getLeaveAmount().longValue());
391            }
392            
393            @Test
394            public void testPayoutWithThreeLeaveBlocks() throws Exception {
395                    LeavePayout lp = new LeavePayout();
396                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
397                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER);
398                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
399                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
400                    lp = TkServiceLocator.getLeavePayoutService().payout(lp);
401                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getForfeitedLeaveBlockId());
402                    LeaveBlock payoutLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutLeaveBlockId());
403                    LeaveBlock payoutFromLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutFromLeaveBlockId());
404                    assertEquals("forfeited leave block leave amount incorrect", (new BigDecimal(-7)).longValue(), forfeitedLeaveBlock.getLeaveAmount().longValue());
405                    assertEquals((new BigDecimal(10)).longValue(), payoutLeaveBlock.getLeaveAmount().longValue());
406                    assertEquals((new BigDecimal(-10)).longValue(), payoutFromLeaveBlock.getLeaveAmount().longValue());
407            }
408            
409            //TODO: write tests for adjusted max balance cases - i.e. FTE < 1, employee override's w/ type MAX_BALANCE
410            
411            @Test
412            public void testgetEligiblePayoutsLeaveApprove() throws Exception {
413                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(janEntry, USER_ID);
414                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
415                    assertEquals(3, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
416                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
417                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
418                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE))
419                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
420                            
421                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
422                    for(AccrualCategoryRule aRule : rules) {
423                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
424                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
425                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
426                    }
427            }
428            
429            @Test
430            public void testgetEligiblePayoutsYearEnd() throws Exception {
431                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(janEntry, USER_ID);
432                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
433                    assertEquals(3, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
434                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
435                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
436                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
437                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
438                    
439                    // Set should contain an accrual category whose rule's max balance is trumped by an employee override.
440                    // Comparing accrued balance to a rule's defined max balance is insufficient for testing
441                    // whether or not an accrual category is indeed over it's balance limit. Same can be said for FTE-proration.
442                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
443                    for(AccrualCategoryRule aRule : rules) {
444                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
445                            BigDecimal maxBalance = aRule.getMaxBalance();
446                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(USER_ID,
447                                            "testLP",
448                                            row.getAccrualCategory(),
449                                            "MB",
450                                            janEntry.getBeginPeriodDate());
451                            if(ObjectUtils.isNotNull(mbOverride))
452                                    maxBalance = new BigDecimal(mbOverride.getOverrideValue());
453                            assertNotNull("eligible accrual category has no balance limit",maxBalance);
454                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(maxBalance) > 0);
455                    }
456            }
457            
458            @Test
459            public void testgetEligiblePayoutsOnDemand() throws Exception {
460                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(janEntry, USER_ID);
461                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
462                    assertEquals(3, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
463                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
464                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
465                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
466                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
467    
468                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
469                    for(AccrualCategoryRule aRule : rules) {
470                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
471                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
472                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
473                    }
474            }
475            
476            @Test
477            public void testgetEligiblePayoutsOnYearEndCaseOne() throws Exception {
478                    //calendar entry is not the last calendar entry of the leave plan's calendar year.
479                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(decEntry, USER_ID);
480                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
481                    assertEquals(0, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
482                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
483                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
484                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
485                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
486    
487                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
488                    for(AccrualCategoryRule aRule : rules) {
489                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
490                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
491                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
492                    }
493            }
494            
495            @Test
496            public void testgetEligiblePayoutsOnYearEndCaseTwo() throws Exception {
497                    //calendar entry is the last calendar entry of the leave plan's calendar year.
498                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(janEntry, USER_ID);
499                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
500                    assertEquals(3, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
501                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
502                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
503                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
504                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
505    
506                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
507                    for(AccrualCategoryRule aRule : rules) {
508                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
509                            BigDecimal maxBalance = aRule.getMaxBalance();
510                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(USER_ID,
511                                            "testLP",
512                                            row.getAccrualCategory(),
513                                            "MB",
514                                            janEntry.getBeginPeriodDate());
515                            EmployeeOverride macOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(USER_ID,
516                                            "testLP",
517                                            row.getAccrualCategory(),
518                                            "MAC",
519                                            janEntry.getBeginPeriodDate());
520                            if(ObjectUtils.isNotNull(mbOverride) && ObjectUtils.isNotNull(macOverride))
521                                    maxBalance = new BigDecimal(Math.min(mbOverride.getOverrideValue(), macOverride.getOverrideValue()));
522                            else {
523                                    if(ObjectUtils.isNotNull(macOverride))
524                                            maxBalance = new BigDecimal(macOverride.getOverrideValue());
525                                    if(ObjectUtils.isNotNull(mbOverride))
526                                            maxBalance = new BigDecimal(mbOverride.getOverrideValue());
527                            }
528                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(maxBalance));
529                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(maxBalance) > 0);
530                    }
531            }
532            
533            @Test
534            public void testSubmitToWorkflow() {
535                    assertNull(null);
536            }
537            
538            /**
539             * 
540             * TIMESHEET ELIGIBLE TESTS
541             * 
542             */
543            
544            @Test
545            public void testgetEligiblePayoutsLeaveApproveForTimesheetCaseOne() throws Exception {
546                    //Timesheet does not contain the leave calendar end period
547                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
548                    midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
549                    midDecTSDEntry = midDecTSD.getCalendarEntry();
550    
551                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(midDecTSDEntry, TS_USER_ID);
552                    //Assert correct number of payout eligible for frequency
553                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
554    
555                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
556                    //according to their rules. - does not consider FTE.
557                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
558                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE))
559                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
560    
561                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, midDecTSDEntry);
562                    for(AccrualCategoryRule aRule : rules) {
563                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
564                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
565                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
566                    }
567            }
568            
569            @Test
570            public void testgetEligiblePayoutsYearEndForTimesheetCaseOne() throws Exception {
571                    //Timesheet does not include the leave calendar end period
572                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
573                    midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
574                    midDecTSDEntry = midDecTSD.getCalendarEntry();
575    
576                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(midDecTSDEntry, TS_USER_ID);
577                    //Assert correct number of payout eligible for frequency
578                    assertEquals(0, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
579                    
580                    /**
581                     * No eligible payouts to test balance limit.
582                     */
583    /*              //Assert that the accrual categories returned by BT service are in fact over their balance limit,
584                    //according to their rules.
585                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
586                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
587                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
588                            
589                    // Set should contain an accrual category whose rule's max balance is trumped by an employee override.
590                    // Comparing accrued balance to a rule's defined max balance is insufficient for testing
591                    // whether or not an accrual category is indeed over it's balance limit. Same can be said for FTE-proration.
592                    // However, in this case, using an employee override will 
593                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, midDecTSDEntry);
594                    for(AccrualCategoryRule aRule : rules) {
595                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
596                            BigDecimal maxBalance = aRule.getMaxBalance();
597                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
598                                            "testLP",
599                                            row.getAccrualCategory(),
600                                            "MB",
601                                            janEntry.getBeginPeriodDate());
602                            if(ObjectUtils.isNotNull(mbOverride))
603                                    maxBalance = new BigDecimal(mbOverride.getOverrideValue());
604                            //Don't care about employee override existence, this is not the leave plan's roll-over period.
605                            assertNotNull("eligible accrual category has no balance limit",maxBalance);
606                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(maxBalance) > 0);
607                    }*/
608            }
609            
610            @Test
611            public void testgetEligiblePayoutsOnDemandForTimesheetCaseOne() throws Exception {
612                    //Timesheet does not include the leave calendar end period
613                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
614                    midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
615                    midDecTSDEntry = midDecTSD.getCalendarEntry();
616    
617                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(midDecTSDEntry, TS_USER_ID);
618                    //Assert correct number of payout eligible for frequency
619                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
620    
621                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
622                    //according to their rules. - does not consider FTE.
623                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
624                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
625                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
626    
627                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, midDecTSDEntry);
628                    for(AccrualCategoryRule aRule : rules) {
629                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
630                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
631                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
632                    }
633            }
634            
635            @Test
636            public void testgetEligiblePayoutsLeaveApproveForTimesheetCaseTwo() throws Exception {
637                    //Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
638                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
639                    endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
640                    endDecTSDEntry = endDecTSD.getCalendarEntry();
641    
642                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(endDecTSDEntry, TS_USER_ID);
643                    //Assert correct number of payout eligible for frequency
644                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
645                    
646                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
647                    //according to their rules. - does not consider FTE.
648                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
649                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE))
650                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
651    
652                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, endDecTSDEntry);
653                    for(AccrualCategoryRule aRule : rules) {
654                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
655                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
656                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
657                    }
658            }
659            
660            @Test
661            public void testgetEligiblePayoutsYearEndForTimesheetCaseTwo() throws Exception {
662                    //Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
663                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
664                    endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
665                    endDecTSDEntry = endDecTSD.getCalendarEntry();
666    
667                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(endDecTSDEntry, TS_USER_ID);
668                    //Assert correct number of payout eligible for frequency
669                    assertEquals(0, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
670                    
671                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
672                    //according to their rules. - does not consider FTE.
673                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
674                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
675                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
676    
677                    // Set should contain an accrual category whose rule's max balance is trumped by an employee override.
678                    // Comparing accrued balance to a rule's defined max balance is insufficient for testing
679                    // whether or not an accrual category is indeed over it's balance limit. Same can be said for FTE-proration.
680                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, endDecTSDEntry);
681                    for(AccrualCategoryRule aRule : rules) {
682                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
683                            BigDecimal maxBalance = aRule.getMaxBalance();
684                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
685                                            "testLP",
686                                            row.getAccrualCategory(),
687                                            "MB",
688                                            janEntry.getBeginPeriodDate());
689                            if(ObjectUtils.isNotNull(mbOverride))
690                                    maxBalance = new BigDecimal(mbOverride.getOverrideValue());
691                            assertNotNull("eligible accrual category has no balance limit",maxBalance);
692                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(maxBalance) > 0);
693                    }
694            }
695            
696            @Test
697            public void testgetEligiblePayoutsOnDemandForTimesheetCaseTwo() throws Exception {
698                    //Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
699                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
700                    endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
701                    endDecTSDEntry = endDecTSD.getCalendarEntry();
702    
703    
704                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(endDecTSDEntry, TS_USER_ID);
705                    //Assert correct number of payout eligible for frequency
706                    assertEquals(2, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
707                    
708                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
709                    //according to their rules. - does not consider FTE.
710                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
711                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
712                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
713    
714                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID,endDecTSDEntry);
715                    for(AccrualCategoryRule aRule : rules) {
716                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
717                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
718                            assertTrue("accrual category not eligible for payout",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
719                    }
720            }
721            
722            @Test
723            public void testgetEligiblePayoutsYearEndForTimesheetCaseThree() throws Exception {
724                    //Timesheet includes the leave calendar end period, which is the leave plan's roll-over date.
725                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
726                    endJanTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_JAN_PERIOD_ID);
727                    endJanTSDEntry = endJanTSD.getCalendarEntry();
728    
729                    Map<String, ArrayList<String>> eligiblePayouts = TkServiceLocator.getLeavePayoutService().getEligiblePayouts(endJanTSDEntry, TS_USER_ID);
730    
731                    //Assert correct number of payout eligible for frequency
732                    assertEquals(3, eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
733                    
734                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
735                    //according to their rules. - does not consider FTE.
736                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
737                    for(String eligiblePayout : eligiblePayouts.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
738                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligiblePayout));
739    
740                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID,endJanTSDEntry);
741                    for(AccrualCategoryRule aRule : rules) {
742                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
743                            BigDecimal maxBalance = aRule.getMaxBalance();
744                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
745                                            "testLP",
746                                            row.getAccrualCategory(),
747                                            "MB",
748                                            janEntry.getBeginPeriodDate());
749                            EmployeeOverride macOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
750                                            "testLP",
751                                            row.getAccrualCategory(),
752                                            "MAC",
753                                            janEntry.getBeginPeriodDate());
754                            if(ObjectUtils.isNotNull(mbOverride) && ObjectUtils.isNotNull(macOverride))
755                                    maxBalance = new BigDecimal(Math.min(mbOverride.getOverrideValue(), macOverride.getOverrideValue()));
756                            else {
757                                    if(ObjectUtils.isNotNull(macOverride))
758                                            maxBalance = new BigDecimal(macOverride.getOverrideValue());
759                                    if(ObjectUtils.isNotNull(mbOverride))
760                                            maxBalance = new BigDecimal(mbOverride.getOverrideValue());
761                            }
762                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(maxBalance));
763                            assertTrue("accrual category " + aRule.getLmAccrualCategoryId() + " not eligible for payout",row.getAccruedBalance().compareTo(maxBalance) > 0);
764                    }
765            }
766    }