From 5f413092ebad3ae7c0a60e1be8e115ac24e4b588 Mon Sep 17 00:00:00 2001 From: Arthur Suzuki Date: Wed, 18 Feb 2026 00:53:27 +0000 Subject: [PATCH] Bug 41768: create and use public pickup_locations endpoints Sponsored-by: BibLibre --- Koha/REST/V1/Biblios.pm | 8 +++ Koha/REST/V1/Items.pm | 7 ++ api/v1/swagger/paths/biblios.yaml | 56 ++++++++++++++++ api/v1/swagger/paths/holds.yaml | 65 +++++++++++++++++++ api/v1/swagger/paths/items.yaml | 57 ++++++++++++++++ api/v1/swagger/swagger.yaml | 6 ++ .../bootstrap/js/pickup-locations.js | 12 +--- 7 files changed, 202 insertions(+), 9 deletions(-) diff --git a/Koha/REST/V1/Biblios.pm b/Koha/REST/V1/Biblios.pm index a4d50e38005..0043281c9c2 100644 --- a/Koha/REST/V1/Biblios.pm +++ b/Koha/REST/V1/Biblios.pm @@ -475,6 +475,14 @@ sub pickup_locations { unless $biblio; my $patron = Koha::Patrons->find( $c->param('patron_id') ); + + unless ($patron) { + my $userenv = C4::Context->userenv; + if ( $userenv and $userenv->{number} ) { + $patron = Koha::Patrons->find( $userenv->{number} ); + } + } + $c->req->params->remove('patron_id'); unless ($patron) { diff --git a/Koha/REST/V1/Items.pm b/Koha/REST/V1/Items.pm index 07a8a4f03e5..cd9bc34a8d7 100644 --- a/Koha/REST/V1/Items.pm +++ b/Koha/REST/V1/Items.pm @@ -19,6 +19,7 @@ use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; +use C4::Context; use C4::Circulation qw( barcodedecode ); use Koha::Items; @@ -212,6 +213,12 @@ sub pickup_locations { my $patron_id = $c->param('patron_id'); my $patron = Koha::Patrons->find($patron_id); + unless ($patron) { + my $userenv = C4::Context->userenv; + if ( $userenv and $userenv->{number} ) { + $patron = Koha::Patrons->find( $userenv->{number} ); + } + } $c->req->params->remove('patron_id'); diff --git a/api/v1/swagger/paths/biblios.yaml b/api/v1/swagger/paths/biblios.yaml index 18120c5dd98..3e2c7ed81e5 100644 --- a/api/v1/swagger/paths/biblios.yaml +++ b/api/v1/swagger/paths/biblios.yaml @@ -920,3 +920,59 @@ description: Under maintenance schema: $ref: "../swagger.yaml#/definitions/error" +"/public/biblios/{biblio_id}/pickup_locations": + get: + x-mojo-to: Biblios#pickup_locations + operationId: getBiblioPickupLocationsPublic + tags: + - biblios + summary: Get valid pickup locations for a biblio for the connected user + parameters: + - $ref: "../swagger.yaml#/parameters/biblio_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: Biblio pickup locations + schema: + type: array + items: + $ref: "../swagger.yaml#/definitions/library" + "400": + description: | + Bad request. Possible `error_code` attribute values: + + * `invalid_query` + schema: + $ref: "../swagger.yaml#/definitions/error" + "401": + description: Authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + "403": + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + "404": + description: Bibliographic record not found + schema: + $ref: "../swagger.yaml#/definitions/error" + "500": + description: | + Internal server error. Possible `error_code` attribute values: + + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + "503": + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" diff --git a/api/v1/swagger/paths/holds.yaml b/api/v1/swagger/paths/holds.yaml index dcd6413c03a..444ae7ed68b 100644 --- a/api/v1/swagger/paths/holds.yaml +++ b/api/v1/swagger/paths/holds.yaml @@ -957,3 +957,68 @@ x-koha-authorization: permissions: reserveforothers: modify_holds_priority +"/public/holds/{hold_id}/pickup_locations": + get: + x-mojo-to: Holds#pickup_locations + operationId: getHoldPickupLocationsPublic + tags: + - holds + summary: Get valid pickup locations for hold + parameters: + - name: x-koha-override + in: header + required: false + description: Overrides list sent as a request header + type: array + items: + type: string + enum: + - any + collectionFormat: csv + - $ref: "../swagger.yaml#/parameters/hold_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/request_id_header" + produces: + - application/json + responses: + "200": + description: Hold pickup location + schema: + type: array + items: + $ref: "../swagger.yaml#/definitions/library" + "400": + description: | + Bad request. Possible `error_code` attribute values: + + * `invalid_query` + schema: + $ref: "../swagger.yaml#/definitions/error" + "401": + description: Authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + "403": + description: Hold pickup location list not allowed + schema: + $ref: "../swagger.yaml#/definitions/error" + "404": + description: Hold not found + schema: + $ref: "../swagger.yaml#/definitions/error" + "500": + description: | + Internal server error. Possible `error_code` attribute values: + + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + "503": + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" diff --git a/api/v1/swagger/paths/items.yaml b/api/v1/swagger/paths/items.yaml index e99a6e0e55f..3c6b246e397 100644 --- a/api/v1/swagger/paths/items.yaml +++ b/api/v1/swagger/paths/items.yaml @@ -542,3 +542,60 @@ description: Under maintenance schema: $ref: "../swagger.yaml#/definitions/error" +"/public/items/{item_id}/pickup_locations": + get: + x-mojo-to: Items#pickup_locations + operationId: getItemPickupLocationsPublic + summary: Get valid pickup locations for an item for the connected user + tags: + - items + parameters: + - $ref: "../swagger.yaml#/parameters/item_id_pp" + - $ref: "../swagger.yaml#/parameters/match" + - $ref: "../swagger.yaml#/parameters/order_by" + - $ref: "../swagger.yaml#/parameters/page" + - $ref: "../swagger.yaml#/parameters/per_page" + - $ref: "../swagger.yaml#/parameters/q_param" + - $ref: "../swagger.yaml#/parameters/q_body" + - $ref: "../swagger.yaml#/parameters/request_id_header" + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: Item pickup locations + schema: + type: array + items: + $ref: "../swagger.yaml#/definitions/library" + "400": + description: | + Bad request. Possible `error_code` attribute values: + + * `invalid_query` + schema: + $ref: "../swagger.yaml#/definitions/error" + "401": + description: Authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + "403": + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + "404": + description: Bibliographic record not found + schema: + $ref: "../swagger.yaml#/definitions/error" + "500": + description: | + Internal server error. Possible `error_code` attribute values: + + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + "503": + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 9a9b7af7565..9cd44e96885 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -555,6 +555,12 @@ paths: $ref: ./paths/checkouts.yaml#/~1public~1checkouts~1availability "/public/items": $ref: "./paths/items.yaml#/~1public~1items" + "/public/items/{item_id}/pickup_locations": + $ref: "./paths/items.yaml#/~1public~1items~1{item_id}~1pickup_locations" + "/public/holds/{hold_id}/pickup_locations": + $ref: "./paths/holds.yaml#/~1public~1holds~1{hold_id}~1pickup_locations" + "/public/biblios/{biblio_id}/pickup_locations": + $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}~1pickup_locations" "/public/biblios/{biblio_id}/items": $ref: "./paths/biblios.yaml#/~1public~1biblios~1{biblio_id}~1items" "/public/biblios/{biblio_id}/ratings": diff --git a/koha-tmpl/opac-tmpl/bootstrap/js/pickup-locations.js b/koha-tmpl/opac-tmpl/bootstrap/js/pickup-locations.js index cb25fcdc70f..6aadd2dd50b 100644 --- a/koha-tmpl/opac-tmpl/bootstrap/js/pickup-locations.js +++ b/koha-tmpl/opac-tmpl/bootstrap/js/pickup-locations.js @@ -44,7 +44,6 @@ * * It expects the select object to contain several data-* attributes * - data-pickup-location-source: 'biblio', 'item' or 'hold' (default) - * - data-patron-id: required for 'biblio' and 'item' * - data-biblio-id: required for 'biblio' only * - data-item-id: required for 'item' only * @@ -54,7 +53,6 @@ $.fn.pickup_locations_dropdown = function () { var select = $(this); var pickup_location_source = $(this).data("pickup-location-source"); - var patron_id = $(this).data("patron-id"); var biblio_id = $(this).data("biblio-id"); var item_id = $(this).data("item-id"); var hold_id = $(this).data("hold-id"); @@ -63,18 +61,18 @@ if (pickup_location_source === "biblio") { url = - "/api/v1/biblios/" + + "/api/v1/public/biblios/" + encodeURIComponent(biblio_id) + "/pickup_locations"; } else if (pickup_location_source === "item") { url = - "/api/v1/items/" + + "/api/v1/public/items/" + encodeURIComponent(item_id) + "/pickup_locations"; } else { // hold url = - "/api/v1/holds/" + + "/api/v1/public/holds/" + encodeURIComponent(hold_id) + "/pickup_locations"; } @@ -98,10 +96,6 @@ _page: params.page, }; - if (pickup_location_source !== "hold") { - query["patron_id"] = patron_id; - } - return query; }, processResults: function (data) { -- 2.39.5