From a3cba5d4beb83b32672f044d208e09c31b3e938f Mon Sep 17 00:00:00 2001
From: Serhii_Nosko <Serhii_Nosko@epam.com>
Date: Thu, 12 Sep 2024 12:34:45 +0300
Subject: [PATCH 1/2] MODORDERS-1183. Introduce new error code for missed
 affiliations

---
 .../java/org/folio/rest/core/RestClient.java  |  9 ++---
 .../rest/core/exceptions/ErrorCodes.java      |  1 +
 .../rest/core/exceptions/ExceptionUtil.java   | 20 ++++++++++
 .../core/exceptions/ExceptionUtilTest.java    | 38 +++++++++++++++++++
 4 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/folio/rest/core/RestClient.java b/src/main/java/org/folio/rest/core/RestClient.java
index d95ac0f29..9a71d8a4e 100644
--- a/src/main/java/org/folio/rest/core/RestClient.java
+++ b/src/main/java/org/folio/rest/core/RestClient.java
@@ -5,8 +5,7 @@
 import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
 import static org.folio.rest.RestConstants.ID;
 import static org.folio.rest.RestConstants.OKAPI_URL;
-import static org.folio.rest.core.exceptions.ExceptionUtil.isErrorsMessageJson;
-import static org.folio.rest.core.exceptions.ExceptionUtil.mapToErrors;
+import static org.folio.rest.core.exceptions.ExceptionUtil.getHttpException;
 
 import java.util.Map;
 
@@ -38,11 +37,9 @@ public class RestClient {
   private static final ErrorConverter ERROR_CONVERTER = ErrorConverter.createFullBody(
     result -> {
       String error = result.response().bodyAsString();
-      if (isErrorsMessageJson(error)) {
-        return new HttpException(result.response().statusCode(), mapToErrors(error));
-      }
-      return new HttpException(result.response().statusCode(), error);
+      return getHttpException(result.response().statusCode(), error);
     });
+
   private static final ResponsePredicate SUCCESS_RESPONSE_PREDICATE =
     ResponsePredicate.create(ResponsePredicate.SC_SUCCESS, ERROR_CONVERTER);
 
diff --git a/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java b/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java
index bff976338..fec1ec717 100644
--- a/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java
+++ b/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java
@@ -57,6 +57,7 @@ public enum ErrorCodes {
   USER_HAS_NO_APPROVAL_PERMISSIONS("userHasNoApprovalPermission", "User does not have permissions to approve order - operation is restricted"),
   USER_HAS_NO_UNOPEN_PERMISSIONS("userHasNoOrderUnopenPermission", "User does not have permissions to move order from open to pending - operation is restricted"),
   USER_HAS_NO_REOPEN_PERMISSIONS("userHasNoOrderReopenPermission", "User does not have permissions to move order from closed to open - operation is restricted"),
+  USER_HAS_MISSED_AFFILIATIONS("userHasMissedAffiliations", "User does not have all required affiliations to process - operation is restricted"),
   APPROVAL_REQUIRED_TO_OPEN("orderApprovalRequired","Approval is required to open order"),
   ISBN_NOT_VALID("invalidISBN", "ISBN value is invalid"),
   FUNDS_NOT_FOUND("fundsNotFound", "The fund records are not found"),
diff --git a/src/main/java/org/folio/rest/core/exceptions/ExceptionUtil.java b/src/main/java/org/folio/rest/core/exceptions/ExceptionUtil.java
index 5a3074df3..6c1db5969 100644
--- a/src/main/java/org/folio/rest/core/exceptions/ExceptionUtil.java
+++ b/src/main/java/org/folio/rest/core/exceptions/ExceptionUtil.java
@@ -2,6 +2,7 @@
 
 import static org.folio.rest.core.exceptions.ErrorCodes.GENERIC_ERROR_CODE;
 import static org.folio.rest.core.exceptions.ErrorCodes.POSTGRE_SQL_ERROR;
+import static org.folio.rest.core.exceptions.ErrorCodes.USER_HAS_MISSED_AFFILIATIONS;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -29,6 +30,7 @@ public class ExceptionUtil {
   public static final String NOT_PROVIDED = "Not Provided";
   private static final Pattern ERROR_PATTERN = Pattern.compile("(message).*(code).*(parameters)");
   private static final Pattern ERRORS_PATTERN = Pattern.compile("(errors).*(message).*(code).*(parameters)");
+  private static final Pattern AFFILIATION_MISSED_PATTERN = Pattern.compile("Invalid token: User with id ([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}) does not exist");
 
   private ExceptionUtil() {
   }
@@ -53,6 +55,16 @@ public static Errors convertToErrors(Throwable throwable) {
     return errors;
   }
 
+  public static HttpException getHttpException(int statusCode, String error) {
+    if (isAffiliationMissedError(error)) {
+      return new HttpException(statusCode, USER_HAS_MISSED_AFFILIATIONS);
+    }
+    if (isErrorsMessageJson(error)) {
+      return new HttpException(statusCode, mapToErrors(error));
+    }
+    return new HttpException(statusCode, error);
+  }
+
   public static boolean isErrorMessageJson(String errorMessage) {
     if (!StringUtils.isEmpty(errorMessage)) {
       Matcher matcher = ERROR_PATTERN.matcher(errorMessage);
@@ -74,6 +86,14 @@ public static boolean isErrorsMessageJson(String errorsMessage) {
     return false;
   }
 
+  public static boolean isAffiliationMissedError(String errorMessage) {
+    if (StringUtils.isEmpty(errorMessage)) {
+      return false;
+    }
+    Matcher matcher = AFFILIATION_MISSED_PATTERN.matcher(errorMessage);
+    return matcher.find();
+  }
+
   public static String errorAsString(Errors errors) {
     return Optional.ofNullable(JsonObject.mapFrom(errors).encode()).orElse(ErrorCodes.GENERIC_ERROR_CODE.getDescription());
   }
diff --git a/src/test/java/org/folio/rest/core/exceptions/ExceptionUtilTest.java b/src/test/java/org/folio/rest/core/exceptions/ExceptionUtilTest.java
index 11f443cf5..8ef0c5fa9 100644
--- a/src/test/java/org/folio/rest/core/exceptions/ExceptionUtilTest.java
+++ b/src/test/java/org/folio/rest/core/exceptions/ExceptionUtilTest.java
@@ -3,6 +3,8 @@
 import static org.folio.rest.core.exceptions.ErrorCodes.GENERIC_ERROR_CODE;
 import static org.folio.rest.core.exceptions.ErrorCodes.POSTGRE_SQL_ERROR;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.folio.rest.jaxrs.model.Errors;
 import org.junit.jupiter.api.Assertions;
@@ -12,6 +14,15 @@
 
 public class ExceptionUtilTest {
 
+  private static final String INVALID_TOKEN_ERROR = """
+    {
+      "errors" : [ {
+        "message" : "Invalid token: User with id 858cbba3-6fd0-4430-9011-9939574677d8 does not exist",
+        "code" : "genericError",
+        "parameters" : [ ]
+      } ],
+      "total_records" : 1
+    }""";
 
   @Test
   void testIfBadRequestMessageNotNull() {
@@ -50,4 +61,31 @@ void testIsExceptionMessageIsJSON() {
     boolean act = ExceptionUtil.isErrorMessageJson(errorMsg);
     Assertions.assertTrue(act);
   }
+
+  @Test
+  void testGetHttpExceptionMissedAffiliationError() {
+    HttpException httpException = ExceptionUtil.getHttpException(401, INVALID_TOKEN_ERROR);
+    assertEquals(ErrorCodes.USER_HAS_MISSED_AFFILIATIONS.toError(), httpException.getError());
+  }
+
+  @Test
+  void testGetHttpExceptionOtherError() {
+    HttpException httpException = ExceptionUtil.getHttpException(500, "Module failure");
+    assertEquals(500, httpException.getCode());
+    assertEquals(GENERIC_ERROR_CODE.getCode(), httpException.getError().getCode());
+    assertEquals("Module failure", httpException.getError().getMessage());
+  }
+
+  @Test
+  void testIsAffiliationMissedTrue() {
+    boolean act = ExceptionUtil.isAffiliationMissedError(INVALID_TOKEN_ERROR);
+    assertTrue(act);
+  }
+
+  @Test
+  void testIsAffiliationMissedFalse() {
+    String errorMsg = "{\"message\":\"Test\",\"code\":\"Test\",\"parameters\":[]}";
+    boolean act = ExceptionUtil.isAffiliationMissedError(errorMsg);
+    assertFalse(act);
+  }
 }

From 5353f2d9d243fddcfed1323c097f35e8072eaa40 Mon Sep 17 00:00:00 2001
From: Serhii_Nosko <Serhii_Nosko@epam.com>
Date: Wed, 4 Dec 2024 17:43:08 +0200
Subject: [PATCH 2/2] MODORDERS-1218/MODORDERS-1219. Fix async issue with
 changing instance connection

---
 .../orders/lines/update/OrderLinePatchOperationService.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/folio/service/orders/lines/update/OrderLinePatchOperationService.java b/src/main/java/org/folio/service/orders/lines/update/OrderLinePatchOperationService.java
index 57c63aa36..940d9c0bb 100644
--- a/src/main/java/org/folio/service/orders/lines/update/OrderLinePatchOperationService.java
+++ b/src/main/java/org/folio/service/orders/lines/update/OrderLinePatchOperationService.java
@@ -131,7 +131,7 @@ private Future<Void> updateInventoryInstanceInformation(PatchOrderLineRequest re
 
     String newInstanceId = request.getReplaceInstanceRef().getNewInstanceId();
     purchaseOrderLineService.getOrderLineById(lineId, requestContext)
-      .map(poLine -> {
+      .compose(poLine -> {
         RequestEntry requestEntry = new RequestEntry(INVENTORY_LOOKUP_ENDPOINTS.get(INSTANCE_RECORDS_BY_ID_ENDPOINT)).withId(newInstanceId);
         return restClient.getAsJsonObject(requestEntry, requestContext)
           .compose(instanceRecord -> updatePoLineWithInstanceRecordInfo(instanceRecord, poLine, requestContext))