From 777b6da9b2d03023be5859752961aef951283a47 Mon Sep 17 00:00:00 2001 From: Serhii Nosko Date: Fri, 13 Dec 2024 17:59:23 +0200 Subject: [PATCH] [MODORDERS-1220]. Update validation to prevent adding piece to an pending order with synchronized status (#1068) * MODORDERS-1183. Introduce new error code for missed affiliations * MODORDERS-1220. Update validation to prevent adding piece to an pending order with synchronized status * MODORDERS-1220. Revert unnecessary change * MODORDERS-1220. Fix unit tests with mocks server --- .../rest/core/exceptions/ErrorCodes.java | 1 + .../flows/DefaultPieceFlowsValidator.java | 8 +- .../flows/create/PieceCreateFlowManager.java | 2 +- .../flows/update/PieceUpdateFlowManager.java | 2 +- .../pieces/validators/PieceValidatorUtil.java | 13 ++ .../org/folio/rest/impl/PieceApiTest.java | 11 ++ .../flows/DefaultPieceFlowsValidatorTest.java | 112 ++++++++++-------- .../validators/PieceValidatorUtilTest.java | 43 +++++++ ...5b454292-6aaa-474f-9510-b59a564e0c8d2.json | 2 +- 9 files changed, 140 insertions(+), 54 deletions(-) diff --git a/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java b/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java index e7beec940..8515cd7c6 100644 --- a/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java +++ b/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java @@ -108,6 +108,7 @@ public enum ErrorCodes { POSTGRE_SQL_ERROR("pgException", "PostgreSQL exception"), PIECE_FORMAT_IS_NOT_VALID_ERROR("pieceFormatIsNotValid", "Piece format %s is not compatible with purchase line %s"), PIECE_DISPLAY_ON_HOLDINGS_IS_NOT_CONSISTENT("pieceDisplayOnHoldingsIsNotConsistent", "Display On Holdings could not be set to false when Display To Public is true"), + PIECE_RELATED_ORDER_DATA_IS_NOT_VALID("pieceRelatedOrderDataIsNotValid", "Adding piece for pending order with synchronized workflow is not allowed"), CREATE_PIECE_FOR_PENDING_ORDER_ERROR("createPiecePendingOrderError", "Creating piece for pending order is not possible. Please open order."), CREATE_ITEM_FOR_PIECE_IS_NOT_ALLOWED_ERROR("createItemForPieceIsNotAllowedError", "Create item for piece format %s is not allowed. Please check inventory option in the purchase order line %s"), NOT_FOUND("notFound", "Not Found"), diff --git a/src/main/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidator.java b/src/main/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidator.java index 8584d6524..1bc80aae8 100644 --- a/src/main/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidator.java +++ b/src/main/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidator.java @@ -15,6 +15,7 @@ import org.folio.rest.RestConstants; import org.folio.rest.core.exceptions.HttpException; import org.folio.rest.jaxrs.model.CompositePoLine; +import org.folio.rest.jaxrs.model.CompositePurchaseOrder; import org.folio.rest.jaxrs.model.Eresource; import org.folio.rest.jaxrs.model.Error; import org.folio.rest.jaxrs.model.Errors; @@ -27,16 +28,17 @@ public class DefaultPieceFlowsValidator { private static final Logger logger = LogManager.getLogger(DefaultPieceFlowsValidator.class); - public void isPieceRequestValid(Piece pieceToCreate, CompositePoLine originPoLine, boolean isCreateItem) { - List combinedErrors = new ArrayList<>(); + public void isPieceRequestValid(Piece pieceToCreate, CompositePurchaseOrder originalOrder, CompositePoLine originPoLine, boolean isCreateItem) { List isItemCreateValidError = validateItemCreateFlag(pieceToCreate, originPoLine, isCreateItem); - combinedErrors.addAll(isItemCreateValidError); + List combinedErrors = new ArrayList<>(isItemCreateValidError); List pieceLocationErrors = Optional.ofNullable(PieceValidatorUtil.validatePieceLocation(pieceToCreate, originPoLine)).orElse(new ArrayList<>()); combinedErrors.addAll(pieceLocationErrors); List pieceFormatErrors = Optional.ofNullable(PieceValidatorUtil.validatePieceFormat(pieceToCreate, originPoLine)).orElse(new ArrayList<>()); combinedErrors.addAll(pieceFormatErrors); List displayOnHoldingsErrors = validateDisplayOnHoldingsConsistency(pieceToCreate); combinedErrors.addAll(displayOnHoldingsErrors); + List relatedOrderErrors = PieceValidatorUtil.validatePieceRelatedOrder(originalOrder, originPoLine); + combinedErrors.addAll(relatedOrderErrors); if (CollectionUtils.isNotEmpty(combinedErrors)) { Errors errors = new Errors().withErrors(combinedErrors).withTotalRecords(combinedErrors.size()); logger.error("Validation error : " + JsonObject.mapFrom(errors).encodePrettily()); diff --git a/src/main/java/org/folio/service/pieces/flows/create/PieceCreateFlowManager.java b/src/main/java/org/folio/service/pieces/flows/create/PieceCreateFlowManager.java index 554376b12..53981f186 100644 --- a/src/main/java/org/folio/service/pieces/flows/create/PieceCreateFlowManager.java +++ b/src/main/java/org/folio/service/pieces/flows/create/PieceCreateFlowManager.java @@ -40,7 +40,7 @@ public Future createPiece(Piece pieceToCreate, boolean createItem, Reques PieceCreationHolder holder = new PieceCreationHolder().withPieceToCreate(pieceToCreate).withCreateItem(createItem); return basePieceFlowHolderBuilder.updateHolderWithOrderInformation(holder, requestContext) .compose(aHolder -> basePieceFlowHolderBuilder.updateHolderWithTitleInformation(holder, requestContext)) - .map(v -> {defaultPieceFlowsValidator.isPieceRequestValid(pieceToCreate, holder.getOriginPoLine(), createItem); return null;}) + .map(v -> {defaultPieceFlowsValidator.isPieceRequestValid(pieceToCreate, holder.getOriginPurchaseOrder(), holder.getOriginPoLine(), createItem); return null;}) .compose(order -> protectionService.isOperationRestricted(holder.getTitle().getAcqUnitIds(), ProtectedOperationType.CREATE, requestContext)) .compose(v -> pieceCreateFlowInventoryManager.processInventory(holder.getPurchaseOrderToSave(), holder.getPoLineToSave(), holder.getPieceToCreate(), holder.isCreateItem(), requestContext)) .compose(compPoLine -> updatePoLine(holder, requestContext)) 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 9b49dec53..5eed324f9 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 @@ -82,7 +82,7 @@ public Future updatePiece(Piece pieceToUpdate, boolean createItem, boolean .map(holder::withPieceFromStorage) .compose(aHolder -> basePieceFlowHolderBuilder.updateHolderWithOrderInformation(holder, requestContext)) .compose(aHolder -> basePieceFlowHolderBuilder.updateHolderWithTitleInformation(holder, requestContext)) - .compose(v -> asFuture(() -> defaultPieceFlowsValidator.isPieceRequestValid(pieceToUpdate, holder.getOriginPoLine(), createItem))) + .compose(v -> asFuture(() -> defaultPieceFlowsValidator.isPieceRequestValid(pieceToUpdate, holder.getOriginPurchaseOrder(), holder.getOriginPoLine(), createItem))) .compose(title -> protectionService.isOperationRestricted(holder.getTitle().getAcqUnitIds(), UPDATE, requestContext)) .compose(v -> pieceUpdateFlowInventoryManager.processInventory(holder, requestContext)) .compose(v -> updatePoLine(holder, requestContext)) diff --git a/src/main/java/org/folio/service/pieces/validators/PieceValidatorUtil.java b/src/main/java/org/folio/service/pieces/validators/PieceValidatorUtil.java index bf48afa97..21b23207d 100644 --- a/src/main/java/org/folio/service/pieces/validators/PieceValidatorUtil.java +++ b/src/main/java/org/folio/service/pieces/validators/PieceValidatorUtil.java @@ -15,6 +15,8 @@ import org.folio.rest.core.exceptions.ErrorCodes; import org.folio.rest.jaxrs.model.CompositePoLine; +import org.folio.rest.jaxrs.model.CompositePurchaseOrder; +import org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus; import org.folio.rest.jaxrs.model.Eresource; import org.folio.rest.jaxrs.model.Error; import org.folio.rest.jaxrs.model.Physical; @@ -40,6 +42,17 @@ public static List validatePieceFormat(Piece piece, CompositePoLine compo return Collections.emptyList(); } + public static List validatePieceRelatedOrder(CompositePurchaseOrder order, CompositePoLine poLine) { + if (order == null || poLine == null) { + return Collections.emptyList(); + } + if (WorkflowStatus.PENDING == order.getWorkflowStatus() && Boolean.FALSE.equals(poLine.getCheckinItems())) { + return List.of(new Error().withCode(ErrorCodes.PIECE_RELATED_ORDER_DATA_IS_NOT_VALID.getCode()) + .withMessage(ErrorCodes.PIECE_RELATED_ORDER_DATA_IS_NOT_VALID.getDescription())); + } + return Collections.emptyList(); + } + public static boolean isLocationRequired(Piece.Format pieceFormat, CompositePoLine compPOL) { if (ELECTRONIC.equals(pieceFormat)) { return compPOL.getEresource() != null && diff --git a/src/test/java/org/folio/rest/impl/PieceApiTest.java b/src/test/java/org/folio/rest/impl/PieceApiTest.java index e4294800e..c3df0f1a1 100644 --- a/src/test/java/org/folio/rest/impl/PieceApiTest.java +++ b/src/test/java/org/folio/rest/impl/PieceApiTest.java @@ -266,6 +266,11 @@ void testPostShouldSuccessfullyCreatePieceWithoutReceiptDate() { void testPutPiecesByIdTest() throws Exception { logger.info("=== Test update piece by id - valid Id 204 ==="); + CompositePoLine poLineForOpenOrder = getMockAsJson(PO_LINES_COLLECTION).getJsonArray("poLines").getJsonObject(5).mapTo(CompositePoLine.class); + CompositePurchaseOrder compositePurchaseOrder = new CompositePurchaseOrder().withId(poLineForOpenOrder.getPurchaseOrderId()).withWorkflowStatus(CompositePurchaseOrder.WorkflowStatus.OPEN); + addMockEntry(PURCHASE_ORDER_STORAGE, compositePurchaseOrder); + addMockEntry(PO_LINES_STORAGE, poLineForOpenOrder); + String reqData = getMockData(PIECE_RECORDS_MOCK_DATA_PATH + "pieceRecord.json"); String pieceId = UUID.randomUUID().toString(); JsonObject pieceStorage = new JsonObject((reqData)); @@ -274,6 +279,7 @@ void testPutPiecesByIdTest() throws Exception { JsonObject pieceRequest = new JsonObject((reqData)); pieceRequest.put(ID, pieceId); pieceRequest.put("receivingStatus", "Received"); + pieceRequest.put("poLineId", poLineForOpenOrder.getId()); addMockEntry(PIECES_STORAGE, pieceStorage); verifyPut(String.format(PIECES_ID_PATH, pieceId), pieceRequest, "", 204); @@ -339,6 +345,11 @@ void testPutPiecesByIdEcs(String purchaseOrderId, String pieceId, boolean mockIt void testPutPiecesByIdConsistentReceiptStatusTest() throws Exception { logger.info("=== Test update piece by id when receipt status is consistent - valid Id 204 ==="); + CompositePoLine poLineForOpenOrder = getMockAsJson(PO_LINES_COLLECTION).getJsonArray("poLines").getJsonObject(5).mapTo(CompositePoLine.class); + CompositePurchaseOrder compositePurchaseOrder = new CompositePurchaseOrder().withId(poLineForOpenOrder.getPurchaseOrderId()).withWorkflowStatus(CompositePurchaseOrder.WorkflowStatus.OPEN); + addMockEntry(PURCHASE_ORDER_STORAGE, compositePurchaseOrder); + addMockEntry(PO_LINES_STORAGE, poLineForOpenOrder); + String reqData = getMockData(PIECE_RECORDS_MOCK_DATA_PATH + "pieceRecord-received-consistent-receipt-status-5b454292-6aaa-474f-9510-b59a564e0c8d2.json"); verifyPut(String.format(PIECES_ID_PATH, CONSISTENT_RECEIVED_STATUS_PIECE_UUID), reqData, "", 204); diff --git a/src/test/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidatorTest.java b/src/test/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidatorTest.java index b7a66c0d4..62e80e51e 100644 --- a/src/test/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidatorTest.java +++ b/src/test/java/org/folio/service/pieces/flows/DefaultPieceFlowsValidatorTest.java @@ -9,6 +9,8 @@ import org.folio.rest.core.exceptions.ErrorCodes; import org.folio.rest.core.exceptions.HttpException; import org.folio.rest.jaxrs.model.CompositePoLine; +import org.folio.rest.jaxrs.model.CompositePurchaseOrder; +import org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus; import org.folio.rest.jaxrs.model.Cost; import org.folio.rest.jaxrs.model.Eresource; import org.folio.rest.jaxrs.model.Location; @@ -19,22 +21,24 @@ import org.junit.jupiter.params.provider.CsvSource; public class DefaultPieceFlowsValidatorTest { + private static final String ORDER_IRD = UUID.randomUUID().toString(); + private static final String LOCATION_ID = UUID.randomUUID().toString(); + private static final String PO_LINE_ID = UUID.randomUUID().toString(); + private DefaultPieceFlowsValidator defaultPieceFlowsValidator = new DefaultPieceFlowsValidator(); @Test void createPieceIsForbiddenIfPieceAndLIneFormatIsNotCompatible() { - String orderId = UUID.randomUUID().toString(); - String locationId = UUID.randomUUID().toString(); - String lineId = UUID.randomUUID().toString(); - Piece piece = new Piece().withPoLineId(lineId).withLocationId(locationId).withFormat(Piece.Format.ELECTRONIC); - Location loc = new Location().withLocationId(locationId).withQuantityElectronic(1).withQuantity(1); + Piece piece = new Piece().withPoLineId(PO_LINE_ID).withLocationId(LOCATION_ID).withFormat(Piece.Format.ELECTRONIC); + Location loc = new Location().withLocationId(LOCATION_ID).withQuantityElectronic(1).withQuantity(1); Cost cost = new Cost().withQuantityElectronic(1); - CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(orderId) - .withOrderFormat(CompositePoLine.OrderFormat.PHYSICAL_RESOURCE).withId(lineId) + CompositePurchaseOrder originOrder = new CompositePurchaseOrder().withId(ORDER_IRD).withWorkflowStatus(WorkflowStatus.OPEN); + CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(ORDER_IRD) + .withOrderFormat(CompositePoLine.OrderFormat.PHYSICAL_RESOURCE).withId(PO_LINE_ID) .withLocations(List.of(loc)).withCost(cost); HttpException exception = Assertions.assertThrows(HttpException.class, () -> { - defaultPieceFlowsValidator.isPieceRequestValid(piece, originPoLine, true); + defaultPieceFlowsValidator.isPieceRequestValid(piece, originOrder, originPoLine, true); }); boolean isErrorPresent = exception.getErrors().getErrors().stream() @@ -44,20 +48,18 @@ void createPieceIsForbiddenIfPieceAndLIneFormatIsNotCompatible() { @Test void createPieceIsForbiddenIfCreateInventoryInTheLineDonNotAllowThat() { - String orderId = UUID.randomUUID().toString(); - String locationId = UUID.randomUUID().toString(); - String lineId = UUID.randomUUID().toString(); - Piece piece = new Piece().withPoLineId(lineId).withLocationId(locationId).withFormat(Piece.Format.ELECTRONIC); - Location loc = new Location().withLocationId(locationId).withQuantityElectronic(1).withQuantity(1); + Piece piece = new Piece().withPoLineId(PO_LINE_ID).withLocationId(LOCATION_ID).withFormat(Piece.Format.ELECTRONIC); + Location loc = new Location().withLocationId(LOCATION_ID).withQuantityElectronic(1).withQuantity(1); Cost cost = new Cost().withQuantityElectronic(1); Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.INSTANCE_HOLDING); - CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(orderId) - .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(lineId) + CompositePurchaseOrder originOrder = new CompositePurchaseOrder().withId(ORDER_IRD).withWorkflowStatus(WorkflowStatus.OPEN); + CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(ORDER_IRD) + .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(PO_LINE_ID) .withEresource(eresource) .withLocations(List.of(loc)).withCost(cost); HttpException exception = Assertions.assertThrows(HttpException.class, () -> { - defaultPieceFlowsValidator.isPieceRequestValid(piece, originPoLine, true); + defaultPieceFlowsValidator.isPieceRequestValid(piece, originOrder, originPoLine, true); }); boolean isErrorPresent = exception.getErrors().getErrors().stream() @@ -67,36 +69,32 @@ void createPieceIsForbiddenIfCreateInventoryInTheLineDonNotAllowThat() { @Test void createPieceAllowableIfCreateInventoryInTheLineAllowThatButCreateItemFlagIsFalse() { - String orderId = UUID.randomUUID().toString(); - String locationId = UUID.randomUUID().toString(); - String lineId = UUID.randomUUID().toString(); - Piece piece = new Piece().withPoLineId(lineId).withLocationId(locationId).withFormat(Piece.Format.ELECTRONIC); - Location loc = new Location().withLocationId(locationId).withQuantityElectronic(1).withQuantity(1); + Piece piece = new Piece().withPoLineId(PO_LINE_ID).withLocationId(LOCATION_ID).withFormat(Piece.Format.ELECTRONIC); + Location loc = new Location().withLocationId(LOCATION_ID).withQuantityElectronic(1).withQuantity(1); Cost cost = new Cost().withQuantityElectronic(1); Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.INSTANCE_HOLDING_ITEM); - CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(orderId) - .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(lineId) + CompositePurchaseOrder originOrder = new CompositePurchaseOrder().withId(ORDER_IRD).withWorkflowStatus(WorkflowStatus.OPEN); + CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(ORDER_IRD) + .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(PO_LINE_ID) .withEresource(eresource) .withLocations(List.of(loc)).withCost(cost); - defaultPieceFlowsValidator.isPieceRequestValid(piece, originPoLine, true); + defaultPieceFlowsValidator.isPieceRequestValid(piece, originOrder, originPoLine, true); } @Test void createPieceIsValid() { - String orderId = UUID.randomUUID().toString(); - String locationId = UUID.randomUUID().toString(); - String lineId = UUID.randomUUID().toString(); - Piece piece = new Piece().withPoLineId(lineId).withLocationId(locationId).withFormat(Piece.Format.ELECTRONIC); - Location loc = new Location().withLocationId(locationId).withQuantityElectronic(1).withQuantity(1); + Piece piece = new Piece().withPoLineId(PO_LINE_ID).withLocationId(LOCATION_ID).withFormat(Piece.Format.ELECTRONIC); + Location loc = new Location().withLocationId(LOCATION_ID).withQuantityElectronic(1).withQuantity(1); Cost cost = new Cost().withQuantityElectronic(1); Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.INSTANCE_HOLDING_ITEM); - CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(orderId) - .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(lineId) + CompositePurchaseOrder originOrder = new CompositePurchaseOrder().withId(ORDER_IRD).withWorkflowStatus(WorkflowStatus.OPEN); + CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(ORDER_IRD) + .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(PO_LINE_ID) .withEresource(eresource) .withLocations(List.of(loc)).withCost(cost); - defaultPieceFlowsValidator.isPieceRequestValid(piece, originPoLine, true); + defaultPieceFlowsValidator.isPieceRequestValid(piece, originOrder, originPoLine, true); } @ParameterizedTest @@ -104,44 +102,62 @@ void createPieceIsValid() { "true:false", "false:false"}, delimiter = ':') void createPieceWithValidDisplayFlagsCombinations(Boolean displayOnHoldings, Boolean displayToPublic) { - String orderId = UUID.randomUUID().toString(); - String locationId = UUID.randomUUID().toString(); - String lineId = UUID.randomUUID().toString(); - Piece piece = new Piece().withPoLineId(lineId).withLocationId(locationId).withFormat(Piece.Format.ELECTRONIC) + Piece piece = new Piece().withPoLineId(PO_LINE_ID).withLocationId(LOCATION_ID).withFormat(Piece.Format.ELECTRONIC) .withDisplayOnHolding(displayOnHoldings) .withDisplayToPublic(displayToPublic); - Location loc = new Location().withLocationId(locationId).withQuantityElectronic(1).withQuantity(1); + Location loc = new Location().withLocationId(LOCATION_ID).withQuantityElectronic(1).withQuantity(1); Cost cost = new Cost().withQuantityElectronic(1); Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.INSTANCE_HOLDING_ITEM); - CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(orderId) - .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(lineId) + CompositePurchaseOrder originOrder = new CompositePurchaseOrder().withId(ORDER_IRD).withWorkflowStatus(WorkflowStatus.OPEN); + CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(ORDER_IRD) + .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(PO_LINE_ID) .withEresource(eresource) .withLocations(List.of(loc)).withCost(cost); - defaultPieceFlowsValidator.isPieceRequestValid(piece, originPoLine, true); + defaultPieceFlowsValidator.isPieceRequestValid(piece, originOrder, originPoLine, true); } @Test void createPieceWithInvalidDisplayFlagsCombination() { - String orderId = UUID.randomUUID().toString(); - String locationId = UUID.randomUUID().toString(); - String lineId = UUID.randomUUID().toString(); - Piece piece = new Piece().withPoLineId(lineId).withLocationId(locationId).withFormat(Piece.Format.ELECTRONIC) + Piece piece = new Piece().withPoLineId(PO_LINE_ID).withLocationId(LOCATION_ID).withFormat(Piece.Format.ELECTRONIC) .withDisplayOnHolding(false) .withDisplayToPublic(true); - Location loc = new Location().withLocationId(locationId).withQuantityElectronic(1).withQuantity(1); + Location loc = new Location().withLocationId(LOCATION_ID).withQuantityElectronic(1).withQuantity(1); Cost cost = new Cost().withQuantityElectronic(1); Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.INSTANCE_HOLDING_ITEM); - CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(orderId) - .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(lineId) + CompositePurchaseOrder originOrder = new CompositePurchaseOrder().withId(ORDER_IRD).withWorkflowStatus(WorkflowStatus.OPEN); + CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(ORDER_IRD) + .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(PO_LINE_ID) .withEresource(eresource) .withLocations(List.of(loc)).withCost(cost); HttpException exception = Assertions.assertThrows(HttpException.class, () -> { - defaultPieceFlowsValidator.isPieceRequestValid(piece, originPoLine, true); + defaultPieceFlowsValidator.isPieceRequestValid(piece, originOrder, originPoLine, true); }); boolean isErrorPresent = exception.getErrors().getErrors().stream() .anyMatch(error -> error.getCode().equals(ErrorCodes.PIECE_DISPLAY_ON_HOLDINGS_IS_NOT_CONSISTENT.getCode())); assertTrue(isErrorPresent); } + + @Test + void createPieceWithPendingOrderThatHasSynchronizedStatus() { + Piece piece = new Piece().withPoLineId(PO_LINE_ID).withLocationId(LOCATION_ID).withFormat(Piece.Format.ELECTRONIC); + Location loc = new Location().withLocationId(LOCATION_ID).withQuantityElectronic(1).withQuantity(1); + Cost cost = new Cost().withQuantityElectronic(1); + Eresource eresource = new Eresource().withCreateInventory(Eresource.CreateInventory.INSTANCE_HOLDING_ITEM); + // creating order with pending status + CompositePurchaseOrder originOrder = new CompositePurchaseOrder().withId(ORDER_IRD).withWorkflowStatus(WorkflowStatus.PENDING); + // creating poLine with synchronized status(by default) + CompositePoLine originPoLine = new CompositePoLine().withIsPackage(true).withPurchaseOrderId(ORDER_IRD) + .withOrderFormat(CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE).withId(PO_LINE_ID) + .withEresource(eresource) + .withLocations(List.of(loc)).withCost(cost); + + HttpException exception = Assertions.assertThrows(HttpException.class, () -> { + defaultPieceFlowsValidator.isPieceRequestValid(piece, originOrder, originPoLine, true); + }); + boolean isErrorPresent = exception.getErrors().getErrors().stream() + .anyMatch(error -> error.getCode().equals(ErrorCodes.PIECE_RELATED_ORDER_DATA_IS_NOT_VALID.getCode())); + assertTrue(isErrorPresent); + } } diff --git a/src/test/java/org/folio/service/pieces/validators/PieceValidatorUtilTest.java b/src/test/java/org/folio/service/pieces/validators/PieceValidatorUtilTest.java index a10150ead..56651a8d8 100644 --- a/src/test/java/org/folio/service/pieces/validators/PieceValidatorUtilTest.java +++ b/src/test/java/org/folio/service/pieces/validators/PieceValidatorUtilTest.java @@ -11,13 +11,18 @@ import java.util.List; import java.util.UUID; +import org.folio.CopilotGenerated; +import org.folio.rest.core.exceptions.ErrorCodes; import org.folio.rest.jaxrs.model.CompositePoLine; +import org.folio.rest.jaxrs.model.CompositePurchaseOrder; +import org.folio.rest.jaxrs.model.CompositePurchaseOrder.WorkflowStatus; import org.folio.rest.jaxrs.model.Eresource; import org.folio.rest.jaxrs.model.Error; import org.folio.rest.jaxrs.model.Physical; import org.folio.rest.jaxrs.model.Piece; import org.junit.jupiter.api.Test; +@CopilotGenerated(partiallyGenerated = true) public class PieceValidatorUtilTest { @Test @@ -128,4 +133,42 @@ void testPieceIsValidWhenLineIsMixedAndPieceIsPhysical() { List errorList = PieceValidatorUtil.validatePieceFormat(piece, poLine); assertEquals(0, errorList.size()); } + + @Test + void testValidateRelatedOrderWhenOrderIsNull() { + CompositePoLine poLine = new CompositePoLine(); + List errorList = PieceValidatorUtil.validatePieceRelatedOrder(null, poLine); + assertEquals(0, errorList.size()); + } + + @Test + void testValidateRelatedOrderWhenPoLineIsNull() { + CompositePurchaseOrder order = new CompositePurchaseOrder(); + List errorList = PieceValidatorUtil.validatePieceRelatedOrder(order, null); + assertEquals(0, errorList.size()); + } + + @Test + void testValidateRelatedWhenOrderIsPendingAndCheckinItemsIsFalse() { + CompositePurchaseOrder order = new CompositePurchaseOrder().withWorkflowStatus(WorkflowStatus.PENDING); + CompositePoLine poLine = new CompositePoLine().withCheckinItems(false); + List errorList = PieceValidatorUtil.validatePieceRelatedOrder(order, poLine); + assertEquals(ErrorCodes.PIECE_RELATED_ORDER_DATA_IS_NOT_VALID.getCode(), errorList.get(0).getCode()); + } + + @Test + void testValidateRelatedOrderWhenOrderIsPendingAndCheckinItemsIsTrue() { + CompositePurchaseOrder order = new CompositePurchaseOrder().withWorkflowStatus(WorkflowStatus.PENDING); + CompositePoLine poLine = new CompositePoLine().withCheckinItems(true); + List errorList = PieceValidatorUtil.validatePieceRelatedOrder(order, poLine); + assertEquals(0, errorList.size()); + } + + @Test + void testValidateRelatedWhenOrderIsNotPending() { + CompositePurchaseOrder order = new CompositePurchaseOrder().withWorkflowStatus(WorkflowStatus.OPEN); + CompositePoLine poLine = new CompositePoLine().withCheckinItems(false); + List errorList = PieceValidatorUtil.validatePieceRelatedOrder(order, poLine); + assertEquals(0, errorList.size()); + } } diff --git a/src/test/resources/mockdata/pieces/pieceRecord-received-consistent-receipt-status-5b454292-6aaa-474f-9510-b59a564e0c8d2.json b/src/test/resources/mockdata/pieces/pieceRecord-received-consistent-receipt-status-5b454292-6aaa-474f-9510-b59a564e0c8d2.json index f18cec280..41aeb19eb 100644 --- a/src/test/resources/mockdata/pieces/pieceRecord-received-consistent-receipt-status-5b454292-6aaa-474f-9510-b59a564e0c8d2.json +++ b/src/test/resources/mockdata/pieces/pieceRecord-received-consistent-receipt-status-5b454292-6aaa-474f-9510-b59a564e0c8d2.json @@ -6,7 +6,7 @@ "itemId": "522a501a-56b5-48d9-b28a-3a8f02482d97", "titleId": "9a665b22-9fe5-4c95-b4ee-837a5433c95d", "locationId": "53cf956f-c1df-410b-8bea-27f712cca7c0", - "poLineId": "c0d08448-347b-418a-8c2f-5fb50248d67e", + "poLineId": "fe47e95d-24e9-4a9a-9dc0-bcba64b51f56", "receivingStatus": "Received", "supplement": true, "receiptDate": "2018-10-10T00:00:00.000Z",