use of org.folio.rest.jaxrs.model.Physical in project mod-orders by folio-org.
the class CompositePoLineValidationUtilTest method shouldReturnErrorIfLocationAndHoldingReferenceArePresentAtTheSameTimeInTheLocation.
@Test
@DisplayName("Should return error if location and holding reference are not present in the location")
void shouldReturnErrorIfLocationAndHoldingReferenceArePresentAtTheSameTimeInTheLocation() {
Location location1 = new Location().withHoldingId(UUID.randomUUID().toString()).withLocationId(UUID.randomUUID().toString()).withQuantity(1).withQuantityPhysical(1);
Location location2 = new Location().withHoldingId(UUID.randomUUID().toString()).withLocationId(UUID.randomUUID().toString()).withQuantity(1).withQuantityPhysical(1);
Physical physical = new Physical().withCreateInventory(Physical.CreateInventory.INSTANCE_HOLDING_ITEM);
Cost cost = new Cost().withQuantityPhysical(2);
CompositePoLine compositePoLine = new CompositePoLine().withPhysical(physical).withCost(cost).withLocations(List.of(location1, location2));
List<Error> errors = CompositePoLineValidationUtil.validateLocations(compositePoLine);
assertEquals(2, errors.size());
errors.forEach(error -> {
assertEquals(ErrorCodes.MAY_BE_LINK_TO_EITHER_HOLDING_OR_LOCATION_ERROR.getCode(), error.getCode());
});
}
use of org.folio.rest.jaxrs.model.Physical in project mod-orders by folio-org.
the class OpenCompositeOrderPieceServiceTest method shouldCreatePieceWithLocationAndHoldingReferenceIfMixedLineContainsLocationAndInventoryIsInstanceOrNoneAndNoCreatedPieces.
@ParameterizedTest
@CsvSource(value = { "P/E Mix:Instance:Instance, Holding:2:3", "P/E Mix:None:Instance, Holding:2:3" }, delimiter = ':')
void shouldCreatePieceWithLocationAndHoldingReferenceIfMixedLineContainsLocationAndInventoryIsInstanceOrNoneAndNoCreatedPieces(String lineType, String elecCreateInventory, String physCreateInventory, int elecQty1, int physQty2) {
// given
String lineId = UUID.randomUUID().toString();
String locationId1 = UUID.randomUUID().toString();
String holdingId = UUID.randomUUID().toString();
String titleId = UUID.randomUUID().toString();
Location location1 = new Location().withLocationId(locationId1).withQuantityElectronic(elecQty1).withQuantity(elecQty1);
Location location2 = new Location().withHoldingId(holdingId).withQuantityPhysical(physQty2).withQuantity(physQty2);
Cost cost = new Cost().withQuantityElectronic(elecQty1 + physQty2);
Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.fromValue(elecCreateInventory));
Physical physical = new Physical().withCreateInventory(Physical.CreateInventory.fromValue(physCreateInventory));
CompositePoLine line = new CompositePoLine().withId(lineId).withCost(cost).withLocations(List.of(location1, location2)).withIsPackage(false).withEresource(eresource).withPhysical(physical).withOrderFormat(CompositePoLine.OrderFormat.fromValue(lineType));
CompositePurchaseOrder compOrder = new CompositePurchaseOrder().withCompositePoLines(List.of(line));
doReturn(completedFuture(null)).when(openCompositeOrderPieceService).openOrderUpdateInventory(any(CompositePoLine.class), any(Piece.class), any(Boolean.class), eq(requestContext));
doReturn(completedFuture(Collections.emptyList())).when(pieceStorageService).getPiecesByPoLineId(line, requestContext);
doReturn(completedFuture(new Piece())).when(pieceStorageService).insertPiece(any(Piece.class), eq(requestContext));
doReturn(completedFuture(null)).when(protectionService).isOperationRestricted(any(List.class), any(ProtectedOperationType.class), eq(requestContext));
doReturn(completedFuture(compOrder)).when(purchaseOrderStorageService).getCompositeOrderByPoLineId(eq(lineId), eq(requestContext));
final ArgumentCaptor<Piece> pieceArgumentCaptor = ArgumentCaptor.forClass(Piece.class);
doAnswer((Answer<CompletableFuture<Piece>>) invocation -> {
Piece piece = invocation.getArgument(0);
return completedFuture(piece);
}).when(pieceStorageService).insertPiece(pieceArgumentCaptor.capture(), eq(requestContext));
// When
List<Piece> createdPieces = openCompositeOrderPieceService.handlePieces(line, titleId, Collections.emptyList(), false, requestContext).join();
// Then
List<Piece> piecesLoc1 = createdPieces.stream().filter(piece -> locationId1.equals(piece.getLocationId())).collect(toList());
assertEquals(elecQty1, piecesLoc1.size());
piecesLoc1.forEach(piece -> {
assertNull(piece.getHoldingId());
assertNull(piece.getItemId());
assertEquals(lineId, piece.getPoLineId());
assertEquals(titleId, piece.getTitleId());
assertEquals(Piece.Format.ELECTRONIC, piece.getFormat());
});
List<Piece> piecesLoc2 = createdPieces.stream().filter(piece -> holdingId.equals(piece.getHoldingId())).collect(toList());
assertEquals(physQty2, piecesLoc2.size());
piecesLoc2.forEach(piece -> {
assertNull(piece.getLocationId());
assertNull(piece.getItemId());
assertEquals(lineId, piece.getPoLineId());
assertEquals(titleId, piece.getTitleId());
assertEquals(Piece.Format.PHYSICAL, piece.getFormat());
});
}
use of org.folio.rest.jaxrs.model.Physical in project mod-orders by folio-org.
the class OpenCompositeOrderPieceServiceTest method shouldCreatePieceWithLocationAndHoldingReferenceIfMixedLineContainsLocationAndInventoryIsInstanceOrNoneAndExistPiecesWithItems.
@ParameterizedTest
@CsvSource(value = { "P/E Mix:Instance:Instance, Holding, Item:2:3", "P/E Mix:None:Instance, Holding, Item:2:3" }, delimiter = ':')
void shouldCreatePieceWithLocationAndHoldingReferenceIfMixedLineContainsLocationAndInventoryIsInstanceOrNoneAndExistPiecesWithItems(String lineType, String elecCreateInventory, String physCreateInventory, int elecQty1, int physQty2) {
// given
String lineId = UUID.randomUUID().toString();
String locationId = UUID.randomUUID().toString();
String holdingId = UUID.randomUUID().toString();
String titleId = UUID.randomUUID().toString();
List<Piece> expectedPiecesWithItem = new ArrayList<>();
Location elecLocation = new Location().withQuantityElectronic(elecQty1).withQuantity(elecQty1);
if (Eresource.CreateInventory.INSTANCE_HOLDING_ITEM == Eresource.CreateInventory.fromValue(elecCreateInventory)) {
elecLocation.withHoldingId(holdingId);
expectedPiecesWithItem.addAll(createElecPiecesWithHoldingId(lineId, titleId, true, elecLocation));
} else {
elecLocation.withLocationId(locationId);
}
Location physLocation = new Location().withQuantityPhysical(physQty2).withQuantity(physQty2);
if (Physical.CreateInventory.INSTANCE_HOLDING_ITEM == Physical.CreateInventory.fromValue(physCreateInventory)) {
physLocation.withHoldingId(holdingId);
expectedPiecesWithItem.addAll(createPhysPiecesWithHoldingId(lineId, titleId, true, physLocation));
} else {
physLocation.withLocationId(locationId);
}
Cost cost = new Cost().withQuantityElectronic(elecQty1 + physQty2);
Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.fromValue(elecCreateInventory));
Physical physical = new Physical().withCreateInventory(Physical.CreateInventory.fromValue(physCreateInventory));
CompositePoLine line = new CompositePoLine().withId(lineId).withCost(cost).withLocations(List.of(elecLocation, physLocation)).withIsPackage(false).withEresource(eresource).withPhysical(physical).withOrderFormat(CompositePoLine.OrderFormat.fromValue(lineType));
CompositePurchaseOrder compOrder = new CompositePurchaseOrder().withCompositePoLines(List.of(line));
doReturn(completedFuture(null)).when(openCompositeOrderPieceService).openOrderUpdateInventory(any(CompositePoLine.class), any(Piece.class), any(Boolean.class), eq(requestContext));
doReturn(completedFuture(Collections.emptyList())).when(pieceStorageService).getPiecesByPoLineId(line, requestContext);
doReturn(completedFuture(new Piece())).when(pieceStorageService).insertPiece(any(Piece.class), eq(requestContext));
doReturn(completedFuture(null)).when(protectionService).isOperationRestricted(any(List.class), any(ProtectedOperationType.class), eq(requestContext));
doReturn(completedFuture(compOrder)).when(purchaseOrderStorageService).getCompositeOrderByPoLineId(eq(lineId), eq(requestContext));
final ArgumentCaptor<Piece> pieceArgumentCaptor = ArgumentCaptor.forClass(Piece.class);
doAnswer((Answer<CompletableFuture<Piece>>) invocation -> {
Piece piece = invocation.getArgument(0);
return completedFuture(piece);
}).when(pieceStorageService).insertPiece(pieceArgumentCaptor.capture(), eq(requestContext));
// When
List<Piece> createdPieces = openCompositeOrderPieceService.handlePieces(line, titleId, expectedPiecesWithItem, false, requestContext).join();
// Then
List<Piece> piecesLocElec = createdPieces.stream().filter(piece -> Piece.Format.ELECTRONIC.equals(piece.getFormat())).collect(toList());
assertEquals(elecQty1, piecesLocElec.size());
piecesLocElec.forEach(piece -> {
assertEquals(lineId, piece.getPoLineId());
assertEquals(titleId, piece.getTitleId());
if (Eresource.CreateInventory.INSTANCE_HOLDING_ITEM == Eresource.CreateInventory.fromValue(elecCreateInventory)) {
assertEquals(holdingId, piece.getHoldingId());
assertNotNull(piece.getItemId());
} else {
assertEquals(locationId, piece.getLocationId());
assertNull(piece.getItemId());
}
});
List<Piece> piecesLocPhys = createdPieces.stream().filter(piece -> Piece.Format.PHYSICAL.equals(piece.getFormat())).collect(toList());
assertEquals(physQty2, piecesLocPhys.size());
piecesLocPhys.forEach(piece -> {
assertEquals(lineId, piece.getPoLineId());
assertEquals(titleId, piece.getTitleId());
if (Physical.CreateInventory.INSTANCE_HOLDING_ITEM == Physical.CreateInventory.fromValue(physCreateInventory)) {
assertEquals(holdingId, piece.getHoldingId());
assertNotNull(piece.getItemId());
} else {
assertEquals(locationId, piece.getLocationId());
assertNull(piece.getItemId());
}
});
}
use of org.folio.rest.jaxrs.model.Physical in project mod-orders by folio-org.
the class PurchaseOrdersApiTest method testPostOpenOrderInventoryUpdateWithOrderFormatOther.
@Test
@Disabled
// TODO must be fixed in scope of https://issues.folio.org/browse/MODORDERS-587
void testPostOpenOrderInventoryUpdateWithOrderFormatOther() throws Exception {
logger.info("=== Test POST Order By Id to change status of Order to Open - inventory interaction required only for first POL ===");
// Get Open Order
CompositePurchaseOrder reqData = getMockDraftOrder().mapTo(CompositePurchaseOrder.class);
MockServer.addMockTitles(reqData.getCompositePoLines());
// Make sure that mock po has 2 po lines
assertThat(reqData.getCompositePoLines(), hasSize(2));
// Make sure that mock po has the first PO line with 3 locations
assertThat(reqData.getCompositePoLines().get(0).getLocations(), hasSize(3));
// Make sure that Order moves to Open
reqData.setWorkflowStatus(CompositePurchaseOrder.WorkflowStatus.OPEN);
// Prepare second POL
CompositePoLine secondPol = reqData.getCompositePoLines().get(1);
List<Location> secondPolLocations = secondPol.getLocations();
// MODORDERS-117 Setting OrderFormat to OTHER which means it behaves similar
// to Physical order
secondPol.setOrderFormat(CompositePoLine.OrderFormat.OTHER);
Physical physical = new Physical();
physical.setCreateInventory(CreateInventory.NONE);
secondPol.setPhysical(physical);
// Specify correct quantities for OTHER format
secondPol.getCost().setQuantityElectronic(0);
secondPol.getCost().setListUnitPriceElectronic(null);
secondPol.getCost().setListUnitPrice(10d);
secondPol.getCost().setQuantityPhysical(secondPolLocations.size());
secondPol.setEresource(null);
secondPolLocations.forEach(location -> {
location.setQuantityElectronic(0);
location.setQuantityPhysical(1);
});
LocalDate now = LocalDate.now();
final CompositePurchaseOrder resp = verifyPostResponse(COMPOSITE_ORDERS_PATH, JsonObject.mapFrom(reqData).toString(), prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, X_OKAPI_USER_ID), APPLICATION_JSON, 201).as(CompositePurchaseOrder.class);
LocalDate dateOrdered = resp.getDateOrdered().toInstant().atZone(ZoneId.of(ZoneOffset.UTC.getId())).toLocalDate();
assertThat(dateOrdered.getMonth(), equalTo(now.getMonth()));
assertThat(dateOrdered.getYear(), equalTo(now.getYear()));
// Check that search of the existing instances and items was done for first PO line only
List<JsonObject> instancesSearches = getInstancesSearches();
List<JsonObject> holdingsSearches = getHoldingsSearches();
List<JsonObject> itemsSearches = getItemsSearches();
assertNotNull(instancesSearches);
assertNull(holdingsSearches);
assertNotNull(itemsSearches);
assertEquals(1, instancesSearches.size());
CompositePoLine respLine1 = resp.getCompositePoLines().get(0);
respLine1.getLocations().forEach(location -> {
assertNull(location.getLocationId());
assertNotNull(location.getHoldingId());
});
CompositePoLine respLine2 = resp.getCompositePoLines().get(1);
respLine2.getLocations().forEach(location -> {
assertNotNull(location.getLocationId());
assertNull(location.getHoldingId());
});
List<JsonObject> createdInstances = getCreatedInstances();
assertEquals(1, createdInstances.size(), "Quantity of created instance must be equal of line, if create inventory include instance");
assertNotNull("Line must be connected to instance, if create inventory include instance", respLine1.getInstanceId());
assertNotNull("Line must be connected to instance, if create inventory include instance", respLine2.getInstanceId());
List<JsonObject> createdHoldings = getCreatedHoldings();
assertEquals(3, createdHoldings.size(), "Quantity of created instance must be depended of quantity in the locations and create inventory include holding");
verifyHoldingsCreated(3, createdHoldings, respLine1);
verifyHoldingsCreated(0, createdHoldings, respLine2);
// All existing and created items
List<JsonObject> items = joinExistingAndNewItems();
verifyItemsCreated(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, 4, items, respLine1);
verifyItemsCreated(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, 0, items, respLine2);
List<JsonObject> createdPieces = getCreatedPieces();
createdPieces.stream().map(json -> json.mapTo(Piece.class)).filter(piece -> !OTHER.equals(piece.getFormat())).forEach(piece -> {
assertNull(piece.getLocationId());
assertNotNull(piece.getHoldingId());
});
createdPieces.stream().map(json -> json.mapTo(Piece.class)).filter(piece -> OTHER.equals(piece.getFormat())).forEach(piece -> {
assertNotNull(piece.getLocationId());
assertNull(piece.getHoldingId());
});
verifyOpenOrderPiecesCreated(items, resp.getCompositePoLines(), createdPieces, 4);
verifyCalculatedData(resp);
}
use of org.folio.rest.jaxrs.model.Physical in project mod-orders by folio-org.
the class OpenCompositeOrderPieceServiceTest method shouldCreatePieceWithLocationReferenceIfLineContainsLocationAndInventoryIsInstanceOrNoneAndNoCreatedPieces.
@ParameterizedTest
@CsvSource(value = { "Physical Resource:Instance:2:3:Physical", "Physical Resource:None:2:3:Physical", "Other:Instance:2:3:Other", "Other:None:2:3:Other" }, delimiter = ':')
void shouldCreatePieceWithLocationReferenceIfLineContainsLocationAndInventoryIsInstanceOrNoneAndNoCreatedPieces(String lineType, String createInventory, int qty1, int qty2, String pieceFormat) {
// given
String lineId = UUID.randomUUID().toString();
String locationId1 = UUID.randomUUID().toString();
String locationId2 = UUID.randomUUID().toString();
String titleId = UUID.randomUUID().toString();
Location location1 = new Location().withLocationId(locationId1).withQuantityPhysical(qty1).withQuantity(qty1);
Location location2 = new Location().withLocationId(locationId2).withQuantityPhysical(qty2).withQuantity(qty2);
Cost cost = new Cost().withQuantityPhysical(qty1 + qty2).withQuantityElectronic(null);
Physical physical = new Physical().withCreateInventory(Physical.CreateInventory.fromValue(createInventory));
CompositePoLine line = new CompositePoLine().withId(lineId).withCost(cost).withLocations(List.of(location1, location2)).withIsPackage(false).withPhysical(physical).withOrderFormat(CompositePoLine.OrderFormat.fromValue(lineType));
CompositePurchaseOrder compOrder = new CompositePurchaseOrder().withCompositePoLines(List.of(line));
doReturn(completedFuture(null)).when(openCompositeOrderPieceService).openOrderUpdateInventory(any(CompositePoLine.class), any(Piece.class), any(Boolean.class), eq(requestContext));
doReturn(completedFuture(Collections.emptyList())).when(pieceStorageService).getPiecesByPoLineId(line, requestContext);
doReturn(completedFuture(new Piece())).when(pieceStorageService).insertPiece(any(Piece.class), eq(requestContext));
doReturn(completedFuture(null)).when(protectionService).isOperationRestricted(any(List.class), any(ProtectedOperationType.class), eq(requestContext));
doReturn(completedFuture(compOrder)).when(purchaseOrderStorageService).getCompositeOrderByPoLineId(eq(lineId), eq(requestContext));
final ArgumentCaptor<Piece> pieceArgumentCaptor = ArgumentCaptor.forClass(Piece.class);
doAnswer((Answer<CompletableFuture<Piece>>) invocation -> {
Piece piece = invocation.getArgument(0);
return completedFuture(piece);
}).when(pieceStorageService).insertPiece(pieceArgumentCaptor.capture(), eq(requestContext));
// When
List<Piece> createdPieces = openCompositeOrderPieceService.handlePieces(line, titleId, Collections.emptyList(), false, requestContext).join();
// Then
List<Piece> piecesLoc1 = createdPieces.stream().filter(piece -> piece.getLocationId().equals(locationId1)).collect(toList());
assertEquals(qty1, piecesLoc1.size());
piecesLoc1.forEach(piece -> {
assertNull(piece.getHoldingId());
assertNull(piece.getItemId());
assertEquals(lineId, piece.getPoLineId());
assertEquals(titleId, piece.getTitleId());
assertEquals(Piece.Format.fromValue(pieceFormat), piece.getFormat());
});
List<Piece> piecesLoc2 = createdPieces.stream().filter(piece -> piece.getLocationId().equals(locationId2)).collect(toList());
assertEquals(qty2, piecesLoc2.size());
piecesLoc2.forEach(piece -> {
assertNull(piece.getHoldingId());
assertNull(piece.getItemId());
assertEquals(lineId, piece.getPoLineId());
assertEquals(titleId, piece.getTitleId());
assertEquals(Piece.Format.fromValue(pieceFormat), piece.getFormat());
});
}
Aggregations