From ecb97402d93aa9ea1aeaee5c444ca0248502f8a8 Mon Sep 17 00:00:00 2001 From: Jan Kissig Date: Thu, 4 Jul 2024 13:37:47 +0200 Subject: [PATCH] Bug 37253: Enhance POST /checkouts endpoint to accept barcode or item_id This patch adds external_id as a body param in POST /checkouts which acts as the items barcode. This enhances the checkouts route to checkout items directly via barcode which could be useful for external tools like Koha Offline Circulation Tool Test plan: a) apply patch b) enable system preference RESTBasicAuth c) check out an item via an API testing tool. Be sure that item is not checked out already. Auth: username: koha & password: koha Body JSON: { "external_id" : "39999000011418", "library_id": "CPL", "patron_id": 5 } POST http://localhost:8081/api/v1/checkouts d) check response code 201 and response content Signed-off-by: Matt Blenkinsop Signed-off-by: Tomas Cohen Arazi --- Koha/REST/V1/Checkouts.pm | 35 +++++++++++++++++++++++- api/v1/swagger/definitions/checkout.yaml | 6 +++- t/db_dependent/api/v1/checkouts.t | 24 ++++++++++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Koha/REST/V1/Checkouts.pm b/Koha/REST/V1/Checkouts.pm index 301369a45c3..a2c76c6efa8 100644 --- a/Koha/REST/V1/Checkouts.pm +++ b/Koha/REST/V1/Checkouts.pm @@ -189,6 +189,7 @@ sub add { my $item_id = $body->{item_id}; my $patron_id = $body->{patron_id}; my $onsite = $body->{onsite_checkout}; + my $barcode = $body->{external_id}; if ( $c->stash('is_public') && !C4::Context->preference('OpacTrustedCheckout') ) @@ -203,7 +204,24 @@ sub add { } return try { - my $item = Koha::Items->find($item_id); + + unless ( $item_id or $barcode ) { + return $c->render( + status => 400, + openapi => { + error => 'Missing or wrong parameters', + error_code => 'MISSING_OR_WRONG_PARAMETERS', + } + ); + } + + my $item; + if ($item_id) { + $item = Koha::Items->find($item_id); + } else { + $item = Koha::Items->find( { barcode => $barcode } ); + } + unless ($item) { return $c->render( status => 409, @@ -214,6 +232,21 @@ sub add { ); } + # check that item matches when barcode and item_id were given + if ( $item_id + and $barcode + and ( $item->barcode ne $barcode or $item->id != $item_id ) ) + { + return $c->render( + status => 409, + openapi => { + error => 'Item id and external id belong to different items', + error_code => 'ITEM_ID_NOT_MATCHING_EXTERNAL_ID', + } + ); + } + + my $patron = Koha::Patrons->find($patron_id); unless ($patron) { return $c->render( diff --git a/api/v1/swagger/definitions/checkout.yaml b/api/v1/swagger/definitions/checkout.yaml index 4a9847623c2..4ace091bd58 100644 --- a/api/v1/swagger/definitions/checkout.yaml +++ b/api/v1/swagger/definitions/checkout.yaml @@ -11,7 +11,11 @@ properties: type: - integer - "null" - description: internal identifier of checked out item + external_id: + type: + - string + - "null" + description: other identifier of checked out item f.e. barcode due_date: type: string format: date-time diff --git a/t/db_dependent/api/v1/checkouts.t b/t/db_dependent/api/v1/checkouts.t index 8f306df0e0e..779f00156ac 100755 --- a/t/db_dependent/api/v1/checkouts.t +++ b/t/db_dependent/api/v1/checkouts.t @@ -439,7 +439,7 @@ subtest 'get_availability' => sub { subtest 'add checkout' => sub { - plan tests => 10; + plan tests => 14; $schema->storage->txn_begin; my $librarian = $builder->build_object( @@ -465,8 +465,13 @@ subtest 'add checkout' => sub { my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode}; - my $item1 = $builder->build_sample_item; - my $item1_id = $item1->id; + my $item1 = $builder->build_sample_item; + my $item1_id = $item1->id; + my $item1_barcode = $item1->barcode; + + my $item2 = $builder->build_sample_item; + my $item2_id = $item2->id; + my $item2_barcode = $item2->barcode; my %issuingimpossible = (); my %needsconfirmation = (); @@ -491,6 +496,19 @@ subtest 'add checkout' => sub { $t->post_ok( "//$userid:$password@/api/v1/checkouts" => json => { item_id => $item1_id, patron_id => $patron_id } ) ->status_is(201); + $t->post_ok( + "//$userid:$password@/api/v1/checkouts" => json => { external_id => $item1_barcode, patron_id => $patron_id } ) + ->status_is(201); + + # mismatch of item_id and barcode when both given + $t->post_ok( + "//$userid:$password@/api/v1/checkouts" => json => { + external_id => $item1_barcode, + item_id => $item2_id, + patron_id => $patron_id + } + )->status_is(409); + # Needs confirm %needsconfirmation = ( confirm1 => 1, confirm2 => 'please' ); $t->post_ok( -- 2.47.0