Java tutorial
/* * Copyright (c) 2005-2010 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.accounts.loan.business; import static org.apache.commons.lang.math.NumberUtils.DOUBLE_ZERO; import static org.apache.commons.lang.math.NumberUtils.SHORT_ZERO; import static org.mifos.application.meeting.util.helpers.MeetingType.CUSTOMER_MEETING; import static org.mifos.application.meeting.util.helpers.RecurrenceType.MONTHLY; import static org.mifos.application.meeting.util.helpers.RecurrenceType.WEEKLY; import static org.mifos.application.meeting.util.helpers.WeekDay.MONDAY; import static org.mifos.framework.util.helpers.DateUtils.currentDate; import static org.mifos.framework.util.helpers.DateUtils.getCurrentDateWithoutTimeStamp; import static org.mifos.framework.util.helpers.DateUtils.getDateFromToday; import static org.mifos.framework.util.helpers.TestObjectFactory.EVERY_MONTH; import static org.mifos.framework.util.helpers.TestObjectFactory.EVERY_SECOND_MONTH; import static org.mifos.framework.util.helpers.TestObjectFactory.EVERY_SECOND_WEEK; import static org.mifos.framework.util.helpers.TestObjectFactory.EVERY_WEEK; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.Assert; import org.hibernate.Session; import org.joda.time.DateMidnight; import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; import org.mifos.accounts.acceptedpaymenttype.business.service.AcceptedPaymentTypeService; import org.mifos.accounts.business.AccountActionDateEntity; import org.mifos.accounts.business.AccountBO; import org.mifos.accounts.business.AccountFeesActionDetailEntity; import org.mifos.accounts.business.AccountFeesEntity; import org.mifos.accounts.business.AccountPaymentEntity; import org.mifos.accounts.business.AccountTrxnEntity; import org.mifos.accounts.business.FeesTrxnDetailEntity; import org.mifos.accounts.exceptions.AccountException; import org.mifos.accounts.fees.business.AmountFeeBO; import org.mifos.accounts.fees.business.FeeBO; import org.mifos.accounts.fees.business.FeeView; import org.mifos.accounts.fees.business.RateFeeBO; import org.mifos.accounts.fees.util.helpers.FeeCategory; import org.mifos.accounts.fees.util.helpers.FeeFormula; import org.mifos.accounts.fees.util.helpers.FeePayment; import org.mifos.accounts.fees.util.helpers.FeeStatus; import org.mifos.accounts.loan.persistance.LoanDao; import org.mifos.accounts.loan.util.helpers.LoanConstants; import org.mifos.accounts.persistence.AccountPersistence; import org.mifos.accounts.productdefinition.business.LoanOfferingBO; import org.mifos.accounts.productdefinition.business.LoanOfferingInstallmentRange; import org.mifos.accounts.productdefinition.util.helpers.ApplicableTo; import org.mifos.accounts.productdefinition.util.helpers.GraceType; import org.mifos.accounts.productdefinition.util.helpers.InterestType; import org.mifos.accounts.productdefinition.util.helpers.PrdStatus; import org.mifos.accounts.productsmix.business.service.ProductMixBusinessService; import org.mifos.accounts.util.helpers.AccountActionTypes; import org.mifos.accounts.util.helpers.AccountConstants; import org.mifos.accounts.util.helpers.AccountState; import org.mifos.accounts.util.helpers.AccountStates; import org.mifos.accounts.util.helpers.PaymentData; import org.mifos.accounts.util.helpers.PaymentStatus; import org.mifos.accounts.util.helpers.WaiveEnum; import org.mifos.accounts.fund.business.FundBO; import org.mifos.application.collectionsheet.business.CollSheetCustBO; import org.mifos.application.collectionsheet.business.CollectionSheetBO; import org.mifos.application.collectionsheet.persistence.MeetingBuilder; import org.mifos.application.holiday.business.Holiday; import org.mifos.application.holiday.business.HolidayBO; import org.mifos.application.holiday.business.HolidayPK; import org.mifos.application.holiday.business.RepaymentRuleEntity; import org.mifos.application.holiday.persistence.HolidayPersistence; import org.mifos.application.holiday.util.helpers.RepaymentRuleTypes; import org.mifos.application.master.business.CustomFieldType; import org.mifos.application.master.business.CustomFieldView; import org.mifos.application.master.business.InterestTypesEntity; import org.mifos.application.master.business.MifosCurrency; import org.mifos.application.master.business.PaymentTypeEntity; import org.mifos.application.master.business.FundCodeEntity; import org.mifos.application.meeting.business.MeetingBO; import org.mifos.application.meeting.exceptions.MeetingException; import org.mifos.application.meeting.util.helpers.RecurrenceType; import org.mifos.application.meeting.util.helpers.WeekDay; import org.mifos.application.util.helpers.EntityType; import org.mifos.application.util.helpers.YesNoFlag; import org.mifos.config.AccountingRules; import org.mifos.config.AccountingRulesConstants; import org.mifos.config.ConfigurationManager; import org.mifos.config.FiscalCalendarRules; import org.mifos.config.business.Configuration; import org.mifos.config.persistence.ConfigurationPersistence; import org.mifos.customers.business.CustomerBO; import org.mifos.customers.business.CustomerBOTestUtils; import org.mifos.customers.business.CustomerStatusEntity; import org.mifos.customers.client.business.ClientBO; import org.mifos.customers.client.business.ClientPerformanceHistoryEntity; import org.mifos.customers.group.business.GroupPerformanceHistoryEntity; import org.mifos.customers.personnel.util.helpers.PersonnelConstants; import org.mifos.customers.util.helpers.CustomerStatus; import org.mifos.framework.MifosIntegrationTestCase; import org.mifos.framework.TestUtils; import org.mifos.framework.components.audit.business.AuditLog; import org.mifos.framework.components.audit.business.AuditLogRecord; import org.mifos.framework.exceptions.ApplicationException; import org.mifos.framework.exceptions.InvalidDateException; import org.mifos.framework.exceptions.PersistenceException; import org.mifos.framework.exceptions.SystemException; import org.mifos.framework.hibernate.helper.StaticHibernateUtil; import org.mifos.framework.persistence.TestDatabase; import org.mifos.framework.persistence.TestObjectPersistence; import org.mifos.framework.util.DateTimeService; import org.mifos.framework.util.helpers.DateUtils; import org.mifos.framework.util.helpers.Money; import org.mifos.framework.util.helpers.TestObjectFactory; import org.mifos.security.util.UserContext; public class LoanBOIntegrationTest extends MifosIntegrationTestCase { public LoanBOIntegrationTest() throws Exception { super(); } private static final double DELTA = 0.00000001; private static final double DEFAULT_LOAN_AMOUNT = 300.0; private LoanOfferingBO loanOffering = null; // TODO: probably should be of type LoanBO private AccountBO accountBO = null; private AccountBO badAccountBO = null; private CustomerBO center = null; private CustomerBO group = null; private CustomerBO client = null; private AccountPersistence accountPersistence = null; private MeetingBO meeting; private UserContext userContext = null; private final List<FeeView> feeViews = new ArrayList<FeeView>(); private BigDecimal savedInitialRoundOffMultiple = null; private BigDecimal savedFinalRoundOffMultiple = null; private RoundingMode savedCurrencyRoundingMode = null; private RoundingMode savedInitialRoundingMode = null; private RoundingMode savedFinalRoundingMode = null; private Short savedDigitAfterDecimal; private LoanDao loanDao; private List<Days> workingDays = new FiscalCalendarRules().getWorkingDaysAsJodaTimeDays(); private List<Holiday> holidays = new ArrayList<Holiday>(); @Override protected void setUp() throws Exception { super.setUp(); userContext = TestObjectFactory.getContext(); accountPersistence = new AccountPersistence(); savedInitialRoundOffMultiple = AccountingRules.getInitialRoundOffMultiple(); savedFinalRoundOffMultiple = AccountingRules.getFinalRoundOffMultiple(); savedCurrencyRoundingMode = AccountingRules.getCurrencyRoundingMode(); savedDigitAfterDecimal = AccountingRules.getDigitsAfterDecimal(); savedInitialRoundingMode = AccountingRules.getInitialRoundingMode(); savedFinalRoundingMode = AccountingRules.getFinalRoundingMode(); AccountingRules.setInitialRoundOffMultiple(new BigDecimal("1")); AccountingRules.setFinalRoundOffMultiple(new BigDecimal("1")); AccountingRules.setCurrencyRoundingMode(RoundingMode.CEILING); AccountingRules.setInitialRoundingMode(RoundingMode.CEILING); AccountingRules.setFinalRoundingMode(RoundingMode.CEILING); AccountingRules.setDigitsAfterDecimal((short) 1); loanDao = new LoanDao(); } @Override protected void tearDown() throws Exception { try { TestObjectFactory.removeObject(loanOffering); if (accountBO != null) { accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); } if (badAccountBO != null) { badAccountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, badAccountBO.getAccountId()); } if (group != null) { group = (CustomerBO) StaticHibernateUtil.getSessionTL().get(CustomerBO.class, group.getCustomerId()); } if (center != null) { center = (CustomerBO) StaticHibernateUtil.getSessionTL().get(CustomerBO.class, center.getCustomerId()); } TestObjectFactory.cleanUp(accountBO); TestObjectFactory.cleanUp(badAccountBO); TestObjectFactory.cleanUp(client); TestObjectFactory.cleanUp(group); TestObjectFactory.cleanUp(center); } catch (Exception e) { // TODO Whoops, cleanup didnt work, reset db TestDatabase.resetMySQLDatabase(); } AccountingRules.setInitialRoundOffMultiple(savedInitialRoundOffMultiple); AccountingRules.setFinalRoundOffMultiple(savedFinalRoundOffMultiple); AccountingRules.setCurrencyRoundingMode(savedCurrencyRoundingMode); AccountingRules.setDigitsAfterDecimal(savedDigitAfterDecimal); AccountingRules.setInitialRoundingMode(savedInitialRoundingMode); AccountingRules.setFinalRoundingMode(savedFinalRoundingMode); StaticHibernateUtil.closeSession(); new DateTimeService().resetToCurrentSystemDateTime(); new ConfigurationPersistence() .updateConfigurationKeyValueInteger("repaymentSchedulesIndependentOfMeetingIsEnabled", 0); super.tearDown(); } private AccountBO getLoanAccount(final Date startDate, final AccountState state) throws MeetingException { createInitialCustomers(startDate); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, center.getCustomerMeeting().getMeeting()); return TestObjectFactory.createLoanAccount("42423142341", group, state, startDate, loanOffering); } private void createInitialCustomers(final Date meetingStartDate) throws MeetingException { Calendar cal = Calendar.getInstance(); cal.setTime(meetingStartDate); // create a meeting based on meetingStartDate rather than the // current system date MeetingBO meeting = TestObjectFactory .createMeeting(new MeetingBO(WeekDay.getWeekDay(cal.get(Calendar.DAY_OF_WEEK)), EVERY_WEEK, meetingStartDate, CUSTOMER_MEETING, "place")); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); } private HolidayBO createHoliday(final Date holidayDate) throws PersistenceException, ApplicationException { // next working day repayment rule RepaymentRuleEntity entity = new HolidayPersistence() .getRepaymentRule(RepaymentRuleTypes.NEXT_WORKING_DAY.getValue()); HolidayBO holiday = new HolidayBO(new HolidayPK((short) 1, holidayDate), holidayDate, "a holiday", entity); holiday.setValidationEnabled(false); holiday.save(); StaticHibernateUtil.commitTransaction(); return holiday; } private void deleteHoliday(final HolidayBO holiday) throws PersistenceException { new HolidayPersistence().delete(holiday); StaticHibernateUtil.commitTransaction(); } // see issue MIFOS-2154 public void testVerifyNoDateShiftWhenDisbursingAnLsimLoanWithModifiedDisbursalDate() throws Exception { short graceDuration = (short) 0; new DateTimeService().setCurrentDateTime(new LocalDate(2010, 2, 25).toDateTimeAtStartOfDay()); new ConfigurationPersistence() .updateConfigurationKeyValueInteger("repaymentSchedulesIndependentOfMeetingIsEnabled", 1); MeetingBO meeting = TestObjectFactory.createMeeting(new MeetingBuilder().buildMonthlyForDayNumber(1)); center = TestObjectFactory.createCenter(this.getClass().getSimpleName() + " Center", meeting, TestObjectFactory.SAMPLE_BRANCH_OFFICE, PersonnelConstants.TEST_USER, null); group = TestObjectFactory.createNoFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); client = TestObjectFactory.createClient(this.getClass().getSimpleName() + " Client", CustomerStatus.CLIENT_ACTIVE, group, null, (String) null, new Date(1222333444000L)); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.CLIENTS, new DateTimeService().getCurrentJavaDateTime(), PrdStatus.LOAN_ACTIVE, 300.0, 12.0, (short) 3, InterestType.DECLINING, center.getCustomerMeeting().getMeeting()); List<FeeView> feeViewList = new ArrayList<FeeView>(); boolean loanScheduleIndependentOfMeeting = true; accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, client, AccountState.LOAN_APPROVED, new Money(getCurrency(), "1000.0"), Short.valueOf("6"), new DateMidnight(2010, 3, 5).toDate(), false, // 6 installments 12.0, graceDuration, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, loanScheduleIndependentOfMeeting); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); Assert.assertEquals(new LocalDate(2010, 4, 1), new LocalDate(paymentsArray[0].getActionDate().getTime())); new DateTimeService().setCurrentDateTime(new LocalDate(2010, 3, 8).toDateTimeAtStartOfDay()); List<PaymentTypeEntity> paymentTypeEntities = new AcceptedPaymentTypeService() .getAcceptedPaymentTypes(TestObjectFactory.TEST_LOCALE); AccountPaymentEntity accountPaymentEntity = new AccountPaymentEntity(accountBO, new Money(Money.getDefaultCurrency(), new BigDecimal(1000)), "", new DateTimeService().getCurrentJavaDateTime(), paymentTypeEntities.get(0), new DateTimeService().getCurrentJavaDateTime()); ((LoanBO) accountBO).disburseLoan(accountPaymentEntity); actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); Assert.assertEquals(new LocalDate(2010, 4, 1), new LocalDate(paymentsArray[0].getActionDate().getTime())); } public void testCreateLoanAccountWithDecliningInterestGraceAllRepaymentsWithLsimOn() throws Exception { short graceDuration = (short) 2; MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, new Date(System.currentTimeMillis()), PrdStatus.LOAN_ACTIVE, 300.0, 12.0, (short) 3, InterestType.DECLINING, center.getCustomerMeeting().getMeeting()); List<FeeView> feeViewList = new ArrayList<FeeView>(); boolean loanScheduleIndependentOfMeeting = true; accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, // 6 installments 12.0, graceDuration, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, loanScheduleIndependentOfMeeting); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(14 * (0 + graceDuration)), "49.6", "1.4", fees0, paymentsArray[0]); checkLoanScheduleEntity(incrementCurrentDate(14 * (1 + graceDuration)), "49.8", "1.2", fees0, paymentsArray[1]); checkLoanScheduleEntity(incrementCurrentDate(14 * (2 + graceDuration)), "50.0", "1.0", fees0, paymentsArray[2]); checkLoanScheduleEntity(incrementCurrentDate(14 * (3 + graceDuration)), "50.3", "0.7", fees0, paymentsArray[3]); checkLoanScheduleEntity(incrementCurrentDate(14 * (4 + graceDuration)), "50.5", "0.5", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * (5 + graceDuration)), "49.8", "0.2", fees0, paymentsArray[5]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); } // set up a loan similar to those required by Al Majmoua public void testCreateLoanScheduleLikeAlMajmoua() throws Exception { String loanAmount = "950000.0"; double interestRate = 15.6; int numInstallments = 12; // total interest = 148200 // total payment = 950000 + 148200 = 1098200 // initial installments = 92000.0 String initialInstallmentPrincipal = "79650.0"; String initialInstallmentInterest = "12350.0"; // final installment = 86200.0 String finalInstallmentPrincipal = "73850.0"; String finalInstallmentInterest = "12350.0"; String currencyCodeSuffix = "." + TestUtils.EURO.getCurrencyCode(); ConfigurationManager configMgr = ConfigurationManager.getInstance(); configMgr.setProperty(AccountingRulesConstants.DIGITS_AFTER_DECIMAL + currencyCodeSuffix, "0"); configMgr.setProperty(AccountingRulesConstants.INITIAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix, "1000"); configMgr.setProperty(AccountingRulesConstants.FINAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix, "100"); configMgr.setProperty(AccountingRulesConstants.ADDITIONAL_CURRENCY_CODES, TestUtils.EURO.getCurrencyCode()); DateMidnight startDate = new DateMidnight(2010, 1, 4); new DateTimeService().setCurrentDateTime(new DateTime(startDate.getMillis())); try { MifosCurrency currency = TestUtils.EURO; setupMonthlyLoanForCurrencyTests(loanAmount, currency, interestRate, numInstallments, startDate); validateLoanForMonthlyCurrencyTests(loanAmount, initialInstallmentPrincipal, finalInstallmentPrincipal, initialInstallmentInterest, finalInstallmentInterest, startDate, currency, numInstallments); } finally { new DateTimeService().resetToCurrentSystemDateTime(); configMgr.clearProperty(AccountingRulesConstants.DIGITS_AFTER_DECIMAL + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.INITIAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.FINAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.ADDITIONAL_CURRENCY_CODES); } } /* * Note: defaults are digits after decimal = 1, initial rounding multiple = 1 * final rounding multiple = 1 */ public void testCreateLoanScheduleWithDefaultCurrency() throws Exception { String loanAmount = "10000.0"; double interestRate = 100.0; int numInstallments = 10; // initial installments = 1384 String initialInstallmentPrincipal = "1000.4"; String initialInstallmentInterest = "383.6"; // final installment = 1380 String finalInstallmentPrincipal = "996.4"; String finalInstallmentInterest = "383.6"; MifosCurrency currency = getCurrency(); DateMidnight startDate = setupLoanForCurrencyTests(loanAmount, currency, interestRate, numInstallments); validateLoanForCurrencyTests(loanAmount, initialInstallmentPrincipal, finalInstallmentPrincipal, initialInstallmentInterest, finalInstallmentInterest, startDate, currency, numInstallments); } public void testCreateLoanScheduleWithNonDefaultCurrencyAndZeroDigitsAfterDecimal() throws Exception { String loanAmount = "10000.0"; double interestRate = 100.0; int numInstallments = 10; // initial installments = 1400.0 String initialInstallmentPrincipal = "1016.0"; String initialInstallmentInterest = "384.0"; // final installment = 1240.0 String finalInstallmentPrincipal = "856.0"; String finalInstallmentInterest = "384.0"; String currencyCodeSuffix = "." + TestUtils.EURO.getCurrencyCode(); ConfigurationManager configMgr = ConfigurationManager.getInstance(); configMgr.setProperty(AccountingRulesConstants.DIGITS_AFTER_DECIMAL + currencyCodeSuffix, "0"); configMgr.setProperty(AccountingRulesConstants.INITIAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix, "100"); configMgr.setProperty(AccountingRulesConstants.FINAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix, "10"); configMgr.setProperty(AccountingRulesConstants.ADDITIONAL_CURRENCY_CODES, TestUtils.EURO.getCurrencyCode()); try { MifosCurrency currency = TestUtils.EURO; DateMidnight startDate = setupLoanForCurrencyTests(loanAmount, currency, interestRate, numInstallments); validateLoanForCurrencyTests(loanAmount, initialInstallmentPrincipal, finalInstallmentPrincipal, initialInstallmentInterest, finalInstallmentInterest, startDate, currency, numInstallments); } finally { configMgr.clearProperty(AccountingRulesConstants.DIGITS_AFTER_DECIMAL + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.INITIAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.FINAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.ADDITIONAL_CURRENCY_CODES); } } public void testCreateLoanScheduleWithNonDefaultCurrencyAndOneDigitAfterDecimal() throws Exception { String loanAmount = "10000.0"; double interestRate = 100.0; int numInstallments = 10; // initial installments = 1400.0 String initialInstallmentPrincipal = "1016.4"; String initialInstallmentInterest = "383.6"; // final installment = 1240.0 String finalInstallmentPrincipal = "852.4"; String finalInstallmentInterest = "387.6"; String currencyCodeSuffix = "." + TestUtils.EURO.getCurrencyCode(); ConfigurationManager configMgr = ConfigurationManager.getInstance(); configMgr.setProperty(AccountingRulesConstants.DIGITS_AFTER_DECIMAL + currencyCodeSuffix, "1"); configMgr.setProperty(AccountingRulesConstants.INITIAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix, "100"); configMgr.setProperty(AccountingRulesConstants.FINAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix, "10"); configMgr.setProperty(AccountingRulesConstants.ADDITIONAL_CURRENCY_CODES, TestUtils.EURO.getCurrencyCode()); try { MifosCurrency currency = TestUtils.EURO; DateMidnight startDate = setupLoanForCurrencyTests(loanAmount, currency, interestRate, numInstallments); validateLoanForCurrencyTests(loanAmount, initialInstallmentPrincipal, finalInstallmentPrincipal, initialInstallmentInterest, finalInstallmentInterest, startDate, currency, numInstallments); } finally { configMgr.clearProperty(AccountingRulesConstants.DIGITS_AFTER_DECIMAL + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.INITIAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.FINAL_ROUND_OFF_MULTIPLE + currencyCodeSuffix); configMgr.clearProperty(AccountingRulesConstants.ADDITIONAL_CURRENCY_CODES); } } private void validateLoanForCurrencyTests(String loanAmount, String initialInstallmentPrincipal, String finalInstallmentPrincipal, String initialInstallmentInterest, String finalInstallmentInterest, DateMidnight startDate, MifosCurrency currency, int numInstallments) { Assert.assertEquals(numInstallments, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); for (int installment = 1; installment < numInstallments; ++installment) { checkLoanScheduleEntity(startDate.plusDays(14 * installment).toDate(), initialInstallmentPrincipal, initialInstallmentInterest, fees0, paymentsArray[installment - 1]); } checkLoanScheduleEntity(startDate.plusDays(14 * numInstallments).toDate(), finalInstallmentPrincipal, finalInstallmentInterest, fees0, paymentsArray[numInstallments - 1]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(currency, loanAmount), loanSummaryEntity.getOriginalPrincipal()); } private void validateLoanForMonthlyCurrencyTests(String loanAmount, String initialInstallmentPrincipal, String finalInstallmentPrincipal, String initialInstallmentInterest, String finalInstallmentInterest, DateMidnight startDate, MifosCurrency currency, int numInstallments) { Assert.assertEquals(numInstallments, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); for (int installment = 1; installment < numInstallments; ++installment) { checkLoanScheduleEntity(startDate.plusMonths(installment).toDate(), initialInstallmentPrincipal, initialInstallmentInterest, fees0, paymentsArray[installment - 1]); } checkLoanScheduleEntity(startDate.plusMonths(numInstallments).toDate(), finalInstallmentPrincipal, finalInstallmentInterest, fees0, paymentsArray[numInstallments - 1]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(currency, loanAmount), loanSummaryEntity.getOriginalPrincipal()); } private void setupMonthlyLoanForCurrencyTests(String loanAmount, MifosCurrency currency, double interestRate, int numInstallments, DateMidnight startDate) throws AccountException, MeetingException { MeetingBO meeting = new MeetingBuilder().customerMeeting().every(1) .buildMonthlyForDayNumber(startDate.getDayOfMonth()); center = TestObjectFactory.createCenter(this.getClass().getSimpleName() + " Center", meeting, (List<FeeView>) null); group = TestObjectFactory.createNoFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "L", ApplicableTo.GROUPS, startDate.toDate(), PrdStatus.LOAN_ACTIVE, 300.0, 0.0, (short) 3, InterestType.FLAT, false, false, center.getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1", currency); List<FeeView> feeViewList = new ArrayList<FeeView>(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(currency, loanAmount), (short) numInstallments, startDate.toDate(), false, interestRate, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); } private DateMidnight setupLoanForCurrencyTests(String loanAmount, MifosCurrency currency, double interestRate, int numInstallments) throws AccountException { DateMidnight startDate = new DateMidnight(); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "L", ApplicableTo.GROUPS, startDate.toDate(), PrdStatus.LOAN_ACTIVE, 300.0, 0.0, (short) 3, InterestType.FLAT, false, false, center.getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1", currency); List<FeeView> feeViewList = new ArrayList<FeeView>(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(currency, loanAmount), (short) numInstallments, startDate.toDate(), false, interestRate, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); return startDate; } public void testApplyPeriodicFee() throws Exception { accountBO = getBasicLoanAccount(); Money intialTotalFeeAmount = ((LoanBO) accountBO).getLoanSummary().getOriginalFees(); TestObjectFactory.flushandCloseSession(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "200", RecurrenceType.WEEKLY, Short.valueOf("2")); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); UserContext uc = TestUtils.makeUser(); accountBO.setUserContext(uc); accountBO.applyCharge(periodicFee.getFeeId(), ((AmountFeeBO) periodicFee).getFeeAmount().getAmountDoubleValue()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Date lastAppliedDate = null; Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Periodic Fee", "200.0");// missing an entry fees1.put("Mainatnence Fee", "100.0"); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils .getSortedAccountActionDateEntity(((LoanBO) accountBO).getAccountActionDates()); Assert.assertEquals(6, paymentsArray.length); checkFees(fees1, paymentsArray[0], false); checkFees(fees1, paymentsArray[2], false); checkFees(fees1, paymentsArray[4], false); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("5"))) { Assert.assertEquals(2, loanScheduleEntity.getAccountFeesActionDetails().size()); lastAppliedDate = loanScheduleEntity.getActionDate(); } } Assert.assertEquals(intialTotalFeeAmount.add(new Money(getCurrency(), "600.0")), ((LoanBO) accountBO).getLoanSummary().getOriginalFees()); LoanActivityEntity loanActivityEntity = (LoanActivityEntity) ((LoanBO) accountBO).getLoanActivityDetails() .toArray()[0]; Assert.assertEquals(periodicFee.getFeeName() + " applied", loanActivityEntity.getComments()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getOriginalFees(), loanActivityEntity.getFeeOutstanding()); AccountFeesEntity accountFeesEntity = accountBO.getAccountFees(periodicFee.getFeeId()); Assert.assertEquals(FeeStatus.ACTIVE, accountFeesEntity.getFeeStatusAsEnum()); Assert.assertEquals(DateUtils.getDateWithoutTimeStamp(lastAppliedDate.getTime()), DateUtils.getDateWithoutTimeStamp(accountFeesEntity.getLastAppliedDate().getTime())); } public void testApplyPeriodicFeeWithHoliday() throws Exception { Date startDate = DateUtils.getDate(2008, Calendar.MAY, 23); new DateTimeService().setCurrentDateTime(new DateTime(startDate)); accountBO = getLoanAccount(startDate, AccountState.LOAN_APPROVED); Money intialTotalFeeAmount = ((LoanBO) accountBO).getLoanSummary().getOriginalFees(); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); // create holiday on first installment date HolidayBO holiday = createHoliday(DateUtils.getDate(2008, Calendar.MAY, 30)); try { LoanBO loanBO = (LoanBO) accountBO; loanBO.updateLoan(loanBO.isInterestDeductedAtDisbursement(), loanBO.getLoanAmount(), loanBO.getInterestRate(), loanBO.getNoOfInstallments(), loanBO.getDisbursementDate(), loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), "Loan account updated", null, null, false, null, null); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "25", RecurrenceType.WEEKLY, EVERY_WEEK); UserContext uc = TestUtils.makeUser(); loanBO.setUserContext(uc); loanBO.applyCharge(periodicFee.getFeeId(), ((AmountFeeBO) periodicFee).getFeeAmount().getAmountDoubleValue()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Mainatnence Fee", "100.0"); Map<String, String> fees2 = new HashMap<String, String>(); fees2.put("Mainatnence Fee", "100.0"); fees2.put("Periodic Fee", "25.0"); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils .getSortedAccountActionDateEntity(loanBO.getAccountActionDates()); List<Date> installmentDates = new ArrayList<Date>(); List<Date> feeDates = new ArrayList<Date>(); for (LoanScheduleEntity loanScheduleEntity : paymentsArray) { installmentDates.add(loanScheduleEntity.getActionDate()); for (AccountFeesActionDetailEntity accountFeesActionDetailEntity : loanScheduleEntity .getAccountFeesActionDetails()) { Date feeDate = accountFeesActionDetailEntity.getAccountActionDate().getActionDate(); feeDates.add(feeDate); } } Assert.assertEquals(6, paymentsArray.length); checkFees(fees2, paymentsArray[0], false); checkFees(fees2, paymentsArray[1], false); checkFees(fees2, paymentsArray[2], false); checkFees(fees2, paymentsArray[3], false); checkFees(fees2, paymentsArray[4], false); checkFees(fees2, paymentsArray[5], false); List<Date> expectedDates = new ArrayList<Date>(); expectedDates.add(DateUtils.getDate(2008, Calendar.MAY, 31)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 06)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 13)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 20)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 27)); expectedDates.add(DateUtils.getDate(2008, Calendar.JULY, 04)); int i = 0; for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; Assert.assertEquals(expectedDates.get(i++), loanScheduleEntity.getActionDate()); Assert.assertEquals(new Money(getCurrency(), "125"), loanScheduleEntity.getTotalFees()); } Assert.assertEquals(intialTotalFeeAmount.add(new Money(getCurrency(), "750.0")), loanBO.getLoanSummary().getOriginalFees()); } finally { // make sure that we don't leave any persistent changes that could // affect subsequent tests new DateTimeService().resetToCurrentSystemDateTime(); deleteHoliday(holiday); } } public void testPeriodicFeeWithHoliday() throws Exception { Date startDate = DateUtils.getDate(2008, Calendar.MAY, 23); new DateTimeService().setCurrentDateTime(new DateTime(startDate)); accountBO = getLoanAccount(startDate, AccountState.LOAN_APPROVED); Money intialTotalFeeAmount = ((LoanBO) accountBO).getLoanSummary().getOriginalFees(); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); // create holiday on first installment date HolidayBO holiday = createHoliday(DateUtils.getDate(2008, Calendar.MAY, 30)); try { LoanBO loanBO = (LoanBO) accountBO; loanBO.updateLoan(loanBO.isInterestDeductedAtDisbursement(), loanBO.getLoanAmount(), loanBO.getInterestRate(), loanBO.getNoOfInstallments(), loanBO.getDisbursementDate(), loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), "Loan account updated", null, null, false, null, null); Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Mainatnence Fee", "100.0"); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils .getSortedAccountActionDateEntity(loanBO.getAccountActionDates()); List<Date> installmentDates = new ArrayList<Date>(); List<Date> feeDates = new ArrayList<Date>(); for (LoanScheduleEntity loanScheduleEntity : paymentsArray) { installmentDates.add(loanScheduleEntity.getActionDate()); for (AccountFeesActionDetailEntity accountFeesActionDetailEntity : loanScheduleEntity .getAccountFeesActionDetails()) { Date feeDate = accountFeesActionDetailEntity.getAccountActionDate().getActionDate(); feeDates.add(feeDate); } } System.out.println(installmentDates); System.out.println(feeDates); Assert.assertEquals(6, paymentsArray.length); checkFees(fees1, paymentsArray[0], false); checkFees(fees1, paymentsArray[1], false); checkFees(fees1, paymentsArray[2], false); checkFees(fees1, paymentsArray[3], false); checkFees(fees1, paymentsArray[4], false); checkFees(fees1, paymentsArray[5], false); List<Date> expectedDates = new ArrayList<Date>(); expectedDates.add(DateUtils.getDate(2008, Calendar.MAY, 31)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 06)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 13)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 20)); expectedDates.add(DateUtils.getDate(2008, Calendar.JUNE, 27)); expectedDates.add(DateUtils.getDate(2008, Calendar.JULY, 04)); int i = 0; for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; Assert.assertEquals(expectedDates.get(i++), loanScheduleEntity.getActionDate()); Assert.assertEquals(new Money(getCurrency(), "100"), loanScheduleEntity.getTotalFees()); } Assert.assertEquals(intialTotalFeeAmount.add(new Money(getCurrency(), "600.0")), loanBO.getLoanSummary().getOriginalFees()); } finally { // make sure that we don't leave any persistent changes that could // affect subsequent tests new DateTimeService().resetToCurrentSystemDateTime(); deleteHoliday(holiday); } } public void testCreateIndividualLoan() throws Exception { createInitialCustomers(); MeetingBO meeting = TestObjectFactory.createLoanMeeting(group.getCustomerMeeting().getMeeting()); Date startDate = new Date(System.currentTimeMillis()); loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 1, InterestType.FLAT, meeting); List<Date> meetingDates = TestObjectFactory.getMeetingDates(meeting, 1); try { LoanBO.createIndividualLoan(userContext, loanOffering, group, AccountState.LOAN_PARTIAL_APPLICATION, TestUtils.createMoney("300.0"), Short.valueOf("1"), meetingDates.get(0), true, false, 10.0, (short) 0, null, new ArrayList<FeeView>(), null, false); Assert.fail(); } catch (AccountException e) { Assert.assertTrue(true); } } public void testWaiveMiscFeeAfterPayment() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); List<FeeView> feeViews = new ArrayList<FeeView>(); boolean isInterestDedAtDisb = false; Short noOfinstallments = (short) 6; LoanBO loan = createAndRetrieveLoanAccount(loanOffering, isInterestDedAtDisb, feeViews, noOfinstallments); loan.setUserContext(TestUtils.makeUser()); loan.applyCharge(Short.valueOf("-1"), Double.valueOf("200")); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscFee(), new Money(getCurrency(), "200")); Assert.assertEquals(loanScheduleEntity.getMiscFeePaid(), new Money(getCurrency())); } } Assert.assertEquals(loan.getLoanSummary().getOriginalFees(), new Money(getCurrency(), "200")); Assert.assertEquals(loan.getLoanSummary().getFeesPaid(), new Money(getCurrency())); List<AccountActionDateEntity> accntActionDates = new ArrayList<AccountActionDateEntity>(); accntActionDates.addAll(loan.getAccountActionDates()); Date currentDate = new Date(System.currentTimeMillis()); PaymentData paymentData = TestObjectFactory.getLoanAccountPaymentData(accntActionDates, TestUtils.createMoney(200), null, accountBO.getPersonnel(), "receiptNum", Short.valueOf("1"), currentDate, currentDate); loan.applyPaymentWithPersist(paymentData); TestObjectFactory.updateObject(loan); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscFee(), new Money(getCurrency(), "200")); Assert.assertEquals(loanScheduleEntity.getMiscFeePaid(), new Money(getCurrency(), "200")); } } Assert.assertEquals(loan.getLoanSummary().getOriginalFees(), new Money(getCurrency(), "200")); Assert.assertEquals(loan.getLoanSummary().getFeesPaid(), new Money(getCurrency(), "200")); loan.applyCharge(Short.valueOf("-1"), Double.valueOf("300")); TestObjectFactory.updateObject(loan); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscFee(), new Money(getCurrency(), "500")); Assert.assertEquals(loanScheduleEntity.getMiscFeePaid(), new Money(getCurrency(), "200")); } } Assert.assertEquals(loan.getLoanSummary().getOriginalFees(), new Money(getCurrency(), "500")); Assert.assertEquals(loan.getLoanSummary().getFeesPaid(), new Money(getCurrency(), "200")); loan.waiveAmountDue(WaiveEnum.FEES); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscFee(), new Money(getCurrency(), "200")); Assert.assertEquals(loanScheduleEntity.getMiscFeePaid(), new Money(getCurrency(), "200")); } } Assert.assertEquals(loan.getLoanSummary().getOriginalFees(), new Money(getCurrency(), "200")); Assert.assertEquals(loan.getLoanSummary().getFeesPaid(), new Money(getCurrency(), "200")); } public void testWaiveMiscPenaltyAfterPayment() throws Exception { accountBO = getLoanAccount(); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(LoanBO.class, accountBO.getAccountId()); accountBO.setUserContext(TestUtils.makeUser()); Date currentDate = new Date(System.currentTimeMillis()); LoanBO loan = (LoanBO) accountBO; loan.applyCharge(Short.valueOf("-2"), Double.valueOf("200")); TestObjectFactory.updateObject(loan); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscPenalty(), new Money(getCurrency(), "200")); Assert.assertEquals(loanScheduleEntity.getMiscPenaltyPaid(), new Money(getCurrency())); } } Assert.assertEquals(loan.getLoanSummary().getOriginalPenalty(), new Money(getCurrency(), "200")); Assert.assertEquals(loan.getLoanSummary().getPenaltyPaid(), new Money(getCurrency())); List<AccountActionDateEntity> accntActionDates = new ArrayList<AccountActionDateEntity>(); accntActionDates.addAll(loan.getAccountActionDates()); PaymentData paymentData = TestObjectFactory.getLoanAccountPaymentData(accntActionDates, TestUtils.createMoney(200), null, accountBO.getPersonnel(), "receiptNum", Short.valueOf("1"), currentDate, currentDate); loan.applyPaymentWithPersist(paymentData); TestObjectFactory.updateObject(loan); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscPenalty(), new Money(getCurrency(), "200")); Assert.assertEquals(loanScheduleEntity.getMiscPenaltyPaid(), new Money(getCurrency(), "200")); } } Assert.assertEquals(loan.getLoanSummary().getOriginalPenalty(), new Money(getCurrency(), "200")); Assert.assertEquals(loan.getLoanSummary().getPenaltyPaid(), new Money(getCurrency(), "200")); loan.applyCharge(Short.valueOf("-2"), Double.valueOf("300")); TestObjectFactory.updateObject(loan); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscPenalty(), new Money(getCurrency(), "500")); Assert.assertEquals(loanScheduleEntity.getMiscPenaltyPaid(), new Money(getCurrency(), "200")); } } Assert.assertEquals(loan.getLoanSummary().getOriginalPenalty(), new Money(getCurrency(), "500")); Assert.assertEquals(loan.getLoanSummary().getPenaltyPaid(), new Money(getCurrency(), "200")); loan.waiveAmountDue(WaiveEnum.PENALTY); for (AccountActionDateEntity accountActionDateEntity : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(loanScheduleEntity.getMiscPenalty(), new Money(getCurrency(), "200")); Assert.assertEquals(loanScheduleEntity.getMiscPenaltyPaid(), new Money(getCurrency(), "200")); } } Assert.assertEquals(loan.getLoanSummary().getOriginalPenalty(), new Money(getCurrency(), "200")); Assert.assertEquals(loan.getLoanSummary().getPenaltyPaid(), new Money(getCurrency(), "200")); } public void testAddLoanDetailsForDisbursal() { LoanBO loan = (LoanBO) createLoanAccount(); loan.setLoanAmount(TestUtils.createMoney(100)); loan.setNoOfInstallments(Short.valueOf("5")); InterestTypesEntity interestType = new InterestTypesEntity(InterestType.FLAT); loan.setInterestType(interestType); List<LoanBO> loanWithDisbursalDate = new ArrayList<LoanBO>(); loanWithDisbursalDate.add(loan); CollectionSheetBO collSheet = new CollectionSheetBO(); collSheet.addLoanDetailsForDisbursal(loanWithDisbursalDate); CollSheetCustBO collectionSheetCustomer = collSheet .getCollectionSheetCustomerForCustomerId(group.getCustomerId()); Assert.assertNotNull(collectionSheetCustomer); Assert.assertEquals( collectionSheetCustomer.getLoanDetailsForAccntId(loan.getAccountId()).getTotalNoOfInstallments(), Short.valueOf("5")); } public void testPrdOfferingsCanCoexist() throws PersistenceException { LoanBO loan = (LoanBO) createLoanAccount(); Assert.assertTrue( new ProductMixBusinessService().canProductsCoExist(loan.getLoanOffering(), loan.getLoanOffering())); } public void testLoanPerfObject() throws PersistenceException { java.sql.Date currentDate = new java.sql.Date(System.currentTimeMillis()); createInitialObjects(); accountBO = getLoanAccount(client, meeting); LoanBO loanBO = (LoanBO) accountBO; LoanPerformanceHistoryEntity loanPerformanceHistory = loanBO.getPerformanceHistory(); loanPerformanceHistory.setNoOfPayments(Integer.valueOf("3")); loanPerformanceHistory.setLoanMaturityDate(currentDate); TestObjectFactory.updateObject(loanBO); loanBO = (LoanBO) new AccountPersistence().getAccount(loanBO.getAccountId()); Assert.assertEquals(Integer.valueOf("3"), loanBO.getPerformanceHistory().getNoOfPayments()); Assert.assertEquals(currentDate, loanBO.getPerformanceHistory().getLoanMaturityDate()); } /** * This test has been disabled until code is able to handle removing fees. * TODO: re-enable this test when loan schedule adjustments correctly handle * removing fees. */ public void xtestSuccessRemoveFees() throws Exception { accountBO = getLoanAccount(); UserContext uc = TestUtils.makeUser(); Set<AccountFeesEntity> accountFeesEntitySet = accountBO.getAccountFees(); ((LoanBO) accountBO).getLoanOffering().setPrinDueLastInst(false); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("2"))) { ((LoanScheduleEntity) accountActionDateEntity).setMiscFee(new Money(getCurrency(), "20.3")); } } Iterator<AccountFeesEntity> itr = accountFeesEntitySet.iterator(); while (itr.hasNext()) { accountBO.removeFees(itr.next().getFees().getFeeId(), uc.getId()); } StaticHibernateUtil.getTransaction().commit(); for (AccountFeesEntity accountFeesEntity : accountFeesEntitySet) { Assert.assertEquals(accountFeesEntity.getFeeStatusAsEnum(), FeeStatus.INACTIVE); } LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); for (LoanActivityEntity accountNonTrxnEntity : ((LoanBO) accountBO).getLoanActivityDetails()) { Assert.assertEquals(loanSummaryEntity.getOriginalFees().subtract(loanSummaryEntity.getFeesPaid()), accountNonTrxnEntity.getFeeOutstanding()); Assert.assertEquals( loanSummaryEntity.getOriginalPrincipal().subtract(loanSummaryEntity.getPrincipalPaid()), accountNonTrxnEntity.getPrincipalOutstanding()); Assert.assertEquals( loanSummaryEntity.getOriginalInterest().subtract(loanSummaryEntity.getInterestPaid()), accountNonTrxnEntity.getInterestOutstanding()); Assert.assertEquals(loanSummaryEntity.getOriginalPenalty().subtract(loanSummaryEntity.getPenaltyPaid()), accountNonTrxnEntity.getPenaltyOutstanding()); break; } for (AccountActionDateEntity accountActionDate : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDate; if (accountActionDate.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(new Money(getCurrency(), "212.0"), loanScheduleEntity.getTotalDueWithFees()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("2"))) { Assert.assertEquals(new Money(getCurrency(), "133.0"), loanScheduleEntity.getTotalDueWithFees()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("6"))) { Assert.assertEquals(new Money(getCurrency(), "111.3"), loanScheduleEntity.getTotalDueWithFees()); } else { Assert.assertEquals(new Money(getCurrency(), "112.0"), loanScheduleEntity.getTotalDueWithFees()); } } } /* * TODO: turn back on when IntersetDeductedAtDisbursement is re-enabled * * public void * testCreateLoanAccountWithIntersetDeductedAtDisbursementFailure() throws * Exception { createInitialCustomers(); MeetingBO meeting = * TestObjectFactory.createLoanMeeting(group * .getCustomerMeeting().getMeeting()); * * Date startDate = new Date(System.currentTimeMillis()); loanOffering = * TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, * startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 1, InterestType.FLAT, true, * true, meeting); List<Date> meetingDates = * TestObjectFactory.getMeetingDates(meeting, 1); MifosCurrency currency = * TestObjectFactory.getCurrency(); try { LoanOfferingInstallmentRange * eligibleInstallmentRange = * loanOffering.getEligibleInstallmentSameForAllLoan(); * LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_PARTIAL_APPLICATION, new Money(getCurrency(), currency, * "300.0"), Short.valueOf("1"), meetingDates.get(0), true, 10.0, (short) 0, * null, new ArrayList<FeeView>(), null, DEFAULT_LOAN_AMOUNT, * DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), * eligibleInstallmentRange.getMinNoOfInstall(), false, null); * * Assert.fail(); } catch (AccountException e) {Assert.assertTrue(true); } } */ public void testHandleArrearsAging_Create() throws Exception { Calendar calendar = new GregorianCalendar(); calendar.setTime(DateUtils.getCurrentDateWithoutTimeStamp()); calendar.add(calendar.WEEK_OF_MONTH, -2); java.sql.Date secondWeekDate = new java.sql.Date(calendar.getTimeInMillis()); accountBO = getLoanAccount(); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(secondWeekDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertNull(((LoanBO) accountBO).getLoanArrearsAgingEntity()); ((LoanBO) accountBO).handleArrearsAging(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); LoanArrearsAgingEntity agingEntity = ((LoanBO) accountBO).getLoanArrearsAgingEntity(); Assert.assertNotNull(agingEntity); Assert.assertEquals(new Money(getCurrency(), "100"), agingEntity.getOverduePrincipal()); Assert.assertEquals(new Money(getCurrency(), "12"), agingEntity.getOverdueInterest()); Assert.assertEquals(new Money(getCurrency(), "112"), agingEntity.getOverdueBalance()); Assert.assertEquals(Short.valueOf("14"), agingEntity.getDaysInArrears()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getPrincipalDue(), agingEntity.getUnpaidPrincipal()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getInterestDue(), agingEntity.getUnpaidInterest()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getPrincipalDue() .add(((LoanBO) accountBO).getLoanSummary().getInterestDue()), agingEntity.getUnpaidBalance()); Assert.assertEquals(((LoanBO) accountBO).getTotalPrincipalAmountInArrears(), agingEntity.getOverduePrincipal()); Assert.assertEquals(((LoanBO) accountBO).getTotalInterestAmountInArrears(), agingEntity.getOverdueInterest()); Assert.assertEquals(((LoanBO) accountBO).getTotalPrincipalAmountInArrears() .add(((LoanBO) accountBO).getTotalInterestAmountInArrears()), agingEntity.getOverdueBalance()); } public void testHandleArrearsAging_Update() throws Exception { testHandleArrearsAging_Create(); Calendar calendar = new GregorianCalendar(); calendar.setTime(DateUtils.getCurrentDateWithoutTimeStamp()); calendar.add(calendar.WEEK_OF_MONTH, -1); java.sql.Date lastWeekDate = new java.sql.Date(calendar.getTimeInMillis()); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 2) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertNotNull(((LoanBO) accountBO).getLoanArrearsAgingEntity()); ((LoanBO) accountBO).handleArrearsAging(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); LoanArrearsAgingEntity agingEntity = ((LoanBO) accountBO).getLoanArrearsAgingEntity(); Assert.assertEquals(new Money(getCurrency(), "200"), agingEntity.getOverduePrincipal()); Assert.assertEquals(new Money(getCurrency(), "24"), agingEntity.getOverdueInterest()); Assert.assertEquals(new Money(getCurrency(), "224"), agingEntity.getOverdueBalance()); Assert.assertEquals(Short.valueOf("14"), agingEntity.getDaysInArrears()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getPrincipalDue(), agingEntity.getUnpaidPrincipal()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getInterestDue(), agingEntity.getUnpaidInterest()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getPrincipalDue() .add(((LoanBO) accountBO).getLoanSummary().getInterestDue()), agingEntity.getUnpaidBalance()); Assert.assertEquals(((LoanBO) accountBO).getTotalPrincipalAmountInArrears(), agingEntity.getOverduePrincipal()); Assert.assertEquals(((LoanBO) accountBO).getTotalInterestAmountInArrears(), agingEntity.getOverdueInterest()); Assert.assertEquals(((LoanBO) accountBO).getTotalPrincipalAmountInArrears() .add(((LoanBO) accountBO).getTotalInterestAmountInArrears()), agingEntity.getOverdueBalance()); } public void testUpdateLoanForLogging() throws Exception { FundCodeEntity fundCodeEntity = (FundCodeEntity) StaticHibernateUtil.getSessionTL() .get(FundCodeEntity.class, (short) 1); FundBO fund = TestObjectFactory.createFund(fundCodeEntity, "Fund1"); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); TestObjectFactory.cleanUpChangeLog(); Date newDate = incrementCurrentDate(14); accountBO = getLoanAccount(); accountBO.setUserContext(TestUtils.makeUser()); StaticHibernateUtil.getInterceptor().createInitialValueMap(accountBO); LoanBO loanBO = (LoanBO) accountBO; ((LoanBO) accountBO).updateLoan(true, loanBO.getLoanAmount(), loanBO.getInterestRate(), loanBO.getNoOfInstallments(), newDate, (short) 2, TestObjectFactory.SAMPLE_BUSINESS_ACTIVITY_2, "Added note", null, null, false, null, fund); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); group = TestObjectFactory.getCustomer(group.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); List<AuditLog> auditLogList = TestObjectFactory.getChangeLog(EntityType.LOAN, accountBO.getAccountId()); Assert.assertEquals(1, auditLogList.size()); for (int auditLogListIndex = 0; auditLogListIndex < auditLogList.size(); auditLogListIndex++) { auditLogList.get(auditLogListIndex).getAuditLogRecords(); } Assert.assertEquals(EntityType.LOAN, auditLogList.get(0).getEntityTypeAsEnum()); Assert.assertEquals(4, auditLogList.get(0).getAuditLogRecords().size()); for (AuditLogRecord auditLogRecord : auditLogList.get(0).getAuditLogRecords()) { if (auditLogRecord.getFieldName().equalsIgnoreCase("Collateral Notes")) { Assert.assertEquals("-", auditLogRecord.getOldValue()); Assert.assertEquals("Added note", auditLogRecord.getNewValue()); } else if (auditLogRecord.getFieldName().equalsIgnoreCase("Sources of funds")) { Assert.assertEquals("-", auditLogRecord.getOldValue()); Assert.assertEquals("Fund1", auditLogRecord.getNewValue()); } else if (auditLogRecord.getFieldName().equalsIgnoreCase("Service Charge deducted At Disbursement")) { Assert.assertEquals("1", auditLogRecord.getOldValue()); Assert.assertEquals("0", auditLogRecord.getNewValue()); } } TestObjectFactory.cleanUpChangeLog(); } public void testGetTotalRepayAmountForCurrentDateBeforeFirstInstallment() { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); changeFirstInstallmentDateToNextDate(accountBO); Money totalRepaymentAmount = new Money(getCurrency()); for (AccountActionDateEntity accountAction : accountBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { totalRepaymentAmount = totalRepaymentAmount.add(accountActionDateEntity.getTotalDueWithFees()); } else { totalRepaymentAmount = totalRepaymentAmount.add(accountActionDateEntity.getPrincipal()); } } Assert.assertEquals(totalRepaymentAmount, ((LoanBO) accountBO).getTotalEarlyRepayAmount()); } public void testGetTotalRepayAmountForCurrentDateSameAsInstallmentDate() { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Money totalRepaymentAmount = new Money(getCurrency()); for (AccountActionDateEntity accountAction : accountBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { totalRepaymentAmount = totalRepaymentAmount.add(accountActionDateEntity.getTotalDueWithFees()); } else { totalRepaymentAmount = totalRepaymentAmount.add(accountActionDateEntity.getPrincipal()); } } Assert.assertEquals(totalRepaymentAmount, ((LoanBO) accountBO).getTotalEarlyRepayAmount()); } public void testGetTotalRepayAmountForCurrentDateLiesBetweenInstallmentDates() { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); changeFirstInstallmentDate(accountBO); Money totalRepaymentAmount = new Money(getCurrency()); for (AccountActionDateEntity accountAction : accountBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1")) || accountActionDateEntity.getInstallmentId().equals(Short.valueOf("2"))) { totalRepaymentAmount = totalRepaymentAmount.add(accountActionDateEntity.getTotalDueWithFees()); } else { totalRepaymentAmount = totalRepaymentAmount.add(accountActionDateEntity.getPrincipal()); } } Assert.assertEquals(totalRepaymentAmount, ((LoanBO) accountBO).getTotalEarlyRepayAmount()); } public void testMakeEarlyRepaymentForCurrentDateLiesBetweenInstallmentDates() throws Exception { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); changeFirstInstallmentDate(accountBO); LoanBO loanBO = (LoanBO) accountBO; UserContext uc = TestUtils.makeUser(); Money totalRepaymentAmount = loanBO.getTotalEarlyRepayAmount(); loanBO.makeEarlyRepayment(loanBO.getTotalEarlyRepayAmount(), null, null, "1", uc.getId()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(accountBO.getAccountState().getId(), Short.valueOf(AccountStates.LOANACC_OBLIGATIONSMET)); LoanSummaryEntity loanSummaryEntity = loanBO.getLoanSummary(); Assert.assertEquals(totalRepaymentAmount, loanSummaryEntity.getPrincipalPaid().add(loanSummaryEntity.getFeesPaid()) .add(loanSummaryEntity.getInterestPaid()).add(loanSummaryEntity.getPenaltyPaid())); Assert.assertEquals(1, accountBO.getAccountPayments().size()); // / Change this to more clearly separate what we are testing for from // the // machinery needed to get that data? // for (AccountPaymentEntity accountPaymentEntity : accountBO.getAccountPayments()) { Assert.assertEquals(6, accountPaymentEntity.getAccountTrxns().size()); for (AccountTrxnEntity accountTrxnEntity : accountPaymentEntity.getAccountTrxns()) { if (accountTrxnEntity.getInstallmentId().equals(Short.valueOf("1")) || accountTrxnEntity.getInstallmentId().equals(Short.valueOf("2"))) { Assert.assertEquals(new Money(getCurrency(), "212.0"), accountTrxnEntity.getAmount()); LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "100.0"), loanTrxnDetailEntity.getPrincipalAmount()); Assert.assertEquals(new Money(getCurrency(), "12.0"), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(6, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(1, loanTrxnDetailEntity.getFeesTrxnDetails().size()); for (FeesTrxnDetailEntity feesTrxnDetailEntity : loanTrxnDetailEntity.getFeesTrxnDetails()) { Assert.assertEquals(new Money(getCurrency(), "100.0"), feesTrxnDetailEntity.getFeeAmount()); } } else { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "100.0"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(2, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } } } } public void testMakeEarlyRepaymentForCurrentDateSameAsInstallmentDate() throws Exception { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loanBO = (LoanBO) accountBO; UserContext uc = TestUtils.makeUser(); Money totalRepaymentAmount = loanBO.getTotalEarlyRepayAmount(); loanBO.makeEarlyRepayment(loanBO.getTotalEarlyRepayAmount(), null, null, "1", uc.getId()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(accountBO.getAccountState().getId(), Short.valueOf(AccountStates.LOANACC_OBLIGATIONSMET)); LoanSummaryEntity loanSummaryEntity = loanBO.getLoanSummary(); Assert.assertEquals(totalRepaymentAmount, loanSummaryEntity.getPrincipalPaid().add(loanSummaryEntity.getFeesPaid()) .add(loanSummaryEntity.getInterestPaid()).add(loanSummaryEntity.getPenaltyPaid())); Assert.assertEquals(1, accountBO.getAccountPayments().size()); // Change this to more clearly separate what we are testing for from the // machinery needed to get that data? for (AccountPaymentEntity accountPaymentEntity : accountBO.getAccountPayments()) { Assert.assertEquals(6, accountPaymentEntity.getAccountTrxns().size()); for (AccountTrxnEntity accountTrxnEntity : accountPaymentEntity.getAccountTrxns()) { if (accountTrxnEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(new Money(getCurrency(), "212.0"), accountTrxnEntity.getAmount()); LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "100.0"), loanTrxnDetailEntity.getPrincipalAmount()); Assert.assertEquals(new Money(getCurrency(), "12.0"), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(6, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(1, loanTrxnDetailEntity.getFeesTrxnDetails().size()); for (FeesTrxnDetailEntity feesTrxnDetailEntity : loanTrxnDetailEntity.getFeesTrxnDetails()) { Assert.assertEquals(new Money(getCurrency(), "100.0"), feesTrxnDetailEntity.getFeeAmount()); } } else { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "100.0"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(2, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } } } } public void testMakeEarlyRepaymentOnPartiallyPaidAccount() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = createOfferingNoPrincipalInLastInstallment(startDate, center.getCustomerMeeting().getMeeting()); UserContext userContext = TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("1")); feeViewList.add(new FeeView(userContext, periodicFee)); FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, upfrontFee)); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); accountBO = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 1.2, (short) 0, null, feeViewList, getCustomFields(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Assert.assertEquals(1, accountBO.getAccountCustomFields().size()); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "160"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, startDate, startDate)); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(new Money(getCurrency()), ((LoanBO) accountBO).getTotalPaymentDue()); LoanBO loanBO = (LoanBO) accountBO; UserContext uc = TestUtils.makeUser(); Money totalRepaymentAmount = loanBO.getTotalEarlyRepayAmount(); Assert.assertEquals(new Money(getCurrency(), "300.2"), totalRepaymentAmount); loanBO.makeEarlyRepayment(loanBO.getTotalEarlyRepayAmount(), null, null, "1", uc.getId()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(accountBO.getAccountState().getId(), Short.valueOf(AccountStates.LOANACC_OBLIGATIONSMET)); LoanSummaryEntity loanSummaryEntity = loanBO.getLoanSummary(); Assert.assertEquals(new Money(getCurrency()), loanSummaryEntity.getPrincipalDue().add(loanSummaryEntity.getFeesDue()) .add(loanSummaryEntity.getInterestDue()).add(loanSummaryEntity.getPenaltyDue())); Assert.assertEquals(2, accountBO.getAccountPayments().size()); AccountPaymentEntity accountPaymentEntity = (AccountPaymentEntity) Arrays .asList(accountBO.getAccountPayments().toArray()).get(0); // Change this to more clearly separate what we are testing for from the // machinery needed to get that data? for (AccountTrxnEntity accountTrxnEntity : accountPaymentEntity.getAccountTrxns()) { if (accountTrxnEntity.getInstallmentId().equals(Short.valueOf("6"))) { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "46.0"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(2, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } else if (accountTrxnEntity.getInstallmentId().equals(Short.valueOf("1"))) { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "51.0"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency(), "0.2"), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(4, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } else { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "50.8"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(2, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } } } private LoanOfferingBO createOfferingNoPrincipalInLastInstallment(final Date startDate, final MeetingBO meeting) { return TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, DEFAULT_LOAN_AMOUNT, 1.2, 3, InterestType.FLAT, meeting); } public void testApplyRoundingAfterAddMiscFee() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = createOfferingNoPrincipalInLastInstallment(startDate, center.getCustomerMeeting().getMeeting()); UserContext userContext = TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "33", RecurrenceType.WEEKLY, Short.valueOf("1")); feeViewList.add(new FeeView(userContext, periodicFee)); // 20% of 300 = 60.0, applied to first installment FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, upfrontFee)); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); accountBO = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 0.0, (short) 0, null, feeViewList, null, DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); /* * StaticHibernateUtil.closeSession(); * * accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get( * AccountBO.class, accountBO.getAccountId()); * accountBO.applyPaymentWithPersist(TestObjectFactory * .getLoanAccountPaymentData(null, new Money(getCurrency(), "180.1"), * accountBO .getCustomer(), accountBO.getPersonnel(), "432423", (short) * 1, startDate, startDate)); * * StaticHibernateUtil.commitTransaction(); * StaticHibernateUtil.closeSession(); accountBO = (AccountBO) * StaticHibernateUtil.getSessionTL().get( AccountBO.class, * accountBO.getAccountId());Assert.assertEquals(new * Money(getCurrency()), ((LoanBO) accountBO).getTotalPaymentDue()); */ LoanBO loanBO = (LoanBO) accountBO; Assert.assertEquals(new Money(getCurrency(), "300.0"), loanBO.getLoanAmount()); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipal()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "93.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("2"))) { // periodic fee applies every 2nd week so no payments in even // weeks Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("3"))) { // pay periodic fee in 1st, 3rd, and 5th week Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("4"))) { // pay periodic fee in 1st, 3rd, and 5th week Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("5"))) { // pay periodic fee in 1st, 3rd, and 5th week Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("6"))) { // pay periodic fee in 1st, 3rd, and 5th week Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } } accountBO.applyCharge(Short.valueOf(AccountConstants.MISC_FEES), new Double("10.0")); accountBO.applyCharge(Short.valueOf(AccountConstants.MISC_PENALTY), new Double("2")); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipal()); Assert.assertEquals(new Money(getCurrency(), "10.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "93.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); Assert.assertEquals(new Money(getCurrency(), "2.0"), loanScheduleEntity.getMiscPenaltyDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("2"))) { // periodic fee applies every week so double fee payment (66) // due Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("3"))) { Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("4"))) { Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("5"))) { Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } else if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("6"))) { // pay periodic fee in 1st, 3rd, and 5th week Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getPrincipalDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getMiscFeeDue()); Assert.assertEquals(new Money(getCurrency(), "66.0"), loanScheduleEntity.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanScheduleEntity.getInterestDue()); } } } public void testMakeEarlyRepaymentOnPartiallyPaidPricipal() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = createOfferingNoPrincipalInLastInstallment(startDate, center.getCustomerMeeting().getMeeting()); UserContext userContext = TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("1")); feeViewList.add(new FeeView(userContext, periodicFee)); FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, upfrontFee)); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); accountBO = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 1.2, (short) 0, null, feeViewList, null, DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "180.1"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, startDate, startDate)); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(new Money(getCurrency()), ((LoanBO) accountBO).getTotalPaymentDue()); LoanBO loanBO = (LoanBO) accountBO; UserContext uc = TestUtils.makeUser(); Money totalRepaymentAmount = loanBO.getTotalEarlyRepayAmount(); Assert.assertEquals(new Money(getCurrency(), "280.1"), totalRepaymentAmount); loanBO.makeEarlyRepayment(loanBO.getTotalEarlyRepayAmount(), null, null, "1", uc.getId()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(accountBO.getAccountState().getId(), Short.valueOf(AccountStates.LOANACC_OBLIGATIONSMET)); LoanSummaryEntity loanSummaryEntity = loanBO.getLoanSummary(); Assert.assertEquals(new Money(getCurrency()), loanSummaryEntity.getPrincipalDue().add(loanSummaryEntity.getFeesDue()) .add(loanSummaryEntity.getInterestDue()).add(loanSummaryEntity.getPenaltyDue())); Assert.assertEquals(2, accountBO.getAccountPayments().size()); AccountPaymentEntity accountPaymentEntity = (AccountPaymentEntity) Arrays .asList(accountBO.getAccountPayments().toArray()).get(0); Assert.assertEquals(6, accountPaymentEntity.getAccountTrxns().size()); // Change this to more clearly separate what we are testing for from the // machinery needed to get that data? for (AccountTrxnEntity accountTrxnEntity : accountPaymentEntity.getAccountTrxns()) { if (accountTrxnEntity.getInstallmentId().equals(Short.valueOf("6"))) { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "46.0"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(2, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } else if (accountTrxnEntity.getInstallmentId().equals(Short.valueOf("1"))) { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "30.9"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(2, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } else { LoanTrxnDetailEntity loanTrxnDetailEntity = (LoanTrxnDetailEntity) accountTrxnEntity; Assert.assertEquals(new Money(getCurrency(), "50.8"), accountTrxnEntity.getAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getInterestAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscFeeAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getMiscPenaltyAmount()); Assert.assertEquals(new Money(getCurrency()), loanTrxnDetailEntity.getPenaltyAmount()); Assert.assertEquals(2, accountTrxnEntity.getFinancialTransactions().size()); Assert.assertEquals(0, loanTrxnDetailEntity.getFeesTrxnDetails().size()); } } } public void testUpdateTotalFeeAmount() { Date startDate = new Date(System.currentTimeMillis()); accountBO = getLoanAccount(AccountState.LOAN_APPROVED, startDate, 1); LoanBO loanBO = (LoanBO) accountBO; LoanSummaryEntity loanSummaryEntity = loanBO.getLoanSummary(); Money orignalFeesAmount = loanSummaryEntity.getOriginalFees(); loanBO.updateTotalFeeAmount(new Money(getCurrency(), "20")); Assert.assertEquals(loanSummaryEntity.getOriginalFees(), orignalFeesAmount.subtract(new Money(getCurrency(), "20"))); } public void testDisburseLoanWithFeeAtDisbursement() throws Exception { Date startDate = new Date(System.currentTimeMillis()); Money miscFee = new Money(getCurrency(), "20"); Money miscPenalty = new Money(getCurrency(), "50"); accountBO = getLoanAccountWithMiscFeeAndPenalty(AccountState.LOAN_APPROVED, startDate, 1, miscFee, miscPenalty); // disburse loan ((LoanBO) accountBO).disburseLoan("1234", startDate, Short.valueOf("1"), accountBO.getPersonnel(), startDate, Short.valueOf("1")); Session session = StaticHibernateUtil.getSessionTL(); StaticHibernateUtil.startTransaction(); session.save(accountBO); StaticHibernateUtil.getTransaction().commit(); for (AccountActionDateEntity accountAction : accountBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(miscPenalty, accountActionDateEntity.getMiscPenalty()); Assert.assertEquals(miscFee, accountActionDateEntity.getMiscFee()); break; } } List<AccountPaymentEntity> accountpayments = accountBO.getAccountPayments(); Assert.assertEquals(1, accountpayments.size()); for (AccountPaymentEntity entity : accountpayments) { Assert.assertEquals("1234", entity.getReceiptNumber()); // asssert loan trxns Set<AccountTrxnEntity> accountTrxns = entity.getAccountTrxns(); Assert.assertEquals(2, accountTrxns.size()); for (AccountTrxnEntity transaction : accountTrxns) { if (transaction.getAccountAction() == AccountActionTypes.FEE_REPAYMENT) { Assert.assertEquals(TestUtils.createMoney(30.0), transaction.getAmount()); // it should have two feetrxn's Set<FeesTrxnDetailEntity> feesTrxnDetails = ((LoanTrxnDetailEntity) transaction) .getFeesTrxnDetails(); Assert.assertEquals(2, feesTrxnDetails.size()); } if (transaction.getAccountAction() == AccountActionTypes.DISBURSAL) { Assert.assertEquals(TestUtils.createMoney(300.0), transaction.getAmount()); } Assert.assertEquals(accountBO.getAccountId(), transaction.getAccount().getAccountId()); } // check loan summary fee paid should be updated LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(TestUtils.createMoney(30.0), loanSummaryEntity.getFeesPaid()); // check the loan object for the disbursal date Assert.assertEquals(startDate, ((LoanBO) accountBO).getDisbursementDate()); // check new account state Assert.assertEquals(AccountStates.LOANACC_ACTIVEINGOODSTANDING, ((LoanBO) accountBO).getAccountState().getId().shortValue()); } LoanSummaryEntity loanSummary = ((LoanBO) accountBO).getLoanSummary(); for (LoanActivityEntity loanActivityEntity : ((LoanBO) accountBO).getLoanActivityDetails()) { if (loanActivityEntity.getComments().equalsIgnoreCase("Loan Disbursal")) { Assert.assertEquals(loanSummary.getOriginalPrincipal(), loanActivityEntity.getPrincipalOutstanding()); Assert.assertEquals(loanSummary.getOriginalFees(), loanActivityEntity.getFeeOutstanding()); break; } } accountBO = TestObjectFactory.getObject(LoanBO.class, accountBO.getAccountId()); } public void testDisbursalLoanNoFeeOrInterestAtDisbursal() throws Exception { Date startDate = new Date(System.currentTimeMillis()); accountBO = getLoanAccount(AccountState.LOAN_APPROVED, startDate, 3); // disburse loan ((LoanBO) accountBO).disburseLoan("1234", startDate, Short.valueOf("1"), accountBO.getPersonnel(), startDate, Short.valueOf("1")); Session session = StaticHibernateUtil.getSessionTL(); StaticHibernateUtil.startTransaction(); session.save(accountBO); StaticHibernateUtil.getTransaction().commit(); ((LoanBO) accountBO).setLoanMeeting(null); List<AccountPaymentEntity> accountpayments = accountBO.getAccountPayments(); Assert.assertEquals(1, accountpayments.size()); for (AccountPaymentEntity entity : accountpayments) { Assert.assertEquals("1234", entity.getReceiptNumber()); // asssert loan trxns Set<AccountTrxnEntity> accountTrxns = entity.getAccountTrxns(); Assert.assertEquals(1, accountTrxns.size()); AccountTrxnEntity accountTrxn = accountTrxns.iterator().next(); Assert.assertEquals(AccountActionTypes.DISBURSAL, accountTrxn.getAccountAction()); Assert.assertEquals(TestUtils.createMoney(300.0), accountTrxn.getAmount()); Assert.assertEquals(accountBO.getAccountId(), accountTrxn.getAccount().getAccountId()); } } /* * TODO: turn back on when IntersetDeductedAtDisbursement is re-enabled * * * public void testDisbursalLoanWithInterestDeductedAtDisbursal() throws * Exception { Date startDate = new Date(System.currentTimeMillis()); * accountBO = getLoanAccount(AccountState.LOAN_APPROVED, startDate, 2); int * statusChangeHistorySize = accountBO.getAccountStatusChangeHistory() * .size(); * * ((LoanBO) accountBO).disburseLoan("1234", startDate, Short.valueOf("1"), * accountBO.getPersonnel(), startDate, Short .valueOf("1")); Session * session = StaticHibernateUtil.getSessionTL(); * StaticHibernateUtil.startTransaction(); session.save(accountBO); * StaticHibernateUtil.getTransaction().commit(); ((LoanBO) * accountBO).setLoanMeeting(null); Set<AccountPaymentEntity> * accountpayments = accountBO .getAccountPayments();Assert.assertEquals(1, * accountpayments.size()); * * AccountPaymentEntity entity = accountpayments.iterator().next(); * Assert.assertEquals("1234", entity.getReceiptNumber()); // asssert loan * trxns Set<AccountTrxnEntity> accountTrxns = entity.getAccountTrxns(); * Assert.assertEquals(2, accountTrxns.size()); int finTransaction = 0; for * (AccountTrxnEntity transaction : accountTrxns) { finTransaction += * transaction.getFinancialTransactions().size(); AccountActionTypes * accountAction = transaction.getAccountAction(); if (accountAction == * AccountActionTypes.FEE_REPAYMENT) {Assert.assertEquals(40.0, * transaction.getAmount() ); // it should * have two feetrxn's Set<FeesTrxnDetailEntity> feesTrxnDetails = * ((LoanTrxnDetailEntity) transaction) .getFeesTrxnDetails(); * Assert.assertEquals(2, feesTrxnDetails.size()); * Assert.fail("This doesn't actually happen. " + * "Is it a copy-paste from a test which doesn't apply here?"); } else if * (accountAction == AccountActionTypes.DISBURSAL) * {Assert.assertEquals(300.0, transaction.getAmount() * ); } else if (accountAction == * AccountActionTypes.LOAN_REPAYMENT) {Assert.assertEquals(52.0, * transaction.getAmount() ); } else { * Assert.fail("unexpected account action " + accountAction.name()); } * * Assert.assertEquals(accountBO.getAccountId(), transaction.getAccount() * .getAccountId()); }Assert.assertEquals(10, finTransaction); // check loan * summary fee paid should be updated * * LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO) * .getLoanSummary();Assert.assertEquals(40.0, * loanSummaryEntity.getFeesPaid() ); * * // check new account state * Assert.assertEquals(AccountStates.LOANACC_ACTIVEINGOODSTANDING, ((LoanBO) * accountBO).getAccountState().getId().shortValue()); * Assert.assertEquals(statusChangeHistorySize + 1, accountBO * .getAccountStatusChangeHistory().size()); } */ public void testDisbursalLoanRegeneteRepaymentScheduleWithInvalidDisbDate() throws Exception { // Allowing loan disbursal dates to become independent of meeting // schedules. Date startDate = new Date(System.currentTimeMillis()); accountBO = getLoanAccount(AccountState.LOAN_APPROVED, startDate, 3); // disburse loan Calendar disbDate = new GregorianCalendar(); disbDate.setTimeInMillis(startDate.getTime()); disbDate.roll(Calendar.DATE, 1); Date disbursalDate = new Date(disbDate.getTimeInMillis()); try { ((LoanBO) accountBO).disburseLoan("1234", disbursalDate, Short.valueOf("1"), accountBO.getPersonnel(), startDate, Short.valueOf("1")); Assert.assertEquals(true, true); } catch (ApplicationException rse) { Assert.assertEquals(true, false); } finally { Session session = StaticHibernateUtil.getSessionTL(); StaticHibernateUtil.startTransaction(); ((LoanBO) accountBO).setLoanMeeting(null); session.update(accountBO); StaticHibernateUtil.getTransaction().commit(); } } public void testDisbursalLoanRegeneteRepaymentSchedule() throws Exception { Date startDate = new Date(System.currentTimeMillis()); accountBO = getLoanAccountWithMiscFeeAndPenalty(AccountState.LOAN_APPROVED, startDate, 3, new Money(getCurrency(), "20"), new Money(getCurrency(), "30")); Set<AccountActionDateEntity> intallments = accountBO.getAccountActionDates(); AccountActionDateEntity firstInstallment = null; for (AccountActionDateEntity entity : intallments) { if (entity.getInstallmentId().intValue() == 1) { firstInstallment = entity; break; } } Calendar disbursalDate = new GregorianCalendar(); disbursalDate.setTimeInMillis(firstInstallment.getActionDate().getTime()); Calendar cal = new GregorianCalendar(disbursalDate.get(Calendar.YEAR), disbursalDate.get(Calendar.MONTH), disbursalDate.get(Calendar.DATE), 0, 0); ((LoanBO) accountBO).disburseLoan("1234", cal.getTime(), Short.valueOf("1"), accountBO.getPersonnel(), startDate, Short.valueOf("1")); Set<AccountActionDateEntity> actionDateEntities = accountBO.getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(null, null, null, "20", "30", null, null, null, null, null, paymentsArray[0]); Session session = StaticHibernateUtil.getSessionTL(); StaticHibernateUtil.startTransaction(); ((LoanBO) accountBO).setLoanMeeting(null); session.update(accountBO); StaticHibernateUtil.getTransaction().commit(); Assert.assertEquals(true, true); } public void testGetTotalAmountDueForCurrentDateMeeting() { accountBO = getLoanAccount(); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountDue(), TestUtils.createMoney(212.0)); } public void testGetTotalAmountDueForSingleInstallment() throws Exception { accountBO = getLoanAccount(); AccountActionDateEntity accountActionDateEntity = accountBO.getAccountActionDate((short) 1); ((LoanScheduleEntity) accountActionDateEntity).setActionDate(offSetCurrentDate(1)); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountDue(), TestUtils.createMoney(424.0)); } public void testGetTotalAmountDueWithPayment() throws Exception { accountBO = getLoanAccount(); LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountBO.getAccountActionDate((short) 1); accountActionDateEntity.setPrincipalPaid(new Money(getCurrency(), "20.0")); accountActionDateEntity.setInterestPaid(new Money(getCurrency(), "10.0")); accountActionDateEntity.setPenaltyPaid(new Money(getCurrency(), "5.0")); accountActionDateEntity.setActionDate(offSetCurrentDate(1)); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountDue(), TestUtils.createMoney(389.0)); } public void testGetTotalAmountDueWithPaymentDone() throws Exception { accountBO = getLoanAccount(); AccountActionDateEntity accountActionDateEntity = accountBO.getAccountActionDate((short) 1); ((LoanScheduleEntity) accountActionDateEntity).setActionDate(offSetCurrentDate(1)); ((LoanScheduleEntity) accountActionDateEntity).setPaymentStatus(PaymentStatus.PAID); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountDue(), TestUtils.createMoney(212.0)); } public void testGetTotalAmountDueForTwoInstallments() throws Exception { accountBO = getLoanAccount(); AccountActionDateEntity accountActionDateEntity = accountBO.getAccountActionDate((short) 1); ((LoanScheduleEntity) accountActionDateEntity).setActionDate(offSetCurrentDate(2)); AccountActionDateEntity accountActionDateEntity2 = accountBO.getAccountActionDate((short) 2); ((LoanScheduleEntity) accountActionDateEntity2).setActionDate(offSetCurrentDate(1)); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountDue(), TestUtils.createMoney(636.0)); } public void testGetOustandingBalance() { accountBO = getLoanAccount(); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getOutstandingBalance(), TestUtils.createMoney(336.0)); } public void testGetOustandingBalancewithPayment() throws Exception { accountBO = getLoanAccount(); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); loanSummaryEntity.setPrincipalPaid(new Money(getCurrency(), "20.0")); loanSummaryEntity.setInterestPaid(new Money(getCurrency(), "10.0")); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getOutstandingBalance(), TestUtils.createMoney(306.0)); } public void testGetNextMeetingDateAsCurrentDate() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting); accountBO = TestObjectFactory.createLoanAccount("42423142341", group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Date(System.currentTimeMillis()), loanOffering); Calendar currentDateCalendar = new GregorianCalendar(); int year = currentDateCalendar.get(Calendar.YEAR); int month = currentDateCalendar.get(Calendar.MONTH); int day = currentDateCalendar.get(Calendar.DAY_OF_MONTH); currentDateCalendar = new GregorianCalendar(year, month, day); accountBO = accountPersistence.getAccount(accountBO.getAccountId()); Assert.assertEquals(((LoanBO) accountBO).getNextMeetingDate().toString(), new java.sql.Date(currentDateCalendar.getTimeInMillis()).toString()); } public void testGetNextMeetingDateAsFutureDate() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting); accountBO = TestObjectFactory.createLoanAccount("42423142341", group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Date(System.currentTimeMillis()), loanOffering); AccountActionDateEntity accountActionDateEntity = accountBO.getAccountActionDate(Short.valueOf("1")); Calendar currentDateCalendar = new GregorianCalendar(); int year = currentDateCalendar.get(Calendar.YEAR); int month = currentDateCalendar.get(Calendar.MONTH); int day = currentDateCalendar.get(Calendar.DAY_OF_MONTH); currentDateCalendar = new GregorianCalendar(year, month, day - 1); ((LoanScheduleEntity) accountActionDateEntity) .setActionDate(new java.sql.Date(currentDateCalendar.getTimeInMillis())); TestObjectFactory.updateObject(accountBO); accountBO = accountPersistence.getAccount(accountBO.getAccountId()); Assert.assertEquals(((LoanBO) accountBO).getNextMeetingDate().toString(), accountBO.getAccountActionDate(Short.valueOf("2")).getActionDate().toString()); } public void testGetTotalAmountInArrearsForCurrentDateMeeting() { accountBO = getLoanAccount(); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountInArrears(), TestUtils.createMoney()); } public void testGetTotalAmountInArrearsForSingleInstallmentDue() throws Exception { accountBO = getLoanAccount(); AccountActionDateEntity accountActionDateEntity = accountBO.getAccountActionDate((short) 1); ((LoanScheduleEntity) accountActionDateEntity).setActionDate(offSetCurrentDate(1)); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountInArrears(), TestUtils.createMoney(212.0)); } public void testGetTotalAmountInArrearsWithPayment() throws Exception { accountBO = getLoanAccount(); LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountBO.getAccountActionDate((short) 1); accountActionDateEntity.setPrincipalPaid(new Money(getCurrency(), "20.0")); accountActionDateEntity.setInterestPaid(new Money(getCurrency(), "10.0")); accountActionDateEntity.setPenaltyPaid(new Money(getCurrency(), "5.0")); accountActionDateEntity.setActionDate(offSetCurrentDate(1)); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountInArrears(), TestUtils.createMoney(177.0)); } public void testGetTotalAmountInArrearsWithPaymentDone() throws Exception { accountBO = getLoanAccount(); AccountActionDateEntity accountActionDateEntity = accountBO.getAccountActionDate(Short.valueOf("1")); ((LoanScheduleEntity) accountActionDateEntity).setActionDate(offSetCurrentDate(1)); ((LoanScheduleEntity) accountActionDateEntity).setPaymentStatus(PaymentStatus.PAID); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountInArrears(), TestUtils.createMoney()); } public void testGetTotalAmountDueForTwoInstallmentsDue() throws Exception { accountBO = getLoanAccount(); AccountActionDateEntity accountActionDateEntity = accountBO.getAccountActionDate((short) 1); ((LoanScheduleEntity) accountActionDateEntity).setActionDate(offSetCurrentDate(2)); AccountActionDateEntity accountActionDateEntity2 = accountBO.getAccountActionDate((short) 2); ((LoanScheduleEntity) accountActionDateEntity2).setActionDate(offSetCurrentDate(1)); accountBO = saveAndFetch(accountBO); Assert.assertEquals(((LoanBO) accountBO).getTotalAmountInArrears(), TestUtils.createMoney(424.0)); } public void testChangedStatusForLastInstallmentPaid() throws Exception { accountBO = getLoanAccount(); Date startDate = new Date(System.currentTimeMillis()); java.sql.Date offSetDate = offSetCurrentDate(1); for (AccountActionDateEntity accountAction : accountBO.getAccountActionDates()) { ((LoanScheduleEntity) accountAction).setActionDate(offSetDate); } accountBO = saveAndFetch(accountBO); List<AccountActionDateEntity> accountActions = new ArrayList<AccountActionDateEntity>(); accountActions.addAll(accountBO.getAccountActionDates()); PaymentData paymentData = TestObjectFactory.getLoanAccountPaymentData(accountActions, new Money(Configuration.getInstance().getSystemConfig().getCurrency(), "1272.0"), null, accountBO.getPersonnel(), "5435345", Short.valueOf("1"), startDate, startDate); accountBO.applyPaymentWithPersist(paymentData); Assert.assertEquals("When Last installment is paid the status has been changed to closed", ((LoanBO) accountBO).getAccountState().getId().toString(), String.valueOf(AccountStates.LOANACC_OBLIGATIONSMET)); accountBO.getAccountPayments().clear(); } public void testHandleArrears() throws AccountException { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); int statusChangeHistorySize = accountBO.getAccountStatusChangeHistory().size(); ((LoanBO) accountBO).handleArrears(); Assert.assertEquals(Short.valueOf(AccountStates.LOANACC_BADSTANDING), accountBO.getAccountState().getId()); Assert.assertEquals(statusChangeHistorySize + 1, accountBO.getAccountStatusChangeHistory().size()); } public void testChangedStatusOnPayment() throws Exception { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); ((LoanBO) accountBO).handleArrears(); Assert.assertEquals("The status of account before payment should be active in bad standing", Short.valueOf(AccountStates.LOANACC_BADSTANDING), accountBO.getAccountState().getId()); accountBO = applyPaymentandRetrieveAccount(); Assert.assertEquals("The status of account after payment should be active in good standing", Short.valueOf(AccountStates.LOANACC_ACTIVEINGOODSTANDING), accountBO.getAccountState().getId()); } public void testIsInterestDeductedAtDisbursement() { accountBO = getLoanAccount(); LoanBO loan = (LoanBO) accountBO; Assert.assertEquals(false, loan.isInterestDeductedAtDisbursement()); loan.setInterestDeductedAtDisbursement(true); Assert.assertEquals(true, loan.isInterestDeductedAtDisbursement()); } public void testWtiteOff() throws Exception { accountBO = getLoanAccount(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loanBO = (LoanBO) accountBO; UserContext uc = TestUtils.makeUser(); loanBO.setUserContext(uc); loanBO.writeOff(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loan = (LoanBO) accountBO; for (LoanActivityEntity loanActivityEntity : loan.getLoanActivityDetails()) { Assert.assertEquals(loanActivityEntity.getComments(), "Loan Written Off"); Assert.assertEquals(new Timestamp(DateUtils.getCurrentDateWithoutTimeStamp().getTime()), loanActivityEntity.getTrxnCreatedDate()); break; } } /* * TODO: it seems unclear what this test is testing and whether or not the * loan is being set up correctly. Originally it was created with the * InterestDueAtDisbursement flag on, but now with that flag turned off, the * result returned is 102.5 According to the setup method, the disbursal * type parameter which was originally "2" should probably be "1" now. * * * public void testGetAmountTobePaidAtdisburtail() throws Exception { Date * startDate = new Date(System.currentTimeMillis()); accountBO = * getLoanAccount(AccountState.LOAN_APPROVED, startDate, 2); * Assert.assertEquals(new Money(getCurrency(), "52"), ((LoanBO) accountBO) * .getAmountTobePaidAtdisburtail(startDate)); } */ public void testWaivePenaltyChargeDue() throws Exception { accountBO = getLoanAccount(); for (AccountActionDateEntity accountAction : ((LoanBO) accountBO).getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { accountActionDateEntity.setMiscPenalty(new Money(getCurrency(), "100")); } } ((LoanBO) accountBO).getLoanSummary().setOriginalPenalty(new Money(getCurrency(), "100")); TestObjectFactory.updateObject(accountBO); StaticHibernateUtil.closeSession(); LoanBO loanBO = TestObjectFactory.getObject(LoanBO.class, accountBO.getAccountId()); UserContext userContext = TestUtils.makeUser(); loanBO.setUserContext(userContext); loanBO.waiveAmountDue(WaiveEnum.PENALTY); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); loanBO = TestObjectFactory.getObject(LoanBO.class, loanBO.getAccountId()); for (AccountActionDateEntity accountAction : loanBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(new Money(getCurrency()), accountActionDateEntity.getMiscPenalty()); } } List<LoanActivityEntity> loanActivityDetailsSet = loanBO.getLoanActivityDetails(); LoanActivityEntity loanActivityEntity = loanActivityDetailsSet.get(0); Assert.assertEquals(LoanConstants.PENALTY_WAIVED, loanActivityEntity.getComments()); Assert.assertEquals(new Money(getCurrency(), "100"), loanActivityEntity.getPenalty()); Assert.assertEquals(new Timestamp(DateUtils.getCurrentDateWithoutTimeStamp().getTime()), loanActivityEntity.getTrxnCreatedDate()); Assert.assertEquals( loanBO.getLoanSummary().getOriginalPenalty().subtract(loanBO.getLoanSummary().getPenaltyPaid()), loanActivityEntity.getPenaltyOutstanding()); } public void testWaivePenaltyOverDue() throws Exception { accountBO = getLoanAccount(); for (AccountActionDateEntity installment : ((LoanBO) accountBO).getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) installment; if (installment.getInstallmentId().intValue() == 1) { loanScheduleEntity.setMiscPenalty(new Money(getCurrency(), "100")); } else if (installment.getInstallmentId().intValue() == 2) { loanScheduleEntity.setMiscPenalty(new Money(getCurrency(), "100")); } } ((LoanBO) accountBO).getLoanSummary().setOriginalPenalty(new Money(getCurrency(), "200")); TestObjectFactory.updateObject(accountBO); StaticHibernateUtil.closeSession(); LoanBO loanBO = TestObjectFactory.getObject(LoanBO.class, accountBO.getAccountId()); Calendar calendar = new GregorianCalendar(); calendar.setTime(DateUtils.getCurrentDateWithoutTimeStamp()); calendar.add(calendar.WEEK_OF_MONTH, -1); java.sql.Date lastWeekDate = new java.sql.Date(calendar.getTimeInMillis()); Calendar date = new GregorianCalendar(); date.setTime(DateUtils.getCurrentDateWithoutTimeStamp()); date.add(date.WEEK_OF_MONTH, -2); java.sql.Date twoWeeksBeforeDate = new java.sql.Date(date.getTimeInMillis()); for (AccountActionDateEntity installment : loanBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } else if (installment.getInstallmentId().intValue() == 2) { ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } } TestObjectFactory.updateObject(loanBO); StaticHibernateUtil.closeSession(); loanBO = TestObjectFactory.getObject(LoanBO.class, loanBO.getAccountId()); UserContext userContext = TestUtils.makeUser(); loanBO.setUserContext(userContext); loanBO.waiveAmountOverDue(WaiveEnum.PENALTY); TestObjectFactory.flushandCloseSession(); loanBO = TestObjectFactory.getObject(LoanBO.class, loanBO.getAccountId()); for (AccountActionDateEntity accountAction : loanBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; Assert.assertEquals(new Money(getCurrency()), accountActionDateEntity.getMiscPenalty()); } List<LoanActivityEntity> loanActivityDetailsSet = loanBO.getLoanActivityDetails(); LoanActivityEntity loanActivityEntity = loanActivityDetailsSet.get(0); Assert.assertEquals(new Timestamp(DateUtils.getCurrentDateWithoutTimeStamp().getTime()), loanActivityEntity.getTrxnCreatedDate()); Assert.assertEquals(new Money(getCurrency(), "200"), loanActivityEntity.getPenalty()); Assert.assertEquals( loanBO.getLoanSummary().getOriginalPenalty().subtract(loanBO.getLoanSummary().getPenaltyPaid()), loanActivityEntity.getPenaltyOutstanding()); } public void testWaiveFeeChargeDue() throws Exception { accountBO = getLoanAccount(); StaticHibernateUtil.closeSession(); LoanBO loanBO = TestObjectFactory.getObject(LoanBO.class, accountBO.getAccountId()); UserContext userContext = TestUtils.makeUser(); loanBO.setUserContext(userContext); loanBO.waiveAmountDue(WaiveEnum.FEES); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); loanBO = TestObjectFactory.getObject(LoanBO.class, loanBO.getAccountId()); // Change this to more clearly separate what we are testing for from the // machinery needed to get that data? for (AccountActionDateEntity accountAction : loanBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; for (AccountFeesActionDetailEntity accountFeesActionDetailEntity : accountActionDateEntity .getAccountFeesActionDetails()) { if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(new Money(getCurrency()), accountFeesActionDetailEntity.getFeeAmount()); } else { Assert.assertEquals(new Money(getCurrency(), "100"), accountFeesActionDetailEntity.getFeeAmount()); } } } List<LoanActivityEntity> loanActivityDetailsSet = loanBO.getLoanActivityDetails(); LoanActivityEntity loanActivityEntity = loanActivityDetailsSet.get(0); Assert.assertEquals(LoanConstants.FEE_WAIVED, loanActivityEntity.getComments()); Assert.assertEquals(new Money(getCurrency(), "100"), loanActivityEntity.getFee()); Assert.assertEquals(new Timestamp(DateUtils.getCurrentDateWithoutTimeStamp().getTime()), loanActivityEntity.getTrxnCreatedDate()); Assert.assertEquals( loanBO.getLoanSummary().getOriginalFees().subtract(loanBO.getLoanSummary().getFeesPaid()), loanActivityEntity.getFeeOutstanding()); } public void testWaiveFeeChargeOverDue() throws Exception { accountBO = getLoanAccount(); StaticHibernateUtil.closeSession(); LoanBO loanBO = TestObjectFactory.getObject(LoanBO.class, accountBO.getAccountId()); Calendar calendar = new GregorianCalendar(); calendar.setTime(DateUtils.getCurrentDateWithoutTimeStamp()); calendar.add(calendar.WEEK_OF_MONTH, -1); java.sql.Date lastWeekDate = new java.sql.Date(calendar.getTimeInMillis()); Calendar date = new GregorianCalendar(); date.setTime(DateUtils.getCurrentDateWithoutTimeStamp()); date.add(date.WEEK_OF_MONTH, -2); java.sql.Date twoWeeksBeforeDate = new java.sql.Date(date.getTimeInMillis()); for (AccountActionDateEntity installment : loanBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } else if (installment.getInstallmentId().intValue() == 2) { ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } } TestObjectFactory.updateObject(loanBO); StaticHibernateUtil.closeSession(); loanBO = TestObjectFactory.getObject(LoanBO.class, loanBO.getAccountId()); UserContext userContext = TestUtils.makeUser(); loanBO.setUserContext(userContext); loanBO.waiveAmountOverDue(WaiveEnum.FEES); TestObjectFactory.flushandCloseSession(); loanBO = TestObjectFactory.getObject(LoanBO.class, loanBO.getAccountId()); // Change this to more clearly separate what we are testing for from the // machinery needed to get that data? for (AccountActionDateEntity accountAction : loanBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; for (AccountFeesActionDetailEntity accountFeesActionDetailEntity : accountActionDateEntity .getAccountFeesActionDetails()) { if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1")) || accountActionDateEntity.getInstallmentId().equals(Short.valueOf("2"))) { Assert.assertEquals(new Money(getCurrency()), accountFeesActionDetailEntity.getFeeAmount()); } else { Assert.assertEquals(new Money(getCurrency(), "100"), accountFeesActionDetailEntity.getFeeAmount()); } } } List<LoanActivityEntity> loanActivityDetailsSet = loanBO.getLoanActivityDetails(); LoanActivityEntity loanActivityEntity = loanActivityDetailsSet.get(0); Assert.assertEquals(new Money(getCurrency(), "200"), loanActivityEntity.getFee()); Assert.assertEquals(new Timestamp(DateUtils.getCurrentDateWithoutTimeStamp().getTime()), loanActivityEntity.getTrxnCreatedDate()); Assert.assertEquals( loanBO.getLoanSummary().getOriginalFees().subtract(loanBO.getLoanSummary().getFeesPaid()), loanActivityEntity.getFeeOutstanding()); } public void testHasPortfolioAtRisk() { accountBO = getLoanAccount(); Assert.assertFalse(((LoanBO) accountBO).hasPortfolioAtRisk()); changeFirstInstallmentDate(accountBO, 31); Assert.assertTrue(((LoanBO) accountBO).hasPortfolioAtRisk()); } public void testGetRemainingPrincipalAmount() throws AccountException, SystemException { accountBO = getLoanAccount(); Date currentDate = new Date(System.currentTimeMillis()); LoanBO loan = (LoanBO) accountBO; List<AccountActionDateEntity> accntActionDates = new ArrayList<AccountActionDateEntity>(); accntActionDates.addAll(loan.getAccountActionDates()); PaymentData paymentData = TestObjectFactory.getLoanAccountPaymentData(accntActionDates, TestUtils.createMoney(700), null, accountBO.getPersonnel(), "receiptNum", Short.valueOf("1"), currentDate, currentDate); loan.applyPaymentWithPersist(paymentData); TestObjectFactory.updateObject(loan); TestObjectFactory.flushandCloseSession(); Assert.assertEquals("The amount returned for the payment should have been 700", 700.0, loan.getLastPmntAmnt()); accountBO = TestObjectFactory.getObject(AccountBO.class, loan.getAccountId()); loan = (LoanBO) accountBO; loan.getLoanSummary().getOriginalPrincipal().subtract(loan.getLoanSummary().getPrincipalPaid()); Assert.assertEquals(loan.getRemainingPrincipalAmount(), loan.getLoanSummary().getOriginalPrincipal().subtract(loan.getLoanSummary().getPrincipalPaid())); } public void testIsAccountActive() throws Exception { Date startDate = new Date(System.currentTimeMillis()); accountBO = getLoanAccount(AccountState.LOAN_APPROVED, startDate, 3); Assert.assertFalse(((LoanBO) accountBO).isAccountActive()); // disburse loan ((LoanBO) accountBO).disburseLoan("1234", startDate, Short.valueOf("1"), accountBO.getPersonnel(), startDate, Short.valueOf("1")); Session session = StaticHibernateUtil.getSessionTL(); StaticHibernateUtil.startTransaction(); session.save(accountBO); StaticHibernateUtil.getTransaction().commit(); ((LoanBO) accountBO).setLoanMeeting(null); List<AccountPaymentEntity> accountpayments = accountBO.getAccountPayments(); Assert.assertEquals(1, accountpayments.size()); for (AccountPaymentEntity entity : accountpayments) { Assert.assertEquals("1234", entity.getReceiptNumber()); // asssert loan trxns Set<AccountTrxnEntity> accountTrxns = entity.getAccountTrxns(); Assert.assertEquals(1, accountTrxns.size()); AccountTrxnEntity transaction = accountTrxns.iterator().next(); Assert.assertEquals(AccountActionTypes.DISBURSAL, transaction.getAccountAction()); Assert.assertEquals(TestUtils.createMoney(300.0), transaction.getAmount()); Assert.assertEquals(accountBO.getAccountId(), transaction.getAccount().getAccountId()); } Assert.assertTrue(((LoanBO) accountBO).isAccountActive()); } public void testGetNoOfBackDatedPayments() throws AccountException, SystemException { accountBO = getLoanAccount(); accountBO.setUserContext(TestObjectFactory.getContext()); accountBO.changeStatus(AccountState.LOAN_ACTIVE_IN_BAD_STANDING, null, ""); changeInstallmentDate(accountBO, 14, Short.valueOf("1")); changeInstallmentDate(accountBO, 14, Short.valueOf("2")); TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Date startDate = new Date(System.currentTimeMillis()); PaymentData paymentData = PaymentData.createPaymentData( new Money(Configuration.getInstance().getSystemConfig().getCurrency(), "212.0"), accountBO.getPersonnel(), Short.valueOf("1"), startDate); paymentData.setReceiptDate(startDate); paymentData.setReceiptNum("5435345"); accountBO.applyPaymentWithPersist(paymentData); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(Integer.valueOf("2"), ((LoanBO) accountBO).getPerformanceHistory().getTotalNoOfMissedPayments()); } public void testGetTotalRepayAmountForCustomerPerfHistory() throws Exception { accountBO = getLoanAccountWithPerformanceHistory(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); changeFirstInstallmentDate(accountBO); LoanBO loanBO = (LoanBO) accountBO; UserContext uc = TestUtils.makeUser(); Money totalRepaymentAmount = loanBO.getTotalEarlyRepayAmount(); Integer noOfActiveLoans = ((ClientPerformanceHistoryEntity) ((LoanBO) accountBO).getCustomer() .getPerformanceHistory()).getNoOfActiveLoans(); LoanPerformanceHistoryEntity loanPerfHistory = ((LoanBO) accountBO).getPerformanceHistory(); Integer noOfPayments = loanPerfHistory.getNoOfPayments(); loanBO.makeEarlyRepayment(loanBO.getTotalEarlyRepayAmount(), null, null, "1", uc.getId()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); loanPerfHistory = ((LoanBO) accountBO).getPerformanceHistory(); Assert.assertEquals(noOfPayments + 1, loanPerfHistory.getNoOfPayments().intValue()); ClientPerformanceHistoryEntity clientPerfHistory = (ClientPerformanceHistoryEntity) ((LoanBO) accountBO) .getCustomer().getPerformanceHistory(); /* * customerPerformanceHistory = ((LoanBO) * accountBO).getCustomer().getPerformanceHistory(); // TODO: The * following checks and 'hacks' aren't perceived to be normal, something * sometimes goes astray here? if (null == customerPerformanceHistory) { * customerPerformanceHistory = (CustomerPerformanceHistory) * StaticHibernateUtil.getSessionTL().createQuery( * "from org.mifos.customers.client.business.ClientPerformanceHistoryEntity e where e.client.customerId = " * + ((LoanBO) accountBO).getCustomer().getCustomerId()).uniqueResult(); * } */ Assert.assertEquals(Integer.valueOf(1), clientPerfHistory.getLoanCycleNumber()); Assert.assertEquals(noOfActiveLoans - 1, clientPerfHistory.getNoOfActiveLoans().intValue()); Assert.assertEquals(totalRepaymentAmount, clientPerfHistory.getLastLoanAmount()); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); } public void testWtiteOffForCustomerPerfHistory() throws Exception { accountBO = getLoanAccountWithPerformanceHistory(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loanBO = (LoanBO) accountBO; UserContext uc = TestUtils.makeUser(); loanBO.setUserContext(uc); ClientPerformanceHistoryEntity clientPerfHistory = (ClientPerformanceHistoryEntity) ((LoanBO) accountBO) .getCustomer().getPerformanceHistory(); Integer noOfActiveLoans = clientPerfHistory.getNoOfActiveLoans(); Integer loanCycleNumber = clientPerfHistory.getLoanCycleNumber(); loanBO.writeOff(); loanBO.update(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loan = (LoanBO) accountBO; clientPerfHistory = (ClientPerformanceHistoryEntity) loan.getCustomer().getPerformanceHistory(); Assert.assertEquals(loanCycleNumber - 1, clientPerfHistory.getLoanCycleNumber().intValue()); Assert.assertEquals(noOfActiveLoans - 1, clientPerfHistory.getNoOfActiveLoans().intValue()); } public void testDisbursalLoanForCustomerPerfHistory() throws Exception { Date startDate = new Date(System.currentTimeMillis()); accountBO = getLoanAccountWithPerformanceHistory(AccountState.LOAN_APPROVED, startDate, 3); ClientPerformanceHistoryEntity clientPerfHistory = (ClientPerformanceHistoryEntity) ((LoanBO) accountBO) .getCustomer().getPerformanceHistory(); Integer noOfActiveLoans = clientPerfHistory.getNoOfActiveLoans(); Integer loanCycleNumber = clientPerfHistory.getLoanCycleNumber(); ((LoanBO) accountBO).disburseLoan("1234", startDate, Short.valueOf("1"), accountBO.getPersonnel(), startDate, Short.valueOf("1")); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loan = (LoanBO) accountBO; Assert.assertEquals(noOfActiveLoans + 1, clientPerfHistory.getNoOfActiveLoans().intValue()); Assert.assertEquals(loanCycleNumber + 1, clientPerfHistory.getLoanCycleNumber().intValue()); LoanPerformanceHistoryEntity loanPerfHistory = loan.getPerformanceHistory(); Assert.assertEquals(getLastInstallmentAccountAction(loan).getActionDate(), loanPerfHistory.getLoanMaturityDate()); } public void testHandleArrearsForCustomerPerfHistory() throws AccountException, SystemException, InvalidDateException { accountBO = getLoanAccountWithPerformanceHistory(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); ClientPerformanceHistoryEntity clientPerfHistory = (ClientPerformanceHistoryEntity) ((LoanBO) accountBO) .getCustomer().getPerformanceHistory(); Integer noOfActiveLoans = clientPerfHistory.getNoOfActiveLoans(); ((LoanBO) accountBO).handleArrears(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loan = (LoanBO) accountBO; clientPerfHistory = (ClientPerformanceHistoryEntity) loan.getCustomer().getPerformanceHistory(); Assert.assertEquals(noOfActiveLoans.intValue(), clientPerfHistory.getNoOfActiveLoans().intValue()); } public void testMakePaymentForCustomerPerfHistory() throws AccountException, SystemException { accountBO = getLoanAccountWithPerformanceHistory(); accountBO.setUserContext(TestObjectFactory.getContext()); accountBO.changeStatus(AccountState.LOAN_ACTIVE_IN_BAD_STANDING, null, ""); TestObjectFactory.updateObject(accountBO); StaticHibernateUtil.closeSession(); client = TestObjectFactory.getCustomer(client.getCustomerId()); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); ClientPerformanceHistoryEntity clientPerfHistory = (ClientPerformanceHistoryEntity) ((LoanBO) accountBO) .getCustomer().getPerformanceHistory(); Integer noOfActiveLoans = clientPerfHistory.getNoOfActiveLoans(); LoanPerformanceHistoryEntity loanPerfHistory = ((LoanBO) accountBO).getPerformanceHistory(); Integer noOfPayments = loanPerfHistory.getNoOfPayments(); accountBO = applyPaymentandRetrieveAccount(); LoanBO loan = (LoanBO) accountBO; client = TestObjectFactory.getCustomer(client.getCustomerId()); clientPerfHistory = (ClientPerformanceHistoryEntity) loan.getCustomer().getPerformanceHistory(); Assert.assertEquals(noOfActiveLoans - 1, clientPerfHistory.getNoOfActiveLoans().intValue()); Assert.assertEquals(noOfPayments + 1, loan.getPerformanceHistory().getNoOfPayments().intValue()); } public void testDisbursalLoanForGroupPerfHistory() throws Exception { Date startDate = new Date(System.currentTimeMillis()); accountBO = getLoanAccountWithGroupPerformanceHistory(AccountState.LOAN_APPROVED, startDate, 3); GroupPerformanceHistoryEntity groupPerformanceHistoryEntity = (GroupPerformanceHistoryEntity) ((LoanBO) accountBO) .getCustomer().getPerformanceHistory(); ((LoanBO) accountBO).disburseLoan("1234", startDate, Short.valueOf("1"), accountBO.getPersonnel(), startDate, Short.valueOf("1")); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); group = TestObjectFactory.getCustomer(group.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); LoanBO loan = (LoanBO) accountBO; Assert.assertEquals(new Money(getCurrency(), "300.0"), groupPerformanceHistoryEntity.getLastGroupLoanAmount()); LoanPerformanceHistoryEntity loanPerfHistory = loan.getPerformanceHistory(); Assert.assertEquals(getLastInstallmentAccountAction(loan).getActionDate(), loanPerfHistory.getLoanMaturityDate()); } /** * TODO: Re-enable this test when rounding code correctly handles mid-stream * changes to the loan schedule. Note the use of method getLoanAccount(), * which radically alters the terms of the loan, unbeknownst to the reader * of this code. Here's a trace of this bizarre code: * <ul> * <li>getLoanAccount() calls * <li>TestObjectFactory.createLoanAccount(), which calls * <li>LoanBOIntegrationTest.createLoanAccount(). This method initiall * creates the loan with terms: * <ul> * <li>Loan amount 0 * <li>Interest rate 0.0 * <li>6 weekly installments * <li>no fees * </ul> * <li>The method then goes on to alter the loan by directly manipulating * instance variables: * <ul> * <li>Add a periodic amount fee of 100 to each installment * <li>Change each installment's principal to 100 and interest to 12.0 (but * the loan amount is still 300, although the principal due is now 600!) * </ul> * </ul> * This leaves the loan in a badly inconsistent state, causing the (second) * call to applyRounding() to break. This test code needs to be refactored! * <p> * This test now breaks. However, rounding with miscellaneous fees is fully * covered by tests in TestLoanRedoDisbursal.java, so it is disabled. */ public void xtestRoundInstallments() throws AccountException, SystemException { accountBO = getLoanAccount(); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); ((LoanBO) accountBO).getLoanOffering().setPrinDueLastInst(false); List<Short> installmentIdList = new ArrayList<Short>(); for (AccountActionDateEntity accountAction : accountBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; installmentIdList.add(accountActionDateEntity.getInstallmentId()); if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { accountActionDateEntity.setMiscFee(new Money(getCurrency(), "20.3")); } } ((LoanBO) accountBO).applyRounding(); TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Set<AccountActionDateEntity> actionDateEntities = accountBO.getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkTotalDueWithFees("233.0", paymentsArray[0]); checkTotalDueWithFees("212.0", paymentsArray[1]); checkTotalDueWithFees("212.0", paymentsArray[2]); checkTotalDueWithFees("212.0", paymentsArray[3]); checkTotalDueWithFees("212.0", paymentsArray[4]); checkTotalDueWithFees("212.0", paymentsArray[5]); } public void testBuildLoanWithoutLoanOffering() throws Exception { createInitialCustomers(); try { loanDao.createLoan(TestUtils.makeUser(), null, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); Assert.assertFalse("The Loan object is created for null loan offering", true); } catch (AccountException ae) { Assert.assertTrue("The Loan object is not created for null loan offering", true); } } public void testBuildForInactiveLoanOffering() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false, false, PrdStatus.LOAN_INACTIVE); try { LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering .getEligibleInstallmentSameForAllLoan(); LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.fail("The Loan object is created for inactive loan offering"); } catch (AccountException ae) { Assert.assertTrue("The Loan object is not created for inactive loan offering", true); } TestObjectFactory.removeObject(loanOffering); } public void testBuildLoanWithoutCustomer() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); try { LoanBO.createLoan(TestUtils.makeUser(), loanOffering, null, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertFalse("The Loan object is created for null customer", true); } catch (AccountException ae) { Assert.assertTrue("The Loan object is not created for null customer", true); } TestObjectFactory.removeObject(loanOffering); } public void testBuildForInactiveCustomer() throws Exception { createInitialCustomers(); CustomerBOTestUtils.setCustomerStatus(group, new CustomerStatusEntity(CustomerStatus.GROUP_CLOSED)); TestObjectFactory.updateObject(group); group = TestObjectFactory.getGroup(group.getCustomerId()); LoanOfferingBO loanOffering = createLoanOffering(false); try { loanDao.createLoan(TestUtils.makeUser(), loanOffering, null, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); Assert.assertFalse("The Loan object is created for inactive customer", true); } catch (AccountException ae) { Assert.assertTrue("The Loan object is not created for inactive customer", true); } TestObjectFactory.removeObject(loanOffering); } public void testMeetingNotMatchingForCustomerAndLoanOffering() throws Exception { createInitialCustomers(); MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(MONTHLY, EVERY_MONTH, CUSTOMER_MEETING)); Date startDate = new Date(System.currentTimeMillis()); LoanOfferingBO loanOffering = createOfferingNoPrincipalInLastInstallment(startDate, meeting); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); try { LoanBO.createLoan(TestUtils.makeUser(), loanOffering, null, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertFalse("The Loan object is created even if meetings do not match", true); } catch (AccountException ae) { Assert.assertTrue("The Loan object is not created if meetings do not match", true); } TestObjectFactory.removeObject(loanOffering); } public void testMeetingRecurrenceOfLoanOfferingInMultipleOfCustomer() throws Exception { Date startDate = new Date(System.currentTimeMillis()); createInitialCustomers(); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); LoanOfferingBO loanOffering = createOfferingNoPrincipalInLastInstallment(startDate, meeting); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertTrue( "The Loan object is created if meeting recurrence of loan offering is in multiples of customer", true); TestObjectFactory.removeObject(loanOffering); } public void testBuildLoanWithoutLoanAmount() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); try { LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, null, Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertFalse("The Loan object is created for null customer", true); } catch (AccountException ae) { Assert.assertTrue("The Loan object is not created for null customer", true); } TestObjectFactory.removeObject(loanOffering); } public void testGracePeriodGraterThanMaxNoOfInst() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); try { LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, null, Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 5, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertFalse("The Loan object is created for grace period greather than max installments", true); } catch (AccountException ae) { Assert.assertTrue("The Loan object is not created for grace period greather than max installments", true); } TestObjectFactory.removeObject(loanOffering); } public void testGracePeriodForInterestNotDedAtDisb() throws Exception { createInitialCustomers(); LoanOfferingBO product = createLoanOffering(false); // product.updateLoanOfferingSameForAllLoan(product); LoanOfferingInstallmentRange eligibleInstallmentRange = product.getEligibleInstallmentSameForAllLoan(); LoanBO loan = LoanBO.createLoan(TestUtils.makeUser(), product, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 1, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertEquals(product.getGraceType(), loan.getGraceType()); Assert.assertEquals(1, loan.getGracePeriodDuration().intValue()); assertNotSame(new java.sql.Date(DateUtils.getCurrentDateWithoutTimeStamp().getTime()).toString(), loan.getAccountActionDate((short) 1).getActionDate().toString()); TestObjectFactory.removeObject(product); } /* * TODO: turn this back on when interest deducted at disbursement are * re-enabled. * * * public void testGracePeriodForInterestDedAtDisb() throws * NumberFormatException, AccountException, Exception { * createInitialCustomers(); LoanOfferingBO loanOffering = * createLoanOffering(false, true); LoanOfferingInstallmentRange * eligibleInstallmentRange = loanOffering * .getEligibleInstallmentSameForAllLoan(); LoanBO loan = * LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short * .valueOf("6"), new Date(System.currentTimeMillis()), true, 10.0, (short) * 5, null, new ArrayList<FeeView>(), new * ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, * eligibleInstallmentRange .getMaxNoOfInstall(), eligibleInstallmentRange * .getMinNoOfInstall(), false, null);Assert.assertEquals( * "For interest ded at disb, grace period type should be none", * GraceType.NONE, loan.getGraceType());Assert.assertEquals(0, * loan.getGracePeriodDuration().intValue());Assert.assertEquals(new * java.sql.Date(DateUtils * .getCurrentDateWithoutTimeStamp().getTime()).toString(), loan * .getAccountActionDate((short) 1).getActionDate().toString()); * * TestObjectFactory.removeObject(loanOffering); } */ public void testBuildLoanWithValidDisbDate() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); Date disbursementDate = new Date(System.currentTimeMillis()); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); try { LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), disbursementDate, false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertTrue("The Loan object is created for valid disbursement date", true); } catch (AccountException ae) { Assert.assertFalse("The Loan object is created for valid disbursement date", true); } TestObjectFactory.removeObject(loanOffering); } // Ability to enter a loan disbursal date wich doesn't occur on a meeting // day // TODO : test method to be removed /* * public void testBuildLoanWithInvalidDisbDate() throws * NumberFormatException, AccountException, Exception { * createInitialCustomers(); LoanOfferingBO loanOffering = * createLoanOffering(false); Date disbursementDate = * incrementCurrentDate(3); * * try { new LoanBO(TestUtils.makeUser(), loanOffering, group, * AccountState.LOANACC_APPROVED, new Money(getCurrency(), "300.0"), Short * .valueOf("6"), disbursementDate, false, 10.0, (short) 0, null, * new ArrayList<FeeView>(), new ArrayList<CustomFieldView>()); * Assert.assertFalse( * "The Loan object is created for invalid disbursement date", true); } * catch (AccountException ae) {Assert.assertTrue( * "The Loan object is created for invalid disbursement date", true); } * TestObjectFactory.removeObject(loanOffering); } */ public void testBuildLoanWithDisbDateOlderThanCurrentDate() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); Date disbursementDate = offSetCurrentDate(15); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); try { LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), disbursementDate, false, 10.0, (short) 0, null, new ArrayList<FeeView>(), new ArrayList<CustomFieldView>(), DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertFalse("The Loan object is created for invalid disbursement date", true); } catch (AccountException ae) { Assert.assertTrue("The Loan object is created for invalid disbursement date", true); } TestObjectFactory.removeObject(loanOffering); } public void testBuildLoanWithFee() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); List<FeeView> feeViews = getFeeViews(); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); LoanBO loan = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, feeViews, null, DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertEquals(2, loan.getAccountFees().size()); for (AccountFeesEntity accountFees : loan.getAccountFees()) { if (accountFees.getFees().getFeeName().equals("One Time Amount Fee")) { Assert.assertEquals(new Double("120.0"), accountFees.getFeeAmount()); } else { Assert.assertEquals(new Double("10.0"), accountFees.getFeeAmount()); } } Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Periodic Fee", "10.0"); fees1.put("One Time Amount Fee", "120.0"); Map<String, String> fees2 = new HashMap<String, String>(); fees2.put("Periodic Fee", "10.0"); Set<AccountActionDateEntity> actionDateEntities = loan.getAccountActionDates(); Assert.assertEquals(6, actionDateEntities.size()); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); /* * TODO: fix this check checkFees(fees1, "130.0", paymentsArray[0]); */ checkFees(fees2, "10.0", paymentsArray[1]); checkFees(fees2, "10.0", paymentsArray[2]); checkFees(fees2, "10.0", paymentsArray[3]); checkFees(fees2, "10.0", paymentsArray[4]); checkFees(fees2, "10.0", paymentsArray[5]); deleteFee(feeViews); TestObjectFactory.removeObject(loanOffering); } public void testBuildLoan() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); List<FeeView> feeViews = getFeeViews(); LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); LoanBO loan = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, feeViews, null, DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); Assert.assertNotNull(loan.getLoanSummary()); Assert.assertNotNull(loan.getPerformanceHistory()); Assert.assertEquals(new Money(getCurrency(), "300.0"), loan.getLoanSummary().getOriginalPrincipal()); Assert.assertEquals(new Money(getCurrency(), "300.0"), loan.getLoanAmount()); Assert.assertEquals(new Money(getCurrency(), "300.0"), loan.getLoanBalance()); Assert.assertEquals(Short.valueOf("6"), loan.getNoOfInstallments()); Assert.assertEquals(6, loan.getAccountActionDates().size()); Assert.assertEquals(loan.getNoOfInstallments().intValue(), loan.getAccountActionDates().size()); deleteFee(feeViews); TestObjectFactory.removeObject(loanOffering); } public void testCreateLoan() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); List<FeeView> feeViews = getFeeViews(); boolean isInterestDedAtDisb = false; Short noOfinstallments = (short) 6; LoanBO loan = createAndRetrieveLoanAccount(loanOffering, isInterestDedAtDisb, feeViews, noOfinstallments); Assert.assertEquals(2, loan.getAccountFees().size()); for (AccountFeesEntity accountFees : loan.getAccountFees()) { if (accountFees.getFees().getFeeName().equals("One Time Amount Fee")) { Assert.assertEquals(new Double("120.0"), accountFees.getFeeAmount()); } else { Assert.assertEquals(new Double("10.0"), accountFees.getFeeAmount()); } } Set<AccountActionDateEntity> actionDateEntities = loan.getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkPrincipalAndInterest("50.4", "0.6", paymentsArray[0]); checkPrincipalAndInterest("50.4", "0.6", paymentsArray[1]); checkPrincipalAndInterest("50.4", "0.6", paymentsArray[2]); checkPrincipalAndInterest("50.4", "0.6", paymentsArray[3]); checkPrincipalAndInterest("50.4", "0.6", paymentsArray[4]); checkPrincipalAndInterest("48.0", "1.0", paymentsArray[5]); Assert.assertNotNull(loan.getLoanSummary()); Assert.assertNotNull(loan.getPerformanceHistory()); Assert.assertEquals(new Money(getCurrency(), "300.0"), loan.getLoanSummary().getOriginalPrincipal()); Assert.assertEquals(new Money(getCurrency(), "300.0"), loan.getLoanAmount()); Assert.assertEquals(new Money(getCurrency(), "300.0"), loan.getLoanBalance()); Assert.assertEquals(Short.valueOf("6"), loan.getNoOfInstallments()); Assert.assertEquals(6, loan.getAccountActionDates().size()); } /* * TODO: Turn this test back on when interest deducted at disbursement is * re-enabled. * * public void testCreateLoanForInterestDedAtDisb() throws * NumberFormatException, AccountException, Exception { * createInitialCustomers(); LoanOfferingBO loanOffering = * createLoanOffering(false, true); List<FeeView> feeViews = getFeeViews(); * boolean isInterestDedAtDisb = true; Short noOfinstallments = (short) 6; * * LoanBO loan = createAndRetrieveLoanAccount(loanOffering, * isInterestDedAtDisb, feeViews, noOfinstallments); * * Assert.assertEquals(2, loan.getAccountFees().size()); for * (AccountFeesEntity accountFees : loan.getAccountFees()) { if * (accountFees.getFees().getFeeName() .equals("One Time Amount Fee")) * Assert.assertEquals(new Double("120.0"), accountFees.getFeeAmount()); * elseAssert.assertEquals(new Double("10.0"), accountFees.getFeeAmount()); * } * * Set<AccountActionDateEntity> actionDateEntities = loan * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkPrincipalAndInterest("0.0", "3.0", paymentsArray[0]); * checkPrincipalAndInterest("60.0", "0.0", paymentsArray[1]); * checkPrincipalAndInterest("60.0", "0.0", paymentsArray[2]); * checkPrincipalAndInterest("60.0", "0.0", paymentsArray[3]); * checkPrincipalAndInterest("60.0", "0.0", paymentsArray[4]); * checkPrincipalAndInterest("60.0", "0.0", paymentsArray[5]); * * Assert.assertNotNull(loan.getLoanSummary()); * Assert.assertNotNull(loan.getPerformanceHistory * ());Assert.assertEquals(new Money("300.0"), loan.getLoanSummary() * .getOriginalPrincipal());Assert.assertEquals(new Money(getCurrency(), * "300.0"), loan.getLoanAmount());Assert.assertEquals(new Money("300.0"), * loan.getLoanBalance());Assert.assertEquals(Short.valueOf("6"), * loan.getNoOfInstallments());Assert.assertEquals(6, * loan.getAccountActionDates().size()); } */ /* * TODO: Add this back in when principal due in last installment is * supported again. * * public void testCreateLoanForPrincipalAtLastInst() throws * NumberFormatException, AccountException, Exception { * createInitialCustomers(); LoanOfferingBO loanOffering = * createLoanOffering(true); List<FeeView> feeViews = getFeeViews(); boolean * isInterestDedAtDisb = false; Short noOfinstallments = (short) 6; * * LoanBO loan = createAndRetrieveLoanAccount(loanOffering, * isInterestDedAtDisb, feeViews, noOfinstallments); * * Assert.assertEquals(2, loan.getAccountFees().size()); for * (AccountFeesEntity accountFees : loan.getAccountFees()) { if * (accountFees.getFees().getFeeName() .equals("One Time Amount Fee")) * Assert.assertEquals(new Double("120.0"), accountFees.getFeeAmount()); * elseAssert.assertEquals(new Double("10.0"), accountFees.getFeeAmount()); * } * * Set<AccountActionDateEntity> actionDateEntities = loan * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkPrincipalAndInterest("0.0", "0.5", paymentsArray[0]); * checkPrincipalAndInterest("0.0", "0.5", paymentsArray[1]); * checkPrincipalAndInterest("0.0", "0.5", paymentsArray[2]); * checkPrincipalAndInterest("0.0", "0.5", paymentsArray[3]); * checkPrincipalAndInterest("0.0", "0.5", paymentsArray[4]); * checkPrincipalAndInterest("300.0", "0.5", paymentsArray[5]); * * Assert.assertNotNull(loan.getLoanSummary()); * Assert.assertNotNull(loan.getPerformanceHistory * ());Assert.assertEquals(new Money("300.0"), loan.getLoanSummary() * .getOriginalPrincipal());Assert.assertEquals(new Money(getCurrency(), * "300.0"), loan.getLoanAmount());Assert.assertEquals(new Money("300.0"), * loan.getLoanBalance());Assert.assertEquals(Short.valueOf("6"), * loan.getNoOfInstallments());Assert.assertEquals(6, * loan.getAccountActionDates().size()); * * } */ /* * TODO: turn this back on when principal due in last installment and * interest deducted at disbursement are re-enabled. * * public void testCreateLoanForPrincipalAtLastInstAndIntDedAtDisb() throws * NumberFormatException, AccountException, Exception { * createInitialCustomers(); LoanOfferingBO loanOffering = * createLoanOffering(true, true); List<FeeView> feeViews = getFeeViews(); * boolean isInterestDedAtDisb = true; Short noOfinstallments = (short) 6; * * LoanBO loan = createAndRetrieveLoanAccount(loanOffering, * isInterestDedAtDisb, feeViews, noOfinstallments); * * Assert.assertEquals(2, loan.getAccountFees().size()); for * (AccountFeesEntity accountFees : loan.getAccountFees()) { if * (accountFees.getFees().getFeeName() .equals("One Time Amount Fee")) * Assert.assertEquals(new Double("120.0"), accountFees.getFeeAmount()); * elseAssert.assertEquals(new Double("10.0"), accountFees.getFeeAmount()); * } * * Set<AccountActionDateEntity> actionDateEntities = loan * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkPrincipalAndInterest("0.0", "3.0", paymentsArray[0]); * checkPrincipalAndInterest("0.0", "0.0", paymentsArray[1]); * checkPrincipalAndInterest("0.0", "0.0", paymentsArray[2]); * checkPrincipalAndInterest("0.0", "0.0", paymentsArray[3]); * checkPrincipalAndInterest("0.0", "0.0", paymentsArray[4]); * checkPrincipalAndInterest("300.0", "0.0", paymentsArray[5]); * * Assert.assertNotNull(loan.getLoanSummary()); * Assert.assertNotNull(loan.getPerformanceHistory * ());Assert.assertEquals(new Money("300.0"), loan.getLoanSummary() * .getOriginalPrincipal());Assert.assertEquals(new Money(getCurrency(), * "300.0"), loan.getLoanAmount());Assert.assertEquals(new Money("300.0"), * loan.getLoanBalance());Assert.assertEquals(Short.valueOf("6"), * loan.getNoOfInstallments());Assert.assertEquals(6, * loan.getAccountActionDates().size()); * * } */ public void testLoanScheduleRoundingWithMiscFee() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); Short noOfinstallments = (short) 2; LoanBO loan = createButDontRetrieveLoanAccount(loanOffering, false, null, noOfinstallments, 0.0, new Money(getCurrency(), "300.0")); for (AccountActionDateEntity accountActionDate : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDate; if (loanScheduleEntity.getInstallmentId() == 1) { Assert.assertEquals(new Money(getCurrency(), "150.0"), loanScheduleEntity.getTotalDueWithFees()); } else { Assert.assertEquals(new Money(getCurrency(), "150.0"), loanScheduleEntity.getTotalDueWithFees()); } } loan.applyCharge(Short.valueOf(AccountConstants.MISC_FEES), 10.0); for (AccountActionDateEntity accountActionDate : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDate; if (loanScheduleEntity.getInstallmentId() == 1) { Assert.assertEquals(new Money(getCurrency(), "160.0"), loanScheduleEntity.getTotalDueWithFees()); Assert.assertEquals(new Money(getCurrency(), "150.0"), loanScheduleEntity.getPrincipal()); } else { Assert.assertEquals(new Money(getCurrency(), "150.0"), loanScheduleEntity.getTotalDueWithFees()); } } } public void testAmountRoundedWhileCreate() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); boolean isInterestDedAtDisb = false; Short noOfinstallments = (short) 6; LoanBO loan = createAndRetrieveLoanAccount(loanOffering, isInterestDedAtDisb, null, noOfinstallments); for (AccountActionDateEntity accountActionDate : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDate; if (loanScheduleEntity.getInstallmentId() != 6) { Assert.assertEquals(new Money(getCurrency(), "51.0"), loanScheduleEntity.getTotalDueWithFees()); } else { Assert.assertEquals("The last installment amount is adjusted for rounding", new Money(getCurrency(), "49.0"), loanScheduleEntity.getTotalDueWithFees()); } } } public void testAmountNotRoundedWhileCreate() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); boolean isInterestDedAtDisb = false; Short noOfinstallments = (short) 6; LoanBO loan = createAndRetrieveLoanAccount(loanOffering, isInterestDedAtDisb, null, noOfinstallments, 0.0, new Money(getCurrency(), "300.0")); // Change this to more clearly separate what we are testing for from the // machinery needed to get that data? for (AccountActionDateEntity accountActionDate : loan.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDate; if (loanScheduleEntity.getInstallmentId() != 6) { Assert.assertEquals(new Money(getCurrency(), "50.0"), loanScheduleEntity.getTotalDueWithFees()); } else { Assert.assertEquals("The last installment amount is not adjusted for rounding", new Money(getCurrency(), "50.0"), loanScheduleEntity.getTotalDueWithFees()); } } } public void testApplyMiscCharge() throws Exception { accountBO = getLoanAccount(); Money intialTotalFeeAmount = ((LoanBO) accountBO).getLoanSummary().getOriginalFees(); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); UserContext uc = TestUtils.makeUser(); accountBO.setUserContext(uc); accountBO.applyCharge(Short.valueOf(AccountConstants.MISC_FEES), new Double("33")); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(new Money(getCurrency(), "33.0"), loanScheduleEntity.getMiscFee()); } } Assert.assertEquals(intialTotalFeeAmount.add(new Money(getCurrency(), "33.0")), ((LoanBO) accountBO).getLoanSummary().getOriginalFees()); LoanActivityEntity loanActivityEntity = (LoanActivityEntity) ((LoanBO) accountBO).getLoanActivityDetails() .toArray()[0]; Assert.assertEquals(AccountConstants.MISC_FEES_APPLIED, loanActivityEntity.getComments()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getOriginalFees(), loanActivityEntity.getFeeOutstanding()); } /** * TODO: Re-enable this method when rounding code can handle mid-stream * changes to the loan that require re-applying applyRounding(). (method * LoanBO.applyCharge() does. When this method sets payment status to PAID, * applyRounding applies only to unpaid installments, which it cannot * currently handle.) * <p/> * Note: this method should not directly set status to PAID, as it leaves * the loan in an inconsistent state. The the status is paid, but the * installment's state is inconsistent -- the "paidX" instance variable * still have value 0. */ public void testApplyMiscChargeWithFirstInstallmentPaid() throws Exception { accountBO = getLoanAccount(); Money intialTotalFeeAmount = ((LoanBO) accountBO).getLoanSummary().getOriginalFees(); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { loanScheduleEntity.setPaymentStatus(PaymentStatus.PAID); } } UserContext uc = TestUtils.makeUser(); accountBO.setUserContext(uc); accountBO.applyCharge(Short.valueOf("-1"), new Double("33")); // Change this to more clearly separate what we are testing for from the // machinery needed to get that data? for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("2"))) { Assert.assertEquals(new Money(getCurrency(), "33.0"), loanScheduleEntity.getMiscFee()); } } Assert.assertEquals(intialTotalFeeAmount.add(new Money(getCurrency(), "33.0")), ((LoanBO) accountBO).getLoanSummary().getOriginalFees()); LoanActivityEntity loanActivityEntity = (LoanActivityEntity) ((LoanBO) accountBO).getLoanActivityDetails() .toArray()[0]; Assert.assertEquals(AccountConstants.MISC_FEES_APPLIED, loanActivityEntity.getComments()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getOriginalFees(), loanActivityEntity.getFeeOutstanding()); } public void testApplyUpfrontFee() throws Exception { accountBO = getLoanAccount(); Money intialTotalFeeAmount = ((LoanBO) accountBO).getLoanSummary().getOriginalFees(); TestObjectFactory.flushandCloseSession(); FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); UserContext uc = TestUtils.makeUser(); accountBO.setUserContext(uc); accountBO.applyCharge(upfrontFee.getFeeId(), ((RateFeeBO) upfrontFee).getRate()); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Date lastAppliedDate = null; Money feeAmountApplied = new Money(getCurrency()); Map<String, String> fees2 = new HashMap<String, String>(); fees2.put("Upfront Fee", "60.0"); fees2.put("Mainatnence Fee", "100.0"); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); Assert.assertEquals(6, actionDateEntities.size()); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkFees(fees2, paymentsArray[0], false); // setting of values here for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { lastAppliedDate = loanScheduleEntity.getActionDate(); for (AccountFeesActionDetailEntity accountFeesActionDetailEntity : loanScheduleEntity .getAccountFeesActionDetails()) { if (accountFeesActionDetailEntity.getFee().getFeeName().equalsIgnoreCase("Upfront Fee")) { feeAmountApplied = accountFeesActionDetailEntity.getFeeAmount(); } } } } Assert.assertEquals(intialTotalFeeAmount.add(feeAmountApplied), ((LoanBO) accountBO).getLoanSummary().getOriginalFees()); LoanActivityEntity loanActivityEntity = (LoanActivityEntity) ((LoanBO) accountBO).getLoanActivityDetails() .toArray()[0]; Assert.assertEquals(upfrontFee.getFeeName() + " applied", loanActivityEntity.getComments()); Assert.assertEquals(((LoanBO) accountBO).getLoanSummary().getOriginalFees(), loanActivityEntity.getFeeOutstanding()); AccountFeesEntity accountFeesEntity = accountBO.getAccountFees(upfrontFee.getFeeId()); Assert.assertEquals(FeeStatus.ACTIVE, accountFeesEntity.getFeeStatusAsEnum()); Assert.assertEquals(DateUtils.getDateWithoutTimeStamp(lastAppliedDate.getTime()), DateUtils.getDateWithoutTimeStamp(accountFeesEntity.getLastAppliedDate().getTime())); } public void testUpdateLoanSuccessWithRegeneratingNewRepaymentSchedule() throws Exception { // newDate is the new disbursement date Date newDate = incrementCurrentDate(14); // first installment date is the first installment which is one // week after the disbursement date since this is a weekly loan Date firstInstallmentDate = incrementCurrentDate(21); accountBO = getLoanAccount(); accountBO.setUserContext(TestObjectFactory.getContext()); accountBO.changeStatus(AccountState.LOAN_APPROVED, null, ""); LoanBO loanBO = (LoanBO) accountBO; ((LoanBO) accountBO).updateLoan(loanBO.isInterestDeductedAtDisbursement(), loanBO.getLoanAmount(), loanBO.getInterestRate(), loanBO.getNoOfInstallments(), newDate, loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), loanBO.getCollateralNote(), null, null, false, null, null); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); group = TestObjectFactory.getCustomer(group.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Date newActionDate = DateUtils.getDateWithoutTimeStamp( accountBO.getAccountActionDate(Short.valueOf("1")).getActionDate().getTime()); Assert.assertEquals("New repayment schedule generated, so first installment date should be same as newDate", firstInstallmentDate, newActionDate); } public void testUpdateLoanWithoutRegeneratingNewRepaymentSchedule() throws Exception { Date newDate = incrementCurrentDate(14); accountBO = getLoanAccount(); Date oldActionDate = DateUtils.getDateWithoutTimeStamp( accountBO.getAccountActionDate(Short.valueOf("1")).getActionDate().getTime()); LoanBO loanBO = (LoanBO) accountBO; ((LoanBO) accountBO).updateLoan(loanBO.isInterestDeductedAtDisbursement(), loanBO.getLoanAmount(), loanBO.getInterestRate(), loanBO.getNoOfInstallments(), newDate, loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), loanBO.getCollateralNote(), null, null, false, null, null); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); group = TestObjectFactory.getCustomer(group.getCustomerId()); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); Date newActionDate = DateUtils.getDateWithoutTimeStamp( accountBO.getAccountActionDate(Short.valueOf("1")).getActionDate().getTime()); Assert.assertEquals( "Didn't generate new repayment schedule, so first installment date should be same as before ", oldActionDate, newActionDate); } /* * TODO: turn back on when PrincipalDueInLastPayment is re-enabled * * * public void testCreateLoanAccountWithPrincipalDueInLastPayment() throws * Exception { Date startDate = new Date(System.currentTimeMillis()); * MeetingBO meeting = TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( startDate, * center.getCustomerMeeting().getMeeting()); UserContext userContext = * TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> * feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = * TestObjectFactory.createPeriodicAmountFee( "Periodic Fee", * FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("3")); * feeViewList.add(new FeeView(userContext, periodicFee)); FeeBO upfrontFee * = TestObjectFactory.createOneTimeRateFee( "Upfront Fee", * FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, * FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, * upfrontFee)); FeeBO disbursementFee = * TestObjectFactory.createOneTimeAmountFee( "Disbursement Fee", * FeeCategory.LOAN, "30", FeePayment.TIME_OF_DISBURSEMENT); * feeViewList.add(new FeeView(userContext, disbursementFee)); * * accountBO = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), startDate, false, 1.2, (short) 0, new * FundBO(), feeViewList, null); new * TestObjectPersistence().persist(accountBO);Assert.assertEquals(6, * accountBO.getAccountActionDates().size()); * * HashMap fees0 = new HashMap(); * * HashMap fees1 = new HashMap(); fees1.put("Periodic Fee", "100.0"); * * HashMap fees2 = new HashMap(); fees2.put("Periodic Fee", "100.0"); * fees2.put("Upfront Fee", "60.0"); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(null, "0.0", "0.1", fees2, paymentsArray[0]); * checkLoanScheduleEntity(null, "0.0", "0.1", fees0, paymentsArray[1]); * checkLoanScheduleEntity(null, "0.0", "0.1", fees1, paymentsArray[2]); * checkLoanScheduleEntity(null, "0.0", "0.1", fees1, paymentsArray[3]); * checkLoanScheduleEntity(null, "0.0", "0.1", fees0, paymentsArray[4]); * checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "300.0", "0.1", * fees1, paymentsArray[5]); * * Assert.assertEquals(3, accountBO.getAccountFees().size()); for * (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { if * (accountFeesEntity.getFees().getFeeName().equals("Upfront Fee")) { * Assert.assertEquals(new Money(getCurrency(), "60.0"), accountFeesEntity * .getAccountFeeAmount());Assert.assertEquals(new Double("20.0"), * accountFeesEntity .getFeeAmount()); } else if * (accountFeesEntity.getFees().getFeeName().equals( "Disbursement Fee")) { * Assert.assertEquals(new Money(getCurrency(), "30.0"), accountFeesEntity * .getAccountFeeAmount());Assert.assertEquals(new Double("30.0"), * accountFeesEntity .getFeeAmount()); } else {Assert.assertEquals(new * Money("100.0"), accountFeesEntity .getAccountFeeAmount()); * Assert.assertEquals(new Double("100.0"), accountFeesEntity * .getFeeAmount()); } } LoanSummaryEntity loanSummaryEntity = ((LoanBO) * accountBO) .getLoanSummary();Assert.assertEquals(new Money(getCurrency(), * "300.0"), loanSummaryEntity * .getOriginalPrincipal());Assert.assertEquals(new Money(getCurrency(), * "0.6"), loanSummaryEntity.getOriginalInterest());Assert.assertEquals(new * Money("490.0"), * loanSummaryEntity.getOriginalFees());Assert.assertEquals(new * Money("0.0"), loanSummaryEntity.getOriginalPenalty()); } */ /* * TODO: turn back on when InterestDeductedAtDisbursement is re-enabled * * public void testCreateLoanAccountWithInterestDeductedAtDisbursement() * throws Exception { Date startDate = new Date(System.currentTimeMillis()); * MeetingBO meeting = TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( "Loan", ApplicableTo.GROUPS, * startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, true, * false, center .getCustomerMeeting().getMeeting()); UserContext * userContext = TestUtils.makeUser(); userContext.setLocaleId(null); * List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = * TestObjectFactory.createPeriodicAmountFee( "Periodic Fee", * FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("3")); * feeViewList.add(new FeeView(userContext, periodicFee)); FeeBO upfrontFee * = TestObjectFactory.createOneTimeRateFee( "Upfront Fee", * FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, * FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, * upfrontFee)); FeeBO disbursementFee = * TestObjectFactory.createOneTimeAmountFee( "Disbursement Fee", * FeeCategory.LOAN, "30", FeePayment.TIME_OF_DISBURSEMENT); * feeViewList.add(new FeeView(userContext, disbursementFee)); * * accountBO = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), startDate, true, 1.2, (short) 0, new * FundBO(), feeViewList, null); new * TestObjectPersistence().persist(accountBO); * * HashMap fees3 = new HashMap(); fees3.put("Periodic Fee", "100.0"); * fees3.put("Disbursement Fee", "30.0"); fees3.put("Upfront Fee", "60.0"); * * HashMap fees0 = new HashMap(); * * HashMap fees1 = new HashMap(); fees1.put("Periodic Fee", "100.0"); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(0), "0.0", "0.6", fees3, * paymentsArray[0]); checkLoanScheduleEntity(null, "60.0", "0.0", fees0, * paymentsArray[1]); checkLoanScheduleEntity(null, "60.0", "0.0", fees1, * paymentsArray[2]); checkLoanScheduleEntity(null, "60.0", "0.0", fees1, * paymentsArray[3]); checkLoanScheduleEntity(null, "60.0", "0.0", fees0, * paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * 5), * "60.0", "0.0", fees1, paymentsArray[5]); * * Assert.assertEquals(3, accountBO.getAccountFees().size()); for * (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { if * (accountFeesEntity.getFees().getFeeName().equals("Upfront Fee")) { * Assert.assertEquals(new Money(getCurrency(), "60.0"), accountFeesEntity * .getAccountFeeAmount());Assert.assertEquals(new Double("20.0"), * accountFeesEntity .getFeeAmount()); } else if * (accountFeesEntity.getFees().getFeeName().equals( "Disbursement Fee")) { * Assert.assertEquals(new Money(getCurrency(), "30.0"), accountFeesEntity * .getAccountFeeAmount());Assert.assertEquals(new Double("30.0"), * accountFeesEntity .getFeeAmount()); } else {Assert.assertEquals(new * Money("100.0"), accountFeesEntity .getAccountFeeAmount()); * Assert.assertEquals(new Double("100.0"), accountFeesEntity * .getFeeAmount()); } } LoanSummaryEntity loanSummaryEntity = ((LoanBO) * accountBO) .getLoanSummary();Assert.assertEquals(new Money(getCurrency(), * "300.0"), loanSummaryEntity * .getOriginalPrincipal());Assert.assertEquals(new Money(getCurrency(), * "0.6"), loanSummaryEntity.getOriginalInterest());Assert.assertEquals(new * Money("490.0"), * loanSummaryEntity.getOriginalFees());Assert.assertEquals(new * Money("0.0"), loanSummaryEntity.getOriginalPenalty()); } */ /* * TODO: turn back on when IntersetDeductedAtDisbursement and * PrincipalDueInLastPayment are re-enabled * * * public void testCreateLoanAccountWithIDADAndPDILI() throws Exception { * Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting * = TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( startDate, * center.getCustomerMeeting().getMeeting()); UserContext userContext = * TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> * feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = * TestObjectFactory.createPeriodicAmountFee( "Periodic Fee", * FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("3")); * feeViewList.add(new FeeView(userContext, periodicFee)); FeeBO upfrontFee * = TestObjectFactory.createOneTimeRateFee( "Upfront Fee", * FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, * FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, * upfrontFee)); FeeBO disbursementFee = * TestObjectFactory.createOneTimeAmountFee( "Disbursement Fee", * FeeCategory.LOAN, "30", FeePayment.TIME_OF_DISBURSEMENT); * feeViewList.add(new FeeView(userContext, disbursementFee)); * * accountBO = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), startDate, false, 1.2, (short) 0, new * FundBO(), feeViewList, null); new * TestObjectPersistence().persist(accountBO); * * HashMap fees0 = new HashMap(); * * HashMap fees1 = new HashMap(); fees1.put("Periodic Fee", "100.0"); * * HashMap fees3 = new HashMap(); fees3.put("Periodic Fee", "100.0"); * fees3.put("Disbursement Fee", "30.0"); fees3.put("Upfront Fee", "60.0"); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(0), "0.0", "0.6", null, * null, null, fees3, null, null, null, paymentsArray[0]); * checkLoanScheduleEntity(null, "0.0", "0.0", null, null, null, fees0, * null, null, null, paymentsArray[1]); checkLoanScheduleEntity(null, "0.0", * "0.0", null, null, null, fees1, null, null, null, paymentsArray[2]); * checkLoanScheduleEntity(null, "0.0", "0.0", null, null, null, fees1, * null, null, null, paymentsArray[3]); checkLoanScheduleEntity(null, "0.0", * "0.0", null, null, null, fees0, null, null, null, paymentsArray[4]); * checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "300.0", "0.0", * null, null, null, fees1, null, null, null, paymentsArray[5]); * * Assert.assertEquals(3, accountBO.getAccountFees().size()); for * (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { if * (accountFeesEntity.getFees().getFeeName().equals("Upfront Fee")) { * Assert.assertEquals(new Money(getCurrency(), "60.0"), accountFeesEntity * .getAccountFeeAmount());Assert.assertEquals(new Double("20.0"), * accountFeesEntity .getFeeAmount()); } else if * (accountFeesEntity.getFees().getFeeName().equals( "Disbursement Fee")) { * Assert.assertEquals(new Money(getCurrency(), "30.0"), accountFeesEntity * .getAccountFeeAmount());Assert.assertEquals(new Double("30.0"), * accountFeesEntity .getFeeAmount()); } else {Assert.assertEquals(new * Money("100.0"), accountFeesEntity .getAccountFeeAmount()); * Assert.assertEquals(new Double("100.0"), accountFeesEntity * .getFeeAmount()); } } LoanSummaryEntity loanSummaryEntity = ((LoanBO) * accountBO) .getLoanSummary();Assert.assertEquals(new Money(getCurrency(), * "300.0"), loanSummaryEntity * .getOriginalPrincipal());Assert.assertEquals(new Money(getCurrency(), * "0.6"), loanSummaryEntity.getOriginalInterest());Assert.assertEquals(new * Money("490.0"), * loanSummaryEntity.getOriginalFees());Assert.assertEquals(new * Money("0.0"), loanSummaryEntity.getOriginalPenalty()); } */ public void testCreateNormalLoanAccount() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, center.getCustomerMeeting().getMeeting()); UserContext userContext = TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("3")); feeViewList.add(new FeeView(userContext, periodicFee)); FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, upfrontFee)); FeeBO disbursementFee = TestObjectFactory.createOneTimeAmountFee("Disbursement Fee", FeeCategory.LOAN, "30", FeePayment.TIME_OF_DISBURSEMENT); feeViewList.add(new FeeView(userContext, disbursementFee)); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 1.2, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Map<String, String> fees0 = new HashMap<String, String>(); Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Periodic Fee", "100.0"); Map<String, String> fees2 = new HashMap<String, String>(); fees2.put("Periodic Fee", "100.0"); fees2.put("Upfront Fee", "60.0"); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(14), "50.8", "0.2", fees2, paymentsArray[0]); checkLoanScheduleEntity(null, "50.8", "0.2", fees0, paymentsArray[1]); checkLoanScheduleEntity(null, "50.8", "0.2", fees1, paymentsArray[2]); checkLoanScheduleEntity(null, "50.8", "0.2", fees1, paymentsArray[3]); checkLoanScheduleEntity(null, "50.8", "0.2", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "46.0", "0.0", fees1, paymentsArray[5]); Assert.assertEquals(3, accountBO.getAccountFees().size()); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { if (accountFeesEntity.getFees().getFeeName().equals("Upfront Fee")) { Assert.assertEquals(new Money(getCurrency(), "60.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("20.0"), accountFeesEntity.getFeeAmount()); } else if (accountFeesEntity.getFees().getFeeName().equals("Disbursement Fee")) { Assert.assertEquals(new Money(getCurrency(), "30.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("30.0"), accountFeesEntity.getFeeAmount()); } else { Assert.assertEquals(new Money(getCurrency(), "100.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("100.0"), accountFeesEntity.getFeeAmount()); } } LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); Assert.assertEquals(new Money(getCurrency(), "1.0"), loanSummaryEntity.getOriginalInterest()); Assert.assertEquals(new Money(getCurrency(), "490.0"), loanSummaryEntity.getOriginalFees()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanSummaryEntity.getOriginalPenalty()); } public void testCreateNormalLoanAccountWithPricipalOnlyGrace() throws Exception { MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "Loan".substring(0, 1), ApplicableTo.GROUPS, new Date(System.currentTimeMillis()), PrdStatus.LOAN_ACTIVE, 300.0, 1.2, (short) 3, InterestType.FLAT, true, false, center.getCustomerMeeting().getMeeting(), GraceType.PRINCIPALONLYGRACE, "1", "1"); UserContext userContext = TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("3")); feeViewList.add(new FeeView(userContext, periodicFee)); FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, upfrontFee)); FeeBO disbursementFee = TestObjectFactory.createOneTimeAmountFee("Disbursement Fee", FeeCategory.LOAN, "30", FeePayment.TIME_OF_DISBURSEMENT); feeViewList.add(new FeeView(userContext, disbursementFee)); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 1.2, (short) 1, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Map<String, String> fees0 = new HashMap<String, String>(); Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Periodic Fee", "100.0"); Map<String, String> fees2 = new HashMap<String, String>(); fees2.put("Periodic Fee", "100.0"); fees2.put("Upfront Fee", "60.0"); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(14), "0.0", "1.0", fees2, paymentsArray[0]); checkLoanScheduleEntity(null, "60.8", "0.2", fees0, paymentsArray[1]); checkLoanScheduleEntity(null, "60.8", "0.2", fees1, paymentsArray[2]); checkLoanScheduleEntity(null, "60.8", "0.2", fees1, paymentsArray[3]); checkLoanScheduleEntity(null, "60.8", "0.2", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "56.8", "-0.8", fees1, paymentsArray[5]); Assert.assertEquals(3, accountBO.getAccountFees().size()); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { if (accountFeesEntity.getFees().getFeeName().equals("Upfront Fee")) { Assert.assertEquals(new Money(getCurrency(), "60.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("20.0"), accountFeesEntity.getFeeAmount()); } else if (accountFeesEntity.getFees().getFeeName().equals("Disbursement Fee")) { Assert.assertEquals(new Money(getCurrency(), "30.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("30.0"), accountFeesEntity.getFeeAmount()); } else { Assert.assertEquals(new Money(getCurrency(), "100.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("100.0"), accountFeesEntity.getFeeAmount()); } } LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); Assert.assertEquals(new Money(getCurrency(), "1.0"), loanSummaryEntity.getOriginalInterest()); Assert.assertEquals(new Money(getCurrency(), "490.0"), loanSummaryEntity.getOriginalFees()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanSummaryEntity.getOriginalPenalty()); } public void testCreateNormalLoanAccountWithMonthlyInstallments() throws Exception { Short dayOfMonth = (short) 1; /* * A date in the past won't work (we don't yet have a way of telling the * validation code "pretend it is such-and-such a date"). The * errors.startdateexception message says the date must be less than a * year in the future (it really means an end date less than the end of * next year). */ long sampleTime = new DateMidnight(2010, 11, 24).getMillis(); MeetingBO meeting = TestObjectFactory.getNewMeeting(MONTHLY, EVERY_SECOND_MONTH, CUSTOMER_MEETING, MONDAY); Calendar meetingStart = Calendar.getInstance(); meetingStart.setTimeInMillis(sampleTime); meeting.setMeetingStartDate(meetingStart.getTime()); meeting.getMeetingDetails().getMeetingRecurrence().setDayNumber(dayOfMonth); TestObjectFactory.createMeeting(meeting); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); Date loanStart = new Date(sampleTime); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, loanStart, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, center.getCustomerMeeting().getMeeting()); Calendar disbursementDate = new GregorianCalendar(); disbursementDate.setTimeInMillis(sampleTime); int year = disbursementDate.get(Calendar.YEAR); int zeroBasedMonth = disbursementDate.get(Calendar.MONTH); /* * TODO: this "if" is a relic from when sampleTime was based on when the * test was run. We should test these two cases somehow. */ if (disbursementDate.get(Calendar.DAY_OF_MONTH) == dayOfMonth.intValue()) { disbursementDate = new GregorianCalendar(year, zeroBasedMonth, dayOfMonth); } else { disbursementDate = new GregorianCalendar(year, zeroBasedMonth + 1, dayOfMonth); } UserContext userContext = TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, upfrontFee)); FeeBO disbursementFee = TestObjectFactory.createOneTimeRateFee("Disbursement Fee", FeeCategory.LOAN, Double.valueOf("30"), FeeFormula.AMOUNT_AND_INTEREST, FeePayment.TIME_OF_DISBURSEMENT); feeViewList.add(new FeeView(userContext, disbursementFee)); FeeBO firstRepaymentFee = TestObjectFactory.createOneTimeRateFee("First Repayment Fee", FeeCategory.LOAN, Double.valueOf("40"), FeeFormula.INTEREST, FeePayment.TIME_OF_FIRSTLOANREPAYMENT); feeViewList.add(new FeeView(userContext, firstRepaymentFee)); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.MONTHLY, Short.valueOf("1")); feeViewList.add(new FeeView(userContext, periodicFee)); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), disbursementDate.getTime(), false, 1.2, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Periodic Fee", "200.0"); Map<String, String> fees3 = new HashMap<String, String>(); fees3.put("Periodic Fee", "100.0"); fees3.put("Upfront Fee", "60.0"); fees3.put("First Repayment Fee", "1.5"); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(null, "50.9", "0.6", fees3, paymentsArray[0]); checkLoanScheduleEntity(null, "50.4", "0.6", fees1, paymentsArray[1]); checkLoanScheduleEntity(null, "50.4", "0.6", fees1, paymentsArray[2]); checkLoanScheduleEntity(null, "50.4", "0.6", fees1, paymentsArray[3]); checkLoanScheduleEntity(null, "50.4", "0.6", fees1, paymentsArray[4]); checkLoanScheduleEntity(null, "47.5", "1.5", fees1, paymentsArray[5]); Assert.assertEquals(4, accountBO.getAccountFees().size()); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { if (accountFeesEntity.getFees().getFeeName().equals("Upfront Fee")) { Assert.assertEquals(new Money(getCurrency(), "60.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("20.0"), accountFeesEntity.getFeeAmount()); } else if (accountFeesEntity.getFees().getFeeName().equals("Disbursement Fee")) { // TODO: fee_rounding should there be 2 digits to // the right of the decimal here? Assert.assertEquals(new Money(getCurrency(), "91.08"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("30.0"), accountFeesEntity.getFeeAmount()); } else if (accountFeesEntity.getFees().getFeeName().equals("First Repayment Fee")) { Assert.assertEquals(new Money(getCurrency(), "1.44"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("40.0"), accountFeesEntity.getFeeAmount()); } else { Assert.assertEquals(new Money(getCurrency(), "100.0"), accountFeesEntity.getAccountFeeAmount()); Assert.assertEquals(new Double("100.0"), accountFeesEntity.getFeeAmount()); } } LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); // TODO: fee_rounding is the difference in original interest just // a result of compounded rounding adjustments? // Assert.assertEquals(new Money(getCurrency(), "3.6"), // loanSummaryEntity.getOriginalInterest()); Assert.assertEquals(new Money(getCurrency(), "4.5"), loanSummaryEntity.getOriginalInterest()); // Assert.assertEquals(new Money(getCurrency(), "1252.5"), // loanSummaryEntity.getOriginalFees()); Assert.assertEquals(new Money(getCurrency(), "1252.58"), loanSummaryEntity.getOriginalFees()); Assert.assertEquals(new Money(getCurrency(), "0.0"), loanSummaryEntity.getOriginalPenalty()); } public void testDisburseLoanWithAllTypeOfFees() throws Exception { Date startDate = new Date(System.currentTimeMillis()); Short dayOfMonth = (short) 25; MeetingBO meeting = TestObjectFactory.getNewMeeting(MONTHLY, EVERY_MONTH, CUSTOMER_MEETING, MONDAY); TestObjectFactory.createMeeting(meeting); meeting.setMeetingStartDate(new Date()); meeting.getMeetingDetails().getMeetingRecurrence().setDayNumber(dayOfMonth); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, center.getCustomerMeeting().getMeeting()); Calendar disbursementDate = new GregorianCalendar(); int year = disbursementDate.get(Calendar.YEAR); int month = disbursementDate.get(Calendar.MONTH); int day = 25; if (disbursementDate.get(Calendar.DAY_OF_MONTH) == dayOfMonth.intValue()) { disbursementDate = new GregorianCalendar(year, month, day); } else { disbursementDate = new GregorianCalendar(year, month + 1, day); } UserContext userContext = TestUtils.makeUser(); userContext.setLocaleId(null); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO upfrontFee = TestObjectFactory.createOneTimeRateFee("Upfront Fee", FeeCategory.LOAN, Double.valueOf("20"), FeeFormula.AMOUNT, FeePayment.UPFRONT); feeViewList.add(new FeeView(userContext, upfrontFee)); FeeBO disbursementFee = TestObjectFactory.createOneTimeRateFee("Disbursement Fee", FeeCategory.LOAN, Double.valueOf("30"), FeeFormula.AMOUNT_AND_INTEREST, FeePayment.TIME_OF_DISBURSEMENT); feeViewList.add(new FeeView(userContext, disbursementFee)); FeeBO firstRepaymentFee = TestObjectFactory.createOneTimeRateFee("First Repayment Fee", FeeCategory.LOAN, Double.valueOf("40"), FeeFormula.INTEREST, FeePayment.TIME_OF_FIRSTLOANREPAYMENT); feeViewList.add(new FeeView(userContext, firstRepaymentFee)); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.MONTHLY, Short.valueOf("1")); feeViewList.add(new FeeView(userContext, periodicFee)); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), disbursementDate.getTime(), false, 1.2, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); disbursementDate = new GregorianCalendar(); year = disbursementDate.get(Calendar.YEAR); month = disbursementDate.get(Calendar.MONTH); day = 25; if (disbursementDate.get(Calendar.DAY_OF_MONTH) == dayOfMonth.intValue()) { disbursementDate = new GregorianCalendar(year, month + 1, day); } else { disbursementDate = new GregorianCalendar(year, month + 2, day); } ((LoanBO) accountBO).disburseLoan("1234", disbursementDate.getTime(), Short.valueOf("1"), accountBO.getPersonnel(), disbursementDate.getTime(), Short.valueOf("1")); Session session = StaticHibernateUtil.getSessionTL(); StaticHibernateUtil.startTransaction(); session.save(accountBO); StaticHibernateUtil.getTransaction().commit(); } public void testUpdateLoanFailure() throws Exception { Date startDate = new Date(System.currentTimeMillis()); createInitialCustomers(); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, center.getCustomerMeeting().getMeeting()); accountBO = TestObjectFactory.createLoanAccount("42423142341", group, AccountState.LOAN_PENDING_APPROVAL, startDate, loanOffering); try { LoanBO loanBO = (LoanBO) accountBO; ((LoanBO) accountBO).updateLoan(loanBO.isInterestDeductedAtDisbursement(), loanBO.getLoanAmount(), loanBO.getInterestRate(), loanBO.getNoOfInstallments(), offSetCurrentDate(15), loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), "Loan account updated", null, null, false, null, null); Assert.fail("The Loan object is created for invalid disbursement date"); } catch (AccountException expected) { if (new ConfigurationPersistence().isRepaymentIndepOfMeetingEnabled()) { Assert.assertEquals("exceptions.application.loan.invalidDisbursement", expected.getKey()); } else { Assert.assertEquals("errors.invalidDisbursementDate", expected.getKey()); } } } public void testUpdateLoanSuccess() { accountBO = getLoanAccount(); try { LoanBO loanBO = (LoanBO) accountBO; ((LoanBO) accountBO).updateLoan(loanBO.isInterestDeductedAtDisbursement(), loanBO.getLoanAmount(), loanBO.getInterestRate(), loanBO.getNoOfInstallments(), loanBO.getDisbursementDate(), loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), "Loan account updated", null, null, false, null, null); Assert.assertTrue("The Loan object is created for valid disbursement date", true); } catch (AccountException ae) { Assert.assertFalse("The Loan object is created for valid disbursement date", true); } } public void testUpdateLoanWithInterestDeductedInterestDeductedAtDisbursement() { final short NUMBER_OF_INSTALLMENTS = 1; accountBO = getLoanAccount(); try { LoanBO loanBO = (LoanBO) accountBO; ((LoanBO) accountBO).updateLoan(true, loanBO.getLoanAmount(), loanBO.getInterestRate(), NUMBER_OF_INSTALLMENTS, loanBO.getDisbursementDate(), loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), "Loan account updated", null, null, false, null, null); Assert.fail("Invalid no of installment"); } catch (AccountException ae) { Assert.assertTrue("Invalid no of installment", true); } } public void testUpdateLoanWithInterestDeductedNoInterestDeductedAtDisbursement() { final short NUMBER_OF_INSTALLMENTS = 1; accountBO = getLoanAccount(); try { LoanBO loanBO = (LoanBO) accountBO; ((LoanBO) accountBO).updateLoan(false, loanBO.getLoanAmount(), loanBO.getInterestRate(), NUMBER_OF_INSTALLMENTS, loanBO.getDisbursementDate(), loanBO.getGracePeriodDuration(), loanBO.getBusinessActivityId(), "Loan account updated", null, null, false, null, null); } catch (AccountException ae) { Assert.fail("Invalid no of installment"); } } /* * TODO: fee_rounding 0.3 is expected as the onetime fee, but 0.27 is * returned. Should this be rounded or not? * * public void testApplyTimeOfFirstRepaymentFee() throws Exception { * accountBO = getLoanAccount(); Money intialTotalFeeAmount = ((LoanBO) * accountBO).getLoanSummary() .getOriginalFees(); * TestObjectFactory.flushandCloseSession(); FeeBO oneTimeFee = * TestObjectFactory.createOneTimeRateFee( "Onetime Fee", FeeCategory.LOAN, * new Double("0.09"), FeeFormula.AMOUNT, * FeePayment.TIME_OF_FIRSTLOANREPAYMENT); accountBO = * TestObjectFactory.getObject(AccountBO.class, accountBO .getAccountId()); * UserContext uc = TestUtils.makeUser(); accountBO.setUserContext(uc); * accountBO.applyCharge(oneTimeFee.getFeeId(), ((RateFeeBO) oneTimeFee) * .getRate()); StaticHibernateUtil.commitTransaction(); * StaticHibernateUtil.closeSession(); accountBO = * TestObjectFactory.getObject(AccountBO.class, accountBO .getAccountId()); * * HashMap fees2 = new HashMap(); fees2.put("Onetime Fee", "0.3"); * fees2.put("Mainatnence Fee", "100.0"); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates();Assert.assertEquals(6, * actionDateEntities.size()); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkFees(fees2, paymentsArray[0], false); * * Assert.assertEquals(intialTotalFeeAmount.add(new Money(getCurrency(), * "0.3")), ((LoanBO) accountBO).getLoanSummary().getOriginalFees()); * LoanActivityEntity loanActivityEntity = ((LoanActivityEntity) (((LoanBO) * accountBO) .getLoanActivityDetails().toArray())[0]); * Assert.assertEquals(oneTimeFee.getFeeName() + " applied", * loanActivityEntity .getComments());Assert.assertEquals(((LoanBO) * accountBO).getLoanSummary().getOriginalFees(), * loanActivityEntity.getFeeOutstanding()); AccountFeesEntity * accountFeesEntity = accountBO .getAccountFees(oneTimeFee.getFeeId()); * Assert.assertEquals(FeeStatus.ACTIVE, * accountFeesEntity.getFeeStatusAsEnum()); } */ public void testApplyPaymentForFullPayment() throws Exception { accountBO = getLoanAccount(); Assert.assertEquals(new Money(getCurrency(), "212.0"), ((LoanBO) accountBO).getTotalPaymentDue()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "212"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency()), ((LoanBO) accountBO).getTotalPaymentDue()); } public void testApplyPaymentForPartialPayment() throws Exception { accountBO = getLoanAccount(); Assert.assertEquals(new Money(getCurrency(), "212.0"), ((LoanBO) accountBO).getTotalPaymentDue()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "200"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "12"), ((LoanBO) accountBO).getTotalPaymentDue()); Assert.assertEquals(Integer.valueOf(0), ((LoanBO) accountBO).getPerformanceHistory().getNoOfPayments()); } public void testApplyPaymentForFuturePayment() throws Exception { accountBO = getLoanAccount(); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "212.0"), ((LoanBO) accountBO).getTotalPaymentDue()); LoanScheduleEntity nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO) .getApplicableIdsForFutureInstallments().get(0); Assert.assertEquals(new Money(getCurrency(), "212.0"), nextInstallment.getTotalDueWithFees()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "312"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency()), ((LoanBO) accountBO).getTotalPaymentDue()); nextInstallment = (LoanScheduleEntity) accountBO.getAccountActionDate(nextInstallment.getInstallmentId()); Assert.assertEquals(new Money(getCurrency(), "112.0"), nextInstallment.getTotalDueWithFees()); } public void testApplyPaymentForCompletePayment() throws Exception { accountBO = getLoanAccount(); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "212.0"), ((LoanBO) accountBO).getTotalPaymentDue()); LoanScheduleEntity nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO) .getApplicableIdsForFutureInstallments().get(0); Assert.assertEquals(new Money(getCurrency(), "212.0"), nextInstallment.getTotalDueWithFees()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "1272"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency()), ((LoanBO) accountBO).getTotalPaymentDue()); nextInstallment = (LoanScheduleEntity) accountBO.getAccountActionDate(nextInstallment.getInstallmentId()); Assert.assertEquals(new Money(getCurrency()), nextInstallment.getTotalDueWithFees()); Assert.assertEquals(AccountState.LOAN_CLOSED_OBLIGATIONS_MET, accountBO.getState()); } public void testApplyPaymentForPaymentGretaterThanTotalDue() throws Exception { accountBO = getLoanAccount(); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "212.0"), ((LoanBO) accountBO).getTotalPaymentDue()); LoanScheduleEntity nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO) .getApplicableIdsForFutureInstallments().get(0); Assert.assertEquals(new Money(getCurrency(), "212.0"), nextInstallment.getTotalDueWithFees()); try { accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "1300"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); Assert.assertFalse(true); } catch (AccountException e) { Assert.assertTrue(true); } } public void testFeeForMultiplePayments() throws Exception { accountBO = getLoanAccount(); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "212.0"), ((LoanBO) accountBO).getTotalPaymentDue()); LoanScheduleEntity nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO) .getDetailsOfNextInstallment(); Assert.assertEquals(new Money(getCurrency(), "100.0"), nextInstallment.getTotalFeeDue()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "10"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO).getDetailsOfNextInstallment(); Assert.assertEquals(new Money(getCurrency(), "90"), nextInstallment.getTotalFeeDue()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "30"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO).getDetailsOfNextInstallment(); Assert.assertEquals(new Money(getCurrency(), "60"), nextInstallment.getTotalFeeDue()); } public void testLoanPerfHistoryForUndisbursedLoans() throws Exception { accountBO = getLoanAccount(); LoanBO loan = (LoanBO) accountBO; Date disbursementDate = offSetCurrentDate(28); AccountActionDateEntity accountActionDate1 = loan.getAccountActionDate((short) 1); AccountActionDateEntity accountActionDate2 = loan.getAccountActionDate((short) 2); accountBO.setUserContext(TestObjectFactory.getContext()); accountBO.changeStatus(AccountState.LOAN_APPROVED, null, ""); ((LoanScheduleEntity) accountActionDate1).setActionDate(offSetCurrentDate(21)); ((LoanScheduleEntity) accountActionDate2).setActionDate(offSetCurrentDate(14)); loan.setDisbursementDate(disbursementDate); accountBO = saveAndFetch(loan); loan = (LoanBO) accountBO; Assert.assertEquals(Integer.valueOf("0"), loan.getPerformanceHistory().getTotalNoOfMissedPayments()); Assert.assertEquals(Short.valueOf("0"), loan.getPerformanceHistory().getDaysInArrears()); Assert.assertEquals(Integer.valueOf("0"), loan.getPerformanceHistory().getNoOfPayments()); } public void testFeeForMultiplePaymentsIncludingCompletePayment() throws Exception { accountBO = getLoanAccount(); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "212.0"), ((LoanBO) accountBO).getTotalPaymentDue()); LoanScheduleEntity nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO) .getDetailsOfNextInstallment(); Assert.assertEquals(new Money(getCurrency(), "100.0"), nextInstallment.getTotalFeeDue()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "10"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO).getDetailsOfNextInstallment(); Assert.assertEquals(new Money(getCurrency(), "90"), nextInstallment.getTotalFeeDue()); Assert.assertEquals(new Money(getCurrency(), "202.0"), ((LoanBO) accountBO).getTotalPaymentDue()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "202"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); nextInstallment = (LoanScheduleEntity) ((LoanBO) accountBO).getDetailsOfNextInstallment(); Assert.assertEquals(new Money(getCurrency()), nextInstallment.getTotalFeeDue()); } /** * TODO: Re-enable this test when rounding code correctly handles mid-stream * changes to the loan schedule. */ public void testRemoveFeeForPartiallyPaidFeesAccount() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = createOfferingNoPrincipalInLastInstallment(startDate, center.getCustomerMeeting().getMeeting()); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("1")); feeViewList.add(new FeeView(TestObjectFactory.getContext(), periodicFee)); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 1.2, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "60"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, startDate, startDate)); StaticHibernateUtil.commitTransaction(); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { accountBO.removeFees(accountFeesEntity.getFees().getFeeId(), Short.valueOf("1")); } StaticHibernateUtil.commitTransaction(); Map<String, String> fees0 = new HashMap<String, String>(); Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Periodic Fee", "60"); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); Assert.assertEquals(6, actionDateEntities.size()); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkFees(fees1, paymentsArray[0], false); checkFees(fees0, paymentsArray[1], false); checkFees(fees0, paymentsArray[2], false); checkFees(fees0, paymentsArray[3], false); checkFees(fees0, paymentsArray[4], false); checkFees(fees0, paymentsArray[5], false); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { Assert.assertEquals(FeeStatus.INACTIVE, accountFeesEntity.getFeeStatusAsEnum()); Assert.assertNull(accountFeesEntity.getLastAppliedDate()); } LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "60"), loanSummaryEntity.getFeesPaid()); Assert.assertEquals(new Money(getCurrency(), "60"), loanSummaryEntity.getOriginalFees()); Assert.assertEquals(new Money(getCurrency()), loanSummaryEntity.getFeesDue()); for (LoanActivityEntity loanActivityEntity : ((LoanBO) accountBO).getLoanActivityDetails()) { if (loanActivityEntity.getComments().equalsIgnoreCase("Periodic Fee removed")) { Assert.assertEquals(loanSummaryEntity.getFeesDue(), loanActivityEntity.getFeeOutstanding()); Assert.assertEquals(new Money(getCurrency(), "1040"), loanActivityEntity.getFee()); break; } } } /** * TODO: Re-enable this test when rounding code correctly handles mid-stream * changes to the loan schedule. */ public void testApplyChargeForPartiallyPaidFeesAccount() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, center.getCustomerMeeting().getMeeting()); List<FeeView> feeViewList = new ArrayList<FeeView>(); FeeBO periodicFee = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "100", RecurrenceType.WEEKLY, Short.valueOf("1")); feeViewList.add(new FeeView(TestObjectFactory.getContext(), periodicFee)); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 1.2, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); StaticHibernateUtil.closeSession(); accountBO = (AccountBO) StaticHibernateUtil.getSessionTL().get(AccountBO.class, accountBO.getAccountId()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "60"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, startDate, startDate)); StaticHibernateUtil.commitTransaction(); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { accountBO.removeFees(accountFeesEntity.getFees().getFeeId(), Short.valueOf("1")); } StaticHibernateUtil.commitTransaction(); Map<String, String> fees0 = new HashMap<String, String>(0); Map<String, String> fees1 = new HashMap<String, String>(); fees1.put("Periodic Fee", "60"); Map<String, String> feesPaid1 = new HashMap<String, String>(); feesPaid1.put("Periodic Fee", "60"); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils .getSortedAccountActionDateEntity(((LoanBO) accountBO).getAccountActionDates()); Assert.assertEquals(6, paymentsArray.length); checkLoanScheduleEntity(null, null, null, null, null, null, fees1, feesPaid1, null, null, paymentsArray[0]); checkLoanScheduleEntity(null, null, null, null, null, null, fees0, null, null, null, paymentsArray[1]); checkLoanScheduleEntity(null, null, null, null, null, null, fees0, null, null, null, paymentsArray[2]); checkLoanScheduleEntity(null, null, null, null, null, null, fees0, null, null, null, paymentsArray[3]); checkLoanScheduleEntity(null, null, null, null, null, null, fees0, null, null, null, paymentsArray[4]); checkLoanScheduleEntity(null, null, null, null, null, null, fees0, null, null, null, paymentsArray[5]); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { Assert.assertEquals(FeeStatus.INACTIVE, accountFeesEntity.getFeeStatusAsEnum()); Assert.assertNull(accountFeesEntity.getLastAppliedDate()); } LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "60"), loanSummaryEntity.getFeesPaid()); Assert.assertEquals(new Money(getCurrency(), "60"), loanSummaryEntity.getOriginalFees()); Assert.assertEquals(new Money(getCurrency()), loanSummaryEntity.getFeesDue()); for (LoanActivityEntity loanActivityEntity : ((LoanBO) accountBO).getLoanActivityDetails()) { if (loanActivityEntity.getComments().equalsIgnoreCase("Periodic Fee removed")) { Assert.assertEquals(loanSummaryEntity.getFeesDue(), loanActivityEntity.getFeeOutstanding()); Assert.assertEquals(new Money(getCurrency(), "1040"), loanActivityEntity.getFee()); break; } } accountBO.setUserContext(TestUtils.makeUser()); for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { accountBO.applyCharge(accountFeesEntity.getFees().getFeeId(), Double.valueOf("200")); } StaticHibernateUtil.commitTransaction(); Map<String, String> fee260 = new HashMap<String, String>(); fee260.put("Periodic Fee", "260"); Map<String, String> fee400 = new HashMap<String, String>(); fee400.put("Periodic Fee", "400"); Set<AccountActionDateEntity> actionDateEntities1 = ((LoanBO) accountBO).getAccountActionDates(); Assert.assertEquals(6, actionDateEntities1.size()); LoanScheduleEntity[] paymentsArray1 = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities1); checkLoanScheduleEntity(null, null, null, null, null, null, fee260, null, null, null, paymentsArray1[0]); checkLoanScheduleEntity(null, null, null, null, null, null, fee400, null, null, null, paymentsArray1[1]); checkLoanScheduleEntity(null, null, null, null, null, null, fee400, null, null, null, paymentsArray1[2]); checkLoanScheduleEntity(null, null, null, null, null, null, fee400, null, null, null, paymentsArray1[3]); checkLoanScheduleEntity(null, null, null, null, null, null, fee400, null, null, null, paymentsArray1[4]); checkLoanScheduleEntity(null, null, null, null, null, null, fee400, null, null, null, paymentsArray1[5]); // not sure if the remaining is being handled by validatePayments for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { LoanScheduleEntity loanScheduleEntity = (LoanScheduleEntity) accountActionDateEntity; if (!loanScheduleEntity.getInstallmentId().equals(Short.valueOf("1"))) { Assert.assertEquals(1, loanScheduleEntity.getAccountFeesActionDetails().size()); for (AccountFeesActionDetailEntity accountFeesActionDetailEntity : loanScheduleEntity .getAccountFeesActionDetails()) { LoanFeeScheduleEntity loanFeeScheduleEntity = (LoanFeeScheduleEntity) accountFeesActionDetailEntity; Assert.assertEquals(TestUtils.createMoney(), loanFeeScheduleEntity.getFeeAmountPaid()); } } } for (AccountFeesEntity accountFeesEntity : accountBO.getAccountFees()) { Assert.assertEquals(FeeStatus.ACTIVE, accountFeesEntity.getFeeStatusAsEnum()); Assert.assertNotNull(accountFeesEntity.getLastAppliedDate()); } loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "60"), loanSummaryEntity.getFeesPaid()); Assert.assertEquals(new Money(getCurrency(), "2260"), loanSummaryEntity.getOriginalFees()); Assert.assertEquals(new Money(getCurrency(), "2200"), loanSummaryEntity.getFeesDue()); for (LoanActivityEntity loanActivityEntity : ((LoanBO) accountBO).getLoanActivityDetails()) { if (loanActivityEntity.getComments().equalsIgnoreCase("Periodic Fee applied")) { Assert.assertEquals(loanSummaryEntity.getFeesDue(), loanActivityEntity.getFeeOutstanding()); Assert.assertEquals(new Money(getCurrency(), "2200"), loanActivityEntity.getFee()); break; } } } public void testPartialPaymentForPrincipalGrace() throws Exception { accountBO = getLoanAccount(); ((LoanScheduleEntity) accountBO.getAccountActionDate((short) 1)).setPrincipal(new Money(getCurrency())); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "112.0"), ((LoanBO) accountBO).getTotalPaymentDue()); accountBO.applyPaymentWithPersist(TestObjectFactory.getLoanAccountPaymentData(null, new Money(getCurrency(), "100"), accountBO.getCustomer(), accountBO.getPersonnel(), "432423", (short) 1, new Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()))); accountBO = saveAndFetch(accountBO); Assert.assertEquals(new Money(getCurrency(), "12"), ((LoanBO) accountBO).getTotalPaymentDue()); Assert.assertEquals(Integer.valueOf(0), ((LoanBO) accountBO).getPerformanceHistory().getNoOfPayments()); Assert.assertFalse(((LoanBO) accountBO).getAccountActionDate((short) 1).isPaid()); } public void testGetDaysInArrears() { java.sql.Date lastWeekDate = setDate(new GregorianCalendar().DAY_OF_MONTH, -14); java.sql.Date twoWeeksBeforeDate = setDate(new GregorianCalendar().DAY_OF_MONTH, -21); accountBO = getLoanAccount(); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } else if (installment.getInstallmentId().intValue() == 2) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(Short.valueOf("21"), ((LoanBO) accountBO).getDaysInArrears()); } public void testGetDaysWithoutPaymentWhendaysLessThanLateness() throws PersistenceException { int daysLessThanLateness = -7; java.sql.Date lastWeekDate = setDate(new GregorianCalendar().DAY_OF_MONTH, daysLessThanLateness); accountBO = getLoanAccount(); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(0, ((LoanBO) accountBO).getDaysWithoutPayment()); } public void testGetDaysWithoutPaymentWhendaysMoreThanLateness() throws PersistenceException { int daysMoreThanLateness = -21; java.sql.Date twoWeeksBeforeDate = setDate(new GregorianCalendar().DAY_OF_MONTH, daysMoreThanLateness); accountBO = getLoanAccount(); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(21, ((LoanBO) accountBO).getDaysWithoutPayment()); } public void testGetTotalInterestAmountInArrears() { java.sql.Date lastWeekDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -1); java.sql.Date twoWeeksBeforeDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -2); accountBO = getLoanAccount(); Money interest = new Money(getCurrency()); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); interest = interest.add(((LoanScheduleEntity) installment).getInterest()); } else if (installment.getInstallmentId().intValue() == 2) { interest = interest.add(((LoanScheduleEntity) installment).getInterest()); ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(interest, ((LoanBO) accountBO).getTotalInterestAmountInArrears()); } public void testGetTotalInterestAmountInArrearsAndOutsideLateness() throws PersistenceException { java.sql.Date lastWeekDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -1); java.sql.Date twoWeeksBeforeDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -2); accountBO = getLoanAccount(); Money interest = new Money(getCurrency()); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } else if (installment.getInstallmentId().intValue() == 2) { interest = interest.add(((LoanScheduleEntity) installment).getInterest()); ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(interest, ((LoanBO) accountBO).getTotalInterestAmountInArrearsAndOutsideLateness()); } public void testGetTotalPrincipalAmount() { accountBO = getLoanAccount(); TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(new Money(getCurrency(), "600"), ((LoanBO) accountBO).getTotalPrincipalAmount()); } public void testGetTotalPrincipalAmountInArrears() { java.sql.Date lastWeekDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -1); java.sql.Date twoWeeksBeforeDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -2); accountBO = getLoanAccount(); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } else if (installment.getInstallmentId().intValue() == 2) { ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(new Money(getCurrency(), "200"), ((LoanBO) accountBO).getTotalPrincipalAmountInArrears()); } public void testGetTotalPrincipalAmountInArrearsAndOutsideLateness() throws PersistenceException { java.sql.Date lastWeekDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -1); java.sql.Date twoWeeksBeforeDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -2); accountBO = getLoanAccount(); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } else if (installment.getInstallmentId().intValue() == 2) { ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(new Money(getCurrency(), "100"), ((LoanBO) accountBO).getTotalPrincipalAmountInArrearsAndOutsideLateness()); } public void testGetDisbursementTerm() throws Exception { accountBO = getLoanAccount(); TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(0, ((LoanBO) accountBO).getDisbursementTerm()); } public void testGetNetOfSaving() throws Exception { accountBO = getLoanAccount(); LoanBO loanAccount = (LoanBO) accountBO; Assert.assertEquals(loanAccount.getRemainingPrincipalAmount().subtract( loanAccount.getCustomer().getSavingsBalance(getCurrency())), loanAccount.getNetOfSaving()); } public void testGetPaymentsInArrears() throws Exception { java.sql.Date lastWeekDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -1); java.sql.Date twoWeeksBeforeDate = setDate(new GregorianCalendar().WEEK_OF_MONTH, -2); accountBO = getLoanAccount(); for (AccountActionDateEntity installment : accountBO.getAccountActionDates()) { if (installment.getInstallmentId().intValue() == 1) { ((LoanScheduleEntity) installment).setActionDate(lastWeekDate); } else if (installment.getInstallmentId().intValue() == 2) { ((LoanScheduleEntity) installment).setActionDate(twoWeeksBeforeDate); } } TestObjectFactory.updateObject(accountBO); TestObjectFactory.flushandCloseSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); Assert.assertEquals(1.0, ((LoanBO) accountBO).getPaymentsInArrears(), DELTA); } public void testSaveLoanForInvalidConnection() throws Exception { createInitialCustomers(); LoanOfferingBO loanOffering = createLoanOffering(false); List<FeeView> feeViews = getFeeViews(); LoanBO loan = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, 10.0, (short) 0, null, feeViews, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); TestObjectFactory.simulateInvalidConnection(); try { loan.save(); Assert.fail(); } catch (AccountException e) { Assert.assertTrue(true); } finally { StaticHibernateUtil.closeSession(); } deleteFee(feeViews); TestObjectFactory.removeObject(loanOffering); } public void testUpdateLoanFOrInvalidConnection() { accountBO = getLoanAccount(); TestObjectFactory.simulateInvalidConnection(); try { accountBO.update(); Assert.fail(); } catch (AccountException e) { Assert.assertTrue(true); } finally { StaticHibernateUtil.closeSession(); } } public void testSuccessUpdateTotalFeeAmount() { accountBO = getLoanAccount(); LoanBO loanBO = (LoanBO) accountBO; LoanSummaryEntity loanSummaryEntity = loanBO.getLoanSummary(); Money orignalFeesAmount = loanSummaryEntity.getOriginalFees(); loanBO.updateTotalFeeAmount(TestUtils.createMoney("20")); Assert.assertEquals(loanSummaryEntity.getOriginalFees(), orignalFeesAmount.subtract(TestUtils.createMoney("20"))); } public void testCreateLoanAccountWithDecliningInterestNoGracePeriod() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "L", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 12.0, (short) 3, InterestType.DECLINING, false, false, center.getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1"); List<FeeView> feeViewList = new ArrayList<FeeView>(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, // 6 // installments 12.0, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(7 * 1), "50.3", "0.7", fees0, paymentsArray[0]); checkLoanScheduleEntity(incrementCurrentDate(7 * 2), "50.4", "0.6", fees0, paymentsArray[1]); checkLoanScheduleEntity(incrementCurrentDate(7 * 3), "50.5", "0.5", fees0, paymentsArray[2]); checkLoanScheduleEntity(incrementCurrentDate(7 * 4), "50.6", "0.4", fees0, paymentsArray[3]); checkLoanScheduleEntity(incrementCurrentDate(7 * 5), "50.7", "0.3", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(7 * 6), "47.5", "0.5", fees0, paymentsArray[5]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); } /** * Check amount of the account fee in the installment. Note that this only * works correctly if the installment has just one account fee. */ /* * private void assertOneInstallmentFee (Money expected, LoanScheduleEntity * installment) { Set<AccountFeesActionDetailEntity> actionDetails = * installment.getAccountFeesActionDetails(); for * (AccountFeesActionDetailEntity detail : actionDetails) * {Assert.assertEquals (expected, detail.getFeeAmount()); } } * * private void assertInstallmentDetails (LoanScheduleEntity installment, * Double principal, Double interest, Double accountFee, Double miscFee, * Double miscPenalty) {Assert.assertEquals(new Money(getCurrency(), * principal.toString()), * installment.getPrincipalDue());Assert.assertEquals(new * Money(interest.toString()), installment.getInterestDue()); * Assert.assertEquals(new Money(getCurrency(), miscFee.toString()), * installment.getMiscFeeDue());Assert.assertEquals(new Money(getCurrency(), * miscPenalty.toString()), installment.getMiscPenaltyDue()); * assertOneInstallmentFee(new Money(accountFee.toString()), installment); } */ public void testCreateLoanAccountWithDecliningInterestWithFeesNoGracePeriod() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "L", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 12.0, (short) 3, InterestType.DECLINING, false, false, center.getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1"); FeeBO fee = TestObjectFactory.createPeriodicRateFee("Periodic Rate Fee", FeeCategory.LOAN, new Double("9.0"), FeeFormula.INTEREST, RecurrenceType.WEEKLY, new Short("1"), userContext, meeting); feeViews.add(new FeeView(userContext, fee)); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, // 6 12.0, (short) 0, null, feeViews, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); LoanBO loan = (LoanBO) accountBO; loan.applyCharge(Short.valueOf(AccountConstants.MISC_FEES), 2.0); loan.applyCharge(Short.valueOf(AccountConstants.MISC_PENALTY), 10.0); Set<AccountActionDateEntity> actionDateEntities = loan.getAccountActionDates(); LoanScheduleEntity[] sortedInstallments = LoanBOTestUtils .getSortedAccountActionDateEntity(actionDateEntities); LoanTestUtils.assertInstallmentDetails(sortedInstallments[0], 50.0, 0.7, 0.3, 2.0, 10.0); LoanTestUtils.assertInstallmentDetails(sortedInstallments[1], 50.1, 0.6, 0.3, 0.0, 0.0); LoanTestUtils.assertInstallmentDetails(sortedInstallments[2], 50.2, 0.5, 0.3, 0.0, 0.0); LoanTestUtils.assertInstallmentDetails(sortedInstallments[3], 50.3, 0.4, 0.3, 0.0, 0.0); LoanTestUtils.assertInstallmentDetails(sortedInstallments[4], 50.4, 0.3, 0.3, 0.0, 0.0); LoanTestUtils.assertInstallmentDetails(sortedInstallments[5], 49.0, 0.1, -0.1, 0.0, 0.0); /* * HashMap fees0 = new HashMap(); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) * accountBO) .getAccountActionDates(); LoanScheduleEntity[] * paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(7 * 1), "50.0", "0.7", * fees0, paymentsArray[0]); assertOneInstallmentFee(new * Money(getCurrency(), "0.3"), paymentsArray[0]); * * checkLoanScheduleEntity(incrementCurrentDate(7 * 2), "50.1", "0.6", * fees0, paymentsArray[1]); assertOneInstallmentFee(new * Money(getCurrency(), "0.3"), paymentsArray[1]); * * checkLoanScheduleEntity(incrementCurrentDate(7 * 3), "50.2", "0.5", * fees0, paymentsArray[2]); assertOneInstallmentFee(new * Money(getCurrency(), "0.3"), paymentsArray[2]); * * checkLoanScheduleEntity(incrementCurrentDate(7 * 4), "50.3", "0.4", * fees0, paymentsArray[3]); assertOneInstallmentFee(new * Money(getCurrency(), "0.3"), paymentsArray[3]); * * checkLoanScheduleEntity(incrementCurrentDate(7 * 5), "50.4", "0.3", * fees0, paymentsArray[4]); assertOneInstallmentFee(new * Money(getCurrency(), "0.3"), paymentsArray[4]); * * checkLoanScheduleEntity(incrementCurrentDate(7 * 6), "49.0", "0.1", * fees0, paymentsArray[5]); assertOneInstallmentFee(new * Money(getCurrency(), "-0.1"), paymentsArray[5]); * * LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO) * .getLoanSummary(); * * Assert.assertEquals(new Money(getCurrency(), "300.0"), * loanSummaryEntity .getOriginalPrincipal()); */ } public void testCreateLoanAccountWithZeroFlatInterest() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "L", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 0.0, (short) 3, InterestType.FLAT, false, false, center.getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1"); List<FeeView> feeViewList = new ArrayList<FeeView>(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 0.0, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(14 * 1), "50.0", "0.0", fees0, paymentsArray[0]); checkLoanScheduleEntity(incrementCurrentDate(14 * 2), "50.0", "0.0", fees0, paymentsArray[1]); checkLoanScheduleEntity(incrementCurrentDate(14 * 3), "50.0", "0.0", fees0, paymentsArray[2]); checkLoanScheduleEntity(incrementCurrentDate(14 * 4), "50.0", "0.0", fees0, paymentsArray[3]); checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "50.0", "0.0", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "50.0", "0.0", fees0, paymentsArray[5]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); } public void testCreateLoanAccountWithZeroDecliningInterest() throws Exception { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "L", ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 0.0, (short) 3, InterestType.DECLINING, false, false, center.getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1"); List<FeeView> feeViewList = new ArrayList<FeeView>(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), startDate, false, 0.0, (short) 0, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(14 * 1), "50.0", "0.0", fees0, paymentsArray[0]); checkLoanScheduleEntity(incrementCurrentDate(14 * 2), "50.0", "0.0", fees0, paymentsArray[1]); checkLoanScheduleEntity(incrementCurrentDate(14 * 3), "50.0", "0.0", fees0, paymentsArray[2]); checkLoanScheduleEntity(incrementCurrentDate(14 * 4), "50.0", "0.0", fees0, paymentsArray[3]); checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "50.0", "0.0", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "50.0", "0.0", fees0, paymentsArray[5]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); } public void testCreateLoanAccountWithDecliningInterestGraceAllRepayments() throws Exception { short graceDuration = (short) 2; MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, new Date(System.currentTimeMillis()), PrdStatus.LOAN_ACTIVE, 300.0, 12.0, (short) 3, InterestType.DECLINING, center.getCustomerMeeting().getMeeting()); List<FeeView> feeViewList = new ArrayList<FeeView>(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, // 6 installments 12.0, graceDuration, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(14 * (1 + graceDuration)), "49.6", "1.4", fees0, paymentsArray[0]); checkLoanScheduleEntity(incrementCurrentDate(14 * (2 + graceDuration)), "49.8", "1.2", fees0, paymentsArray[1]); checkLoanScheduleEntity(incrementCurrentDate(14 * (3 + graceDuration)), "50.0", "1.0", fees0, paymentsArray[2]); checkLoanScheduleEntity(incrementCurrentDate(14 * (4 + graceDuration)), "50.3", "0.7", fees0, paymentsArray[3]); checkLoanScheduleEntity(incrementCurrentDate(14 * (5 + graceDuration)), "50.5", "0.5", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * (6 + graceDuration)), "49.8", "0.2", fees0, paymentsArray[5]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); } public void testCreateLoanAccountWithDecliningInterestGracePrincipalOnly() throws Exception { BigDecimal savedInitialRoundingMode = AccountingRules.getInitialRoundOffMultiple(); BigDecimal savedFinalRoundingMode = AccountingRules.getFinalRoundOffMultiple(); AccountingRules.setInitialRoundOffMultiple(new BigDecimal("0.1")); AccountingRules.setFinalRoundOffMultiple(new BigDecimal("0.1")); try { short graceDuration = (short) 2; MeetingBO meeting = TestObjectFactory.createMeeting( TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loan", "L", ApplicableTo.GROUPS, new Date(System.currentTimeMillis()), PrdStatus.LOAN_ACTIVE, 300.0, 12.0, (short) 3, InterestType.DECLINING, false, false, center.getCustomerMeeting().getMeeting(), GraceType.PRINCIPALONLYGRACE, "1", "1"); List<FeeView> feeViewList = new ArrayList<FeeView>(); accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), Short.valueOf("6"), new Date(System.currentTimeMillis()), false, // 6 installments 12.0, graceDuration, null, feeViewList, null, DOUBLE_ZERO, DOUBLE_ZERO, SHORT_ZERO, SHORT_ZERO, false); new TestObjectPersistence().persist(accountBO); Assert.assertEquals(6, accountBO.getAccountActionDates().size()); Map<String, String> fees0 = new HashMap<String, String>(); Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO).getAccountActionDates(); LoanScheduleEntity[] paymentsArray = LoanBOTestUtils .getSortedAccountActionDateEntity(actionDateEntities); checkLoanScheduleEntity(incrementCurrentDate(14 * 1), "0.0", "1.4", fees0, paymentsArray[0]); checkLoanScheduleEntity(incrementCurrentDate(14 * 2), "0.0", "1.4", fees0, paymentsArray[1]); checkLoanScheduleEntity(incrementCurrentDate(14 * 3), "74.5", "1.4", fees0, paymentsArray[2]); checkLoanScheduleEntity(incrementCurrentDate(14 * 4), "74.8", "1.1", fees0, paymentsArray[3]); checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "75.2", "0.7", fees0, paymentsArray[4]); checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "75.5", "0.3", fees0, paymentsArray[5]); LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO).getLoanSummary(); Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity.getOriginalPrincipal()); } finally { AccountingRules.setInitialRoundOffMultiple(savedInitialRoundingMode); AccountingRules.setFinalRoundOffMultiple(savedFinalRoundingMode); } } /* * TODO: turn back on when PrincipalDueInLastPayment is re-enabled * * * public void * testCreateLoanAccountWithDecliningInterestPrincipalDueOnLastInstallment() * throws NumberFormatException, PropertyNotFoundException, SystemException, * ApplicationException { Date startDate = new * Date(System.currentTimeMillis()); * * short graceDuration = (short) 2; MeetingBO meeting = * TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( "Loan", "Loan".substring(0, 1), * ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, * (short) 3, InterestType.DECLINING, false, true, center * .getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1"); * List<FeeView> feeViewList = new ArrayList<FeeView>(); * * accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), startDate, false, // 6 // installments 1.2, * graceDuration, null, feeViewList, null); new * TestObjectPersistence().persist(accountBO);Assert.assertEquals(6, * accountBO.getAccountActionDates().size()); * * HashMap fees0 = new HashMap(); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 1), "0.0", "0.1", * fees0, paymentsArray[0]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 2), "0.0", "0.1", * fees0, paymentsArray[1]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 3), "0.0", "0.1", * fees0, paymentsArray[2]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 4), "0.0", "0.1", * fees0, paymentsArray[3]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "0.0", "0.1", * fees0, paymentsArray[4]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "300.0", "0.1", * fees0, paymentsArray[5]); * * LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO) * .getLoanSummary();Assert.assertEquals(new Money(getCurrency(), "300.0"), * loanSummaryEntity .getOriginalPrincipal()); * * } */ /* * TODO: turn back on when EPI (equal principal loans) is re-enabled * * * * public void * testCreateLoanAccountWithEqualPrincipalDecliningInterestNoGracePeriod() * throws NumberFormatException, PropertyNotFoundException, SystemException, * ApplicationException { Date startDate = new * Date(System.currentTimeMillis()); * * MeetingBO meeting = TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( "Loan", "L", ApplicableTo.GROUPS, * startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, (short) 3, * InterestType.DECLINING_EPI, false, false, center * .getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1"); * List<FeeView> feeViewList = new ArrayList<FeeView>(); * * accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), startDate, false, // 6 // installments 1.2, * (short) 0, null, feeViewList, null); new * TestObjectPersistence().persist(accountBO);Assert.assertEquals(6, * accountBO.getAccountActionDates().size()); * * HashMap fees0 = new HashMap(); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 1), "50.9", "0.1", * fees0, paymentsArray[0]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 2), "50.9", "0.1", * fees0, paymentsArray[1]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 3), "50.9", "0.1", * fees0, paymentsArray[2]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 4), "50.9", "0.1", * fees0, paymentsArray[3]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "50.0", "0.0", * fees0, paymentsArray[4]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "46.4", "0.0", * fees0, paymentsArray[5]); * * LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO) * .getLoanSummary(); * * Assert.assertEquals(new Money(getCurrency(), "300.0"), loanSummaryEntity * .getOriginalPrincipal()); * * } * * * public void * testCreateLoanAccountWithEqualPrincipalDecliningInterestGraceAllRepayments * () throws NumberFormatException, PropertyNotFoundException, * SystemException, ApplicationException { * * short graceDuration = (short) 2; MeetingBO meeting = * TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( "Loan", ApplicableTo.GROUPS, new * Date(System .currentTimeMillis()), PrdStatus.LOAN_ACTIVE, 300.0, 1.2, * (short) 3, InterestType.DECLINING_EPI, * center.getCustomerMeeting().getMeeting()); List<FeeView> feeViewList = * new ArrayList<FeeView>(); * * accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), new Date(System .currentTimeMillis()), * false, // 6 installments 1.2, graceDuration, null, feeViewList, * null); new * TestObjectPersistence().persist(accountBO);Assert.assertEquals(6, * accountBO.getAccountActionDates().size()); HashMap fees0 = new HashMap(); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(14 * (1 + graceDuration)), * "50.9", "0.1", fees0, paymentsArray[0]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * (2 + graceDuration)), * "50.9", "0.1", fees0, paymentsArray[1]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * (3 + graceDuration)), * "50.9", "0.1", fees0, paymentsArray[2]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * (4 + graceDuration)), * "50.9", "0.1", fees0, paymentsArray[3]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * (5 + graceDuration)), * "50.0", "0.0", fees0, paymentsArray[4]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * (6 + graceDuration)), * "46.4", "0.0", fees0, paymentsArray[5]); * * LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO) * .getLoanSummary();Assert.assertEquals(new Money(getCurrency(), "300.0"), * loanSummaryEntity .getOriginalPrincipal()); * * } * * public void * testCreateLoanAccountWithEqualPrincipalDecliningInterestGracePrincipalOnly * () throws NumberFormatException, PropertyNotFoundException, * SystemException, ApplicationException { * * short graceDuration = (short) 2; MeetingBO meeting = * TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( "Loan", "L", ApplicableTo.GROUPS, * new Date(System .currentTimeMillis()), PrdStatus.LOAN_ACTIVE, 300.0, 1.2, * (short) 3, InterestType.DECLINING_EPI, false, false, * center.getCustomerMeeting().getMeeting(), GraceType.PRINCIPALONLYGRACE, * "1", "1"); List<FeeView> feeViewList = new ArrayList<FeeView>(); * * accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), new Date(System .currentTimeMillis()), * false, // 6 installments 1.2, graceDuration, null, feeViewList, * null); new * TestObjectPersistence().persist(accountBO);Assert.assertEquals(6, * accountBO.getAccountActionDates().size()); * * HashMap fees0 = new HashMap(); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 1), "0.0", "0.1", * fees0, paymentsArray[0]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 2), "0.0", "0.1", * fees0, paymentsArray[1]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 3), "75.0", "0.1", * fees0, paymentsArray[2]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 4), "75.0", "0.1", * fees0, paymentsArray[3]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "75.0", "0.1", * fees0, paymentsArray[4]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "75.0", "0.0", * fees0, paymentsArray[5]); * * LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO) * .getLoanSummary();Assert.assertEquals(new Money(getCurrency(), "300.0"), * loanSummaryEntity .getOriginalPrincipal()); * * } * * * public void * testCreateLoanAccountWithEqualPrincipalDecliningInterestPrincipalDueOnLastInstallment * () throws NumberFormatException, PropertyNotFoundException, * SystemException, ApplicationException { Date startDate = new * Date(System.currentTimeMillis()); * * short graceDuration = (short) 2; MeetingBO meeting = * TestObjectFactory.createMeeting(TestObjectFactory * .getNewMeetingForToday(WEEKLY, EVERY_SECOND_WEEK, CUSTOMER_MEETING)); * center = TestObjectFactory.createCenter("Center", meeting); group = * TestObjectFactory.createGroupUnderCenter("Group", * CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = * TestObjectFactory.createLoanOffering( "Loan", "Loan".substring(0, 1), * ApplicableTo.GROUPS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, * (short) 3, InterestType.DECLINING_EPI, false, true, center * .getCustomerMeeting().getMeeting(), GraceType.NONE, "1", "1"); * List<FeeView> feeViewList = new ArrayList<FeeView>(); * * accountBO = loanDao.createLoan(TestUtils.makeUser(), loanOffering, group, * AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), * "300.0"), Short.valueOf("6"), startDate, false, // 6 // installments 1.2, * graceDuration, null, feeViewList, null); new * TestObjectPersistence().persist(accountBO);Assert.assertEquals(6, * accountBO.getAccountActionDates().size()); * * HashMap fees0 = new HashMap(); * * Set<AccountActionDateEntity> actionDateEntities = ((LoanBO) accountBO) * .getAccountActionDates(); LoanScheduleEntity[] paymentsArray = * LoanBOTestUtils.getSortedAccountActionDateEntity(actionDateEntities); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 1), "0.0", "0.1", * fees0, paymentsArray[0]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 2), "0.0", "0.1", * fees0, paymentsArray[1]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 3), "0.0", "0.1", * fees0, paymentsArray[2]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 4), "0.0", "0.1", * fees0, paymentsArray[3]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 5), "0.0", "0.1", * fees0, paymentsArray[4]); * * checkLoanScheduleEntity(incrementCurrentDate(14 * 6), "300.0", "0.1", * fees0, paymentsArray[5]); * * LoanSummaryEntity loanSummaryEntity = ((LoanBO) accountBO) * .getLoanSummary();Assert.assertEquals(new Money(getCurrency(), "300.0"), * loanSummaryEntity .getOriginalPrincipal()); * * } */ private java.sql.Date setDate(final int dayUnit, final int interval) { Calendar calendar = new GregorianCalendar(); calendar.setTime(DateUtils.getCurrentDateWithoutTimeStamp()); calendar.add(dayUnit, interval); return new java.sql.Date(calendar.getTimeInMillis()); } /* * creates loan with an initial status of LOAN_ACTIVE_IN_GOOD_STANDING * (rather than LOAN_APPROVED) as tests using this method only process * repayments not disbursals and you can't repay until you disburse - jpw */ private LoanBO createAndRetrieveLoanAccount(final LoanOfferingBO loanOffering, final boolean isInterestDedAtDisb, final List<FeeView> feeViews, final Short noOfinstallments, final Double interestRate, final Money loanAmount) throws NumberFormatException, AccountException, SystemException, ApplicationException { LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); // LoanBO loan = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, LoanBO loan = LoanBO.createLoan(userContext, loanOffering, group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, new Money(getCurrency(), "300.0"), noOfinstallments, new Date(System.currentTimeMillis()), isInterestDedAtDisb, interestRate, (short) 0, null, feeViews, null, DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); loan.save(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); accountBO = TestObjectFactory.getObject(AccountBO.class, loan.getAccountId()); LoanBO loanBO = (LoanBO) accountBO; return loanBO; } /** * Added by Keith -- the original, createAndRetrieveLoanAccount(), when it * retrieves the loan from the database, would have its userContext set to * null -- this would happen in the test method * testLoanScheduleRoundingWithMiscFee(). This modified method saves the * loan but does not replace it with the retrieved one before returning it. */ private LoanBO createButDontRetrieveLoanAccount(final LoanOfferingBO loanOffering, final boolean isInterestDedAtDisb, final List<FeeView> feeViews, final Short noOfinstallments, final Double interestRate, final Money loanAmount) throws Exception { LoanOfferingInstallmentRange eligibleInstallmentRange = loanOffering.getEligibleInstallmentSameForAllLoan(); // LoanBO loan = LoanBO.createLoan(TestUtils.makeUser(), loanOffering, LoanBO loan = LoanBO.createLoan(userContext, loanOffering, group, AccountState.LOAN_APPROVED, new Money(getCurrency(), "300.0"), noOfinstallments, new Date(System.currentTimeMillis()), isInterestDedAtDisb, interestRate, (short) 0, null, feeViews, null, DEFAULT_LOAN_AMOUNT, DEFAULT_LOAN_AMOUNT, eligibleInstallmentRange.getMaxNoOfInstall(), eligibleInstallmentRange.getMinNoOfInstall(), false, null); loan.save(); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); return loan; } private LoanBO createAndRetrieveLoanAccount(final LoanOfferingBO loanOffering, final boolean isInterestDedAtDisb, final List<FeeView> feeViews, final Short noOfinstallments) throws NumberFormatException, AccountException, SystemException, ApplicationException { return createAndRetrieveLoanAccount(loanOffering, isInterestDedAtDisb, feeViews, noOfinstallments, 10.0, new Money(getCurrency(), "300.0")); } private LoanOfferingBO createLoanOffering(final boolean isPrincipalAtLastInst) { return createLoanOffering(isPrincipalAtLastInst, false, PrdStatus.LOAN_ACTIVE); } // TODO: check where this is used to see if the test cases that use it // need to be commented out private LoanOfferingBO createLoanOffering(final boolean principalAtLastInst, final boolean interestDeductedAtDisbursement, final PrdStatus status) { MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); return TestObjectFactory.createLoanOffering("Loan", ApplicableTo.GROUPS, new Date(System.currentTimeMillis()), status, 300.0, 1.2, 3, InterestType.FLAT, interestDeductedAtDisbursement, principalAtLastInst, meeting); } private List<FeeView> getFeeViews() { FeeBO fee1 = TestObjectFactory.createOneTimeAmountFee("One Time Amount Fee", FeeCategory.LOAN, "120.0", FeePayment.TIME_OF_DISBURSEMENT); FeeBO fee3 = TestObjectFactory.createPeriodicAmountFee("Periodic Fee", FeeCategory.LOAN, "10.0", RecurrenceType.WEEKLY, (short) 1); List<FeeView> feeViews = new ArrayList<FeeView>(); FeeView feeView1 = new FeeView(userContext, fee1); FeeView feeView2 = new FeeView(userContext, fee3); feeViews.add(feeView1); feeViews.add(feeView2); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); return feeViews; } private void deleteFee(final List<FeeView> feeViews) { for (FeeView feeView : feeViews) { TestObjectFactory.cleanUp((FeeBO) TestObjectFactory.getObject(FeeBO.class, feeView.getFeeIdValue())); } } private AccountBO getLoanAccount() { Date startDate = new Date(System.currentTimeMillis()); createInitialCustomers(); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, center.getCustomerMeeting().getMeeting()); return TestObjectFactory.createLoanAccount("42423142341", group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, startDate, loanOffering); } private AccountBO getBasicLoanAccount() { Date startDate = new Date(System.currentTimeMillis()); createInitialCustomers(); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, center.getCustomerMeeting().getMeeting()); return TestObjectFactory.createBasicLoanAccount(group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, startDate, loanOffering); } private void createInitialCustomers() { MeetingBO meeting = TestObjectFactory.createMeeting(TestObjectFactory.getNewWeeklyMeeting(EVERY_WEEK)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); } private void changeFirstInstallmentDateToNextDate(final AccountBO accountBO) { Calendar currentDateCalendar = new GregorianCalendar(); int year = currentDateCalendar.get(Calendar.YEAR); int month = currentDateCalendar.get(Calendar.MONTH); int day = currentDateCalendar.get(Calendar.DAY_OF_MONTH); currentDateCalendar = new GregorianCalendar(year, month, day + 1); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { ((LoanScheduleEntity) accountActionDateEntity) .setActionDate(new java.sql.Date(currentDateCalendar.getTimeInMillis())); break; } } private AccountBO applyPaymentandRetrieveAccount() throws AccountException, SystemException { Date startDate = new Date(System.currentTimeMillis()); PaymentData paymentData = PaymentData.createPaymentData( new Money(Configuration.getInstance().getSystemConfig().getCurrency(), "212.0"), accountBO.getPersonnel(), Short.valueOf("1"), startDate); paymentData.setReceiptDate(startDate); paymentData.setReceiptNum("5435345"); accountBO.applyPaymentWithPersist(paymentData); StaticHibernateUtil.commitTransaction(); StaticHibernateUtil.closeSession(); return TestObjectFactory.getObject(AccountBO.class, accountBO.getAccountId()); } private AccountBO getLoanAccountWithMiscFeeAndPenalty(final AccountState state, final Date startDate, final int disbursalType, final Money miscFee, final Money miscPenalty) { LoanBO accountBO = getLoanAccount(state, startDate, disbursalType); for (AccountActionDateEntity accountAction : accountBO.getAccountActionDates()) { LoanScheduleEntity accountActionDateEntity = (LoanScheduleEntity) accountAction; if (accountActionDateEntity.getInstallmentId().equals(Short.valueOf("1"))) { accountActionDateEntity.setMiscFee(miscFee); accountActionDateEntity.setMiscPenalty(miscPenalty); break; } } LoanSummaryEntity loanSummaryEntity = accountBO.getLoanSummary(); loanSummaryEntity.setOriginalFees(loanSummaryEntity.getOriginalFees().add(miscFee)); loanSummaryEntity.setOriginalPenalty(loanSummaryEntity.getOriginalPenalty().add(miscPenalty)); TestObjectPersistence testObjectPersistence = new TestObjectPersistence(); testObjectPersistence.update(accountBO); return testObjectPersistence.getObject(LoanBO.class, accountBO.getAccountId()); } private void changeInstallmentDate(final AccountBO accountBO, final int numberOfDays, final Short installmentId) { for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { if (accountActionDateEntity.getInstallmentId().equals(installmentId)) { Calendar dateCalendar = new GregorianCalendar(); dateCalendar.setTimeInMillis(accountActionDateEntity.getActionDate().getTime()); int year = dateCalendar.get(Calendar.YEAR); int month = dateCalendar.get(Calendar.MONTH); int day = dateCalendar.get(Calendar.DAY_OF_MONTH); dateCalendar = new GregorianCalendar(year, month, day - numberOfDays); ((LoanScheduleEntity) accountActionDateEntity) .setActionDate(new java.sql.Date(dateCalendar.getTimeInMillis())); break; } } } private AccountBO getLoanAccountWithPerformanceHistory() { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); client = TestObjectFactory.createClient(this.getClass().getSimpleName() + " Client", CustomerStatus.CLIENT_ACTIVE, group); /* * ((ClientBO) client).getPerformanceHistory().setLoanCycleNumber(1); * TestObjectFactory.updateObject(client); */ LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting); accountBO = TestObjectFactory.createLoanAccount("42423142341", client, AccountState.LOAN_APPROVED, startDate, loanOffering); ((ClientBO) client).getClientPerformanceHistory().updateLoanCounter(loanOffering, YesNoFlag.YES); TestObjectFactory.updateObject(client); TestObjectFactory.updateObject(accountBO); return accountBO; } private AccountBO getLoanAccountWithPerformanceHistory(final AccountState state, final Date startDate, final int disbursalType) { MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); client = TestObjectFactory.createClient(this.getClass().getSimpleName() + " Client", CustomerStatus.CLIENT_ACTIVE, group); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting); // ((ClientBO) client).getPerformanceHistory().setLoanCycleNumber(1); accountBO = TestObjectFactory.createLoanAccountWithDisbursement("99999999999", client, state, startDate, loanOffering, disbursalType); ((ClientBO) client).getClientPerformanceHistory().updateLoanCounter(loanOffering, YesNoFlag.YES); return accountBO; } private AccountBO getLoanAccountWithGroupPerformanceHistory(final AccountState state, final Date startDate, final int disbursalType) { MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering( this.getClass().getSimpleName() + " Loan", ApplicableTo.CLIENTS, startDate, PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, meeting); accountBO = TestObjectFactory.createLoanAccountWithDisbursement("99999999999", group, state, startDate, loanOffering, disbursalType); return accountBO; } private AccountActionDateEntity getLastInstallmentAccountAction(final LoanBO loanBO) { AccountActionDateEntity nextAccountAction = null; if (loanBO.getAccountActionDates() != null && loanBO.getAccountActionDates().size() > 0) { for (AccountActionDateEntity accountAction : loanBO.getAccountActionDates()) { if (null == nextAccountAction) { nextAccountAction = accountAction; } else if (nextAccountAction.getInstallmentId() < accountAction.getInstallmentId()) { nextAccountAction = accountAction; } } } return nextAccountAction; } private void changeFirstInstallmentDate(final AccountBO accountBO, final int numberOfDays) { Calendar currentDateCalendar = new GregorianCalendar(); int year = currentDateCalendar.get(Calendar.YEAR); int month = currentDateCalendar.get(Calendar.MONTH); int day = currentDateCalendar.get(Calendar.DAY_OF_MONTH); currentDateCalendar = new GregorianCalendar(year, month, day - numberOfDays); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { ((LoanScheduleEntity) accountActionDateEntity) .setActionDate(new java.sql.Date(currentDateCalendar.getTimeInMillis())); break; } } private void changeFirstInstallmentDate(final AccountBO accountBO) { Calendar currentDateCalendar = new GregorianCalendar(); int year = currentDateCalendar.get(Calendar.YEAR); int month = currentDateCalendar.get(Calendar.MONTH); int day = currentDateCalendar.get(Calendar.DAY_OF_MONTH); currentDateCalendar = new GregorianCalendar(year, month, day - 1); for (AccountActionDateEntity accountActionDateEntity : accountBO.getAccountActionDates()) { ((LoanScheduleEntity) accountActionDateEntity) .setActionDate(new java.sql.Date(currentDateCalendar.getTimeInMillis())); break; } } private AccountBO saveAndFetch(final AccountBO account) throws Exception { TestObjectFactory.updateObject(account); StaticHibernateUtil.closeSession(); return accountPersistence.getAccount(account.getAccountId()); } private java.sql.Date offSetCurrentDate(final int noOfDays) { Calendar currentDateCalendar = new GregorianCalendar(); int year = currentDateCalendar.get(Calendar.YEAR); int month = currentDateCalendar.get(Calendar.MONTH); int day = currentDateCalendar.get(Calendar.DAY_OF_MONTH); currentDateCalendar = new GregorianCalendar(year, month, day - noOfDays); return new java.sql.Date(currentDateCalendar.getTimeInMillis()); } private LoanBO getLoanAccount(final AccountState state, final Date startDate, final int disbursalType) { MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting); return TestObjectFactory.createLoanAccountWithDisbursement("99999999999", group, state, startDate, loanOffering, disbursalType); } private Date incrementCurrentDate(final int noOfDays) { Calendar currentDateCalendar = new GregorianCalendar(); int year = currentDateCalendar.get(Calendar.YEAR); int month = currentDateCalendar.get(Calendar.MONTH); int day = currentDateCalendar.get(Calendar.DAY_OF_MONTH); currentDateCalendar = new GregorianCalendar(year, month, day + noOfDays); return DateUtils.getDateWithoutTimeStamp(currentDateCalendar.getTimeInMillis()); } private void checkLoanScheduleEntity(final Date date, final String principal, final String interest, final String miscFee, final String miscPenalty, final String penalty, final Map<String, String> fees, final Map<String, String> feesPaid, final String totalFeeDue, final String totalDueWithFees, final LoanScheduleEntity entity) { if (date != null) { assertDate(date, entity); } if (principal != null) { Assert.assertEquals(new Money(entity.getPrincipal().getCurrency(), principal), entity.getPrincipal()); } if (interest != null) { Assert.assertEquals(new Money(entity.getInterest().getCurrency(), interest), entity.getInterest()); } if (miscFee != null) { Assert.assertEquals(new Money(entity.getMiscFee().getCurrency(), miscFee), entity.getMiscFee()); } if (miscPenalty != null) { Assert.assertEquals(new Money(entity.getMiscPenalty().getCurrency(), miscPenalty), entity.getMiscPenalty()); } if (penalty != null) { Assert.assertEquals(new Money(entity.getPenalty().getCurrency(), penalty), entity.getPenalty()); } if (fees != null) { checkFees(fees, entity, false); } if (feesPaid != null) { checkFees(feesPaid, entity, true); } if (totalFeeDue != null) { checkTotalDue(totalFeeDue, entity); } if (totalDueWithFees != null) { checkTotalDueWithFees(totalDueWithFees, entity); } } private void checkTotalDueWithFees(final String totalDueWithFees, final LoanScheduleEntity entity) { Assert.assertEquals(new Money(entity.getTotalDueWithFees().getCurrency(), totalDueWithFees), entity.getTotalDueWithFees()); } private void checkTotalDue(final String totalFeeDue, final LoanScheduleEntity entity) { Assert.assertEquals(new Money(entity.getTotalFeeDue().getCurrency(), totalFeeDue), entity.getTotalFeeDue()); } private void checkLoanScheduleEntity(final Date date, final String principal, final String interest, final Map<String, String> fees, final LoanScheduleEntity entity) { if (date != null) { assertDate(date, entity); } Assert.assertEquals(new Money(entity.getPrincipal().getCurrency(), principal), entity.getPrincipal()); Assert.assertEquals(new Money(entity.getInterest().getCurrency(), interest), entity.getInterest()); checkFees(fees, entity, false); } private void assertDate(final Date date, final LoanScheduleEntity entity) { Assert.assertEquals(DateUtils.getDateWithoutTimeStamp(date.getTime()), DateUtils.getDateWithoutTimeStamp(entity.getActionDate().getTime())); } private void checkFees(final Map<String, String> expectedFess, final String totalFeeDue, final LoanScheduleEntity entity) { checkFees(expectedFess, entity, false); Assert.assertEquals(new Money(entity.getTotalFeeDue().getCurrency(), totalFeeDue), entity.getTotalFeeDue()); } private void checkPrincipalAndInterest(final String principal, final String interest, final LoanScheduleEntity entity) { Assert.assertEquals(new Money(entity.getPrincipal().getCurrency(), principal), entity.getPrincipal()); Assert.assertEquals(new Money(entity.getInterest().getCurrency(), interest), entity.getInterest()); } private void checkFees(final Map<String, String> expected, final LoanScheduleEntity loanScheduleEntity, final boolean checkPaid) { Set<AccountFeesActionDetailEntity> accountFeesActionDetails = loanScheduleEntity .getAccountFeesActionDetails(); Assert.assertEquals("fees were " + feeNames(accountFeesActionDetails), expected.size(), accountFeesActionDetails.size()); for (AccountFeesActionDetailEntity accountFeesActionDetailEntity : accountFeesActionDetails) { if (expected.get(accountFeesActionDetailEntity.getFee().getFeeName()) != null) { Assert.assertEquals( new Money(TestUtils.RUPEE, expected.get(accountFeesActionDetailEntity.getFee().getFeeName())), checkPaid ? accountFeesActionDetailEntity.getFeeAmountPaid() : accountFeesActionDetailEntity.getFeeAmount()); } else { Assert.assertFalse( "Fee amount not found for " + accountFeesActionDetailEntity.getFee().getFeeName(), true); } } } private String feeNames(final Collection<AccountFeesActionDetailEntity> details) { StringBuilder debugString = new StringBuilder(); for (Iterator<AccountFeesActionDetailEntity> iter = details.iterator(); iter.hasNext();) { AccountFeesActionDetailEntity detail = iter.next(); debugString.append(detail.getFee().getFeeName()); if (iter.hasNext()) { debugString.append(", "); } } return debugString.toString(); } private void createInitialObjects() { meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); client = TestObjectFactory.createClient(this.getClass().getSimpleName() + " Client", CustomerStatus.CLIENT_ACTIVE, group); } private AccountBO getLoanAccount(final CustomerBO customer, final MeetingBO meeting) { Date startDate = new Date(System.currentTimeMillis()); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting); return TestObjectFactory.createLoanAccount("42423142341", customer, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, startDate, loanOffering); } private AccountBO createLoanAccount() { Date startDate = new Date(System.currentTimeMillis()); MeetingBO meeting = TestObjectFactory .createMeeting(TestObjectFactory.getNewMeetingForToday(WEEKLY, EVERY_WEEK, CUSTOMER_MEETING)); center = TestObjectFactory.createWeeklyFeeCenter(this.getClass().getSimpleName() + " Center", meeting); group = TestObjectFactory.createWeeklyFeeGroupUnderCenter(this.getClass().getSimpleName() + " Group", CustomerStatus.GROUP_ACTIVE, center); LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering(startDate, meeting); accountBO = TestObjectFactory.createLoanAccount("42423142341", group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, startDate, loanOffering); return accountBO; } private List<CustomFieldView> getCustomFields() { List<CustomFieldView> fields = new ArrayList<CustomFieldView>(); fields.add(new CustomFieldView(Short.valueOf("5"), "value1", CustomFieldType.ALPHA_NUMERIC)); return fields; } public void testIsDisbursementDateLessThanCurrentDateShouldReturnTrueIfDateInPast() throws Exception { Assert.assertTrue(LoanBO.isDisbursementDateLessThanCurrentDate(getDateFromToday(-1))); } public void testIsDisbursementDateLessThanCurrentDateShouldReturnFalseIfDateInFuture() throws Exception { Assert.assertFalse(LoanBO.isDisbursementDateLessThanCurrentDate(getDateFromToday(1))); } public void testIsDisbursementDateLessThanCurrentDateShouldReturnFalseIfDateIsToday() throws Exception { Assert.assertFalse(LoanBO.isDisbursementDateLessThanCurrentDate(getCurrentDateWithoutTimeStamp())); } public void testIsDisbursementDateAfterProductStartDateShouldReturnFalseIfProductStartDateIsLaterThanDisbursement() throws Exception { Assert.assertFalse(LoanBO.isDisbursementDateAfterProductStartDate(currentDate(), new LoanOfferingBO() { @Override public Date getStartDate() { return getDateFromToday(1); } })); } public void testIsDisbursementDateAfterProductStartDateShouldReturnTrueIfProductStartDateIsEarlierThanDisbursement() throws Exception { Assert.assertTrue(LoanBO.isDisbursementDateAfterProductStartDate(currentDate(), new LoanOfferingBO() { @Override public Date getStartDate() { return getDateFromToday(-1); } })); } public void testIsDisbursementDateAfterProductStartDateShouldReturnTrueIfProductStartDateSameAsDisbursement() throws Exception { Assert.assertTrue(LoanBO.isDisbursementDateAfterProductStartDate(currentDate(), new LoanOfferingBO() { @Override public Date getStartDate() { return currentDate(); } })); } public void testDisbursementDateInvalidForRedoIfDisbursementBeforeCustomerActivationDate() throws Exception { Assert.assertFalse(LoanBO.isDibursementDateValidForRedoLoan(new LoanOfferingBO() { @Override public Date getStartDate() { return DateUtils.getDate(2008, Calendar.JANUARY, 1); } }, new ClientBO() { @Override public Date getCustomerActivationDate() { return DateUtils.getDate(2008, Calendar.JANUARY, 2); } }, DateUtils.getDate(2008, Calendar.JANUARY, 1))); } public void testDisbursementDateInvalidForRedoIfDisbursementBeforeProductStartDate() throws Exception { Assert.assertFalse(LoanBO.isDibursementDateValidForRedoLoan(new LoanOfferingBO() { @Override public Date getStartDate() { return DateUtils.getDate(2008, Calendar.JANUARY, 2); } }, new ClientBO() { @Override public Date getCustomerActivationDate() { return DateUtils.getDate(2008, Calendar.JANUARY, 1); } }, DateUtils.getDate(2008, Calendar.JANUARY, 1))); } public void testDisbursementDateValidForRedoIfDisbursementAfterActivationAndProductStartDate() throws Exception { Assert.assertTrue(LoanBO.isDibursementDateValidForRedoLoan(new LoanOfferingBO() { @Override public Date getStartDate() { return DateUtils.getDate(2008, Calendar.JANUARY, 1); } }, new ClientBO() { @Override public Date getCustomerActivationDate() { return DateUtils.getDate(2008, Calendar.JANUARY, 1); } }, DateUtils.getDate(2008, Calendar.JANUARY, 1))); } }