From a2742ae5d41894761e74f821d88a2567cc6be8d6 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Wed, 7 Jun 2023 10:42:15 -0300 Subject: [PATCH] Bug 33573: Add public endpoint for cancelling holds This patch introduces a public endpoint for cancelling holds. Cancellation requests are generated when the hold is waiting and configuration allows requesting cancellation, as the OPAC does right now. Tests cover all the use cases. To test: 1. Apply this patches 2. Run: $ ktd --shell k$ prove t/db_dependent/api/v1/patrons_holds.t => SUCCESS: Tests pass! 3. Sign off :-D --- Koha/REST/V1/Patrons/Holds.pm | 45 +++++++++++++++++++++++ api/v1/swagger/paths/public_patrons.yaml | 46 ++++++++++++++++++++++++ api/v1/swagger/swagger.yaml | 2 ++ 3 files changed, 93 insertions(+) diff --git a/Koha/REST/V1/Patrons/Holds.pm b/Koha/REST/V1/Patrons/Holds.pm index 370e13a2013..e4c2547ccb7 100644 --- a/Koha/REST/V1/Patrons/Holds.pm +++ b/Koha/REST/V1/Patrons/Holds.pm @@ -64,4 +64,49 @@ sub list { }; } + +=head3 delete_public + +Controller function that handles cancelling a hold for the requested patron. Returns +a I<204> if cancelling took place, and I<202> if a cancellation request is recorded +instead. + +=cut + +sub delete_public { + my $c = shift->openapi->valid_input or return; + + return try { + my $hold = $c->objects->find_rs( Koha::Holds->new, $c->param('hold_id') ); + + unless ( $hold and $c->param('patron_id') == $hold->borrowernumber ) { + return $c->render( + status => 404, + openapi => { error => 'Object not found' } + ); + } + + if ( $hold->is_cancelable_from_opac ) { + $hold->cancel; + return $c->render( + status => 204, + openapi => q{}, + ); + } elsif ( $hold->is_waiting and $hold->cancellation_requestable_from_opac ) { + $hold->add_cancellation_request; + return $c->render( + status => 202, + openapi => q{}, + ); + } else { # reject + return $c->render( + status => 403, + openapi => { error => 'Cancellation forbidden' } + ); + } + } catch { + $c->unhandled_exception($_); + }; +} + 1; diff --git a/api/v1/swagger/paths/public_patrons.yaml b/api/v1/swagger/paths/public_patrons.yaml index 2f92f6751bc..ef6233f42ae 100644 --- a/api/v1/swagger/paths/public_patrons.yaml +++ b/api/v1/swagger/paths/public_patrons.yaml @@ -170,3 +170,49 @@ $ref: "../swagger.yaml#/definitions/error" x-koha-authorization: allow-owner: true +"/public/patrons/{patron_id}/holds/{hold_id}": + delete: + x-mojo-to: Patrons::Holds#delete_public + operationId: cancelPatronHoldPublic + tags: + - patrons + summary: Cancel a patron's hold (public) + parameters: + - $ref: "../swagger.yaml#/parameters/patron_id_pp" + - $ref: "../swagger.yaml#/parameters/hold_id_pp" + produces: + - application/json + responses: + "202": + description: Hold cancellation request accepted + "204": + description: Hold cancelled + "400": + description: Bad request + 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: 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" + x-koha-authorization: + allow-owner: true diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 9e60aa77a2d..3faa4805dd1 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -325,6 +325,8 @@ paths: $ref: "./paths/public_patrons.yaml#/~1public~1patrons~1{patron_id}~1guarantors~1can_see_charges" "/public/patrons/{patron_id}/guarantors/can_see_checkouts": $ref: "./paths/public_patrons.yaml#/~1public~1patrons~1{patron_id}~1guarantors~1can_see_checkouts" + "/public/patrons/{patron_id}/holds/{hold_id}": + $ref: "./paths/public_patrons.yaml#/~1public~1patrons~1{patron_id}~1holds~1{hold_id}" "/public/patrons/{patron_id}/password": $ref: "./paths/public_patrons.yaml#/~1public~1patrons~1{patron_id}~1password" "/public/tickets": -- 2.34.1