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 573b4bb99 FINERACT-1724: Loan product creation - duplicate short name 
fix
573b4bb99 is described below

commit 573b4bb998aeebd547daae81b18edf4a1ef5ab5a
Author: abraham.menyhart <[email protected]>
AuthorDate: Wed Jun 21 14:50:42 2023 +0200

    FINERACT-1724: Loan product creation - duplicate short name fix
---
 ...oductWritePlatformServiceJpaRepositoryImpl.java | 11 +++-
 .../LoanProductShortNameValidationTest.java        | 73 ++++++++++++++++++++++
 .../common/loans/LoanProductTestBuilder.java       |  7 ++-
 3 files changed, 89 insertions(+), 2 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java
index fdc7547f8..cff6227ba 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java
@@ -328,7 +328,8 @@ public class 
LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
             final String name = command.stringValueOfParameterNamed("name");
             throw new 
PlatformDataIntegrityException("error.msg.product.loan.duplicate.name",
                     "Loan product with name `" + name + "` already exists", 
"name", name, realCause);
-        } else if (realCause.getMessage().contains("'unq_short_name'")) {
+        } else if (realCause.getMessage().contains("'unq_short_name'") || 
containsDuplicateShortnameErrorForPostgreSQL(realCause)
+                || containsDuplicateShortnameErrorForMySQL(realCause)) {
 
             final String shortName = 
command.stringValueOfParameterNamed("shortName");
             throw new 
PlatformDataIntegrityException("error.msg.product.loan.duplicate.short.name",
@@ -343,6 +344,14 @@ public class 
LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
                 "Unknown data integrity issue with resource.", realCause);
     }
 
+    private static boolean 
containsDuplicateShortnameErrorForPostgreSQL(Throwable realCause) {
+        return 
realCause.getMessage().contains("m_product_loan_short_name_key");
+    }
+
+    private static boolean containsDuplicateShortnameErrorForMySQL(Throwable 
realCause) {
+        return (realCause.getMessage().contains("short_name") && 
realCause.getMessage().toLowerCase().contains("duplicate"));
+    }
+
     private void validateInputDates(final JsonCommand command) {
         final LocalDate startDate = 
command.localDateValueOfParameterNamed("startDate");
         final LocalDate closeDate = 
command.localDateValueOfParameterNamed("closeDate");
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductShortNameValidationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductShortNameValidationTest.java
new file mode 100644
index 000000000..7f8e21b96
--- /dev/null
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanProductShortNameValidationTest.java
@@ -0,0 +1,73 @@
+/**
+ * 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;
+
+import static io.restassured.http.ContentType.JSON;
+import static 
org.apache.fineract.integrationtests.common.Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey;
+import static 
org.apache.fineract.integrationtests.common.Utils.uniqueRandomStringGenerator;
+import static org.hamcrest.Matchers.equalTo;
+
+import io.restassured.builder.RequestSpecBuilder;
+import io.restassured.builder.ResponseSpecBuilder;
+import io.restassured.specification.RequestSpecification;
+import io.restassured.specification.ResponseSpecification;
+import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
+import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
+import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(LoanTestLifecycleExtension.class)
+public class LoanProductShortNameValidationTest {
+
+    private RequestSpecification requestSpec;
+
+    @BeforeEach
+    public void setup() {
+        requestSpec = new RequestSpecBuilder().setContentType(JSON)
+                .addHeader("Authorization", "Basic " + 
loginIntoServerAndGetBase64EncodedAuthenticationKey()).build();
+    }
+
+    @Test
+    public void createLoanProductsWithSameShortName() {
+        String shortName = uniqueRandomStringGenerator("", 4);
+        createLoanProduct(shortName, successResponseSpec());
+        createLoanProduct(shortName, validationFailedResponseSpec());
+    }
+
+    private ResponseSpecification successResponseSpec() {
+        return new ResponseSpecBuilder().expectStatusCode(200).build();
+    }
+
+    private ResponseSpecification validationFailedResponseSpec() {
+        return new 
ResponseSpecBuilder().expectBody("userMessageGlobalisationCode", 
equalTo("error.msg.product.loan.duplicate.short.name"))
+                .expectStatusCode(403).build();
+    }
+
+    private void createLoanProduct(String shortName, ResponseSpecification 
responseSpec) {
+        LoanTransactionHelper loanTransactionHelper = new 
LoanTransactionHelper(requestSpec, responseSpec);
+
+        final String loanProductJSON = new 
LoanProductTestBuilder().withPrincipal("10000").withRepaymentAfterEvery("1")
+                
.withShortName(shortName).withRepaymentTypeAsMonth().withInterestRateFrequencyTypeAsMonths().build(null);
+
+        loanTransactionHelper.getLoanProductId(loanProductJSON);
+    }
+}
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index 180a74f67..d06dbd24d 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -75,7 +75,7 @@ public class LoanProductTestBuilder {
     private String inMultiplesOf = "0";
 
     private String nameOfLoanProduct = 
Utils.uniqueRandomStringGenerator("LOAN_PRODUCT_", 6);
-    private final String shortName = Utils.uniqueRandomStringGenerator("", 4);
+    private String shortName = Utils.uniqueRandomStringGenerator("", 4);
     private String principal = "10000.00";
     private String numberOfRepayments = "5";
     private String repaymentFrequency = MONTHS;
@@ -311,6 +311,11 @@ public class LoanProductTestBuilder {
         return this;
     }
 
+    public LoanProductTestBuilder withShortName(final String shortName) {
+        this.shortName = shortName;
+        return this;
+    }
+
     public LoanProductTestBuilder withNumberOfRepayments(final String 
numberOfRepayment) {
         this.numberOfRepayments = numberOfRepayment;
         return this;

Reply via email to