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.balancetransfer.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.balancetransfer.BalanceTransfer;
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 BalanceTransferServiceTest 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 testInitializeTransferNullAccrualRule() throws Exception {
144                    BalanceTransfer bt = new BalanceTransfer();
145    
146                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
147                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, null, BigDecimal.ZERO, effectiveDate);
148                    assertNull(bt);
149            }
150            
151            @Test
152            public void testInitializeTransferNullLeaveSummary() throws Exception {
153                    BalanceTransfer bt = new BalanceTransfer();
154    
155                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, OD_XFER, null, TKUtils.getCurrentDate());
156                    assertNull(bt);
157            }
158            
159            @Test
160            public void testInitializeTransferNullAccrualRuleNullLeaveSummary() {
161                    BalanceTransfer bt = new BalanceTransfer();
162                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, null, null, TKUtils.getCurrentDate());
163                    assertNull(bt);
164            }
165            
166            @Test
167            public void testInitializeTransferOnDemand() throws Exception {
168                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
173                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(1)).longValue(), bt.getTransferAmount().longValue());
174                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(0)).longValue(), bt.getForfeitedAmount().longValue());
175                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0.5)).longValue(), bt.getAmountTransferred().longValue());
176            }
177            
178            @Test
179            public void testInitializeTransferOnDemandWithForfeiture() throws Exception {
180                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
185                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(10)).longValue(), bt.getTransferAmount().longValue());
186                    assertEquals("transferOnDemand forfeited amount", (new BigDecimal(7)).longValue(), bt.getForfeitedAmount().longValue());
187                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(5)).longValue(), bt.getAmountTransferred().longValue());
188            }
189            
190            @Test
191            public void testInitializeTransferOnYearEnd() throws Exception {
192                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
198                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(1)).longValue(), bt.getTransferAmount().longValue());
199                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(0)).longValue(), bt.getForfeitedAmount().longValue());
200                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0.5)).longValue(), bt.getAmountTransferred().longValue());
201            }
202            
203            @Test
204            public void testInitializeTransferOnYearEndWithForfeiture() throws Exception {
205                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
210                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(10)).longValue(), bt.getTransferAmount().longValue());
211                    assertEquals("transferOnDemand forfeited amount", (new BigDecimal(7)).longValue(), bt.getForfeitedAmount().longValue());
212                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(5)).longValue(), bt.getAmountTransferred().longValue());
213            }
214            
215            @Test
216            public void testInitializeTransferOnLeaveApprove() throws Exception {
217                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, LA_XFER, aRow.getAccruedBalance(), effectiveDate);
222                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(1)).longValue(), bt.getTransferAmount().longValue());
223                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(0)).longValue(), bt.getForfeitedAmount().longValue());
224                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0.5)).longValue(), bt.getAmountTransferred().longValue());
225            }
226            
227            @Test
228            public void testInitializeTransferOnLeaveApproveWithForfeiture() throws Exception {
229                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, LA_XFER, aRow.getAccruedBalance(), effectiveDate);
234                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(10)).longValue(), bt.getTransferAmount().longValue());
235                    assertEquals("transferOnDemand forfeited amount", (new BigDecimal(7)).longValue(), bt.getForfeitedAmount().longValue());
236                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(5)).longValue(), bt.getAmountTransferred().longValue());
237            }
238            
239            @Test
240            public void testInitializeTransferOnDemandMaxCarryOver() throws Exception {
241                    //N/A - Max Carry Over on Year End transfers.
242                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, OD_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
247                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(1)).longValue(), bt.getTransferAmount().longValue());
248                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(0)).longValue(), bt.getForfeitedAmount().longValue());
249                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0.5)).longValue(), bt.getAmountTransferred().longValue());
250            }
251            
252            @Test
253            public void testInitializeTransferOnYearEndMaxCarryOver() 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 transfer limit.
257                     * 
258                     * max transfer amount = 10
259                     * leave balance = 16
260                     * max balance = 15
261                     * max carry over = 10
262                     * 
263                     * all excess should be transferrable. 1 unit of time for excess over max balance, 5 units of time for
264                     * excess over max carry over.
265                     * 
266                     */
267                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
272                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(6)).longValue(), bt.getTransferAmount().longValue());
273                    assertEquals("transferOnDemand forfeited amount", (new BigDecimal(0)).longValue(), bt.getForfeitedAmount().longValue());
274                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(3)).longValue(), bt.getAmountTransferred().longValue());
275            }
276            
277    /*      @Test
278            public void testInitializeTransferUnderMaxBalanceOnYearEndMaxCarryOver() 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 transfer 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                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
304                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(4)).longValue(), bt.getTransferAmount().longValue());
305                    assertEquals("transferOnDemand forfeited amount", (new BigDecimal(0)).longValue(), bt.getForfeitedAmount().longValue());
306                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(2)).longValue(), bt.getAmountTransferred().longValue());
307            }*/
308            
309            @Test
310            public void testInitializeTransferOnYearEndMaxCarryOverWithForfeiture() throws Exception {
311                    //max bal limit reached and max annual carry over triggererd.
312                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
317                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(10)).longValue(), bt.getTransferAmount().longValue());
318                    assertEquals("transferOnDemand forfeited amount", (new BigDecimal(12)).longValue(), bt.getForfeitedAmount().longValue());
319                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(5)).longValue(), bt.getAmountTransferred().longValue());
320            }
321            
322            @Test
323            public void testInitializeTransferOnLeaveApproveMaxCarryOver() throws Exception {
324                    BalanceTransfer bt = new BalanceTransfer();
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                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, LA_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
329                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(1)).longValue(), bt.getTransferAmount().longValue());
330                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(0)).longValue(), bt.getForfeitedAmount().longValue());
331                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0.5)).longValue(), bt.getAmountTransferred().longValue());
332            }
333            
334            //
335            // ACTION_AT_MAX_BALANCE = LOSE
336            //
337            @Test
338            public void testInitializeLoseOnDemand() throws Exception {
339                    BalanceTransfer bt = new BalanceTransfer();
340                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
341                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_LOSE);
342                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
343                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, OD_LOSE, aRow.getAccruedBalance(), effectiveDate);
344                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(0)).longValue(), bt.getTransferAmount().longValue());
345                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(1)).longValue(), bt.getForfeitedAmount().longValue());
346                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0)).longValue(), bt.getAmountTransferred().longValue());
347            }
348            
349            @Test
350            public void testInitializeLoseOnYearEnd() throws Exception {
351                    BalanceTransfer bt = new BalanceTransfer();
352                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
353                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_LOSE);
354                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
355                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_LOSE, aRow.getAccruedBalance(), effectiveDate);
356                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(0)).longValue(), bt.getTransferAmount().longValue());
357                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(17)).longValue(), bt.getForfeitedAmount().longValue());
358                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0)).longValue(), bt.getAmountTransferred().longValue());
359            }
360            
361            @Test
362            public void testInitializeLoseOnLeaveApprove() throws Exception {
363                    BalanceTransfer bt = new BalanceTransfer();
364                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
365                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_LOSE);
366                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
367                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, LA_LOSE, aRow.getAccruedBalance(), effectiveDate);
368                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(0)).longValue(), bt.getTransferAmount().longValue());
369                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(17)).longValue(), bt.getForfeitedAmount().longValue());
370                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0)).longValue(), bt.getAmountTransferred().longValue());
371            }
372            
373            @Test
374            public void testInitializeLoseOnDemandMaxCarryOver() throws Exception {
375                    BalanceTransfer bt = new BalanceTransfer();
376                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
377                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_LOSE_MAC);
378                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
379                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, OD_LOSE_MAC, aRow.getAccruedBalance(), effectiveDate);
380                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(0)).longValue(), bt.getTransferAmount().longValue());
381                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(17)).longValue(), bt.getForfeitedAmount().longValue());
382                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0)).longValue(), bt.getAmountTransferred().longValue());
383            }
384            
385            @Test
386            public void testInitializeLoseOnYearEndMaxCarryOver() throws Exception {
387                    BalanceTransfer bt = new BalanceTransfer();
388                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
389                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_LOSE_MAC);
390                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
391                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_LOSE_MAC, aRow.getAccruedBalance(), effectiveDate);
392                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(0)).longValue(), bt.getTransferAmount().longValue());
393                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(22)).longValue(), bt.getForfeitedAmount().longValue());
394                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0)).longValue(), bt.getAmountTransferred().longValue());
395            }
396            
397            @Test
398            public void testInitializeLoseOnLeaveApproveMaxCarryOver() throws Exception {
399                    BalanceTransfer bt = new BalanceTransfer();
400                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
401                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_LOSE_MAC);
402                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
403                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, LA_LOSE_MAC, aRow.getAccruedBalance(), effectiveDate);
404                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(0)).longValue(), bt.getTransferAmount().longValue());
405                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(17)).longValue(), bt.getForfeitedAmount().longValue());
406                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(0)).longValue(), bt.getAmountTransferred().longValue());
407            }
408            
409            @Test
410            public void testInitializeTransferWithOverrides() throws Exception {
411                    BalanceTransfer bt = new BalanceTransfer();
412                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
413                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER_EO);
414                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
415                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_XFER_EO, aRow.getAccruedBalance(), effectiveDate);
416                    assertEquals("transferOnDemand transfer amount", (new BigDecimal(7)).longValue(), bt.getTransferAmount().longValue());
417                    assertEquals("transferOnDemand forfeited amount",(new BigDecimal(20)).longValue(), bt.getForfeitedAmount().longValue());
418                    // max balance transfer conversion factor is undefined for YE_XFER_EO
419                    assertEquals("transferOnDemand amount transferred", (new BigDecimal(7)).longValue(), bt.getAmountTransferred().longValue());
420            }
421            /**
422             * End Use-case testing
423             */
424            
425            @Test
426            public void testTransferNullBalanceTransfer() {
427                    BalanceTransfer balanceTransfer = null;
428                    try {
429                            balanceTransfer = TkServiceLocator.getBalanceTransferService().transfer(balanceTransfer);
430                    } catch (RuntimeException re) {
431                            assertTrue(re.getMessage().contains("did not supply a valid BalanceTransfer object"));
432                    }
433            }
434            
435            @Test
436            public void testTransferWithZeroTransferAmount() throws Exception {
437                    BalanceTransfer bt = new BalanceTransfer();
438                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
439                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_LOSE);
440                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
441                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_LOSE, aRow.getAccruedBalance(), effectiveDate);
442                    bt = TkServiceLocator.getBalanceTransferService().transfer(bt);
443                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getForfeitedLeaveBlockId());
444                    LeaveBlock accruedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getAccruedLeaveBlockId());
445                    LeaveBlock debitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getDebitedLeaveBlockId());
446                    assertEquals("forfeited leave block leave amount incorrect", (new BigDecimal(-17)).longValue(), forfeitedLeaveBlock.getLeaveAmount().longValue());
447                    assertTrue("accrued leave block should not exist",ObjectUtils.isNull(accruedLeaveBlock));
448                    assertTrue("debited leave block should not exist",ObjectUtils.isNull(debitedLeaveBlock));
449            }
450            
451            @Test
452            public void testTransferWithNoAmountTransferred() throws Exception {
453                    BalanceTransfer bt = new BalanceTransfer();
454                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
455                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_LOSE);
456                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
457                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_LOSE, aRow.getAccruedBalance(), effectiveDate);
458                    bt.setAmountTransferred(null);
459                    bt = TkServiceLocator.getBalanceTransferService().transfer(bt);
460                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getForfeitedLeaveBlockId());
461                    LeaveBlock accruedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getAccruedLeaveBlockId());
462                    LeaveBlock debitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getDebitedLeaveBlockId());
463                    assertEquals("forfeited leave block leave amount incorrect",(new BigDecimal(-17)).longValue(), forfeitedLeaveBlock.getLeaveAmount().longValue());
464                    assertTrue("accrued leave block should not exist",ObjectUtils.isNull(accruedLeaveBlock));
465                    assertTrue("debited leave block should not exist",ObjectUtils.isNull(debitedLeaveBlock));       
466            }
467            
468            @Test
469            public void testTransferWithZeroForfeiture() throws Exception {
470                    BalanceTransfer bt = new BalanceTransfer();
471                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
472                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER);
473                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
474                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
475                    bt = TkServiceLocator.getBalanceTransferService().transfer(bt);
476                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getForfeitedLeaveBlockId());
477                    LeaveBlock accruedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getAccruedLeaveBlockId());
478                    LeaveBlock debitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getDebitedLeaveBlockId());
479                    assertEquals("accrued leave block leave amount incorrect", (new BigDecimal(0.5)).longValue(), accruedLeaveBlock.getLeaveAmount().longValue());
480                    assertTrue("forfeited leave block should not exist",ObjectUtils.isNull(forfeitedLeaveBlock));
481                    assertEquals("transfered leave block leave amount incorrect", (new BigDecimal(-1)).longValue(), debitedLeaveBlock.getLeaveAmount().longValue());
482            }
483            
484            @Test
485            public void testTransferWithThreeLeaveBlocks() throws Exception {
486                    BalanceTransfer bt = new BalanceTransfer();
487                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
488                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER);
489                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
490                    bt = TkServiceLocator.getBalanceTransferService().initializeTransfer(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
491                    bt = TkServiceLocator.getBalanceTransferService().transfer(bt);
492                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getForfeitedLeaveBlockId());
493                    LeaveBlock accruedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getAccruedLeaveBlockId());
494                    LeaveBlock debitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(bt.getDebitedLeaveBlockId());
495                    assertEquals("forfeited leave block leave amount incorrect", (new BigDecimal(-7)).longValue(), forfeitedLeaveBlock.getLeaveAmount().longValue());
496                    assertEquals((new BigDecimal(5)).longValue(), accruedLeaveBlock.getLeaveAmount().longValue());
497                    assertEquals((new BigDecimal(-10)).longValue(), debitedLeaveBlock.getLeaveAmount().longValue());
498            }
499            
500            //TODO: write tests for adjusted max balance cases - i.e. FTE < 1, employee override's w/ type MAX_BALANCE
501            
502            @Test
503            public void testGetEligibleTransfersLeaveApprove() throws Exception {
504                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(janEntry, USER_ID);
505                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
506                    assertEquals(5, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
507                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());               List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
508                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE))
509                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
510                            
511                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
512                    for(AccrualCategoryRule aRule : rules) {
513                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
514                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
515                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
516                    }
517            }
518            
519            @Test
520            public void testGetEligibleTransfersYearEnd() throws Exception {
521                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(janEntry, USER_ID);
522                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
523                    assertEquals(5, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
524                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
525                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
526                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
527                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
528                    
529                    // Set should contain an accrual category whose rule's max balance is trumped by an employee override.
530                    // Comparing accrued balance to a rule's defined max balance is insufficient for testing
531                    // whether or not an accrual category is indeed over it's balance limit. Same can be said for FTE-proration.
532                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
533                    for(AccrualCategoryRule aRule : rules) {
534                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
535                            BigDecimal maxBalance = aRule.getMaxBalance();
536                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(USER_ID,
537                                            "testLP",
538                                            row.getAccrualCategory(),
539                                            "MB",
540                                            janEntry.getBeginPeriodDate());
541                            if(ObjectUtils.isNotNull(mbOverride))
542                                    maxBalance = new BigDecimal(mbOverride.getOverrideValue());
543                            assertNotNull("eligible accrual category has no balance limit",maxBalance);
544                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(maxBalance) > 0);
545                    }
546            }
547            
548            @Test
549            public void testGetEligibleTransfersOnDemand() throws Exception {
550                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(janEntry, USER_ID);
551                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
552                    assertEquals(5, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
553                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
554                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
555                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
556                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
557    
558                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
559                    for(AccrualCategoryRule aRule : rules) {
560                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
561                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
562                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
563                    }
564            }
565            
566            @Test
567            public void testGetEligibleTransfersOnYearEndCaseOne() throws Exception {
568                    //calendar entry is not the last calendar entry of the leave plan's calendar year.
569                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(decEntry, USER_ID);
570                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
571                    assertEquals(0, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
572                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
573                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
574                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
575                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
576    
577                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
578                    for(AccrualCategoryRule aRule : rules) {
579                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
580                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
581                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
582                    }
583            }
584            
585            @Test
586            public void testGetEligibleTransfersOnYearEndCaseTwo() throws Exception {
587                    //calendar entry is the last calendar entry of the leave plan's calendar year.
588                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(janEntry, USER_ID);
589                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
590                    assertEquals(5, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
591                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
592                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
593                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
594                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
595    
596                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
597                    for(AccrualCategoryRule aRule : rules) {
598                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
599                            BigDecimal maxBalance = aRule.getMaxBalance();
600                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(USER_ID,
601                                            "testLP",
602                                            row.getAccrualCategory(),
603                                            "MB",
604                                            janEntry.getBeginPeriodDate());
605                            EmployeeOverride macOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(USER_ID,
606                                            "testLP",
607                                            row.getAccrualCategory(),
608                                            "MAC",
609                                            janEntry.getBeginPeriodDate());
610                            if(ObjectUtils.isNotNull(mbOverride) && ObjectUtils.isNotNull(macOverride))
611                                    maxBalance = new BigDecimal(Math.min(mbOverride.getOverrideValue(), macOverride.getOverrideValue()));
612                            else {
613                                    if(ObjectUtils.isNotNull(macOverride))
614                                            maxBalance = new BigDecimal(macOverride.getOverrideValue());
615                                    if(ObjectUtils.isNotNull(mbOverride))
616                                            maxBalance = new BigDecimal(mbOverride.getOverrideValue());
617                            }
618                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(maxBalance));
619                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(maxBalance) > 0);
620                    }
621            }
622            
623            @Test
624            public void testSubmitToWorkflow() {
625                    assertNull(null);
626            }
627            
628            /**
629             * 
630             * TIMESHEET ELIGIBLE TESTS
631             * 
632             */
633            
634            @Test
635            public void testGetEligibleTransfersLeaveApproveForTimesheetCaseOne() throws Exception {
636                    //Timesheet does not contain the leave calendar end period
637                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
638                    midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
639                    midDecTSDEntry = midDecTSD.getCalendarEntry();
640    
641                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(midDecTSDEntry, TS_USER_ID);
642                    //Assert correct number of transfer eligible for frequency
643                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
644    
645                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
646                    //according to their rules. - does not consider FTE.
647                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
648                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE))
649                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
650    
651                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, midDecTSDEntry);
652                    for(AccrualCategoryRule aRule : rules) {
653                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
654                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
655                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
656                    }
657            }
658            
659            @Test
660            public void testGetEligibleTransfersYearEndForTimesheetCaseOne() throws Exception {
661                    //Timesheet does not include the leave calendar end period
662                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
663                    midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
664                    midDecTSDEntry = midDecTSD.getCalendarEntry();
665    
666                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(midDecTSDEntry, TS_USER_ID);
667                    //Assert correct number of transfer eligible for frequency
668                    assertEquals(0, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
669                    
670                    /**
671                     * No eligible transfers to test balance limit.
672                     */
673    /*              //Assert that the accrual categories returned by BT service are in fact over their balance limit,
674                    //according to their rules.
675                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
676                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
677                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
678                            
679                    // Set should contain an accrual category whose rule's max balance is trumped by an employee override.
680                    // Comparing accrued balance to a rule's defined max balance is insufficient for testing
681                    // whether or not an accrual category is indeed over it's balance limit. Same can be said for FTE-proration.
682                    // However, in this case, using an employee override will 
683                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, midDecTSDEntry);
684                    for(AccrualCategoryRule aRule : rules) {
685                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
686                            BigDecimal maxBalance = aRule.getMaxBalance();
687                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
688                                            "testLP",
689                                            row.getAccrualCategory(),
690                                            "MB",
691                                            janEntry.getBeginPeriodDate());
692                            if(ObjectUtils.isNotNull(mbOverride))
693                                    maxBalance = new BigDecimal(mbOverride.getOverrideValue());
694                            //Don't care about employee override existence, this is not the leave plan's roll-over period.
695                            assertNotNull("eligible accrual category has no balance limit",maxBalance);
696                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(maxBalance) > 0);
697                    }*/
698            }
699            
700            @Test
701            public void testGetEligibleTransfersOnDemandForTimesheetCaseOne() throws Exception {
702                    //Timesheet does not include the leave calendar end period
703                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
704                    midDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_MID_DEC_PERIOD_ID);
705                    midDecTSDEntry = midDecTSD.getCalendarEntry();
706    
707                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(midDecTSDEntry, TS_USER_ID);
708                    //Assert correct number of transfer eligible for frequency
709                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
710    
711                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
712                    //according to their rules. - does not consider FTE.
713                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
714                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
715                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
716    
717                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, midDecTSDEntry);
718                    for(AccrualCategoryRule aRule : rules) {
719                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
720                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
721                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
722                    }
723            }
724            
725            @Test
726            public void testGetEligibleTransfersLeaveApproveForTimesheetCaseTwo() throws Exception {
727                    //Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
728                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
729                    endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
730                    endDecTSDEntry = endDecTSD.getCalendarEntry();
731    
732                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(endDecTSDEntry, TS_USER_ID);
733                    //Assert correct number of transfer eligible for frequency
734                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE).size());
735                    
736                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
737                    //according to their rules. - does not consider FTE.
738                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
739                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.LEAVE_APPROVE))
740                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
741    
742                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, endDecTSDEntry);
743                    for(AccrualCategoryRule aRule : rules) {
744                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
745                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
746                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
747                    }
748            }
749            
750            @Test
751            public void testGetEligibleTransfersYearEndForTimesheetCaseTwo() throws Exception {
752                    //Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
753                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
754                    endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
755                    endDecTSDEntry = endDecTSD.getCalendarEntry();
756    
757                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(endDecTSDEntry, TS_USER_ID);
758                    //Assert correct number of transfer eligible for frequency
759                    assertEquals(0, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
760                    
761                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
762                    //according to their rules. - does not consider FTE.
763                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
764                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END))
765                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
766    
767                    // Set should contain an accrual category whose rule's max balance is trumped by an employee override.
768                    // Comparing accrued balance to a rule's defined max balance is insufficient for testing
769                    // whether or not an accrual category is indeed over it's balance limit. Same can be said for FTE-proration.
770                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID, endDecTSDEntry);
771                    for(AccrualCategoryRule aRule : rules) {
772                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
773                            BigDecimal maxBalance = aRule.getMaxBalance();
774                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
775                                            "testLP",
776                                            row.getAccrualCategory(),
777                                            "MB",
778                                            janEntry.getBeginPeriodDate());
779                            if(ObjectUtils.isNotNull(mbOverride))
780                                    maxBalance = new BigDecimal(mbOverride.getOverrideValue());
781                            assertNotNull("eligible accrual category has no balance limit",maxBalance);
782                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(maxBalance) > 0);
783                    }
784            }
785            
786            @Test
787            public void testGetEligibleTransfersOnDemandForTimesheetCaseTwo() throws Exception {
788                    //Timesheet includes the leave calendar end period, but does not include the leave plan's start date.
789                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
790                    endDecTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_DEC_PERIOD_ID);
791                    endDecTSDEntry = endDecTSD.getCalendarEntry();
792    
793    
794                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(endDecTSDEntry, TS_USER_ID);
795                    //Assert correct number of transfer eligible for frequency
796                    assertEquals(4, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND).size());
797                    
798                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
799                    //according to their rules. - does not consider FTE.
800                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
801                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.ON_DEMAND))
802                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
803    
804                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID,endDecTSDEntry);
805                    for(AccrualCategoryRule aRule : rules) {
806                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
807                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(aRule.getMaxBalance()));
808                            assertTrue("accrual category not eligible for transfer",row.getAccruedBalance().compareTo(aRule.getMaxBalance()) > 0);
809                    }
810            }
811            
812            @Test
813            public void testGetEligibleTransfersYearEndForTimesheetCaseThree() throws Exception {
814                    //Timesheet includes the leave calendar end period, which is the leave plan's roll-over date.
815                    TkServiceLocator.getAccrualService().runAccrual(TS_USER_ID,TK_FROM,TK_TO,true,TS_USER_ID);
816                    endJanTSD = TkServiceLocator.getTimesheetService().getTimesheetDocument(TSD_END_JAN_PERIOD_ID);
817                    endJanTSDEntry = endJanTSD.getCalendarEntry();
818    
819                    Map<String, ArrayList<String>> eligibleTransfers = TkServiceLocator.getBalanceTransferService().getEligibleTransfers(endJanTSDEntry, TS_USER_ID);
820                    //Assert correct number of transfer eligible for frequency
821                    assertEquals(3, eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END).size());
822                    
823                    //Assert that the accrual categories returned by BT service are in fact over their balance limit,
824                    //according to their rules. - does not consider FTE.
825                    List<AccrualCategoryRule> rules = new ArrayList<AccrualCategoryRule>();
826                    for(String eligibleTransfer : eligibleTransfers.get(LMConstants.MAX_BAL_ACTION_FREQ.YEAR_END)) {
827                            rules.add(TkServiceLocator.getAccrualCategoryRuleService().getAccrualCategoryRule(eligibleTransfer));
828            }
829    
830                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TS_USER_ID,endJanTSDEntry);
831                    for(AccrualCategoryRule aRule : rules) {
832                            LeaveSummaryRow row = summary.getLeaveSummaryRowForAccrualCategory(aRule.getLmAccrualCategoryId());
833                            BigDecimal maxBalance = aRule.getMaxBalance();
834                            EmployeeOverride mbOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
835                                            "testLP",
836                                            row.getAccrualCategory(),
837                                            "MB",
838                                            janEntry.getBeginPeriodDate());
839                            EmployeeOverride macOverride = TkServiceLocator.getEmployeeOverrideService().getEmployeeOverride(TS_USER_ID,
840                                            "testLP",
841                                            row.getAccrualCategory(),
842                                            "MAC",
843                                            janEntry.getBeginPeriodDate());
844                            if(ObjectUtils.isNotNull(mbOverride) && ObjectUtils.isNotNull(macOverride)) {
845                                    maxBalance = new BigDecimal(Math.min(mbOverride.getOverrideValue(), macOverride.getOverrideValue()));
846                } else {
847                                    if(ObjectUtils.isNotNull(macOverride)) {
848                                            maxBalance = new BigDecimal(macOverride.getOverrideValue());
849                    }
850                                    if(ObjectUtils.isNotNull(mbOverride)) {
851                                            maxBalance = new BigDecimal(mbOverride.getOverrideValue());
852                    }
853                            }
854                            assertNotNull("eligible accrual category has no balance limit",ObjectUtils.isNotNull(maxBalance));
855                            assertTrue("accrual category " + aRule.getLmAccrualCategoryId() + " not eligible for transfer",row.getAccruedBalance().compareTo(maxBalance) > 0);
856                    }
857            }
858    }