From 832eec2683cc87a4e4c844303d009823cdeb327e 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 Signed-off-by: Sam Lau --- 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 370e13a201..e4c2547ccb 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 2f92f6751b..ef6233f42a 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 9e60aa77a2..3faa4805dd 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.30.2