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 06a56d106 FINERACT-1992 Improve validation errors.
06a56d106 is described below

commit 06a56d106d8f2590c4232f838ab85e3794108f25
Author: Peter Bagrij <[email protected]>
AuthorDate: Mon Nov 20 18:59:04 2023 +0100

    FINERACT-1992 Improve validation errors.
---
 .../DelinquencyActionParseAndValidator.java        | 39 +++++++++++++++++-----
 .../DelinquencyActionParseAndValidatorTest.java    | 38 ++++++++++++++++++---
 2 files changed, 64 insertions(+), 13 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidator.java
index eac6670e5..163ee2730 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidator.java
@@ -19,6 +19,9 @@
 package org.apache.fineract.portfolio.delinquency.validator;
 
 import static 
org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.RESUME;
+import static 
org.apache.fineract.portfolio.delinquency.validator.DelinquencyActionParameters.ACTION;
+import static 
org.apache.fineract.portfolio.delinquency.validator.DelinquencyActionParameters.END_DATE;
+import static 
org.apache.fineract.portfolio.delinquency.validator.DelinquencyActionParameters.START_DATE;
 
 import com.google.gson.JsonElement;
 import jakarta.validation.constraints.NotNull;
@@ -54,6 +57,7 @@ public class DelinquencyActionParseAndValidator extends 
ParseAndValidator {
         LoanDelinquencyAction parsedDelinquencyAction = parseCommand(command);
         validateLoanIsActive(loan);
         if 
(DelinquencyAction.PAUSE.equals(parsedDelinquencyAction.getAction())) {
+            validateBothStartAndEndDatesAreProvided(parsedDelinquencyAction);
             validatePauseStartAndEndDate(parsedDelinquencyAction, 
businessDate);
             validatePauseShallNotOverlap(parsedDelinquencyAction, 
effectiveDelinquencyList);
         } else if 
(DelinquencyAction.RESUME.equals(parsedDelinquencyAction.getAction())) {
@@ -64,6 +68,16 @@ public class DelinquencyActionParseAndValidator extends 
ParseAndValidator {
         return parsedDelinquencyAction;
     }
 
+    private void validateBothStartAndEndDatesAreProvided(LoanDelinquencyAction 
parsedDelinquencyAction) {
+        if (parsedDelinquencyAction.getStartDate() == null) {
+            
raiseValidationError("loan-delinquency-action-pause-startDate-cannot-be-blank", 
"The parameter `startDate` is mandatory",
+                    START_DATE);
+        }
+        if (parsedDelinquencyAction.getEndDate() == null) {
+            
raiseValidationError("loan-delinquency-action-pause-endDate-cannot-be-blank", 
"The parameter `endDate` is mandatory", END_DATE);
+        }
+    }
+
     private List<LoanDelinquencyActionData> 
calculateEffectiveDelinquencyList(List<LoanDelinquencyAction> 
savedDelinquencyActions) {
         // partition them based on type
         Map<DelinquencyAction, List<LoanDelinquencyAction>> partitioned = 
savedDelinquencyActions.stream()
@@ -106,14 +120,18 @@ public class DelinquencyActionParseAndValidator extends 
ParseAndValidator {
     private void validateResumeNoEndDate(LoanDelinquencyAction 
parsedDelinquencyAction) {
         if (parsedDelinquencyAction.getEndDate() != null) {
             
raiseValidationError("loan-delinquency-action-resume-should-have-no-end-date",
-                    "Resume Delinquency action can not have end date");
+                    "Resume Delinquency action can not have end date", 
END_DATE);
         }
     }
 
     private void validateResumeStartDate(LoanDelinquencyAction 
parsedDelinquencyAction, LocalDate businessDate) {
+        if (parsedDelinquencyAction.getStartDate() == null) {
+            
raiseValidationError("loan-delinquency-action-resume-startDate-cannot-be-blank",
 "The parameter `startDate` is mandatory",
+                    START_DATE);
+        }
         if (!parsedDelinquencyAction.getStartDate().equals(businessDate)) {
             raiseValidationError("loan-delinquency-action-invalid-start-date",
-                    "Start date of the Resume Delinquency action must be the 
current business date");
+                    "Start date of the Resume Delinquency action must be the 
current business date", START_DATE);
         }
     }
 
@@ -124,7 +142,8 @@ public class DelinquencyActionParseAndValidator extends 
ParseAndValidator {
         }
 
         if (businessDate.isAfter(parsedDelinquencyAction.getStartDate())) {
-            raiseValidationError("loan-delinquency-action-invalid-start-date", 
"Start date of pause period must be in the future");
+            raiseValidationError("loan-delinquency-action-invalid-start-date", 
"Start date of pause period must be in the future",
+                    START_DATE);
         }
     }
 
@@ -167,22 +186,21 @@ public class DelinquencyActionParseAndValidator extends 
ParseAndValidator {
         } else if ("resume".equalsIgnoreCase(actionString)) {
             return DelinquencyAction.RESUME;
         } else {
-            throw new 
PlatformApiDataValidationException(List.of(ApiParameterError.generalError("loan-delinquency-action-invalid-action",
-                    "Invalid Delinquency Action: " + actionString)));
+            throw new 
PlatformApiDataValidationException(List.of(ApiParameterError.parameterError("loan-delinquency-action-invalid-action",
+                    "Invalid Delinquency Action: " + actionString, ACTION)));
         }
     }
 
     private void validateActionString(String actionString) {
         if (StringUtils.isEmpty(actionString)) {
-            raiseValidationError("loan-delinquency-action-missing-action", 
"Delinquency Action must not be null or empty");
+            raiseValidationError("loan-delinquency-action-missing-action", 
"Delinquency Action must not be null or empty", ACTION);
         }
     }
 
     private LocalDate extractStartDate(JsonElement json) {
         String dateFormat = 
jsonHelper.extractStringNamed(DelinquencyActionParameters.DATE_FORMAT, json);
         String locale = 
jsonHelper.extractStringNamed(DelinquencyActionParameters.LOCALE, json);
-        return 
jsonHelper.extractLocalDateNamed(DelinquencyActionParameters.START_DATE, json, 
dateFormat,
-                JsonParserHelper.localeFromString(locale));
+        return jsonHelper.extractLocalDateNamed(START_DATE, json, dateFormat, 
JsonParserHelper.localeFromString(locale));
     }
 
     private LocalDate extractEndDate(JsonElement json) {
@@ -196,4 +214,9 @@ public class DelinquencyActionParseAndValidator extends 
ParseAndValidator {
         throw new 
PlatformApiDataValidationException(List.of(ApiParameterError.generalError(globalisationMessageCode,
 msg)));
     }
 
+    private void raiseValidationError(String globalisationMessageCode, String 
msg, String fieldName)
+            throws PlatformApiDataValidationException {
+        throw new 
PlatformApiDataValidationException(List.of(ApiParameterError.parameterError(globalisationMessageCode,
 msg, fieldName)));
+    }
+
 }
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidatorTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidatorTest.java
index daa161095..cc8ee2117 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidatorTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/validator/DelinquencyActionParseAndValidatorTest.java
@@ -36,6 +36,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Optional;
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import 
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
@@ -44,6 +45,7 @@ import 
org.apache.fineract.portfolio.delinquency.domain.LoanDelinquencyAction;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.function.Executable;
@@ -78,7 +80,7 @@ class DelinquencyActionParseAndValidatorTest {
 
         LoanDelinquencyAction parsedDelinquencyAction = 
underTest.validateAndParseUpdate(command, loan,
                 List.of(loanDelinquencyAction(PAUSE, "05 September 2022", "15 
September 2022")), localDate("09 September 2022"));
-        Assertions.assertEquals(DelinquencyAction.RESUME, 
parsedDelinquencyAction.getAction());
+        Assertions.assertEquals(RESUME, parsedDelinquencyAction.getAction());
         Assertions.assertEquals(localDate("09 September 2022"), 
parsedDelinquencyAction.getStartDate());
         Assertions.assertNull(parsedDelinquencyAction.getEndDate());
     }
@@ -249,14 +251,40 @@ class DelinquencyActionParseAndValidatorTest {
                 () -> underTest.validateAndParseUpdate(command, loan, 
List.of(), localDate("09 September 2022")));
     }
 
+    @Test
+    public void testStartDateOrEndDateIsMissingForPause() {
+        Loan loan = Mockito.mock(Loan.class);
+        Mockito.when(loan.getStatus()).thenReturn(LoanStatus.ACTIVE);
+
+        assertPlatformValidationException("The parameter `startDate` is 
mandatory",
+                "loan-delinquency-action-pause-startDate-cannot-be-blank",
+                () -> 
underTest.validateAndParseUpdate(delinquencyAction("pause", null, "09 September 
2022"), loan, List.of(),
+                        localDate("09 September 2022")));
+
+        assertPlatformValidationException("The parameter `endDate` is 
mandatory", "loan-delinquency-action-pause-endDate-cannot-be-blank",
+                () -> 
underTest.validateAndParseUpdate(delinquencyAction("pause", "09 September 
2022", null), loan, List.of(),
+                        localDate("09 September 2022")));
+    }
+
+    @Test
+    public void testStartDateIsMissingForResume() {
+        Loan loan = Mockito.mock(Loan.class);
+        Mockito.when(loan.getStatus()).thenReturn(LoanStatus.ACTIVE);
+
+        assertPlatformValidationException("The parameter `startDate` is 
mandatory",
+                "loan-delinquency-action-resume-startDate-cannot-be-blank", () 
-> underTest
+                        .validateAndParseUpdate(delinquencyAction("resume", 
null, null), loan, List.of(), localDate("09 September 2022")));
+    }
+
     @NotNull
-    private JsonCommand delinquencyAction(String action, String startDate, 
String endDate) throws JsonProcessingException {
+    private JsonCommand delinquencyAction(@Nullable String action, @Nullable 
String startDate, @Nullable String endDate)
+            throws JsonProcessingException {
         Map<String, Object> map = new HashMap<>();
-        map.put(ACTION, action);
+        Optional.ofNullable(action).ifPresent(a -> map.put(ACTION, a));
         map.put(DATE_FORMAT, "dd MMMM yyyy");
         map.put(LOCALE, "en");
-        map.put(START_DATE, startDate);
-        map.put(END_DATE, endDate);
+        Optional.ofNullable(startDate).ifPresent(sd -> map.put(START_DATE, 
sd));
+        Optional.ofNullable(endDate).ifPresent(ed -> map.put(END_DATE, ed));
         return createJsonCommand(map);
     }
 

Reply via email to