Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

CIRC-2142: Merge ECS TLR feature branch into master #1510

Merged
merged 34 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
19bf73c
[CIRC-2051] Add ecsRequestRouting parameter to allowed-service-points…
roman-barannyk Apr 15, 2024
e131373
Merge remote-tracking branch 'origin/ecs-tlr-feature' into ecs-tlr-fe…
roman-barannyk Apr 23, 2024
6e3315d
conflicts resolving
roman-barannyk Apr 23, 2024
ae6991d
conflicts resolving
roman-barannyk Apr 24, 2024
32b7e00
CIRC-2081: Fetch TLR settings from mod-settings (#1467)
OleksandrVidinieiev Apr 26, 2024
3167b20
CIRC-2072 Create a facade for instance search
MagzhanArtykov Apr 30, 2024
6676cde
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 2, 2024
1c1cd46
CIRC-2072 Added API test
MagzhanArtykov May 13, 2024
6797c1b
CIRC-2072 Added API test
MagzhanArtykov May 15, 2024
eac3e54
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 20, 2024
1b29087
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 21, 2024
a6e440e
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 23, 2024
1c88c01
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 24, 2024
be46a67
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 24, 2024
9d68320
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
af5a9f7
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
f86281c
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
0702200
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 27, 2024
0b2acfd
CIRC-2072 Create a facade for instance search
MagzhanArtykov May 28, 2024
123dca6
Merge pull request #1471 from folio-org/CIRC-2072b
MagzhanArtykov May 29, 2024
ba47983
Merge branch 'master' into ecs-tlr-feature
OleksandrVidinieiev May 30, 2024
3f6bd4f
CIRC-2101: Fetch item details across tenants (#1474)
OleksandrVidinieiev Jun 6, 2024
5cff758
Merge branch 'master' into ecs-tlr-feature
alexanderkurash Jun 21, 2024
ea17564
CIRC-2109 Pass additional includeRoutingServicePoints parameter when …
alexanderkurash Jul 3, 2024
5bd43b6
CIRC-2117 Return empty result when search doesn't find anything (#1485)
Maksat-Galymzhan Jul 19, 2024
1bb48aa
[CIRC-2116] Allowed SP endpoint should support patronGroupId paramete…
MagzhanArtykov Jul 22, 2024
e9f3399
CIRC-2125: Search title-level requests by both `itemId` and `instance…
OleksandrVidinieiev Aug 9, 2024
c53bbcd
CIRC-2137 Allow operation `replace` for instance with no items (#1489)
OleksandrVidinieiev Aug 29, 2024
0907443
CIRC-2151 Change ECS Primary request validation (#1496)
alexanderkurash Sep 27, 2024
afcd021
Merge branch 'master' into ecs-tlr-feature
alexanderkurash Oct 18, 2024
50a3e6f
Fix tests after merging with master branch
alexanderkurash Oct 18, 2024
7115a63
Merge branch 'master' of https://github.com/folio-org/mod-circulation…
MagzhanArtykov Oct 24, 2024
52f1120
Merge remote-tracking branch 'origin/master' into ecs-tlr-feature
OleksandrVidinieiev Nov 7, 2024
1797308
CIRC-2153 Post-merge fixes
OleksandrVidinieiev Nov 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 58 additions & 7 deletions descriptors/ModuleDescriptor-template.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,22 @@
}
]
},
{
"id": "instance-items",
"version": "0.1",
"handlers": [
{
"methods": ["GET"],
"pathPattern": "/circulation/items-by-instance",
"permissionsRequired": [
"circulation.items-by-instance.get"
],
"modulePermissions": [
"search.instances.collection.get"
]
}
]
},
{
"id": "add-info",
"version": "0.1",
Expand Down Expand Up @@ -649,7 +665,7 @@
},
{
"id": "allowed-service-points",
"version": "1.0",
"version": "1.2",
OleksandrVidinieiev marked this conversation as resolved.
Show resolved Hide resolved
"handlers": [
{
"methods": [
Expand Down Expand Up @@ -677,7 +693,10 @@
"inventory-storage.instances.item.get",
"inventory-storage.instances.collection.get",
"configuration.entries.item.get",
"configuration.entries.collection.get"
"configuration.entries.collection.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation"
]
}
]
Expand Down Expand Up @@ -1604,6 +1623,11 @@
"displayName": "circulation settings - Read configuration",
"description": "To read the configuration from mod settings."
},
{
"permissionName": "circulation.items-by-instance.get",
"displayName": "circulation - get items by instance",
"description": "get items by instance"
},
{
"permissionName": "circulation.settings.collection.get",
"displayName": "circulation - get circulation settings",
Expand Down Expand Up @@ -1670,7 +1694,8 @@
"circulation.requests.allowed-service-points.get",
"circulation.inventory.items-in-transit-report.get",
"circulation.pick-slips.get",
"circulation.search-slips.get"
"circulation.search-slips.get",
"circulation.items-by-instance.get"
]
},
{
Expand Down Expand Up @@ -1776,6 +1801,10 @@
"configuration.entries.collection.get",
"calendar.endpoint.calendars.surroundingOpenings.get",
"calendar.endpoint.calendars.allOpenings.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation",
"calendar.endpoint.dates.get",
"pubsub.publish.post",
"circulation-storage.loans-history.collection.get"
],
Expand Down Expand Up @@ -1829,7 +1858,8 @@
"checkout-lock-storage.checkout-locks.item.delete",
"mod-settings.entries.collection.get",
"mod-settings.entries.item.get",
"mod-settings.global.read.mod-circulation"
"mod-settings.global.read.mod-circulation",
"mod-settings.global.read.circulation"
],
"visible": false
},
Expand Down Expand Up @@ -1891,7 +1921,10 @@
"actual-cost-fee-fine-cancel.post",
"departments.item.get",
"departments.collection.get",
"circulation-storage.loans-history.collection.get"
"circulation-storage.loans-history.collection.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation"
],
"visible": false
},
Expand Down Expand Up @@ -1924,6 +1957,9 @@
"calendar.endpoint.calendars.surroundingOpenings.get",
"calendar.endpoint.calendars.allOpenings.get",
"configuration.entries.collection.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation",
"scheduled-notice-storage.scheduled-notices.collection.delete",
"scheduled-notice-storage.scheduled-notices.item.post",
"patron-notice.post",
Expand Down Expand Up @@ -2109,6 +2145,9 @@
"scheduled-notice-storage.scheduled-notices.collection.delete",
"scheduled-notice-storage.scheduled-notices.item.post",
"configuration.entries.collection.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation",
"manualblocks.collection.get",
"pubsub.publish.post",
"automated-patron-blocks.collection.get",
Expand Down Expand Up @@ -2190,6 +2229,9 @@
"proxiesfor.collection.get",
"patron-notice.post",
"configuration.entries.collection.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation",
"scheduled-notice-storage.scheduled-notices.collection.delete",
"scheduled-notice-storage.scheduled-notices.item.post",
"pubsub.publish.post",
Expand Down Expand Up @@ -2233,7 +2275,10 @@
"addresstypes.collection.get",
"usergroups.collection.get",
"usergroups.item.get",
"pubsub.publish.post"
"pubsub.publish.post",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation"
],
"visible": false
},
Expand Down Expand Up @@ -2269,6 +2314,9 @@
"calendar.endpoint.calendars.surroundingOpenings.get",
"calendar.endpoint.calendars.allOpenings.get",
"configuration.entries.collection.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation",
"scheduled-notice-storage.scheduled-notices.collection.delete",
"scheduled-notice-storage.scheduled-notices.item.post",
"manualblocks.collection.get",
Expand Down Expand Up @@ -2326,7 +2374,10 @@
"addresstypes.collection.get",
"pubsub.publish.post",
"patron-notice.post",
"circulation-storage.loans-history.collection.get"
"circulation-storage.loans-history.collection.get",
"mod-settings.entries.item.get",
"mod-settings.entries.collection.get",
"mod-settings.global.read.circulation"
],
"visible": false
},
Expand Down
8 changes: 8 additions & 0 deletions ramls/circulation.raml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,14 @@ resourceTypes:
description: "Instance ID"
pattern: "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[1-5][a-fA-F0-9]{3}-[89abAB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$"
required: false
useStubItem:
description: "When true, allows to apply circulation rules based on patron group only"
type: boolean
required: false
ecsRequestRouting:
description: "When true, returns only service points with ecsRequestRouting"
type: boolean
required: false
responses:
200:
description: "List of allowed service points was retrieved successfully"
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/folio/circulation/CirculationVerticle.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.folio.circulation.resources.FeeFineNotRealTimeScheduledNoticeProcessingResource;
import org.folio.circulation.resources.FeeFineScheduledNoticeProcessingResource;
import org.folio.circulation.resources.HealthResource;
import org.folio.circulation.resources.ItemsByInstanceResource;
import org.folio.circulation.resources.ItemsInTransitResource;
import org.folio.circulation.resources.LoanAnonymizationResource;
import org.folio.circulation.resources.LoanCirculationRulesEngineResource;
Expand Down Expand Up @@ -94,6 +95,7 @@ public void start(Promise<Void> startFuture) {
new RequestCollectionResource(client).register(router);
new RequestQueueResource(client).register(router);
new RequestByInstanceIdResource(client).register(router);
new ItemsByInstanceResource(client).register(router);

new RequestHoldShelfClearanceResource(
"/circulation/requests-reports/hold-shelf-clearance/:servicePointId", client)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ public class AllowedServicePointsRequest {

private Request.Operation operation;
private String requesterId;
private String patronGroupId;
private String instanceId;
private String itemId;
private String requestId;
private boolean useStubItem;
private boolean ecsRequestRouting;

public boolean isForTitleLevelRequest() {
return instanceId != null;
Expand All @@ -27,7 +31,6 @@ public boolean isForTitleLevelRequest() {
public boolean isForItemLevelRequest() {
return itemId != null;
}
private String requestId;

public AllowedServicePointsRequest updateWithRequestInformation(Request request) {
log.debug("updateWithRequestInformation:: parameters request: {}", request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ private CompletableFuture<Result<RequestAndRelatedRecords>> checkPolicy(
boolean tlrFeatureEnabled = request.getTlrSettingsConfiguration().isTitleLevelRequestsFeatureEnabled();

if (tlrFeatureEnabled && request.isTitleLevel() && request.isHold()) {
if (request.getEcsRequestPhase() == EcsRequestPhase.PRIMARY) {
log.warn("checkPolicy:: ECS TLR primary Hold detected, skipping policy check");
return ofAsync(() -> records);
}

log.info("checkPolicy:: checking policy for title-level hold");
return completedFuture(checkPolicyForTitleLevelHold(records));
}
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/org/folio/circulation/domain/EcsRequestPhase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.folio.circulation.domain;

import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase;

import java.util.Arrays;

public enum EcsRequestPhase {
NONE(""),
PRIMARY("Primary"),
SECONDARY("Secondary");

public final String value;

public static EcsRequestPhase from(String value) {
return Arrays.stream(values())
.filter(status -> status.nameMatches(value))
.findFirst()
.orElse(NONE);
}

EcsRequestPhase(String value) {
this.value = value;
}

public String getValue() {
return value;
}

public boolean nameMatches(String value) {
return equalsIgnoreCase(getValue(), value);
}

@Override
public String toString() {
return value;
}
}
11 changes: 11 additions & 0 deletions src/main/java/org/folio/circulation/domain/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,17 @@ public String getDcbItemTitle() {
return getProperty(itemRepresentation, "instanceTitle");
}

public String getTenantId() {
return getProperty(itemRepresentation, "tenantId");
}

public Item changeTenantId(String tenantId) {
if (itemRepresentation != null) {
write(itemRepresentation, "tenantId", tenantId);
}
return this;
}

public boolean isAtLocation(String locationCode) {
return locationCode != null && getLocation() != null && (
locationCode.equals(getLocation().getCode()) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.apache.logging.log4j.Logger;
import org.folio.circulation.domain.validation.RequestLoanValidator;
import org.folio.circulation.infrastructure.storage.ConfigurationRepository;
import org.folio.circulation.infrastructure.storage.SettingsRepository;
import org.folio.circulation.infrastructure.storage.requests.RequestPolicyRepository;
import org.folio.circulation.infrastructure.storage.requests.RequestQueueRepository;
import org.folio.circulation.infrastructure.storage.requests.RequestRepository;
Expand All @@ -27,13 +28,14 @@ public class MoveRequestService {
private final ConfigurationRepository configurationRepository;
private final EventPublisher eventPublisher;
private final RequestQueueRepository requestQueueRepository;
private final SettingsRepository settingsRepository;
private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass());

public MoveRequestService(RequestRepository requestRepository, RequestPolicyRepository requestPolicyRepository,
UpdateUponRequest updateUponRequest, MoveRequestProcessAdapter moveRequestHelper,
RequestLoanValidator requestLoanValidator, RequestNoticeSender requestNoticeSender,
ConfigurationRepository configurationRepository, EventPublisher eventPublisher,
RequestQueueRepository requestQueueRepository) {
RequestQueueRepository requestQueueRepository, SettingsRepository settingsRepository) {

this.requestRepository = requestRepository;
this.requestPolicyRepository = requestPolicyRepository;
Expand All @@ -44,11 +46,12 @@ public MoveRequestService(RequestRepository requestRepository, RequestPolicyRepo
this.configurationRepository = configurationRepository;
this.eventPublisher = eventPublisher;
this.requestQueueRepository = requestQueueRepository;
this.settingsRepository = settingsRepository;
}

public CompletableFuture<Result<RequestAndRelatedRecords>> moveRequest(
RequestAndRelatedRecords requestAndRelatedRecords, Request originalRequest) {
return configurationRepository.lookupTlrSettings()
return settingsRepository.lookupTlrSettings()
.thenApply(r -> r.map(requestAndRelatedRecords::withTlrSettings))
.thenApply(r -> r.next(RequestServiceUtility::refuseTlrProcessingWhenFeatureIsDisabled))
.thenApply(r -> r.next(records -> RequestServiceUtility.refuseMovingToOrFromHoldTlr(records,
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/org/folio/circulation/domain/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.folio.circulation.domain.representations.RequestProperties.CANCELLATION_REASON_NAME;
import static org.folio.circulation.domain.representations.RequestProperties.CANCELLATION_REASON_PUBLIC_DESCRIPTION;
import static org.folio.circulation.domain.representations.RequestProperties.ITEM_LOCATION_CODE;
import static org.folio.circulation.domain.representations.RequestProperties.ECS_REQUEST_PHASE;
import static org.folio.circulation.domain.representations.RequestProperties.HOLDINGS_RECORD_ID;
import static org.folio.circulation.domain.representations.RequestProperties.HOLD_SHELF_EXPIRATION_DATE;
import static org.folio.circulation.domain.representations.RequestProperties.INSTANCE_ID;
Expand Down Expand Up @@ -269,6 +270,10 @@ public RequestType getRequestType() {
return RequestType.from(getProperty(requestRepresentation, REQUEST_TYPE));
}

public EcsRequestPhase getEcsRequestPhase() {
return EcsRequestPhase.from(getProperty(requestRepresentation, ECS_REQUEST_PHASE));
}

boolean allowedForItem() {
return RequestTypeItemStatusWhiteList.canCreateRequestForItem(getItem().getStatus(), getRequestType());
}
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/org/folio/circulation/domain/SearchInstance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.folio.circulation.domain;

import static org.folio.circulation.support.json.JsonObjectArrayPropertyFetcher.mapToList;
import static org.folio.circulation.support.json.JsonPropertyWriter.write;

import java.lang.invoke.MethodHandles;
import java.util.Collection;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.folio.circulation.domain.representations.ItemSummaryRepresentation;
import org.folio.circulation.storage.mappers.ItemMapper;

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import lombok.NonNull;
import lombok.ToString;
import lombok.Value;

@Value
@ToString(onlyExplicitlyIncluded = true)
public class SearchInstance {

private static final Logger log = LogManager.getLogger(MethodHandles.lookup().lookupClass());
JsonObject representation;
String id;
@NonNull Collection<Item> items;

public static SearchInstance from(JsonObject representation) {
return new SearchInstance(representation, representation.getString("id"), mapItems(representation));
}

private static List<Item> mapItems(JsonObject representation) {
return mapToList(representation, "items", new ItemMapper()::toDomain);
}

public SearchInstance changeItems(Collection<Item> items) {
JsonArray itemsArray = new JsonArray();
for (Item item : items) {
itemsArray.add(new ItemSummaryRepresentation().createItemSummary(item));
}
write(representation, "items", itemsArray);
return new SearchInstance(representation, id, items);
}

public JsonObject toJson() {
return representation;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public JsonObject createItemSummary(Item item) {
write(itemSummary, "copyNumber", item.getCopyNumber());
write(itemSummary, CALL_NUMBER_COMPONENTS,
createCallNumberComponents(item.getCallNumberComponents()));
write(itemSummary, "tenantId", item.getTenantId());

JsonObject status = new JsonObject()
.put("name", item.getStatus().getValue());
Expand Down
Loading