Skip to content

Commit

Permalink
[MODORDERS-1006] Create Routing Lists API (#879)
Browse files Browse the repository at this point in the history
* [MODORDSTOR-381] Create Routing Lists API

* [MODORDSTOR-381] Add unit tests and fix validation logic

* [MODORDSTOR-381] Add validator tests

* [MODORDSTOR-381] Add unit tests for service

* [MODORDSTOR-381] Remove unused logger

* [MODORDSTOR-381] Merge with master and refactor code

* [MODORDSTOR-381] Fix failing unit tests

* [MODORDSTOR-381] Fix failing unit tests

* [MODORDSTOR-381] Fix failing unit tests

* [MODORDERS-1006] Change to meet coding convention rules

* [MODORDERS-1006] Add permissions and create private constructor for util class

* [MODORDERS-1006] Adjust perms

* [MODORDERS-1006] Remove unnecessary lines
  • Loading branch information
Saba-Zedginidze-EPAM authored Apr 8, 2024
1 parent 354903f commit b25126d
Show file tree
Hide file tree
Showing 17 changed files with 902 additions and 158 deletions.
70 changes: 69 additions & 1 deletion descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,36 @@
"id": "orders.routing-list",
"version": "1.0",
"handlers": [
{
"methods": ["GET"],
"pathPattern": "/orders/routing-lists",
"permissionsRequired": ["orders.routing-lists.collection.get"],
"modulePermissions": ["orders-storage.routing-lists.collection.get"]
},
{
"methods": ["POST"],
"pathPattern": "/orders/routing-lists",
"permissionsRequired": ["orders.routing-lists.item.post"],
"modulePermissions": ["orders-storage.routing-lists.item.post"]
},
{
"methods": ["GET"],
"pathPattern": "/orders/routing-lists/{id}",
"permissionsRequired": ["orders.routing-lists.item.get"],
"modulePermissions": ["orders-storage.routing-lists.item.get"]
},
{
"methods": ["PUT"],
"pathPattern": "/orders/routing-lists/{id}",
"permissionsRequired": ["orders.routing-lists.item.put"],
"modulePermissions": ["orders-storage.routing-lists.item.put"]
},
{
"methods": ["DELETE"],
"pathPattern": "/orders/routing-lists/{id}",
"permissionsRequired": ["orders.routing-lists.item.delete"],
"modulePermissions": ["orders-storage.routing-lists.item.delete"]
},
{
"methods": ["GET"],
"pathPattern": "/orders/routing-lists/{id}/template",
Expand Down Expand Up @@ -1731,11 +1761,49 @@
"displayName" : "orders holding-summary get",
"description" : "Holding summary"
},
{
"permissionName" : "orders.routing-lists.collection.get",
"displayName" : "orders routing-list collection get",
"description" : "Orders routing-list collection get"
},
{
"permissionName" : "orders.routing-lists.item.post",
"displayName" : "orders routing-list item post",
"description" : "Orders routing-list item post"
},
{
"permissionName" : "orders.routing-lists.item.get",
"displayName" : "orders routing-list item get",
"description" : "Orders routing-list item get"
},
{
"permissionName" : "orders.routing-lists.item.put",
"displayName" : "orders routing-list item put",
"description" : "Orders routing-list item put"
},
{
"permissionName" : "orders.routing-lists.item.delete",
"displayName" : "orders routing-list item delete",
"description" : "Orders routing-list item delete"
},
{
"permissionName": "orders.routing-list-template.item.get",
"displayName" : "orders routing-list-template item get",
"description" : "Orders routing-list-template item get"
},
{
"permissionName" : "orders.routing-lists.all",
"displayName" : "All routing list perms",
"description" : "All permissions for the routing list",
"subPermissions" : [
"orders.routing-lists.collection.get",
"orders.routing-lists.item.post",
"orders.routing-lists.item.get",
"orders.routing-lists.item.put",
"orders.routing-lists.item.delete",
"orders.routing-list-template.item.get"
]
},
{
"permissionName": "orders.all",
"displayName": "orders - all permissions",
Expand Down Expand Up @@ -1771,7 +1839,7 @@
"orders.holding-summary.collection.get",
"orders.acquisition-methods.all",
"orders.export-history.all",
"orders.routing-list-template.item.get"
"orders.routing-lists.all"
]
},
{
Expand Down
74 changes: 58 additions & 16 deletions ramls/routing-lists.raml
Original file line number Diff line number Diff line change
@@ -1,47 +1,89 @@
#%RAML 1.0
title: "RoutingList"
title: Routing Lists
baseUri: https://github.com/folio-org/mod-orders
version: v1.0

documentation:
- title: Routing lists
content: <b>CRUD API to manage routing lists.</b>
- title: Routing Lists API
content: <b>API for routing lists</b>

types:
routing_list: !include acq-models/mod-orders-storage/schemas/routing_list.json
routing_list_collection: !include acq-models/mod-orders-storage/schemas/routing_list_collection.json
UUID:
type: string
pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$
routing-list: !include acq-models/mod-orders-storage/schemas/routing_list.json
routing-list-collection: !include acq-models/mod-orders-storage/schemas/routing_list_collection.json
error: !include raml-util/schemas/error.schema
errors: !include raml-util/schemas/errors.schema
UUID:
type: string
pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$

traits:
pageable: !include raml-util/traits/pageable.raml
searchable: !include raml-util/traits/searchable.raml
pageable: !include raml-util/traits/pageable.raml
searchable: !include raml-util/traits/searchable.raml
validate: !include raml-util/traits/validation.raml

resourceTypes:
collection: !include rtypes/collection-with-json-response.raml
collection-item: !include rtypes/item-collection-with-json-response.raml

/orders/routing-lists:
displayName: Routing Lists
type:
collection:
exampleCollection: !include acq-models/mod-orders-storage/examples/routing_list_collection.sample
exampleItem: !include acq-models/mod-orders-storage/examples/routing_list_get.sample
schemaCollection: routing_list_collection
schemaItem: routing_list
schemaCollection: routing-list-collection
schemaItem: routing-list
get:
description: Get routing lists
description: Get a collection of routing lists
is: [
searchable: {description: "with valid searchable fields: for example routing list", example: "[\"routing_list\", \"ROUTING_LIST\", \"=\"]"},
searchable: { description: "CQL query", example: "name=MyRoutingList" },
pageable
]
post:
description: Create routing lists

description: Create a new routing list record
is: [validate]
body:
application/json:
type: routing-list
example:
strict: false
value: !include acq-models/mod-orders-storage/examples/routing_list_get.sample
responses:
201:
description: "Returns a newly created item, with server-controlled fields like 'id' populated"
body:
application/json:
example: !include acq-models/mod-orders-storage/examples/routing_list_get.sample
400:
description: "Bad request, e.g. malformed request body or query parameter. Details of the error (e.g. name of the parameter or line/character number with malformed data) provided in the response."
body:
application/json:
type: error
401:
description: "Not authorized to perform requested action"
body:
application/json:
type: error
500:
description: "Internal server error, e.g. due to misconfiguration"
body:
application/json:
type: error
/{id}:
uriParameters:
id:
description: The UUID of a Routing List
type: UUID
description: Get, Delete or Update a specific routing list
type:
collection-item:
exampleItem: !include acq-models/mod-orders-storage/examples/routing_list_get.sample
schema: routing-list
/{id}/template:
uriParameters:
id:
description: The UUID of a Title
type: UUID
get:
description: Execute mod-template-engine to process templates with replaced token placeholders [update]

6 changes: 3 additions & 3 deletions src/main/java/org/folio/config/ApplicationConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
import org.folio.service.pieces.flows.update.PieceUpdateFlowInventoryManager;
import org.folio.service.pieces.flows.update.PieceUpdateFlowManager;
import org.folio.service.pieces.flows.update.PieceUpdateFlowPoLineService;
import org.folio.service.RoutingListService;
import org.folio.service.routinglists.RoutingListService;
import org.folio.service.titles.TitleValidationService;
import org.folio.service.titles.TitlesService;
import org.springframework.beans.factory.annotation.Qualifier;
Expand Down Expand Up @@ -437,8 +437,8 @@ CompositeOrderDynamicDataPopulateService combinedPopulateService(CompositeOrderR
}

@Bean
RoutingListService routingListService(RestClient restClient, UserService userService) {
return new RoutingListService(restClient, userService);
RoutingListService routingListService(RestClient restClient, PurchaseOrderLineService purchaseOrderLineService, UserService userService) {
return new RoutingListService(restClient, purchaseOrderLineService, userService);
}

@Bean
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/org/folio/rest/core/exceptions/ErrorCodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ public enum ErrorCodes {
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"),
BARCODE_IS_NOT_UNIQUE("barcodeIsNotUnique", "The barcode already exists. The barcode must be unique"),
DELETE_WITH_EXPENDED_AMOUNT("deleteWithExpendedAmount", "Cannot delete en encumbrance with an expended amount");
DELETE_WITH_EXPENDED_AMOUNT("deleteWithExpendedAmount", "Cannot delete an encumbrance with an expended amount"),
INVALID_ROUTING_LIST_FOR_PO_LINE_FORMAT("invalidRoutingListForPoLineFormat", "Cannot create routing list for POL without 'Physical' or 'P/E Mix' order format"),
ROUTING_LIST_LIMIT_REACHED_FOR_PO_LINE("routingListLimitReachedForPoLine", "Cannot create routing list for POL as the associated lists' amount is not less than Physical copies"),
PO_LINE_NOT_FOUND_FOR_ROUTING_LIST("poLineNotFoundForRoutingList", "Cannot find a corresponding PO Line with the provided id");

private final String code;
private final String description;
Expand Down
54 changes: 42 additions & 12 deletions src/main/java/org/folio/rest/impl/RoutingListsAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
import javax.ws.rs.core.Response;
import java.util.Map;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import org.apache.commons.lang.NotImplementedException;
import org.folio.rest.annotations.Validate;
import org.folio.rest.core.models.RequestContext;
import org.folio.rest.jaxrs.model.RoutingList;
import org.folio.rest.jaxrs.resource.OrdersRoutingLists;
import org.folio.service.RoutingListService;
import org.folio.service.routinglists.RoutingListService;
import org.folio.spring.SpringContextUtil;
import org.springframework.beans.factory.annotation.Autowired;

import io.vertx.core.AsyncResult;
import io.vertx.core.Context;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;

public class RoutingListsAPI extends BaseApi implements OrdersRoutingLists {

@Autowired
Expand All @@ -27,15 +28,44 @@ public RoutingListsAPI() {
}

@Override
public void getOrdersRoutingLists(String query, String totalRecords, int offset, int limit, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
throw new NotImplementedException();
@Validate
public void getOrdersRoutingLists(String query, String totalRecords, int offset, int limit, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
routingListService.getRoutingLists(limit, offset, query, new RequestContext(vertxContext, okapiHeaders))
.onSuccess(lists -> asyncResultHandler.handle(succeededFuture(buildOkResponse(lists))))
.onFailure(fail -> handleErrorResponse(asyncResultHandler, fail));
}

@Override
@Validate
public void postOrdersRoutingLists(RoutingList entity, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
routingListService.createRoutingList(entity, new RequestContext(vertxContext, okapiHeaders))
.onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildOkResponse(list))))
.onFailure(fail -> handleErrorResponse(asyncResultHandler, fail));
}

@Override
@Validate
public void getOrdersRoutingListsById(String id, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
routingListService.getRoutingList(id, new RequestContext(vertxContext, okapiHeaders))
.onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildOkResponse(list))))
.onFailure(fail -> handleErrorResponse(asyncResultHandler, fail));
}

@Override
@Validate
public void deleteOrdersRoutingListsById(String id, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
routingListService.deleteRoutingList(id, new RequestContext(vertxContext, okapiHeaders))
.onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildNoContentResponse())))
.onFailure(fail -> handleErrorResponse(asyncResultHandler, fail));

}

@Override
public void postOrdersRoutingLists(RoutingList entity, Map<String, String> okapiHeaders,
Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
throw new NotImplementedException();
@Validate
public void putOrdersRoutingListsById(String id, RoutingList entity, Map<String, String> okapiHeaders, Handler<AsyncResult<Response>> asyncResultHandler, Context vertxContext) {
routingListService.updateRoutingList(entity, new RequestContext(vertxContext, okapiHeaders))
.onSuccess(list -> asyncResultHandler.handle(succeededFuture(buildNoContentResponse())))
.onFailure(fail -> handleErrorResponse(asyncResultHandler, fail));
}

@Override
Expand Down
Loading

0 comments on commit b25126d

Please sign in to comment.