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

adamsaghy 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 8d636fab2 FINERACT-1724 - Reschedule Loan fix - [x] Reschedule loan 
COB API filter fix - [x] Unit test for filter
8d636fab2 is described below

commit 8d636fab2bd0cb7aabac2ef7b3aeaef6824f3780
Author: Janos Haber <[email protected]>
AuthorDate: Wed Mar 8 13:34:17 2023 +0100

    FINERACT-1724 - Reschedule Loan fix
    - [x] Reschedule loan COB API filter fix
    - [x] Unit test for filter
---
 .../jobs/filter/LoanCOBApiFilter.java              | 17 ++++++---
 .../domain/LoanRescheduleRequestRepository.java    |  4 +++
 .../jobs/filter/LoanCOBApiFilterTest.java          | 41 ++++++++++++++++++++++
 3 files changed, 58 insertions(+), 4 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java
index 09ddddcff..d8e9a6773 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilter.java
@@ -48,6 +48,7 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepositor
 import 
org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
+import 
org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository;
 import 
org.apache.fineract.useradministration.exception.UnAuthenticatedUserException;
 import org.apache.http.HttpStatus;
 import org.springframework.http.HttpMethod;
@@ -64,12 +65,14 @@ public class LoanCOBApiFilter extends OncePerRequestFilter 
implements BatchFilte
     private final InlineLoanCOBExecutorServiceImpl 
inlineLoanCOBExecutorService;
     private final LoanRepository loanRepository;
 
+    private final LoanRescheduleRequestRepository 
loanRescheduleRequestRepository;
+
     private static final List<HttpMethod> HTTP_METHODS = 
List.of(HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE);
 
     public static final Pattern IGNORE_LOAN_PATH_PATTERN = 
Pattern.compile("\\/loans\\/catch-up");
-    public static final Pattern LOAN_PATH_PATTERN = 
Pattern.compile("\\/?loans\\/(?:external-id\\/)?([^\\/\\?]+).*");
+    public static final Pattern LOAN_PATH_PATTERN = 
Pattern.compile("\\/(?:reschedule)?loans\\/(?:external-id\\/)?([^\\/\\?]+).*");
 
-    public static final Pattern LOAN_GLIMACCOUNT_PATH_PATTERN = 
Pattern.compile("\\/?loans\\/glimAccount\\/(\\d+).*");
+    public static final Pattern LOAN_GLIMACCOUNT_PATH_PATTERN = 
Pattern.compile("\\/loans\\/glimAccount\\/(\\d+).*");
     private static final Predicate<String> URL_FUNCTION = s -> 
LOAN_PATH_PATTERN.matcher(s).find()
             || LOAN_GLIMACCOUNT_PATH_PATTERN.matcher(s).find();
     private static final String JOB_NAME = "INLINE_LOAN_COB";
@@ -123,7 +126,7 @@ public class LoanCOBApiFilter extends OncePerRequestFilter 
implements BatchFilte
                 } else {
                     try {
                         List<Long> loanIds = 
calculateRelevantLoanIds(request.getPathInfo());
-                        if (isLoanSoftLocked(loanIds) || 
isLoanBehind(loanIds)) {
+                        if (!loanIds.isEmpty() && (isLoanSoftLocked(loanIds) 
|| isLoanBehind(loanIds))) {
                             executeInlineCob(loanIds);
                         }
                         proceed(filterChain, request, response);
@@ -207,6 +210,8 @@ public class LoanCOBApiFilter extends OncePerRequestFilter 
implements BatchFilte
             if (isExternal(pathInfo)) {
                 String externalId = id;
                 return loanRepository.findIdByExternalId(new 
ExternalId(externalId));
+            } else if (isRescheduleLoans(pathInfo)) {
+                return 
loanRescheduleRequestRepository.getLoanIdByRescheduleRequestId(Long.valueOf(id)).orElse(null);
             } else if (StringUtils.isNumeric(id)) {
                 return Long.valueOf(id);
             } else {
@@ -221,6 +226,10 @@ public class LoanCOBApiFilter extends OncePerRequestFilter 
implements BatchFilte
         return LOAN_PATH_PATTERN.matcher(pathInfo).matches() && 
pathInfo.contains("external-id");
     }
 
+    private boolean isRescheduleLoans(String pathInfo) {
+        return LOAN_PATH_PATTERN.matcher(pathInfo).matches() && 
pathInfo.contains("/rescheduleloans/");
+    }
+
     private boolean isOnApiList(String pathInfo, String method) {
         if (StringUtils.isBlank(pathInfo)) {
             return false;
@@ -245,7 +254,7 @@ public class LoanCOBApiFilter extends OncePerRequestFilter 
implements BatchFilte
                 } else {
                     try {
                         List<Long> result = calculateRelevantLoanIds("/" + 
batchRequest.getRelativeUrl());
-                        if (isLoanSoftLocked(result) || isLoanBehind(result)) {
+                        if (!result.isEmpty() && (isLoanSoftLocked(result) || 
isLoanBehind(result))) {
                             executeInlineCob(result);
                         }
                         return chain.serviceCall(batchRequest, uriInfo);
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequestRepository.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequestRepository.java
index 64ed26bc0..4d93a9352 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequestRepository.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequestRepository.java
@@ -18,10 +18,14 @@
  */
 package org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain;
 
+import java.util.Optional;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
 
 public interface LoanRescheduleRequestRepository
         extends JpaRepository<LoanRescheduleRequest, Long>, 
JpaSpecificationExecutor<LoanRescheduleRequest> {
 
+    @Query("select lrr.loan.id from LoanRescheduleRequest lrr where lrr.id = 
:rescheduleRequestId")
+    Optional<Long> getLoanIdByRescheduleRequestId(Long rescheduleRequestId);
 }
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
index 6043d748d..b787abffb 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/jobs/filter/LoanCOBApiFilterTest.java
@@ -34,6 +34,7 @@ import java.time.LocalDate;
 import java.time.ZoneId;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Optional;
 import java.util.UUID;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -48,6 +49,8 @@ import 
org.apache.fineract.portfolio.loanaccount.domain.GLIMAccountInfoRepositor
 import 
org.apache.fineract.portfolio.loanaccount.domain.GroupLoanIndividualMonitoringAccount;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
+import 
org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest;
+import 
org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequestRepository;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.apache.http.HttpStatus;
 import org.junit.jupiter.api.Assertions;
@@ -78,16 +81,25 @@ class LoanCOBApiFilterTest {
     @Mock
     private LoanRepository loanRepository;
 
+    @Mock
+    private LoanRescheduleRequestRepository loanRescheduleRequestRepository;
+
     @Test
     void shouldLoanAndExternalMatchToo() {
         String externalId = UUID.randomUUID().toString();
         
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12").matches());
         
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12?correct=parameter").matches());
+        
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12?correct=parameter").matches());
+        
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12").matches());
+        
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12?correct=parameter").matches());
+        
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12?correct=parameter").matches());
         
Assertions.assertTrue(LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/external-id/"
 + externalId).matches());
         Assertions.assertTrue(
                 
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/external-id/" + externalId + 
"?additional=parameter").matches());
         Assertions.assertEquals("12", 
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12").replaceAll("$1"));
         Assertions.assertEquals("12", 
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/12?correct=parameter").replaceAll("$1"));
+        Assertions.assertEquals("12", 
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12").replaceAll("$1"));
+        Assertions.assertEquals("12", 
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/rescheduleloans/12?correct=parameter").replaceAll("$1"));
         Assertions.assertEquals(externalId,
                 
LoanCOBApiFilter.LOAN_PATH_PATTERN.matcher("/loans/external-id/" + 
externalId).replaceAll("$1"));
         Assertions.assertEquals(externalId,
@@ -210,6 +222,35 @@ class LoanCOBApiFilterTest {
         verify(filterChain, times(1)).doFilter(request, response);
     }
 
+    @Test
+    void shouldProceedWhenRescheduleLoanIsNotLockedAndNotBehind() throws 
ServletException, IOException {
+        MockHttpServletRequest request = mock(MockHttpServletRequest.class);
+        MockHttpServletResponse response = mock(MockHttpServletResponse.class);
+        FilterChain filterChain = mock(FilterChain.class);
+        AppUser appUser = mock(AppUser.class);
+        ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, 
"default", "Default", "Asia/Kolkata", null));
+        HashMap<BusinessDateType, LocalDate> businessDates = new HashMap<>();
+        LocalDate businessDate = LocalDate.now(ZoneId.systemDefault());
+        businessDates.put(BusinessDateType.BUSINESS_DATE, businessDate);
+        businessDates.put(BusinessDateType.COB_DATE, 
businessDate.minusDays(1));
+        ThreadLocalContextUtil.setBusinessDates(businessDates);
+        Long resourceId = 123L;
+        given(request.getPathInfo()).willReturn("/rescheduleloans/" + 
resourceId + "/charges");
+        given(request.getMethod()).willReturn(HTTPMethods.POST.value());
+        given(loanAccountLockService.isLoanHardLocked(2L)).willReturn(false);
+        given(loanAccountLockService.isLoanSoftLocked(2L)).willReturn(false);
+        LoanRescheduleRequest rescheduleRequest = 
mock(LoanRescheduleRequest.class);
+        
given(loanRescheduleRequestRepository.getLoanIdByRescheduleRequestId(resourceId)).willReturn(Optional.of(2L));
+        given(context.authenticatedUser()).willReturn(appUser);
+
+        given(loanRepository.findAllNonClosedLoansBehindByLoanIds(
+                
eq(ThreadLocalContextUtil.getBusinessDateByType(BusinessDateType.COB_DATE)), 
anyList()))
+                        .willReturn(Collections.emptyList());
+
+        testObj.doFilterInternal(request, response, filterChain);
+        verify(filterChain, times(1)).doFilter(request, response);
+    }
+
     @Test
     void shouldRunInlineCOBAndProceedWhenLoanIsSoftLocked() throws 
ServletException, IOException {
         MockHttpServletRequest request = mock(MockHttpServletRequest.class);

Reply via email to