From 6bdf70459efcc43fd207e63ff24478cde8c4e1a8 Mon Sep 17 00:00:00 2001 From: John Malconian Date: Thu, 22 Aug 2024 16:34:48 -0400 Subject: [PATCH 1/6] add ID dev workflows --- .github/workflows/k8s-deploy-latest.yml | 27 +++++ .github/workflows/mvn-dev-build-deploy.yml | 132 +++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 .github/workflows/k8s-deploy-latest.yml create mode 100644 .github/workflows/mvn-dev-build-deploy.yml diff --git a/.github/workflows/k8s-deploy-latest.yml b/.github/workflows/k8s-deploy-latest.yml new file mode 100644 index 0000000000..42f9b28419 --- /dev/null +++ b/.github/workflows/k8s-deploy-latest.yml @@ -0,0 +1,27 @@ +# Very simple workflow to deploy the *latest* published container image with the 'latest' tag. +# This does not post updated module descriptors to okapi, update permissions or enable +# new versions of a module with the tenant. If that is needed, it should be done manually +# via the Okapi API. + +name: k8s-deploy-latest + +env: + K8S_NAMESPACE: 'snapshot-dev' + K8S_DEPLOYMENT: 'mod-circulation-dev' + +on: + workflow_dispatch + +jobs: + k8s-deploy-latest: + + runs-on: ubuntu-latest + steps: + - name: Deploy latest to K8s + uses: actions-hub/kubectl@v1.21.2 + env: + KUBE_CONFIG: ${{ secrets.SNAPSHOT_DEV_SA_KUBECONFIG }} + with: + args: + -n ${{ env.K8S_NAMESPACE }} rollout restart deployment ${{ env.K8S_DEPLOYMENT }} + diff --git a/.github/workflows/mvn-dev-build-deploy.yml b/.github/workflows/mvn-dev-build-deploy.yml new file mode 100644 index 0000000000..a05e2db06f --- /dev/null +++ b/.github/workflows/mvn-dev-build-deploy.yml @@ -0,0 +1,132 @@ +name: mvn-dev-build-deploy + +on: + push: + pull_request: + types: [opened, synchronize, reopened] + workflow_dispatch: + +env: + PUBLISH_BRANCH: 'deployment' + OKAPI_URL: 'https://snapshot-dev-okapi.folio-dev.indexdata.com' + OKAPI_SECRET_USER: "${{ secrets.SNAPSHOT_DEV_OKAPI_USER }}" + OKAPI_SECRET_PASSWORD: "${{ secrets.SNAPSHOT_DEV_OKAPI_PASSWORD }}" + OK_SESSION: 'session1' + +jobs: + mvn-dev-build-deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + submodules: recursive + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: 'temurin' # Alternative distribution options are available. + + - name: Prepare okclient + run: git clone https://github.com/indexdata/okclient + + - name: Ensure OK and FOLIO login + # So do not proceed with other workflow steps if not available. + run: | + source okclient/ok.sh + OK -S ${{ env.OK_SESSION }} \ + -h ${{ env.OKAPI_URL }} \ + -t "supertenant" \ + -u ${{ env.OKAPI_SECRET_USER }} \ + -p ${{ env.OKAPI_SECRET_PASSWORD }} + OK -S ${{ env.OK_SESSION }} -x + + - name: Gather some variables + run: | + echo "MODULE_NAME=$(mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout)" >> $GITHUB_ENV + echo "SHA_SHORT=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + echo "CURRENT_BRANCH=$(echo ${GITHUB_REF#refs/heads/})" >> $GITHUB_ENV + + - name: Set module version + run: | + echo "MODULE_VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)-${SHA_SHORT}" >> $GITHUB_ENV + + - name: Cache SonarCloud packages + uses: actions/cache@v4 + with: + path: ~/.sonar/cache + key: ${{ runner.os }}-sonar + restore-keys: ${{ runner.os }}-sonar + + - name: Cache Maven packages + uses: actions/cache@v4 + with: + path: ~/.m2 + key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} + restore-keys: ${{ runner.os }}-m2 + + - name: Maven build + run: mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent install org.jacoco:jacoco-maven-plugin:report + + - name: SQ analyze + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + run: mvn -B org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=indexdata -Dsonar.projectKey=indexdata_${{ github.event.repository.name }} + + - name: Update ModuleDescriptor Id + run: | + if test -f "$MOD_DESCRIPTOR"; then + echo "Found $MOD_DESCRIPTOR" + cat <<< $(jq '.id = "${{ env.MODULE_NAME}}-${{ env.MODULE_VERSION }}"' $MOD_DESCRIPTOR) > $MOD_DESCRIPTOR + echo "MODULE_DESCRIPTOR=$MOD_DESCRIPTOR" >> $GITHUB_ENV + else + echo "Could not find $MOD_DESCRIPTOR" + exit 1 + fi + env: + MOD_DESCRIPTOR: './target/ModuleDescriptor.json' + + - name: Read ModuleDescriptor + id: moduleDescriptor + uses: juliangruber/read-file-action@v1 + with: + path: ${{ env.MODULE_DESCRIPTOR }} + + - name: Login to Index Data Docker Hub account + if: ${{ env.CURRENT_BRANCH == env.PUBLISH_BRANCH }} + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and publish Docker image + if: ${{ env.CURRENT_BRANCH == env.PUBLISH_BRANCH }} + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: indexdata/${{ env.MODULE_NAME }}:${{ env.MODULE_VERSION }},indexdata/${{ env.MODULE_NAME }}:latest + + - name: Publish ModuleDescriptor to Okapi + if: ${{ env.CURRENT_BRANCH == env.PUBLISH_BRANCH }} + run: | + source okclient/ok.sh + echo "Do login ..." + OK -S ${{ env.OK_SESSION }} \ + -h ${{ env.OKAPI_URL }} \ + -t "supertenant" \ + -u ${{ env.OKAPI_SECRET_USER }} \ + -p ${{ env.OKAPI_SECRET_PASSWORD }} + echo "Post the MD and report the response status ..." + OK -S ${{ env.OK_SESSION }} _/proxy/modules \ + -X post -f ${{ env.MODULE_DESCRIPTOR }} + declare -n NAMEREF_STATUS=${{ env.OK_SESSION }}_HTTPStatus + echo "Response status: $NAMEREF_STATUS" + echo "Do logout ..." + OK -S ${{ env.OK_SESSION }} -x + + - name: Print module version to job summary + run: | + echo "#### Module Version: ${{ env.MODULE_VERSION }}" >> $GITHUB_STEP_SUMMARY From f56ee44757e6852d2b2759a1d39da5cc23832fc9 Mon Sep 17 00:00:00 2001 From: David Crossley Date: Fri, 23 Aug 2024 19:51:51 +1000 Subject: [PATCH 2/6] Enable verbose debug both okclient and its curl DEVOPS-3370 --- .github/workflows/mvn-dev-build-deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/mvn-dev-build-deploy.yml b/.github/workflows/mvn-dev-build-deploy.yml index a05e2db06f..960c1f7753 100644 --- a/.github/workflows/mvn-dev-build-deploy.yml +++ b/.github/workflows/mvn-dev-build-deploy.yml @@ -115,6 +115,8 @@ jobs: source okclient/ok.sh echo "Do login ..." OK -S ${{ env.OK_SESSION }} \ + -v \ + -o '-v' \ -h ${{ env.OKAPI_URL }} \ -t "supertenant" \ -u ${{ env.OKAPI_SECRET_USER }} \ From d589efaa09cb5c0014cb9933e2a0f56e6b33bc8f Mon Sep 17 00:00:00 2001 From: David Crossley Date: Fri, 23 Aug 2024 20:05:44 +1000 Subject: [PATCH 3/6] Disable verbose okclient --- .github/workflows/mvn-dev-build-deploy.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/mvn-dev-build-deploy.yml b/.github/workflows/mvn-dev-build-deploy.yml index 960c1f7753..a05e2db06f 100644 --- a/.github/workflows/mvn-dev-build-deploy.yml +++ b/.github/workflows/mvn-dev-build-deploy.yml @@ -115,8 +115,6 @@ jobs: source okclient/ok.sh echo "Do login ..." OK -S ${{ env.OK_SESSION }} \ - -v \ - -o '-v' \ -h ${{ env.OKAPI_URL }} \ -t "supertenant" \ -u ${{ env.OKAPI_SECRET_USER }} \ From 086c70aa51c42db6de3c5409272af197fdac76c3 Mon Sep 17 00:00:00 2001 From: John Malconian Date: Wed, 28 Aug 2024 10:04:06 -0400 Subject: [PATCH 4/6] update kubectl action --- .github/workflows/k8s-deploy-latest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/k8s-deploy-latest.yml b/.github/workflows/k8s-deploy-latest.yml index 42f9b28419..fde161bd64 100644 --- a/.github/workflows/k8s-deploy-latest.yml +++ b/.github/workflows/k8s-deploy-latest.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Deploy latest to K8s - uses: actions-hub/kubectl@v1.21.2 + uses: actions-hub/kubectl@v1.29.3 env: KUBE_CONFIG: ${{ secrets.SNAPSHOT_DEV_SA_KUBECONFIG }} with: From e70f55b95e63317bab45d6d1fc527c4dd187ecfd Mon Sep 17 00:00:00 2001 From: Janis Saldabols Date: Fri, 6 Sep 2024 13:35:37 +0300 Subject: [PATCH 5/6] CIRC-2141 Allow specifying item location when creating title-level requests --- .../org/folio/circulation/domain/Campus.java | 3 +- .../folio/circulation/domain/Institution.java | 3 +- .../org/folio/circulation/domain/Library.java | 3 +- .../org/folio/circulation/domain/Request.java | 5 ++ .../representations/RequestProperties.java | 1 + .../storage/inventory/LocationRepository.java | 30 +++++++++- .../services/ItemForTlrService.java | 23 +++++++- .../storage/mappers/CampusMapper.java | 3 +- .../storage/mappers/InstitutionMapper.java | 3 +- .../storage/mappers/LibraryMapper.java | 3 +- .../requests/RequestsAPICreationTests.java | 58 +++++++++++++++++++ .../api/support/builders/RequestBuilder.java | 7 ++- 12 files changed, 133 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/folio/circulation/domain/Campus.java b/src/main/java/org/folio/circulation/domain/Campus.java index 1b294cce79..dd1d88ffee 100644 --- a/src/main/java/org/folio/circulation/domain/Campus.java +++ b/src/main/java/org/folio/circulation/domain/Campus.java @@ -9,9 +9,10 @@ public static Campus unknown() { } public static Campus unknown(String id) { - return new Campus(id, null); + return new Campus(id, null, null); } String id; String name; + String code; } diff --git a/src/main/java/org/folio/circulation/domain/Institution.java b/src/main/java/org/folio/circulation/domain/Institution.java index 3d94f43ec4..216a0a8b1c 100644 --- a/src/main/java/org/folio/circulation/domain/Institution.java +++ b/src/main/java/org/folio/circulation/domain/Institution.java @@ -9,9 +9,10 @@ public static Institution unknown() { } public static Institution unknown(String id) { - return new Institution(id, null); + return new Institution(id, null, null); } String id; String name; + String code; } diff --git a/src/main/java/org/folio/circulation/domain/Library.java b/src/main/java/org/folio/circulation/domain/Library.java index 372f754731..d702165ab5 100644 --- a/src/main/java/org/folio/circulation/domain/Library.java +++ b/src/main/java/org/folio/circulation/domain/Library.java @@ -9,9 +9,10 @@ public static Library unknown() { } public static Library unknown(String id) { - return new Library(id, null); + return new Library(id, null, null); } String id; String name; + String code; } diff --git a/src/main/java/org/folio/circulation/domain/Request.java b/src/main/java/org/folio/circulation/domain/Request.java index d1cecb8085..1de0416426 100644 --- a/src/main/java/org/folio/circulation/domain/Request.java +++ b/src/main/java/org/folio/circulation/domain/Request.java @@ -17,6 +17,7 @@ import static org.folio.circulation.domain.representations.RequestProperties.CANCELLATION_REASON_ID; 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.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; @@ -379,6 +380,10 @@ public String getPatronComments() { return getProperty(requestRepresentation, "patronComments"); } + public String geItemLocationCode() { + return getProperty(requestRepresentation, ITEM_LOCATION_CODE); + } + public Request truncateRequestExpirationDateToTheEndOfTheDay(ZoneId zone) { ZonedDateTime requestExpirationDate = getRequestExpirationDate(); if (requestExpirationDate != null) { diff --git a/src/main/java/org/folio/circulation/domain/representations/RequestProperties.java b/src/main/java/org/folio/circulation/domain/representations/RequestProperties.java index cf3be67cb1..830f2109d7 100644 --- a/src/main/java/org/folio/circulation/domain/representations/RequestProperties.java +++ b/src/main/java/org/folio/circulation/domain/representations/RequestProperties.java @@ -21,4 +21,5 @@ private RequestProperties() { } public static final String REQUESTER_ID = "requesterId"; public static final String FULFILLMENT_PREFERENCE = "fulfillmentPreference"; public static final String PICKUP_SERVICE_POINT_ID = "pickupServicePointId"; + public static final String ITEM_LOCATION_CODE = "itemLocationCode"; } diff --git a/src/main/java/org/folio/circulation/infrastructure/storage/inventory/LocationRepository.java b/src/main/java/org/folio/circulation/infrastructure/storage/inventory/LocationRepository.java index 52fe73dc2d..6099d95589 100644 --- a/src/main/java/org/folio/circulation/infrastructure/storage/inventory/LocationRepository.java +++ b/src/main/java/org/folio/circulation/infrastructure/storage/inventory/LocationRepository.java @@ -138,7 +138,9 @@ public CompletableFuture>> fetchLocations( new LocationMapper()::toDomain); return fetcher.findByIds(locationIds) - .thenCompose(this::loadLibrariesForLocations); + .thenCompose(this::loadLibrariesForLocations) + .thenCompose(this::loadCampusesForLocations) + .thenCompose(this::loadInstitutionsForLocations); } private CompletableFuture> loadLibrary(Location location) { @@ -208,6 +210,19 @@ public CompletableFuture>> getLibraries( .thenApply(mapResult(records -> records.toMap(Library::getId))); } + private CompletableFuture>> loadCampusesForLocations( + Result> multipleRecordsResult) { + + log.debug("loadCampusesForLocations:: parameters multipleRecordsResult: {}", + () -> resultAsString(multipleRecordsResult)); + + return multipleRecordsResult.combineAfter( + locations -> getCampuses(locations.getRecords()), (locations, campuses) -> + locations.mapRecords(location -> location.withCampus( + campuses.getOrDefault(location.getCampusId(), Campus.unknown(location.getCampusId()))))); + + } + public CompletableFuture>> getCampuses( Collection locations) { @@ -223,6 +238,19 @@ public CompletableFuture>> getCampuses( .thenApply(mapResult(records -> records.toMap(Campus::getId))); } + private CompletableFuture>> loadInstitutionsForLocations( + Result> multipleRecordsResult) { + + log.debug("loadInstitutionsForLocations:: parameters multipleRecordsResult: {}", + () -> resultAsString(multipleRecordsResult)); + + return multipleRecordsResult.combineAfter( + locations -> getInstitutions(locations.getRecords()), (locations, institutions) -> + locations.mapRecords(location -> location.withInstitution( + institutions.getOrDefault(location.getInstitutionId(), Institution.unknown(location.getInstitutionId()))))); + + } + public CompletableFuture>> getInstitutions( Collection locations) { diff --git a/src/main/java/org/folio/circulation/services/ItemForTlrService.java b/src/main/java/org/folio/circulation/services/ItemForTlrService.java index 3a306991a7..b8147312e6 100644 --- a/src/main/java/org/folio/circulation/services/ItemForTlrService.java +++ b/src/main/java/org/folio/circulation/services/ItemForTlrService.java @@ -4,6 +4,7 @@ import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; import static org.folio.circulation.domain.RequestType.PAGE; +import static org.folio.circulation.domain.representations.RequestProperties.ITEM_LOCATION_CODE; import static org.folio.circulation.domain.representations.RequestProperties.INSTANCE_ID; import static org.folio.circulation.support.ValidationErrorFailure.failedValidation; import static org.folio.circulation.support.results.Result.of; @@ -69,7 +70,27 @@ private Result> refusePageRequestWhenNoAvailablePageableItemsExist(Re return failedValidation(message, INSTANCE_ID, request.getInstanceId()); } - return of(() -> availablePageableItems); + List finalAvailablePageableItems; + if (request.geItemLocationCode() != null) { + finalAvailablePageableItems = availablePageableItems.stream() + .filter(item -> request.geItemLocationCode().equals(item.getLocation().getCode()) || + request.geItemLocationCode().equals(item.getLocation().getLibrary().getCode()) || + request.geItemLocationCode().equals(item.getLocation().getCampus().getCode()) || + request.geItemLocationCode().equals(item.getLocation().getInstitution().getCode()) + ) + .toList(); + if (finalAvailablePageableItems.isEmpty()) { + String message = "Cannot create page TLR for this instance ID - no pageable available " + + "items found in forced location"; + log.info("{}. Instance ID: {}, Forced location code {}", + message, request.getInstanceId(), request.geItemLocationCode()); + return failedValidation(message, ITEM_LOCATION_CODE, request.geItemLocationCode()); + } + } else { + finalAvailablePageableItems = availablePageableItems; + } + + return of(() -> finalAvailablePageableItems); } private static Item pickClosestItem(Collection requestedLocations, List availableItems) { diff --git a/src/main/java/org/folio/circulation/storage/mappers/CampusMapper.java b/src/main/java/org/folio/circulation/storage/mappers/CampusMapper.java index 12f44d5cf5..42ef65d610 100644 --- a/src/main/java/org/folio/circulation/storage/mappers/CampusMapper.java +++ b/src/main/java/org/folio/circulation/storage/mappers/CampusMapper.java @@ -9,6 +9,7 @@ public class CampusMapper { public Campus toDomain(JsonObject representation) { return new Campus(getProperty(representation, "id"), - getProperty(representation, "name")); + getProperty(representation, "name"), + getProperty(representation, "code")); } } diff --git a/src/main/java/org/folio/circulation/storage/mappers/InstitutionMapper.java b/src/main/java/org/folio/circulation/storage/mappers/InstitutionMapper.java index 061a5d1c4a..899d14fa9d 100644 --- a/src/main/java/org/folio/circulation/storage/mappers/InstitutionMapper.java +++ b/src/main/java/org/folio/circulation/storage/mappers/InstitutionMapper.java @@ -9,6 +9,7 @@ public class InstitutionMapper { public Institution toDomain(JsonObject representation) { return new Institution(getProperty(representation, "id"), - getProperty(representation, "name")); + getProperty(representation, "name"), + getProperty(representation, "code")); } } diff --git a/src/main/java/org/folio/circulation/storage/mappers/LibraryMapper.java b/src/main/java/org/folio/circulation/storage/mappers/LibraryMapper.java index ceb319c3d3..f509d1dff6 100644 --- a/src/main/java/org/folio/circulation/storage/mappers/LibraryMapper.java +++ b/src/main/java/org/folio/circulation/storage/mappers/LibraryMapper.java @@ -9,6 +9,7 @@ public class LibraryMapper { public Library toDomain(JsonObject representation) { return new Library(getProperty(representation, "id"), - getProperty(representation, "name")); + getProperty(representation, "name"), + getProperty(representation, "code")); } } diff --git a/src/test/java/api/requests/RequestsAPICreationTests.java b/src/test/java/api/requests/RequestsAPICreationTests.java index a7493260b7..35a023650a 100644 --- a/src/test/java/api/requests/RequestsAPICreationTests.java +++ b/src/test/java/api/requests/RequestsAPICreationTests.java @@ -631,6 +631,64 @@ void canCreateTitleLevelRequestWhenTlrEnabled() { assertThat(publishedEvents.filterToList(byEventType("LOAN_DUE_DATE_CHANGED")), hasSize(0)); } + @ParameterizedTest + @CsvSource(value = { + "NU/JC/DL/3F", + "DLRC", + "JC", + "NU" + }) + void createTitleLevelRequestWhenTlrEnabledSetLocation(String locationCode) { + UUID patronId = usersFixture.charlotte().getId(); + final UUID pickupServicePointId = servicePointsFixture.cd1().getId(); + + final var items = itemsFixture.createMultipleItemsForTheSameInstance(2); + UUID instanceId = items.get(0).getInstanceId(); + + configurationsFixture.enableTlrFeature(); + + IndividualResource requestResource = requestsClient.create(new RequestBuilder() + .page() + .withNoHoldingsRecordId() + .withNoItemId() + .titleRequestLevel() + .withInstanceId(instanceId) + .withPickupServicePointId(pickupServicePointId) + .withRequesterId(patronId) + .withItemLocationCode(locationCode)); + + JsonObject request = requestResource.getJson(); + assertThat(request.getString("requestLevel"), is("Title")); + } + + @Test + void createTitleLevelRequestWhenTlrEnabledSetLocationNoItems() { + UUID patronId = usersFixture.charlotte().getId(); + final UUID pickupServicePointId = servicePointsFixture.cd1().getId(); + + final var items = itemsFixture.createMultipleItemsForTheSameInstance(2); + UUID instanceId = items.get(0).getInstanceId(); + + configurationsFixture.enableTlrFeature(); + + Response response = requestsClient.attemptCreate( + new RequestBuilder() + .page() + .withNoHoldingsRecordId() + .withNoItemId() + .titleRequestLevel() + .withInstanceId(instanceId) + .withPickupServicePointId(pickupServicePointId) + .withRequesterId(patronId) + .withItemLocationCode("DoesNotExist") + .create()); + + assertThat(response.getStatusCode(), is(422)); + assertThat(response.getJson(), hasErrorWith( + hasMessage("Cannot create page TLR for this instance ID - no pageable " + + "available items found in forced location"))); + } + @Test void cannotCreateRequestWithNonExistentRequestLevelWhenTlrEnabled() { UUID patronId = usersFixture.charlotte().getId(); diff --git a/src/test/java/api/support/builders/RequestBuilder.java b/src/test/java/api/support/builders/RequestBuilder.java index 2514482a1e..473ebf8184 100644 --- a/src/test/java/api/support/builders/RequestBuilder.java +++ b/src/test/java/api/support/builders/RequestBuilder.java @@ -3,6 +3,7 @@ import static api.support.utl.DateTimeUtils.getLocalDatePropertyForDateWithTime; import static java.time.ZoneOffset.UTC; import static java.util.stream.Collectors.toList; +import static org.folio.circulation.domain.representations.RequestProperties.ITEM_LOCATION_CODE; import static org.folio.circulation.support.json.JsonPropertyFetcher.getDateTimeProperty; import static org.folio.circulation.support.json.JsonPropertyFetcher.getIntegerProperty; import static org.folio.circulation.support.json.JsonPropertyFetcher.getLocalDateProperty; @@ -63,6 +64,7 @@ public class RequestBuilder extends JsonBuilder implements Builder { private final Tags tags; private final String patronComments; private final BlockOverrides blockOverrides; + private final String itemLocationCode; public RequestBuilder() { this(UUID.randomUUID(), @@ -89,6 +91,7 @@ public RequestBuilder() { null, null, null, + null, null); } @@ -120,7 +123,8 @@ public static RequestBuilder from(IndividualResource response) { getUUIDProperty(representation, "pickupServicePointId"), new Tags((toStream(representation.getJsonObject("tags"), "tagList").collect(toList()))), getProperty(representation, "patronComments"), - null + null, + getProperty(representation, ITEM_LOCATION_CODE) ); } @@ -149,6 +153,7 @@ public JsonObject create() { put(request, "cancelledDate", formatDateTimeOptional(cancelledDate)); put(request, "pickupServicePointId", this.pickupServicePointId); put(request, "patronComments", this.patronComments); + put(request, ITEM_LOCATION_CODE, this.itemLocationCode); if (itemSummary != null) { final JsonObject itemRepresentation = new JsonObject(); From cbf3abdd648d5f771889862be34af3008d5ef061 Mon Sep 17 00:00:00 2001 From: Janis Saldabols Date: Wed, 11 Sep 2024 11:39:17 +0300 Subject: [PATCH 6/6] CIRC-2141 Add new field to request schema --- ramls/request.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ramls/request.json b/ramls/request.json index 1b80913dbb..64ca7d9088 100644 --- a/ramls/request.json +++ b/ramls/request.json @@ -423,6 +423,10 @@ "description": "Request fields used for search", "type": "object", "$ref": "request-search-index.json" + }, + "itemLocationCode": { + "description": "Allow specifying item location when creating title-level requests", + "type": "string" } }, "additionalProperties": false,