From 252753f84f53a33f3fd3bd4bf3fb8ae02b53ede7 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 Signed-off-by: Emily Lamancusa Signed-off-by: Tomas Cohen Arazi --- 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 33022743f9..07f27fd0d4 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -327,6 +327,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.39.2