Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MODORDERS-1143] Paying an invoice reopens the order #1025

Merged
merged 12 commits into from
Sep 23, 2024
Merged
2 changes: 1 addition & 1 deletion src/main/java/org/folio/helper/PurchaseOrderHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
473 changes: 201 additions & 272 deletions src/main/java/org/folio/helper/PurchaseOrderLineHelper.java

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions src/main/java/org/folio/models/PoLineInvoiceLineHolder.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@
import org.folio.rest.jaxrs.model.CompositePoLine;
import org.folio.rest.jaxrs.model.PoLine;

import io.vertx.core.json.JsonObject;


public class PoLineInvoiceLineHolder {
private CompositePoLine poLineFromRequest;
private PoLine poLineFromStorage;

private final CompositePoLine poLineFromRequest;
private final PoLine poLineFromStorage;
private List<InvoiceLine> invoiceLines;
private List<InvoiceLine> openOrReviewedInvoiceLines;

public PoLineInvoiceLineHolder(CompositePoLine poLineFromRequest, JsonObject poLineFromStorage) {
public PoLineInvoiceLineHolder(CompositePoLine poLineFromRequest, PoLine poLineFromStorage) {
this.poLineFromRequest = poLineFromRequest;
this.poLineFromStorage = poLineFromStorage.mapTo(PoLine.class);
this.poLineFromStorage = poLineFromStorage;
this.invoiceLines = new ArrayList<>();
this.openOrReviewedInvoiceLines = new ArrayList<>();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -108,7 +108,7 @@ protected JsonArray messageAsJsonArray(String rootElement, Message<JsonObject> m
}

protected CompositePurchaseOrder convert(PurchaseOrder po, List<PoLine> 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);
}

Expand Down
60 changes: 5 additions & 55 deletions src/main/java/org/folio/orders/utils/HelperUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,12 @@
import org.folio.rest.core.exceptions.NoInventoryRecordException;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.jaxrs.model.Alert;
import org.folio.rest.jaxrs.model.CloseReason;
import org.folio.rest.jaxrs.model.CompositePoLine;
import org.folio.rest.jaxrs.model.CompositePurchaseOrder;
import org.folio.rest.jaxrs.model.Cost;
import org.folio.rest.jaxrs.model.Location;
import org.folio.rest.jaxrs.model.Piece;
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 org.folio.rest.jaxrs.model.ReportingCode;
import org.folio.rest.jaxrs.model.Title;
Expand Down Expand Up @@ -67,10 +64,6 @@
import static org.folio.rest.RestConstants.EN;
import static org.folio.rest.core.exceptions.ErrorCodes.MULTIPLE_NONPACKAGE_TITLES;
import static org.folio.rest.core.exceptions.ErrorCodes.TITLE_NOT_FOUND;
import static org.folio.rest.jaxrs.model.PoLine.PaymentStatus.FULLY_PAID;
import static org.folio.rest.jaxrs.model.PoLine.PaymentStatus.PAYMENT_NOT_REQUIRED;
import static org.folio.rest.jaxrs.model.PoLine.ReceiptStatus.FULLY_RECEIVED;
import static org.folio.rest.jaxrs.model.PoLine.ReceiptStatus.RECEIPT_NOT_REQUIRED;

public class HelperUtils {

Expand Down Expand Up @@ -393,59 +386,16 @@ public static CompositePurchaseOrder convertToCompositePurchaseOrder(JsonObject
return poJson.mapTo(CompositePurchaseOrder.class);
}

public static boolean changeOrderStatus(PurchaseOrder purchaseOrder, List<PoLine> 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<String> values, String fieldName, boolean strictMatch) {

String prefix = fieldName + (strictMatch ? "==(\"" : "=(\"");
return StreamEx.of(values).joining("\" or \"", prefix, "\")");
}

private static boolean toBeClosed(PurchaseOrder purchaseOrder, List<PoLine> poLines) {
return purchaseOrder.getWorkflowStatus() == PurchaseOrder.WorkflowStatus.OPEN
&& poLines.stream().allMatch(HelperUtils::isCompletedPoLine);
}

private static boolean toBeCancelled(PurchaseOrder purchaseOrder, List<PoLine> 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<PoLine> 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) {
azizbekxm marked this conversation as resolved.
Show resolved Hide resolved
JsonObject pol = JsonObject.mapFrom(poLine);
pol.remove(ALERTS);
pol.remove(REPORTING_CODES);
return pol.mapTo(CompositePoLine.class);
}

public static PoLine convertToPoLine(CompositePoLine compPoLine) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.folio.rest.jaxrs.model.PoLine;

import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;

public class PoLineInvoiceLineHolderBuilder {
private static final List<InvoiceLine.InvoiceLineStatus> EDITABLE_STATUSES = List.of(InvoiceLine.InvoiceLineStatus.OPEN, InvoiceLine.InvoiceLineStatus.REVIEWED);
Expand All @@ -22,7 +21,7 @@ public PoLineInvoiceLineHolderBuilder(InvoiceLineService invoiceLineService) {
}

public Future<PoLineInvoiceLineHolder> buildHolder(CompositePoLine compOrderLine, PoLine poLineFromStorage, RequestContext requestContext) {
PoLineInvoiceLineHolder holder = new PoLineInvoiceLineHolder(compOrderLine, JsonObject.mapFrom(poLineFromStorage));
var holder = new PoLineInvoiceLineHolder(compOrderLine, poLineFromStorage);
return invoiceLineService.getInvoiceLinesByOrderLineId(compOrderLine.getId(), requestContext)
.onSuccess(holder::withInvoiceLines)
.compose(aResult -> CollectionUtils.isEmpty(holder.getInvoiceLines()) ? Future.succeededFuture(holder) :
Expand Down
99 changes: 99 additions & 0 deletions src/main/java/org/folio/service/orders/utils/StatusUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.folio.service.orders.utils;

import org.apache.commons.lang3.StringUtils;
import org.folio.rest.jaxrs.model.CloseReason;
import org.folio.rest.jaxrs.model.CompositePoLine;
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.orders.utils.HelperUtils.REASON_CANCELLED;
import static org.folio.orders.utils.HelperUtils.REASON_COMPLETE;

public class StatusUtils {

private static final Set<String> resolutionPaymentStatus = Set.of(PaymentStatus.CANCELLED.value(), PaymentStatus.PAYMENT_NOT_REQUIRED.value(), PaymentStatus.FULLY_PAID.value());
private static final Set<String> resolutionReceiptStatus = Set.of(ReceiptStatus.CANCELLED.value(), ReceiptStatus.RECEIPT_NOT_REQUIRED.value(), ReceiptStatus.FULLY_RECEIVED.value());

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());
}

public static boolean areAllPoLinesCanceled(List<PoLine> poLines) {
return poLines.stream().allMatch(StatusUtils::isStatusCanceledPoLine);
}

public static boolean changeOrderStatus(PurchaseOrder purchaseOrder, List<PoLine> 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<PoLine> poLines) {
return isOrderOpen(purchaseOrder)
&& poLines.stream().allMatch(StatusUtils::isCompletedPoLine);
}

private static boolean toBeCancelled(PurchaseOrder purchaseOrder, List<PoLine> poLines) {
return isOrderOpen(purchaseOrder)
&& poLines.stream().allMatch(StatusUtils::isCancelledPoLine);
}

private static boolean toBeReopened(PurchaseOrder purchaseOrder, List<PoLine> poLines) {
return isOrderClosed(purchaseOrder)
&& poLines.stream().anyMatch(StatusUtils::isNonResolutionPoLine);
}

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() {}

}
3 changes: 2 additions & 1 deletion src/test/java/org/folio/orders/utils/HelperUtilsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -92,7 +93,7 @@ void testOrderStatusToBeCancelled() {

List<PoLine> 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));
}
Expand Down