/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.fp.document.service; import java.math.BigDecimal; import java.sql.Date; import java.sql.Timestamp; import java.util.Collection; import org.joda.time.DateTime; import org.kuali.kfs.fp.businessobject.TravelMileageRate; import org.kuali.kfs.fp.document.DisbursementVoucherDocument; import org.kuali.kfs.fp.document.dataaccess.TravelMileageRateDao; import org.kuali.kfs.sys.ConfigureContext; import org.kuali.kfs.sys.context.KualiTestBase; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.dataaccess.UnitTestSqlDao; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.krad.service.BusinessObjectService; /** * This class tests the DisbursementVoucherTravel service. */ @ConfigureContext public class DisbursementVoucherTravelServiceTest extends KualiTestBase { protected DisbursementVoucherDocument dvDocument; protected TravelMileageRateDao rateDao; protected UnitTestSqlDao sqlDao; protected DateTimeService dateTimeService; protected BusinessObjectService businessObjectService; @Override protected void setUp() throws Exception { super.setUp(); sqlDao = SpringContext.getBean(UnitTestSqlDao.class); rateDao = SpringContext.getBean(TravelMileageRateDao.class); dvDocument = new DisbursementVoucherDocument(); dateTimeService = SpringContext.getBean(DateTimeService.class); businessObjectService = SpringContext.getBean(BusinessObjectService.class); setupMileageRates(); } /** * Test calculation of per diem. * * @throws Exception */ public void testCalculatePerDiem() throws Exception { dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 12:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/22/2006 12:01 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(12.50)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 10:00 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/22/2006 05:00 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), KualiDecimal.ZERO); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 12:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/23/2006 12:01 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(22.50)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 12:01 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/23/2006 11:59 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(25.00)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 11:59 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/23/2006 11:59 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(22.50)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 12:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/23/2006 12:01 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(30.00)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("12/28/2005 12:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("01/01/2006 12:01 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(42.50)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 01:00 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/23/2006 12:01 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(17.50)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 06:00 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/23/2006 12:01 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(15.00)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("12/28/2005 12:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("01/01/2006 06:01 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(45.00)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("12/28/2005 12:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("01/01/2006 11:59 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(50.00)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 12:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/21/2006 11:59 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(7.50)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 03:00 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/21/2006 06:00 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), KualiDecimal.ZERO); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 05:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/21/2006 05:00 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), KualiDecimal.ZERO); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 04:59 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/21/2006 05:00 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(5.00)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 01:00 AM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/21/2006 07:01 PM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(50), new KualiDecimal(37.50)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 11:59 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/22/2006 06:00 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), KualiDecimal.ZERO); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 06:01 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/22/2006 05:59 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(5.00)); dvDocument.getDvNonEmployeeTravel().setPerDiemStartDateTime("04/21/2006 03:00 PM"); dvDocument.getDvNonEmployeeTravel().setPerDiemEndDateTime("04/22/2006 06:01 AM"); runPerDiemTest(dvDocument.getDvNonEmployeeTravel().getDvPerdiemStartDttmStamp(), dvDocument.getDvNonEmployeeTravel().getDvPerdiemEndDttmStamp(), new KualiDecimal(10), new KualiDecimal(10)); } protected void runPerDiemTest(Timestamp startTime, Timestamp endTime, KualiDecimal perDiemRate, KualiDecimal expectedPerDiemAmount) { assertEquals("Per diem amount not correct ", expectedPerDiemAmount, SpringContext.getBean(DisbursementVoucherTravelService.class).calculatePerDiemAmount(startTime, endTime, perDiemRate)); } /** * Tests the calculation of travel mileage amount. This is testing against the mileage rates defined currently, we need to find * a way to fix this for when they change: 0-500 0.375 500-3000 0.18 3000 - 0 * * @throws Exception */ public void testCalculateMileageAmount() throws Exception { Timestamp effectiveDate = new Timestamp( DateTime.parse("2004-01-01").toDateMidnight().toDate().getTime() ); runMileageAmountTest(new Integer(0), KualiDecimal.ZERO, effectiveDate); runMileageAmountTest(new Integer(1), new KualiDecimal(.38), effectiveDate); runMileageAmountTest(new Integer(10), new KualiDecimal(3.75), effectiveDate); runMileageAmountTest(new Integer(15), new KualiDecimal(5.63), effectiveDate); runMileageAmountTest(new Integer(100), new KualiDecimal(37.5), effectiveDate); runMileageAmountTest(new Integer(200), new KualiDecimal(75.00), effectiveDate); runMileageAmountTest(new Integer(380), new KualiDecimal(142.5), effectiveDate); runMileageAmountTest(new Integer(500), new KualiDecimal(187.5), effectiveDate); runMileageAmountTest(new Integer(501), new KualiDecimal(187.68), effectiveDate); runMileageAmountTest(new Integer(600), new KualiDecimal(205.5), effectiveDate); runMileageAmountTest(new Integer(2500), new KualiDecimal(547.5), effectiveDate); runMileageAmountTest(new Integer(3000), new KualiDecimal(637.5), effectiveDate); runMileageAmountTest(new Integer(3001), new KualiDecimal(637.5), effectiveDate); runMileageAmountTest(new Integer(8000), new KualiDecimal(637.5), effectiveDate); } public void testCalculateMileageAmount_2012_100miles() throws Exception { Timestamp effectiveDate = new Timestamp( DateTime.parse("2012-12-01").toDateMidnight().toDate().getTime() ); runMileageAmountTest(100, KualiDecimal.ZERO, effectiveDate); runMileageAmountTest(500, KualiDecimal.ZERO, effectiveDate); runMileageAmountTest(501, new KualiDecimal("0.50"), effectiveDate); } protected void runMileageAmountTest(Integer totalMiles, KualiDecimal expectedMileageAmount, Timestamp effectiveDate) { assertEquals("Mileage amount not correct miles=" + totalMiles + " / date = " + effectiveDate, expectedMileageAmount, SpringContext.getBean(DisbursementVoucherTravelService.class).calculateMileageAmount(totalMiles, effectiveDate)); } protected TravelMileageRate createRate( DateTime effectiveDate, int mileageLimit, BigDecimal rateAmount ) { TravelMileageRate rate = new TravelMileageRate(); rate.setDisbursementVoucherMileageEffectiveDate(new Date( effectiveDate.toDateMidnight().toDate().getTime() )); rate.setMileageLimitAmount(mileageLimit); rate.setMileageRate(rateAmount); return rate; } protected void setupMileageRates() { sqlDao.sqlCommand("DELETE FROM FP_DV_MLG_T"); businessObjectService.save( createRate( DateTime.parse("2012-10-30"), 100, new BigDecimal("5") ) ); businessObjectService.save( createRate( DateTime.parse("2012-10-25"), 500, new BigDecimal("0.5") ) ); businessObjectService.save( createRate( DateTime.parse("2012-11-01"), 500, new BigDecimal("0.5") ) ); businessObjectService.save( createRate( DateTime.parse("2003-07-01"), 0, new BigDecimal("0.375") ) ); businessObjectService.save( createRate( DateTime.parse("2003-07-01"), 500, new BigDecimal("0.18") ) ); businessObjectService.save( createRate( DateTime.parse("2003-07-01"), 3000, new BigDecimal("0") ) ); businessObjectService.save( createRate( DateTime.parse("2012-10-29"), 500, new BigDecimal("0.5") ) ); } public void testRetrievedRatesAllHaveSameDate_1() { Date travelStartDate = new Date( DateTime.parse("2012-12-01").toDateMidnight().toDate().getTime() ); Collection<TravelMileageRate> rates = rateDao.retrieveMostEffectiveMileageRates( travelStartDate ); assertFalse( "rates should have been returned", rates.isEmpty() ); System.err.println( rates ); Date returnedDate = rates.iterator().next().getDisbursementVoucherMileageEffectiveDate(); for ( TravelMileageRate rate : rates ) { assertEquals( "All returned rates should have the same date: " + rate, returnedDate, rate.getDisbursementVoucherMileageEffectiveDate() ); } } public void testRetrievedRatesAllHaveSameDate_2() { DateTime date = new DateTime(2004, 1, 1, 0, 0); Date travelStartDate = new Date( date.toDateMidnight().toDate().getTime() ); Collection<TravelMileageRate> rates = rateDao.retrieveMostEffectiveMileageRates( travelStartDate ); assertFalse( "rates should have been returned", rates.isEmpty() ); System.err.println( rates ); Date returnedDate = rates.iterator().next().getDisbursementVoucherMileageEffectiveDate(); for ( TravelMileageRate rate : rates ) { assertEquals( "All returned rates should have the same date: " + rate, returnedDate, rate.getDisbursementVoucherMileageEffectiveDate() ); } } }