Skip to content

Commit

Permalink
Merge branch 'MODORDERS-1209' of github.com:folio-org/mod-orders into…
Browse files Browse the repository at this point in the history
… MODORDERS-1209
  • Loading branch information
BKadirkhodjaev committed Dec 9, 2024
2 parents b015700 + 1bfb9e8 commit 0f57567
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 120 deletions.
20 changes: 10 additions & 10 deletions src/main/java/org/folio/config/ApplicationConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -712,14 +712,14 @@ PurchaseOrderHelper purchaseOrderHelper(PurchaseOrderLineHelper purchaseOrderLin
ProtectionService protectionService, InventoryItemStatusSyncService itemStatusSyncService,
OpenCompositeOrderManager openCompositeOrderManager, PurchaseOrderStorageService purchaseOrderStorageService,
ConfigurationEntriesCache configurationEntriesCache, PoNumberHelper poNumberHelper,
OpenCompositeOrderFlowValidator openCompositeOrderFlowValidator,
ReOpenCompositeOrderManager reOpenCompositeOrderManager, OrderValidationService orderValidationService) {
OpenCompositeOrderFlowValidator openCompositeOrderFlowValidator, ReOpenCompositeOrderManager reOpenCompositeOrderManager,
OrderValidationService orderValidationService, CompositePoLineValidationService compositePoLineValidationService) {
return new PurchaseOrderHelper(purchaseOrderLineHelper, orderLinesSummaryPopulateService, encumbranceService,
combinedPopulateService, encumbranceWorkflowStrategyFactory, orderInvoiceRelationService, tagService,
purchaseOrderLineService, titlesService, protectionService, itemStatusSyncService,
openCompositeOrderManager, purchaseOrderStorageService, configurationEntriesCache,
poNumberHelper, openCompositeOrderFlowValidator, reOpenCompositeOrderManager,
orderValidationService);
orderValidationService, compositePoLineValidationService);
}

@Bean
Expand All @@ -746,18 +746,18 @@ PurchaseOrderLineHelper purchaseOrderLineHelper(InventoryItemStatusSyncService i
PurchaseOrderStorageService purchaseOrderStorageService,
RestClient restClient,
CompositePoLineValidationService compositePoLineValidationService,
POLInvoiceLineRelationService polInvoiceLineRelationService,
OrganizationService organizationService,
ConsortiumConfigurationService consortiumConfigurationService,
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever) {
OrganizationService organizationService) {
return new PurchaseOrderLineHelper(itemStatusSyncService, inventoryInstanceManager, encumbranceService, expenseClassValidationService,
encumbranceWorkflowStrategyFactory, orderInvoiceRelationService, titlesService, protectionService,
purchaseOrderLineService, purchaseOrderStorageService, restClient, compositePoLineValidationService,
organizationService, consortiumConfigurationService, consortiumUserTenantsRetriever);
organizationService);
}

@Bean CompositePoLineValidationService compositePoLineValidationService(ExpenseClassValidationService expenseClassValidationService) {
return new CompositePoLineValidationService(expenseClassValidationService);
@Bean
CompositePoLineValidationService compositePoLineValidationService(ExpenseClassValidationService expenseClassValidationService,
ConsortiumConfigurationService consortiumConfigurationService,
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever) {
return new CompositePoLineValidationService(expenseClassValidationService, consortiumConfigurationService, consortiumUserTenantsRetriever);
}

@Bean TitleValidationService titleValidationService() {
Expand Down
28 changes: 25 additions & 3 deletions src/main/java/org/folio/helper/PurchaseOrderHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import static org.folio.service.UserService.getCurrentUserId;
import static org.folio.service.orders.utils.StatusUtils.changeOrderStatusForOrderUpdate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -63,6 +64,7 @@
import org.folio.service.finance.transaction.EncumbranceWorkflowStrategyFactory;
import org.folio.service.inventory.InventoryItemStatusSyncService;
import org.folio.service.orders.CompositeOrderDynamicDataPopulateService;
import org.folio.service.orders.CompositePoLineValidationService;
import org.folio.service.orders.OrderInvoiceRelationService;
import org.folio.service.orders.OrderValidationService;
import org.folio.service.orders.OrderWorkflowType;
Expand All @@ -78,6 +80,7 @@
import io.vertx.core.json.JsonObject;

public class PurchaseOrderHelper {

private static final Logger logger = LogManager.getLogger(PurchaseOrderHelper.class);

private final PurchaseOrderLineHelper purchaseOrderLineHelper;
Expand All @@ -98,6 +101,7 @@ public class PurchaseOrderHelper {
private final PoNumberHelper poNumberHelper;
private final ReOpenCompositeOrderManager reOpenCompositeOrderManager;
private final OrderValidationService orderValidationService;
private final CompositePoLineValidationService compositePoLineValidationService;

public PurchaseOrderHelper(PurchaseOrderLineHelper purchaseOrderLineHelper,
CompositeOrderDynamicDataPopulateService orderLinesSummaryPopulateService, EncumbranceService encumbranceService,
Expand All @@ -109,7 +113,8 @@ public PurchaseOrderHelper(PurchaseOrderLineHelper purchaseOrderLineHelper,
OpenCompositeOrderManager openCompositeOrderManager, PurchaseOrderStorageService purchaseOrderStorageService,
ConfigurationEntriesCache configurationEntriesCache, PoNumberHelper poNumberHelper,
OpenCompositeOrderFlowValidator openCompositeOrderFlowValidator,
ReOpenCompositeOrderManager reOpenCompositeOrderManager, OrderValidationService orderValidationService) {
ReOpenCompositeOrderManager reOpenCompositeOrderManager, OrderValidationService orderValidationService,
CompositePoLineValidationService compositePoLineValidationService) {
this.purchaseOrderLineHelper = purchaseOrderLineHelper;
this.orderLinesSummaryPopulateService = orderLinesSummaryPopulateService;
this.encumbranceService = encumbranceService;
Expand All @@ -128,6 +133,7 @@ public PurchaseOrderHelper(PurchaseOrderLineHelper purchaseOrderLineHelper,
this.openCompositeOrderFlowValidator = openCompositeOrderFlowValidator;
this.reOpenCompositeOrderManager = reOpenCompositeOrderManager;
this.orderValidationService = orderValidationService;
this.compositePoLineValidationService = compositePoLineValidationService;
}

/**
Expand Down Expand Up @@ -224,9 +230,26 @@ public Future<Void> updateOrder(CompositePurchaseOrder compPO, boolean deleteHol
.map(HelperUtils::convertToCompositePurchaseOrder)
.compose(lines -> purchaseOrderLineService.populateOrderLines(lines, requestContext))
.compose(poFromStorage -> {
CompositePurchaseOrder clonedPoFromStorage = JsonObject.mapFrom(poFromStorage).mapTo(CompositePurchaseOrder.class);
boolean isTransitionToOpen = isTransitionToOpen(poFromStorage, compPO);
return orderValidationService.validateOrderForUpdate(compPO, poFromStorage, deleteHoldings, requestContext)
.compose(ok -> {
.compose(v -> {
var poLineFutures = new ArrayList<Future<Void>>();
if (!compPO.getCompositePoLines().isEmpty()) {
compPO.getCompositePoLines().forEach(poLine -> {
var compPoLineFromStorage = clonedPoFromStorage.getCompositePoLines().stream()
.filter(entry -> StringUtils.equals(entry.getId(), poLine.getId()))
.findFirst().orElse(null);
if (Objects.nonNull(compPoLineFromStorage)) {
var updatedLocations = poLine.getLocations();
var storedLocations = compPoLineFromStorage.getLocations();
poLineFutures.add(compositePoLineValidationService.validateUserUnaffiliatedLocationUpdates(poLine.getId(), updatedLocations, storedLocations, requestContext));
}
});
}
return collectResultsOnSuccess(poLineFutures);
})
.compose(v -> {
if (isTransitionToClosed(poFromStorage, compPO)) {
return closeOrder(compPO, poFromStorage, requestContext);
}
Expand All @@ -235,7 +258,6 @@ public Future<Void> updateOrder(CompositePurchaseOrder compPO, boolean deleteHol
.compose(v -> {
if (isTransitionToOpen) {
if (CollectionUtils.isEmpty(compPO.getCompositePoLines())) {
CompositePurchaseOrder clonedPoFromStorage = JsonObject.mapFrom(poFromStorage).mapTo(CompositePurchaseOrder.class);
compPO.setCompositePoLines(clonedPoFromStorage.getCompositePoLines());
}
compPO.getCompositePoLines().forEach(poLine -> PoLineCommonUtil.updateLocationsQuantity(poLine.getLocations()));
Expand Down
50 changes: 3 additions & 47 deletions src/main/java/org/folio/helper/PurchaseOrderLineHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
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.extractUnaffiliatedLocations;
import static org.folio.orders.utils.PoLineCommonUtil.updateLocationsQuantity;
import static org.folio.orders.utils.PoLineCommonUtil.verifyProtectedFieldsChanged;
import static org.folio.orders.utils.ProtectedOperationType.DELETE;
Expand Down Expand Up @@ -42,7 +41,6 @@

import io.vertx.core.json.JsonArray;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.SetUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand Down Expand Up @@ -70,14 +68,11 @@
import org.folio.rest.jaxrs.model.Error;
import org.folio.rest.jaxrs.model.Errors;
import org.folio.rest.jaxrs.model.FundDistribution;
import org.folio.rest.jaxrs.model.Location;
import org.folio.rest.jaxrs.model.Physical;
import org.folio.rest.jaxrs.model.PoLine;
import org.folio.rest.jaxrs.model.PoLineCollection;
import org.folio.rest.jaxrs.model.ReportingCode;
import org.folio.service.ProtectionService;
import org.folio.service.consortium.ConsortiumConfigurationService;
import org.folio.service.consortium.ConsortiumUserTenantsRetriever;
import org.folio.service.finance.expenceclass.ExpenseClassValidationService;
import org.folio.service.finance.transaction.EncumbranceService;
import org.folio.service.finance.transaction.EncumbranceWorkflowStrategy;
Expand All @@ -97,8 +92,8 @@
import io.vertx.core.json.JsonObject;

public class PurchaseOrderLineHelper {
private static final Logger logger = LogManager.getLogger(PurchaseOrderLineHelper.class);

private static final Logger logger = LogManager.getLogger(PurchaseOrderLineHelper.class);

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";
Expand All @@ -121,8 +116,6 @@ public class PurchaseOrderLineHelper {
private final RestClient restClient;
private final CompositePoLineValidationService compositePoLineValidationService;
private final OrganizationService organizationService;
private final ConsortiumConfigurationService consortiumConfigurationService;
private final ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever;

public PurchaseOrderLineHelper(InventoryItemStatusSyncService inventoryItemStatusSyncService,
InventoryInstanceManager inventoryInstanceManager,
Expand All @@ -136,9 +129,7 @@ public PurchaseOrderLineHelper(InventoryItemStatusSyncService inventoryItemStatu
PurchaseOrderStorageService purchaseOrderStorageService,
RestClient restClient,
CompositePoLineValidationService compositePoLineValidationService,
OrganizationService organizationService,
ConsortiumConfigurationService consortiumConfigurationService,
ConsortiumUserTenantsRetriever consortiumUserTenantsRetriever) {
OrganizationService organizationService) {

this.itemStatusSyncService = inventoryItemStatusSyncService;
this.inventoryInstanceManager = inventoryInstanceManager;
Expand All @@ -153,8 +144,6 @@ public PurchaseOrderLineHelper(InventoryItemStatusSyncService inventoryItemStatu
this.restClient = restClient;
this.compositePoLineValidationService = compositePoLineValidationService;
this.organizationService = organizationService;
this.consortiumConfigurationService = consortiumConfigurationService;
this.consortiumUserTenantsRetriever = consortiumUserTenantsRetriever;
}

/**
Expand Down Expand Up @@ -289,7 +278,7 @@ public Future<Void> updateOrderLine(CompositePoLine compOrderLine, RequestContex
.compose(compOrder -> protectionService.isOperationRestricted(compOrder.getAcqUnitIds(), UPDATE, requestContext)
.compose(v -> purchaseOrderLineService.validateAndNormalizeISBNAndProductType(Collections.singletonList(compOrderLine), requestContext))
.compose(v -> validateAccessProviders(compOrderLine, requestContext))
.compose(v -> validateUserUnaffiliatedLocationUpdates(compOrderLine, poLineFromStorage, requestContext))
.compose(v -> compositePoLineValidationService.validateUserUnaffiliatedLocationUpdates(compOrderLine.getId(), compOrderLine.getLocations(), poLineFromStorage.getLocations(), requestContext))
.compose(v -> expenseClassValidationService.validateExpenseClassesForOpenedOrder(compOrder, Collections.singletonList(compOrderLine), requestContext))
.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
Expand Down Expand Up @@ -733,39 +722,6 @@ private Future<Void> validateAccessProviders(CompositePoLine compOrderLine, Requ
.mapEmpty();
}

private Future<Void> validateUserUnaffiliatedLocationUpdates(CompositePoLine updatedPoLine, PoLine storedPoLine, RequestContext requestContext) {
return getUserTenantsIfNeeded(requestContext)
.compose(userTenants -> {
if (CollectionUtils.isEmpty(userTenants)) {
logger.info("validateUserUnaffiliatedLocationUpdates:: User tenants is empty");
return Future.succeededFuture();
}
var storageUnaffiliatedLocations = extractUnaffiliatedLocations(storedPoLine.getLocations(), userTenants);
var updatedUnaffiliatedLocations = extractUnaffiliatedLocations(updatedPoLine.getLocations(), userTenants);
logger.info("validateUserUnaffiliatedLocationUpdates:: Found unaffiliated POL location tenant ids, poLineId: '{}', stored: '{}', updated: '{}'",
updatedPoLine.getId(),
storageUnaffiliatedLocations.stream().map(Location::getTenantId).distinct().toList(),
updatedUnaffiliatedLocations.stream().map(Location::getTenantId).distinct().toList());
if (!SetUtils.isEqualSet(storageUnaffiliatedLocations, updatedUnaffiliatedLocations)) {
logger.info("validateUserUnaffiliatedLocationUpdates:: User is not affiliated with all locations on the POL, poLineId: '{}'",
updatedPoLine.getId());
return Future.failedFuture(new HttpException(422, ErrorCodes.LOCATION_UPDATE_WITHOUT_AFFILIATION));
}
logger.info("validateUserUnaffiliatedLocationUpdates:: User is affiliated with all locations on the POL, poLineId: '{}'",
updatedPoLine.getId());
return Future.succeededFuture();
});
}

private Future<List<String>> getUserTenantsIfNeeded(RequestContext requestContext) {
return consortiumConfigurationService.getConsortiumConfiguration(requestContext)
.compose(consortiumConfiguration ->
consortiumConfiguration
.map(configuration -> consortiumUserTenantsRetriever.getUserTenants(configuration.consortiumId(), configuration.centralTenantId(), requestContext))
.orElse(Future.succeededFuture())
);
}

private void validatePOLineProtectedFieldsChanged(CompositePoLine compOrderLine, PoLine poLineFromStorage, CompositePurchaseOrder purchaseOrder) {
if (purchaseOrder.getWorkflowStatus() != PENDING) {
verifyProtectedFieldsChanged(POLineProtectedFieldsUtil.getFieldNames(compOrderLine.getOrderFormat().value()), JsonObject.mapFrom(poLineFromStorage), JsonObject.mapFrom(compOrderLine));
Expand Down
Loading

0 comments on commit 0f57567

Please sign in to comment.