| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.fineract.integrationtests.common; |
| |
| import com.google.gson.Gson; |
| import io.restassured.builder.RequestSpecBuilder; |
| import io.restassured.builder.ResponseSpecBuilder; |
| import io.restassured.http.ContentType; |
| import io.restassured.path.json.JsonPath; |
| import io.restassured.specification.RequestSpecification; |
| import io.restassured.specification.ResponseSpecification; |
| import java.math.BigDecimal; |
| import java.text.ParseException; |
| import java.time.LocalDate; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import org.apache.fineract.integrationtests.common.accounting.Account; |
| import org.apache.fineract.integrationtests.common.accounting.AccountHelper; |
| import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; |
| import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder; |
| import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker; |
| import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension; |
| import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper; |
| import org.apache.fineract.integrationtests.common.provisioning.ProvisioningHelper; |
| import org.apache.fineract.integrationtests.common.provisioning.ProvisioningTransactionHelper; |
| import org.junit.jupiter.api.Assertions; |
| import org.junit.jupiter.api.Assumptions; |
| import org.junit.jupiter.api.BeforeEach; |
| import org.junit.jupiter.api.Test; |
| import org.junit.jupiter.api.extension.ExtendWith; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| @SuppressWarnings({ "rawtypes", "unchecked" }) |
| @ExtendWith(LoanTestLifecycleExtension.class) |
| public class ProvisioningIntegrationTest { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(ProvisioningIntegrationTest.class); |
| private static final String NONE = "1"; |
| private static final int LOANPRODUCTS_SIZE = 10; |
| |
| private RequestSpecification requestSpec; |
| private ResponseSpecification responseSpec; |
| private AccountHelper accountHelper; |
| private LoanTransactionHelper loanTransactionHelper; |
| |
| @BeforeEach |
| public void setup() throws ParseException { |
| Utils.initializeRESTAssured(); |
| this.requestSpec = new RequestSpecBuilder().setContentType(ContentType.JSON).build(); |
| this.requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey()); |
| this.responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build(); |
| this.requestSpec.header("Fineract-Platform-TenantId", "default"); |
| this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpec); |
| this.accountHelper = new AccountHelper(this.requestSpec, this.responseSpec); |
| Assumptions.assumeTrue(!isAlreadyProvisioningEntriesCreated()); |
| } |
| |
| @Test |
| public void testCreateProvisioningCriteria() { |
| ProvisioningTransactionHelper transactionHelper = new ProvisioningTransactionHelper(requestSpec, responseSpec); |
| ArrayList<Integer> loanProducts = new ArrayList<>(LOANPRODUCTS_SIZE); |
| final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec); |
| ClientHelper.verifyClientCreatedOnServer(this.requestSpec, this.responseSpec, clientID); |
| |
| for (int i = 0; i < LOANPRODUCTS_SIZE; i++) { |
| final Integer loanProductID = createLoanProduct(false, NONE); |
| loanProducts.add(loanProductID); |
| Assertions.assertNotNull(loanProductID); |
| List<HashMap> collaterals = new ArrayList<>(); |
| final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec); |
| Assertions.assertNotNull(collateralId); |
| final Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(this.requestSpec, this.responseSpec, |
| String.valueOf(clientID), collateralId); |
| Assertions.assertNotNull(clientCollateralId); |
| addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1)); |
| final Integer loanID = applyForLoanApplication(clientID, loanProductID, null, null, "1,00,000.00", collaterals); |
| HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); |
| LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); |
| loanStatusHashMap = this.loanTransactionHelper.approveLoan("20 September 2011", loanID); |
| LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); |
| LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); |
| LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); |
| String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); |
| loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("20 September 2011", loanID, |
| JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); |
| LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); |
| Assertions.assertNotNull(loanID); |
| } |
| |
| ArrayList categories = transactionHelper.retrieveAllProvisioningCategories(); |
| Assertions.assertTrue(categories.size() > 0); |
| Account liability = accountHelper.createLiabilityAccount(); |
| Account expense = accountHelper.createExpenseAccount(); |
| Map requestCriteria = ProvisioningHelper.createProvisioingCriteriaJson(loanProducts, categories, liability, expense); |
| String provisioningCriteriaCreateJson = new Gson().toJson(requestCriteria); |
| Integer criteriaId = transactionHelper.createProvisioningCriteria(provisioningCriteriaCreateJson); |
| Assertions.assertNotNull(criteriaId); |
| |
| Map newCriteria = transactionHelper.retrieveProvisioningCriteria(criteriaId); |
| validateProvisioningCriteria(requestCriteria, newCriteria); |
| |
| ArrayList definitions = (ArrayList) newCriteria.get("definitions"); |
| for (int i = 0; i < definitions.size(); i++) { |
| Map criteriadefinition = (Map) definitions.get(i); |
| criteriadefinition.put("provisioningPercentage", Float.valueOf((float) 20.0)); |
| } |
| newCriteria.put("locale", "en"); |
| String updateCriteriaString = new Gson().toJson(newCriteria); |
| Integer criteriaId1 = transactionHelper.updateProvisioningCriteria(criteriaId, updateCriteriaString); |
| Map updatedCriteria = transactionHelper.retrieveProvisioningCriteria(criteriaId1); |
| validateProvisioningCriteria(newCriteria, updatedCriteria); |
| |
| transactionHelper.deleteProvisioningCriteria(criteriaId1); |
| |
| categories = transactionHelper.retrieveAllProvisioningCategories(); |
| liability = accountHelper.createLiabilityAccount(); |
| expense = accountHelper.createExpenseAccount(); |
| requestCriteria = ProvisioningHelper.createProvisioingCriteriaJson(loanProducts, categories, liability, expense); |
| provisioningCriteriaCreateJson = new Gson().toJson(requestCriteria); |
| criteriaId = transactionHelper.createProvisioningCriteria(provisioningCriteriaCreateJson); |
| Assertions.assertNotNull(criteriaId); |
| |
| String provisioningEntryJson = ProvisioningHelper.createProvisioningEntryJson(); |
| Integer provisioningEntryId = transactionHelper.createProvisioningEntries(provisioningEntryJson); |
| Assertions.assertNotNull(provisioningEntryId); |
| |
| transactionHelper.updateProvisioningEntry("recreateprovisioningentry", provisioningEntryId, ""); |
| transactionHelper.updateProvisioningEntry("createjournalentry", provisioningEntryId, ""); |
| Map entry = transactionHelper.retrieveProvisioningEntry(provisioningEntryId); |
| Assertions.assertTrue((Boolean) entry.get("journalEntry")); |
| Map provisioningEntry = transactionHelper.retrieveProvisioningEntries(provisioningEntryId); |
| Assertions.assertTrue(((ArrayList) provisioningEntry.get("pageItems")).size() > 0); |
| } |
| |
| private HashMap<String, String> collaterals(Integer collateralId, BigDecimal quantity) { |
| HashMap<String, String> collateral = new HashMap<String, String>(2); |
| collateral.put("clientCollateralId", collateralId.toString()); |
| collateral.put("quantity", quantity.toString()); |
| return collateral; |
| } |
| |
| private void addCollaterals(List<HashMap> collaterals, Integer collateralId, BigDecimal quantity) { |
| collaterals.add(collaterals(collateralId, quantity)); |
| } |
| |
| private void validateProvisioningCriteria(Map requestCriteria, Map newCriteria) { |
| |
| // criteria name validation |
| String requestCriteriaName = (String) requestCriteria.get("criteriaName"); |
| String criteriaName = (String) newCriteria.get("criteriaName"); |
| Assertions.assertEquals(criteriaName, requestCriteriaName); |
| |
| // loan products validation |
| ArrayList requestProducts = (ArrayList) requestCriteria.get("loanProducts"); |
| ArrayList products = (ArrayList) newCriteria.get("loanProducts"); |
| Assertions.assertEquals(products.size(), requestProducts.size()); |
| |
| ArrayList requestedDefinitions = (ArrayList) requestCriteria.get("definitions"); |
| ArrayList newdefintions = (ArrayList) newCriteria.get("definitions"); |
| Assertions.assertEquals(newdefintions.size(), requestedDefinitions.size()); |
| for (int i = 0; i < newdefintions.size(); i++) { |
| Map requestedMap = (Map) requestedDefinitions.get(i); |
| Object requestedCategoryId = requestedMap.get("categoryId"); |
| boolean found = false; |
| for (int j = 0; j < newdefintions.size(); j++) { |
| Map newMap = (Map) newdefintions.get(j); |
| Object newCategoryId = newMap.get("categoryId"); |
| if (requestedCategoryId.equals(newCategoryId)) { |
| found = true; |
| checkProperty("categoryId", requestedMap, newMap); |
| checkProperty("categoryName", requestedMap, newMap); |
| checkProperty("minAge", requestedMap, newMap); |
| checkProperty("maxAge", requestedMap, newMap); |
| checkProperty("provisioningPercentage", requestedMap, newMap); |
| checkProperty("liabilityAccount", requestedMap, newMap); |
| checkProperty("expenseAccount", requestedMap, newMap); |
| break; // internal loop |
| } |
| } |
| if (!found) { |
| Assertions.fail("No Category found with Id:" + requestedCategoryId); |
| } |
| } |
| } |
| |
| private void checkProperty(String propertyName, Map requestMap, Map newMap) { |
| Object requested = requestMap.get(propertyName); |
| Object modified = newMap.get(propertyName); |
| Assertions.assertEquals(requested, modified); |
| } |
| |
| private Integer createLoanProduct(final boolean multiDisburseLoan, final String accountingRule, final Account... accounts) { |
| LOG.info("------------------------------CREATING NEW LOAN PRODUCT ---------------------------------------"); |
| LoanProductTestBuilder builder = new LoanProductTestBuilder() // |
| .withPrincipal("1,00,000.00") // |
| .withNumberOfRepayments("4") // |
| .withRepaymentAfterEvery("1") // |
| .withRepaymentTypeAsMonth() // |
| .withinterestRatePerPeriod("1") // |
| .withInterestRateFrequencyTypeAsMonths() // |
| .withAmortizationTypeAsEqualInstallments() // |
| .withInterestTypeAsDecliningBalance() // |
| .withTranches(multiDisburseLoan) // |
| .withAccounting(accountingRule, accounts); |
| if (multiDisburseLoan) { |
| builder = builder.withInterestCalculationPeriodTypeAsRepaymentPeriod(true); |
| } |
| final String loanProductJSON = builder.build(null); |
| |
| return this.loanTransactionHelper.getLoanProductId(loanProductJSON); |
| } |
| |
| private Integer applyForLoanApplication(final Integer clientID, final Integer loanProductID, List<HashMap> charges, |
| final String savingsId, String principal, List<HashMap> collaterals) { |
| LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); |
| final String loanApplicationJSON = new LoanApplicationTestBuilder() // |
| .withPrincipal(principal) // |
| .withLoanTermFrequency("4") // |
| .withLoanTermFrequencyAsMonths() // |
| .withNumberOfRepayments("4") // |
| .withRepaymentEveryAfter("1") // |
| .withRepaymentFrequencyTypeAsMonths() // |
| .withInterestRatePerPeriod("2") // |
| .withAmortizationTypeAsEqualInstallments() // |
| .withInterestTypeAsDecliningBalance() // |
| .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() // |
| .withExpectedDisbursementDate("20 September 2011") // |
| .withSubmittedOnDate("20 September 2011") // |
| .withCollaterals(collaterals).withCharges(charges).build(clientID.toString(), loanProductID.toString(), savingsId); |
| return this.loanTransactionHelper.getLoanId(loanApplicationJSON); |
| } |
| |
| private boolean isAlreadyProvisioningEntriesCreated() throws ParseException { |
| ProvisioningTransactionHelper transactionHelper = new ProvisioningTransactionHelper(requestSpec, responseSpec); |
| Map entries = transactionHelper.retrieveAllProvisioningEntries(); |
| ArrayList<Map> pageItems = (ArrayList) entries.get("pageItems"); |
| boolean provisioningetryAlreadyCreated = false; |
| if (pageItems != null) { |
| for (Map item : pageItems) { |
| List<Integer> date = (ArrayList) item.get("createdDate"); |
| LocalDate localDate = LocalDate.of(date.get(0), date.get(1), date.get(2)); |
| |
| if (localDate.equals(Utils.getLocalDateOfTenant())) { |
| provisioningetryAlreadyCreated = true; |
| break; |
| } |
| } |
| } |
| return provisioningetryAlreadyCreated; |
| } |
| } |