From a0fbbc63db466635f46a21a54a4fca4e65bb7e23 Mon Sep 17 00:00:00 2001 From: Lari Taskula Date: Mon, 22 Aug 2016 17:35:44 +0300 Subject: [PATCH] Bug 17003: Add API route to get checkout's renewability Signed-off-by: Johanna Raisa Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize (cherry picked from commit 563458f20e413388d11cf92ea36d2867f488416f) Signed-off-by: Fridolin Somers --- Koha/REST/V1/Checkouts.pm | 35 ++++++++++++++++++++ api/v1/swagger/definitions.json | 3 ++ api/v1/swagger/definitions/renewability.json | 13 ++++++++ api/v1/swagger/paths.json | 3 ++ api/v1/swagger/paths/checkouts.json | 31 +++++++++++++++++ t/db_dependent/api/v1/checkouts.t | 11 ++++++ 6 files changed, 96 insertions(+) create mode 100644 api/v1/swagger/definitions/renewability.json diff --git a/Koha/REST/V1/Checkouts.pm b/Koha/REST/V1/Checkouts.pm index 0e3b60e445..a45974369a 100644 --- a/Koha/REST/V1/Checkouts.pm +++ b/Koha/REST/V1/Checkouts.pm @@ -18,6 +18,7 @@ package Koha::REST::V1::Checkouts; use Modern::Perl; use Mojo::Base 'Mojolicious::Controller'; +use Mojo::JSON; use C4::Auth qw( haspermission ); use C4::Context; @@ -127,6 +128,40 @@ sub renew { ); } +sub renewability { + my ($c, $args, $cb) = @_; + + my $user = $c->stash('koha.user'); + + my $OpacRenewalAllowed; + if ($user->borrowernumber == $borrowernumber) { + $OpacRenewalAllowed = C4::Context->preference('OpacRenewalAllowed'); + } + + unless ($user && ($OpacRenewalAllowed + || haspermission($user->userid, { circulate => "circulate_remaining_permissions" }))) { + return $c->$cb({error => "You don't have the required permission"}, 403); + } + + my $checkout_id = $args->{checkout_id}; + my $checkout = Koha::Issues->find($checkout_id); + + if (!$checkout) { + return $c->$cb({ + error => "Checkout doesn't exist" + }, 404); + } + + my $borrowernumber = $checkout->borrowernumber; + my $itemnumber = $checkout->itemnumber; + + my ($can_renew, $error) = C4::Circulation::CanBookBeRenewed( + $borrowernumber, $itemnumber); + + return $c->$cb({ renewable => Mojo::JSON->true, error => undef }, 200) if $can_renew; + return $c->$cb({ renewable => Mojo::JSON->false, error => $error }, 200); +} + =head3 _to_api Helper function that maps a hashref of Koha::Checkout attributes into REST api diff --git a/api/v1/swagger/definitions.json b/api/v1/swagger/definitions.json index 1dc90f3f58..8fe086da7e 100644 --- a/api/v1/swagger/definitions.json +++ b/api/v1/swagger/definitions.json @@ -32,6 +32,9 @@ "patron_balance": { "$ref": "definitions/patron_balance.json" }, + "renewability": { + "$ref": "definitions/renewability.json" + }, "vendor": { "$ref": "definitions/vendor.json" }, diff --git a/api/v1/swagger/definitions/renewability.json b/api/v1/swagger/definitions/renewability.json new file mode 100644 index 0000000000..654691e8b4 --- /dev/null +++ b/api/v1/swagger/definitions/renewability.json @@ -0,0 +1,13 @@ +{ + "type": "object", + "properties": { + "renewable": { + "type": "boolean", + "description": "Renewability status; true = renewable, false = not renewable" + }, + "error": { + "type": ["string", "null"], + "description": "Description on false renewability." + } + } +} diff --git a/api/v1/swagger/paths.json b/api/v1/swagger/paths.json index 33cfd3aa5a..9a6bf3ca9f 100644 --- a/api/v1/swagger/paths.json +++ b/api/v1/swagger/paths.json @@ -44,6 +44,9 @@ "/libraries/{library_id}": { "$ref": "paths/libraries.json#/~1libraries~1{library_id}" }, + "/checkouts/{checkout_id}/renewability": { + "$ref": "paths/checkouts.json#/~1checkouts~1{checkout_id}~1renewability" + }, "/patrons": { "$ref": "paths/patrons.json#/~1patrons" }, diff --git a/api/v1/swagger/paths/checkouts.json b/api/v1/swagger/paths/checkouts.json index 3cb15c49a1..76e7151824 100644 --- a/api/v1/swagger/paths/checkouts.json +++ b/api/v1/swagger/paths/checkouts.json @@ -96,5 +96,36 @@ } } } + }, + "/checkouts/{checkout_id}/renewability": { + "get": { + "operationId": "renewabilityCheckout", + "tags": ["patrons", "checkouts"], + "parameters": [{ + "$ref": "../parameters.json#/checkoutIdPathParam" + }], + "produces": ["application/json"], + "responses": { + "200": { + "description": "Checkout renewability", + "schema": { "$ref": "../definitions.json#/renewability" } + }, + "403": { + "description": "Forbidden", + "schema": { "$ref": "../definitions.json#/error" } + }, + "404": { + "description": "Checkout not found", + "schema": { "$ref": "../definitions.json#/error" } + } + }, + "x-koha-authorization": { + "allow-owner": true, + "allow-guarantor": true, + "permissions": { + "circulate": "circulate_remaining_permissions" + } + } + } } } diff --git a/t/db_dependent/api/v1/checkouts.t b/t/db_dependent/api/v1/checkouts.t index c4da7461c3..e4c0f2102e 100644 --- a/t/db_dependent/api/v1/checkouts.t +++ b/t/db_dependent/api/v1/checkouts.t @@ -169,6 +169,12 @@ $t->post_ok( "//$unauth_userid:$unauth_password@/api/v1/checkouts/" . $issue3->i required_permissions => { circulate => "circulate_remaining_permissions" } }); +$tx = $t->ua->build_tx(GET => "/api/v1/checkouts/" . $issue2->issue_id . "/renewability"); +$tx->req->cookies({name => 'CGISESSID', value => $patron_session->id}); +$t->request_ok($tx) + ->status_is(200) + ->json_is({ renewable => Mojo::JSON->true, error => undef }); + $t->post_ok( "//$userid:$password@/api/v1/checkouts/" . $issue2->issue_id . "/renewal" ) ->status_is(201) ->json_is('/due_date' => output_pref({ dateformat => "rfc3339", dt => $expected_datedue}) ) @@ -179,3 +185,8 @@ $t->post_ok( "//$userid:$password@/api/v1/checkouts/" . $issue1->issue_id . "/re ->status_is(403) ->json_is({ error => 'Renewal not authorized (too_many)' }); +$tx = $t->ua->build_tx(GET => "/api/v1/checkouts/" . $issue2->issue_id . "/renewability"); +$tx->req->cookies({name => 'CGISESSID', value => $patron_session->id}); +$t->request_ok($tx) + ->status_is(200) + ->json_is({ renewable => Mojo::JSON->false, error => 'too_many' }); -- 2.39.5