/* * 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.application.servicefacade; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.joda.time.LocalDate; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.mifos.accounts.business.AccountBO; import org.mifos.accounts.business.AccountNotesEntity; import org.mifos.accounts.business.AccountPaymentEntity; import org.mifos.accounts.persistence.LegacyAccountDao; import org.mifos.accounts.savings.business.SavingsBO; import org.mifos.accounts.util.helpers.AccountState; import org.mifos.application.master.business.PaymentTypeEntity; import org.mifos.core.MifosRuntimeException; import org.mifos.customers.personnel.business.PersonnelBO; import org.mifos.framework.MifosIntegrationTestCase; import org.mifos.framework.TestUtils; import org.mifos.framework.hibernate.helper.StaticHibernateUtil; import org.mifos.framework.util.helpers.IntegrationTestObjectMother; import org.mifos.framework.util.helpers.Money; import org.mifos.framework.util.helpers.TestObjectFactory; import org.mifos.security.util.UserContext; import org.springframework.beans.factory.annotation.Autowired; public class CollectionSheetServiceImplRetrieveSavingsAccountsIntegrationTest extends MifosIntegrationTestCase { @Autowired private LegacyAccountDao legacyAccountDao; @BeforeClass public static void init() { collectionSheetService = ApplicationContextProvider.getBean(CollectionSheetService.class); } private static CollectionSheetService collectionSheetService; private TestCollectionSheetRetrieveSavingsAccountsUtils collectionSheetRetrieveSavingsAccountsUtils; @Before public void setUp() throws Exception { enableCustomWorkingDays(); collectionSheetRetrieveSavingsAccountsUtils = new TestCollectionSheetRetrieveSavingsAccountsUtils(); } @After public void tearDown() throws Exception { } /** * need to clean up test data set up */ @Ignore @Test public void testRetrievedCollectionSheetHasAnEntryForCentreSavingsAccountsWhenCenterIsOnlyCustomerInHierarchy() throws Exception { collectionSheetRetrieveSavingsAccountsUtils.setOnlyCreateCenterAndItsSavingsAccount(); CollectionSheetDto collectionSheet = collectionSheetRetrieveSavingsAccountsUtils .createSampleCollectionSheetDto(); // For the center - There should be one normal savings account and no individual savings account assertThat(collectionSheet.getCollectionSheetCustomer().get(0).getCollectionSheetCustomerSaving().size(), is(1)); assertThat(collectionSheet.getCollectionSheetCustomer().get(0).getIndividualSavingAccounts().size(), is(0)); } /** * need to clean up test data set up */ @Ignore @Test public void testCollectionSheetRetrieveOnlyReturnsActiveAndInactiveSavingsAccounts() throws Exception { UserContext userContext = TestUtils.makeUser(); collectionSheetRetrieveSavingsAccountsUtils.createSampleCenterHierarchy(); SavingsBO centerSavingsAccount = (SavingsBO) legacyAccountDao .getAccount(collectionSheetRetrieveSavingsAccountsUtils.getCenterSavingsAccount().getAccountId()); centerSavingsAccount.setUserContext(userContext); PersonnelBO loggedInUser = IntegrationTestObjectMother.testUser(); centerSavingsAccount.changeStatus(AccountState.SAVINGS_INACTIVE, Short.valueOf("1"), "Make Center Savings Account Inactive", loggedInUser); SavingsBO clientSavings = (SavingsBO) legacyAccountDao.getAccount(collectionSheetRetrieveSavingsAccountsUtils .getClientOfGroupCompleteGroupSavingsAccount().getAccountId()); AccountPaymentEntity payment = new AccountPaymentEntity(clientSavings, new Money(clientSavings.getCurrency()), null, null, new PaymentTypeEntity(Short.valueOf("1")), new Date()); AccountNotesEntity notes = new AccountNotesEntity(new java.sql.Date(System.currentTimeMillis()), "close client savings account", TestObjectFactory.getPersonnel(userContext.getId()), clientSavings); clientSavings.setUserContext(userContext); clientSavings.closeAccount(payment, notes, clientSavings.getCustomer(), loggedInUser); IntegrationTestObjectMother.saveSavingsAccount(clientSavings); StaticHibernateUtil.flushSession(); CollectionSheetDto collectionSheet = collectionSheetService.retrieveCollectionSheet( collectionSheetRetrieveSavingsAccountsUtils.getCenter().getCustomerId(), new LocalDate()); List<CollectionSheetCustomerDto> customers = collectionSheet.getCollectionSheetCustomer(); for (CollectionSheetCustomerDto customer : customers) { for (CollectionSheetCustomerSavingDto customerSaving : customer.getCollectionSheetCustomerSaving()) { Boolean accountIsActiveOrInactive = false; AccountBO accountBO = legacyAccountDao.getAccount(customerSaving.getAccountId()); if ((accountBO.getState().equals(AccountState.SAVINGS_ACTIVE)) || (accountBO.getState().equals(AccountState.SAVINGS_INACTIVE))) { accountIsActiveOrInactive = true; } Assert.assertTrue("Found Account State: " + accountBO.getState().toString() + " - Only Active and Inactive Savings Accounts are Allowed", accountIsActiveOrInactive); } } } /** * need to clean up test data set up */ @Ignore @Test public void testAllSavingsAccountsEntriesReturnedWithCorrectTotalDepositAmount() throws Exception { CollectionSheetDto collectionSheet = collectionSheetRetrieveSavingsAccountsUtils .createSampleCollectionSheetDto(); List<CollectionSheetCustomerDto> customers = collectionSheet.getCollectionSheetCustomer(); // check all savings accounts are included in the collection sheet and all have the correct deposit values. verifyAllSavingsAccountsIncluded(customers); // check group with complete_group savings account assertThat(customers.get(1).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(2.0)); // check complete_group client // assertThat(customers.get(2).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(3.0)); assertThat(customers.get(2).getIndividualSavingAccounts().get(0).getTotalDepositAmount(), is(1.0)); // check per_individual client // assertThat(customers.get(4).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(5.0)); // The individual accounts could be returned in any order Integer centerAccountId = customers.get(0).getCollectionSheetCustomerSaving().get(0).getAccountId(); Integer clientIndividualSavingsIndex = getIndexMatchingAccountId( customers.get(4).getIndividualSavingAccounts(), centerAccountId); Double firstIndividualAccountAmount = 1.0; Double secondIndividualAccountAmount = 4.0; if (clientIndividualSavingsIndex.equals(1)) { firstIndividualAccountAmount = 4.0; secondIndividualAccountAmount = 1.0; } assertThat(customers.get(4).getIndividualSavingAccounts().get(0).getTotalDepositAmount(), is(firstIndividualAccountAmount)); assertThat(customers.get(4).getIndividualSavingAccounts().get(1).getTotalDepositAmount(), is(secondIndividualAccountAmount)); } /** * need to clean up test data set up */ @Ignore @Test public void testSavingsAccountsEntriesReturnedWithZeroTotalDepositAmountWhenNoOutstandingInstallmentExists() throws Exception { CollectionSheetDto collectionSheet = collectionSheetRetrieveSavingsAccountsUtils .createSampleCollectionSheetDto(); StaticHibernateUtil.flushAndClearSession(); // process List<CollectionSheetCustomerDto> customersAfterProcessing = convertSaveRetrieveVerifyAndReturnProcessedCollectionSheetCustomers(collectionSheet); // All the accounts below are set to a value but should be zero when no outstanding installments Double zeroDouble = 0.0; // check group with complete_group savings account assertThat(customersAfterProcessing.get(1).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(zeroDouble)); // check complete_group client assertThat(customersAfterProcessing.get(2).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(zeroDouble)); assertThat(customersAfterProcessing.get(2).getIndividualSavingAccounts().get(0).getTotalDepositAmount(), is(zeroDouble)); // check per_individual client assertThat(customersAfterProcessing.get(4).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(zeroDouble)); assertThat(customersAfterProcessing.get(4).getIndividualSavingAccounts().get(0).getTotalDepositAmount(), is(zeroDouble)); assertThat(customersAfterProcessing.get(4).getIndividualSavingAccounts().get(1).getTotalDepositAmount(), is(zeroDouble)); } /** * need to clean up test data set up */ @Ignore @Test public void testPartPayingVoluntarySavingsAccountResultsInAZeroTotalDepositAmountWhenCollectionSheetRetrievedAgain() throws Exception { CollectionSheetDto collectionSheet = collectionSheetRetrieveSavingsAccountsUtils .createSampleCollectionSheetDto(); StaticHibernateUtil.flushAndClearSession(); // pay 0.5 of the 2.0 voluntary group complete_group savings account amount due collectionSheet.getCollectionSheetCustomer().get(1).getCollectionSheetCustomerSaving().get(0) .setDepositDue(new BigDecimal("0.5")); // process List<CollectionSheetCustomerDto> customersAfterProcessing = convertSaveRetrieveVerifyAndReturnProcessedCollectionSheetCustomers(collectionSheet); assertThat(customersAfterProcessing.get(1).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(0.0)); } /** * need to clean up test data set up */ @Ignore @Test public void testPartPayingMandatorySavingsAccountResultsInAReducedTotalDepositAmountWhenCollectionSheetRetrievedAgain() throws Exception { CollectionSheetDto collectionSheet = collectionSheetRetrieveSavingsAccountsUtils .createSampleCollectionSheetDto(); StaticHibernateUtil.flushAndClearSession(); // pay 0.2 of the 1.0 mandatory client individual savings amount due (derived from center mandatory savings // account) collectionSheet.getCollectionSheetCustomer().get(2).getIndividualSavingAccounts().get(0) .setDepositDue(new BigDecimal("0.2")); // process List<CollectionSheetCustomerDto> customersAfterProcessing = convertSaveRetrieveVerifyAndReturnProcessedCollectionSheetCustomers(collectionSheet); assertThat(customersAfterProcessing.get(2).getIndividualSavingAccounts().get(0).getTotalDepositAmount(), is(0.8)); } /** * need to clean up test data set up */ @Ignore @Test public void testNotPayingVoluntarySavingsAccountForClientUnderPerIndividualGroupResultsInAFullTotalDepositAmountWhenCollectionSheetRetrievedAgain() throws Exception { CollectionSheetDto collectionSheet = collectionSheetRetrieveSavingsAccountsUtils .createSampleCollectionSheetDto(); StaticHibernateUtil.flushAndClearSession(); // Find the client's group individual account Integer groupPerIndividualAccountId = collectionSheet.getCollectionSheetCustomer().get(3) .getCollectionSheetCustomerSaving().get(0).getAccountId(); Integer clientIndividualSavingsIndex = getIndexMatchingAccountId(collectionSheet.getCollectionSheetCustomer() .get(4).getIndividualSavingAccounts(), groupPerIndividualAccountId); // pay none of the 4.0 voluntary group individual savings amount due account) collectionSheet.getCollectionSheetCustomer().get(4).getIndividualSavingAccounts() .get(clientIndividualSavingsIndex).setDepositDue(BigDecimal.ZERO); // process List<CollectionSheetCustomerDto> customersAfterProcessing = convertSaveRetrieveVerifyAndReturnProcessedCollectionSheetCustomers(collectionSheet); groupPerIndividualAccountId = customersAfterProcessing.get(3).getCollectionSheetCustomerSaving().get(0) .getAccountId(); clientIndividualSavingsIndex = getIndexMatchingAccountId(customersAfterProcessing.get(4) .getIndividualSavingAccounts(), groupPerIndividualAccountId); assertThat(customersAfterProcessing.get(4).getIndividualSavingAccounts().get(clientIndividualSavingsIndex) .getTotalDepositAmount(), is(4.0)); } /* * method verifies that all the savings accounts from the sample savings account center structure (created by a * utility method) are represented in the retrieved collection sheet and are in their appropriate list * * This is considered important because understanding individual savings can be tricky. */ private void verifyAllSavingsAccountsIncluded(List<CollectionSheetCustomerDto> customers) { // per_individual accounts are always zero in collection sheet Double zeroDouble = 0.0; assertThat(customers.get(0).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(zeroDouble)); assertThat(customers.get(3).getCollectionSheetCustomerSaving().get(0).getTotalDepositAmount(), is(zeroDouble)); // structure checking // check center assertThat(customers.get(0).getCollectionSheetCustomerSaving().size(), is(1)); assertThat(customers.get(0).getIndividualSavingAccounts().size(), is(0)); // check group with complete_group savings account assertThat(customers.get(1).getCollectionSheetCustomerSaving().size(), is(1)); assertThat(customers.get(1).getIndividualSavingAccounts().size(), is(0)); // check groups client assertThat(customers.get(2).getCollectionSheetCustomerSaving().size(), is(1)); assertThat(customers.get(2).getIndividualSavingAccounts().size(), is(1)); assertThat(customers.get(2).getIndividualSavingAccounts().get(0).getAccountId(), is(customers.get(0) .getCollectionSheetCustomerSaving().get(0).getAccountId())); // check group with per_individual savings account assertThat(customers.get(3).getCollectionSheetCustomerSaving().size(), is(1)); assertThat(customers.get(3).getIndividualSavingAccounts().size(), is(0)); // check groups client assertThat(customers.get(4).getCollectionSheetCustomerSaving().size(), is(1)); assertThat(customers.get(4).getIndividualSavingAccounts().size(), is(2)); List<Integer> perIndividualAccountIds = new ArrayList<Integer>(); perIndividualAccountIds.add(customers.get(0).getCollectionSheetCustomerSaving().get(0).getAccountId()); perIndividualAccountIds.add(customers.get(3).getCollectionSheetCustomerSaving().get(0).getAccountId()); CollectionSheetCustomerDto customer4 = customers.get(4); Assert.assertTrue( "Client Id: " + customer4.getCustomerId() + " Account Id: " + customer4.getIndividualSavingAccounts().get(0).getAccountId() + " Product: " + customer4.getIndividualSavingAccounts().get(0).getProductShortName(), isPerIndividualAccount(perIndividualAccountIds, customer4.getIndividualSavingAccounts().get(0) .getAccountId())); Assert.assertTrue( "Client Id: " + customer4.getCustomerId() + " Account Id: " + customer4.getIndividualSavingAccounts().get(1).getAccountId() + " Product: " + customer4.getIndividualSavingAccounts().get(1).getProductShortName(), isPerIndividualAccount(perIndividualAccountIds, customer4.getIndividualSavingAccounts().get(1) .getAccountId())); } /* * Search list of client individual savings accounts as the accounts don't have to be in accountId order */ private boolean isPerIndividualAccount(List<Integer> perIndividualAccountIds, Integer accountId) { for (Integer individualAccountId : perIndividualAccountIds) { if (individualAccountId.compareTo(accountId) == 0) { return true; } } return false; } private List<CollectionSheetCustomerDto> convertSaveRetrieveVerifyAndReturnProcessedCollectionSheetCustomers( CollectionSheetDto collectionSheet) { Integer customerId = collectionSheet.getCollectionSheetCustomer().get(0).getCustomerId(); // convert to save collection sheet format TestSaveCollectionSheetUtils saveCollectionSheetUtils = new TestSaveCollectionSheetUtils(); SaveCollectionSheetDto saveCollectionSheet = saveCollectionSheetUtils.assembleSaveCollectionSheetDto( collectionSheet, new LocalDate()); // Save collection sheet saveAndVerifyCollectionSheetSave(saveCollectionSheet); // Retrieve the collection sheet customer list for the same date (current date) List<CollectionSheetCustomerDto> customers = collectionSheetService.retrieveCollectionSheet(customerId, new LocalDate()).getCollectionSheetCustomer(); // check all savings accounts are included in the collection sheet verifyAllSavingsAccountsIncluded(customers); return customers; } private void saveAndVerifyCollectionSheetSave(SaveCollectionSheetDto saveCollectionSheet) { CollectionSheetErrorsDto errors = null; try { errors = collectionSheetService.saveCollectionSheet(saveCollectionSheet); } catch (SaveCollectionSheetException e) { throw new MifosRuntimeException(e.printInvalidSaveCollectionSheetReasons()); } Assert.assertNotNull("'errors' should not be null", errors); assertThat(errors.getSavingsDepNames().size(), is(0)); assertThat(errors.getSavingsWithNames().size(), is(0)); assertThat(errors.getLoanDisbursementAccountNumbers().size(), is(0)); assertThat(errors.getLoanRepaymentAccountNumbers().size(), is(0)); assertThat(errors.getCustomerAccountNumbers().size(), is(0)); Assert.assertNull("There shouldn't have been a database error", errors.getDatabaseError()); } private Integer getIndexMatchingAccountId(List<CollectionSheetCustomerSavingDto> savingsAccounts, Integer accountId) { // If the first doesn't match the second one must (for this data) if (savingsAccounts.get(0).getAccountId().compareTo(accountId) == 0) { return 0; } return 1; } }