Skip to content

Commit

Permalink
[MODORDERS-1108] Update PiecesAPI CRUD methods to process inventory i…
Browse files Browse the repository at this point in the history
…n desired tenant (#942)

* [MODORDERS-1108] Refactor PieceCreateFlowInventoryManager

* [MODORDERS-1108] Refactor PieceDeleteFlowManager

* [MODORDERS-1108] Split PieceDeleteFlowManager and create PieceDeleteFlowInventoryManager

* [MODORDERS-1108] Refactor PieceUpdateFlowInventoryManager

* [MODORDERS-1108] Fix failing PieceUpdate/CreateFlowInventoryManagerTest

* [MODORDERS-1108] Fix failing PieceCreateFlowInventoryManagerTest

* [MODORDERS-1108] Rebuild

* [MODORDERS-1108] Add support for mulitenant

* [MODORDERS-1108]  a small bug in binding

* [MODORDERS-1112] Remove redundant code

* [MODORDERS-1112] Make code readable, add PieceDeleteInventoryService, pass missed locationContext

* [MODORDERS-1112] Static import createContextWithNewTenantId

* [MODORDERS-1112] Update acq-models

* [MODORDERS-1112] Minor refactoring

* [MODORDERS-1122] Change correct attribute

* [MODORDERS-1108] Remove BooleanUtils

* [MODORDERS-1108] Replace TRUE with FALSE checks

* Revert "[MODORDERS-1108] Replace TRUE with FALSE checks"

This reverts commit 3132594.
  • Loading branch information
Saba-Zedginidze-EPAM authored May 27, 2024
1 parent fc5216f commit 241b810
Show file tree
Hide file tree
Showing 15 changed files with 349 additions and 348 deletions.
2 changes: 1 addition & 1 deletion ramls/acq-models
Submodule acq-models updated 0 files
67 changes: 46 additions & 21 deletions src/main/java/org/folio/config/ApplicationConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
import org.folio.service.orders.lines.update.instance.WithoutHoldingOrderLineUpdateInstanceStrategy;
import org.folio.service.organization.OrganizationService;
import org.folio.service.pieces.PieceChangeReceiptStatusPublisher;
import org.folio.service.pieces.PieceDeleteInventoryService;
import org.folio.service.pieces.PieceService;
import org.folio.service.pieces.PieceStorageService;
import org.folio.service.pieces.PieceUpdateInventoryService;
Expand All @@ -108,6 +109,7 @@
import org.folio.service.pieces.flows.create.PieceCreateFlowInventoryManager;
import org.folio.service.pieces.flows.create.PieceCreateFlowManager;
import org.folio.service.pieces.flows.create.PieceCreateFlowPoLineService;
import org.folio.service.pieces.flows.delete.PieceDeleteFlowInventoryManager;
import org.folio.service.pieces.flows.delete.PieceDeleteFlowManager;
import org.folio.service.pieces.flows.delete.PieceDeleteFlowPoLineService;
import org.folio.service.pieces.flows.strategies.ProcessInventoryElectronicStrategy;
Expand Down Expand Up @@ -521,26 +523,34 @@ PieceChangeReceiptStatusPublisher receiptStatusPublisher() {
return new PieceChangeReceiptStatusPublisher();
}

@Bean PieceStorageService pieceStorageService(RestClient restClient) {
@Bean
PieceStorageService pieceStorageService(RestClient restClient) {
return new PieceStorageService(restClient);
}

@Bean PieceService piecesService(PieceChangeReceiptStatusPublisher receiptStatusPublisher) {
@Bean
PieceService piecesService(PieceChangeReceiptStatusPublisher receiptStatusPublisher) {
return new PieceService(receiptStatusPublisher);
}

@Bean DefaultPieceFlowsValidator pieceCreateFlowValidator() {
@Bean
DefaultPieceFlowsValidator pieceCreateFlowValidator() {
return new DefaultPieceFlowsValidator();
}

@Bean PieceCreateFlowPoLineService pieceCreateFlowPoLineService(PurchaseOrderStorageService purchaseOrderStorageService,
PurchaseOrderLineService purchaseOrderLineService, ReceivingEncumbranceStrategy receivingEncumbranceStrategy) {
@Bean
PieceCreateFlowPoLineService pieceCreateFlowPoLineService(PurchaseOrderStorageService purchaseOrderStorageService,
PurchaseOrderLineService purchaseOrderLineService,
ReceivingEncumbranceStrategy receivingEncumbranceStrategy) {
return new PieceCreateFlowPoLineService(purchaseOrderStorageService, purchaseOrderLineService, receivingEncumbranceStrategy);
}

@Bean PieceCreateFlowManager pieceCreationService(PieceStorageService pieceStorageService, ProtectionService protectionService,
PieceCreateFlowInventoryManager pieceCreateFlowInventoryManager, DefaultPieceFlowsValidator defaultPieceFlowsValidator,
PieceCreateFlowPoLineService pieceCreateFlowPoLineService, BasePieceFlowHolderBuilder basePieceFlowHolderBuilder) {
@Bean
PieceCreateFlowManager pieceCreationService(PieceStorageService pieceStorageService, ProtectionService protectionService,
PieceCreateFlowInventoryManager pieceCreateFlowInventoryManager,
DefaultPieceFlowsValidator defaultPieceFlowsValidator,
PieceCreateFlowPoLineService pieceCreateFlowPoLineService,
BasePieceFlowHolderBuilder basePieceFlowHolderBuilder) {
return new PieceCreateFlowManager(pieceStorageService, protectionService, pieceCreateFlowInventoryManager,
defaultPieceFlowsValidator, pieceCreateFlowPoLineService, basePieceFlowHolderBuilder);
}
Expand Down Expand Up @@ -580,36 +590,51 @@ PieceUpdateInventoryService pieceUpdateInventoryService(InventoryItemManager inv
return new PieceUpdateInventoryService(inventoryItemManager, inventoryHoldingManager, pieceStorageService);
}

@Bean PieceDeleteFlowPoLineService pieceDeleteFlowPoLineService(PurchaseOrderStorageService purchaseOrderStorageService,
@Bean
PieceDeleteInventoryService pieceDeleteInventoryService(InventoryItemManager inventoryItemManager) {
return new PieceDeleteInventoryService(inventoryItemManager);
}

@Bean
PieceDeleteFlowPoLineService pieceDeleteFlowPoLineService(PurchaseOrderStorageService purchaseOrderStorageService,
PurchaseOrderLineService purchaseOrderLineService, ReceivingEncumbranceStrategy receivingEncumbranceStrategy) {
return new PieceDeleteFlowPoLineService(purchaseOrderStorageService, purchaseOrderLineService, receivingEncumbranceStrategy);
}

@Bean PieceDeleteFlowManager pieceDeletionFlowManager(PieceStorageService pieceStorageService,
ProtectionService protectionService,
InventoryItemManager inventoryItemManager,
PieceUpdateInventoryService pieceUpdateInventoryService,
PieceDeleteFlowPoLineService pieceDeleteFlowPoLineService,
BasePieceFlowHolderBuilder basePieceFlowHolderBuilder,
CirculationRequestsRetriever circulationRequestsRetriever) {
return new PieceDeleteFlowManager(pieceStorageService, protectionService, inventoryItemManager, pieceUpdateInventoryService,
pieceDeleteFlowPoLineService, basePieceFlowHolderBuilder, circulationRequestsRetriever);
@Bean
PieceDeleteFlowManager pieceDeletionFlowManager(PieceDeleteFlowInventoryManager pieceDeleteFlowInventoryManager,
PieceStorageService pieceStorageService,
ProtectionService protectionService,
PieceDeleteFlowPoLineService pieceDeleteFlowPoLineService,
BasePieceFlowHolderBuilder basePieceFlowHolderBuilder,
CirculationRequestsRetriever circulationRequestsRetriever) {
return new PieceDeleteFlowManager(pieceDeleteFlowInventoryManager, pieceStorageService, protectionService,
pieceDeleteFlowPoLineService, basePieceFlowHolderBuilder, circulationRequestsRetriever);
}

@Bean
PieceDeleteFlowInventoryManager pieceDeleteFlowInventoryManager(PieceDeleteInventoryService pieceDeleteInventoryService,
PieceUpdateInventoryService pieceUpdateInventoryService) {
return new PieceDeleteFlowInventoryManager(pieceDeleteInventoryService, pieceUpdateInventoryService);
}


@Bean BasePieceFlowHolderBuilder basePieceFlowHolderBuilder(PurchaseOrderStorageService purchaseOrderStorageService,
@Bean
BasePieceFlowHolderBuilder basePieceFlowHolderBuilder(PurchaseOrderStorageService purchaseOrderStorageService,
PurchaseOrderLineService purchaseOrderLineService, TitlesService titlesService) {
return new BasePieceFlowHolderBuilder(purchaseOrderStorageService, purchaseOrderLineService, titlesService);
}

@Bean PieceUpdateFlowPoLineService pieceUpdateFlowPoLineService(PurchaseOrderStorageService purchaseOrderStorageService, PurchaseOrderLineService purchaseOrderLineService,
@Bean
PieceUpdateFlowPoLineService pieceUpdateFlowPoLineService(PurchaseOrderStorageService purchaseOrderStorageService, PurchaseOrderLineService purchaseOrderLineService,
ReceivingEncumbranceStrategy receivingEncumbranceStrategy, PieceDeleteFlowPoLineService pieceDeleteFlowPoLineService,
PieceCreateFlowPoLineService pieceCreateFlowPoLineService) {
return new PieceUpdateFlowPoLineService(purchaseOrderStorageService, purchaseOrderLineService, receivingEncumbranceStrategy,
pieceCreateFlowPoLineService, pieceDeleteFlowPoLineService);
}

@Bean PieceUpdateFlowManager pieceUpdateFlowManager(PieceStorageService pieceStorageService, PieceService pieceService, ProtectionService protectionService,
@Bean
PieceUpdateFlowManager pieceUpdateFlowManager(PieceStorageService pieceStorageService, PieceService pieceService, ProtectionService protectionService,
PieceUpdateFlowPoLineService pieceUpdateFlowPoLineService, PieceUpdateFlowInventoryManager pieceUpdateFlowInventoryManager,
BasePieceFlowHolderBuilder basePieceFlowHolderBuilder, DefaultPieceFlowsValidator defaultPieceFlowsValidator,
PurchaseOrderLineService purchaseOrderLineService) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static java.util.stream.Collectors.toList;
import static org.folio.orders.utils.HelperUtils.calculateInventoryItemsQuantity;
import static org.folio.orders.utils.HelperUtils.collectResultsOnSuccess;
import static org.folio.orders.utils.RequestContextUtil.createContextWithNewTenantId;

import java.util.ArrayList;
import java.util.Date;
Expand All @@ -23,6 +24,7 @@
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.jaxrs.model.CompositePoLine;
import org.folio.rest.jaxrs.model.Piece;
import org.folio.rest.jaxrs.model.Title;
import org.folio.service.ProtectionService;
import org.folio.service.inventory.InventoryHoldingManager;
import org.folio.service.inventory.InventoryItemManager;
Expand Down Expand Up @@ -161,36 +163,30 @@ public Future<Void> updatePieceRecord(Piece piece, RequestContext requestContext
* @return CompletableFuture with void.
*/
public Future<Void> openOrderUpdateInventory(CompositePoLine compPOL, Piece piece, boolean isInstanceMatchingDisabled, RequestContext requestContext) {
if (Boolean.TRUE.equals(compPOL.getIsPackage())) {
return titlesService.getTitleById(piece.getTitleId(), requestContext)
.compose(title -> titlesService.updateTitleWithInstance(title, isInstanceMatchingDisabled, requestContext).map(title::withInstanceId))
.compose(title -> {
if (piece.getHoldingId() != null) {
return Future.succeededFuture(piece.getHoldingId());
}
if (!PoLineCommonUtil.isHoldingsUpdateRequired(compPOL)) {
return Future.succeededFuture();
}
return inventoryHoldingManager.createHoldingAndReturnId(title.getInstanceId(), piece.getLocationId(), requestContext)
.map(holdingId -> {
piece.setLocationId(null);
piece.setHoldingId(holdingId);
return holdingId;
});
})
.compose(holdingId -> {
if (PoLineCommonUtil.isItemsUpdateRequired(compPOL)) {
return inventoryItemManager.openOrderCreateItemRecord(compPOL, holdingId, requestContext);
}
return Future.succeededFuture();
})
.onSuccess(itemId -> Optional.ofNullable(itemId).ifPresent(piece::withItemId))
.mapEmpty();
}
else
{
if (!Boolean.TRUE.equals(compPOL.getIsPackage())) {
return inventoryItemManager.updateItemWithPieceFields(piece, requestContext);
}
var locationContext = createContextWithNewTenantId(requestContext, piece.getReceivingTenantId());
return titlesService.getTitleById(piece.getTitleId(), requestContext)
.compose(title -> titlesService.updateTitleWithInstance(title, isInstanceMatchingDisabled, locationContext, requestContext).map(title::withInstanceId))
.compose(title -> getOrCreateHolding(compPOL, piece, title, locationContext))
.compose(holdingId -> updateItemsIfNeeded(compPOL, holdingId, locationContext))
.map(itemId -> Optional.ofNullable(itemId).map(piece::withItemId))
.mapEmpty();
}

private Future<String> getOrCreateHolding(CompositePoLine compPOL, Piece piece, Title title, RequestContext locationContext) {
if (piece.getHoldingId() != null || !PoLineCommonUtil.isHoldingsUpdateRequired(compPOL)) {
return Future.succeededFuture(piece.getHoldingId());
}
return inventoryHoldingManager.createHoldingAndReturnId(title.getInstanceId(), piece.getLocationId(), locationContext)
.map(holdingId -> piece.withLocationId(null).withHoldingId(holdingId).getHoldingId());
}

private Future<String> updateItemsIfNeeded(CompositePoLine compPOL, String holdingId, RequestContext locationContext) {
return PoLineCommonUtil.isItemsUpdateRequired(compPOL)
? inventoryItemManager.openOrderCreateItemRecord(compPOL, holdingId, locationContext)
: Future.succeededFuture();
}

private void validateItemsCreation(CompositePoLine compPOL, int itemsSize) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.folio.service.pieces;

import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import org.apache.commons.lang3.StringUtils;
import org.folio.models.ItemStatus;
import org.folio.models.pieces.PieceDeletionHolder;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.jaxrs.model.Piece;
import org.folio.service.inventory.InventoryItemManager;

import java.util.Optional;

import static org.folio.service.inventory.InventoryItemManager.ITEM_STATUS;
import static org.folio.service.inventory.InventoryItemManager.ITEM_STATUS_NAME;

public class PieceDeleteInventoryService {

private final InventoryItemManager inventoryItemManager;

public PieceDeleteInventoryService(InventoryItemManager inventoryItemManager) {
this.inventoryItemManager = inventoryItemManager;
}

public Future<Void> deleteItem(PieceDeletionHolder holder, RequestContext requestContext) {
var piece = holder.getPieceToDelete();
return getOnOrderItemForPiece(piece, requestContext)
.compose(item -> Optional.ofNullable(item)
.map(mItem -> inventoryItemManager.deleteItem(piece.getItemId(), true, requestContext))
.orElse(Future.succeededFuture()));
}

private Future<JsonObject> getOnOrderItemForPiece(Piece piece, RequestContext requestContext) {
if (StringUtils.isEmpty(piece.getItemId())) {
return Future.succeededFuture();
}
return inventoryItemManager.getItemRecordById(piece.getItemId(), true, requestContext)
.map(item -> getItemWithStatus(item, ItemStatus.ON_ORDER.value()));
}

private JsonObject getItemWithStatus(JsonObject item, String status) {
return Optional.ofNullable(item)
.map(itemObj -> itemObj.getJsonObject(ITEM_STATUS))
.filter(itemStatus -> status.equalsIgnoreCase(itemStatus.getString(ITEM_STATUS_NAME)))
.orElse(null);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.folio.service.pieces;

import static org.folio.orders.utils.RequestContextUtil.createContextWithNewTenantId;
import static org.folio.service.inventory.InventoryHoldingManager.HOLDING_PERMANENT_LOCATION_ID;

import java.util.List;
Expand Down Expand Up @@ -62,32 +63,42 @@ public Future<String> manualPieceFlowCreateItemRecord(Piece piece, CompositePoLi
}

public Future<Pair<String, String>> deleteHoldingConnectedToPiece(Piece piece, RequestContext requestContext) {
if (piece != null && piece.getHoldingId() != null) {
if (piece == null || piece.getHoldingId() == null) {
return Future.succeededFuture();
}
var locationContext = createContextWithNewTenantId(requestContext, piece.getReceivingTenantId());
String holdingId = piece.getHoldingId();
return inventoryHoldingManager.getHoldingById(holdingId, true, requestContext)
.compose(holding -> {
if (holding != null && !holding.isEmpty()) {
return pieceStorageService.getPiecesByHoldingId(holdingId, requestContext)
.map(pieces -> skipPieceToProcess(piece, pieces))
.compose(existingPieces -> inventoryItemManager.getItemsByHoldingId(holdingId, requestContext)
.map(existingItems-> {
List<Piece> remainingPieces = skipPieceToProcess(piece, existingPieces);
if (CollectionUtils.isEmpty(remainingPieces) && CollectionUtils.isEmpty(existingItems)) {
return Pair.of(true, holding);
}
return Pair.of(false, new JsonObject());
}));
}
return Future.succeededFuture(Pair.of(false, new JsonObject()));
})
.compose(isUpdatePossibleVsHolding -> {
if (isUpdatePossibleVsHolding.getKey() && !isUpdatePossibleVsHolding.getValue().isEmpty()) {
String permanentLocationId = isUpdatePossibleVsHolding.getValue().getString(HOLDING_PERMANENT_LOCATION_ID);
return inventoryHoldingManager.deleteHoldingById(holdingId, true, requestContext)
.map(v -> Pair.of(holdingId, permanentLocationId));
}
return Future.succeededFuture();
});
return inventoryHoldingManager.getHoldingById(holdingId, true, locationContext)
.compose(holding -> getUpdatePossibleForHolding(holding, holdingId, piece, locationContext, requestContext))
.compose(isUpdatePossibleVsHolding -> deleteHoldingIfPossible(isUpdatePossibleVsHolding, holdingId, locationContext));
}

private Future<Pair<Boolean, JsonObject>> getUpdatePossibleForHolding(JsonObject holding, String holdingId, Piece piece,
RequestContext locationContext, RequestContext requestContext) {
if (holding == null || holding.isEmpty()) {
return Future.succeededFuture(Pair.of(false, new JsonObject()));
}
return pieceStorageService.getPiecesByHoldingId(holdingId, requestContext)
.map(pieces -> skipPieceToProcess(piece, pieces))
.compose(existingPieces -> inventoryItemManager.getItemsByHoldingId(holdingId, locationContext)
.map(existingItems-> {
List<Piece> remainingPieces = skipPieceToProcess(piece, existingPieces);
if (CollectionUtils.isEmpty(remainingPieces) && CollectionUtils.isEmpty(existingItems)) {
return Pair.of(true, holding);
}
return Pair.of(false, new JsonObject());
})
);
}

private Future<Pair<String, String>> deleteHoldingIfPossible(Pair<Boolean, JsonObject> isUpdatePossibleVsHolding,
String holdingId, RequestContext locationContext) {
var isUpdatePossible = isUpdatePossibleVsHolding.getKey();
var holding = isUpdatePossibleVsHolding.getValue();
if (isUpdatePossible && !holding.isEmpty()) {
String permanentLocationId = holding.getString(HOLDING_PERMANENT_LOCATION_ID);
return inventoryHoldingManager.deleteHoldingById(holdingId, true, locationContext)
.map(v -> Pair.of(holdingId, permanentLocationId));
}
return Future.succeededFuture();
}
Expand Down
Loading

0 comments on commit 241b810

Please sign in to comment.