/* * Copyright (c) 2005-2011 Grameen Foundation USA * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * See also http://www.apache.org/licenses/LICENSE-2.0.html for an * explanation of the license and how it is applied. */ package org.mifos.framework.components.batchjobs.helpers; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; import org.joda.time.DateTime; import org.joda.time.DateTimeConstants; import org.joda.time.LocalDate; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.mifos.accounts.business.AccountActionDateEntity; import org.mifos.accounts.loan.business.LoanBO; import org.mifos.accounts.savings.business.SavingsBO; import org.mifos.application.holiday.business.Holiday; import org.mifos.application.holiday.business.HolidayBO; import org.mifos.application.holiday.persistence.HolidayDao; import org.mifos.application.holiday.util.helpers.RepaymentRuleTypes; import org.mifos.application.master.business.MifosCurrency; import org.mifos.application.servicefacade.TestCollectionSheetRetrieveSavingsAccountsUtils; import org.mifos.application.servicefacade.TestSaveCollectionSheetUtils; import org.mifos.customers.business.CustomerAccountBO; import org.mifos.customers.business.CustomerBO; import org.mifos.customers.office.business.OfficeBO; import org.mifos.domain.builders.HolidayBuilder; import org.mifos.domain.builders.OfficeBuilder; import org.mifos.framework.MifosIntegrationTestCase; import org.mifos.framework.TestUtils; import org.mifos.framework.hibernate.helper.StaticHibernateUtil; import org.mifos.framework.util.DateTimeService; import org.mifos.framework.util.StandardTestingService; import org.mifos.framework.util.helpers.IntegrationTestObjectMother; import org.mifos.framework.util.helpers.Money; import org.mifos.service.test.TestMode; import org.mifos.test.framework.util.DatabaseCleaner; import org.springframework.beans.factory.annotation.Autowired; public class ApplyHolidayChangesHelperIntegrationTest extends MifosIntegrationTestCase { @Autowired private DatabaseCleaner databaseCleaner; @Autowired private HolidayDao holidayDao; private static MifosCurrency oldDefaultCurrency; private ApplyHolidayChangesHelper applyHolidayChangesHelper; private DateTimeService dateTimeService = new DateTimeService(); // john w - Collection Sheet Util Classes just used to create center hierarchies private TestSaveCollectionSheetUtils testSaveCollectionSheetUtils; private TestCollectionSheetRetrieveSavingsAccountsUtils testCollectionSheetRetrieveSavingsAccountsUtils; private SavingsBO newCenterSavingsAccount; private SavingsBO newGroupSavingsAccount; @BeforeClass public static void initialiseHibernateUtilAndSetDefaultCurrency() { oldDefaultCurrency = Money.getDefaultCurrency(); Money.setDefaultCurrency(TestUtils.RUPEE); new StandardTestingService().setTestMode(TestMode.INTEGRATION); } @AfterClass public static void resetDefaultCurrency() { Money.setDefaultCurrency(oldDefaultCurrency); } @After public void cleanDatabaseTablesAndResetCurrentDateTimeAfterTest() { // NOTE: - only added to stop older integration tests failing due to brittleness databaseCleaner.clean(); dateTimeService.resetToCurrentSystemDateTime(); StaticHibernateUtil.rollbackTransaction(); StaticHibernateUtil.flushAndClearSession(); } @Before public void cleanDatabaseTablesAndSetupCustomerTestDataBeforeTest() throws Exception { databaseCleaner.clean(); dateTimeService.setCurrentDateTime(new DateTime().withYear(2010).withMonthOfYear(DateTimeConstants.FEBRUARY) .withDayOfMonth(23)); ApplyHolidayChangesTask applyHolidayChangesTask = new ApplyHolidayChangesTask(); applyHolidayChangesHelper = (ApplyHolidayChangesHelper) applyHolidayChangesTask.getTaskHelper(); testSaveCollectionSheetUtils = new TestSaveCollectionSheetUtils(); testCollectionSheetRetrieveSavingsAccountsUtils = new TestCollectionSheetRetrieveSavingsAccountsUtils(); // create center hierarchy with loan and savings and customer accounts. createCenterHierarchy(dateTimeService.getCurrentJavaDateTime()); StaticHibernateUtil.flushAndClearSession(); } /** * need to clean up set up of tests data for savings account. */ @Ignore @Test public void testThatNoSchedulesAreUpdatedWhenHolidaysDontAffectThem() throws Exception { DateTime nextYear = new DateTime().plusYears(1); createOfficeHolidayTestData(nextYear); //expected results LocalDate[] expectedDateResultsCustomerAndSavings = noChangeExpectedForCustomerAndSavings(); LocalDate[] expectedDateResultsLoan = noChangeExpectedForLoan(); // run the batch job StaticHibernateUtil.startTransaction(); applyHolidayChangesHelper.execute(dateTimeService.getCurrentJavaDateTime().getTime()); // verify_results(expectedDateResultsCustomerAndSavings, expectedDateResultsLoan); } @Test @Ignore("Convert to unit test") public void testThatAllTypesofSchedulesAreUpdatedGivenAMixOfUnappliedHolidays() throws Exception { DateTime yesterday = new DateTime().minusDays(1); createOfficeHolidayTestData(yesterday); //expected results LocalDate[] expectedDateResultsCustomerAndSavings = changeExpectedForCustomerAndSavings(); LocalDate[] expectedDateResultsLoan = changeExpectedForLoan(); // run the batch job StaticHibernateUtil.startTransaction(); applyHolidayChangesHelper.execute(dateTimeService.getCurrentJavaDateTime().getTime()); // verify_results(expectedDateResultsCustomerAndSavings, expectedDateResultsLoan); } /** * need to clean up set up of tests data for savings account. */ @Ignore @Test public void testThatTaskRunsSuccessfullyWhenNoHolidaysNeedApplying() throws Exception { List<Holiday> unappliedHolidays = holidayDao.getUnAppliedHolidays(); assertThat(unappliedHolidays.size(), is(0)); //expected results LocalDate[] expectedDateResultsCustomerAndSavings = noChangeExpectedForCustomerAndSavings(); LocalDate[] expectedDateResultsLoan = noChangeExpectedForLoan(); // run the batch job StaticHibernateUtil.startTransaction(); applyHolidayChangesHelper.execute(dateTimeService.getCurrentJavaDateTime().getTime()); // verify_results(expectedDateResultsCustomerAndSavings, expectedDateResultsLoan); } private void verify_results(LocalDate[] expectedDateResultsCustomerAndSavings, LocalDate[] expectedDateResultsLoan) { // verify results by refreshing data and comparing with expected results getCustomerAccountAndVerifyDates(testSaveCollectionSheetUtils.getCenter(), expectedDateResultsCustomerAndSavings); getCustomerAccountAndVerifyDates(testSaveCollectionSheetUtils.getGroup(), expectedDateResultsCustomerAndSavings); getCustomerAccountAndVerifyDates(testSaveCollectionSheetUtils.getClientLoan().getCustomer(), expectedDateResultsCustomerAndSavings); getSavingsAccountAndVerifyDates(newCenterSavingsAccount, expectedDateResultsCustomerAndSavings); getSavingsAccountAndVerifyDates(newGroupSavingsAccount, expectedDateResultsCustomerAndSavings); getLoanAccountAndVerifyDates(testSaveCollectionSheetUtils.getClientLoan(), expectedDateResultsLoan); } private void getCustomerAccountAndVerifyDates(CustomerBO customer, LocalDate[] expectedResultDates) { CustomerAccountBO refreshedCustomerAccount = (CustomerAccountBO) StaticHibernateUtil.getSessionTL().get( CustomerAccountBO.class, customer.getCustomerAccount().getAccountId()); verifyAccountActionDates(refreshedCustomerAccount.getAccountActionDates(), expectedResultDates); } private void getSavingsAccountAndVerifyDates(SavingsBO savings, LocalDate[] expectedResultDates) { SavingsBO refreshedSavingsAccount = (SavingsBO) StaticHibernateUtil.getSessionTL().get(SavingsBO.class, savings.getAccountId()); verifyAccountActionDates(refreshedSavingsAccount.getAccountActionDates(), expectedResultDates); } private void getLoanAccountAndVerifyDates(LoanBO loan, LocalDate[] expectedResultDates) { LoanBO refreshedLoanAccount = (LoanBO) StaticHibernateUtil.getSessionTL() .get(LoanBO.class, loan.getAccountId()); verifyAccountActionDates(refreshedLoanAccount.getAccountActionDates(), expectedResultDates); } private void verifyAccountActionDates(Set<AccountActionDateEntity> accountActionDates, LocalDate[] expectedResultDates) { int i = 0; for (AccountActionDateEntity date : accountActionDates) { assertThat(expectedResultDates[i].toString(), is(date.getActionDate().toString())); i++; } } private LocalDate[] noChangeExpectedForCustomerAndSavings() { LocalDate[] expectedDates = new LocalDate[10]; expectedDates[0] = new LocalDate(2010, 2, 23); expectedDates[1] = new LocalDate(2010, 3, 2); expectedDates[2] = new LocalDate(2010, 3, 9); expectedDates[3] = new LocalDate(2010, 3, 16); expectedDates[4] = new LocalDate(2010, 3, 23); expectedDates[5] = new LocalDate(2010, 3, 30); expectedDates[6] = new LocalDate(2010, 4, 6); expectedDates[7] = new LocalDate(2010, 4, 13); expectedDates[8] = new LocalDate(2010, 4, 20); expectedDates[9] = new LocalDate(2010, 4, 27); return expectedDates; } private LocalDate[] noChangeExpectedForLoan() { LocalDate[] expectedDates = new LocalDate[12]; expectedDates[0] = new LocalDate(2010, 3, 2); expectedDates[1] = new LocalDate(2010, 3, 9); expectedDates[2] = new LocalDate(2010, 3, 16); expectedDates[3] = new LocalDate(2010, 3, 23); expectedDates[4] = new LocalDate(2010, 3, 30); expectedDates[5] = new LocalDate(2010, 4, 6); expectedDates[6] = new LocalDate(2010, 4, 13); expectedDates[7] = new LocalDate(2010, 4, 20); expectedDates[8] = new LocalDate(2010, 4, 27); expectedDates[9] = new LocalDate(2010, 5, 4); expectedDates[10] = new LocalDate(2010, 5, 11); expectedDates[11] = new LocalDate(2010, 5, 18); return expectedDates; } private LocalDate[] changeExpectedForCustomerAndSavings() { LocalDate[] expectedDates = new LocalDate[10]; expectedDates[0] = new LocalDate(2010, 3, 2); expectedDates[1] = new LocalDate(2010, 3, 2); expectedDates[2] = new LocalDate(2010, 3, 23); expectedDates[3] = new LocalDate(2010, 3, 30); expectedDates[4] = new LocalDate(2010, 4, 6); expectedDates[5] = new LocalDate(2010, 4, 13); expectedDates[6] = new LocalDate(2010, 4, 20); expectedDates[7] = new LocalDate(2010, 4, 27); expectedDates[8] = new LocalDate(2010, 5, 4); expectedDates[9] = new LocalDate(2010, 5, 11); return expectedDates; } private LocalDate[] changeExpectedForLoan() { LocalDate[] expectedDates = new LocalDate[12]; expectedDates[0] = new LocalDate(2010, 3, 2); expectedDates[1] = new LocalDate(2010, 3, 23); expectedDates[2] = new LocalDate(2010, 3, 30); expectedDates[3] = new LocalDate(2010, 4, 6); expectedDates[4] = new LocalDate(2010, 4, 13); expectedDates[5] = new LocalDate(2010, 4, 20); expectedDates[6] = new LocalDate(2010, 4, 27); expectedDates[7] = new LocalDate(2010, 5, 4); expectedDates[8] = new LocalDate(2010, 5, 11); expectedDates[9] = new LocalDate(2010, 5, 18); expectedDates[10] = new LocalDate(2010, 5, 25); expectedDates[11] = new LocalDate(2010, 6, 1); return expectedDates; } private void createOfficeHolidayTestData(DateTime startDate) throws Exception { /* * When startDate is 'yesterday' Head Office Holiday: from 2010-02-22 thru 2010-03-01 ... repayment rule is next * meeting date Branch Holiday: * * from 2010-03-08 thru 2010-03-22 ... moratorium * * One more holiday that should not affect any schedules */ // Creating Office Holidays Set<HolidayBO> holidays; OfficeBO headOffice = IntegrationTestObjectMother.findOfficeById(Short.valueOf("1")); holidays = new HashSet<HolidayBO>(); holidays.add((HolidayBO) new HolidayBuilder().withName("HO Holiday").from(startDate).to(startDate.plusWeeks(1)) .withRepaymentRule(RepaymentRuleTypes.NEXT_MEETING_OR_REPAYMENT).build()); headOffice.setHolidays(holidays); IntegrationTestObjectMother.createOffice(headOffice); OfficeBO centerOffice = testSaveCollectionSheetUtils.getCenter().getOffice(); holidays = new HashSet<HolidayBO>(); holidays.add((HolidayBO) new HolidayBuilder().withName("Center Hierarchy Holiday").from(startDate.plusWeeks(2)) .to(startDate.plusWeeks(4)).withRepaymentMoratoriumRule().build()); centerOffice.setHolidays(holidays); IntegrationTestObjectMother.createOffice(centerOffice); // builder not setting searchId correctly due to not going thru office.save (which uses HierarchyManager) String headOfficeSearchId = headOffice.getSearchId(); OfficeBO anotherOffice = new OfficeBuilder().withParentOffice(headOffice).withName("Another Office") .withSearchId(headOfficeSearchId + "26.").withGlobalOfficeNum("n/a001").build(); holidays = new HashSet<HolidayBO>(); holidays.add((HolidayBO) new HolidayBuilder().withName("N/A").from(startDate.minusWeeks(3)).to( startDate.plusWeeks(8)).withRepaymentMoratoriumRule().build()); anotherOffice.setHolidays(holidays); IntegrationTestObjectMother.createOffice(anotherOffice); } private void createCenterHierarchy(Date today) throws Exception { // John W - apologies for ugliness of reusing Collection Sheet test utility class here. testSaveCollectionSheetUtils.createSampleCenterHierarchy(today); newCenterSavingsAccount = testCollectionSheetRetrieveSavingsAccountsUtils.createSavingsAccount( testSaveCollectionSheetUtils.getCenter(), "cvi", "6.6", true, true); newGroupSavingsAccount = testCollectionSheetRetrieveSavingsAccountsUtils.createSavingsAccount( testSaveCollectionSheetUtils.getGroup(), "gm", "2.5", false, false); } }