From 2dc2bbb13a4ed54c8499e8e5e16fc9859c292ebb Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Thu, 11 Mar 2021 16:30:52 -0300 Subject: [PATCH] Bug 27931: Add GET /items/:item_id/pickup_locations This patch adds the mentioned route. It does so by: - Adding the new path in paths.json - Adding the full route spec in items.json - Adds a controller method that takes care of the task To test: 1. Apply this patches 2. Run: $ kshell k$ prove t/db_dependent/api/v1/items.t => SUCCESS: Tests pass! 3. Play with your favourite REST tool. Pay special care to the AllowHoldPolicyOverride syspref and the expected behaviors. => SUCCESS: All works as expected 4. Sign off :-D --- Koha/REST/V1/Items.pm | 72 +++++++++++++++++++++++ api/v1/swagger/paths.json | 3 + api/v1/swagger/paths/items.json | 101 ++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+) diff --git a/Koha/REST/V1/Items.pm b/Koha/REST/V1/Items.pm index 4781024b362..21e7aa9febb 100644 --- a/Koha/REST/V1/Items.pm +++ b/Koha/REST/V1/Items.pm @@ -21,6 +21,7 @@ use Mojo::Base 'Mojolicious::Controller'; use Koha::Items; +use List::MoreUtils qw(any); use Try::Tiny; =head1 NAME @@ -80,4 +81,75 @@ sub get { }; } +=head3 pickup_locations + +Method that returns the possible pickup_locations for a given item +used for building the dropdown selector + +=cut + +sub pickup_locations { + my $c = shift->openapi->valid_input or return; + + my $item_id = $c->validation->param('item_id'); + my $item = Koha::Items->find( $item_id ); + + unless ($item) { + return $c->render( + status => 404, + openapi => { error => "Item not found" } + ); + } + + my $patron_id = delete $c->validation->output->{patron_id}; + my $patron = Koha::Patrons->find( $patron_id ); + + unless ($patron) { + return $c->render( + status => 400, + openapi => { error => "Patron not found" } + ); + } + + return try { + + my $ps_set = $item->pickup_locations( { patron => $patron } ); + + my $pickup_locations = $c->objects->search( $ps_set ); + my @response = (); + + if ( C4::Context->preference('AllowHoldPolicyOverride') ) { + + my $libraries_rs = Koha::Libraries->search( { pickup_location => 1 } ); + my $libraries = $c->objects->search($libraries_rs); + + @response = map { + my $library = $_; + $library->{needs_override} = ( + any { $_->{library_id} eq $library->{library_id} } + @{$pickup_locations} + ) + ? Mojo::JSON->false + : Mojo::JSON->true; + $library; + } @{$libraries}; + + return $c->render( + status => 200, + openapi => \@response + ); + } + + @response = map { $_->{needs_override} = Mojo::JSON->false; $_; } @{$pickup_locations}; + + return $c->render( + status => 200, + openapi => \@response + ); + } + catch { + $c->unhandled_exception($_); + }; +} + 1; diff --git a/api/v1/swagger/paths.json b/api/v1/swagger/paths.json index 1e3d2fa82a1..33a3d04b620 100644 --- a/api/v1/swagger/paths.json +++ b/api/v1/swagger/paths.json @@ -80,6 +80,9 @@ "/items/{item_id}": { "$ref": "paths/items.json#/~1items~1{item_id}" }, + "/items/{item_id}/pickup_locations": { + "$ref": "paths/items.json#/~1items~1{item_id}~1pickup_locations" + }, "/libraries": { "$ref": "paths/libraries.json#/~1libraries" }, diff --git a/api/v1/swagger/paths/items.json b/api/v1/swagger/paths/items.json index 86197eadf10..06b0b6cb063 100644 --- a/api/v1/swagger/paths/items.json +++ b/api/v1/swagger/paths/items.json @@ -124,5 +124,106 @@ } } } + }, + "/items/{item_id}/pickup_locations": { + "get": { + "x-mojo-to": "Items#pickup_locations", + "operationId": "getItemPickupLocations", + "tags": [ + "items", + "pickup_locations" + ], + "parameters": [ + { + "$ref": "../parameters.json#/item_id_pp" + }, + { + "name": "patron_id", + "in": "query", + "description": "Internal patron identifier", + "required": true, + "type": "integer" + }, + { + "$ref": "../parameters.json#/match" + }, + { + "$ref": "../parameters.json#/order_by" + }, + { + "$ref": "../parameters.json#/page" + }, + { + "$ref": "../parameters.json#/per_page" + }, + { + "$ref": "../parameters.json#/q_param" + }, + { + "$ref": "../parameters.json#/q_body" + }, + { + "$ref": "../parameters.json#/q_header" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "Item pickup locations", + "schema": { + "type": "array", + "items": { + "$ref": "../definitions.json#/library" + } + } + }, + "400": { + "description": "Missing or wrong parameters", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "401": { + "description": "Authentication required", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "403": { + "description": "Access forbidden", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Biblio not found", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "500": { + "description": "Internal server error", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "503": { + "description": "Under maintenance", + "schema": { + "$ref": "../definitions.json#/error" + } + } + }, + "x-koha-authorization": { + "permissions": { + "reserveforothers": "place_holds" + } + } + } } } -- 2.30.2