001    /**
002     * Copyright 2004-2014 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.time.overtime.daily.rule.service;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    import java.util.HashMap;
021    import java.util.List;
022    
023    import org.joda.time.DateTime;
024    import org.junit.Assert;
025    import org.junit.Test;
026    import org.kuali.hr.KPMEWebTestCase;
027    import org.kuali.kpme.core.FunctionalTest;
028    import org.kuali.kpme.core.calendar.entry.CalendarEntry;
029    import org.kuali.kpme.core.service.HrServiceLocator;
030    import org.kuali.kpme.core.util.TKUtils;
031    import org.kuali.kpme.tklm.time.rules.overtime.daily.DailyOvertimeRule;
032    import org.kuali.kpme.tklm.time.rules.overtime.daily.service.DailyOvertimeRuleService;
033    import org.kuali.kpme.tklm.time.service.TkServiceLocator;
034    import org.kuali.kpme.tklm.time.timeblock.TimeBlock;
035    import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
036    import org.kuali.kpme.tklm.time.util.TkTimeBlockAggregate;
037    import org.kuali.kpme.tklm.utils.TkTestUtils;
038    
039    @FunctionalTest
040    public class DailyOvertimeRuleServiceTest extends KPMEWebTestCase {
041    
042            public static final String USER_PRINCIPAL_ID = "admin";
043            private DateTime JAN_AS_OF_DATE = new DateTime(2010, 1, 1, 0, 0, 0, 0, TKUtils.getSystemDateTimeZone());
044    
045    
046            private void createDailyOvertimeRule(String fromEarnGroup, String earnCode, String location, String paytype, String dept, Long workArea, Long task, BigDecimal minHours, BigDecimal maxGap, String overtimePref) {
047                    DailyOvertimeRuleService service = TkServiceLocator.getDailyOvertimeRuleService();
048                    DailyOvertimeRule rule = new DailyOvertimeRule();
049    
050                    rule.setEffectiveLocalDate(JAN_AS_OF_DATE.toLocalDate());
051                    rule.setFromEarnGroup(fromEarnGroup);
052                    rule.setEarnCode(earnCode);
053                    rule.setLocation(location);
054                    rule.setPaytype(paytype);
055                    rule.setDept(dept);
056                    rule.setWorkArea(workArea);
057                    rule.setMaxGap(maxGap);
058                    rule.setMinHours(minHours);
059                    rule.setActive(true);
060    
061                    service.saveOrUpdate(rule);
062            }
063    
064    
065            @SuppressWarnings("serial")
066            @Test
067            public void testDailyOvertimeGapExceeded() throws Exception {
068                    Long jobNumber = 30L;
069                    Long workArea = 30L;
070                    Long task = 30L;
071                    createDailyOvertimeRule("REG", "OVT", "SD1", "BW", "TEST-DEPT", workArea,
072                                    task, new BigDecimal(8), new BigDecimal("0.10"), null);
073                    // Create Time Blocks (2 days, 2 blocks on each day, 15 minute gap between blocks, 4 hours first block, 5 the next.
074                    // Should end up with 2 hours total OVT.
075                    DateTime start = new DateTime(2010, 3, 29, 14, 0, 0, 0, TKUtils.getSystemDateTimeZone());
076                    List<TimeBlock> blocks = new ArrayList<TimeBlock>();
077                    CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start);
078                    blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 2, new BigDecimal("4"), "REG", jobNumber, workArea, task));
079                    blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(4).plusMinutes(15), 2, new BigDecimal("5"), "REG", jobNumber, workArea, task));
080                    TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry);
081    
082                    // Verify pre-Rule Run
083                    TkTestUtils.verifyAggregateHourSums("Pre-Check", new HashMap<String,BigDecimal>() {{put("OVT", BigDecimal.ZERO);put("REG", new BigDecimal(18));}},aggregate,2);
084    
085                    // Run Rule
086                    TimesheetDocument tdoc = TkTestUtils.populateBlankTimesheetDocument(start, "admin");
087                    tdoc.setTimeBlocks(blocks);
088                    TkServiceLocator.getDailyOvertimeRuleService().processDailyOvertimeRules(tdoc, aggregate);
089    
090                    // Verify post-Rule Run
091                    TkTestUtils.verifyAggregateHourSums("Post Rules Check", new HashMap<String,BigDecimal>() {{put("OVT", new BigDecimal(0));put("REG", new BigDecimal(18));}},aggregate,2);
092            }
093    
094    
095            @SuppressWarnings("serial")
096            @Test
097            public void testDailyOvertimeSimpleCase() throws Exception {
098                    Long jobNumber = 30L;
099                    Long workArea = 30L;
100                    Long task = 30L;
101                    createDailyOvertimeRule("REG", "OVT", "SD1", "BW", "TEST-DEPT", workArea,
102                                    task, new BigDecimal(8), new BigDecimal("15.0"), null);
103    
104                    // Create Time Blocks (2 days, 2 blocks on each day, 15 minute gap between blocks, 4 hours first block, 5 the next.
105                    // Should end up with 2 hours total OVT.
106                    DateTime start = new DateTime(2010, 3, 29, 14, 0, 0, 0, TKUtils.getSystemDateTimeZone());
107                    List<TimeBlock> blocks = new ArrayList<TimeBlock>();
108                    CalendarEntry payCalendarEntry = HrServiceLocator.getCalendarEntryService().getCurrentCalendarDates("admin", start);
109                    blocks.addAll(TkTestUtils.createUniformTimeBlocks(start, 2, new BigDecimal("4"), "REG", jobNumber, workArea, task));
110                    blocks.addAll(TkTestUtils.createUniformTimeBlocks(start.plusHours(4).plusMinutes(15), 2, new BigDecimal("5"), "REG", jobNumber, workArea, task));
111                    TkTimeBlockAggregate aggregate = new TkTimeBlockAggregate(blocks, payCalendarEntry);
112    
113                    // Verify pre-Rule Run
114                    TkTestUtils.verifyAggregateHourSums("Pre-Check", new HashMap<String,BigDecimal>() {{put("OVT", BigDecimal.ZERO);put("REG", new BigDecimal(18));}},aggregate,2);
115    
116                    // Run Rule
117                    TimesheetDocument tdoc = TkTestUtils.populateBlankTimesheetDocument(start, "admin");
118                    tdoc.setTimeBlocks(blocks);
119                    TkServiceLocator.getDailyOvertimeRuleService().processDailyOvertimeRules(tdoc, aggregate);
120    
121                    // Verify post-Rule Run
122                    TkTestUtils.verifyAggregateHourSums("Post Rules Check", new HashMap<String,BigDecimal>() {{put("OVT", new BigDecimal(2));put("REG", new BigDecimal(16));}},aggregate,2);
123            }
124    
125            @Test
126            public void testRuleCreationAndRetrieval() throws Exception {
127                    Long workArea = 0L;
128                    Long task = 30L;
129                    createDailyOvertimeRule("REG", "OVT", "SD1", "BW", "TEST-DEPT", workArea,
130                                    task, new BigDecimal(8), new BigDecimal("0.25"), null);
131                    DailyOvertimeRule rule = TkServiceLocator.getDailyOvertimeRuleService().getDailyOvertimeRule("SD1", "BW", "TEST-DEPT", workArea, JAN_AS_OF_DATE.toLocalDate());
132                    Assert.assertNotNull("Rule not created.", rule);
133            }
134            
135            @Test
136            public void testSearchDailyOvertimeRules() throws Exception {
137                    createDailyOvertimeRule("REG", "OVT", "SD1", "BL", "TEST-DEPT", 30L, 30L, new BigDecimal(8), new BigDecimal("0.10"), null);
138                    createDailyOvertimeRule("REG", "OVT", "SD1", "BL", "TEST-DEPT5", 5555L, 30L, new BigDecimal(8), new BigDecimal("0.10"), null);
139                    
140                    List<DailyOvertimeRule> allResults = TkServiceLocator.getDailyOvertimeRuleService().getDailyOvertimeRules("admin", null, null, null, null, null, "Y", "N");
141                    Assert.assertEquals("Search returned the wrong number of results.", 2, allResults.size());
142                    
143                    List<DailyOvertimeRule> restrictedResults = TkServiceLocator.getDailyOvertimeRuleService().getDailyOvertimeRules("fran", null, null, null, null, null, "Y", "N");
144                    Assert.assertEquals("Search returned the wrong number of results.", 0, restrictedResults.size());
145            }
146    
147    }