/* * 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.customers; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.junit.matchers.JUnitMatchers.hasItem; import java.util.ArrayList; import java.util.List; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.mifos.accounts.business.AccountActionDateEntity; import org.mifos.accounts.business.AccountBO; import org.mifos.accounts.business.AccountFeesEntity; import org.mifos.accounts.fees.business.FeeBO; import org.mifos.application.master.business.MifosCurrency; import org.mifos.application.meeting.business.MeetingBO; import org.mifos.application.meeting.util.helpers.WeekDay; import org.mifos.calendar.CalendarEvent; import org.mifos.calendar.CalendarUtils; import org.mifos.customers.business.CustomerAccountBO; import org.mifos.customers.business.CustomerBO; import org.mifos.customers.center.business.CenterBO; import org.mifos.customers.group.business.GroupBO; import org.mifos.domain.builders.CalendarEventBuilder; import org.mifos.domain.builders.CenterBuilder; import org.mifos.domain.builders.FeeBuilder; import org.mifos.domain.builders.GroupBuilder; import org.mifos.domain.builders.MeetingBuilder; import org.mifos.framework.TestUtils; import org.mifos.framework.util.helpers.Money; /** * I test {@link CustomerAccountBO#createNew(CustomerBO, List, MeetingBO, CalendarEvent)} */ public class CustomerAccountCreationTest { // class under test private CustomerAccountBO customerAccount; // collabrators private CustomerBO customer; private MeetingBO customerMeeting; private List<AccountFeesEntity> accountFees; private CalendarEvent applicableCalendarEvents; private static MifosCurrency oldDefaultCurrency; @BeforeClass public static void setupDefaultCurrency() { oldDefaultCurrency = Money.getDefaultCurrency(); Money.setDefaultCurrency(TestUtils.RUPEE); } @AfterClass public static void replaceOldDefaultCurrency() { Money.setDefaultCurrency(oldDefaultCurrency); } @Test public void customerAccountIsAlwaysCreatedInActiveState() throws Exception { // setup customer = new CenterBuilder().inActive().build(); accountFees = new ArrayList<AccountFeesEntity>(); // exercise test customerAccount = CustomerAccountBO.createNew(customer, accountFees, customerMeeting, applicableCalendarEvents); // verification assertThat(customerAccount.isActive(), is(true)); } @Test public void customerAccountCanBeCreatedWithNoAccountFees() throws Exception { // setup accountFees = new ArrayList<AccountFeesEntity>(); customer = new CenterBuilder().inActive().build(); // exercise test customerAccount = CustomerAccountBO.createNew(customer, accountFees, customerMeeting, applicableCalendarEvents); // verification assertThat(customerAccount.getAccountFees().isEmpty(), is(true)); } @Test public void customerAccountCanBeCreatedWithAccountFees() throws Exception { // setup FeeBO fee = new FeeBuilder().appliesToAllCustomers().periodic().with(new MeetingBuilder().periodicFeeMeeting().weekly().every(1)).build(); AccountFeesEntity accountFee = new AccountFeesEntity(null, fee, Double.valueOf("25.0")); accountFees = new ArrayList<AccountFeesEntity>(); accountFees.add(accountFee); customer = new CenterBuilder().inActive().build(); // exercise test customerAccount = CustomerAccountBO.createNew(customer, accountFees, customerMeeting, applicableCalendarEvents); // verification assertThat(customerAccount.getAccountFees(), hasItem(accountFee)); assertThat(accountFee.getAccount(), is((AccountBO)customerAccount)); } @Test public void customerAccountIsNotCreatedWithCustomerSchedulesWhenAssociatedCustomerIsNotActive() throws Exception { // setup accountFees = new ArrayList<AccountFeesEntity>(); customer = new CenterBuilder().inActive().build(); // exercise test customerAccount = CustomerAccountBO.createNew(customer, accountFees, customerMeeting, applicableCalendarEvents); // verification assertThat(customerAccount.getAccountActionDates().isEmpty(), is(true)); } @Test public void customerAccountIsCreatedWithCustomerSchedulesWhenAssociatedCustomerIsActive() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); customerMeeting = new MeetingBuilder().customerMeeting().weekly().every(1).build(); accountFees = new ArrayList<AccountFeesEntity>(); customer = new CenterBuilder().active().build(); // exercise test customerAccount = CustomerAccountBO.createNew(customer, accountFees, customerMeeting, applicableCalendarEvents); // verification assertThat(customerAccount.getAccountActionDates().isEmpty(), is(false)); } @Test public void customerSchedulesAreCreatedFromCustomersActivationDate() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime twoWeeksAgo = new DateTime().minusWeeks(2); customerMeeting = new MeetingBuilder().customerMeeting().weekly().every(1).startingFrom(twoWeeksAgo.toDate()).build(); accountFees = new ArrayList<AccountFeesEntity>(); customer = new CenterBuilder().active().withActivationDate(new DateMidnight().toDateTime()).build(); // exercise test customerAccount = CustomerAccountBO.createNew(customer, accountFees, customerMeeting, applicableCalendarEvents); // verification assertThat(customerAccount.getAccountActionDates().isEmpty(), is(false)); List<AccountActionDateEntity> customerSchedules = new ArrayList<AccountActionDateEntity>(customerAccount.getAccountActionDates()); LocalDate activationDate = new LocalDate(CalendarUtils.nearestWorkingDay(new DateTime())); assertThat(new LocalDate(customerSchedules.get(0).getActionDate()), is(activationDate)); } @Test public void firstCustomerScheduleIsAlwaysTheClosestMatchingDayOfWeekAndDoesNotTakeIntoAccountWeeklyMeetingFrequency() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().weekly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); LocalDate firstCenterDate = new LocalDate(centerSchedules.get(0).getActionDate()); LocalDate mon25thOfApril = new DateTime().withDate(2011, 4, 25).toLocalDate(); assertThat(firstCenterDate, is(mon25thOfApril)); } @Test public void firstCustomerScheduleIsAlwaysTheClosestMatchingDayOfWeekAndDoesNotTakeIntoAccountMonthlyMeetingFrequency() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().monthly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); LocalDate firstCenterDate = new LocalDate(centerSchedules.get(0).getActionDate()); LocalDate mon18thOfMay = new DateTime().withDate(2011, 5, 18).toLocalDate(); assertThat(firstCenterDate, is(mon18thOfMay)); } @Test public void givenBiWeeklyFrequencyFirstCustomerScheduleForChildSynchsWithNearestScheduleOfParent() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); DateTime tue26thOfApril = new DateTime().withDate(2011, 4, 26); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().weekly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).build(); MeetingBO groupMeeting = new MeetingBuilder().customerMeeting().weekly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue26thOfApril.minusDays(1).toDate()).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); GroupBO group = new GroupBuilder().active().withParentCustomer(center).withActivationDate(tue26thOfApril).withMeeting(groupMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); CustomerAccountBO groupAccount = CustomerAccountBO.createNew(group, accountFees, groupMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); List<AccountActionDateEntity> groupSchedules = new ArrayList<AccountActionDateEntity>(groupAccount.getAccountActionDates()); LocalDate secondCenterDate = new LocalDate(centerSchedules.get(1).getActionDate()); LocalDate thirdCenterDate = new LocalDate(centerSchedules.get(2).getActionDate()); LocalDate firstGroupDate = new LocalDate(groupSchedules.get(0).getActionDate()); LocalDate secondGroupDate = new LocalDate(groupSchedules.get(1).getActionDate()); assertThat("group is activated after center first schedule and so should start on its second scheduled date", firstGroupDate, is(secondCenterDate)); assertThat(secondGroupDate, is(thirdCenterDate)); } @Test public void givenBiWeeklyFrequencyAndChildCreatedThreeWeeksAfterParentFirstCustomerScheduleForChildSynchsWithNearestScheduleOfParent() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); DateTime tue10thOfMay = new DateTime().withDate(2011, 4, 26).plusWeeks(2); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().weekly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).build(); MeetingBO groupMeeting = new MeetingBuilder().customerMeeting().weekly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue10thOfMay.minusDays(1).toDate()).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); GroupBO group = new GroupBuilder().active().withParentCustomer(center).withActivationDate(tue10thOfMay).withMeeting(groupMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); CustomerAccountBO groupAccount = CustomerAccountBO.createNew(group, accountFees, groupMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); List<AccountActionDateEntity> groupSchedules = new ArrayList<AccountActionDateEntity>(groupAccount.getAccountActionDates()); LocalDate thirdCenterDate = new LocalDate(centerSchedules.get(2).getActionDate()); LocalDate firstGroupDate = new LocalDate(groupSchedules.get(0).getActionDate()); assertThat(firstGroupDate, is(thirdCenterDate)); } @Test public void givenTriWeeklyFrequencyFirstCustomerScheduleForChildSynchsWithNearestScheduleOfParent() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); DateTime tue26thOfApril = new DateTime().withDate(2011, 4, 26); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().weekly().every(3).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).build(); MeetingBO groupMeeting = new MeetingBuilder().customerMeeting().weekly().every(3).occuringOnA(WeekDay.MONDAY).startingFrom(tue26thOfApril.minusDays(1).toDate()).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); GroupBO group = new GroupBuilder().active().withParentCustomer(center).withActivationDate(tue26thOfApril).withMeeting(groupMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); CustomerAccountBO groupAccount = CustomerAccountBO.createNew(group, accountFees, groupMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); List<AccountActionDateEntity> groupSchedules = new ArrayList<AccountActionDateEntity>(groupAccount.getAccountActionDates()); LocalDate secondCenterDate = new LocalDate(centerSchedules.get(1).getActionDate()); LocalDate thirdCenterDate = new LocalDate(centerSchedules.get(2).getActionDate()); LocalDate firstGroupDate = new LocalDate(groupSchedules.get(0).getActionDate()); LocalDate secondGroupDate = new LocalDate(groupSchedules.get(1).getActionDate()); assertThat(firstGroupDate, is(secondCenterDate)); assertThat(secondGroupDate, is(thirdCenterDate)); } @Test public void givenMonthlyFrequencyFirstCustomerScheduleForChildSynchsWithNearestScheduleOfParent() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); DateTime tue26thOfApril = new DateTime().withDate(2011, 4, 26); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().monthly().every(1).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); MeetingBO groupMeeting = new MeetingBuilder().customerMeeting().monthly().every(1).occuringOnA(WeekDay.MONDAY).startingFrom(tue26thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); GroupBO group = new GroupBuilder().active().withParentCustomer(center).withActivationDate(tue26thOfApril).withMeeting(groupMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); CustomerAccountBO groupAccount = CustomerAccountBO.createNew(group, accountFees, groupMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); List<AccountActionDateEntity> groupSchedules = new ArrayList<AccountActionDateEntity>(groupAccount.getAccountActionDates()); LocalDate firstCenterDate = new LocalDate(centerSchedules.get(0).getActionDate()); LocalDate secondCenterDate = new LocalDate(centerSchedules.get(1).getActionDate()); LocalDate firstGroupDate = new LocalDate(groupSchedules.get(0).getActionDate()); LocalDate secondGroupDate = new LocalDate(groupSchedules.get(1).getActionDate()); assertThat(firstGroupDate, is(firstCenterDate)); assertThat(secondGroupDate, is(secondCenterDate)); } @Test public void givenMonthlyFrequencyAndChildCreatedAfterParentsFirstScheduleFirstCustomerScheduleForChildSynchsWithNearestScheduleOfParent() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); DateTime thursday26thOfMay = new DateTime().withDate(2011, 5, 26); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().monthly().every(1).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); MeetingBO groupMeeting = new MeetingBuilder().customerMeeting().monthly().every(1).occuringOnA(WeekDay.MONDAY).startingFrom(thursday26thOfMay.minusDays(1).toDate()).onDayOfMonth(18).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); GroupBO group = new GroupBuilder().active().withParentCustomer(center).withActivationDate(thursday26thOfMay).withMeeting(groupMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); CustomerAccountBO groupAccount = CustomerAccountBO.createNew(group, accountFees, groupMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); List<AccountActionDateEntity> groupSchedules = new ArrayList<AccountActionDateEntity>(groupAccount.getAccountActionDates()); LocalDate secondCenterDate = new LocalDate(centerSchedules.get(1).getActionDate()); LocalDate firstGroupDate = new LocalDate(groupSchedules.get(0).getActionDate()); assertThat(firstGroupDate, is(secondCenterDate)); } @Test public void givenBiMonthlyFrequencyFirstCustomerScheduleForChildSynchsWithNearestScheduleOfParent() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); DateTime tue26thOfApril = new DateTime().withDate(2011, 4, 26); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().monthly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); MeetingBO groupMeeting = new MeetingBuilder().customerMeeting().monthly().every(2).occuringOnA(WeekDay.MONDAY).startingFrom(tue26thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); GroupBO group = new GroupBuilder().active().withParentCustomer(center).withActivationDate(tue26thOfApril).withMeeting(groupMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); CustomerAccountBO groupAccount = CustomerAccountBO.createNew(group, accountFees, groupMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); List<AccountActionDateEntity> groupSchedules = new ArrayList<AccountActionDateEntity>(groupAccount.getAccountActionDates()); LocalDate firstCenterDate = new LocalDate(centerSchedules.get(0).getActionDate()); LocalDate secondCenterDate = new LocalDate(centerSchedules.get(1).getActionDate()); LocalDate firstGroupDate = new LocalDate(groupSchedules.get(0).getActionDate()); LocalDate secondGroupDate = new LocalDate(groupSchedules.get(1).getActionDate()); assertThat(firstGroupDate, is(firstCenterDate)); assertThat(secondGroupDate, is(secondCenterDate)); } @Test public void givenTriMonthlyFrequencyFirstCustomerScheduleForChildSynchsWithNearestScheduleOfParent() throws Exception { // setup applicableCalendarEvents = new CalendarEventBuilder().build(); DateTime tue19thOfApril = new DateTime().withDate(2011, 4, 19); DateTime tue26thOfApril = new DateTime().withDate(2011, 4, 26); accountFees = new ArrayList<AccountFeesEntity>(); MeetingBO centerMeeting = new MeetingBuilder().customerMeeting().monthly().every(3).occuringOnA(WeekDay.MONDAY).startingFrom(tue19thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); MeetingBO groupMeeting = new MeetingBuilder().customerMeeting().monthly().every(3).occuringOnA(WeekDay.MONDAY).startingFrom(tue26thOfApril.minusDays(1).toDate()).onDayOfMonth(18).build(); CenterBO center = new CenterBuilder().active().withActivationDate(tue19thOfApril).with(centerMeeting).build(); GroupBO group = new GroupBuilder().active().withParentCustomer(center).withActivationDate(tue26thOfApril).withMeeting(groupMeeting).build(); // exercise test CustomerAccountBO centerAccount = CustomerAccountBO.createNew(center, accountFees, centerMeeting, applicableCalendarEvents); CustomerAccountBO groupAccount = CustomerAccountBO.createNew(group, accountFees, groupMeeting, applicableCalendarEvents); // verification List<AccountActionDateEntity> centerSchedules = new ArrayList<AccountActionDateEntity>(centerAccount.getAccountActionDates()); List<AccountActionDateEntity> groupSchedules = new ArrayList<AccountActionDateEntity>(groupAccount.getAccountActionDates()); LocalDate firstCenterDate = new LocalDate(centerSchedules.get(0).getActionDate()); LocalDate secondCenterDate = new LocalDate(centerSchedules.get(1).getActionDate()); LocalDate firstGroupDate = new LocalDate(groupSchedules.get(0).getActionDate()); LocalDate secondGroupDate = new LocalDate(groupSchedules.get(1).getActionDate()); assertThat(firstGroupDate, is(firstCenterDate)); assertThat(secondGroupDate, is(secondCenterDate)); } }