/* * 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.test.acceptance.loan; import java.io.UnsupportedEncodingException; import java.sql.SQLException; import org.joda.time.DateTime; import org.mifos.test.acceptance.framework.MifosPage; import org.mifos.test.acceptance.framework.UiTestCaseBase; import org.mifos.test.acceptance.framework.loan.ChargeParameters; import org.mifos.test.acceptance.framework.loan.DisburseLoanParameters; import org.mifos.test.acceptance.framework.loan.LoanAccountPage; import org.mifos.test.acceptance.framework.loanproduct.DefineNewLoanProductPage; import org.mifos.test.acceptance.framework.testhelpers.CustomPropertiesHelper; import org.mifos.test.acceptance.framework.testhelpers.LoanTestHelper; import org.mifos.test.acceptance.framework.testhelpers.NavigationHelper; import org.mifos.test.acceptance.loanproduct.LoanProductTestHelper; import org.mifos.test.acceptance.util.ApplicationDatabaseOperation; import org.mifos.test.acceptance.util.TestDataSetup; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @ContextConfiguration(locations = {"classpath:ui-test-context.xml"}) @Test(singleThreaded = true, groups = {"loanproduct", "acceptance", "ui", "no_db_unit"}) public class DecliningPrincipleLoanTest extends UiTestCaseBase { @Autowired private ApplicationDatabaseOperation applicationDatabaseOperation; private final static String clientName = "Client WeeklyTue"; LoanProductTestHelper loanProductTestHelper; LoanTestHelper loanTestHelper; CustomPropertiesHelper propertiesHelper; DateTime systemDateTime; NavigationHelper navigationHelper; String interestTypeName = "Declining Balance-Interest Recalculation"; int interestType = DefineNewLoanProductPage.SubmitFormParameters.DECLINING_BALANCE_INTEREST_RECALCULATION; boolean isLoanProductCreatedAndVerified = false; String feeName = "loanWeeklyFee"; private final static String LOAN_CLOSED = "Closed- Obligation met"; private final static String LOAN_ACTIVE_GOOD = "Active in Good Standing"; private final static String LOAN_ACTIVE_BAD = "Active in Bad Standing"; static final int WEEKLY_RECURRENCE_TYPE_ID = 1; @SuppressWarnings("PMD.SignatureDeclareThrowsException") // one of the dependent methods throws Exception @AfterMethod public void logOut() throws SQLException { (new MifosPage(selenium)).logout(); applicationDatabaseOperation.updateLSIM(0); applicationDatabaseOperation.updateGapBetweenDisbursementAndFirstMeetingDate(1); propertiesHelper.setOverdueInterestPaidFirst("false"); } @Override @SuppressWarnings("PMD.SignatureDeclareThrowsException") // one of the dependent methods throws Exception @BeforeMethod public void setUp() throws Exception { super.setUp(); navigationHelper = new NavigationHelper(selenium); loanTestHelper = new LoanTestHelper(selenium); propertiesHelper = new CustomPropertiesHelper(selenium); loanProductTestHelper = new LoanProductTestHelper(selenium); systemDateTime = new DateTime(2010, 10, 11, 10, 0, 0, 0); TestDataSetup dataSetup = new TestDataSetup(selenium, applicationDatabaseOperation); loanTestHelper.setApplicationTime(systemDateTime); dataSetup.addDecliningPrincipalBalance(); } @SuppressWarnings("PMD.SignatureDeclareThrowsException") // one of the dependent methods throws Exception @Test(enabled=true) public void verifyDecliningPrincipleLoan() throws Exception { applicationDatabaseOperation.updateLSIM(1); DefineNewLoanProductPage.SubmitFormParameters formParameters = loanProductTestHelper.defineLoanProductParameters(3, 1000, 20, interestType, WEEKLY_RECURRENCE_TYPE_ID); loanProductTestHelper. navigateToDefineNewLoanPageAndFillMandatoryFields(formParameters). submitAndGotoNewLoanProductPreviewPage(). verifyInterestTypeInPreview(interestTypeName). submit().navigateToViewLoanDetails(). verifyInterestTypeInSummary(interestTypeName); verifyDecliningPrincipalLoanAccount(3, interestTypeName, systemDateTime.plusDays(1), formParameters.getOfferingName()); } @Test(enabled=true, groups={"loan"}) @SuppressWarnings("PMD.SignatureDeclareThrowsException") // one of the dependent methods throws Exception public void verifyLoanPaymentAndAdjustment() throws Exception { applicationDatabaseOperation.updateLSIM(1); applicationDatabaseOperation.updateGapBetweenDisbursementAndFirstMeetingDate(2); verifyEarlyExcessPayment("000100000000025"); verifyEarlyLessPayment("000100000000026"); verifyLateExcessPayment("000100000000027"); verifyLateLessPayment("000100000000028"); verifyMultipleDue("000100000000029"); verifyOverdue(); } // @Test(enabled = true) // @SuppressWarnings("PMD.SignatureDeclareThrowsException") // one of the dependent methods throws Exception // public void verifyLoanPaymentAndAdjustmentWithWaiveInterest() throws Exception { // new FeeTestHelper(dataSetup).createPeriodicFee(feeName, FeesCreatePage.SubmitFormParameters.LOAN, FeesCreatePage.SubmitFormParameters.WEEKLY_FEE_RECURRENCE, 1, 100); // int noOfInstallments = 4; // DefineNewLoanProductPage.SubmitFormParameters formParameters = loanProductTestHelper.defineLoanProductParameters(noOfInstallments, 1000, 24, interestType); // createLoanProduct(formParameters); // verifyMultipleDue(5, formParameters.getOfferingName()); // } private void verifyMultipleDue(String accountId) throws UnsupportedEncodingException { navigationHelper.navigateToLoanAccountPage(accountId); verifyPayment(accountId); verifyAdjustment(); } private void verifyPayment(String accountId) throws UnsupportedEncodingException { verifyRepaymentAndAdjustment(systemDateTime.plusDays(0), systemDateTime.plusDays(5), "1,100", RepaymentScheduleData.ACCOUNT_SUMMARY_REPAYMENT_ONE, RepaymentScheduleData.ACCOUNT_SUMMARY_ADJUSTMENT_ONE, LOAN_ACTIVE_GOOD); makePaymentAndVerifyPayment(accountId, systemDateTime.plusDays(24), "403", RepaymentScheduleData.MULTIPLE_DUE_FIRST_PAYMENT);//verify first the due fee is knocked verifyRepaymentAndAdjustment(systemDateTime.plusDays(24), systemDateTime.plusDays(25), "1,012.8", RepaymentScheduleData.ACCOUNT_SUMMARY_REPAYMENT_TWO, RepaymentScheduleData.ACCOUNT_SUMMARY_ADJUSTMENT_TWO, LOAN_ACTIVE_BAD); makePaymentAndVerifyPayment(accountId, systemDateTime.plusDays(26), "305.1", RepaymentScheduleData.MULTIPLE_DUE_SECOND_PAYMENT);//verify first the due fee is knocked makePaymentAndVerifyPayment(accountId, systemDateTime.plusDays(29), "104.4", RepaymentScheduleData.MULTIPLE_DUE_THIRD_PAYMENT);//verify first the due fee is knocked makePaymentAndVerifyPayment(accountId, systemDateTime.plusDays(29), "200", RepaymentScheduleData.MULTIPLE_DUE_FORTH_PAYMENT);//verify first the due fee is knocked makePaymentAndVerifyPayment(accountId, systemDateTime.plusDays(29), "102.8", RepaymentScheduleData.MULTIPLE_DUE_FIFTH_PAYMENT);//same date, less payment makePaymentAndVerifyPayment(accountId, systemDateTime.plusDays(35), "112.3", RepaymentScheduleData.MULTIPLE_DUE_SIXTH_PAYMENT);//verify first the due fee is knocked makePaymentAndVerifyPayment(accountId, systemDateTime.plusDays(38), "291.9", RepaymentScheduleData.MULTIPLE_DUE_SEVENTH_PAYMENT);//verify first the due fee is knocked verifyRepaymentAndAdjustment(systemDateTime.plusDays(38), systemDateTime.plusDays(38), "0.2", null, null, LOAN_ACTIVE_BAD); } private void verifyAdjustment() throws UnsupportedEncodingException { verifyAdjustmentFromLoanAccountPage("291.9", RepaymentScheduleData.MULTIPLE_DUE_FIRST_ADJUSTMENT); verifyAdjustmentFromRepaymentSchedule("112.3", RepaymentScheduleData.MULTIPLE_DUE_SECOND_ADJUSTMENT); verifyAdjustmentFromInstallmentsDetails("102.8", RepaymentScheduleData.MULTIPLE_DUE_THIRD_ADJUSTMENT); verifyAdjustmentFromLoanAccountPage("200", RepaymentScheduleData.MULTIPLE_DUE_FORTH_ADJUSTMENT); verifyAdjustmentFromRepaymentSchedule("104.4", RepaymentScheduleData.MULTIPLE_DUE_FIFTH_ADJUSTMENT); verifyAdjustmentFromInstallmentsDetails("305.1", RepaymentScheduleData.MULTIPLE_DUE_SIXTH_ADJUSTMENT); verifyAdjustmentFromRepaymentSchedule("403", RepaymentScheduleData.MULTIPLE_DUE_SEVENTH_ADJUSTMENT); } private void verifyRepaymentAndAdjustment(DateTime repaymentDate, DateTime adjustmentDate, String loanAmount, String[][] repaymentAccountSummery, String[][] adjustedAccountSummery, String loanStatus) throws UnsupportedEncodingException { loanTestHelper.repayLoan(repaymentDate). verifyLoanStatus(LOAN_CLOSED).verifyAccountSummary(repaymentAccountSummery); loanTestHelper.setApplicationTime(adjustmentDate).navigateBack(); new LoanAccountPage(selenium).navigateToApplyAdjustment(). verifyRepayAdjustment(loanAmount).verifyLoanStatus(loanStatus).verifyAccountSummary(adjustedAccountSummery); } private void verifyAdjustmentFromInstallmentsDetails(String adjustedAmount, String[][] adjustedSchedule) { new LoanAccountPage(selenium). navigateToViewNextInstallmentDetails(). navigateToApplyAdjustment(). verifyAdjustment(adjustedAmount). navigateToRepaymentSchedulePage(). verifyScheduleTable(adjustedSchedule).navigateToLoanAccountPage(); } private void verifyAdjustmentFromRepaymentSchedule(String adjustedAmount, String[][] adjustedSchedule) { new LoanAccountPage(selenium). navigateToRepaymentSchedulePage(). navigateToApplyAdjustment(). verifyAdjustment(adjustedAmount). navigateToRepaymentSchedulePage(). verifyScheduleTable(adjustedSchedule).navigateToLoanAccountPage(); } private void verifyAdjustmentFromLoanAccountPage(String adjustedAmount, String[][] adjustedSchedule) { new LoanAccountPage(selenium). navigateToApplyAdjustment(). verifyAdjustment(adjustedAmount). navigateToRepaymentSchedulePage(). verifyScheduleTable(adjustedSchedule).navigateToLoanAccountPage(); } private void verifyLateLessPayment(String accountId) throws UnsupportedEncodingException { DateTime paymentDate = systemDateTime.plusDays(12); navigationHelper.navigateToLoanAccountPage(accountId); makePaymentAndVerifyPayment(accountId, paymentDate, "100", RepaymentScheduleData.LATE_LESS_FIRST_PAYMENT);//verify first the due fee is knocked makePaymentAndVerifyPayment(accountId, paymentDate, "5.3", RepaymentScheduleData.LATE_LESS_SECOND_PAYMENT);//verify due interest is knocked next makePaymentAndVerifyPayment(accountId, paymentDate, "100", RepaymentScheduleData.LATE_LESS_THIRD_PAYMENT);//verify the due principle is knocked next new LoanAccountPage(selenium).navigateToApplyPayment().verifyPaymentPriorLastPaymentDate(loanTestHelper.setPaymentParams("10", paymentDate)); } private void verifyLateExcessPayment(String accountId) throws UnsupportedEncodingException { DateTime paymentDate = systemDateTime.plusDays(12); navigationHelper.navigateToLoanAccountPage(accountId); makePaymentAndVerifyPayment(accountId, paymentDate, "354", RepaymentScheduleData.LATE_EXCESS_PAYMENT); makePaymentAndVerifyPayment(accountId, paymentDate, "2.5", RepaymentScheduleData.LATE_EXCESS_SECOND_PAYMENT);//verifying only overdue interest in knocked makePaymentAndVerifyPayment(accountId, paymentDate, "100", RepaymentScheduleData.LATE_EXCESS_THIRD_PAYMENT);//verify if future interest in reduced as the future principle is paid } private void verifyEarlyLessPayment(String accountId) throws UnsupportedEncodingException { DateTime paymentDate = systemDateTime.plusDays(1); navigationHelper.navigateToLoanAccountPage(accountId); makePaymentAndVerifyPayment(accountId, paymentDate, "100", RepaymentScheduleData.EARLY_LESS_FIRST_PAYMENT); //verifying interest till date } @SuppressWarnings("PMD.SignatureDeclareThrowsException") // one of the dependent methods throws Exception public void createLoan() throws Exception { DateTime testDateTime = new DateTime(2011, 02, 22, 10, 0, 0, 0); loanTestHelper.setApplicationTime(testDateTime); createAndDisburseLoanAccount(4, testDateTime, "WeeklyClientFlatLoanWithNoFee"); } private void verifyEarlyExcessPayment(String accountID) throws UnsupportedEncodingException { DateTime paymentDate = systemDateTime.plusDays(1); navigationHelper.navigateToLoanAccountPage(accountID); makePaymentAndVerifyPayment(accountID, paymentDate, "280", RepaymentScheduleData.EARLY_EXCESS_FIRST_PAYMENT); } private void verifyOverdue() throws UnsupportedEncodingException { propertiesHelper.setOverdueInterestPaidFirst("true"); DateTime testDateTime = new DateTime(2010, 10, 12, 0, 0, 0, 0); loanTestHelper.setApplicationTime(testDateTime); DisburseLoanParameters disburseParams = new DisburseLoanParameters(); disburseParams.setDisbursalDateDD("12"); disburseParams.setDisbursalDateMM("10"); disburseParams.setDisbursalDateYYYY("2010"); disburseParams.setPaymentType(DisburseLoanParameters.CASH); LoanAccountPage loanAccountPage = loanTestHelper.createLoanAccount(clientName, "WeeklyPawdepLoan") .changeAccountStatusToAccepted().disburseLoan(disburseParams); String accountId = loanAccountPage.getAccountId(); loanTestHelper.setApplicationTime(testDateTime.plusWeeks(5)); verifyOverdueSummary(accountId); verifyOverduePayment(accountId, testDateTime); } private void verifyOverdueSummary(String accountId) throws UnsupportedEncodingException { LoanAccountPage loanAccountPage = navigationHelper.navigateToLoanAccountPage(accountId); loanAccountPage.verifyAccountSummary(RepaymentScheduleData.ACCOUNT_SUMMARY_OVERDUE); } private void verifyOverduePayment(String accountId, DateTime disbursementDate) throws UnsupportedEncodingException { navigationHelper.navigateToLoanAccountPage(accountId); loanTestHelper.makePayment(disbursementDate.plusWeeks(5), "1023.5").verifyAccountSummary( RepaymentScheduleData.ACCOUNT_SUMMARY_OVERDUE_REPAYMENT); } private String makePaymentAndVerifyPayment(String accountId, DateTime paymentDate, String paymentAmount, String[][] expectedSchedule) throws UnsupportedEncodingException { loanTestHelper.makePayment(paymentDate, paymentAmount). navigateToRepaymentSchedulePage(). verifyScheduleTable(expectedSchedule).navigateToLoanAccountPage(); return accountId; } private LoanAccountPage createAndDisburseLoanAccount(int noOfInstallments, DateTime disbursalDate, String loanProductName) throws UnsupportedEncodingException { DisburseLoanParameters disburseLoanParameters = loanTestHelper.setDisbursalParams(disbursalDate); navigationHelper.navigateToHomePage(); return loanTestHelper. navigateToCreateLoanAccountEntryPageWithoutLogout(clientName, loanProductName). setDisbursalDate(disbursalDate). setInstallments(noOfInstallments). clickContinue(). clickPreviewAndGoToReviewLoanAccountPage(). submit().navigateToLoanAccountDetailsPage(). navigateToEditAccountStatus(). submitAndNavigateToNextPage(loanTestHelper.setApprovedStatusParameters()). submitAndNavigateToLoanAccountPage(). navigateToDisburseLoan(). submitAndNavigateToDisburseLoanConfirmationPage(disburseLoanParameters) .submitAndNavigateToLoanAccountPage().navigateToApplyCharge().applyFeeAndConfirm(setCharge()); } private ChargeParameters setCharge() { ChargeParameters chargeParameters = new ChargeParameters(); chargeParameters.setType(feeName); return chargeParameters; } private void verifyDecliningPrincipalLoanAccount(int noOfInstallments, String interestTypeName, DateTime disbursalDate, String loanProductName) { navigationHelper.navigateToHomePage(); loanTestHelper. navigateToCreateLoanAccountEntryPageWithoutLogout(clientName, loanProductName). setDisbursalDate(disbursalDate). setInstallments(noOfInstallments). verifyInterestTypeInLoanCreation(interestTypeName). clickContinue(). clickPreviewAndGoToReviewLoanAccountPage(). verifyInterestTypeInLoanPreview(interestTypeName). submit().navigateToLoanAccountDetailsPage(). verifyInterestTypeInLoanAccountDetails(interestTypeName). navigateToRepaymentSchedulePage(). verifyScheduleDateField(); } }