From 5081d028dd6cc29ac65c9fd1cf4ab0ff2968383a Mon Sep 17 00:00:00 2001 From: saba_zedginidze Date: Fri, 20 Sep 2024 13:59:38 +0400 Subject: [PATCH] [MODORDERS-1174] Simplify status change logic --- .../org/folio/helper/PurchaseOrderHelper.java | 2 +- .../folio/helper/PurchaseOrderLineHelper.java | 19 ++- .../handlers/AbstractOrderStatusHandler.java | 6 +- .../org/folio/orders/utils/HelperUtils.java | 50 -------- .../service/orders/utils/StatusUtils.java | 115 ++++++++++++------ .../folio/orders/utils/HelperUtilsTest.java | 3 +- 6 files changed, 103 insertions(+), 92 deletions(-) diff --git a/src/main/java/org/folio/helper/PurchaseOrderHelper.java b/src/main/java/org/folio/helper/PurchaseOrderHelper.java index 168f67ad3..62d183862 100644 --- a/src/main/java/org/folio/helper/PurchaseOrderHelper.java +++ b/src/main/java/org/folio/helper/PurchaseOrderHelper.java @@ -6,7 +6,6 @@ import static org.folio.orders.utils.HelperUtils.ORDER_CONFIG_MODULE_NAME; import static org.folio.orders.utils.HelperUtils.REASON_CANCELLED; import static org.folio.orders.utils.HelperUtils.WORKFLOW_STATUS; -import static org.folio.orders.utils.HelperUtils.changeOrderStatus; import static org.folio.orders.utils.HelperUtils.collectResultsOnSuccess; import static org.folio.orders.utils.HelperUtils.convertToCompositePurchaseOrder; import static org.folio.orders.utils.OrderStatusTransitionUtil.isOrderClosing; @@ -24,6 +23,7 @@ import static org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus.OPEN; import static org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus.PENDING; import static org.folio.service.UserService.getCurrentUserId; +import static org.folio.service.orders.utils.StatusUtils.changeOrderStatus; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java b/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java index 5083c334e..d8b1353e5 100644 --- a/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java +++ b/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java @@ -3,6 +3,8 @@ import static org.apache.commons.collections4.CollectionUtils.isEqualCollection; import static org.apache.commons.collections4.CollectionUtils.isNotEmpty; import static org.apache.commons.collections4.CollectionUtils.isEmpty; +import static org.folio.helper.BaseHelper.EVENT_PAYLOAD; +import static org.folio.helper.BaseHelper.ORDER_ID; import static org.folio.orders.utils.HelperUtils.calculateEstimatedPrice; import static org.folio.orders.utils.HelperUtils.convertToCompositePoLine; import static org.folio.orders.utils.HelperUtils.convertToPoLine; @@ -20,9 +22,8 @@ import static org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus.OPEN; import static org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus.PENDING; import static org.folio.service.orders.utils.StatusUtils.areAllPoLinesCanceled; -import static org.folio.service.orders.utils.StatusUtils.isCompositePoLineStatusCanceled; +import static org.folio.service.orders.utils.StatusUtils.isStatusCanceledCompositePoLine; import static org.folio.service.orders.utils.StatusUtils.isStatusChanged; -import static org.folio.service.orders.utils.StatusUtils.updateOrderStatusIfNeeded; import java.util.ArrayList; import java.util.Collections; @@ -37,6 +38,7 @@ import javax.ws.rs.core.Response; +import io.vertx.core.json.JsonArray; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; @@ -44,6 +46,7 @@ import org.folio.models.ItemStatus; import org.folio.models.PoLineInvoiceLineHolder; import org.folio.okapi.common.GenericCompositeFuture; +import org.folio.orders.events.handlers.MessageAddress; import org.folio.orders.utils.HelperUtils; import org.folio.orders.utils.POLineProtectedFieldsUtil; import org.folio.orders.utils.PoLineCommonUtil; @@ -672,7 +675,7 @@ private Future processPoLineEncumbrances(CompositePurchaseOrder compOrder, } private Future updateInventoryItemStatus(CompositePoLine compOrderLine, PoLine lineFromStorage, RequestContext requestContext) { - if (!isStatusChanged(compOrderLine, lineFromStorage) || !isCompositePoLineStatusCanceled(compOrderLine)) { + if (!isStatusChanged(compOrderLine, lineFromStorage) || !isStatusCanceledCompositePoLine(compOrderLine)) { return Future.succeededFuture(); } return purchaseOrderLineService.getPoLinesByOrderId(compOrderLine.getPurchaseOrderId(), requestContext) @@ -686,6 +689,16 @@ private Future updateInventoryItemStatus(CompositePoLine compOrderLine, Po }); } + public Future updateOrderStatusIfNeeded(CompositePurchaseOrder compositePurchaseOrder, CompositePoLine compOrderLine, + PoLine poLineFromStorage, RequestContext requestContext) { + // See MODORDERS-218 + if (isStatusChanged(compOrderLine, poLineFromStorage)) { + var updateOrderMessage = JsonObject.of(EVENT_PAYLOAD, JsonArray.of(JsonObject.of(ORDER_ID, compOrderLine.getPurchaseOrderId()))); + HelperUtils.sendEvent(MessageAddress.RECEIVE_ORDER_STATUS_UPDATE, updateOrderMessage, requestContext); + } + return Future.succeededFuture(); + } + private boolean isEncumbranceUpdateNeeded(CompositePurchaseOrder compOrder, CompositePoLine compositePoLine, PoLine storagePoLine) { List requestFundDistros = compositePoLine.getFundDistribution(); List storageFundDistros = storagePoLine.getFundDistribution(); diff --git a/src/main/java/org/folio/orders/events/handlers/AbstractOrderStatusHandler.java b/src/main/java/org/folio/orders/events/handlers/AbstractOrderStatusHandler.java index b4ed22894..cb1c48350 100644 --- a/src/main/java/org/folio/orders/events/handlers/AbstractOrderStatusHandler.java +++ b/src/main/java/org/folio/orders/events/handlers/AbstractOrderStatusHandler.java @@ -1,7 +1,7 @@ package org.folio.orders.events.handlers; -import static org.folio.orders.utils.HelperUtils.changeOrderStatus; import static org.folio.orders.utils.HelperUtils.getOkapiHeaders; +import static org.folio.service.orders.utils.StatusUtils.changeOrderStatus; import java.util.ArrayList; import java.util.List; @@ -10,8 +10,8 @@ import org.folio.completablefuture.AsyncUtil; import org.folio.helper.BaseHelper; import org.folio.helper.PurchaseOrderHelper; +import org.folio.orders.utils.HelperUtils; import org.folio.rest.core.models.RequestContext; -import org.folio.rest.jaxrs.model.CompositePoLine; import org.folio.rest.jaxrs.model.CompositePurchaseOrder; import org.folio.rest.jaxrs.model.PoLine; import org.folio.rest.jaxrs.model.PurchaseOrder; @@ -108,7 +108,7 @@ protected JsonArray messageAsJsonArray(String rootElement, Message m } protected CompositePurchaseOrder convert(PurchaseOrder po, List poLines) { - var lines = poLines.stream().map(line -> JsonObject.mapFrom(line).mapTo(CompositePoLine.class)).toList(); + var lines = poLines.stream().map(HelperUtils::convertToCompositePoLine).toList(); return JsonObject.mapFrom(po).mapTo(CompositePurchaseOrder.class).withCompositePoLines(lines); } diff --git a/src/main/java/org/folio/orders/utils/HelperUtils.java b/src/main/java/org/folio/orders/utils/HelperUtils.java index 872d085b6..e470c725f 100644 --- a/src/main/java/org/folio/orders/utils/HelperUtils.java +++ b/src/main/java/org/folio/orders/utils/HelperUtils.java @@ -393,61 +393,11 @@ public static CompositePurchaseOrder convertToCompositePurchaseOrder(JsonObject return poJson.mapTo(CompositePurchaseOrder.class); } - public static boolean changeOrderStatus(PurchaseOrder purchaseOrder, List poLines) { - if (toBeCancelled(purchaseOrder, poLines)) { - purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.CLOSED); - purchaseOrder.setCloseReason(new CloseReason().withReason(REASON_CANCELLED)); - return true; - } - - if (toBeClosed(purchaseOrder, poLines)) { - purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.CLOSED); - purchaseOrder.setCloseReason(new CloseReason().withReason(REASON_COMPLETE)); - return true; - } - - if (toBeReopened(purchaseOrder, poLines)) { - purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.OPEN); - return true; - } - - return false; - } - public static String convertTagListToCqlQuery(Collection values, String fieldName, boolean strictMatch) { - String prefix = fieldName + (strictMatch ? "==(\"" : "=(\""); return StreamEx.of(values).joining("\" or \"", prefix, "\")"); } - private static boolean toBeClosed(PurchaseOrder purchaseOrder, List poLines) { - return purchaseOrder.getWorkflowStatus() == PurchaseOrder.WorkflowStatus.OPEN - && poLines.stream().allMatch(HelperUtils::isCompletedPoLine); - } - - private static boolean toBeCancelled(PurchaseOrder purchaseOrder, List poLines) { - return purchaseOrder.getWorkflowStatus() == PurchaseOrder.WorkflowStatus.OPEN - && poLines.stream().allMatch(HelperUtils::isCancelledPoLine); - } - - private static boolean isCancelledPoLine(PoLine line) { - PoLine.PaymentStatus paymentStatus = line.getPaymentStatus(); - PoLine.ReceiptStatus receiptStatus = line.getReceiptStatus(); - return paymentStatus == PaymentStatus.CANCELLED && receiptStatus == ReceiptStatus.CANCELLED; - } - - private static boolean toBeReopened(PurchaseOrder purchaseOrder, List poLines) { - return purchaseOrder.getWorkflowStatus() == PurchaseOrder.WorkflowStatus.CLOSED - && poLines.stream().anyMatch(line -> !isCompletedPoLine(line)); - } - - private static boolean isCompletedPoLine(PoLine line) { - PoLine.PaymentStatus paymentStatus = line.getPaymentStatus(); - PoLine.ReceiptStatus receiptStatus = line.getReceiptStatus(); - return (paymentStatus == PAYMENT_NOT_REQUIRED || paymentStatus == FULLY_PAID || paymentStatus == PaymentStatus.CANCELLED) - && (receiptStatus == FULLY_RECEIVED || receiptStatus == RECEIPT_NOT_REQUIRED || receiptStatus == ReceiptStatus.CANCELLED); - } - public static CompositePoLine convertToCompositePoLine(PoLine poLine) { JsonObject pol = JsonObject.mapFrom(poLine); pol.remove(ALERTS); diff --git a/src/main/java/org/folio/service/orders/utils/StatusUtils.java b/src/main/java/org/folio/service/orders/utils/StatusUtils.java index d5ec49ead..a97aee9f7 100644 --- a/src/main/java/org/folio/service/orders/utils/StatusUtils.java +++ b/src/main/java/org/folio/service/orders/utils/StatusUtils.java @@ -1,62 +1,109 @@ package org.folio.service.orders.utils; -import io.vertx.core.Future; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; import org.apache.commons.lang3.StringUtils; -import org.folio.orders.events.handlers.MessageAddress; -import org.folio.orders.utils.HelperUtils; -import org.folio.rest.core.models.RequestContext; +import org.folio.rest.jaxrs.model.CloseReason; import org.folio.rest.jaxrs.model.CompositePoLine; -import org.folio.rest.jaxrs.model.CompositePoLine.PaymentStatus; -import org.folio.rest.jaxrs.model.CompositePoLine.ReceiptStatus; -import org.folio.rest.jaxrs.model.CompositePurchaseOrder; import org.folio.rest.jaxrs.model.PoLine; +import org.folio.rest.jaxrs.model.PoLine.PaymentStatus; +import org.folio.rest.jaxrs.model.PoLine.ReceiptStatus; +import org.folio.rest.jaxrs.model.PurchaseOrder; import java.util.List; import java.util.Set; -import static org.folio.helper.BaseHelper.EVENT_PAYLOAD; -import static org.folio.helper.BaseHelper.ORDER_ID; +import static org.folio.orders.utils.HelperUtils.REASON_CANCELLED; +import static org.folio.orders.utils.HelperUtils.REASON_COMPLETE; public class StatusUtils { - private static final Set resolutionPaymentStatus = Set.of(PaymentStatus.CANCELLED, PaymentStatus.FULLY_PAID, PaymentStatus.PAYMENT_NOT_REQUIRED); - private static final Set resolutionReceiptStatus = Set.of(ReceiptStatus.CANCELLED, ReceiptStatus.FULLY_RECEIVED, ReceiptStatus.RECEIPT_NOT_REQUIRED); + private static final Set resolutionPaymentStatus = Set.of(PaymentStatus.CANCELLED.value(), PaymentStatus.PAYMENT_NOT_REQUIRED.value(), PaymentStatus.FULLY_PAID.value()); + private static final Set resolutionReceiptStatus = Set.of(ReceiptStatus.CANCELLED.value(), ReceiptStatus.RECEIPT_NOT_REQUIRED.value(), ReceiptStatus.FULLY_RECEIVED.value()); - public static Future updateOrderStatusIfNeeded(CompositePurchaseOrder compositePurchaseOrder, CompositePoLine compOrderLine, - PoLine poLineFromStorage, RequestContext requestContext) { - // See MODORDERS-218 - if (isStatusChanged(compOrderLine, poLineFromStorage) && shouldUpdateOrderStatus(compositePurchaseOrder, compOrderLine)) { - var updateOrderMessage = JsonObject.of(EVENT_PAYLOAD, JsonArray.of(JsonObject.of(ORDER_ID, compOrderLine.getPurchaseOrderId()))); - HelperUtils.sendEvent(MessageAddress.RECEIVE_ORDER_STATUS_UPDATE, updateOrderMessage, requestContext); - } - return Future.succeededFuture(); - } + +// private static boolean isCompositeOrderClosed(CompositePurchaseOrder order) { +// return order.getWorkflowStatus() == CompositePurchaseOrder.WorkflowStatus.CLOSED; +// } public static boolean isStatusChanged(CompositePoLine compOrderLine, PoLine lineFromStorage) { return !StringUtils.equals(lineFromStorage.getReceiptStatus().value(), compOrderLine.getReceiptStatus().value()) || !StringUtils.equals(lineFromStorage.getPaymentStatus().value(), compOrderLine.getPaymentStatus().value()); } - private static boolean shouldUpdateOrderStatus(CompositePurchaseOrder compositePurchaseOrder, CompositePoLine compOrderLine) { - return compositePurchaseOrder.getWorkflowStatus() != CompositePurchaseOrder.WorkflowStatus.CLOSED - && !resolutionPaymentStatus.contains(compOrderLine.getPaymentStatus()) - && !resolutionReceiptStatus.contains(compOrderLine.getReceiptStatus()); - } +// public static boolean shouldUpdateOrderStatus(CompositePurchaseOrder compositePurchaseOrder, CompositePoLine compOrderLine, PoLine lineFromStorage) { +// return !isCompositeOrderClosed(compositePurchaseOrder) && isStatusChanged(compOrderLine, lineFromStorage) +// || isCompositeOrderClosed(compositePurchaseOrder) && isNonResolutionPoLine(compOrderLine); +// } public static boolean areAllPoLinesCanceled(List poLines) { - return poLines.stream().allMatch(StatusUtils::isPoLineStatusCanceled); + return poLines.stream().allMatch(StatusUtils::isStatusCanceledPoLine); + } + + public static boolean changeOrderStatus(PurchaseOrder purchaseOrder, List poLines) { + if (toBeCancelled(purchaseOrder, poLines)) { + purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.CLOSED); + purchaseOrder.setCloseReason(new CloseReason().withReason(REASON_CANCELLED)); + return true; + } + if (toBeClosed(purchaseOrder, poLines)) { + purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.CLOSED); + purchaseOrder.setCloseReason(new CloseReason().withReason(REASON_COMPLETE)); + return true; + } + if (toBeReopened(purchaseOrder, poLines)) { + purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.OPEN); + return true; + } + return false; + } + + private static boolean toBeClosed(PurchaseOrder purchaseOrder, List poLines) { + return isOrderOpen(purchaseOrder) + && poLines.stream().allMatch(StatusUtils::isCompletedPoLine); + } + + private static boolean toBeCancelled(PurchaseOrder purchaseOrder, List poLines) { + return isOrderOpen(purchaseOrder) + && poLines.stream().allMatch(StatusUtils::isCancelledPoLine); } - private static boolean isPoLineStatusCanceled(PoLine poLine) { - return PoLine.PaymentStatus.CANCELLED.equals(poLine.getPaymentStatus()) || - PoLine.ReceiptStatus.CANCELLED.equals(poLine.getReceiptStatus()); + private static boolean toBeReopened(PurchaseOrder purchaseOrder, List poLines) { + return isOrderClosed(purchaseOrder) + && poLines.stream().anyMatch(StatusUtils::isNonResolutionPoLine); } - public static boolean isCompositePoLineStatusCanceled(CompositePoLine compOrderLine) { - return CompositePoLine.ReceiptStatus.CANCELLED.equals(compOrderLine.getReceiptStatus()) || - CompositePoLine.PaymentStatus.CANCELLED.equals(compOrderLine.getPaymentStatus()); + private static boolean isCompletedPoLine(PoLine line) { + return resolutionPaymentStatus.contains(line.getPaymentStatus().value()) + && resolutionReceiptStatus.contains(line.getReceiptStatus().value()); } + private static boolean isNonResolutionPoLine(PoLine line) { + return !resolutionPaymentStatus.contains(line.getPaymentStatus().value()) + && !resolutionReceiptStatus.contains(line.getReceiptStatus().value()); + } + + private static boolean isCancelledPoLine(PoLine poLine) { + return poLine.getPaymentStatus() == PoLine.PaymentStatus.CANCELLED + && poLine.getReceiptStatus() == PoLine.ReceiptStatus.CANCELLED; + } + + private static boolean isStatusCanceledPoLine(PoLine poLine) { + return poLine.getPaymentStatus() == PoLine.PaymentStatus.CANCELLED + || poLine.getReceiptStatus() == PoLine.ReceiptStatus.CANCELLED; + } + + public static boolean isStatusCanceledCompositePoLine(CompositePoLine compOrderLine) { + return compOrderLine.getReceiptStatus() == CompositePoLine.ReceiptStatus.CANCELLED + || compOrderLine.getPaymentStatus() == CompositePoLine.PaymentStatus.CANCELLED; + } + + private static boolean isOrderOpen(PurchaseOrder order) { + return order.getWorkflowStatus() == PurchaseOrder.WorkflowStatus.OPEN; + } + + private static boolean isOrderClosed(PurchaseOrder order) { + return order.getWorkflowStatus() == PurchaseOrder.WorkflowStatus.CLOSED; + } + + private StatusUtils() {} + } diff --git a/src/test/java/org/folio/orders/utils/HelperUtilsTest.java b/src/test/java/org/folio/orders/utils/HelperUtilsTest.java index 2ab275f8e..b050517bd 100644 --- a/src/test/java/org/folio/orders/utils/HelperUtilsTest.java +++ b/src/test/java/org/folio/orders/utils/HelperUtilsTest.java @@ -5,6 +5,7 @@ import org.folio.rest.jaxrs.model.CloseReason; import org.folio.rest.jaxrs.model.PoLine; import org.folio.rest.jaxrs.model.PurchaseOrder; +import org.folio.service.orders.utils.StatusUtils; import org.junit.jupiter.api.Test; import javax.money.convert.ConversionQuery; @@ -92,7 +93,7 @@ void testOrderStatusToBeCancelled() { List poLines = List.of(firstPoLine, secondPoLine); - assertTrue(HelperUtils.changeOrderStatus(purchaseOrder, poLines)); + assertTrue(StatusUtils.changeOrderStatus(purchaseOrder, poLines)); assertEquals(purchaseOrder.getWorkflowStatus(), PurchaseOrder.WorkflowStatus.CLOSED); assertEquals(purchaseOrder.getCloseReason(), new CloseReason().withReason(REASON_CANCELLED)); }