diff --git a/src/main/java/org/folio/helper/CheckinReceivePiecesHelper.java b/src/main/java/org/folio/helper/CheckinReceivePiecesHelper.java index 0429f3f9d..a2f216236 100644 --- a/src/main/java/org/folio/helper/CheckinReceivePiecesHelper.java +++ b/src/main/java/org/folio/helper/CheckinReceivePiecesHelper.java @@ -399,7 +399,7 @@ private PoLine updateRelatedPoLineDetails(PoLine poLine, } short updatedLocations = 0; - CompositePoLine compositePoLine = PoLineCommonUtil.convertToCompositePoLine(poLine); + var compositePoLine = PoLineCommonUtil.convertToCompositePoLine(poLine); for (Piece pieceToUpdate : successfullyProcessed) { Optional relatedStoragePiece = piecesFromStorage.stream() .filter(piece -> piece.getId().equals(pieceToUpdate.getId())) @@ -415,7 +415,7 @@ private PoLine updateRelatedPoLineDetails(PoLine poLine, updatedLocations++; } - return updatedLocations > 0 ? HelperUtils.convertToPoLine(compositePoLine) : poLine; + return updatedLocations > 0 ? PoLineCommonUtil.convertToPoLine(compositePoLine) : poLine; } /** diff --git a/src/main/java/org/folio/helper/PurchaseOrderHelper.java b/src/main/java/org/folio/helper/PurchaseOrderHelper.java index 168f67ad3..3c39c92cf 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; @@ -282,7 +282,7 @@ public Future handleFinalOrderStatus(CompositePurchaseOrder compPO, String } else { Future.succeededFuture() .map(v -> { - List poLines = HelperUtils.convertToPoLines(compPO.getCompositePoLines()); + List poLines = PoLineCommonUtil.convertToPoLines(compPO.getCompositePoLines()); if (initialOrdersStatus.equals(compPO.getWorkflowStatus().value())) changeOrderStatus(purchaseOrder, poLines); promise.complete(poLines); diff --git a/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java b/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java index 7dcc2cafc..82a288865 100644 --- a/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java +++ b/src/main/java/org/folio/helper/PurchaseOrderLineHelper.java @@ -1,13 +1,14 @@ package org.folio.helper; -import static io.vertx.core.json.JsonObject.mapFrom; import static org.apache.commons.collections4.CollectionUtils.isEqualCollection; import static org.apache.commons.collections4.CollectionUtils.isNotEmpty; -import static org.apache.commons.lang3.StringUtils.isEmpty; +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.getPoLineLimit; +import static org.folio.orders.utils.PoLineCommonUtil.convertToCompositePoLine; +import static org.folio.orders.utils.PoLineCommonUtil.convertToPoLine; import static org.folio.orders.utils.PoLineCommonUtil.verifyProtectedFieldsChanged; import static org.folio.orders.utils.ProtectedOperationType.DELETE; import static org.folio.orders.utils.ProtectedOperationType.UPDATE; @@ -20,6 +21,9 @@ import static org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus.CLOSED; 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.isStatusCanceledCompositePoLine; +import static org.folio.service.orders.utils.StatusUtils.isStatusChanged; import java.util.ArrayList; import java.util.Collections; @@ -28,13 +32,13 @@ import java.util.Optional; import java.util.UUID; import java.util.Objects; -import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; 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; @@ -67,7 +71,6 @@ import org.folio.rest.jaxrs.model.PoLine; import org.folio.rest.jaxrs.model.PoLineCollection; import org.folio.rest.jaxrs.model.ReportingCode; -import org.folio.rest.jaxrs.model.Title; import org.folio.service.ProtectionService; import org.folio.service.finance.expenceclass.ExpenseClassValidationService; import org.folio.service.finance.transaction.EncumbranceService; @@ -85,9 +88,7 @@ import org.folio.service.titles.TitlesService; import io.vertx.core.Future; -import io.vertx.core.Promise; import io.vertx.core.http.HttpMethod; -import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; public class PurchaseOrderLineHelper { @@ -96,12 +97,11 @@ public class PurchaseOrderLineHelper { private static final Pattern PO_LINE_NUMBER_PATTERN = Pattern.compile("([a-zA-Z0-9]{1,22}-)(\\d{1,3})"); private static final String PURCHASE_ORDER_ID = "purchaseOrderId"; - private static final String SEARCH_LOCATION_IDS = "searchLocationIds"; private static final String CREATE_INVENTORY = "createInventory"; public static final String ERESOURCE = "eresource"; public static final String PHYSICAL = "physical"; private static final String OTHER = "other"; - private static final String QUERY_BY_PO_LINE_ID = "poLineId=="; + private static final String QUERY_BY_PO_LINE_ID = "poLineId==%s"; private final InventoryItemStatusSyncService itemStatusSyncService; private final InventoryInstanceManager inventoryInstanceManager; @@ -177,24 +177,23 @@ public Future getOrderLines(int limit, int offset, String quer */ public Future createPoLine(CompositePoLine compPOL, JsonObject tenantConfig, RequestContext requestContext) { // Validate PO Line content and retrieve order only if this operation is allowed - JsonObject cachedTenantConfiguration= new JsonObject(); + JsonObject cachedTenantConfiguration = new JsonObject(); cachedTenantConfiguration.mergeIn(tenantConfig, true); - return setTenantDefaultCreateInventoryValues(compPOL, cachedTenantConfiguration) + return setTenantDefaultCreateInventoryValues(compPOL, cachedTenantConfiguration) .compose(v -> validateNewPoLine(compPOL, cachedTenantConfiguration, requestContext)) .compose(validationErrors -> { - if (CollectionUtils.isEmpty(validationErrors)) { + if (isEmpty(validationErrors)) { return getCompositePurchaseOrder(compPOL.getPurchaseOrderId(), requestContext) // The PO Line can be created only for order in Pending state .map(this::validateOrderState) .compose(po -> protectionService.isOperationRestricted(po.getAcqUnitIds(), ProtectedOperationType.CREATE, requestContext) - .compose(v -> createShadowInstanceIfNeeded(compPOL, requestContext)) - .compose(v -> createPoLineWithOrder(compPOL, po, requestContext))); - } else { - Errors errors = new Errors().withErrors(validationErrors).withTotalRecords(validationErrors.size()); - logger.error("Create POL validation error : {}", JsonObject.mapFrom(errors).encodePrettily()); - throw new HttpException(RestConstants.VALIDATION_ERROR, errors); + .compose(v -> createShadowInstanceIfNeeded(compPOL, requestContext)) + .compose(v -> createPoLineWithOrder(compPOL, po, requestContext))); } + var errors = new Errors().withErrors(validationErrors).withTotalRecords(validationErrors.size()); + logger.error("Create POL validation error : {}", JsonObject.mapFrom(errors).encodePrettily()); + throw new HttpException(RestConstants.VALIDATION_ERROR, errors); }); } @@ -204,48 +203,38 @@ public Future createPoLine(CompositePoLine compPOL, JsonObject * @param compOrder associated {@link CompositePurchaseOrder} object * @return completable future which might hold {@link CompositePoLine} on success or an exception if any issue happens */ - public Future createPoLineWithOrder(CompositePoLine compPoLine, CompositePurchaseOrder compOrder, - RequestContext requestContext) { + public Future createPoLineWithOrder(CompositePoLine compPoLine, CompositePurchaseOrder compOrder, RequestContext requestContext) { // The id is required because sub-objects are being created first - if (isEmpty(compPoLine.getId())) { + if (StringUtils.isEmpty(compPoLine.getId())) { compPoLine.setId(UUID.randomUUID().toString()); } compPoLine.setPurchaseOrderId(compOrder.getId()); updateEstimatedPrice(compPoLine); PoLineCommonUtil.updateLocationsQuantity(compPoLine.getLocations()); - JsonObject line = mapFrom(compPoLine); + var line = convertToPoLine(compPoLine); List> subObjFuts = new ArrayList<>(); - subObjFuts.add(createAlerts(compPoLine, line, requestContext)); subObjFuts.add(createReportingCodes(compPoLine, line, requestContext)); return GenericCompositeFuture.join(new ArrayList<>(subObjFuts)) .compose(v -> generateLineNumber(compOrder, requestContext)) - .map(lineNumber -> line.put(PO_LINE_NUMBER, lineNumber)) + .map(line::withPoLineNumber) .compose(v -> purchaseOrderLineService.updateSearchLocations(compPoLine, requestContext)) - .map(v -> line.put(SEARCH_LOCATION_IDS, compPoLine.getSearchLocationIds())) + .map(v -> line.withSearchLocationIds(compPoLine.getSearchLocationIds())) .compose(v -> createPoLineSummary(compPoLine, line, requestContext)); } public Future setTenantDefaultCreateInventoryValues(CompositePoLine compPOL, JsonObject tenantConfiguration) { - Promise promise = Promise.promise(); - - if (isCreateInventoryNull(compPOL)) { - if (tenantConfiguration != null && !tenantConfiguration.isEmpty() && - StringUtils.isNotEmpty(tenantConfiguration.getString(CREATE_INVENTORY))) { - promise.complete(new JsonObject(tenantConfiguration.getString(CREATE_INVENTORY))); - } else { - promise.complete(new JsonObject()); - } - return promise.future() - .map(jsonConfig -> { - updateCreateInventory(compPOL, jsonConfig); - return null; - }); - } else { + if (!isCreateInventoryNull(compPOL)) { return Future.succeededFuture(); } + var jsonConfig = new JsonObject(); + if (tenantConfiguration != null && !tenantConfiguration.isEmpty() && StringUtils.isNotEmpty(tenantConfiguration.getString(CREATE_INVENTORY))) { + jsonConfig = new JsonObject(tenantConfiguration.getString(CREATE_INVENTORY)); + } + updateCreateInventory(compPOL, jsonConfig); + return Future.succeededFuture(); } public static boolean isCreateInventoryNull(CompositePoLine compPOL) { @@ -256,11 +245,11 @@ public static boolean isCreateInventoryNull(CompositePoLine compPOL) { }; } - public Future getCompositePoLine(String polineId, RequestContext requestContext) { - return purchaseOrderLineService.getOrderLineById(polineId, requestContext) + public Future getCompositePoLine(String poLineId, RequestContext requestContext) { + return purchaseOrderLineService.getOrderLineById(poLineId, requestContext) .compose(line -> getCompositePurchaseOrder(line.getPurchaseOrderId(), requestContext) .compose(order -> protectionService.isOperationRestricted(order.getAcqUnitIds(), ProtectedOperationType.READ, requestContext)) - .compose(ok -> populateCompositeLine(line, requestContext))); + .compose(v -> populateCompositeLine(line, requestContext))); } public Future deleteLine(String lineId, RequestContext requestContext) { @@ -270,8 +259,8 @@ public Future deleteLine(String lineId, RequestContext requestContext) { logger.debug("Deleting PO line..."); return encumbranceService.deletePoLineEncumbrances(line, requestContext) .compose(v -> purchaseOrderLineService.deletePoLine(line, requestContext)); - })) - .onSuccess(json -> logger.info("The PO Line with id='{}' has been deleted successfully", lineId)); + })) + .onSuccess(json -> logger.info("deleteLine:: PoLine with id='{}' has been deleted successfully", lineId)); } /** @@ -279,54 +268,43 @@ public Future deleteLine(String lineId, RequestContext requestContext) { */ public Future updateOrderLine(CompositePoLine compOrderLine, RequestContext requestContext) { return getPoLineByIdAndValidate(compOrderLine.getPurchaseOrderId(), compOrderLine.getId(), requestContext) - .compose(lineFromStorage -> getCompositePurchaseOrder(compOrderLine.getPurchaseOrderId(), requestContext) - .map(compOrder -> addLineToCompOrder(compOrder, lineFromStorage)) - .map(compOrder -> { - validatePOLineProtectedFieldsChanged(compOrderLine, lineFromStorage, compOrder); - PoLineCommonUtil.updateLocationsQuantity(compOrderLine.getLocations()); - updateEstimatedPrice(compOrderLine); - checkLocationCanBeModified(compOrderLine, lineFromStorage.mapTo(PoLine.class), compOrder); - return compOrder; - }) + .map(lineFromStorage -> lineFromStorage.mapTo(PoLine.class)) + .compose(poLineFromStorage -> getCompositePurchaseOrder(compOrderLine.getPurchaseOrderId(), requestContext) + .map(compOrder -> addLineToCompOrder(compOrder, poLineFromStorage)) + .map(compOrder -> { + validatePOLineProtectedFieldsChanged(compOrderLine, poLineFromStorage, compOrder); + PoLineCommonUtil.updateLocationsQuantity(compOrderLine.getLocations()); + updateEstimatedPrice(compOrderLine); + checkLocationCanBeModified(compOrderLine, poLineFromStorage, compOrder); + return compOrder; + }) .compose(compOrder -> protectionService.isOperationRestricted(compOrder.getAcqUnitIds(), UPDATE, requestContext) .compose(v -> purchaseOrderLineService.validateAndNormalizeISBNAndProductType(Collections.singletonList(compOrderLine), requestContext)) .compose(v -> validateAccessProviders(compOrderLine, requestContext)) .compose(v -> expenseClassValidationService.validateExpenseClassesForOpenedOrder(compOrder, Collections.singletonList(compOrderLine), requestContext)) - .compose(v -> processPoLineEncumbrances(compOrder, compOrderLine, lineFromStorage, requestContext)) - .map(v -> lineFromStorage))) - .compose(lineFromStorage -> { - // override PO line number in the request with one from the storage, because it's not allowed to change it during PO line - // update - PoLineInvoiceLineHolder poLineInvoiceLineHolder = new PoLineInvoiceLineHolder(compOrderLine, lineFromStorage); - compOrderLine.setPoLineNumber(lineFromStorage.getString(PO_LINE_NUMBER)); - - return polInvoiceLineRelationService.prepareRelatedInvoiceLines(poLineInvoiceLineHolder, requestContext) - .compose(v -> createShadowInstanceIfNeeded(compOrderLine, requestContext)) - .compose(v -> updateOrderLine(compOrderLine, lineFromStorage, requestContext)) - .compose(v -> updateEncumbranceStatus(compOrderLine, lineFromStorage, requestContext)) - .compose(v -> polInvoiceLineRelationService.updateInvoiceLineReference(poLineInvoiceLineHolder, requestContext)) - .compose(v -> updateInventoryItemStatus(compOrderLine, lineFromStorage, requestContext)) - .map(ok -> { - updateOrderStatus(compOrderLine, lineFromStorage, requestContext); - return null; - }); - }); - - } - - private Future updateEncumbranceStatus(CompositePoLine compOrderLine, JsonObject lineFromStorage, - RequestContext requestContext) { - PoLine poLine = lineFromStorage.mapTo(PoLine.class); - if (isReleaseEncumbrances(compOrderLine, poLine)) { - logger.info("Encumbrances releasing for poLineId={} where paymentStatus={}", compOrderLine.getId(), compOrderLine.getPaymentStatus()); - return encumbranceService.getPoLineUnreleasedEncumbrances(compOrderLine, requestContext) - .compose(transactionList -> encumbranceService.releaseEncumbrances(transactionList, requestContext)); - } else if (isUnreleasedEncumbrances(compOrderLine, poLine)) { - logger.info("Encumbrances unreleasing for poLineId={} where paymentStatus={}", compOrderLine.getId(), compOrderLine.getPaymentStatus()); - return encumbranceService.getPoLineReleasedEncumbrances(compOrderLine, requestContext) - .compose(transactionList -> encumbranceService.unreleaseEncumbrances(transactionList, requestContext)); - } - return Future.succeededFuture(); + .compose(v -> processPoLineEncumbrances(compOrder, compOrderLine, poLineFromStorage, requestContext))) + .map(v -> compOrderLine.withPoLineNumber(poLineFromStorage.getPoLineNumber())) // PoLine number must not be modified during PoLine update, set original value + .map(v -> new PoLineInvoiceLineHolder(compOrderLine, poLineFromStorage)) + .compose(poLineInvoiceLineHolder -> polInvoiceLineRelationService.prepareRelatedInvoiceLines(poLineInvoiceLineHolder, requestContext) + .compose(v -> createShadowInstanceIfNeeded(compOrderLine, requestContext)) + .compose(v -> updateOrderLine(compOrderLine, JsonObject.mapFrom(poLineFromStorage), requestContext)) + .compose(v -> updateEncumbranceStatus(compOrderLine, poLineFromStorage, requestContext)) + .compose(v -> polInvoiceLineRelationService.updateInvoiceLineReference(poLineInvoiceLineHolder, requestContext)) + .compose(v -> updateInventoryItemStatus(compOrderLine, poLineFromStorage, requestContext)) + .compose(v -> updateOrderStatusIfNeeded(compOrderLine, poLineFromStorage, requestContext)))); + } + + private Future updateEncumbranceStatus(CompositePoLine compOrderLine, PoLine poLineFromStorage, RequestContext requestContext) { + if (isReleaseEncumbrances(compOrderLine, poLineFromStorage)) { + logger.info("updateEncumbranceStatus:: Encumbrances releasing for poLineId={} where paymentStatus={}", compOrderLine.getId(), compOrderLine.getPaymentStatus()); + return encumbranceService.getPoLineUnreleasedEncumbrances(compOrderLine, requestContext) + .compose(transactionList -> encumbranceService.releaseEncumbrances(transactionList, requestContext)); + } else if (isUnreleasedEncumbrances(compOrderLine, poLineFromStorage)) { + logger.info("updateEncumbranceStatus:: Encumbrances unreleasing for poLineId={} where paymentStatus={}", compOrderLine.getId(), compOrderLine.getPaymentStatus()); + return encumbranceService.getPoLineReleasedEncumbrances(compOrderLine, requestContext) + .compose(transactionList -> encumbranceService.unreleaseEncumbrances(transactionList, requestContext)); + } + return Future.succeededFuture(); } private boolean isReleaseEncumbrances(CompositePoLine compOrderLine, PoLine poLine) { @@ -352,18 +330,11 @@ private boolean isUnreleasedEncumbrances(CompositePoLine compOrderLine, PoLine p * @param lineFromStorage {@link JsonObject} representing PO line from storage (/acq-models/mod-orders-storage/schemas/po_line.json) */ public Future updateOrderLine(CompositePoLine compOrderLine, JsonObject lineFromStorage, RequestContext requestContext) { - Promise promise = Promise.promise(); - - purchaseOrderLineService.updateSearchLocations(compOrderLine, requestContext) + return purchaseOrderLineService.updateSearchLocations(compOrderLine, requestContext) .compose(v -> purchaseOrderLineService.updatePoLineSubObjects(compOrderLine, lineFromStorage, requestContext)) .compose(poLine -> purchaseOrderLineService.updateOrderLineSummary(compOrderLine.getId(), poLine, requestContext)) - .onSuccess(json -> promise.complete()) - .onFailure(throwable -> { - String message = String.format("PO Line with '%s' id partially updated but there are issues processing some PO Line sub-objects", compOrderLine.getId()); - logger.error(message); - promise.fail(throwable); - }); - return promise.future(); + .onFailure(throwable -> logger.error("PoLine with id - '{}' partially updated but there are issues processing some PoLine sub-objects", compOrderLine.getId())) + .mapEmpty(); } public String buildNewPoLineNumber(PoLine poLineFromStorage, String poNumber) { @@ -386,52 +357,47 @@ public void updateEstimatedPrice(CompositePoLine compPoLine) { } - - - /** * Retrieves PO line from storage by PO line id as JsonObject and validates order id match. */ private Future getPoLineByIdAndValidate(String orderId, String lineId, RequestContext requestContext) { return purchaseOrderLineService.getOrderLineById(lineId, requestContext) - .map(JsonObject::mapFrom) - .map(line -> { + .map(poLine -> { logger.debug("Validating if the retrieved PO line corresponds to PO"); - validateOrderId(orderId, line); - return line; + validateOrderId(orderId, poLine); + return JsonObject.mapFrom(poLine); }); } /** * Validates if the retrieved PO line corresponds to PO (orderId). In case the PO line does not correspond to order id the exception is thrown * @param orderId order identifier - * @param line PO line retrieved from storage + * @param poLine PO line retrieved from storage */ - private void validateOrderId(String orderId, JsonObject line) { - if (!StringUtils.equals(orderId, line.getString(PURCHASE_ORDER_ID))) { + private void validateOrderId(String orderId, PoLine poLine) { + if (!StringUtils.equals(orderId, poLine.getPurchaseOrderId())) { throw new HttpException(422, ErrorCodes.INCORRECT_ORDER_ID_IN_POL); } } - private Future createPoLineSummary(CompositePoLine compPOL, JsonObject jsonLine, RequestContext requestContext) { - RequestEntry rqEntry = new RequestEntry(resourcesPath(PO_LINES_STORAGE)); - var poLine = jsonLine.mapTo(PoLine.class); - return restClient.post(rqEntry, poLine, PoLine.class, requestContext) - .map(createdLine -> compPOL.withId(createdLine.getId()).withPoLineNumber(createdLine.getPoLineNumber())); + private Future createPoLineSummary(CompositePoLine compPOL, PoLine poLine, RequestContext requestContext) { + var requestEntry = new RequestEntry(resourcesPath(PO_LINES_STORAGE)); + return restClient.post(requestEntry, poLine, PoLine.class, requestContext) + .map(createdLine -> compPOL.withId(createdLine.getId()).withPoLineNumber(createdLine.getPoLineNumber())); } - private Future createReportingCodes(CompositePoLine compPOL, JsonObject line, RequestContext requestContext) { - List> futures = new ArrayList<>(); - - List reportingCodes = compPOL.getReportingCodes(); - if (null != reportingCodes) { - RequestEntry rqEntry = new RequestEntry(resourcesPath(REPORTING_CODES)); - reportingCodes - .forEach(reportingObject -> futures.add(restClient.post(rqEntry, reportingObject, ReportingCode.class, requestContext) - .map(ReportingCode::getId))); + private Future createReportingCodes(CompositePoLine compPOL, PoLine poLine, RequestContext requestContext) { + var reportingCodes = compPOL.getReportingCodes(); + if (isEmpty(reportingCodes)) { + return Future.succeededFuture(); } - return GenericCompositeFuture.join(new ArrayList<>(futures)) - .map(reportingIds -> line.put(REPORTING_CODES, reportingIds.list())) + + var requestEntry = new RequestEntry(resourcesPath(REPORTING_CODES)); + var futures = reportingCodes.stream() + .map(reportingObject -> restClient.post(requestEntry, reportingObject, ReportingCode.class, requestContext).map(ReportingCode::getId)) + .toList(); + return GenericCompositeFuture.join(futures) + .map(reportingIds -> poLine.withReportingCodes(reportingIds.list())) .recover(t -> { logger.error("Failed to create reporting codes", t); throw new HttpException(500, "Failed to create reporting codes", t); @@ -439,17 +405,18 @@ private Future createReportingCodes(CompositePoLine compPOL, JsonObject li .mapEmpty(); } - private Future createAlerts(CompositePoLine compPOL, JsonObject line, RequestContext requestContext) { - List> futures = new ArrayList<>(); - - List alerts = compPOL.getAlerts(); - if (null != alerts) { - RequestEntry rqEntry = new RequestEntry(resourcesPath(ALERTS)); - alerts.forEach(alertObject -> futures.add(restClient.post(rqEntry, alertObject, Alert.class, requestContext).map(Alert::getId))); + private Future createAlerts(CompositePoLine compPOL, PoLine poLine, RequestContext requestContext) { + var alerts = compPOL.getAlerts(); + if (isEmpty(alerts)) { + return Future.succeededFuture(); } - return GenericCompositeFuture.join(new ArrayList<>(futures)) - .map(ids -> line.put(ALERTS, ids.list())) + var requestEntry = new RequestEntry(resourcesPath(ALERTS)); + var futures = alerts.stream() + .map(alertObject -> restClient.post(requestEntry, alertObject, Alert.class, requestContext).map(Alert::getId)) + .toList(); + return GenericCompositeFuture.join(futures) + .map(ids -> poLine.withAlerts(ids.list())) .recover(t -> { logger.error("Failed to create alerts", t); throw new HttpException(500, "Failed to create alerts", t); @@ -459,35 +426,35 @@ private Future createAlerts(CompositePoLine compPOL, JsonObject line, Requ public Future updatePoLines(CompositePurchaseOrder poFromStorage, CompositePurchaseOrder compPO, RequestContext requestContext) { logger.debug("updatePoLines start"); - if (isPoLinesUpdateRequired(poFromStorage, compPO)) { - List existingPoLines = HelperUtils.convertToPoLines(poFromStorage.getCompositePoLines()); - if (isNotEmpty(compPO.getCompositePoLines())) { - // New PO Line(s) can be added only to Pending order - if (poFromStorage.getWorkflowStatus() != PENDING && hasNewPoLines(compPO, existingPoLines)) { - throw new HttpException(422, poFromStorage.getWorkflowStatus() == OPEN ? ErrorCodes.ORDER_OPEN : ErrorCodes.ORDER_CLOSED); - } - validatePOLineProtectedFieldsChangedInPO(poFromStorage, compPO, existingPoLines); - return handlePoLines(compPO, existingPoLines, requestContext); - } else { - return updatePoLinesNumber(compPO, existingPoLines, requestContext); - } + if (!isPoLinesUpdateRequired(poFromStorage, compPO)) { + return Future.succeededFuture(); } - return Future.succeededFuture(); + var existingPoLines = PoLineCommonUtil.convertToPoLines(poFromStorage.getCompositePoLines()); + if (isEmpty(compPO.getCompositePoLines())) { + return updatePoLinesNumber(compPO, existingPoLines, requestContext); + } + // New PO Line(s) can be added only to Pending order + if (poFromStorage.getWorkflowStatus() != PENDING && getNewPoLines(compPO, existingPoLines).findAny().isPresent()) { + throw new HttpException(422, poFromStorage.getWorkflowStatus() == OPEN ? ErrorCodes.ORDER_OPEN : ErrorCodes.ORDER_CLOSED); + } + validatePoLineProtectedFieldsChangedOrder(poFromStorage, compPO, existingPoLines); + return handlePoLines(compPO, existingPoLines, requestContext); } - private void validatePOLineProtectedFieldsChangedInPO(CompositePurchaseOrder poFromStorage, CompositePurchaseOrder compPO, - List existingPoLines) { - if (poFromStorage.getWorkflowStatus() != PENDING) { - compPO.getCompositePoLines() - .forEach(poLine -> verifyProtectedFieldsChanged(POLineProtectedFieldsUtil.getFieldNames(poLine.getOrderFormat().value()), - findCorrespondingCompositePoLine(poLine, existingPoLines), JsonObject.mapFrom(poLine))); + private void validatePoLineProtectedFieldsChangedOrder(CompositePurchaseOrder poFromStorage, CompositePurchaseOrder compPO, List existingPoLines) { + if (poFromStorage.getWorkflowStatus() == PENDING) { + return; } + compPO.getCompositePoLines().forEach(poLine -> { + var fields = POLineProtectedFieldsUtil.getFieldNames(poLine.getOrderFormat().value()); + var correspondingLine = findCorrespondingCompositePoLine(poLine, existingPoLines); + verifyProtectedFieldsChanged(fields, correspondingLine, JsonObject.mapFrom(poLine)); + }); } private JsonObject findCorrespondingCompositePoLine(CompositePoLine poLine, List poLinesFromStorage) { return poLinesFromStorage.stream() - .filter(line -> line.getId() - .equals(poLine.getId())) + .filter(line -> line.getId().equals(poLine.getId())) .findFirst() .map(JsonObject::mapFrom) .orElse(null); @@ -498,15 +465,10 @@ private boolean isPoLinesUpdateRequired(CompositePurchaseOrder poFromStorage, Co } private Future updatePoLinesNumber(CompositePurchaseOrder compOrder, List poLinesFromStorage, RequestContext requestContext) { - List> futures = poLinesFromStorage - .stream() - .map(lineFromStorage -> { - lineFromStorage.setPoLineNumber(buildNewPoLineNumber(lineFromStorage, compOrder.getPoNumber())); - return purchaseOrderLineService.saveOrderLine(lineFromStorage, requestContext); - }) - .toList(); - - return GenericCompositeFuture.join(new ArrayList<>(futures)) + return GenericCompositeFuture.join(poLinesFromStorage.stream() + .map(lineFromStorage -> lineFromStorage.withPoLineNumber(buildNewPoLineNumber(lineFromStorage, compOrder.getPoNumber()))) + .map(lineFromStorage -> purchaseOrderLineService.saveOrderLine(lineFromStorage, requestContext)) + .toList()) .mapEmpty(); } @@ -516,18 +478,15 @@ private Future handlePoLines(CompositePurchaseOrder compOrder, List futures.add(orderInvoiceRelationService.checkOrderInvoiceRelationship(compOrder.getId(), requestContext) - .compose(v -> encumbranceService.deletePoLineEncumbrances(poLine, requestContext) - .compose(ok -> purchaseOrderLineService.deletePoLine(poLine, requestContext))))); - + poLinesFromStorage.forEach(poLine -> futures.add( + orderInvoiceRelationService.checkOrderInvoiceRelationship(compOrder.getId(), requestContext) + .compose(v -> encumbranceService.deletePoLineEncumbrances(poLine, requestContext)) + .compose(v -> purchaseOrderLineService.deletePoLine(poLine, requestContext)))); } - return GenericCompositeFuture.join(futures) - .mapEmpty(); + return GenericCompositeFuture.join(futures).mapEmpty(); } - private List> processPoLinesUpdate(CompositePurchaseOrder compOrder, List poLinesFromStorage, - RequestContext requestContext) { + private List> processPoLinesUpdate(CompositePurchaseOrder compOrder, List poLinesFromStorage, RequestContext requestContext) { List> futures = new ArrayList<>(); Iterator iterator = poLinesFromStorage.iterator(); while (iterator.hasNext()) { @@ -547,25 +506,15 @@ private List> processPoLinesUpdate(CompositePurchaseOrder compOrder, L return futures; } - private List> processPoLinesCreation(CompositePurchaseOrder compOrder, List poLinesFromStorage, - RequestContext requestContext) { + private List> processPoLinesCreation(CompositePurchaseOrder compOrder, List poLinesFromStorage, RequestContext requestContext) { return getNewPoLines(compOrder, poLinesFromStorage) .map(compPOL -> createPoLineWithOrder(compPOL, compOrder, requestContext)) .toList(); } - private boolean hasNewPoLines(CompositePurchaseOrder compPO, List poLinesFromStorage) { - return getNewPoLines(compPO, poLinesFromStorage).findAny().isPresent(); - } - private Stream getNewPoLines(CompositePurchaseOrder compPO, List poLinesFromStorage) { - List lineIdsInStorage = poLinesFromStorage - .stream() - .map(PoLine::getId) - .toList(); - - return compPO.getCompositePoLines() - .stream() + var lineIdsInStorage = poLinesFromStorage.stream().map(PoLine::getId).toList(); + return compPO.getCompositePoLines().stream() .filter(poLine -> !lineIdsInStorage.contains(poLine.getId())); } @@ -574,22 +523,20 @@ private boolean isPoNumberChanged(CompositePurchaseOrder poFromStorage, Composit } private void checkLocationCanBeModified(CompositePoLine poLine, PoLine lineFromStorage, CompositePurchaseOrder order) { - boolean isOrderOpenAndNoNeedToManualAddPiecesForCreationAndLocationModified = order.getWorkflowStatus() == OPEN + if (order.getWorkflowStatus() == OPEN && !poLine.getSource().equals(CompositePoLine.Source.EBSCONET) && Boolean.FALSE.equals(poLine.getCheckinItems()) - && !isEqualCollection(poLine.getLocations(), lineFromStorage.getLocations()); - - if (isOrderOpenAndNoNeedToManualAddPiecesForCreationAndLocationModified) { + && !isEqualCollection(poLine.getLocations(), lineFromStorage.getLocations())) { throw new HttpException(400, LOCATION_CAN_NOT_BE_MODIFIER_AFTER_OPEN); } } private CompositePurchaseOrder validateOrderState(CompositePurchaseOrder po) { - CompositePurchaseOrder.WorkflowStatus poStatus = po.getWorkflowStatus(); - if (poStatus != PENDING) { - throw new HttpException(422, poStatus == OPEN ? ErrorCodes.ORDER_OPEN : ErrorCodes.ORDER_CLOSED); + var poStatus = po.getWorkflowStatus(); + if (poStatus == PENDING) { + return po; } - return po; + throw new HttpException(422, poStatus == OPEN ? ErrorCodes.ORDER_OPEN : ErrorCodes.ORDER_CLOSED); } /** @@ -598,36 +545,31 @@ private CompositePurchaseOrder validateOrderState(CompositePurchaseOrder po) { * @param tenantConfiguration Tenant configuration * @return completable future which might be completed with {@code true} if line is valid, {@code false} if not valid or an exception if processing fails */ - private Future> validateNewPoLine(CompositePoLine compPOL, JsonObject tenantConfiguration, - RequestContext requestContext) { + private Future> validateNewPoLine(CompositePoLine compPOL, JsonObject tenantConfiguration, RequestContext requestContext) { logger.debug("Validating if PO Line is valid..."); List errors = new ArrayList<>(); if (compPOL.getPurchaseOrderId() == null) { errors.add(ErrorCodes.MISSING_ORDER_ID_IN_POL.toError()); } - // If static validation has failed, no need to call other services - if (CollectionUtils.isNotEmpty(errors)) { + if (isNotEmpty(errors)) { return Future.succeededFuture(errors); } - return compositePoLineValidationService.validatePoLine(compPOL, requestContext) .compose(poLineErrors -> { - if (CollectionUtils.isEmpty(poLineErrors)) { - return validatePoLineLimit(compPOL, tenantConfiguration, requestContext) - .compose(aErrors -> { - if (CollectionUtils.isEmpty(aErrors)) { - return purchaseOrderLineService.validateAndNormalizeISBN(Collections.singletonList(compPOL), requestContext) - .map(v -> errors); - } else { - errors.addAll(aErrors); - return Future.succeededFuture(errors); - } - }); - } else { + if (isNotEmpty(poLineErrors)) { errors.addAll(poLineErrors); return Future.succeededFuture(errors); } + return validatePoLineLimit(compPOL, tenantConfiguration, requestContext) + .compose(aErrors -> { + if (isNotEmpty(aErrors)) { + errors.addAll(aErrors); + return Future.succeededFuture(errors); + } + return purchaseOrderLineService.validateAndNormalizeISBN(Collections.singletonList(compPOL), requestContext) + .map(v -> errors); + }); }); } @@ -645,20 +587,15 @@ private Future> validatePoLineLimit(CompositePoLine compPOL, JsonObj } private Future getCompositePurchaseOrder(String purchaseOrderId, RequestContext requestContext) { - Promise promise = Promise.promise(); - purchaseOrderStorageService.getPurchaseOrderByIdAsJson(purchaseOrderId, requestContext) + return purchaseOrderStorageService.getPurchaseOrderByIdAsJson(purchaseOrderId, requestContext) .map(HelperUtils::convertToCompositePurchaseOrder) - .onSuccess(promise::complete) - .onFailure(cause -> { + .recover(cause -> { // The case when specified order does not exist if (cause instanceof HttpException httpException && httpException.getCode() == Response.Status.NOT_FOUND.getStatusCode()) { - promise.fail(new HttpException(422, ErrorCodes.ORDER_NOT_FOUND)); - } else { - promise.fail(cause); + throw new HttpException(422, ErrorCodes.ORDER_NOT_FOUND); } + throw new HttpException(500, cause.getMessage(), cause); }); - - return promise.future(); } private Future generateLineNumber(CompositePurchaseOrder compOrder, RequestContext requestContext) { @@ -672,36 +609,32 @@ private Future generateLineNumber(CompositePurchaseOrder compOrder, Requ private Future populateCompositeLine(PoLine poline, RequestContext requestContext) { return purchaseOrderLineService.operateOnPoLine(HttpMethod.GET, poline, requestContext) - .compose(compPol -> getLineWithInstanceId(compPol, requestContext)); } + .compose(compPol -> getLineWithInstanceId(compPol, requestContext)); + } private Future getLineWithInstanceId(CompositePoLine line, RequestContext requestContext) { - if (!Boolean.TRUE.equals(line.getIsPackage())) { - return titlesService.getTitles(1, 0, QUERY_BY_PO_LINE_ID + line.getId(), requestContext) - .map(titleCollection -> { - List titles = titleCollection.getTitles(); - if (!titles.isEmpty()) { - line.setInstanceId(titles.get(0).getInstanceId()); - } - return line; - }); - } else { + if (Boolean.TRUE.equals(line.getIsPackage())) { return Future.succeededFuture(line); } + var query = String.format(QUERY_BY_PO_LINE_ID, line.getId()); + return titlesService.getTitles(1, 0, query, requestContext) + .map(titleCollection -> { + var titles = titleCollection.getTitles(); + if (!titles.isEmpty()) { + line.setInstanceId(titles.get(0).getInstanceId()); + } + return line; + }); } - private CompositePurchaseOrder addLineToCompOrder(CompositePurchaseOrder compOrder, JsonObject lineFromStorage) { - PoLine poLine = lineFromStorage.mapTo(PoLine.class); - poLine.setAlerts(null); - poLine.setReportingCodes(null); - CompositePoLine compPoLine = JsonObject.mapFrom(poLine).mapTo(CompositePoLine.class); + private CompositePurchaseOrder addLineToCompOrder(CompositePurchaseOrder compOrder, PoLine lineFromStorage) { + var compPoLine = convertToCompositePoLine(lineFromStorage); compOrder.getCompositePoLines().add(compPoLine); return compOrder; } private Future<Void> processPoLineEncumbrances(CompositePurchaseOrder compOrder, CompositePoLine compositePoLine, - JsonObject lineFromStorage, RequestContext requestContext) { - PoLine storagePoLine = lineFromStorage.mapTo(PoLine.class); - + PoLine storagePoLine, RequestContext requestContext) { List<String> storageFundIds = storagePoLine.getFundDistribution().stream() .map(FundDistribution::getFundId) .toList(); @@ -709,10 +642,10 @@ private Future<Void> processPoLineEncumbrances(CompositePurchaseOrder compOrder, compositePoLine.getFundDistribution().stream() .filter(fundDistribution -> storageFundIds.contains(fundDistribution.getFundId()) && fundDistribution.getEncumbrance() == null) .forEach(fundDistribution -> storagePoLine.getFundDistribution().stream() - .filter(storageFundDistribution -> storageFundDistribution.getFundId().equals(fundDistribution.getFundId())) - .filter(storageFundDistribution -> Objects.equals(storageFundDistribution.getExpenseClassId(), fundDistribution.getExpenseClassId())) - .findFirst() - .ifPresent(storageFundDistribution -> fundDistribution.setEncumbrance(storageFundDistribution.getEncumbrance()))); + .filter(storageFundDistribution -> storageFundDistribution.getFundId().equals(fundDistribution.getFundId())) + .filter(storageFundDistribution -> Objects.equals(storageFundDistribution.getExpenseClassId(), fundDistribution.getExpenseClassId())) + .findFirst() + .ifPresent(storageFundDistribution -> fundDistribution.setEncumbrance(storageFundDistribution.getEncumbrance()))); if (isEncumbranceUpdateNeeded(compOrder, compositePoLine, storagePoLine)) { OrderWorkflowType workflowType = compOrder.getWorkflowStatus() == PENDING ? @@ -724,36 +657,29 @@ private Future<Void> processPoLineEncumbrances(CompositePurchaseOrder compOrder, return Future.succeededFuture(); } - private Future<Void> updateInventoryItemStatus(CompositePoLine compOrderLine, JsonObject lineFromStorage, RequestContext requestContext) { - PoLine poLineFromStorage = lineFromStorage.mapTo(PoLine.class); - if (isStatusChanged(compOrderLine, poLineFromStorage) && isCurrentStatusCanceled(compOrderLine)) { - return purchaseOrderLineService.getPoLinesByOrderId(compOrderLine.getPurchaseOrderId(), requestContext) - .compose(poLines -> { - List<PoLine> notCanceledPoLines = poLines.stream().filter(Predicate.not(this::isDbPoLineStatusCancelled)).toList(); - if (CollectionUtils.isEmpty(notCanceledPoLines)) { - logger.info("updateInventoryItemStatus:: not canceled po lines not found, returning..."); - return Future.succeededFuture(null); - } - return itemStatusSyncService.updateInventoryItemStatus(compOrderLine.getId(), compOrderLine.getLocations(), - ItemStatus.ORDER_CLOSED, requestContext); - }); + private Future<Void> updateInventoryItemStatus(CompositePoLine compOrderLine, PoLine lineFromStorage, RequestContext requestContext) { + var shouldUpdateItemStatus = isStatusChanged(compOrderLine, lineFromStorage) && isStatusCanceledCompositePoLine(compOrderLine); + if (!shouldUpdateItemStatus) { + return Future.succeededFuture(); } - return Future.succeededFuture(null); - } - - private boolean isStatusChanged(CompositePoLine compOrderLine, PoLine lineFromStorage) { - return !StringUtils.equals(lineFromStorage.getReceiptStatus().value(), compOrderLine.getReceiptStatus().value()) || - !StringUtils.equals(lineFromStorage.getPaymentStatus().value(), compOrderLine.getPaymentStatus().value()); - } - - private boolean isDbPoLineStatusCancelled(PoLine poLine) { - return PoLine.PaymentStatus.CANCELLED.equals(poLine.getPaymentStatus()) || - PoLine.ReceiptStatus.CANCELLED.equals(poLine.getReceiptStatus()); + return purchaseOrderLineService.getPoLinesByOrderId(compOrderLine.getPurchaseOrderId(), requestContext) + .compose(poLines -> { + if (areAllPoLinesCanceled(poLines)) { + logger.info("updateInventoryItemStatus:: All PoLines are canceled, returning..."); + return Future.succeededFuture(); + } + return itemStatusSyncService.updateInventoryItemStatus(compOrderLine.getId(), compOrderLine.getLocations(), + ItemStatus.ORDER_CLOSED, requestContext); + }); } - private boolean isCurrentStatusCanceled(CompositePoLine compOrderLine) { - return CompositePoLine.ReceiptStatus.CANCELLED.equals(compOrderLine.getReceiptStatus()) || - CompositePoLine.PaymentStatus.CANCELLED.equals(compOrderLine.getPaymentStatus()); + public Future<Void> updateOrderStatusIfNeeded(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) { @@ -792,8 +718,7 @@ static boolean hasAlteredExchangeRate(Cost oldCost, Cost newCost) { private Future<Void> validateAccessProviders(CompositePoLine compOrderLine, RequestContext requestContext) { return organizationService.validateAccessProviders(Collections.singletonList(compOrderLine), requestContext) .map(errors -> { - if (!errors.getErrors() - .isEmpty()) { + if (isNotEmpty(errors.getErrors())) { throw new HttpException(422, errors.getErrors().get(0)); } return null; @@ -802,24 +727,12 @@ private Future<Void> validateAccessProviders(CompositePoLine compOrderLine, Requ } - private void validatePOLineProtectedFieldsChanged(CompositePoLine compOrderLine, JsonObject lineFromStorage, CompositePurchaseOrder purchaseOrder) { + private void validatePOLineProtectedFieldsChanged(CompositePoLine compOrderLine, PoLine poLineFromStorage, CompositePurchaseOrder purchaseOrder) { if (purchaseOrder.getWorkflowStatus() != PENDING) { - verifyProtectedFieldsChanged(POLineProtectedFieldsUtil.getFieldNames(compOrderLine.getOrderFormat().value()), JsonObject.mapFrom(lineFromStorage.mapTo(PoLine.class)), JsonObject.mapFrom(compOrderLine)); - } - } - - private void updateOrderStatus(CompositePoLine compOrderLine, JsonObject lineFromStorage, RequestContext requestContext) { - PoLine poLine = lineFromStorage.mapTo(PoLine.class); - // See MODORDERS-218 - if (isStatusChanged(compOrderLine, poLine)) { - HelperUtils.sendEvent(MessageAddress.RECEIVE_ORDER_STATUS_UPDATE, createUpdateOrderMessage(compOrderLine), requestContext); + verifyProtectedFieldsChanged(POLineProtectedFieldsUtil.getFieldNames(compOrderLine.getOrderFormat().value()), JsonObject.mapFrom(poLineFromStorage), JsonObject.mapFrom(compOrderLine)); } } - private JsonObject createUpdateOrderMessage(CompositePoLine compOrderLine) { - return new JsonObject().put(EVENT_PAYLOAD, new JsonArray().add(new JsonObject().put(ORDER_ID, compOrderLine.getPurchaseOrderId()))); - } - private Physical.CreateInventory getPhysicalInventoryDefault(String tenantDefault) { return StringUtils.isEmpty(tenantDefault) ? Physical.CreateInventory.INSTANCE_HOLDING_ITEM @@ -863,7 +776,7 @@ private void updateCreateInventory(CompositePoLine compPOL, JsonObject jsonConfi if (compPOL.getEresource() == null) { compPOL.setEresource(new Eresource()); } - if(isEresourceInventoryNotPresent(compPOL)) { + if (isEresourceInventoryNotPresent(compPOL)) { compPOL.getEresource().setCreateInventory(eresourceDefaultValue); } } @@ -882,8 +795,8 @@ private void updateCreateInventory(CompositePoLine compPOL, JsonObject jsonConfi private Future<Void> verifyDeleteAllowed(PoLine line, RequestContext requestContext) { return orderInvoiceRelationService.checkOrderPOLineLinkedToInvoiceLine(line, requestContext) - .compose(v -> getCompositePurchaseOrder(line.getPurchaseOrderId(), requestContext) - .compose(order -> protectionService.isOperationRestricted(order.getAcqUnitIds(), DELETE, requestContext))); + .compose(v -> getCompositePurchaseOrder(line.getPurchaseOrderId(), requestContext)) + .compose(order -> protectionService.isOperationRestricted(order.getAcqUnitIds(), DELETE, requestContext)); } private Future<Void> createShadowInstanceIfNeeded(CompositePoLine compositePoLine, RequestContext requestContext) { diff --git a/src/main/java/org/folio/models/PoLineInvoiceLineHolder.java b/src/main/java/org/folio/models/PoLineInvoiceLineHolder.java index 6055bd2ea..7c001a891 100644 --- a/src/main/java/org/folio/models/PoLineInvoiceLineHolder.java +++ b/src/main/java/org/folio/models/PoLineInvoiceLineHolder.java @@ -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<>(); } 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..6f241036b 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.PoLineCommonUtil; 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<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(PoLineCommonUtil::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 e0ca60a3e..9566acbae 100644 --- a/src/main/java/org/folio/orders/utils/HelperUtils.java +++ b/src/main/java/org/folio/orders/utils/HelperUtils.java @@ -20,18 +20,13 @@ import org.folio.rest.core.exceptions.HttpException; 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; import org.folio.service.exchange.ExchangeRateProviderResolver; import org.javamoney.moneta.Money; @@ -58,19 +53,12 @@ import java.util.regex.Pattern; import static io.vertx.core.Future.succeededFuture; -import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.commons.lang3.StringUtils.isEmpty; -import static org.folio.orders.utils.ResourcePathResolver.ALERTS; -import static org.folio.orders.utils.ResourcePathResolver.REPORTING_CODES; 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 { @@ -393,79 +381,11 @@ 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 PoLine convertToPoLine(CompositePoLine compPoLine) { - JsonObject pol = JsonObject.mapFrom(compPoLine); - pol.remove(ALERTS); - pol.remove(REPORTING_CODES); - PoLine poLine = pol.mapTo(PoLine.class); - poLine.setAlerts(compPoLine.getAlerts().stream().map(Alert::getId).collect(toList())); - poLine.setReportingCodes(compPoLine.getReportingCodes().stream().map(ReportingCode::getId).collect(toList())); - return poLine; - } - - - public static List<PoLine> convertToPoLines(List<CompositePoLine> compositePoLines) { - return compositePoLines - .stream() - .map(HelperUtils::convertToPoLine) - .collect(toList()); - } - public static boolean isProductIdsExist(CompositePoLine compPOL) { return compPOL.getDetails() != null && CollectionUtils.isNotEmpty(compPOL.getDetails().getProductIds()); } @@ -543,17 +463,11 @@ public static String extractCreatedDate(JsonObject json) { } public static CompositePurchaseOrder convertToCompositePurchaseOrder(PurchaseOrder purchaseOrder, List<PoLine> poLineList) { - List<CompositePoLine> compositePoLines = new ArrayList<>(poLineList.size()); - if (CollectionUtils.isNotEmpty(poLineList)) { - poLineList.forEach(poLine -> { - poLine.setAlerts(null); - poLine.setReportingCodes(null); - CompositePoLine compositePoLine = PoLineCommonUtil.convertToCompositePoLine(poLine); - compositePoLines.add(compositePoLine); - }); - } - JsonObject jsonLine = JsonObject.mapFrom(purchaseOrder); - return jsonLine.mapTo(CompositePurchaseOrder.class).withCompositePoLines(compositePoLines); + var purchaseOrderJson = JsonObject.mapFrom(purchaseOrder); + var compositePoLines = poLineList.stream() + .map(PoLineCommonUtil::convertToCompositePoLine) + .toList(); + return purchaseOrderJson.mapTo(CompositePurchaseOrder.class).withCompositePoLines(compositePoLines); } public static void sendEvent(MessageAddress messageAddress, JsonObject data, RequestContext requestContext) { diff --git a/src/main/java/org/folio/orders/utils/PoLineCommonUtil.java b/src/main/java/org/folio/orders/utils/PoLineCommonUtil.java index 894c09663..b90d7a564 100644 --- a/src/main/java/org/folio/orders/utils/PoLineCommonUtil.java +++ b/src/main/java/org/folio/orders/utils/PoLineCommonUtil.java @@ -1,7 +1,10 @@ package org.folio.orders.utils; +import static java.util.stream.Collectors.toList; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.folio.orders.utils.HelperUtils.calculateTotalLocationQuantity; +import static org.folio.orders.utils.ResourcePathResolver.ALERTS; +import static org.folio.orders.utils.ResourcePathResolver.REPORTING_CODES; import static org.folio.rest.core.exceptions.ErrorCodes.PROHIBITED_FIELD_CHANGING; import static org.folio.rest.core.exceptions.ErrorCodes.WRONG_ONGOING_NOT_SUBSCRIPTION_FIELDS_CHANGED; import static org.folio.rest.core.exceptions.ErrorCodes.WRONG_ONGOING_SUBSCRIPTION_FIELDS_CHANGED; @@ -27,6 +30,7 @@ import org.apache.commons.lang3.ObjectUtils; import org.folio.rest.core.exceptions.HttpException; import org.folio.rest.core.exceptions.ErrorCodes; +import org.folio.rest.jaxrs.model.Alert; import org.folio.rest.jaxrs.model.CompositePoLine; import org.folio.rest.jaxrs.model.CompositePurchaseOrder; import org.folio.rest.jaxrs.model.Eresource; @@ -35,6 +39,7 @@ import org.folio.rest.jaxrs.model.Parameter; import org.folio.rest.jaxrs.model.Physical; import org.folio.rest.jaxrs.model.PoLine; +import org.folio.rest.jaxrs.model.ReportingCode; import org.folio.rest.tools.parser.JsonPathParser; import io.vertx.core.json.JsonArray; @@ -250,10 +255,26 @@ public static List<String> getTenantsFromLocations(List<Location> locations) { } public static CompositePoLine convertToCompositePoLine(PoLine poLine) { - poLine.setAlerts(null); - poLine.setReportingCodes(null); - JsonObject jsonLine = JsonObject.mapFrom(poLine); - return jsonLine.mapTo(CompositePoLine.class); + var poLineJson = JsonObject.mapFrom(poLine); + poLineJson.remove(ALERTS); + poLineJson.remove(REPORTING_CODES); + return poLineJson.mapTo(CompositePoLine.class); + } + + public static PoLine convertToPoLine(CompositePoLine compPoLine) { + var pol = JsonObject.mapFrom(compPoLine); + pol.remove(ALERTS); + pol.remove(REPORTING_CODES); + var poLine = pol.mapTo(PoLine.class); + poLine.setAlerts(compPoLine.getAlerts().stream().map(Alert::getId).collect(toList())); + poLine.setReportingCodes(compPoLine.getReportingCodes().stream().map(ReportingCode::getId).collect(toList())); + return poLine; + } + + public static List<PoLine> convertToPoLines(List<CompositePoLine> compositePoLines) { + return compositePoLines.stream() + .map(PoLineCommonUtil::convertToPoLine) + .collect(toList()); } public static void updateLocationsQuantity(List<Location> locations) { diff --git a/src/main/java/org/folio/service/invoice/PoLineInvoiceLineHolderBuilder.java b/src/main/java/org/folio/service/invoice/PoLineInvoiceLineHolderBuilder.java index 5e1e066ee..796002741 100644 --- a/src/main/java/org/folio/service/invoice/PoLineInvoiceLineHolderBuilder.java +++ b/src/main/java/org/folio/service/invoice/PoLineInvoiceLineHolderBuilder.java @@ -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); @@ -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) : diff --git a/src/main/java/org/folio/service/orders/OrderValidationService.java b/src/main/java/org/folio/service/orders/OrderValidationService.java index 4a54b18cb..2e0dd7b82 100644 --- a/src/main/java/org/folio/service/orders/OrderValidationService.java +++ b/src/main/java/org/folio/service/orders/OrderValidationService.java @@ -11,7 +11,6 @@ import org.folio.helper.PurchaseOrderLineHelper; import org.folio.okapi.common.GenericCompositeFuture; import org.folio.orders.utils.AcqDesiredPermissions; -import org.folio.orders.utils.HelperUtils; import org.folio.orders.utils.PoLineCommonUtil; import org.folio.orders.utils.ProtectedOperationType; import org.folio.rest.core.exceptions.ErrorCodes; @@ -292,7 +291,7 @@ private Set<ProtectedOperationType> getInvolvedOperations(CompositePurchaseOrder if (CollectionUtils.isEmpty(compPO.getCompositePoLines())) { return Collections.singleton(UPDATE); } - List<PoLine> poLines = HelperUtils.convertToPoLines(poFromStorage.getCompositePoLines()); + List<PoLine> poLines = PoLineCommonUtil.convertToPoLines(poFromStorage.getCompositePoLines()); Set<String> newIds = compPO.getCompositePoLines().stream().map(CompositePoLine::getId).collect(Collectors.toSet()); Set<String> storageIds = poLines.stream().map(PoLine::getId).collect(Collectors.toSet()); Set<ProtectedOperationType> operations = new HashSet<>(); diff --git a/src/main/java/org/folio/service/orders/PurchaseOrderLineService.java b/src/main/java/org/folio/service/orders/PurchaseOrderLineService.java index 1cc96df3b..88d5ecef6 100644 --- a/src/main/java/org/folio/service/orders/PurchaseOrderLineService.java +++ b/src/main/java/org/folio/service/orders/PurchaseOrderLineService.java @@ -126,7 +126,7 @@ public Future<Void> saveOrderLine(CompositePoLine compositePoLine, RequestContex } public Future<Void> saveOrderLine(CompositePoLine compositePoLine, List<Location> locations, RequestContext requestContext) { - PoLine poLine = HelperUtils.convertToPoLine(compositePoLine); + PoLine poLine = PoLineCommonUtil.convertToPoLine(compositePoLine); return saveOrderLine(poLine, locations, requestContext); } diff --git a/src/main/java/org/folio/service/orders/flows/update/unopen/UnOpenCompositeOrderManager.java b/src/main/java/org/folio/service/orders/flows/update/unopen/UnOpenCompositeOrderManager.java index 5e2bdfa83..6d7c667dd 100644 --- a/src/main/java/org/folio/service/orders/flows/update/unopen/UnOpenCompositeOrderManager.java +++ b/src/main/java/org/folio/service/orders/flows/update/unopen/UnOpenCompositeOrderManager.java @@ -122,7 +122,7 @@ private void makePoLinePending(CompositePoLine poLine) { private Future<Void> updatePoLinesSummary(List<CompositePoLine> compositePoLines, RequestContext requestContext) { return GenericCompositeFuture.join(compositePoLines.stream() - .map(HelperUtils::convertToPoLine) + .map(PoLineCommonUtil::convertToPoLine) .map(line -> purchaseOrderLineService.saveOrderLine(line, requestContext)) .collect(toList())) .map(ok -> null); diff --git a/src/main/java/org/folio/service/orders/utils/StatusUtils.java b/src/main/java/org/folio/service/orders/utils/StatusUtils.java new file mode 100644 index 000000000..325bada90 --- /dev/null +++ b/src/main/java/org/folio/service/orders/utils/StatusUtils.java @@ -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() {} + +} diff --git a/src/main/java/org/folio/service/pieces/flows/update/PieceUpdateFlowManager.java b/src/main/java/org/folio/service/pieces/flows/update/PieceUpdateFlowManager.java index 7ab437c0a..84da4a84c 100644 --- a/src/main/java/org/folio/service/pieces/flows/update/PieceUpdateFlowManager.java +++ b/src/main/java/org/folio/service/pieces/flows/update/PieceUpdateFlowManager.java @@ -15,7 +15,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.folio.models.pieces.PieceUpdateHolder; -import org.folio.orders.utils.HelperUtils; import org.folio.orders.utils.PoLineCommonUtil; import org.folio.rest.core.models.RequestContext; import org.folio.rest.jaxrs.model.CompositePoLine; @@ -118,7 +117,7 @@ protected Future<Void> updatePoLine(PieceUpdateHolder holder, RequestContext req } List<Piece> piecesToUpdate = List.of(holder.getPieceToUpdate()); CompositePoLine poLineToSave = holder.getPoLineToSave(); - if (PoLineCommonUtil.isCancelledOrOngoingStatus(HelperUtils.convertToPoLine(poLineToSave))) { + if (PoLineCommonUtil.isCancelledOrOngoingStatus(PoLineCommonUtil.convertToPoLine(poLineToSave))) { logger.info("updatePoLine:: Skipping updating POL '{}' status for CANCELLED or ONGOING po lines", poLineToSave.getId()); } else { poLineToSave.setReceiptStatus(calculatePoLineReceiptStatus(originPoLine, pieces, piecesToUpdate)); 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<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)); }