Bugzilla – Attachment 151044 Details for
Bug 24400
REST API: Checkout
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24400: Rest API for checkout
Bug-24400-Rest-API-for-checkout.patch (text/plain), 9.17 KB, created by
Danyon Sewell
on 2023-05-11 04:44:34 UTC
(
hide
)
Description:
Bug 24400: Rest API for checkout
Filename:
MIME Type:
Creator:
Danyon Sewell
Created:
2023-05-11 04:44:34 UTC
Size:
9.17 KB
patch
obsolete
>From 3057af973a9fdf5135219c1b2dd1af459a27c48d Mon Sep 17 00:00:00 2001 >From: danyonsewell <danyonsewell@catalyst.net.nz> >Date: Mon, 1 May 2023 04:54:35 +0000 >Subject: [PATCH] Bug 24400: Rest API for checkout > >Feature to provide API endpoints for checking out items. > >To test: >1) Apply this patch >2) Run: > $ ktd --shell > $ prove t/db_dependent/api/v1/items.t >=> SUCCESS: Tests pass! >3. Play with item checkout using a REST tool like Postman >=> SUCCESS: All works as expected >4. Sign off :-D > >Sponsored-by: Auckland University of Technology >--- > Koha/REST/V1/Items.pm | 69 ++++++++++++++++------- > api/v1/swagger/paths/items.yaml | 35 ++++++++++++ > api/v1/swagger/swagger.yaml | 2 + > t/db_dependent/api/v1/items.t | 97 ++++++++++++++++++++++++++++++++- > 4 files changed, 182 insertions(+), 21 deletions(-) > >diff --git a/Koha/REST/V1/Items.pm b/Koha/REST/V1/Items.pm >index 938ffcd659..45e0fa2354 100644 >--- a/Koha/REST/V1/Items.pm >+++ b/Koha/REST/V1/Items.pm >@@ -27,19 +27,13 @@ use List::MoreUtils qw( any ); > use Try::Tiny qw( catch try ); > > =head1 NAME >- > Koha::REST::V1::Items - Koha REST API for handling items (V1) >- > =head1 API >- > =head2 Methods >- > =cut > > =head3 list >- > Controller function that handles listing Koha::Item objects >- > =cut > > sub list { >@@ -59,9 +53,7 @@ sub list { > } > > =head3 list_public >- > Controller function that handles listing Koha::Item objects available to the opac >- > =cut > > sub list_public { >@@ -85,9 +77,7 @@ sub list_public { > } > > =head3 get >- > Controller function that handles retrieving a single Koha::Item >- > =cut > > sub get { >@@ -110,9 +100,7 @@ sub get { > } > > =head3 delete >- > Controller function that handles deleting a single Koha::Item >- > =cut > > sub delete { >@@ -173,12 +161,59 @@ sub delete { > $c->unhandled_exception($_); > }; > } >+=head3 checkout > >-=head3 pickup_locations >+Check out an item >+ >+=cut >+ >+sub checkout { >+ my $c = shift->openapi->valid_input or return; >+ my $item_id = $c->validation->param('item_id'); >+ my $item = Koha::Items->find( $item_id ); >+ unless ( $item ) { >+ return $c->render( >+ status => 404, >+ openapi => { error => "Item not found" } >+ ); >+ } >+ my $patron_id = $c->validation->param('patron_id'); >+ my $patron = Koha::Patrons->find( $patron_id ); >+ unless ( $patron ) { >+ return $c->render( >+ status => 400, >+ openapi => { error => "Patron not found" } >+ ); >+ } >+ try { >+ my $barcode = $item->barcode; >+ my ( $issuing_impossible, $needs_confirmation ) = C4::Circulation::CanBookBeIssued( $patron, $barcode ); >+ if ( keys %$issuing_impossible or keys %$needs_confirmation ) { >+ return $c->render( >+ status => 403, >+ openapi => { error => "Checkout not allowed" } >+ ); >+ } >+ my $borrower = $patron->unblessed; >+ my $checkout = C4::Circulation::AddIssue( >+ $borrower, >+ $barcode >+ ); >+ >+ $c->res->headers->location( $c->req->url->to_string ); >+ return $c->render( >+ status => 201, >+ openapi => $checkout->to_api >+ ); >+ } >+ catch { >+ $c->unhandled_exception($_); >+ }; >+} > >+=head3 pickup_locations > Method that returns the possible pickup_locations for a given item > used for building the dropdown selector >- > =cut > > sub pickup_locations { >@@ -242,9 +277,7 @@ sub pickup_locations { > } > > =head3 bundled_items >- > Controller function that handles bundled_items Koha::Item objects >- > =cut > > sub bundled_items { >@@ -274,9 +307,7 @@ sub bundled_items { > } > > =head3 add_to_bundle >- > Controller function that handles adding items to this bundle >- > =cut > > sub add_to_bundle { >@@ -371,9 +402,7 @@ sub add_to_bundle { > } > > =head3 remove_from_bundle >- > Controller function that handles removing items from this bundle >- > =cut > > sub remove_from_bundle { >diff --git a/api/v1/swagger/paths/items.yaml b/api/v1/swagger/paths/items.yaml >index ac8c313a14..c8029f1dc6 100644 >--- a/api/v1/swagger/paths/items.yaml >+++ b/api/v1/swagger/paths/items.yaml >@@ -396,6 +396,41 @@ > x-koha-authorization: > permissions: > reserveforothers: place_holds >+"/items/{item_id}/checkout/{patron_id}": >+ post: >+ x-mojo-to: Items#checkout >+ operationId: addCheckout >+ tags: >+ - items >+ - checkouts >+ summary: Add a checkout >+ parameters: >+ - $ref: "../swagger.yaml#/parameters/item_id_pp" >+ - $ref: "../swagger.yaml#/parameters/patron_id_pp" >+ consumes: >+ - application/json >+ produces: >+ - application/json >+ responses: >+ "201": >+ description: Added checkout >+ schema: >+ $ref: "../swagger.yaml#/definitions/checkout" >+ "400": >+ description: Patron not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Cannot add checkout >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "404": >+ description: Item not found >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ x-koha-authorization: >+ permissions: >+ circulate: circulate_remaining_permissions > "/public/items": > get: > x-mojo-to: Items#list_public >diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml >index 23c59b96a1..562a8f9d07 100644 >--- a/api/v1/swagger/swagger.yaml >+++ b/api/v1/swagger/swagger.yaml >@@ -273,6 +273,8 @@ paths: > $ref: ./paths/items.yaml#/~1items~1{item_id}~1bundled_items~1{bundled_item_id} > "/items/{item_id}/pickup_locations": > $ref: "./paths/items.yaml#/~1items~1{item_id}~1pickup_locations" >+ "/items/{item_id}/checkout/{patron_id}": >+ $ref: "./paths/items.yaml#/~1items~1{item_id}~1checkout~1{patron_id}" > /jobs: > $ref: ./paths/jobs.yaml#/~1jobs > "/jobs/{job_id}": >diff --git a/t/db_dependent/api/v1/items.t b/t/db_dependent/api/v1/items.t >index a4a6300652..3c3c3b56e5 100755 >--- a/t/db_dependent/api/v1/items.t >+++ b/t/db_dependent/api/v1/items.t >@@ -19,7 +19,7 @@ > > use Modern::Perl; > >-use Test::More tests => 5; >+use Test::More tests => 6; > use Test::MockModule; > use Test::Mojo; > use Test::Warn; >@@ -30,6 +30,7 @@ use t::lib::Mocks; > use Mojo::JSON qw(encode_json); > > use C4::Auth; >+use C4::Circulation; > use Koha::Items; > use Koha::Database; > >@@ -572,3 +573,97 @@ subtest 'pickup_locations() tests' => sub { > > $schema->storage->txn_rollback; > }; >+ >+subtest 'checkout() tests' => sub { >+ >+ plan tests => 27; >+ >+ $schema->storage->txn_begin; >+ >+ my $item = $builder->build_sample_item; >+ my $item2 = $builder->build_sample_item; >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 4 } >+ } >+ ); >+ >+ # Make sure we have at least 10 items >+ for ( 1..10 ) { >+ $builder->build_sample_item; >+ } >+ >+ my $nonprivilegedpatron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ my $password = 'thePassword123'; >+ >+ $nonprivilegedpatron->set_password( >+ { password => $password, skip_validation => 1 } ); >+ >+ my $userid = $nonprivilegedpatron->userid; >+ my $itemid = $item->id; >+ my $itemid2 = $item2->id; >+ my $patronid = $patron->borrowernumber; >+ my $non_existent_code = $item->itemnumber; >+ >+ $t->post_ok( "//$userid:$password@/api/v1/items/$itemid/checkout/$patronid" ) >+ ->status_is(403) >+ ->json_is( >+ '/error' => 'Authorization failure. Missing required permission(s).' ); >+ >+ $t->get_ok( "//$userid:$password@/api/v1/items/" . $non_existent_code ) >+ ->status_is(403) >+ ->json_is( >+ '/error' => 'Authorization failure. Missing required permission(s).' ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ $userid = $patron->userid; >+ >+ $t->get_ok( "//$userid:$password@/api/v1/items?_per_page=10" ) >+ ->status_is( 200, 'SWAGGER3.2.2' ); >+ >+ my $response_count = scalar @{ $t->tx->res->json }; >+ >+ is( $response_count, 10, 'The API returns 10 items' ); >+ >+ $t->get_ok( "//$userid:$password@/api/v1/items?external_id=" . $item->barcode ) >+ ->status_is(200) >+ ->json_is( '' => [ $item->to_api ], 'SWAGGER3.3.2'); >+ >+ $patron->flags(1)->store; >+ my $deleted_patron_id = $nonprivilegedpatron->id; >+ $nonprivilegedpatron->delete; >+ $t->post_ok( "//$userid:$password@/api/v1/items/$itemid/checkout/$deleted_patron_id" ) >+ ->status_is(400) >+ ->json_is( '/error' => 'Patron not found' ); >+ >+ my $barcode = $item->barcode; >+ $item->delete; >+ >+ $t->post_ok("//$userid:$password@/api/v1/items/$itemid/checkout/$patronid") >+ ->status_is(404); >+ >+ $t->get_ok( "//$userid:$password@/api/v1/items?external_id=" . $item->barcode ) >+ ->status_is(200) >+ ->json_is( '' => [] ); >+ >+ $t->get_ok( "//$userid:$password@/api/v1/items/" . $non_existent_code ) >+ ->status_is(404) >+ ->json_is( >+ '/error' => 'Item not found' ); >+ >+ is( $patron->checkouts->count, 0); >+ >+ $t->post_ok( "//$userid:$password@/api/v1/items/$itemid2/checkout/$patronid") >+ ->status_is(201); >+ >+ is( $patron->checkouts->count, 1); >+ >+ $schema->storage->txn_rollback; >+}; >-- >2.30.2
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 24400
:
150449
|
150495
|
150920
|
150921
|
151043
| 151044