This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 357062a18 Loan externalId unique validation
357062a18 is described below

commit 357062a18601ecc8a59cc89770f3959a7d89321b
Author: Jose Alberto Hernandez <[email protected]>
AuthorDate: Thu Jun 30 21:02:40 2022 -0500

    Loan externalId unique validation
---
 .../loanaccount/domain/LoanRepository.java         |  2 ++
 .../loanaccount/domain/LoanRepositoryWrapper.java  |  4 +++
 ...ationWritePlatformServiceJpaRepositoryImpl.java | 10 ++++++
 .../ClientLoanIntegrationTest.java                 | 42 ++++++++++++++++++++++
 .../common/loans/LoanApplicationTestBuilder.java   | 12 ++++++-
 .../common/loans/LoanTransactionHelper.java        |  6 +++-
 6 files changed, 74 insertions(+), 2 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java
index 16c8216cd..44dd7e756 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java
@@ -161,4 +161,6 @@ public interface LoanRepository extends JpaRepository<Loan, 
Long>, JpaSpecificat
     @Query(FIND_BY_ACCOUNT_NUMBER)
     Loan findLoanAccountByAccountNumber(@Param("accountNumber") String 
accountNumber);
 
+    boolean existsByExternalId(@Param("externalId") String externalId);
+
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
index d7bb7adef..5ad13c870 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
@@ -240,6 +240,10 @@ public class LoanRepositoryWrapper {
         return this.repository.findNonClosedLoanByAccountNumber(accountNumber);
     }
 
+    public boolean existLoanByExternalId(final String externalId) {
+        return this.repository.existsByExternalId(externalId);
+    }
+
     // Looks like we need complete entity
     @Transactional(readOnly = true)
     public Loan findNonClosedLoanThatBelongsToClient(@Param("loanId") Long 
loanId, @Param("clientId") Long clientId) {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
index 368e45bcb..606077564 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java
@@ -303,6 +303,16 @@ public class 
LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
 
             this.fromApiJsonDeserializer.validateForCreate(command.json(), 
isMeetingMandatoryForJLGLoans, loanProduct);
 
+            // Validate If the externalId is already registered
+            final String externalId = 
this.fromJsonHelper.extractStringNamed("externalId", command.parsedJson());
+            if (StringUtils.isNotBlank(externalId)) {
+                final boolean existByExternalId = 
this.loanRepositoryWrapper.existLoanByExternalId(externalId);
+                if (existByExternalId) {
+                    throw new 
GeneralPlatformDomainRuleException("error.msg.loan.with.externalId.already.used",
+                            "Loan with externalId is already registered.");
+                }
+            }
+
             final List<ApiParameterError> dataValidationErrors = new 
ArrayList<>();
             final DataValidatorBuilder baseDataValidator = new 
DataValidatorBuilder(dataValidationErrors).resource("loan");
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
index 690dfe88a..6c52a8d13 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.integrationtests;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
@@ -125,6 +126,26 @@ public class ClientLoanIntegrationTest {
         verifyLoanRepaymentSchedule(loanSchedule);
     }
 
+    @Test
+    public void validateClientLoanWithUniqueExternalId() {
+        // Given
+        this.loanTransactionHelper = new 
LoanTransactionHelper(this.requestSpec, this.responseSpec);
+        final ResponseSpecification responseSpec403 = new 
ResponseSpecBuilder().expectStatusCode(403).build();
+
+        final Integer clientID = ClientHelper.createClient(this.requestSpec, 
this.responseSpec);
+        final Integer loanProductID = createLoanProduct(false, NONE);
+
+        final String externalId = Utils.randomStringGenerator("qwerty", 10);
+
+        // When
+        final Integer loanID = 
applyForLoanApplicationWithExternalId(this.requestSpec, this.responseSpec, 
clientID, loanProductID,
+                "12,000.00", externalId);
+
+        // Then
+        assertNotNull(loanID);
+        applyForLoanApplicationWithExternalId(this.requestSpec, 
responseSpec403, clientID, loanProductID, "12,000.00", externalId);
+    }
+
     @Test
     public void testLoanCharges_DISBURSEMENT_FEE() {
         this.loanTransactionHelper = new 
LoanTransactionHelper(this.requestSpec, this.responseSpec);
@@ -1155,6 +1176,27 @@ public class ClientLoanIntegrationTest {
         return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
     }
 
+    private Integer applyForLoanApplicationWithExternalId(RequestSpecification 
requestSpec, ResponseSpecification responseSpec,
+            final Integer clientID, final Integer loanProductID, String 
principal, final String externalId) {
+        LOG.info("------------------------APPLYING FOR LOAN APPLICATION WITH 
EXTERNALID------------------------");
+        final String loanApplicationJSON = new LoanApplicationTestBuilder() //
+                .withPrincipal(principal) //
+                .withExternalId(externalId) //
+                .withLoanTermFrequency("4") //
+                .withLoanTermFrequencyAsMonths() //
+                .withNumberOfRepayments("4") //
+                .withRepaymentEveryAfter("1") //
+                .withRepaymentFrequencyTypeAsMonths() //
+                .withInterestRatePerPeriod("2") //
+                .withAmortizationTypeAsEqualInstallments() //
+                .withInterestTypeAsDecliningBalance() //
+                .withInterestCalculationPeriodTypeSameAsRepaymentPeriod() //
+                .withExpectedDisbursementDate("20 September 2011") //
+                .withSubmittedOnDate("20 September 2011") //
+                .build(clientID.toString(), loanProductID.toString(), null);
+        return this.loanTransactionHelper.getLoanId(loanApplicationJSON, 
requestSpec, responseSpec);
+    }
+
     private Integer applyForLoanApplicationWithTranches(final Integer 
clientID, final Integer loanProductID, List<HashMap> charges,
             final String savingsId, String principal, List<HashMap> tranches, 
List<HashMap> collaterals) {
         LOG.info("--------------------------------APPLYING FOR LOAN 
APPLICATION--------------------------------");
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
index 76f0664a8..a480de000 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanApplicationTestBuilder.java
@@ -43,6 +43,7 @@ public class LoanApplicationTestBuilder {
     public static final String RBI_INDIA_STRATEGY = "4";
     public static final String 
INTEREST_PRINCIPAL_PENALTIES_FEES_ORDER_STRATEGY = "6";
 
+    private String externalId = null;
     private String principal = "10,000";
     private String glimPrincipal = "1000";
     private String loanTermFrequency = "";
@@ -124,7 +125,7 @@ public class LoanApplicationTestBuilder {
         if (this.glimPrincipal != null) {
             map.put("glimPrincipal", this.glimPrincipal);
         }
-        map.put("locale", "en_GB");
+        map.put("locale", LOCALE);
 
         String approvalFormData = new Gson().toJson(map);
         LOG.info("approvalFormData: {} ", approvalFormData);
@@ -153,6 +154,10 @@ public class LoanApplicationTestBuilder {
         map.put("collateral", this.collaterals);
         map.put("interestChargedFromDate", this.interestChargedFromDate);
 
+        if (this.externalId != null) {
+            map.put("externalId", this.externalId);
+        }
+
         if (repaymentsStartingFromDate != null) {
             map.put("repaymentsStartingFromDate", 
this.repaymentsStartingFromDate);
         }
@@ -185,6 +190,11 @@ public class LoanApplicationTestBuilder {
         return new Gson().toJson(map);
     }
 
+    public LoanApplicationTestBuilder withExternalId(final String externalId) {
+        this.externalId = externalId;
+        return this;
+    }
+
     public LoanApplicationTestBuilder withPrincipal(final String 
principalAmount) {
         this.principal = principalAmount;
         return this;
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
index e2688f2da..b0a0121ed 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
@@ -81,7 +81,11 @@ public class LoanTransactionHelper {
     }
 
     public Integer getLoanId(final String loanApplicationJSON) {
-        return Utils.performServerPost(this.requestSpec, this.responseSpec, 
APPLY_LOAN_URL, loanApplicationJSON, "loanId");
+        return this.getLoanId(loanApplicationJSON, this.requestSpec, 
this.responseSpec);
+    }
+
+    public Integer getLoanId(final String loanApplicationJSON, 
RequestSpecification requestSpec, ResponseSpecification responseSpec) {
+        return Utils.performServerPost(requestSpec, responseSpec, 
APPLY_LOAN_URL, loanApplicationJSON, "loanId");
     }
 
     public HashMap<String, Integer> getGlimId(final String 
loanApplicationJSON) {

Reply via email to