From cc02c8169bc2bc11a6236b757954437e50544afa Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:25:50 -0500 Subject: [PATCH 01/14] Improve validation and reject inconsistent order lines --- .../rest/core/exceptions/ErrorCodes.java | 6 +- .../CompositePoLineValidationService.java | 62 ++++++- src/main/resources/postgres-conf.json | 7 + .../templates/db_scripts/schema.json | 25 --- .../rest/impl/PurchaseOrderLinesApiTest.java | 10 +- .../rest/impl/PurchaseOrdersApiTest.java | 15 +- .../CompositePoLineValidationServiceTest.java | 82 +++++++++ .../0009662b-8b80-4001-b704-ca10971f222e.json | 83 +++++++++ .../0009662b-8b80-4001-b704-ca10971f222f.json | 93 ++++++++++ ...ph_for_create_inventory_test_physical.json | 159 ++++++++++++++++++ 10 files changed, 507 insertions(+), 35 deletions(-) create mode 100644 src/main/resources/postgres-conf.json delete mode 100644 src/main/resources/templates/db_scripts/schema.json create mode 100644 src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222e.json create mode 100644 src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222f.json create mode 100644 src/test/resources/print_monograph_for_create_inventory_test_physical.json 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 527424401..fbe31775c 100644 --- a/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java +++ b/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java @@ -114,7 +114,11 @@ public enum ErrorCodes { FUND_LOCATION_RESTRICTION_VIOLATION("fundLocationRestrictionViolation", "One of the funds is restricted to be used for one of the locations."), ENCUMBRANCES_FOR_RE_ENCUMBER_NOT_FOUND("encumbrancesForReEncumberNotFound", "The encumbrances were correctly created during the rollover or have already been updated."), CLAIMING_CONFIG_INVALID("claimingConfigInvalid", "Claiming interval should be set and greater than 0 if claiming is active"), - TEMPLATE_NAME_ALREADY_EXISTS("templateNameNotUnique", "Template name already exists"); + TEMPLATE_NAME_ALREADY_EXISTS("templateNameNotUnique", "Template name already exists"), + INVALID_PHYSICAL_POL("physicalPOLShouldContainOnlyPhysicalElement", "Physical POL should contain only \"physical\" element"), + INVALID_ELECTRONIC_POL("electronicPOLShouldContainOnlyElectronicElement", "Electronic POL should contain only \"electronic\" element"), + INVALID_PEMIX_POL("peMixPOLShouldContainPhysicalAndElectronicElement", "P\\E mix POL should contain \"physical\" and \"electronic\" element"), + INVALID_OTHER_POL("otherPOLShouldContainPhysicalElement", " Other should contain\"physical\" element"); private final String code; diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index dec8e0bba..ce7378cf8 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -34,7 +34,6 @@ import io.vertx.core.Future; - public class CompositePoLineValidationService extends BaseValidationService { private final ExpenseClassValidationService expenseClassValidationService; @@ -55,6 +54,7 @@ public Future> validatePoLine(CompositePoLine compPOL, RequestContex return expenseClassValidationService.validateExpenseClasses(List.of(compPOL), false, requestContext) .onSuccess(v -> errors.addAll(validatePoLineFormats(compPOL))) .onSuccess(v -> errors.addAll(validateLocations(compPOL))) + .onSuccess(v -> errors.addAll(validatePoLineMaterial(compPOL))) .map(v -> { errors.addAll(validateCostPrices(compPOL)); return errors; @@ -76,6 +76,66 @@ private List validatePoLineFormats(CompositePoLine compPOL) { return Collections.emptyList(); } + public List validatePoLineMaterial(CompositePoLine compPOL) { + + CompositePoLine.OrderFormat orderFormat = compPOL.getOrderFormat(); + + if (orderFormat == P_E_MIX) { + return P_E_MixCheck(compPOL); + } else if (orderFormat == ELECTRONIC_RESOURCE) { + return electronicResourceCheck(compPOL); + } else if (orderFormat == CompositePoLine.OrderFormat.PHYSICAL_RESOURCE) { + return physicalResourceCheck(compPOL); + } else if (orderFormat == CompositePoLine.OrderFormat.OTHER) { + return otherResourceCheck(compPOL); + } + + return Collections.emptyList(); + } + + //to check if the P_E_Mix missing either physical or electronic resources + private List P_E_MixCheck (CompositePoLine compPOL ){ + List errors = new ArrayList<>(); + if(compPOL.getPhysical()==null || compPOL.getEresource()==null){ + errors.add(ErrorCodes.INVALID_PEMIX_POL); + }else if (getElectronicCostQuantity(compPOL)==0 || getPhysicalCostQuantity(compPOL)==0){ + errors.add(ErrorCodes.INVALID_PEMIX_POL); + } + return convertErrorCodesToErrors(compPOL, errors); + } + + // to check if electronic order format contains physical resources + private List electronicResourceCheck (CompositePoLine compPOL ){ + List errors = new ArrayList<>(); + if((compPOL.getPhysical()!=null)) { + if (getPhysicalCostQuantity(compPOL) != 0) { + errors.add(ErrorCodes.INVALID_ELECTRONIC_POL); + } + } + return convertErrorCodesToErrors(compPOL, errors); + } + + // to check if physical order format contains electronic resources + private List physicalResourceCheck (CompositePoLine compPOL ){ + List errors = new ArrayList<>(); + if(compPOL.getEresource()!=null) { + if (getElectronicCostQuantity(compPOL) != 0) { + errors.add(ErrorCodes.INVALID_PHYSICAL_POL); + } + } + return convertErrorCodesToErrors(compPOL, errors); + } + + // to check if other order format contains electronic resources + private List otherResourceCheck (CompositePoLine compPOL ){ + List errors = new ArrayList<>(); + if(compPOL.getEresource()!=null) { + if (getElectronicCostQuantity(compPOL) != 0) { + errors.add(ErrorCodes.INVALID_OTHER_POL); + } + } + return convertErrorCodesToErrors(compPOL, errors); + } private List validatePoLineWithMixedFormat(CompositePoLine compPOL) { List errors = new ArrayList<>(); diff --git a/src/main/resources/postgres-conf.json b/src/main/resources/postgres-conf.json new file mode 100644 index 000000000..c717cc3a7 --- /dev/null +++ b/src/main/resources/postgres-conf.json @@ -0,0 +1,7 @@ +{ + "host" : "localhost", + "port" : 5432, + "database" : "okapi_modules", + "username" : "folio_admin", + "password" : "folio_admin" +} diff --git a/src/main/resources/templates/db_scripts/schema.json b/src/main/resources/templates/db_scripts/schema.json deleted file mode 100644 index 2dbaf9b7d..000000000 --- a/src/main/resources/templates/db_scripts/schema.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "tables": [], - "scripts": [ - { - "run": "after", - "snippetPath": "create_processed_records_table.sql", - "fromModuleVersion": "mod-orders-12.6.0" - }, - { - "run": "after", - "snippetPath": "create_sequential_order_id_table.sql", - "fromModuleVersion": "mod-orders-12.6.0" - }, - { - "run": "after", - "snippetPath": "create_po_lines_processing_progress_table.sql", - "fromModuleVersion": "mod-orders-12.6.0" - }, - { - "run": "after", - "snippetPath": "create_failed_ledger_rollover_po_line_table.sql", - "fromModuleVersion": "mod-orders-12.7.0" - } - ] -} diff --git a/src/test/java/org/folio/rest/impl/PurchaseOrderLinesApiTest.java b/src/test/java/org/folio/rest/impl/PurchaseOrderLinesApiTest.java index ea8482648..cebfccd35 100644 --- a/src/test/java/org/folio/rest/impl/PurchaseOrderLinesApiTest.java +++ b/src/test/java/org/folio/rest/impl/PurchaseOrderLinesApiTest.java @@ -59,6 +59,7 @@ import static org.folio.rest.core.exceptions.ErrorCodes.ELECTRONIC_COST_LOC_QTY_MISMATCH; import static org.folio.rest.core.exceptions.ErrorCodes.INACTIVE_EXPENSE_CLASS; import static org.folio.rest.core.exceptions.ErrorCodes.INSTANCE_ID_NOT_ALLOWED_FOR_PACKAGE_POLINE; +import static org.folio.rest.core.exceptions.ErrorCodes.INVALID_ELECTRONIC_POL; import static org.folio.rest.core.exceptions.ErrorCodes.ISBN_NOT_VALID; import static org.folio.rest.core.exceptions.ErrorCodes.LOCATION_CAN_NOT_BE_MODIFIER_AFTER_OPEN; import static org.folio.rest.core.exceptions.ErrorCodes.NON_ZERO_COST_ELECTRONIC_QTY; @@ -449,7 +450,7 @@ void testPutOrderLineElectronicFormatIncorrectQuantityAndPrice() { final Errors response = verifyPut(String.format(LINE_BY_ID_PATH, reqData.getId()), JsonObject.mapFrom(reqData), APPLICATION_JSON, 422).as(Errors.class); - assertThat(response.getErrors(), hasSize(8)); + assertThat(response.getErrors(), hasSize(9)); List errorCodes = response.getErrors() .stream() .map(Error::getCode) @@ -462,7 +463,8 @@ void testPutOrderLineElectronicFormatIncorrectQuantityAndPrice() { COST_ADDITIONAL_COST_INVALID.getCode(), COST_DISCOUNT_INVALID.getCode(), ELECTRONIC_COST_LOC_QTY_MISMATCH.getCode(), - PHYSICAL_COST_LOC_QTY_MISMATCH.getCode())); + PHYSICAL_COST_LOC_QTY_MISMATCH.getCode(), + INVALID_ELECTRONIC_POL.getCode())); // Check that no any calls made by the business logic to other services @@ -1681,7 +1683,7 @@ public void testFundDistributionValidationWhenZeroPriceAndDifferentDistributionT void testPutPhysicalOrderLineByIdWhenSpecificElementIsPresentAndProtectedFieldsChanged(CompositePoLine.OrderFormat orderFormat) { logger.info("=== Test PUT Order Line By Id - Protected fields changed ==="); - String lineId = "0009662b-8b80-4001-b704-ca10971f222d"; + String lineId = "0009662b-8b80-4001-b704-ca10971f222e"; JsonObject body = getMockAsJson(PO_LINES_MOCK_DATA_PATH, lineId); Object[] expected = new Object[]{ POLineFieldNames.ACQUISITION_METHOD.getFieldName()}; if (CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE == orderFormat) { @@ -1749,7 +1751,7 @@ void testPutElecOrderLineByIdWhenSpecificElementIsPresentAndProtectedFieldsChang void testPutMixedOrderLineByIdWhenSpecificElementIsPresentAndProtectedFieldsChanged(CompositePoLine.OrderFormat orderFormat) { logger.info("=== Test PUT Order Line By Id - Protected fields changed ==="); - String lineId = "0009662b-8b80-4001-b704-ca10971f222d"; + String lineId = "0009662b-8b80-4001-b704-ca10971f222f"; JsonObject body = getMockAsJson(PO_LINES_MOCK_DATA_PATH, lineId); Object[] expected = new Object[]{ POLineFieldNames.ACQUISITION_METHOD.getFieldName()}; diff --git a/src/test/java/org/folio/rest/impl/PurchaseOrdersApiTest.java b/src/test/java/org/folio/rest/impl/PurchaseOrdersApiTest.java index 38544c15a..b9375eea9 100644 --- a/src/test/java/org/folio/rest/impl/PurchaseOrdersApiTest.java +++ b/src/test/java/org/folio/rest/impl/PurchaseOrdersApiTest.java @@ -55,6 +55,9 @@ import static org.folio.rest.core.exceptions.ErrorCodes.INACTIVE_EXPENSE_CLASS; import static org.folio.rest.core.exceptions.ErrorCodes.INCORRECT_FUND_DISTRIBUTION_TOTAL; import static org.folio.rest.core.exceptions.ErrorCodes.INSTANCE_ID_NOT_ALLOWED_FOR_PACKAGE_POLINE; +import static org.folio.rest.core.exceptions.ErrorCodes.INVALID_OTHER_POL; +import static org.folio.rest.core.exceptions.ErrorCodes.INVALID_PEMIX_POL; +import static org.folio.rest.core.exceptions.ErrorCodes.INVALID_PHYSICAL_POL; import static org.folio.rest.core.exceptions.ErrorCodes.ISBN_NOT_VALID; import static org.folio.rest.core.exceptions.ErrorCodes.MISMATCH_BETWEEN_ID_IN_PATH_AND_BODY; import static org.folio.rest.core.exceptions.ErrorCodes.MISSING_MATERIAL_TYPE; @@ -603,7 +606,7 @@ void testPostOrderWithIncorrectCost() throws Exception { final Errors response = verifyPostResponse(COMPOSITE_ORDERS_PATH, JsonObject.mapFrom(reqData).encode(), prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10), APPLICATION_JSON, 422).as(Errors.class); - assertThat(response.getErrors(), hasSize(10)); + assertThat(response.getErrors(), hasSize(12)); Set errorCodes = response.getErrors() .stream() .map(Error::getCode) @@ -615,7 +618,9 @@ void testPostOrderWithIncorrectCost() throws Exception { PHYSICAL_COST_LOC_QTY_MISMATCH.getCode(), ELECTRONIC_COST_LOC_QTY_MISMATCH.getCode(), COST_UNIT_PRICE_ELECTRONIC_INVALID.getCode(), - COST_UNIT_PRICE_INVALID.getCode())); + COST_UNIT_PRICE_INVALID.getCode(), + INVALID_OTHER_POL.getCode(), + INVALID_PEMIX_POL.getCode())); } @Test @@ -729,7 +734,7 @@ void testPutOrderWithIncorrectQuantities() throws Exception { APPLICATION_JSON, 422).as(Errors.class); - assertThat(response.getErrors(), hasSize(5)); + assertThat(response.getErrors(), hasSize(6)); Set errorCodes = response.getErrors() .stream() .map(Error::getCode) @@ -739,7 +744,8 @@ void testPutOrderWithIncorrectQuantities() throws Exception { ZERO_COST_PHYSICAL_QTY.getCode(), ELECTRONIC_COST_LOC_QTY_MISMATCH.getCode(), PHYSICAL_COST_LOC_QTY_MISMATCH.getCode(), - ZERO_LOCATION_QTY.getCode())); + ZERO_LOCATION_QTY.getCode(), + INVALID_PEMIX_POL.getCode())); } @Test @@ -2344,6 +2350,7 @@ void testPostOrdersCreateInventoryPhysicalNone() throws Exception { reqData.getCompositePoLines().get(0).getCost().setListUnitPriceElectronic(0d); reqData.getCompositePoLines().get(0).getLocations().get(0).setQuantityElectronic(0); + 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); diff --git a/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java b/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java index 863c6130d..d6bf2b4cf 100644 --- a/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java +++ b/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java @@ -6,9 +6,12 @@ import java.util.List; import java.util.UUID; +import com.github.tomakehurst.wiremock.http.ssl.TrustEverythingStrategy; + import org.folio.rest.core.exceptions.ErrorCodes; import org.folio.rest.jaxrs.model.CompositePoLine; import org.folio.rest.jaxrs.model.Cost; +import org.folio.rest.jaxrs.model.Eresource; import org.folio.rest.jaxrs.model.Error; import org.folio.rest.jaxrs.model.Location; import org.folio.rest.jaxrs.model.Physical; @@ -112,4 +115,83 @@ void shouldReturnErrorIfClaimingIntervalIsNegativeWhenClaimingActive() { assertEquals(1, errors.size()); assertEquals(ErrorCodes.CLAIMING_CONFIG_INVALID.getCode(), errors.get(0).getCode()); } + + + @Test + @DisplayName("Should return error if physical order format contains Electronic resources.") + void shouldReturnErrorIfPhysicalContainsElectronicSource() { + Eresource eresource = new Eresource(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.PHYSICAL_RESOURCE; + Cost cost = new Cost().withQuantityElectronic(1); + CompositePoLine compositePoLine = new CompositePoLine() + .withOrderFormat(format) + .withEresource(eresource) + .withCost(cost); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_PHYSICAL_POL.getCode(), errors.get(0).getCode()); + } + + @Test + @DisplayName("Should return error if electronic order format contains physical resources.") + void shouldReturnErrorIfElectronicContainsPhysicalSource() { + Physical physical = new Physical(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE; + Cost cost = new Cost().withQuantityPhysical(1); + CompositePoLine compositePoLine = new CompositePoLine() + .withOrderFormat(format) + .withPhysical(physical) + .withCost(cost); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_ELECTRONIC_POL.getCode(), errors.get(0).getCode()); + } + + @Test + @DisplayName("Should return error if p/e mix order format does not contains physical resources.") + void shouldReturnErrorIfMixedDoesNotContainsPhysicalSource() { + Eresource eresource = new Eresource(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.P_E_MIX; + CompositePoLine compositePoLine = new CompositePoLine() + .withOrderFormat(format) + .withEresource(eresource); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_PEMIX_POL.getCode(), errors.get(0).getCode()); + } + + @Test + @DisplayName("Should return error if p/e mix order format does not contains electronic resources.") + void shouldReturnErrorIfMixedDoesNotContainsESource() { + Physical physical = new Physical(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.P_E_MIX; + CompositePoLine compositePoLine = new CompositePoLine() + .withOrderFormat(format) + .withPhysical(physical); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_PEMIX_POL.getCode(), errors.get(0).getCode()); + } + + @Test + @DisplayName("Should return error if other order format contains Electronic resources.") + void shouldReturnErrorIfOtherContainsElectronicSource() { + Eresource eresource = new Eresource(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.OTHER; + Cost cost = new Cost().withQuantityElectronic(1); + CompositePoLine compositePoLine = new CompositePoLine() + .withOrderFormat(format) + .withEresource(eresource) + .withCost(cost); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_OTHER_POL.getCode(), errors.get(0).getCode()); + } + + } diff --git a/src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222e.json b/src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222e.json new file mode 100644 index 000000000..4a11b75c0 --- /dev/null +++ b/src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222e.json @@ -0,0 +1,83 @@ +{ + "id" : "0009662b-8b80-4001-b704-ca10971f222e", + "acquisitionMethod" : "Purchase At Vendor System", + "alerts" : [ ], + "cancellationRestriction" : false, + "cancellationRestrictionNote" : "ABCDEFGHIJKLMNOPQRSTUVW", + "claims" : [ ], + "collection" : false, + "contributors" : [ { + "contributor" : "Ed Mashburn", + "contributorNameTypeId" : "fbdd42a8-e47d-4694-b448-cc571d1b44c3" + } ], + "cost": { + "currency": "USD", + "listUnitPrice": 900.00, + "quantityPhysical": 1 + }, + "description": "", + "details": { + "receivingNote": "start with v. 162", + "productIds": [ + { + "productId": "0065-3438", + "productIdType": "913300b2-03ed-469a-8179-c1092c991227" + } + ], + "subscriptionFrom": "2018-07-01T00:00:00.000Z", + "subscriptionInterval": 1095, + "subscriptionTo": "2021-06-30T00:00:00.000Z" + }, + "donor": "", + "fundDistribution": [ + { + "code": "STATE-SUBN", + "fundId": "e54b1f4d-7d05-4b1a-9368-3c36b75d8ac6", + "distributionType": "percentage", + "value": 100.0, + "encumbrance": "eb506834-6c70-4239-8d1a-6414a5b08011" + } + ], + "locations": [ + { + "locationId": "758258bc-ecc1-41b8-abca-f7b610822ffd", + "quantity": 1, + "quantityElectronic": 0, + "quantityPhysical": 1 + } + ], + "orderFormat": "Physical Resource", + "paymentStatus": "Pending", + "physical": { + "createInventory": "Instance, Holding, Item", + "materialSupplier": "6828d7cb-d84e-41e5-9db5-fc2e162f9ffb", + "materialType": "2fa93835-ea37-479d-b133-1d2a2279fcd8", + "receiptDue": "2018-07-31T00:00:00.000Z", + "volumes": [] + }, + "poLineDescription": "", + "poLineNumber": "1EFC97C6B7-1", + "publicationDate": "2018", + "publisher": "Plenum Press", + "purchaseOrderId": "11111111-dddd-4444-9999-ffffffffffff", + "receiptDate": null, + "receiptStatus": "Pending", + "reportingCodes": [], + "requester": "", + "rush": false, + "selector": "", + "source": "User", + "tags": { + "tagList": [] + }, + "titleOrPackage": "Advances in astronautical science", + "vendorDetail": { + "instructions": "", + "noteFromVendor": "", + "vendorAccount": "" + }, + "metadata": { + "createdDate": "2010-10-08T03:53:00.000", + "createdByUserId": "ab18897b-0e40-4f31-896b-9c9adc979a88" + } +} diff --git a/src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222f.json b/src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222f.json new file mode 100644 index 000000000..c00d2dd31 --- /dev/null +++ b/src/test/resources/mockdata/lines/0009662b-8b80-4001-b704-ca10971f222f.json @@ -0,0 +1,93 @@ +{ + "id" : "0009662b-8b80-4001-b704-ca10971f222f", + "acquisitionMethod" : "Purchase At Vendor System", + "alerts" : [ ], + "cancellationRestriction" : false, + "cancellationRestrictionNote" : "ABCDEFGHIJKLMNOPQRSTUVW", + "claims" : [ ], + "collection" : false, + "contributors" : [ { + "contributor" : "Ed Mashburn", + "contributorNameTypeId" : "fbdd42a8-e47d-4694-b448-cc571d1b44c3" + } ], + "cost": { + "currency": "USD", + "listUnitPrice": 900.00, + "listUnitPriceElectronic": 22.99, + "quantityPhysical": 1, + "quantityElectronic": 1 + }, + "description": "", + "details": { + "receivingNote": "start with v. 162", + "productIds": [ + { + "productId": "0065-3438", + "productIdType": "913300b2-03ed-469a-8179-c1092c991227" + } + ], + "subscriptionFrom": "2018-07-01T00:00:00.000Z", + "subscriptionInterval": 1095, + "subscriptionTo": "2021-06-30T00:00:00.000Z" + }, + "donor": "", + "fundDistribution": [ + { + "code": "STATE-SUBN", + "fundId": "e54b1f4d-7d05-4b1a-9368-3c36b75d8ac6", + "distributionType": "percentage", + "value": 100.0, + "encumbrance": "eb506834-6c70-4239-8d1a-6414a5b08011" + } + ], + "locations": [ + { + "locationId": "758258bc-ecc1-41b8-abca-f7b610822ffd", + "quantity": 1, + "quantityElectronic": 1, + "quantityPhysical": 1 + } + ], + "orderFormat": "P/E Mix", + "paymentStatus": "Pending", + "physical": { + "createInventory": "Instance, Holding, Item", + "materialSupplier": "6828d7cb-d84e-41e5-9db5-fc2e162f9ffb", + "materialType": "2fa93835-ea37-479d-b133-1d2a2279fcd8", + "receiptDue": "2018-07-31T00:00:00.000Z", + "volumes": [] + }, + "eresource": { + "activationDue": 0, + "createInventory": "Instance", + "expectedActivation": "2019-01-01T00:00:00.000Z", + "userLimit": 0, + "accessProvider": "d0fb5aa0-cdf1-11e8-a8d5-f2801f1b9fd1", + "materialType": "1a54b431-2e4f-452d-9cae-9cee66c9a892" + }, + "poLineDescription": "", + "poLineNumber": "1EFC97C6B7-1", + "publicationDate": "2018", + "publisher": "Plenum Press", + "purchaseOrderId": "11111111-dddd-4444-9999-ffffffffffff", + "receiptDate": null, + "receiptStatus": "Pending", + "reportingCodes": [], + "requester": "", + "rush": false, + "selector": "", + "source": "User", + "tags": { + "tagList": [] + }, + "titleOrPackage": "Advances in astronautical science", + "vendorDetail": { + "instructions": "", + "noteFromVendor": "", + "vendorAccount": "" + }, + "metadata": { + "createdDate": "2010-10-08T03:53:00.000", + "createdByUserId": "ab18897b-0e40-4f31-896b-9c9adc979a88" + } +} diff --git a/src/test/resources/print_monograph_for_create_inventory_test_physical.json b/src/test/resources/print_monograph_for_create_inventory_test_physical.json new file mode 100644 index 000000000..969bf4642 --- /dev/null +++ b/src/test/resources/print_monograph_for_create_inventory_test_physical.json @@ -0,0 +1,159 @@ +{ + "approved": true, + "assignedTo": "ab18897b-0e40-4f31-896b-9c9adc979a88", + "notes": [ + "ABCDEFGHIJKLMNO", + "ABCDEFGHIJKLMNOPQRST", + "ABCDEFGHIJKLMNOPQRSTUV" + ], + "orderType": "One-Time", + "poNumber": "2687001", + "reEncumber": false, + "totalEstimatedPrice": 300.00, + "totalItems": 4, + "vendor": "d0fb5aa0-cdf1-11e8-a8d5-f2801f1b9fd1", + "workflowStatus": "Pending", + "metadata": { + "createdDate": "2010-10-08T03:53:00.000", + "createdByUserId": "ab18897b-0e40-4f31-896b-9c9adc979a88" + }, + "compositePoLines": [ + { + "acquisitionMethod": "306489dd-0053-49ee-a068-c316444a8f55", + "alerts": [ + { + "alert": "Receipt overdue" + } + ], + "cancellationRestriction": false, + "cancellationRestrictionNote": "ABCDEFGHIJKLMNOPQRSTUVW", + "claims": [ + { + "claimed": false, + "sent": "2018-10-09T00:00:00.000Z", + "grace": 30 + } + ], + "collection": false, + "contributors": [ + { + "contributor": "Ed Mashburn", + "contributorNameTypeId": "fbdd42a8-e47d-4694-b448-cc571d1b44c3" + }, + { + "contributor": "Ed Mashburn 2", + "contributorNameTypeId": "2e48e713-17f3-4c13-a9f8-23845bb210aa" + }, + { + "contributor": "Ed Mashburn 3", + "contributorNameTypeId": "e8b311a6-3b21-43f2-a269-dd9310cb2d0a" + } + ], + "cost": { + "currency": "USD", + "listUnitPrice": 24.99, + "listUnitPriceElectronic": 22.99, + "quantityElectronic": 1, + "quantityPhysical": 1 + }, + "description": "ABCDEFGH", + "details": { + "receivingNote": "ABCDEFGHIJKL", + "productIds": [ + { + "productId": "1-4028-9462-7", + "productIdType": "8261054f-be78-422d-bd51-4ed9f33c3422" + } + ], + "subscriptionFrom": "2018-10-09T00:00:00.000Z", + "subscriptionInterval": 824, + "subscriptionTo": "2020-10-09T00:00:00.000Z" + }, + "donor": "ABCDEFGHIJKLM", + "fundDistribution": [ + { + "code": "HIST", + "fundId": "fb7b70f1-b898-4924-a991-0e4b6312bb5f", + "distributionType": "percentage", + "value": 80.0, + "encumbrance": "eb506834-6c70-4239-8d1a-6414a5b08ac3" + }, + { + "code": "EUROHIST", + "fundId": "e9285a1c-1dfc-4380-868c-e74073003f43", + "distributionType": "percentage", + "value": 20.0, + "encumbrance": "0466cb77-0344-43c6-85eb-0a64aa2934e5" + } + ], + "locations": [ + { + "locationId": "fcd64ce1-6995-48f0-840e-89ffa2288371", + "quantity": 2, + "quantityElectronic": 1, + "quantityPhysical": 1 + } + ], + "orderFormat": "P/E Mix", + "paymentStatus": "Awaiting Payment", + "physical": { + "createInventory": "Instance, Holding, Item", + "volumes": [ + "vol.1" + ], + "materialSupplier": "73d14bc5-d131-48c6-b380-f8e62f63c8b6", + "materialType": "2fa93835-ea37-479d-b133-1d2a2279fcd8", + "receiptDue": "2018-10-10T00:00:00.000Z" + }, + "poLineDescription": "ABCDEFGHIJKLMNOPQRSTUVWXY", + "poLineNumber": "268758-03", + "publicationDate": "2017", + "publisher": "Schiffer Publishing", + "receiptDate": "2018-10-09T00:00:00.000Z", + "receiptStatus": "Pending", + "reportingCodes": [ + { + "code": "CODE1", + "id": "5926dcd7-85f5-4504-8283-712595ebc38b", + "description": "ABCDEF" + }, + { + "code": "CODE2", + "id": "fa316c04-8101-4e72-8aaf-01281bac718f", + "description": "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + }, + { + "code": "CODE3", + "id": "ea68b696-3125-4940-bf91-1d128323473e", + "description": "ABCDE" + } + ], + "requester": "Leo Bulero", + "rush": true, + "selector": "ABCD", + "source": "User", + "tags": { + "tagList": [ + "important" + ] + }, + "titleOrPackage": "Kayak Fishing in the Northern Gulf Coast", + "vendorDetail": { + "instructions": "ABCDEFG", + "noteFromVendor": "ABCDEFGHIKJKLMNOP", + "referenceNumbers": [ + { + "refNumber": "123456-78", + "refNumberType": "Vendor title number", + "vendorDetailsSource": "OrderLine" + } + ], + "vendorAccount": "8910-10" + }, + "metadata": { + "createdDate": "2010-10-08T03:53:00.000", + "createdByUserId": "ab18897b-0e40-4f31-896b-9c9adc979a88" + } + } + ] +} From ceffec233fd0f92f46f941c2e40e1d0b6bba0b91 Mon Sep 17 00:00:00 2001 From: Yuntian Hu <48864579+yuntianhu@users.noreply.github.com> Date: Wed, 31 Jan 2024 12:27:12 -0500 Subject: [PATCH 02/14] Delete src/main/resources/postgres-conf.json --- src/main/resources/postgres-conf.json | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 src/main/resources/postgres-conf.json diff --git a/src/main/resources/postgres-conf.json b/src/main/resources/postgres-conf.json deleted file mode 100644 index c717cc3a7..000000000 --- a/src/main/resources/postgres-conf.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "host" : "localhost", - "port" : 5432, - "database" : "okapi_modules", - "username" : "folio_admin", - "password" : "folio_admin" -} From 845eeb41ec336fd9fc2b3cb589937e4838ae3e2d Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Wed, 31 Jan 2024 12:38:53 -0500 Subject: [PATCH 03/14] Improve validation and reject inconsistent order lines --- .../templates/db_scripts/schema.json | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/resources/templates/db_scripts/schema.json diff --git a/src/main/resources/templates/db_scripts/schema.json b/src/main/resources/templates/db_scripts/schema.json new file mode 100644 index 000000000..2dbaf9b7d --- /dev/null +++ b/src/main/resources/templates/db_scripts/schema.json @@ -0,0 +1,25 @@ +{ + "tables": [], + "scripts": [ + { + "run": "after", + "snippetPath": "create_processed_records_table.sql", + "fromModuleVersion": "mod-orders-12.6.0" + }, + { + "run": "after", + "snippetPath": "create_sequential_order_id_table.sql", + "fromModuleVersion": "mod-orders-12.6.0" + }, + { + "run": "after", + "snippetPath": "create_po_lines_processing_progress_table.sql", + "fromModuleVersion": "mod-orders-12.6.0" + }, + { + "run": "after", + "snippetPath": "create_failed_ledger_rollover_po_line_table.sql", + "fromModuleVersion": "mod-orders-12.7.0" + } + ] +} From c7d90b27c8daab02ed7cccdfb82480c082343265 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Wed, 31 Jan 2024 13:42:52 -0500 Subject: [PATCH 04/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../java/org/folio/rest/core/exceptions/ErrorCodes.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 fbe31775c..c4dffda80 100644 --- a/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java +++ b/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java @@ -115,10 +115,10 @@ public enum ErrorCodes { ENCUMBRANCES_FOR_RE_ENCUMBER_NOT_FOUND("encumbrancesForReEncumberNotFound", "The encumbrances were correctly created during the rollover or have already been updated."), CLAIMING_CONFIG_INVALID("claimingConfigInvalid", "Claiming interval should be set and greater than 0 if claiming is active"), TEMPLATE_NAME_ALREADY_EXISTS("templateNameNotUnique", "Template name already exists"), - INVALID_PHYSICAL_POL("physicalPOLShouldContainOnlyPhysicalElement", "Physical POL should contain only \"physical\" element"), - INVALID_ELECTRONIC_POL("electronicPOLShouldContainOnlyElectronicElement", "Electronic POL should contain only \"electronic\" element"), - INVALID_PEMIX_POL("peMixPOLShouldContainPhysicalAndElectronicElement", "P\\E mix POL should contain \"physical\" and \"electronic\" element"), - INVALID_OTHER_POL("otherPOLShouldContainPhysicalElement", " Other should contain\"physical\" element"); + INVALID_PHYSICAL_POL("physicalPOLShouldContainOnlyPhysicalElement", "Physical order format should contain only physical resource"), + INVALID_ELECTRONIC_POL("electronicPOLShouldContainOnlyElectronicElement", "Electronic order format should contain only electronic resource"), + INVALID_PEMIX_POL("peMixPOLShouldContainPhysicalAndElectronicElement", "PE mix order format should contain both of physical and electronic resource"), + INVALID_OTHER_POL("otherPOLShouldContainPhysicalElement", " Other order format should contain only physical resource"); private final String code; From 6cc03965f16d26c55d67742c9c86643619b0830a Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Thu, 1 Feb 2024 13:59:52 -0500 Subject: [PATCH 05/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../CompositePoLineValidationService.java | 62 ++++++++++++------- .../CompositePoLineValidationServiceTest.java | 48 +------------- 2 files changed, 39 insertions(+), 71 deletions(-) diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index ce7378cf8..03ead76d6 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -77,65 +77,79 @@ private List validatePoLineFormats(CompositePoLine compPOL) { } public List validatePoLineMaterial(CompositePoLine compPOL) { - CompositePoLine.OrderFormat orderFormat = compPOL.getOrderFormat(); - if (orderFormat == P_E_MIX) { - return P_E_MixCheck(compPOL); - } else if (orderFormat == ELECTRONIC_RESOURCE) { - return electronicResourceCheck(compPOL); - } else if (orderFormat == CompositePoLine.OrderFormat.PHYSICAL_RESOURCE) { - return physicalResourceCheck(compPOL); - } else if (orderFormat == CompositePoLine.OrderFormat.OTHER) { - return otherResourceCheck(compPOL); + List errors; + + switch (orderFormat) { + case P_E_MIX: + errors = checkP_E_Mix(compPOL); + break; + case ELECTRONIC_RESOURCE: + errors = checkElectronicResource(compPOL); + break; + case PHYSICAL_RESOURCE: + errors = checkPhysicalResource(compPOL); + break; + case OTHER: + errors = checkOtherResource(compPOL); + break; + default: + errors = Collections.emptyList(); + break; } - return Collections.emptyList(); + return errors; } - //to check if the P_E_Mix missing either physical or electronic resources - private List P_E_MixCheck (CompositePoLine compPOL ){ + private List checkP_E_Mix(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if(compPOL.getPhysical()==null || compPOL.getEresource()==null){ - errors.add(ErrorCodes.INVALID_PEMIX_POL); - }else if (getElectronicCostQuantity(compPOL)==0 || getPhysicalCostQuantity(compPOL)==0){ + + if (compPOL.getPhysical() == null || compPOL.getEresource() == null) { + errors.add(ErrorCodes.INVALID_PEMIX_POL); + } else if (getElectronicCostQuantity(compPOL) == 0 || getPhysicalCostQuantity(compPOL) == 0) { errors.add(ErrorCodes.INVALID_PEMIX_POL); } + return convertErrorCodesToErrors(compPOL, errors); } - // to check if electronic order format contains physical resources - private List electronicResourceCheck (CompositePoLine compPOL ){ + private List checkElectronicResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if((compPOL.getPhysical()!=null)) { + + if (compPOL.getPhysical() != null) { if (getPhysicalCostQuantity(compPOL) != 0) { errors.add(ErrorCodes.INVALID_ELECTRONIC_POL); } } + return convertErrorCodesToErrors(compPOL, errors); } - // to check if physical order format contains electronic resources - private List physicalResourceCheck (CompositePoLine compPOL ){ + private List checkPhysicalResource(CompositePoLine compPOL ){ List errors = new ArrayList<>(); - if(compPOL.getEresource()!=null) { + + if (compPOL.getEresource() != null) { if (getElectronicCostQuantity(compPOL) != 0) { errors.add(ErrorCodes.INVALID_PHYSICAL_POL); } } + return convertErrorCodesToErrors(compPOL, errors); } - // to check if other order format contains electronic resources - private List otherResourceCheck (CompositePoLine compPOL ){ + private List checkOtherResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if(compPOL.getEresource()!=null) { + + if (compPOL.getEresource() != null) { if (getElectronicCostQuantity(compPOL) != 0) { errors.add(ErrorCodes.INVALID_OTHER_POL); } } + return convertErrorCodesToErrors(compPOL, errors); } + private List validatePoLineWithMixedFormat(CompositePoLine compPOL) { List errors = new ArrayList<>(); diff --git a/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java b/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java index d6bf2b4cf..a32b18e93 100644 --- a/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java +++ b/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java @@ -26,7 +26,7 @@ public class CompositePoLineValidationServiceTest { private CompositePoLineValidationService compositePoLineValidationService; @BeforeEach - public void initMocks(){ + public void initMocks() { MockitoAnnotations.openMocks(this); } @@ -116,23 +116,6 @@ void shouldReturnErrorIfClaimingIntervalIsNegativeWhenClaimingActive() { assertEquals(ErrorCodes.CLAIMING_CONFIG_INVALID.getCode(), errors.get(0).getCode()); } - - @Test - @DisplayName("Should return error if physical order format contains Electronic resources.") - void shouldReturnErrorIfPhysicalContainsElectronicSource() { - Eresource eresource = new Eresource(); - CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.PHYSICAL_RESOURCE; - Cost cost = new Cost().withQuantityElectronic(1); - CompositePoLine compositePoLine = new CompositePoLine() - .withOrderFormat(format) - .withEresource(eresource) - .withCost(cost); - List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); - - assertEquals(1, errors.size()); - assertEquals(ErrorCodes.INVALID_PHYSICAL_POL.getCode(), errors.get(0).getCode()); - } - @Test @DisplayName("Should return error if electronic order format contains physical resources.") void shouldReturnErrorIfElectronicContainsPhysicalSource() { @@ -149,20 +132,6 @@ void shouldReturnErrorIfElectronicContainsPhysicalSource() { assertEquals(ErrorCodes.INVALID_ELECTRONIC_POL.getCode(), errors.get(0).getCode()); } - @Test - @DisplayName("Should return error if p/e mix order format does not contains physical resources.") - void shouldReturnErrorIfMixedDoesNotContainsPhysicalSource() { - Eresource eresource = new Eresource(); - CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.P_E_MIX; - CompositePoLine compositePoLine = new CompositePoLine() - .withOrderFormat(format) - .withEresource(eresource); - List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); - - assertEquals(1, errors.size()); - assertEquals(ErrorCodes.INVALID_PEMIX_POL.getCode(), errors.get(0).getCode()); - } - @Test @DisplayName("Should return error if p/e mix order format does not contains electronic resources.") void shouldReturnErrorIfMixedDoesNotContainsESource() { @@ -177,21 +146,6 @@ void shouldReturnErrorIfMixedDoesNotContainsESource() { assertEquals(ErrorCodes.INVALID_PEMIX_POL.getCode(), errors.get(0).getCode()); } - @Test - @DisplayName("Should return error if other order format contains Electronic resources.") - void shouldReturnErrorIfOtherContainsElectronicSource() { - Eresource eresource = new Eresource(); - CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.OTHER; - Cost cost = new Cost().withQuantityElectronic(1); - CompositePoLine compositePoLine = new CompositePoLine() - .withOrderFormat(format) - .withEresource(eresource) - .withCost(cost); - List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); - - assertEquals(1, errors.size()); - assertEquals(ErrorCodes.INVALID_OTHER_POL.getCode(), errors.get(0).getCode()); - } } From cdace76d68253a5d20d8ffe3f262b4ffb78560c3 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Thu, 1 Feb 2024 19:15:16 -0500 Subject: [PATCH 06/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../CompositePoLineValidationServiceTest.java | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java b/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java index a32b18e93..25903b4a8 100644 --- a/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java +++ b/src/test/java/org/folio/service/orders/CompositePoLineValidationServiceTest.java @@ -116,36 +116,67 @@ void shouldReturnErrorIfClaimingIntervalIsNegativeWhenClaimingActive() { assertEquals(ErrorCodes.CLAIMING_CONFIG_INVALID.getCode(), errors.get(0).getCode()); } + @Test + @DisplayName("Should return error if physical order format contains Electronic resources.") + void shouldReturnErrorIfPhysicalContainsElectronicSource() { + Eresource eresource = new Eresource(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.PHYSICAL_RESOURCE; + Cost cost = new Cost().withQuantityElectronic(1); + CompositePoLine compositePoLine = new CompositePoLine().withOrderFormat(format).withEresource(eresource).withCost(cost); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_PHYSICAL_POL.getCode(), errors.get(0).getCode()); + } + @Test @DisplayName("Should return error if electronic order format contains physical resources.") void shouldReturnErrorIfElectronicContainsPhysicalSource() { Physical physical = new Physical(); CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.ELECTRONIC_RESOURCE; Cost cost = new Cost().withQuantityPhysical(1); - CompositePoLine compositePoLine = new CompositePoLine() - .withOrderFormat(format) - .withPhysical(physical) - .withCost(cost); + CompositePoLine compositePoLine = new CompositePoLine().withOrderFormat(format).withPhysical(physical).withCost(cost); List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); assertEquals(1, errors.size()); assertEquals(ErrorCodes.INVALID_ELECTRONIC_POL.getCode(), errors.get(0).getCode()); } + @Test + @DisplayName("Should return error if p/e mix order format does not contains physical resources.") + void shouldReturnErrorIfMixedDoesNotContainsPhysicalSource() { + Eresource eresource = new Eresource(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.P_E_MIX; + CompositePoLine compositePoLine = new CompositePoLine().withOrderFormat(format).withEresource(eresource); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_PEMIX_POL.getCode(), errors.get(0).getCode()); + } + @Test @DisplayName("Should return error if p/e mix order format does not contains electronic resources.") void shouldReturnErrorIfMixedDoesNotContainsESource() { Physical physical = new Physical(); CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.P_E_MIX; - CompositePoLine compositePoLine = new CompositePoLine() - .withOrderFormat(format) - .withPhysical(physical); + CompositePoLine compositePoLine = new CompositePoLine().withOrderFormat(format).withPhysical(physical); List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); assertEquals(1, errors.size()); assertEquals(ErrorCodes.INVALID_PEMIX_POL.getCode(), errors.get(0).getCode()); } + @Test + @DisplayName("Should return error if other order format contains Electronic resources.") + void shouldReturnErrorIfOtherContainsElectronicSource() { + Eresource eresource = new Eresource(); + CompositePoLine.OrderFormat format = CompositePoLine.OrderFormat.OTHER; + Cost cost = new Cost().withQuantityElectronic(1); + CompositePoLine compositePoLine = new CompositePoLine().withOrderFormat(format).withEresource(eresource).withCost(cost); + List errors = compositePoLineValidationService.validatePoLineMaterial(compositePoLine); + assertEquals(1, errors.size()); + assertEquals(ErrorCodes.INVALID_OTHER_POL.getCode(), errors.get(0).getCode()); + } } From 4ade17e329ea9352dc0b53c07468538dc2a5f071 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:50:26 -0500 Subject: [PATCH 07/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../CompositePoLineValidationService.java | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index 03ead76d6..2aef31379 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -79,27 +79,13 @@ private List validatePoLineFormats(CompositePoLine compPOL) { public List validatePoLineMaterial(CompositePoLine compPOL) { CompositePoLine.OrderFormat orderFormat = compPOL.getOrderFormat(); - List errors; - - switch (orderFormat) { - case P_E_MIX: - errors = checkP_E_Mix(compPOL); - break; - case ELECTRONIC_RESOURCE: - errors = checkElectronicResource(compPOL); - break; - case PHYSICAL_RESOURCE: - errors = checkPhysicalResource(compPOL); - break; - case OTHER: - errors = checkOtherResource(compPOL); - break; - default: - errors = Collections.emptyList(); - break; - } - - return errors; + return switch (orderFormat) { + case P_E_MIX -> P_E_MixCheck(compPOL); + case ELECTRONIC_RESOURCE -> electronicResourceCheck(compPOL); + case PHYSICAL_RESOURCE -> physicalResourceCheck(compPOL); + case OTHER -> otherResourceCheck(compPOL); + default -> Collections.emptyList(); + }; } private List checkP_E_Mix(CompositePoLine compPOL) { From ee636f37d39ed9d80be713affa6fb83a7cc4bcbd Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Fri, 2 Feb 2024 08:57:22 -0500 Subject: [PATCH 08/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../service/orders/CompositePoLineValidationService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index 2aef31379..fd61c48f8 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -80,10 +80,10 @@ public List validatePoLineMaterial(CompositePoLine compPOL) { CompositePoLine.OrderFormat orderFormat = compPOL.getOrderFormat(); return switch (orderFormat) { - case P_E_MIX -> P_E_MixCheck(compPOL); - case ELECTRONIC_RESOURCE -> electronicResourceCheck(compPOL); - case PHYSICAL_RESOURCE -> physicalResourceCheck(compPOL); - case OTHER -> otherResourceCheck(compPOL); + case P_E_MIX -> checkP_E_Mix(compPOL); + case ELECTRONIC_RESOURCE -> checkElectronicResource(compPOL); + case PHYSICAL_RESOURCE -> checkPhysicalResource(compPOL); + case OTHER -> checkOtherResource(compPOL); default -> Collections.emptyList(); }; } From 8e864418b38744bf3b1cca6a28295fad6c52b0f3 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:10:45 -0500 Subject: [PATCH 09/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java | 2 +- .../service/orders/CompositePoLineValidationService.java | 4 +--- 2 files changed, 2 insertions(+), 4 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 c4dffda80..8da255c8c 100644 --- a/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java +++ b/src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java @@ -118,7 +118,7 @@ public enum ErrorCodes { INVALID_PHYSICAL_POL("physicalPOLShouldContainOnlyPhysicalElement", "Physical order format should contain only physical resource"), INVALID_ELECTRONIC_POL("electronicPOLShouldContainOnlyElectronicElement", "Electronic order format should contain only electronic resource"), INVALID_PEMIX_POL("peMixPOLShouldContainPhysicalAndElectronicElement", "PE mix order format should contain both of physical and electronic resource"), - INVALID_OTHER_POL("otherPOLShouldContainPhysicalElement", " Other order format should contain only physical resource"); + INVALID_OTHER_POL("otherPOLShouldContainPhysicalElement", "Other order format should contain only physical resource"); private final String code; diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index fd61c48f8..053179dae 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -91,9 +91,7 @@ public List validatePoLineMaterial(CompositePoLine compPOL) { private List checkP_E_Mix(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if (compPOL.getPhysical() == null || compPOL.getEresource() == null) { - errors.add(ErrorCodes.INVALID_PEMIX_POL); - } else if (getElectronicCostQuantity(compPOL) == 0 || getPhysicalCostQuantity(compPOL) == 0) { + if (compPOL.getPhysical() == null || compPOL.getEresource() == null || getElectronicCostQuantity(compPOL) == 0 || getPhysicalCostQuantity(compPOL) == 0) { errors.add(ErrorCodes.INVALID_PEMIX_POL); } From 6e0c64c2501454d44f3ff2936ec1768b22ec74a2 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Fri, 2 Feb 2024 12:04:26 -0500 Subject: [PATCH 10/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../orders/CompositePoLineValidationService.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index 053179dae..b00b23875 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -101,11 +101,9 @@ private List checkP_E_Mix(CompositePoLine compPOL) { private List checkElectronicResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if (compPOL.getPhysical() != null) { - if (getPhysicalCostQuantity(compPOL) != 0) { + if (compPOL.getPhysical() != null && getPhysicalCostQuantity(compPOL) != 0) { errors.add(ErrorCodes.INVALID_ELECTRONIC_POL); } - } return convertErrorCodesToErrors(compPOL, errors); } @@ -113,11 +111,9 @@ private List checkElectronicResource(CompositePoLine compPOL) { private List checkPhysicalResource(CompositePoLine compPOL ){ List errors = new ArrayList<>(); - if (compPOL.getEresource() != null) { - if (getElectronicCostQuantity(compPOL) != 0) { + if (compPOL.getEresource() != null && getElectronicCostQuantity(compPOL) != 0) { errors.add(ErrorCodes.INVALID_PHYSICAL_POL); } - } return convertErrorCodesToErrors(compPOL, errors); } @@ -125,11 +121,9 @@ private List checkPhysicalResource(CompositePoLine compPOL ){ private List checkOtherResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if (compPOL.getEresource() != null) { - if (getElectronicCostQuantity(compPOL) != 0) { + if (compPOL.getEresource() != null && getElectronicCostQuantity(compPOL) != 0) { errors.add(ErrorCodes.INVALID_OTHER_POL); } - } return convertErrorCodesToErrors(compPOL, errors); } From 639a533b9058b0e11016cd490920c6a7e701aa24 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Fri, 2 Feb 2024 13:20:18 -0500 Subject: [PATCH 11/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../service/orders/CompositePoLineValidationService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index b00b23875..754b29e6d 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -80,7 +80,7 @@ public List validatePoLineMaterial(CompositePoLine compPOL) { CompositePoLine.OrderFormat orderFormat = compPOL.getOrderFormat(); return switch (orderFormat) { - case P_E_MIX -> checkP_E_Mix(compPOL); + case P_E_MIX -> checkPEMix(compPOL); case ELECTRONIC_RESOURCE -> checkElectronicResource(compPOL); case PHYSICAL_RESOURCE -> checkPhysicalResource(compPOL); case OTHER -> checkOtherResource(compPOL); @@ -88,7 +88,7 @@ public List validatePoLineMaterial(CompositePoLine compPOL) { }; } - private List checkP_E_Mix(CompositePoLine compPOL) { + private List checkPEMix(CompositePoLine compPOL) { List errors = new ArrayList<>(); if (compPOL.getPhysical() == null || compPOL.getEresource() == null || getElectronicCostQuantity(compPOL) == 0 || getPhysicalCostQuantity(compPOL) == 0) { From 4e75ef4cc9572a15c3f9e6bc11eb081d530377f2 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:01:02 -0500 Subject: [PATCH 12/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../service/orders/CompositePoLineValidationService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index 754b29e6d..4ccf77277 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -91,7 +91,7 @@ public List validatePoLineMaterial(CompositePoLine compPOL) { private List checkPEMix(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if (compPOL.getPhysical() == null || compPOL.getEresource() == null || getElectronicCostQuantity(compPOL) == 0 || getPhysicalCostQuantity(compPOL) == 0) { + if ((compPOL.getPhysical() == null) || (compPOL.getEresource() == null) || (getElectronicCostQuantity(compPOL) == 0) || (getPhysicalCostQuantity(compPOL) == 0)) { errors.add(ErrorCodes.INVALID_PEMIX_POL); } @@ -101,7 +101,7 @@ private List checkPEMix(CompositePoLine compPOL) { private List checkElectronicResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if (compPOL.getPhysical() != null && getPhysicalCostQuantity(compPOL) != 0) { + if ((compPOL.getPhysical() != null) && (getPhysicalCostQuantity(compPOL) != 0)) { errors.add(ErrorCodes.INVALID_ELECTRONIC_POL); } @@ -111,7 +111,7 @@ private List checkElectronicResource(CompositePoLine compPOL) { private List checkPhysicalResource(CompositePoLine compPOL ){ List errors = new ArrayList<>(); - if (compPOL.getEresource() != null && getElectronicCostQuantity(compPOL) != 0) { + if ((compPOL.getEresource() != null) && (getElectronicCostQuantity(compPOL) != 0)) { errors.add(ErrorCodes.INVALID_PHYSICAL_POL); } @@ -121,7 +121,7 @@ private List checkPhysicalResource(CompositePoLine compPOL ){ private List checkOtherResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); - if (compPOL.getEresource() != null && getElectronicCostQuantity(compPOL) != 0) { + if ((compPOL.getEresource() != null) && (getElectronicCostQuantity(compPOL) != 0)) { errors.add(ErrorCodes.INVALID_OTHER_POL); } From 531ca1bb3b8b578255f10f00903703bec18eaae6 Mon Sep 17 00:00:00 2001 From: yuntianhu <48864579+yuntianhu@users.noreply.github.com> Date: Mon, 5 Feb 2024 14:10:29 -0500 Subject: [PATCH 13/14] MODORDERS-585 Improve validation and reject inconsistent order lines --- .../orders/CompositePoLineValidationService.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java index 4ccf77277..bdea6ae02 100644 --- a/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java +++ b/src/main/java/org/folio/service/orders/CompositePoLineValidationService.java @@ -102,18 +102,18 @@ private List checkElectronicResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); if ((compPOL.getPhysical() != null) && (getPhysicalCostQuantity(compPOL) != 0)) { - errors.add(ErrorCodes.INVALID_ELECTRONIC_POL); - } + errors.add(ErrorCodes.INVALID_ELECTRONIC_POL); + } return convertErrorCodesToErrors(compPOL, errors); } - private List checkPhysicalResource(CompositePoLine compPOL ){ + private List checkPhysicalResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); if ((compPOL.getEresource() != null) && (getElectronicCostQuantity(compPOL) != 0)) { - errors.add(ErrorCodes.INVALID_PHYSICAL_POL); - } + errors.add(ErrorCodes.INVALID_PHYSICAL_POL); + } return convertErrorCodesToErrors(compPOL, errors); } @@ -122,8 +122,8 @@ private List checkOtherResource(CompositePoLine compPOL) { List errors = new ArrayList<>(); if ((compPOL.getEresource() != null) && (getElectronicCostQuantity(compPOL) != 0)) { - errors.add(ErrorCodes.INVALID_OTHER_POL); - } + errors.add(ErrorCodes.INVALID_OTHER_POL); + } return convertErrorCodesToErrors(compPOL, errors); } From 5251d57783539a32ae1d63cdbd6601702297d1b1 Mon Sep 17 00:00:00 2001 From: Serhii_Nosko Date: Thu, 8 Feb 2024 14:10:40 +0200 Subject: [PATCH 14/14] MODORDERS-1022. Add receipt Date to the CheckIng Piece schema --- ramls/acq-models | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ramls/acq-models b/ramls/acq-models index d3cfe3c19..0502772fd 160000 --- a/ramls/acq-models +++ b/ramls/acq-models @@ -1 +1 @@ -Subproject commit d3cfe3c19baf07a03465bb6a51161a40ed294877 +Subproject commit 0502772fdadd941734a132501c0cfe9baab243d8