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    import java.util.Set;
027    
028    import org.apache.commons.lang.time.DateUtils;
029    import org.junit.After;
030    import org.junit.Before;
031    import org.junit.Test;
032    import org.kuali.hr.lm.LMConstants;
033    import org.kuali.hr.lm.accrual.AccrualCategoryRule;
034    import org.kuali.hr.lm.leavepayout.LeavePayout;
035    import org.kuali.hr.lm.employeeoverride.EmployeeOverride;
036    import org.kuali.hr.lm.leaveSummary.LeaveSummary;
037    import org.kuali.hr.lm.leaveSummary.LeaveSummaryRow;
038    import org.kuali.hr.lm.leaveblock.LeaveBlock;
039    import org.kuali.hr.lm.leavecalendar.LeaveCalendarDocument;
040    import org.kuali.hr.test.KPMETestCase;
041    import org.kuali.hr.time.calendar.CalendarEntries;
042    import org.kuali.hr.time.service.base.TkServiceLocator;
043    import org.kuali.hr.time.timesheet.TimesheetDocument;
044    import org.kuali.hr.time.util.TKUtils;
045    import org.kuali.rice.krad.util.ObjectUtils;
046    
047    public class LeavePayoutServiceTest extends KPMETestCase {
048    
049            /**
050             * Leave Calendar Document Test data
051             */
052            private final String USER_ID = "testUser1";
053            
054            private LeaveCalendarDocument janLCD;
055            private CalendarEntries janEntry;
056            private LeaveCalendarDocument decLCD;
057            private CalendarEntries decEntry;
058            
059            private Date janStart;
060            private Date janEnd;
061            private Date decStart;
062            private Date decEnd;
063            
064            private final String JAN_ID = "5001";
065            private final String DEC_ID = "5000";
066            
067            /**
068             * Timesheet Document Test Data;
069             */
070            
071            private final String TS_USER_ID = "testUser2";  
072            
073            private TimesheetDocument endJanTSD;
074            private CalendarEntries endJanTSDEntry;
075            private TimesheetDocument midJanTSD;
076            private CalendarEntries midJanTSDEntry;
077            private TimesheetDocument endDecTSD;
078            private CalendarEntries endDecTSDEntry;
079            private TimesheetDocument midDecTSD;
080            private CalendarEntries midDecTSDEntry;
081            
082            private Date midJanStart;
083            private Date midJanEnd;
084            private Date endDecStart;
085            private Date endDecEnd;
086            private Date midDecStart;
087            private Date midDecEnd;
088            
089            private final String TSD_MID_DEC_PERIOD_ID = "5000";
090            private final String TSD_END_DEC_PERIOD_ID = "5001";
091            private final String TSD_MID_JAN_PERIOD_ID = "5002";
092            private final String TSD_END_JAN_PERIOD_ID = "5003";
093    
094            /**
095             *  Common data
096             */
097            
098            private final String OD_XFER = "5000";
099            private final String YE_XFER = "5001";
100            private final String LA_XFER = "5002";
101            private final String OD_XFER_MAC = "5003";
102            private final String YE_XFER_MAC = "5004";
103            private final String LA_XFER_MAC = "5005";
104            private final String OD_LOSE = "5006";
105            private final String YE_LOSE = "5007";
106            private final String LA_LOSE = "5008";
107            private final String OD_LOSE_MAC = "5009";
108            private final String YE_LOSE_MAC = "5010";
109            private final String LA_LOSE_MAC = "5011";
110            private final String YE_XFER_EO = "5012";
111            private final java.sql.Date LM_FROM = TKUtils.formatDateString("11/01/2012");
112            private final java.sql.Date LM_TO = TKUtils.formatDateString("02/01/2013");
113            private final java.sql.Date TK_FROM = TKUtils.formatDateString("11/01/2011");
114            private final java.sql.Date TK_TO = TKUtils.formatDateString("02/01/2012");
115            
116            @Before
117            public void setUp() throws Exception {
118                    super.setUp();
119                    TkServiceLocator.getAccrualService().runAccrual(USER_ID,LM_FROM,LM_TO,true,USER_ID);
120                    janLCD = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(JAN_ID);
121                    janEntry = janLCD.getCalendarEntry();
122                    janStart = janEntry.getBeginPeriodDate();
123                    janEnd = janEntry.getEndPeriodDate();
124                    decLCD = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(DEC_ID);
125                    decEntry = decLCD.getCalendarEntry();
126                    decStart = decEntry.getBeginPeriodDate();
127                    decEnd = decEntry.getEndPeriodDate();
128            }
129            
130            @After
131            public void tearDown() throws Exception {
132                    super.tearDown();
133            }
134            
135            /*****************************
136             * Use-case specific testing *
137             ****************************/
138            
139            //
140            // ACTION_AT_MAX_BALANCE = TRANSFER
141            //
142            
143            @Test
144            public void testInitializePayoutNullAccrualRule() throws Exception {
145                    LeavePayout lp = new LeavePayout();
146    
147                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
148                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, null, BigDecimal.ZERO, effectiveDate);
149                    assertNull(lp);
150            }
151            
152            @Test
153            public void testInitializePayoutNullLeaveSummary() throws Exception {
154                    LeavePayout lp = new LeavePayout();
155    
156                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, null, TKUtils.getCurrentDate());
157                    assertNull(lp);
158            }
159            
160            @Test
161            public void testInitializePayoutNullAccrualRuleNullLeaveSummary() {
162                    LeavePayout lp = new LeavePayout();
163                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, null, null, TKUtils.getCurrentDate());
164                    assertNull(lp);
165            }
166            
167            @Test
168            public void testInitializePayoutOnDemand() throws Exception {
169                    LeavePayout lp = new LeavePayout();
170                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
171                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER);
172                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
173                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
174                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
175                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
176                    ////assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
177            }
178            
179            @Test
180            public void testInitializePayoutOnDemandWithForfeiture() throws Exception {
181                    LeavePayout lp = new LeavePayout();
182                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
183                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER);
184                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
185                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
186                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
187                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(7)).longValue(), lp.getForfeitedAmount().longValue());
188                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
189            }
190            
191            @Test
192            public void testInitializePayoutOnYearEnd() throws Exception {
193                    LeavePayout lp = new LeavePayout();
194                    TkServiceLocator.getLeaveBlockService().deleteLeaveBlocksForDocumentId(DEC_ID);
195                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
196                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER);
197                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
198                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
199                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
200                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
201                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
202            }
203            
204            @Test
205            public void testInitializePayoutOnYearEndWithForfeiture() throws Exception {
206                    LeavePayout lp = new LeavePayout();
207                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
208                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER);
209                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
210                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
211                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
212                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(7)).longValue(), lp.getForfeitedAmount().longValue());
213                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
214            }
215            
216            @Test
217            public void testInitializePayoutOnLeaveApprove() throws Exception {
218                    LeavePayout lp = new LeavePayout();
219                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
220                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_XFER);
221                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
222                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, LA_XFER, aRow.getAccruedBalance(), effectiveDate);
223                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
224                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
225                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
226            }
227            
228            @Test
229            public void testInitializePayoutOnLeaveApproveWithForfeiture() throws Exception {
230                    LeavePayout lp = new LeavePayout();
231                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
232                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_XFER);
233                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
234                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, LA_XFER, aRow.getAccruedBalance(), effectiveDate);
235                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
236                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(7)).longValue(), lp.getForfeitedAmount().longValue());
237                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
238            }
239            
240            @Test
241            public void testInitializePayoutOnDemandMaxCarryOver() throws Exception {
242                    //N/A - Max Carry Over on Year End payouts.
243                    LeavePayout lp = new LeavePayout();
244                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
245                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER_MAC);
246                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
247                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
248                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
249                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
250                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
251            }
252            
253            @Test
254            public void testInitializePayoutOnYearEndMaxCarryOver() throws Exception {
255                    /**
256                     * decEntry is not the last calendar entry in the leave plan. Want to check amounts for this action & action frequency
257                     * without exceeding the payout limit.
258                     * 
259                     * max payout amount = 10
260                     * leave balance = 16
261                     * max balance = 15
262                     * max carry over = 10
263                     * 
264                     * all excess should be payoutrable. 1 unit of time for excess over max balance, 5 units of time for
265                     * excess over max carry over.
266                     * 
267                     */
268                    LeavePayout lp = new LeavePayout();
269                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
270                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER_MAC);
271                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
272                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
273                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(6)).longValue(), lp.getPayoutAmount().longValue());
274                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
275                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(3)).longValue(), lp.getAmountPayoutred().longValue());
276            }
277            
278    /*      @Test
279            public void testInitializePayoutUnderMaxBalanceOnYearEndMaxCarryOver() throws Exception {
280                    //Create a leave block that will bring the available balance for january down to 14.
281                    //this balance would be under the max available balance (15), but over the max annual carry over amount.
282                    //i.o.w., this payout would not due to max balance limit, but max annual carry over.
283                    //could also simply change the accrual amount.
284                    LeaveBlock usage = new LeaveBlock();
285                    usage.setAccrualCategory(YE_XFER_MAC);
286                    usage.setLeaveDate(new java.sql.Date(DateUtils.addDays(janStart,5).getTime()));
287                    usage.setLeaveAmount(new BigDecimal(-18));
288                    usage.setPrincipalId(USER_ID);
289                    usage.setAccrualGenerated(false);
290                    usage.setRequestStatus(LMConstants.REQUEST_STATUS.APPROVED);
291                    usage.setDocumentId(janLCD.getDocumentId());
292                    usage.setLmLeaveBlockId("99999");
293                    usage.setEarnCode("EC5");
294                    usage.setBlockId(0L);
295                    usage.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR);
296                    List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>();
297                    leaveBlocks.add(usage);
298                    TkServiceLocator.getLeaveBlockService().saveLeaveBlocks(leaveBlocks);
299                    
300                    LeavePayout lp = new LeavePayout();
301                    janLCD = TkServiceLocator.getLeaveCalendarService().getLeaveCalendarDocument(JAN_ID);
302                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janLCD.getCalendarEntry());
303                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
304                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
305                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(4)).longValue(), lp.getPayoutAmount().longValue());
306                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
307                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(2)).longValue(), lp.getAmountPayoutred().longValue());
308            }*/
309            
310            @Test
311            public void testInitializePayoutOnYearEndMaxCarryOverWithForfeiture() throws Exception {
312                    //max bal limit reached and max annual carry over triggererd.
313                    LeavePayout lp = new LeavePayout();
314                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
315                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER_MAC);
316                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
317                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
318                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(10)).longValue(), lp.getPayoutAmount().longValue());
319                    assertEquals("payoutOnDemand forfeited amount", (new BigDecimal(12)).longValue(), lp.getForfeitedAmount().longValue());
320                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(5)).longValue(), lp.getAmountPayoutred().longValue());
321            }
322            
323            @Test
324            public void testInitializePayoutOnLeaveApproveMaxCarryOver() throws Exception {
325                    LeavePayout lp = new LeavePayout();
326                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
327                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(LA_XFER_MAC);
328                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
329                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, LA_XFER_MAC, aRow.getAccruedBalance(), effectiveDate);
330                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(1)).longValue(), lp.getPayoutAmount().longValue());
331                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(0)).longValue(), lp.getForfeitedAmount().longValue());
332                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(0.5)).longValue(), lp.getAmountPayoutred().longValue());
333            }
334            
335            @Test
336            public void testInitializePayoutWithOverrides() throws Exception {
337                    LeavePayout lp = new LeavePayout();
338                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
339                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER_EO);
340                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
341                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER_EO, aRow.getAccruedBalance(), effectiveDate);
342                    assertEquals("payoutOnDemand payout amount", (new BigDecimal(7)).longValue(), lp.getPayoutAmount().longValue());
343                    assertEquals("payoutOnDemand forfeited amount",(new BigDecimal(20)).longValue(), lp.getForfeitedAmount().longValue());
344                    // max balance payout conversion factor is undefined for YE_XFER_EO
345                    //assertEquals("payoutOnDemand amount payoutred", (new BigDecimal(7)).longValue(), lp.getAmountPayoutred().longValue());
346            }
347            /**
348             * End Use-case testing
349             */
350            
351            @Test
352            public void testPayoutNullLeavePayout() {
353                    LeavePayout LeavePayout = null;
354                    try {
355                            LeavePayout = TkServiceLocator.getLeavePayoutService().payout(LeavePayout);
356                    } catch (RuntimeException re) {
357                            assertTrue(re.getMessage().contains("did not supply a valid LeavePayout object"));
358                    }
359            }
360            
361            @Test
362            public void testPayoutWithZeroPayoutAmount() throws Exception {
363                    LeavePayout lp = new LeavePayout();
364                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
365                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_LOSE);
366                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
367                    //lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_LOSE, aRow.getAccruedBalance(), effectiveDate);
368                    lp.setPayoutAmount(BigDecimal.ZERO);
369                    lp = TkServiceLocator.getLeavePayoutService().payout(lp);
370                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getForfeitedLeaveBlockId());
371                    LeaveBlock payoutLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutLeaveBlockId());
372                    LeaveBlock payoutFromLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutFromLeaveBlockId());
373                    assertTrue("forfeited leave block should not exist", ObjectUtils.isNull(forfeitedLeaveBlock));
374                    assertTrue("accrued leave block should not exist",ObjectUtils.isNull(payoutLeaveBlock));
375                    assertTrue("debited leave block should not exist",ObjectUtils.isNull(payoutFromLeaveBlock));
376            }
377            
378            @Test
379            public void testPayoutWithZeroForfeiture() throws Exception {
380                    LeavePayout lp = new LeavePayout();
381                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, decEntry);
382                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(OD_XFER);
383                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(decStart,3).getTime());
384                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, OD_XFER, aRow.getAccruedBalance(), effectiveDate);
385                    lp = TkServiceLocator.getLeavePayoutService().payout(lp);
386                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getForfeitedLeaveBlockId());
387                    LeaveBlock payoutLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutLeaveBlockId());
388                    LeaveBlock payoutFromLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutFromLeaveBlockId());
389                    assertEquals("accrued leave block leave amount incorrect", (new BigDecimal(1)).longValue(), payoutLeaveBlock.getLeaveAmount().longValue());
390                    assertTrue("forfeited leave block should not exist",ObjectUtils.isNull(forfeitedLeaveBlock));
391                    assertEquals("payouted leave block leave amount incorrect", (new BigDecimal(-1)).longValue(), payoutFromLeaveBlock.getLeaveAmount().longValue());
392            }
393            
394            @Test
395            public void testPayoutWithThreeLeaveBlocks() throws Exception {
396                    LeavePayout lp = new LeavePayout();
397                    LeaveSummary summary = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(USER_ID, janEntry);
398                    LeaveSummaryRow aRow = summary.getLeaveSummaryRowForAccrualCategory(YE_XFER);
399                    java.sql.Date effectiveDate = new java.sql.Date(DateUtils.addDays(janStart,3).getTime());
400                    lp = TkServiceLocator.getLeavePayoutService().initializePayout(USER_ID, YE_XFER, aRow.getAccruedBalance(), effectiveDate);
401                    lp = TkServiceLocator.getLeavePayoutService().payout(lp);
402                    LeaveBlock forfeitedLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getForfeitedLeaveBlockId());
403                    LeaveBlock payoutLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutLeaveBlockId());
404                    LeaveBlock payoutFromLeaveBlock = TkServiceLocator.getLeaveBlockService().getLeaveBlock(lp.getPayoutFromLeaveBlockId());
405                    assertEquals("forfeited leave block leave amount incorrect", (new BigDecimal(-7)).longValue(), forfeitedLeaveBlock.getLeaveAmount().longValue());
406                    assertEquals((new BigDecimal(10)).longValue(), payoutLeaveBlock.getLeaveAmount().longValue());
407                    assertEquals((new BigDecimal(-10)).longValue(), payoutFromLeaveBlock.getLeaveAmount().longValue());
408            }
409            
410            //TODO: write tests for adjusted max balance cases - i.e. FTE < 1, employee override's w/ type MAX_BALANCE
411            
412            @Test
413            public void testSubmitToWorkflow() {
414                    assertNull(null);
415            }
416    
417    }