Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Modorders 970 #817

Merged
merged 4 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 29 additions & 31 deletions src/main/java/org/folio/orders/utils/HelperUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public static Integer calculateTotalLocationQuantity(Location location) {
*/
public static int calculateTotalQuantity(CompositePoLine compPOL) {
Cost cost = compPOL.getCost();
int eQuantity = ObjectUtils.defaultIfNull(cost.getQuantityElectronic(), 0);
int eQuantity = ObjectUtils.defaultIfNull(cost.getQuantityElectronic(), 0);
int physicalQuantity = ObjectUtils.defaultIfNull(cost.getQuantityPhysical(), 0);
return eQuantity + physicalQuantity;
}
Expand All @@ -177,7 +177,7 @@ public static int calculateInventoryItemsQuantity(CompositePoLine compPOL) {
/**
* Calculates items quantity for specified locations.
*
* @param compPOL composite PO Line
* @param compPOL composite PO Line
* @param locations list of locations to calculate quantity for
* @return quantity of items expected in the inventory for PO Line
* @see #calculateInventoryItemsQuantity(CompositePoLine)
Expand Down Expand Up @@ -297,27 +297,25 @@ public static MonetaryAmount calculateEncumbranceEffectiveAmount(MonetaryAmount
}

public static int getPhysicalLocationsQuantity(List<Location> locations) {
if (CollectionUtils.isNotEmpty(locations)) {
return locations.stream()
.map(Location::getQuantityPhysical)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
} else {
if (CollectionUtils.isEmpty(locations)) {
return 0;
}
return locations.stream()
.map(Location::getQuantityPhysical)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
}

public static int getElectronicLocationsQuantity(List<Location> locations) {
if (CollectionUtils.isNotEmpty(locations)) {
return locations.stream()
.map(Location::getQuantityElectronic)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
} else {
if (CollectionUtils.isEmpty(locations)) {
return 0;
}
return locations.stream()
.map(Location::getQuantityElectronic)
.filter(Objects::nonNull)
.mapToInt(Integer::intValue)
.sum();
}

/**
Expand Down Expand Up @@ -375,23 +373,24 @@ public static CompositePurchaseOrder convertToCompositePurchaseOrder(JsonObject
}

public static boolean changeOrderStatus(PurchaseOrder purchaseOrder, List<PoLine> poLines) {
boolean isUpdateRequired = false;

if (toBeCancelled(purchaseOrder, poLines)) {
purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.CLOSED);
purchaseOrder.setCloseReason(new CloseReason().withReason(REASON_CANCELLED));
return true;
}

if (toBeClosed(purchaseOrder, poLines)) {
isUpdateRequired = true;
purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.CLOSED);
purchaseOrder.setCloseReason(new CloseReason().withReason(REASON_COMPLETE));
} else if (toBeReopened(purchaseOrder, poLines)) {
isUpdateRequired = true;
return true;
}

if (toBeReopened(purchaseOrder, poLines)) {
purchaseOrder.setWorkflowStatus(PurchaseOrder.WorkflowStatus.OPEN);
return true;
}
return isUpdateRequired;

return false;
}

public static String convertTagListToCqlQuery(Collection<String> values, String fieldName, boolean strictMatch) {
Expand Down Expand Up @@ -468,8 +467,7 @@ public static void verifyTitles(Map<String, List<Title>> lineIdTitles, Map<Strin

private static void verifyNonPackageLinesHaveSingleTitle(Map<String, List<Title>> titles,
Map<String, CompositePoLine> poLineById) {
if (titles.keySet().stream().anyMatch(lineId -> titles.get(lineId).size() > 1 &&
!poLineById.get(lineId).getIsPackage())) {
if (titles.keySet().stream().anyMatch(lineId -> titles.get(lineId).size() > 1 && !poLineById.get(lineId).getIsPackage())) {
throw new HttpException(400, MULTIPLE_NONPACKAGE_TITLES);
}
}
Expand Down Expand Up @@ -498,17 +496,17 @@ public static ConversionQuery getConversionQuery(Double exchangeRate, String fro
}

public static void makePoLinePending(CompositePoLine poLine) {
if (poLine.getPaymentStatus() == CompositePoLine.PaymentStatus.AWAITING_PAYMENT) {
poLine.setPaymentStatus(CompositePoLine.PaymentStatus.PENDING);
}
if (poLine.getReceiptStatus() == CompositePoLine.ReceiptStatus.AWAITING_RECEIPT) {
poLine.setReceiptStatus(CompositePoLine.ReceiptStatus.PENDING);
}
if (poLine.getPaymentStatus() == CompositePoLine.PaymentStatus.AWAITING_PAYMENT) {
poLine.setPaymentStatus(CompositePoLine.PaymentStatus.PENDING);
}
if (poLine.getReceiptStatus() == CompositePoLine.ReceiptStatus.AWAITING_RECEIPT) {
poLine.setReceiptStatus(CompositePoLine.ReceiptStatus.PENDING);
}
}

public static ConversionQuery buildConversionQuery(PoLine poLine, String systemCurrency) {
Cost cost = poLine.getCost();
if (cost.getExchangeRate() != null){
if (cost.getExchangeRate() != null) {
return ConversionQueryBuilder.of().setBaseCurrency(cost.getCurrency())
.setTermCurrency(systemCurrency)
.set(RATE_KEY, cost.getExchangeRate()).build();
Expand Down
31 changes: 22 additions & 9 deletions src/main/java/org/folio/service/inventory/InventoryManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -1268,15 +1268,28 @@ private Future<List<JsonObject>> fetchHoldingsByFundIds(List<String> holdingIds,
});
}

private void updateItemWithPieceFields(Piece piece, JsonObject item) {
Optional.ofNullable(piece.getEnumeration())
.ifPresentOrElse(enumeration -> item.put(ITEM_ENUMERATION, enumeration), () -> item.remove(ITEM_ENUMERATION));
Optional.ofNullable(piece.getCopyNumber())
.ifPresentOrElse(copyNumber -> item.put(COPY_NUMBER, copyNumber), () -> item.remove(COPY_NUMBER));
Optional.ofNullable(piece.getChronology())
.ifPresentOrElse(chronology -> item.put(ITEM_CHRONOLOGY, chronology), () -> item.remove(ITEM_CHRONOLOGY));
Optional.ofNullable(piece.getDiscoverySuppress())
.ifPresentOrElse(discSup -> item.put(ITEM_DISCOVERY_SUPPRESS, discSup), () -> item.remove(ITEM_DISCOVERY_SUPPRESS));
void updateItemWithPieceFields(Piece piece, JsonObject item) {
if (StringUtils.isNotEmpty(piece.getEnumeration())) {
item.put(ITEM_ENUMERATION, piece.getEnumeration());
}
if (StringUtils.isNotEmpty(piece.getCopyNumber())) {
item.put(COPY_NUMBER, piece.getCopyNumber());
}
if (StringUtils.isNotEmpty(piece.getChronology())) {
item.put(ITEM_CHRONOLOGY, piece.getChronology());
}
if (StringUtils.isNotEmpty(piece.getBarcode())) {
item.put(ITEM_BARCODE, piece.getBarcode());
}
if (StringUtils.isNotEmpty(piece.getAccessionNumber())) {
item.put(ITEM_ACCESSION_NUMBER, piece.getAccessionNumber());
}
if (StringUtils.isNotEmpty(piece.getCallNumber())) {
item.put(ITEM_LEVEL_CALL_NUMBER, piece.getCallNumber());
}
if (piece.getDiscoverySuppress() != null) {
item.put(ITEM_DISCOVERY_SUPPRESS, piece.getDiscoverySuppress());
}
}

public Future<SharingInstance> createShadowInstanceIfNeeded(String instanceId, RequestContext requestContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static org.folio.service.inventory.InventoryManager.ID;
import static org.folio.service.inventory.InventoryManager.ITEM_HOLDINGS_RECORD_ID;
import static org.folio.service.inventory.InventoryManager.ITEM_PURCHASE_ORDER_LINE_IDENTIFIER;
import static org.folio.service.inventory.InventoryManager.COPY_NUMBER;

import java.util.Optional;

Expand Down Expand Up @@ -45,9 +44,7 @@ public Future<Void> processInventory(PieceUpdateHolder holder, RequestContext re
.compose(aVoid -> {
if (Boolean.TRUE.equals(holder.getOriginPoLine().getIsPackage())) {
return packagePoLineUpdateInventory(holder, requestContext);
}
else
{
} else {
return nonPackagePoLineUpdateInventory(holder, requestContext);
}
});
Expand Down Expand Up @@ -93,72 +90,70 @@ private Future<Location> handleHolding(PieceUpdateHolder holder, RequestContext
if (instanceId != null && DefaultPieceFlowsValidator.isCreateHoldingForPiecePossible(pieceToUpdate, poLineToSave)) {
Location location = new Location().withLocationId(pieceToUpdate.getLocationId());
return inventoryManager.getOrCreateHoldingsRecord(instanceId, location, requestContext)
.map(holdingId -> {
Optional.ofNullable(holdingId).ifPresent(holdingIdP -> {
pieceToUpdate.setLocationId(null);
pieceToUpdate.setHoldingId(holdingId);
location.setLocationId(null);
location.setHoldingId(holdingId);
});
return location;
});
.map(holdingId -> {
Optional.ofNullable(holdingId).ifPresent(holdingIdP -> {
pieceToUpdate.setLocationId(null);
pieceToUpdate.setHoldingId(holdingId);
location.setLocationId(null);
location.setHoldingId(holdingId);
});
return location;
});
}
return Future.succeededFuture(new Location().withLocationId(pieceToUpdate.getLocationId()));
}

private Future<String> handleItem(PieceUpdateHolder holder, RequestContext requestContext) {
CompositePoLine poLineToSave = holder.getPoLineToSave();
Piece pieceToUpdate = holder.getPieceToUpdate();
if (DefaultPieceFlowsValidator.isCreateItemForPiecePossible(pieceToUpdate, poLineToSave)) {
return inventoryManager.getItemRecordById(pieceToUpdate.getItemId(), true, requestContext)
.compose(jsonItem -> {
if (holder.isCreateItem() && (jsonItem == null || jsonItem.isEmpty()) && pieceToUpdate.getHoldingId() != null) {
if (!DefaultPieceFlowsValidator.isCreateItemForPiecePossible(pieceToUpdate, poLineToSave)) {
return Future.succeededFuture();
}
return inventoryManager.getItemRecordById(pieceToUpdate.getItemId(), true, requestContext)
.compose(jsonItem -> {
boolean jsonItemFound = jsonItem != null && !jsonItem.isEmpty();
if (holder.isCreateItem() && !jsonItemFound && pieceToUpdate.getHoldingId() != null) {
return pieceUpdateInventoryService.manualPieceFlowCreateItemRecord(pieceToUpdate, poLineToSave, requestContext);
} else if (jsonItem != null && !jsonItem.isEmpty()) {
return updateItemWithFields(jsonItem, poLineToSave, pieceToUpdate).compose(
aVoid -> inventoryManager.updateItem(jsonItem, requestContext).map(item -> jsonItem.getString(ID)));
} else {
return Future.succeededFuture();
}
if (jsonItemFound) {
return updateItemWithFields(jsonItem, poLineToSave, pieceToUpdate)
.compose(ignored -> inventoryManager.updateItem(jsonItem, requestContext).map(item -> jsonItem.getString(ID)));
}
return Future.succeededFuture();
});
}
return Future.succeededFuture();
}

private Future<Void> updateItemWithFields(JsonObject item, CompositePoLine compPOL, Piece piece) {
Optional.ofNullable(piece.getHoldingId())
.ifPresent(pieceHoldingId -> item.put(ITEM_HOLDINGS_RECORD_ID, piece.getHoldingId()));
Optional.ofNullable(piece.getCopyNumber())
.ifPresentOrElse(copyNumber -> item.put(COPY_NUMBER, copyNumber), () -> item.remove(COPY_NUMBER));
SerhiiNosko marked this conversation as resolved.
Show resolved Hide resolved
item.put(ITEM_PURCHASE_ORDER_LINE_IDENTIFIER, compPOL.getId());
return Future.succeededFuture();
}

private Future<String> nonPackageUpdateTitleWithInstance(PieceUpdateHolder holder, RequestContext requestContext) {
CompositePoLine poLineToSave = holder.getPoLineToSave();
Piece pieceToUpdate = holder.getPieceToUpdate();
if (poLineToSave.getInstanceId() == null && !PoLineCommonUtil.isInventoryUpdateNotRequired(poLineToSave)) {
return titlesService.getTitleById(pieceToUpdate.getTitleId(), requestContext)
.compose(title -> {
if (title.getInstanceId() == null) {
return createTitleInstance(title, requestContext);
}
return Future.succeededFuture(title.getInstanceId());
})
.map(instanceId -> poLineToSave.withInstanceId(instanceId).getInstanceId());
if (poLineToSave.getInstanceId() != null || PoLineCommonUtil.isInventoryUpdateNotRequired(poLineToSave)) {
return Future.succeededFuture(poLineToSave.getInstanceId());
}
return Future.succeededFuture(poLineToSave.getInstanceId());
return titlesService.getTitleById(pieceToUpdate.getTitleId(), requestContext)
.compose(title -> {
if (title.getInstanceId() == null) {
return createTitleInstance(title, requestContext);
}
return Future.succeededFuture(title.getInstanceId());
})
.map(instanceId -> poLineToSave.withInstanceId(instanceId).getInstanceId());
}

private Future<Title> packageUpdateTitleWithInstance(Title title, RequestContext requestContext) {
if (title.getInstanceId() != null) {
return Future.succeededFuture(title);
} else {
return inventoryManager.getOrCreateInstanceRecord(title, requestContext)
.map(title::withInstanceId)
.compose(titleWithInstanceId -> titlesService.saveTitle(titleWithInstanceId, requestContext))
.map(v -> title);
}
return inventoryManager.getOrCreateInstanceRecord(title, requestContext)
.map(title::withInstanceId)
.compose(titleWithInstanceId -> titlesService.saveTitle(titleWithInstanceId, requestContext))
.map(v -> title);
}

private Future<String> createTitleInstance(Title title, RequestContext requestContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,24 @@
import static org.folio.rest.impl.PurchaseOrderLinesApiTest.COMP_PO_LINES_MOCK_DATA_PATH;
import static org.folio.rest.impl.PurchaseOrdersApiTest.X_OKAPI_TENANT;
import static org.folio.rest.jaxrs.model.Eresource.CreateInventory.INSTANCE_HOLDING;
import static org.folio.service.inventory.InventoryManager.COPY_NUMBER;
import static org.folio.service.inventory.InventoryManager.HOLDINGS_RECORDS;
import static org.folio.service.inventory.InventoryManager.HOLDINGS_SOURCES;
import static org.folio.service.inventory.InventoryManager.HOLDING_PERMANENT_LOCATION_ID;
import static org.folio.service.inventory.InventoryManager.ID;
import static org.folio.service.inventory.InventoryManager.ITEMS;
import static org.folio.service.inventory.InventoryManager.ITEM_ACCESSION_NUMBER;
import static org.folio.service.inventory.InventoryManager.ITEM_BARCODE;
import static org.folio.service.inventory.InventoryManager.ITEM_CHRONOLOGY;
import static org.folio.service.inventory.InventoryManager.ITEM_DISCOVERY_SUPPRESS;
import static org.folio.service.inventory.InventoryManager.ITEM_ENUMERATION;
import static org.folio.service.inventory.InventoryManager.ITEM_LEVEL_CALL_NUMBER;
import static org.folio.service.inventory.InventoryManager.ITEM_PURCHASE_ORDER_LINE_IDENTIFIER;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -492,6 +500,71 @@ void testShouldBuildInstanceWithFieldFromTitles() {
verify(title).getProductIds();
}

@Test
void testUpdateItemWithPieceFields() {
// given
Piece piece = new Piece();
piece.setEnumeration("enumeration");
piece.setCopyNumber("copy number");
piece.setChronology("chronology");
piece.setBarcode("barcode");
piece.setAccessionNumber("accession number");
piece.setCallNumber("call number");
piece.setDiscoverySuppress(true);

String oldValue = "old value";
JsonObject item = new JsonObject(new HashMap<>(Map.of(
ITEM_ENUMERATION, oldValue,
COPY_NUMBER, oldValue,
ITEM_CHRONOLOGY, oldValue,
ITEM_BARCODE, oldValue,
ITEM_ACCESSION_NUMBER, oldValue,
ITEM_LEVEL_CALL_NUMBER, oldValue,
ITEM_DISCOVERY_SUPPRESS, false
)));

// when
inventoryManager.updateItemWithPieceFields(piece, item);

// then
assertEquals(piece.getEnumeration(), item.getString(ITEM_ENUMERATION));
assertEquals(piece.getCopyNumber(), item.getString(COPY_NUMBER));
assertEquals(piece.getChronology(), item.getString(ITEM_CHRONOLOGY));
assertEquals(piece.getBarcode(), item.getString(ITEM_BARCODE));
assertEquals(piece.getAccessionNumber(), item.getString(ITEM_ACCESSION_NUMBER));
assertEquals(piece.getCallNumber(), item.getString(ITEM_LEVEL_CALL_NUMBER));
assertEquals(piece.getDiscoverySuppress(), item.getBoolean(ITEM_DISCOVERY_SUPPRESS));
}

@Test
void testUpdateItemWithPieceFields_notOverwrite() {
// given
Piece piece = new Piece();

String oldValue = "old value";
JsonObject item = new JsonObject(new HashMap<>(Map.of(
ITEM_ENUMERATION, oldValue,
COPY_NUMBER, oldValue,
ITEM_CHRONOLOGY, oldValue,
ITEM_BARCODE, oldValue,
ITEM_ACCESSION_NUMBER, oldValue,
ITEM_LEVEL_CALL_NUMBER, oldValue,
ITEM_DISCOVERY_SUPPRESS, false
)));

// when
inventoryManager.updateItemWithPieceFields(piece, item);

// then
assertEquals(oldValue, item.getString(ITEM_ENUMERATION));
assertEquals(oldValue, item.getString(COPY_NUMBER));
assertEquals(oldValue, item.getString(ITEM_CHRONOLOGY));
assertEquals(oldValue, item.getString(ITEM_BARCODE));
assertEquals(oldValue, item.getString(ITEM_ACCESSION_NUMBER));
assertEquals(oldValue, item.getString(ITEM_LEVEL_CALL_NUMBER));
assertFalse(item.getBoolean(ITEM_DISCOVERY_SUPPRESS));
}

@Test
void shouldCheckIfTheHoldingExistsWhenHoldingIdSpecifiedAndIfExistThenReturnHoldingIdFromLocation() throws IOException {
String instanceId = UUID.randomUUID().toString();
Expand Down