diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java index f1d2405f6..9fc0dfc58 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/AccountingScenarioIntegrationTest.java @@ -3,11 +3,13 @@ package org.mifosplatform.integrationtests; import static org.junit.Assert.assertEquals; import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; +import org.joda.time.LocalDate; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -564,7 +566,9 @@ public class AccountingScenarioIntegrationTest { System.out.println("Repayment 1 ......"); final float FIRST_INTEREST = 200.0f; final float FIRST_PRINCIPAL = 2000.0f; - this.loanTransactionHelper.checkAccrualTransactionForRepayment(this.REPAYMENT_DATE[1], FIRST_INTEREST, loanID); + final float FEE_PORTION = 0.0f; + final float PENALTY_PORTION = 0.0f; + this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[1]), FIRST_INTEREST, FEE_PORTION, PENALTY_PORTION, loanID); this.loanTransactionHelper.makeRepayment(this.REPAYMENT_DATE[1], this.REPAYMENT_AMOUNT[1], loanID); float expected_value = this.LP_PRINCIPAL - PRINCIPAL_VALUE_FOR_EACH_PERIOD; this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(1, expected_value, loanID); @@ -580,8 +584,8 @@ public class AccountingScenarioIntegrationTest { final float SECOND_AND_THIRD_INTEREST = 400.0f; final float SECOND_PRINCIPAL = this.REPAYMENT_AMOUNT[2] - SECOND_AND_THIRD_INTEREST; expected_value = expected_value - PRINCIPAL_VALUE_FOR_EACH_PERIOD; - this.loanTransactionHelper.checkAccrualTransactionForRepayment(this.REPAYMENT_DATE[2], FIRST_INTEREST, loanID); - this.loanTransactionHelper.checkAccrualTransactionForRepayment(this.REPAYMENT_DATE[3], FIRST_INTEREST, loanID); + this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[2]), FIRST_INTEREST, FEE_PORTION, PENALTY_PORTION, loanID); + this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[3]), FIRST_INTEREST, FEE_PORTION, PENALTY_PORTION, loanID); this.loanTransactionHelper.verifyRepaymentScheduleEntryFor(2, expected_value, loanID); final JournalEntry[] assetAccountSecondEntry = { new JournalEntry(this.REPAYMENT_AMOUNT[2], JournalEntry.TransactionType.DEBIT), new JournalEntry(SECOND_AND_THIRD_INTEREST, JournalEntry.TransactionType.CREDIT), @@ -591,8 +595,8 @@ public class AccountingScenarioIntegrationTest { // WAIVE INTEREST System.out.println("Waive Interest ......"); - this.loanTransactionHelper.checkAccrualTransactionForRepayment(this.REPAYMENT_DATE[4], FIRST_INTEREST, loanID); - this.loanTransactionHelper.checkAccrualTransactionForRepayment(this.REPAYMENT_DATE[5], FIRST_INTEREST, loanID); + this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[4]), FIRST_INTEREST, FEE_PORTION, PENALTY_PORTION, loanID); + this.loanTransactionHelper.checkAccrualTransactionForRepayment(getDateAsLocalDate(this.REPAYMENT_DATE[5]), FIRST_INTEREST, FEE_PORTION, PENALTY_PORTION, loanID); this.loanTransactionHelper.waiveInterest(this.REPAYMENT_DATE[4], this.AMOUNT_TO_BE_WAIVE.toString(), loanID); final JournalEntry waivedEntry = new JournalEntry(this.AMOUNT_TO_BE_WAIVE, JournalEntry.TransactionType.CREDIT); @@ -752,4 +756,15 @@ public class AccountingScenarioIntegrationTest { .build(null); return this.loanTransactionHelper.getLoanProductId(loanProductJSON); } + + private LocalDate getDateAsLocalDate(String dateAsString) { + LocalDate date = null; + try { + DateFormat df = new SimpleDateFormat("dd MMMM yyyy"); + date = new LocalDate(df.parse(dateAsString)); + } catch (ParseException e) { + e.printStackTrace(); + } + return date; + } } diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientLoanIntegrationTest.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientLoanIntegrationTest.java index 48e6e1055..e01675997 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientLoanIntegrationTest.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/ClientLoanIntegrationTest.java @@ -2,17 +2,24 @@ package org.mifosplatform.integrationtests; import static org.junit.Assert.assertEquals; +import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import org.joda.time.LocalDate; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mifosplatform.integrationtests.common.ClientHelper; +import org.mifosplatform.integrationtests.common.SchedulerJobHelper; import org.mifosplatform.integrationtests.common.Utils; +import org.mifosplatform.integrationtests.common.accounting.Account; +import org.mifosplatform.integrationtests.common.accounting.AccountHelper; +import org.mifosplatform.integrationtests.common.accounting.JournalEntry; +import org.mifosplatform.integrationtests.common.accounting.JournalEntryHelper; import org.mifosplatform.integrationtests.common.charges.ChargesHelper; import org.mifosplatform.integrationtests.common.loans.LoanApplicationTestBuilder; import org.mifosplatform.integrationtests.common.loans.LoanProductTestBuilder; @@ -29,8 +36,9 @@ import com.jayway.restassured.specification.RequestSpecification; import com.jayway.restassured.specification.ResponseSpecification; /** - * Client Loan Integration Test for checking Loan Application Repayment - * Schedule. + * Client Loan Integration Test for checking Loan Application Repayments + * Schedule, loan charges, penalties, loan repayments and verifying accounting + * transactions */ @SuppressWarnings({ "rawtypes", "unchecked" }) public class ClientLoanIntegrationTest { @@ -38,9 +46,17 @@ public class ClientLoanIntegrationTest { public static final String MINIMUM_OPENING_BALANCE = "1000.0"; public static final String ACCOUNT_TYPE_INDIVIDUAL = "INDIVIDUAL"; + private static final String NONE = "1"; + private static final String CASH_BASED = "2"; + private static final String ACCRUAL_PERIODIC = "3"; + private static final String ACCRUAL_UPFRONT = "4"; + private ResponseSpecification responseSpec; private RequestSpecification requestSpec; private LoanTransactionHelper loanTransactionHelper; + private JournalEntryHelper journalEntryHelper; + private AccountHelper accountHelper; + private SchedulerJobHelper schedulerJobHelper; @Before public void setup() { @@ -48,6 +64,8 @@ public class ClientLoanIntegrationTest { this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); + this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); + this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec); } @Test @@ -56,7 +74,7 @@ public class ClientLoanIntegrationTest { final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); - final Integer loanProductID = createLoanProduct(false); + final Integer loanProductID = createLoanProduct(false, NONE); final Integer loanID = applyForLoanApplication(clientID, loanProductID, null, null, "12,000.00"); final ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -70,7 +88,7 @@ public class ClientLoanIntegrationTest { final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); - final Integer loanProductID = createLoanProduct(false); + final Integer loanProductID = createLoanProduct(false, NONE); List charges = new ArrayList(); Integer flatDisbursement = ChargesHelper.createCharges(requestSpec, responseSpec, ChargesHelper.getLoanDisbursementJSON()); @@ -177,7 +195,7 @@ public class ClientLoanIntegrationTest { final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); - final Integer loanProductID = createLoanProduct(false); + final Integer loanProductID = createLoanProduct(false, NONE); List charges = new ArrayList(); Integer flat = ChargesHelper.createCharges(requestSpec, responseSpec, @@ -336,7 +354,7 @@ public class ClientLoanIntegrationTest { this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); - final Integer loanProductID = createLoanProduct(false); + final Integer loanProductID = createLoanProduct(false, NONE); List charges = new ArrayList(); Integer flat = ChargesHelper.createCharges(requestSpec, responseSpec, @@ -601,7 +619,7 @@ public class ClientLoanIntegrationTest { final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); - final Integer loanProductID = createLoanProduct(false); + final Integer loanProductID = createLoanProduct(false, NONE); final Integer savingsId = createSavings(clientID); @@ -644,7 +662,7 @@ public class ClientLoanIntegrationTest { this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); - final Integer loanProductID = createLoanProduct(true); + final Integer loanProductID = createLoanProduct(true, NONE); List tranches = new ArrayList(); tranches.add(createTrancheDetail("1 March 2014", "25000")); @@ -684,7 +702,7 @@ public class ClientLoanIntegrationTest { final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); - final Integer loanProductID = createLoanProduct(true); + final Integer loanProductID = createLoanProduct(true, NONE); final Integer savingsId = createSavings(clientID); @@ -768,7 +786,7 @@ public class ClientLoanIntegrationTest { Assert.assertTrue(new Float(twoDForm.format(new Float(val))).compareTo(new Float(twoDForm.format(new Float(val2)))) == 0); } - private Integer createLoanProduct(boolean multiDisburseLoan) { + private Integer createLoanProduct(final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) { System.out.println("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------"); final String loanProductJSON = new LoanProductTestBuilder() // .withPrincipal("12,000.00") // @@ -780,7 +798,7 @@ public class ClientLoanIntegrationTest { .withAmortizationTypeAsEqualInstallments() // .withInterestTypeAsDecliningBalance() // .withTranches(multiDisburseLoan) // - .build(null); + .withAccounting(accountingRule, accounts).build(null); return this.loanTransactionHelper.getLoanProductId(loanProductJSON); } @@ -958,4 +976,1780 @@ public class ClientLoanIntegrationTest { return detail; } + /*** + * Test case for checking CashBasedAccounting functionality adding charges + * with calculation type flat + */ + @Test + public void loanWithFlatCahargesAndCashBasedAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer flatDisbursement = ChargesHelper.createCharges(requestSpec, responseSpec, ChargesHelper.getLoanDisbursementJSON()); + addCharges(charges, flatDisbursement, "100", null); + Integer flatSpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "100", false)); + addCharges(charges, flatSpecifiedDueDate, "100", "29 September 2011"); + Integer flatInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false)); + addCharges(charges, flatInstallmentFee, "50", null); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, CASH_BASED, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "100.00", "0.0", "0.0"); + validateCharge(flatSpecifiedDueDate, loanCharges, "100", "100.00", "0.0", "0.0"); + validateCharge(flatInstallmentFee, loanCharges, "50", "200.00", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("100.00", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("150.00", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("50.00", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.CREDIT)); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "0.00", "100.0", "0.0"); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3301.49"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "0.00", "100.0", "0.0"); + validateCharge(flatSpecifiedDueDate, loanCharges, "100", "0.00", "100.0", "0.0"); + validateCharge(flatInstallmentFee, loanCharges, "50", "150.00", "50.0", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3301.49"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2911.49"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 October 2011", + new JournalEntry(Float.valueOf("150.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240.00"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatSpecifiedDueDate), "29 October 2011", "100")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("150.00", String.valueOf(secondInstallment.get("feeChargesDue"))); + this.loanTransactionHelper.waiveChargesForLoan(loanID, (Integer) getloanCharge(flatInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatInstallmentFee, loanCharges, "50", "100.00", "50.0", "50.0"); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3251.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3251.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 November 2011", + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("181.77"), + JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + Integer flatPenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "100", true)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatPenaltySpecifiedDueDate), "29 September 2011", "100")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatPenaltySpecifiedDueDate, loanCharges, "100", "0.00", "100.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("100", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3301.49"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2811.49"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 October 2011", + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("150.00"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3301.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3301.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("3129.1"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 November 2011", + new JournalEntry(Float.valueOf("50.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("122.38"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatPenaltySpecifiedDueDate), "10 January 2012", "100")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("100", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3239.70", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("100"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("100"), + JournalEntry.TransactionType.DEBIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 January 2012", + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3139.70", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3139.70"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3139.70"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("3089.70"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 January 2012", new JournalEntry( + Float.valueOf("50.00"), JournalEntry.TransactionType.CREDIT)); + } + + /*** + * Test case for checking CashBasedAccounting functionality adding charges + * with calculation type percentage of amount + */ + @Test + public void loanWithCahargesOfTypeAmountPercentageAndCashBasedAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer percentageDisbursementCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1")); + addCharges(charges, percentageDisbursementCharge, "1", null); + + Integer percentageSpecifiedDueDateCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", false)); + addCharges(charges, percentageSpecifiedDueDateCharge, "1", "29 September 2011"); + + Integer percentageInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", false)); + addCharges(charges, percentageInstallmentFee, "1", "29 September 2011"); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, CASH_BASED, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "120.00", "0.0", "0.0"); + validateCharge(percentageSpecifiedDueDateCharge, loanCharges, "1", "120.00", "0.0", "0.0"); + validateCharge(percentageInstallmentFee, loanCharges, "1", "120.00", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("120.00", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("149.11", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("29.70", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT)); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "0.0", "120.00", "0.0"); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3300.60"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "0.00", "120.00", "0.0"); + validateCharge(percentageSpecifiedDueDateCharge, loanCharges, "1", "0.00", "120.0", "0.0"); + validateCharge(percentageInstallmentFee, loanCharges, "1", "90.89", "29.11", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3300.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2911.49"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 October 2011", + new JournalEntry(Float.valueOf("149.11"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240.00"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentageSpecifiedDueDateCharge), "29 October 2011", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("149.70", String.valueOf(secondInstallment.get("feeChargesDue"))); + this.loanTransactionHelper.waiveChargesForLoan(loanID, (Integer) getloanCharge(percentageInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageInstallmentFee, loanCharges, "1", "61.19", "29.11", "29.70"); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3271.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3271.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 November 2011", + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("181.77"), + JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + Integer percentagePenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", true)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentagePenaltySpecifiedDueDate), "29 September 2011", "1")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentagePenaltySpecifiedDueDate, loanCharges, "1", "0.00", "120.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("120", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3300.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2791.49"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 October 2011", + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("149.11"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3301.77"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3301.77"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("3149.10"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 November 2011", + new JournalEntry(Float.valueOf("30.29"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("122.38"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentagePenaltySpecifiedDueDate), "10 January 2012", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("120", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3240.60", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("120"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.DEBIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 January 2012", + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3120.60", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3120.60"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3120.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("3089.70"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 January 2012", new JournalEntry( + Float.valueOf("30.90"), JournalEntry.TransactionType.CREDIT)); + } + + /*** + * Test case for checking CashBasedAccounting functionality adding charges + * with calculation type percentage of amount plus interest + */ + @Test + public void loanWithCahargesOfTypeAmountPlusInterestPercentageAndCashBasedAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer amountPlusInterestPercentageDisbursementCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1")); + addCharges(charges, amountPlusInterestPercentageDisbursementCharge, "1", null); + + Integer amountPlusInterestPercentageSpecifiedDueDateCharge = ChargesHelper + .createCharges(requestSpec, responseSpec, ChargesHelper.getLoanSpecifiedDueDateJSON( + ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1", false)); + addCharges(charges, amountPlusInterestPercentageSpecifiedDueDateCharge, "1", "29 September 2011"); + + Integer amountPlusInterestPercentageInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1", false)); + addCharges(charges, amountPlusInterestPercentageInstallmentFee, "1", "29 September 2011"); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, CASH_BASED, assetAccount, incomeAccount, expenseAccount, overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "126.06", "0.0", "0.0"); + validateCharge(amountPlusInterestPercentageSpecifiedDueDateCharge, loanCharges, "1", "126.06", "0.0", "0.0"); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "126.04", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("126.06", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("157.57", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("31.51", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.CREDIT)); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "0.0", "126.06", "0.0"); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3309.06"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "0.00", "126.06", "0.0"); + validateCharge(amountPlusInterestPercentageSpecifiedDueDateCharge, loanCharges, "1", "0.00", "126.06", "0.0"); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "94.53", "31.51", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3309.06"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2911.49"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 October 2011", + new JournalEntry(Float.valueOf("157.57"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240.00"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentageSpecifiedDueDateCharge), "29 October 2011", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("157.57", String.valueOf(secondInstallment.get("feeChargesDue"))); + this.loanTransactionHelper.waiveChargesForLoan(loanID, + (Integer) getloanCharge(amountPlusInterestPercentageInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "63.02", "31.51", "31.51"); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3277.54"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3277.54"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 November 2011", + new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("181.77"), + JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + Integer amountPlusInterestPercentagePenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", true)); + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentagePenaltySpecifiedDueDate), "29 September 2011", "1")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentagePenaltySpecifiedDueDate, loanCharges, "1", "0.0", "120.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("120", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3309.06"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("2791.49"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 October 2011", + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("157.57"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3302.99"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3302.99"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("3149.10"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 November 2011", + new JournalEntry(Float.valueOf("31.51"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("122.38"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentagePenaltySpecifiedDueDate), "10 January 2012", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("120", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3241.21", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("120"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.DEBIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 January 2012", + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3121.21", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3121.21"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3121.21"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("3089.70"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 January 2012", new JournalEntry( + Float.valueOf("31.51"), JournalEntry.TransactionType.CREDIT)); + } + + /*** + * Test case for checking AccuralUpfrontAccounting functionality adding + * charges with calculation type flat + */ + @Test + public void loanWithFlatCahargesAndUpfrontAccrualAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer flatDisbursement = ChargesHelper.createCharges(requestSpec, responseSpec, ChargesHelper.getLoanDisbursementJSON()); + addCharges(charges, flatDisbursement, "100", null); + Integer flatSpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "100", false)); + + Integer flatInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false)); + addCharges(charges, flatInstallmentFee, "50", null); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, ACCRUAL_UPFRONT, assetAccount, incomeAccount, expenseAccount, + overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "100.00", "0.0", "0.0"); + validateCharge(flatInstallmentFee, loanCharges, "50", "200.00", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("100.00", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("50.00", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("50.00", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("605.94"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("200.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("605.94"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("100.00"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("200.00"), JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatSpecifiedDueDate), "29 September 2011", "100")); + + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "0.00", "100.0", "0.0"); + validateCharge(flatSpecifiedDueDate, loanCharges, "100", "100.00", "0.0", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "29 September 2011", + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.DEBIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "29 September 2011", + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.CREDIT)); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3301.49"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "0.00", "100.0", "0.0"); + validateCharge(flatSpecifiedDueDate, loanCharges, "100", "0.00", "100.0", "0.0"); + validateCharge(flatInstallmentFee, loanCharges, "50", "150.00", "50.0", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3301.49"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("150.00"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("2911.49"), JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatSpecifiedDueDate), "29 October 2011", "100")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("150.00", String.valueOf(secondInstallment.get("feeChargesDue"))); + System.out.println("----------- Waive installment charge for 2nd installment ---------"); + this.loanTransactionHelper.waiveChargesForLoan(loanID, (Integer) getloanCharge(flatInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatInstallmentFee, loanCharges, "50", "100.00", "50.0", "50.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", new JournalEntry(Float.valueOf("50.0"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 September 2011", + new JournalEntry(Float.valueOf("50.0"), JournalEntry.TransactionType.DEBIT)); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3251.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3251.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("100"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("181.77"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 December 2011", new JournalEntry(Float.valueOf("61.79"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 December 2011", + new JournalEntry(Float.valueOf("61.79"), JournalEntry.TransactionType.DEBIT)); + + Integer flatPenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "100", true)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatPenaltySpecifiedDueDate), "29 September 2011", "100")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatPenaltySpecifiedDueDate, loanCharges, "100", "0.00", "100.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("100", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + // checking the journal entry as applied penalty has been collected + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3301.49"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("100"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("150"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2811.49"), + JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3301.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3301.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("50.00"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("122.38"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3129.10"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatPenaltySpecifiedDueDate), "10 January 2012", "100")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("100", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3239.70", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("100"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("100"), + JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("100"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3139.70", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make over payment for repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3220.60"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3139.70"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("50.00"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3089.70"), JournalEntry.TransactionType.CREDIT)); + loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "status"); + LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap); + } + + /*** + * Test case for checking AccuralUpfrontAccounting functionality adding + * charges with calculation type percentage of amount + */ + @Test + public void loanWithCahargesAndUpfrontAccrualAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer percentageDisbursementCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1")); + addCharges(charges, percentageDisbursementCharge, "1", null); + + Integer percentageSpecifiedDueDateCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", false)); + addCharges(charges, percentageSpecifiedDueDateCharge, "1", "29 September 2011"); + + Integer percentageInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", false)); + addCharges(charges, percentageInstallmentFee, "1", "29 September 2011"); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, ACCRUAL_UPFRONT, assetAccount, incomeAccount, expenseAccount, + overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "120.00", "0.0", "0.0"); + validateCharge(percentageSpecifiedDueDateCharge, loanCharges, "1", "120.00", "0.0", "0.0"); + validateCharge(percentageInstallmentFee, loanCharges, "1", "120.00", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("120.00", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("149.11", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("29.70", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("605.94"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("605.94"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("120.00"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("120.00"), + JournalEntry.TransactionType.CREDIT)); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "0.0", "120.00", "0.0"); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3300.60"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "0.00", "120.00", "0.0"); + validateCharge(percentageSpecifiedDueDateCharge, loanCharges, "1", "0.00", "120.0", "0.0"); + validateCharge(percentageInstallmentFee, loanCharges, "1", "90.89", "29.11", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3300.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("149.11"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("2911.49"), JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentageSpecifiedDueDateCharge), "29 October 2011", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("149.70", String.valueOf(secondInstallment.get("feeChargesDue"))); + System.out.println("----------- Waive installment charge for 2nd installment ---------"); + this.loanTransactionHelper.waiveChargesForLoan(loanID, (Integer) getloanCharge(percentageInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageInstallmentFee, loanCharges, "1", "61.19", "29.11", "29.70"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", new JournalEntry(Float.valueOf("29.7"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 September 2011", + new JournalEntry(Float.valueOf("29.7"), JournalEntry.TransactionType.DEBIT)); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3271.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3271.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("181.77"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 December 2011", new JournalEntry(Float.valueOf("61.79"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 December 2011", + new JournalEntry(Float.valueOf("61.79"), JournalEntry.TransactionType.DEBIT)); + + Integer percentagePenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", true)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentagePenaltySpecifiedDueDate), "29 September 2011", "1")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentagePenaltySpecifiedDueDate, loanCharges, "1", "0.00", "120.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("120", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + // checking the journal entry as applied penalty has been collected + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3300.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("149.11"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2791.49"), + JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3301.77"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3301.77"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("30.29"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("122.38"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3149.10"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentagePenaltySpecifiedDueDate), "10 January 2012", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("120", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3240.60", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("120"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3120.60", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make over payment for repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3220.60"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3120.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("30.90"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3089.70"), JournalEntry.TransactionType.CREDIT)); + loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "status"); + LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap); + } + + + /*** + * Test case for checking AccuralUpfrontAccounting functionality adding + * charges with calculation type percentage of amount plus interest + */ + @Test + public void loanWithCahargesOfTypeAmountPlusInterestPercentageAndUpfrontAccrualAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer amountPlusInterestPercentageDisbursementCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1")); + addCharges(charges, amountPlusInterestPercentageDisbursementCharge, "1", null); + + Integer amountPlusInterestPercentageSpecifiedDueDateCharge = ChargesHelper + .createCharges(requestSpec, responseSpec, ChargesHelper.getLoanSpecifiedDueDateJSON( + ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1", false)); + + Integer amountPlusInterestPercentageInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1", false)); + addCharges(charges, amountPlusInterestPercentageInstallmentFee, "1", "29 September 2011"); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, ACCRUAL_UPFRONT, assetAccount, incomeAccount, expenseAccount, + overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "126.06", "0.0", "0.0"); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "126.04", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("126.06", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("31.51", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("31.51", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("605.94"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("126.04"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("605.94"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("126.06"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("126.04"), + JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentageSpecifiedDueDateCharge), "29 September 2011", "1")); + + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "0.0", "126.06", "0.0"); + validateCharge(amountPlusInterestPercentageSpecifiedDueDateCharge, loanCharges, "1", "126.06", "0.0", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "29 September 2011", + new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.DEBIT)); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "29 September 2011", + new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.CREDIT)); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3309.06"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "0.00", "126.06", "0.0"); + validateCharge(amountPlusInterestPercentageSpecifiedDueDateCharge, loanCharges, "1", "0.00", "126.06", "0.0"); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "94.53", "31.51", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3309.06"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("157.57"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("2911.49"), JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentageSpecifiedDueDateCharge), "29 October 2011", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("157.57", String.valueOf(secondInstallment.get("feeChargesDue"))); + System.out.println("----------- Waive installment charge for 2nd installment ---------"); + this.loanTransactionHelper.waiveChargesForLoan(loanID, (Integer) getloanCharge(amountPlusInterestPercentageInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "63.02", "31.51", "31.51"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", new JournalEntry(Float.valueOf("31.51"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 September 2011", + new JournalEntry(Float.valueOf("31.51"), JournalEntry.TransactionType.DEBIT)); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3277.54"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3277.54"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("126.06"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("181.77"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 December 2011", new JournalEntry(Float.valueOf("61.79"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 December 2011", + new JournalEntry(Float.valueOf("61.79"), JournalEntry.TransactionType.DEBIT)); + + Integer amountPlusInterestPercentagePenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", true)); + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentagePenaltySpecifiedDueDate), "29 September 2011", "1")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentagePenaltySpecifiedDueDate, loanCharges, "1", "0.0", "120.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("120", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + // checking the journal entry as applied penalty has been collected + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3309.06"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("157.57"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2791.49"), + JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3302.99"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3302.99"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("31.51"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("122.38"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3149.10"), + JournalEntry.TransactionType.CREDIT)); + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentagePenaltySpecifiedDueDate), "10 January 2012", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("120", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3241.21", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("120"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3121.21", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make over payment for repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3221.61"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3121.21"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("31.51"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3089.70"), JournalEntry.TransactionType.CREDIT)); + loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "status"); + LoanStatusChecker.verifyLoanAccountIsOverPaid(loanStatusHashMap); + } + /*** + * Test case for checking AccuralPeriodicAccounting functionality adding + * charges with calculation type flat + */ + @Test + public void loanWithFlatCahargesAndPeriodicAccrualAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + this.schedulerJobHelper = new SchedulerJobHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer flatDisbursement = ChargesHelper.createCharges(requestSpec, responseSpec, ChargesHelper.getLoanDisbursementJSON()); + addCharges(charges, flatDisbursement, "100", null); + Integer flatSpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "100", false)); + addCharges(charges, flatSpecifiedDueDate, "100", "29 September 2011"); + Integer flatInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "50", false)); + addCharges(charges, flatInstallmentFee, "50", null); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, ACCRUAL_PERIODIC, assetAccount, incomeAccount, expenseAccount, + overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "100.00", "0.0", "0.0"); + validateCharge(flatSpecifiedDueDate, loanCharges, "100", "100.00", "0.0", "0.0"); + validateCharge(flatInstallmentFee, loanCharges, "50", "200.00", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("100.00", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("150.00", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("50.00", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("100.00"), JournalEntry.TransactionType.CREDIT)); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "0.00", "100.0", "0.0"); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3301.49"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatDisbursement, loanCharges, "100", "0.00", "100.0", "0.0"); + validateCharge(flatSpecifiedDueDate, loanCharges, "100", "0.00", "100.0", "0.0"); + validateCharge(flatInstallmentFee, loanCharges, "50", "150.00", "50.0", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3301.49"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("150.00"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("2911.49"), JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatSpecifiedDueDate), "29 October 2011", "100")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("150.00", String.valueOf(secondInstallment.get("feeChargesDue"))); + System.out.println("----------- Waive installment charge for 2nd installment ---------"); + this.loanTransactionHelper.waiveChargesForLoan(loanID, (Integer) getloanCharge(flatInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatInstallmentFee, loanCharges, "50", "100.00", "50.0", "50.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", new JournalEntry( + Float.valueOf("50.0"), JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 September 2011", + new JournalEntry(Float.valueOf("50.0"), JournalEntry.TransactionType.DEBIT)); + + final String jobName = "Add Accrual Transactions"; + try { + this.schedulerJobHelper.excuteJob(jobName); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + checkAccrualTransactions(loanSchedule, loanID); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3251.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3251.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("100.00"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("181.77"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 December 2011", new JournalEntry(Float.valueOf("61.79"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 December 2011", + new JournalEntry(Float.valueOf("61.79"), JournalEntry.TransactionType.DEBIT)); + + Integer flatPenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "100", true)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatPenaltySpecifiedDueDate), "29 September 2011", "100")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(flatPenaltySpecifiedDueDate, loanCharges, "100", "0.00", "100.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("100", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + // checking the journal entry as applied penalty has been collected + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3301.49"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("100"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("150"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2811.49"), + JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3301.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3301.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("50"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("122.38"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3129.10"), + JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(flatPenaltySpecifiedDueDate), "10 January 2012", "100")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("100", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3239.70", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("100"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("100"), + JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("100"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3139.70", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3139.70"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3139.70"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("50.00"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3089.70"), JournalEntry.TransactionType.CREDIT)); + loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "status"); + LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap); + } + + /** + * Test case for checking AccuralPeriodicAccounting functionality adding + * charges with calculation type percentage of amount + */ + @Test + public void loanWithCahargesOfTypeAmountPercentageAndPeriodicAccrualAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + this.schedulerJobHelper = new SchedulerJobHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer percentageDisbursementCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1")); + addCharges(charges, percentageDisbursementCharge, "1", null); + + Integer percentageSpecifiedDueDateCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", false)); + addCharges(charges, percentageSpecifiedDueDateCharge, "1", "29 September 2011"); + + Integer percentageInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", false)); + addCharges(charges, percentageInstallmentFee, "1", "29 September 2011"); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, ACCRUAL_PERIODIC, assetAccount, incomeAccount, expenseAccount, + overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "120.00", "0.0", "0.0"); + validateCharge(percentageSpecifiedDueDateCharge, loanCharges, "1", "120.00", "0.0", "0.0"); + validateCharge(percentageInstallmentFee, loanCharges, "1", "120.00", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("120.00", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("149.11", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("29.70", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("120.00"), JournalEntry.TransactionType.CREDIT)); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "0.0", "120.00", "0.0"); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3300.60"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageDisbursementCharge, loanCharges, "1", "0.00", "120.00", "0.0"); + validateCharge(percentageSpecifiedDueDateCharge, loanCharges, "1", "0.00", "120.0", "0.0"); + validateCharge(percentageInstallmentFee, loanCharges, "1", "90.89", "29.11", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3300.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("149.11"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("2911.49"), JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentageSpecifiedDueDateCharge), "29 October 2011", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("149.70", String.valueOf(secondInstallment.get("feeChargesDue"))); + System.out.println("----------- Waive installment charge for 2nd installment ---------"); + this.loanTransactionHelper.waiveChargesForLoan(loanID, + (Integer) getloanCharge(percentageInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentageInstallmentFee, loanCharges, "1", "61.19", "29.11", "29.70"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", new JournalEntry( + Float.valueOf("29.7"), JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 September 2011", + new JournalEntry(Float.valueOf("29.7"), JournalEntry.TransactionType.DEBIT)); + + final String jobName = "Add Accrual Transactions"; + try { + this.schedulerJobHelper.excuteJob(jobName); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + checkAccrualTransactions(loanSchedule, loanID); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3271.48"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3271.48"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("181.77"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 December 2011", new JournalEntry(Float.valueOf("61.79"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 December 2011", + new JournalEntry(Float.valueOf("61.79"), JournalEntry.TransactionType.DEBIT)); + + Integer percentagePenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", true)); + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentagePenaltySpecifiedDueDate), "29 September 2011", "1")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(percentagePenaltySpecifiedDueDate, loanCharges, "1", "0.00", "120.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("120", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + // checking the journal entry as applied penalty has been collected + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3300.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("149.11"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2791.49"), + JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3301.77"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3301.77"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("30.29"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("122.38"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3149.1"), + JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(percentagePenaltySpecifiedDueDate), "10 January 2012", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("120", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3240.60", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("120"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3120.60", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3120.60"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3120.60"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("30.90"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3089.70"), JournalEntry.TransactionType.CREDIT)); + loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "status"); + LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap); + } + /*** + * Test case for checking AccuralPeriodicAccounting functionality adding + * charges with calculation type percentage of amount and interest + */ + @Test + public void loanWithCahargesOfTypeAmountPlusInterestPercentageAndPeriodicAccrualAccountingEnabled() { + this.journalEntryHelper = new JournalEntryHelper(this.requestSpec, this.responseSpec); + this.schedulerJobHelper = new SchedulerJobHelper(this.requestSpec, this.responseSpec); + + final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); + ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); + + // Add charges with payment mode regular + List charges = new ArrayList(); + Integer amountPlusInterestPercentageDisbursementCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanDisbursementJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1")); + addCharges(charges, amountPlusInterestPercentageDisbursementCharge, "1", null); + + Integer amountPlusInterestPercentageSpecifiedDueDateCharge = ChargesHelper + .createCharges(requestSpec, responseSpec, ChargesHelper.getLoanSpecifiedDueDateJSON( + ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1", false)); + addCharges(charges, amountPlusInterestPercentageSpecifiedDueDateCharge, "1", "29 September 2011"); + + Integer amountPlusInterestPercentageInstallmentFee = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT_AND_INTEREST, "1", false)); + addCharges(charges, amountPlusInterestPercentageInstallmentFee, "1", "29 September 2011"); + + final Account assetAccount = this.accountHelper.createAssetAccount(); + final Account incomeAccount = this.accountHelper.createIncomeAccount(); + final Account expenseAccount = this.accountHelper.createExpenseAccount(); + final Account overpaymentAccount = this.accountHelper.createLiabilityAccount(); + + final Integer loanProductID = createLoanProduct(false, ACCRUAL_PERIODIC, assetAccount, incomeAccount, expenseAccount, + overpaymentAccount); + final Integer loanID = applyForLoanApplication(clientID, loanProductID, charges, null, "12,000.00"); + Assert.assertNotNull(loanID); + HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); + LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); + + ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + verifyLoanRepaymentSchedule(loanSchedule); + + List loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "126.06", "0.0", "0.0"); + validateCharge(amountPlusInterestPercentageSpecifiedDueDateCharge, loanCharges, "1", "126.06", "0.0", "0.0"); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "126.04", "0.0", "0.0"); + + // check for disbursement fee + HashMap disbursementDetail = loanSchedule.get(0); + validateNumberForEqual("126.06", String.valueOf(disbursementDetail.get("feeChargesDue"))); + + // check for charge at specified date and installment fee + HashMap firstInstallment = loanSchedule.get(1); + validateNumberForEqual("157.57", String.valueOf(firstInstallment.get("feeChargesDue"))); + + // check for installment fee + HashMap secondInstallment = loanSchedule.get(2); + validateNumberForEqual("31.51", String.valueOf(secondInstallment.get("feeChargesDue"))); + + System.out.println("-----------------------------------APPROVE LOAN-----------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); + LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); + + System.out.println("-------------------------------DISBURSE LOAN-------------------------------------------"); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); + + final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.DEBIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("12000.00"), JournalEntry.TransactionType.DEBIT) }; + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", assetAccountInitialEntry); + this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "20 September 2011", + new JournalEntry(Float.valueOf("126.06"), JournalEntry.TransactionType.CREDIT)); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "0.0", "126.06", "0.0"); + + System.out.println("-------------Make repayment 1-----------"); + this.loanTransactionHelper.makeRepayment("20 October 2011", Float.valueOf("3309.06"), loanID); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageDisbursementCharge, loanCharges, "1", "0.00", "126.06", "0.0"); + validateCharge(amountPlusInterestPercentageSpecifiedDueDateCharge, loanCharges, "1", "0.00", "126.06", "0.0"); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "94.53", "31.51", "0.0"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3309.06"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("157.57"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("2911.49"), JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentageSpecifiedDueDateCharge), "29 October 2011", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("157.57", String.valueOf(secondInstallment.get("feeChargesDue"))); + System.out.println("----------- Waive installment charge for 2nd installment ---------"); + this.loanTransactionHelper.waiveChargesForLoan(loanID, + (Integer) getloanCharge(amountPlusInterestPercentageInstallmentFee, loanCharges).get("id"), + LoanTransactionHelper.getWaiveChargeJSON(String.valueOf(2))); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentageInstallmentFee, loanCharges, "1", "63.02", "31.51", "31.51"); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 September 2011", new JournalEntry( + Float.valueOf("31.51"), JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 September 2011", + new JournalEntry(Float.valueOf("31.51"), JournalEntry.TransactionType.DEBIT)); + + final String jobName = "Add Accrual Transactions"; + try { + this.schedulerJobHelper.excuteJob(jobName); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + checkAccrualTransactions(loanSchedule, loanID); + + System.out.println("----------Make repayment 2------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3277.54"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3277.54"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("126.06"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("181.77"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2969.71"), + JournalEntry.TransactionType.CREDIT)); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("0", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("--------------Waive interest---------------"); + this.loanTransactionHelper.waiveInterest("20 December 2011", String.valueOf(61.79), loanID); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap thirdInstallment = loanSchedule.get(3); + validateNumberForEqual("60.59", String.valueOf(thirdInstallment.get("interestOutstanding"))); + + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 December 2011", new JournalEntry(Float.valueOf("61.79"), + JournalEntry.TransactionType.CREDIT)); + this.journalEntryHelper.checkJournalEntryForExpenseAccount(expenseAccount, "20 December 2011", + new JournalEntry(Float.valueOf("61.79"), JournalEntry.TransactionType.DEBIT)); + + Integer amountPlusInterestPercentagePenaltySpecifiedDueDate = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_PERCENTAGE_AMOUNT, "1", true)); + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentagePenaltySpecifiedDueDate), "29 September 2011", "1")); + loanCharges.clear(); + loanCharges = this.loanTransactionHelper.getLoanCharges(loanID); + validateCharge(amountPlusInterestPercentagePenaltySpecifiedDueDate, loanCharges, "1", "0.0", "120.0", "0.0"); + + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + secondInstallment = loanSchedule.get(2); + validateNumberForEqual("120", String.valueOf(secondInstallment.get("totalOutstandingForPeriod"))); + + // checking the journal entry as applied penalty has been collected + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 October 2011", new JournalEntry( + Float.valueOf("3309.06"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("157.57"), JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("240"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("2791.49"), + JournalEntry.TransactionType.CREDIT)); + + System.out.println("----------Make repayment 3 advance------------"); + this.loanTransactionHelper.makeRepayment("20 November 2011", Float.valueOf("3302.99"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 November 2011", + new JournalEntry(Float.valueOf("3302.99"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("31.51"), + JournalEntry.TransactionType.CREDIT), + new JournalEntry(Float.valueOf("122.38"), JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3149.1"), + JournalEntry.TransactionType.CREDIT)); + + this.loanTransactionHelper.addChargesForLoan( + loanID, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( + String.valueOf(amountPlusInterestPercentagePenaltySpecifiedDueDate), "10 January 2012", "1")); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + HashMap fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("120", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3241.21", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Pay applied penalty ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("120"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry(Float.valueOf("120"), + JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("120"), JournalEntry.TransactionType.CREDIT)); + loanSchedule.clear(); + loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); + fourthInstallment = loanSchedule.get(4); + validateNumberForEqual("0", String.valueOf(fourthInstallment.get("penaltyChargesOutstanding"))); + validateNumberForEqual("3121.21", String.valueOf(fourthInstallment.get("totalOutstandingForPeriod"))); + + System.out.println("----------Make repayment 4 ------------"); + this.loanTransactionHelper.makeRepayment("20 January 2012", Float.valueOf("3121.21"), loanID); + this.journalEntryHelper.checkJournalEntryForAssetAccount(assetAccount, "20 January 2012", new JournalEntry( + Float.valueOf("3121.21"), JournalEntry.TransactionType.DEBIT), new JournalEntry(Float.valueOf("31.51"), + JournalEntry.TransactionType.CREDIT), new JournalEntry(Float.valueOf("3089.70"), JournalEntry.TransactionType.CREDIT)); + loanStatusHashMap = (HashMap) this.loanTransactionHelper.getLoanDetail(this.requestSpec, this.responseSpec, loanID, "status"); + LoanStatusChecker.verifyLoanAccountIsClosed(loanStatusHashMap); + } + + private void checkAccrualTransactions(final ArrayList loanSchedule, final Integer loanID) { + + for (int i = 1; i < loanSchedule.size(); i++) { + + final HashMap repayment = loanSchedule.get(i); + + final ArrayList dueDateAsArray = (ArrayList) repayment.get("dueDate"); + final LocalDate transactionDate = new LocalDate(dueDateAsArray.get(0), dueDateAsArray.get(1), dueDateAsArray.get(2)); + + final Float interestPortion = BigDecimal.valueOf(Double.valueOf(repayment.get("interestDue").toString())) + .subtract(BigDecimal.valueOf(Double.valueOf(repayment.get("interestWaived").toString()))) + .subtract(BigDecimal.valueOf(Double.valueOf(repayment.get("interestWrittenOff").toString()))).floatValue(); + + final Float feePortion = BigDecimal.valueOf(Double.valueOf(repayment.get("feeChargesDue").toString())) + .subtract(BigDecimal.valueOf(Double.valueOf(repayment.get("feeChargesWaived").toString()))) + .subtract(BigDecimal.valueOf(Double.valueOf(repayment.get("feeChargesWrittenOff").toString()))).floatValue(); + + final Float penaltyPortion = BigDecimal.valueOf(Double.valueOf(repayment.get("penaltyChargesDue").toString())) + .subtract(BigDecimal.valueOf(Double.valueOf(repayment.get("penaltyChargesWaived").toString()))) + .subtract(BigDecimal.valueOf(Double.valueOf(repayment.get("penaltyChargesWrittenOff").toString()))).floatValue(); + + this.loanTransactionHelper.checkAccrualTransactionForRepayment(transactionDate, interestPortion, feePortion, penaltyPortion, + loanID); + } + } } \ No newline at end of file diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java index b41f2ec4b..eb5ae8eb2 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanProductTestBuilder.java @@ -290,4 +290,10 @@ public class LoanProductTestBuilder { return map; } + public LoanProductTestBuilder withAccounting(final String accountingRule, final Account[] account_list) { + this.accountingRule = accountingRule; + this.accountList = account_list; + return this; + } + } diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanStatusChecker.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanStatusChecker.java index 9501f726d..3885455d8 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanStatusChecker.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanStatusChecker.java @@ -37,6 +37,10 @@ public class LoanStatusChecker { assertFalse(getStatus(loanStatusHashMap, "active")); } + public static void verifyLoanAccountIsOverPaid(final HashMap loanStatusHashMap) { + assertTrue(getStatus(loanStatusHashMap, "overpaid")); + } + public static HashMap getStatusOfLoan(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, final Integer loanID) { final String url = "/mifosng-provider/api/v1/loans/" + loanID + "?tenantIdentifier=default"; diff --git a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java index c99f636e8..c255c3ea7 100644 --- a/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java +++ b/mifosng-provider/src/integrationTest/java/org/mifosplatform/integrationtests/common/loans/LoanTransactionHelper.java @@ -3,9 +3,6 @@ package org.mifosplatform.integrationtests.common.loans; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; @@ -16,7 +13,7 @@ import com.google.gson.Gson; import com.jayway.restassured.specification.RequestSpecification; import com.jayway.restassured.specification.ResponseSpecification; -@SuppressWarnings({ "rawtypes", "unchecked", "cast" }) +@SuppressWarnings({ "rawtypes", "unchecked" }) public class LoanTransactionHelper { private final RequestSpecification requestSpec; @@ -338,7 +335,8 @@ public class LoanTransactionHelper { .get("principalLoanBalanceOutstanding")); } - public void checkAccrualTransactionForRepayment(final String transactionDate, final Float interestAmount, final Integer loanID) { + public void checkAccrualTransactionForRepayment(final LocalDate transactionDate, final Float interestPortion, final Float feePortion, + final Float penaltyPortion, final Integer loanID) { ArrayList transactions = (ArrayList) getLoanDetail(this.requestSpec, this.responseSpec, loanID, "transactions"); boolean isTransactionFound = false; @@ -347,19 +345,19 @@ public class LoanTransactionHelper { boolean isAccrualTransaction = (Boolean) transactionType.get("accrual"); if (isAccrualTransaction) { - ArrayList accrualEntryDateAsArray = (ArrayList)transactions.get(i).get("date"); - LocalDate accrualEntryDate = new LocalDate(accrualEntryDateAsArray.get(0),accrualEntryDateAsArray.get(1),accrualEntryDateAsArray.get(2)); + ArrayList accrualEntryDateAsArray = (ArrayList) transactions.get(i).get("date"); + LocalDate accrualEntryDate = new LocalDate(accrualEntryDateAsArray.get(0), accrualEntryDateAsArray.get(1), + accrualEntryDateAsArray.get(2)); - try { - DateFormat df = new SimpleDateFormat("dd MMMM yyyy"); - LocalDate expectedTransactionDate = new LocalDate(df.parse(transactionDate)); - if (expectedTransactionDate.equals(accrualEntryDate)) { - isTransactionFound = true; - assertEquals("Mismatch in transaction amounts", interestAmount, (Float) transactions.get(i).get("amount")); - break; - } - } catch (ParseException e) { - e.printStackTrace(); + if (transactionDate.equals(accrualEntryDate)) { + isTransactionFound = true; + assertEquals("Mismatch in transaction amounts", interestPortion, + Float.valueOf(String.valueOf(transactions.get(i).get("interestPortion")))); + assertEquals("Mismatch in transaction amounts", feePortion, + Float.valueOf(String.valueOf(transactions.get(i).get("feeChargesPortion")))); + assertEquals("Mismatch in transaction amounts", penaltyPortion, + Float.valueOf(String.valueOf(transactions.get(i).get("penaltyChargesPortion")))); + break; } } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java index ea2bca460..7d0050136 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/api/AuthenticationApiResource.java @@ -22,7 +22,6 @@ import org.mifosplatform.infrastructure.security.service.SpringSecurityPlatformS import org.mifosplatform.useradministration.data.RoleData; import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.Role; -import org.mifosplatform.useradministration.exception.UserNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; @@ -59,10 +58,6 @@ public class AuthenticationApiResource { final Authentication authentication = new UsernamePasswordAuthenticationToken(username, password); final Authentication authenticationCheck = this.customAuthenticationProvider.authenticate(authentication); - final AppUser principal = (AppUser) authenticationCheck.getPrincipal(); - if (principal.isDeleted() || principal.isNotEnabled() ) { - throw new UserNotFoundException(principal.getId()); - } final Collection permissions = new ArrayList(); AuthenticatedUserData authenticatedUserData = new AuthenticatedUserData(username, permissions); @@ -75,6 +70,7 @@ public class AuthenticationApiResource { final byte[] base64EncodedAuthenticationKey = Base64.encode(username + ":" + password); + final AppUser principal = (AppUser) authenticationCheck.getPrincipal(); final Collection roles = new ArrayList(); final Set userRoles = principal.getRoles(); for (final Role role : userRoles) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUserRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUserRepository.java index 14448ec16..f36ad701b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUserRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/domain/PlatformUserRepository.java @@ -7,6 +7,6 @@ package org.mifosplatform.infrastructure.security.domain; public interface PlatformUserRepository { - PlatformUser findByUsername(String username); + PlatformUser findByUsernameAndDeletedAndEnabled(String username, boolean deleted, boolean enabled); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantAwareJpaPlatformUserDetailsService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantAwareJpaPlatformUserDetailsService.java index f0ca9479e..f3aca0924 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantAwareJpaPlatformUserDetailsService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/security/service/TenantAwareJpaPlatformUserDetailsService.java @@ -29,7 +29,11 @@ public class TenantAwareJpaPlatformUserDetailsService implements PlatformUserDet @Cacheable(value = "usersByUsername", key = "T(org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil).getTenant().getTenantIdentifier().concat(#username+'ubu')") public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException, DataAccessException { - final PlatformUser appUser = this.platformUserRepository.findByUsername(username); + // Retrieve active users only + final boolean deleted = false; + final boolean enabled = true; + + final PlatformUser appUser = this.platformUserRepository.findByUsernameAndDeletedAndEnabled(username, deleted, enabled); if (appUser == null) { throw new UsernameNotFoundException(username + ": not found"); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java index 1f1e38f71..01e667c48 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanproduct/serialization/LoanProductDataValidator.java @@ -608,7 +608,7 @@ public final class LoanProductDataValidator { final Long incomeFromRecoveryAccountId = this.fromApiJsonHelper.extractLongNamed( LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_RECOVERY.getValue(), element); baseDataValidator.reset().parameter(LOAN_PRODUCT_ACCOUNTING_PARAMS.INCOME_FROM_RECOVERY.getValue()).value(incomeFromRecoveryAccountId) - .notNull().integerGreaterThanZero(); + .ignoreIfNull().integerGreaterThanZero(); final Long writeOffAccountId = this.fromApiJsonHelper.extractLongNamed( LOAN_PRODUCT_ACCOUNTING_PARAMS.LOSSES_WRITTEN_OFF.getValue(), element);