/*
* Copyright (c) 2005-2011 Grameen Foundation USA
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* See also http://www.apache.org/licenses/LICENSE-2.0.html for an
* explanation of the license and how it is applied.
*/
package org.mifos.framework.components.batchjobs.helpers;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Set;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mifos.accounts.business.AccountActionDateEntity;
import org.mifos.accounts.business.AccountBO;
import org.mifos.accounts.loan.business.LoanBO;
import org.mifos.accounts.loan.business.LoanBOTestUtils;
import org.mifos.accounts.loan.business.LoanScheduleEntity;
import org.mifos.accounts.productdefinition.business.LoanOfferingBO;
import org.mifos.accounts.productdefinition.util.helpers.ApplicableTo;
import org.mifos.accounts.productdefinition.util.helpers.InterestType;
import org.mifos.accounts.productdefinition.util.helpers.PrdStatus;
import org.mifos.accounts.util.helpers.AccountState;
import org.mifos.accounts.util.helpers.AccountTypes;
import org.mifos.accounts.util.helpers.PaymentData;
import org.mifos.application.master.util.helpers.PaymentTypes;
import org.mifos.application.meeting.business.MeetingBO;
import org.mifos.customers.center.business.CenterBO;
import org.mifos.customers.client.business.ClientBO;
import org.mifos.customers.group.business.GroupBO;
import org.mifos.customers.office.business.OfficeBO;
import org.mifos.customers.personnel.business.PersonnelBO;
import org.mifos.customers.util.helpers.CustomerStatus;
import org.mifos.framework.MifosIntegrationTestCase;
import org.mifos.framework.TestUtils;
import org.mifos.framework.hibernate.helper.StaticHibernateUtil;
import org.mifos.framework.util.helpers.IntegrationTestObjectMother;
import org.mifos.framework.util.helpers.Money;
import org.mifos.framework.util.helpers.TestObjectFactory;
public class PortfolioAtRiskCalculationIntegrationTest extends MifosIntegrationTestCase {
private static final double DELTA = 0.00000001;
private AccountBO account1 = null;
private AccountBO account2 = null;
private CenterBO center;
private CenterBO center1 = null;
private GroupBO group;
private GroupBO group1;
private ClientBO client;
private ClientBO client1 = null;
private ClientBO client2 = null;
private OfficeBO officeBO;
@Before
public void setUp() throws Exception {
StaticHibernateUtil.getSessionTL().clear();
}
@After
public void tearDown() throws Exception {
try {
client1 = null;
client2 = null;
account1 = null;
account2 = null;
// account2 = null;
// account1 = null;
// TestObjectFactory.cleanUp(client1);
// TestObjectFactory.cleanUp(client2);
client = null;
group = null;
group1 = null;
center = null;
center1 = null;
officeBO = null;
} catch (Exception e) {
// TODO Whoops, cleanup didnt work, reset db
}
StaticHibernateUtil.flushSession();
}
private void createInitialObject() {
Date startDate = new Date(System.currentTimeMillis());
MeetingBO meeting = TestObjectFactory.createMeeting(TestObjectFactory.getTypicalMeeting());
center = TestObjectFactory.createWeeklyFeeCenter("Center", meeting);
group = TestObjectFactory.createWeeklyFeeGroupUnderCenter("Group", CustomerStatus.GROUP_ACTIVE, center);
client = TestObjectFactory.createClient("Client", CustomerStatus.CLIENT_ACTIVE, group);
LoanOfferingBO loanOffering = TestObjectFactory.createLoanOffering("Loandsdasd", "fsad", startDate, meeting, TestUtils.RUPEE);
account1 = TestObjectFactory.createLoanAccount("42423142341", group, AccountState.LOAN_ACTIVE_IN_GOOD_STANDING,
startDate, loanOffering);
loanOffering = TestObjectFactory.createLoanOffering("Loandfas", "dsvd", ApplicableTo.CLIENTS, startDate,
PrdStatus.LOAN_ACTIVE, 300.0, 1.2, 3, InterestType.FLAT, meeting);
account2 = TestObjectFactory.createLoanAccount("42427777341", client,
AccountState.LOAN_ACTIVE_IN_GOOD_STANDING, startDate, loanOffering);
StaticHibernateUtil.flushAndClearSession();
}
private void createPayment(LoanBO loan, Money amountPaid) throws Exception {
Set<AccountActionDateEntity> actionDateEntities = loan.getAccountActionDates();
LoanScheduleEntity[] paymentsArray = LoanBOTestUtils
.getSortedAccountActionDateEntity(actionDateEntities, 6);
PersonnelBO personnelBO = legacyPersonnelDao.getPersonnel(TestObjectFactory.getContext().getId());
LoanScheduleEntity loanSchedule = paymentsArray[0];
Short paymentTypeId = PaymentTypes.CASH.getValue();
PaymentData paymentData = PaymentData.createPaymentData(amountPaid, personnelBO, paymentTypeId, loanSchedule.getActionDate());
IntegrationTestObjectMother.applyAccountPayment(loan, paymentData);
paymentData = PaymentData.createPaymentData(amountPaid, personnelBO, paymentTypeId, loanSchedule.getActionDate());
IntegrationTestObjectMother.applyAccountPayment(loan, paymentData);
}
private void changeFirstInstallmentDate(AccountBO accountBO, 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()) {
LoanBOTestUtils.setActionDate(accountActionDateEntity, new java.sql.Date(currentDateCalendar
.getTimeInMillis()));
break;
}
}
@Test
public void testGeneratePortfolioAtRiskForTaskNoPayment() throws Exception {
createInitialObject();
StaticHibernateUtil.flushSession();
group = TestObjectFactory.getGroup(group.getCustomerId());
client = TestObjectFactory.getClient(client.getCustomerId());
for (AccountBO account : group.getAccounts()) {
if (account.getType() == AccountTypes.LOAN_ACCOUNT) {
changeFirstInstallmentDate(account, 31);
((LoanBO) account).handleArrears();
}
}
for (AccountBO account : client.getAccounts()) {
if (account.getType() == AccountTypes.LOAN_ACCOUNT) {
changeFirstInstallmentDate(account, 31);
((LoanBO) account).handleArrears();
}
}
StaticHibernateUtil.flushSession();
group = TestObjectFactory.getGroup(group.getCustomerId());
double portfolioAtRisk = PortfolioAtRiskCalculation.generatePortfolioAtRiskForTask(group.getCustomerId(), group
.getOffice().getOfficeId(), group.getSearchId() + ".%");
Assert.assertEquals(1.0, portfolioAtRisk, DELTA);
center = TestObjectFactory.getCenter(center.getCustomerId());
group = TestObjectFactory.getGroup(group.getCustomerId());
client = TestObjectFactory.getClient(client.getCustomerId());
account1 = TestObjectFactory.getObject(AccountBO.class, account1.getAccountId());
account2 = TestObjectFactory.getObject(AccountBO.class, account2.getAccountId());
}
@Test
public void testGeneratePortfolioAtRiskForTaskSomePayments() throws Exception {
createInitialObject();
StaticHibernateUtil.flushSession();
group = TestObjectFactory.getGroup(group.getCustomerId());
client = TestObjectFactory.getClient(client.getCustomerId());
createPayment((LoanBO)account1, new Money(account1.getCurrency(), "200"));
changeFirstInstallmentDate(account2, 31);
IntegrationTestObjectMother.saveLoanAccount((LoanBO)account2);
createPayment((LoanBO)account2, new Money(account2.getCurrency(), "200"));
IntegrationTestObjectMother.saveLoanAccount((LoanBO)account2);
((LoanBO)account2).handleArrears();
IntegrationTestObjectMother.saveLoanAccount((LoanBO)account2);
group = TestObjectFactory.getGroup(group.getCustomerId());
double portfolioAtRisk = PortfolioAtRiskCalculation.generatePortfolioAtRiskForTask(group.getCustomerId(), group
.getOffice().getOfficeId(), group.getSearchId() + ".%");
// Assert.assertEquals(0.5, portfolioAtRisk, DELTA);
}
}