@@ -, +, @@ use it in the holds table --- Koha/Hold.pm | 14 +++++ Koha/REST/V1/Holds.pm | 32 +++++++++++ api/v1/swagger/paths.json | 3 + api/v1/swagger/paths/holds.json | 57 +++++++++++++++++++ .../prog/en/includes/holds_table.inc | 6 +- .../prog/en/modules/reserve/request.tt | 1 + koha-tmpl/intranet-tmpl/prog/js/holds.js | 30 ++++++++++ 7 files changed, 141 insertions(+), 2 deletions(-) --- a/Koha/Hold.pm +++ a/Koha/Hold.pm @@ -338,6 +338,20 @@ sub biblio { return $self->{_biblio}; } +=head3 patron + +Returns the related Koha::Patron object for this hold + +=cut + +sub patron { + my ($self) = @_; + + $self->{_patron} ||= Koha::Patrons->find( $self->borrowernumber() ); + + return $self->{_patron}; +} + =head3 item Returns the related Koha::Item object for this Hold --- a/Koha/REST/V1/Holds.pm +++ a/Koha/REST/V1/Holds.pm @@ -395,4 +395,36 @@ sub update_priority { }; } +=head3 pickup_locations + +Method that returns the possible pickup_locations for a given hold +used for building the dropdown selector + +=cut + +sub pickup_locations { + my $c = shift->openapi->valid_input or return; + + my $hold_id = $c->validation->param('hold_id'); + my $hold = Koha::Holds->find($hold_id); + + unless ($hold) { + return $c->render( + status => 404, + openapi => { error => "Hold not found" } + ); + } + + return try { + my $pickup_locations = $hold->itemnumber ? + $hold->item->pickup_locations({ patron => $hold->patron }) : $hold->biblio->pickup_locations({ patron => $hold->patron }); + warn Data::Dumper::Dumper( $pickup_locations ); + + return $c->render( status => 200, openapi => $pickup_locations ); + } + catch { + $c->unhandled_exception($_); + }; +} + 1; --- a/api/v1/swagger/paths.json +++ a/api/v1/swagger/paths.json @@ -59,6 +59,9 @@ "/holds/{hold_id}/suspension": { "$ref": "paths/holds.json#/~1holds~1{hold_id}~1suspension" }, + "/holds/{hold_id}/pickup_locations": { + "$ref": "paths/holds.json#/~1holds~1{hold_id}~1pickup_locations" + }, "/items": { "$ref": "paths/items.json#/~1items" }, --- a/api/v1/swagger/paths/holds.json +++ a/api/v1/swagger/paths/holds.json @@ -613,5 +613,62 @@ } } } + }, + "/holds/{hold_id}/pickup_locations": { + "get": { + "x-mojo-to": "Holds#pickup_locations", + "operationId": "getHoldPickupLocations", + "tags": ["holds"], + "parameters": [{ + "$ref": "../parameters.json#/hold_id_pp" + }], + "produces": ["application/json"], + "responses": { + "200": { + "description": "Hold pickup location" + }, + "400": { + "description": "Missing or wrong parameters", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "401": { + "description": "Authentication required", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "403": { + "description": "Hold pickup location list not allowed", + "schema": { + "$ref": "../definitions.json#/error" + } + }, + "404": { + "description": "Hold 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": "1" + } + } + } } } --- a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc +++ a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc @@ -132,9 +132,11 @@ [% IF Koha.Preference('IndependentBranches') && Branches.all().size == 1 %] [% Branches.GetName(hold.branchcode) | html %] [% ELSE %] - + + + [% END %] [% END %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -985,6 +985,7 @@ [% INCLUDE 'columns_settings.inc' %] [% Asset.js("lib/hc-sticky.js") | $raw %] [% Asset.js("js/circ-patron-search-results.js") | $raw %] + [% Asset.js("js/holds.js") | $raw %]