From 651b0da46e8d3c15716e35ea04ac8bbdf3087a82 Mon Sep 17 00:00:00 2001 From: Agustin Moyano Date: Fri, 30 Dec 2022 12:18:37 -0300 Subject: [PATCH] Bug 31798: Add REST endpoint to add a biblio's item To test: 1. Apply patch 2. Set RESTBasicAuth preference to true 3. Get a biblio 4. Make a POST request to /api/v1/biblios/:biblio_id/items with a json body that represents the new item 5. Check that the item is created 6. Sign off --- Koha/REST/V1/Biblios.pm | 62 ++++++++++++++++++++++++++++ api/v1/swagger/definitions/item.yaml | 7 ---- api/v1/swagger/paths/biblios.yaml | 51 +++++++++++++++++++++++ t/db_dependent/api/v1/biblios.t | 51 ++++++++++++++++++++++- 4 files changed, 163 insertions(+), 8 deletions(-) diff --git a/Koha/REST/V1/Biblios.pm b/Koha/REST/V1/Biblios.pm index f923255cfa..2cc70b7151 100644 --- a/Koha/REST/V1/Biblios.pm +++ b/Koha/REST/V1/Biblios.pm @@ -24,6 +24,12 @@ use Koha::Ratings; use Koha::RecordProcessor; use C4::Biblio qw( DelBiblio ); +use C4::Barcodes::ValueBuilder; +use C4::Context; + +use Koha::Items; +use Koha::Item; + use List::MoreUtils qw( any ); use MARC::Record::MiJ; @@ -270,6 +276,62 @@ sub get_items { }; } +=head3 add_item + +Controller function that handles creating a biblio's item + +=cut + +sub add_item { + my $c = shift->openapi->valid_input or return; + + try { + my $biblio_id = $c->validation->param('biblio_id'); + my $biblio = Koha::Biblios->find( $biblio_id ); + + unless ($biblio) { + return $c->render( + status => 404, + openapi => { error => "Biblio not found" } + ); + } + + my $body = $c->validation->param('body'); + + $body->{biblio_id} = $biblio_id; + + # Don't save extended subfields yet. To be done in another bug. + $body->{extended_subfields} = undef; + + my $item = Koha::Item->new_from_api($body); + + if ( ! defined $item->barcode && C4::Context->preference('autoBarcode') eq 'incremental' ) { + my ( $barcode ) = C4::Barcodes::ValueBuilder::incremental::get_barcode; + $item->barcode($barcode); + } + + if ( defined $item->barcode + && Koha::Items->search( { barcode => $item->barcode } )->count ) + { + return $c->render( + status => 400, + openapi => { error => "Barcode not unique" } + ); + } + + my $storedItem = $item->store; + $storedItem->discard_changes; + + $c->render( + status => 201, + openapi => $storedItem->to_api + ); + } + catch { + $c->unhandled_exception($_); + } +} + =head3 get_checkouts List Koha::Checkout objects diff --git a/api/v1/swagger/definitions/item.yaml b/api/v1/swagger/definitions/item.yaml index 069c0faebc..bbc07072a8 100644 --- a/api/v1/swagger/definitions/item.yaml +++ b/api/v1/swagger/definitions/item.yaml @@ -229,10 +229,3 @@ properties: - "null" description: A return claims object if one exists that's unresolved additionalProperties: false -required: - - item_id - - biblio_id - - not_for_loan_status - - damaged_status - - lost_status - - withdrawn diff --git a/api/v1/swagger/paths/biblios.yaml b/api/v1/swagger/paths/biblios.yaml index 782de211e7..5b2fa3b45d 100644 --- a/api/v1/swagger/paths/biblios.yaml +++ b/api/v1/swagger/paths/biblios.yaml @@ -217,6 +217,57 @@ x-koha-authorization: permissions: catalogue: "1" + post: + x-mojo-to: Biblios#add_item + operationId: addBiblioItem + tags: + - biblios + summary: Add an item for a biblio + parameters: + - $ref: "../swagger.yaml#/parameters/biblio_id_pp" + - name: body + in: body + description: A JSON object containing information about the new item + required: true + schema: + $ref: "../swagger.yaml#/definitions/item" + produces: + - application/json + responses: + "201": + description: Item added + schema: + $ref: "../swagger.yaml#/definitions/item" + "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: 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: + permissions: + editcatalogue: edit_catalogue "/biblios/{biblio_id}/pickup_locations": get: x-mojo-to: Biblios#pickup_locations diff --git a/t/db_dependent/api/v1/biblios.t b/t/db_dependent/api/v1/biblios.t index b4e98b17f4..7dbbf859b9 100755 --- a/t/db_dependent/api/v1/biblios.t +++ b/t/db_dependent/api/v1/biblios.t @@ -20,7 +20,7 @@ use Modern::Perl; use utf8; use Encode; -use Test::More tests => 8; +use Test::More tests => 9; use Test::MockModule; use Test::Mojo; use Test::Warn; @@ -713,3 +713,52 @@ subtest 'set_rating() tests' => sub { $schema->storage->txn_rollback; }; + +subtest 'add_item() tests' => sub { + plan tests => 5; + + $schema->storage->txn_begin; + + my $patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 0 } + } + ); + my $password = 'thePassword123'; + $patron->set_password( { password => $password, skip_validation => 1 } ); + my $userid = $patron->userid; + + my $biblio = $builder->build_sample_biblio(); + my $biblio_id = $biblio->biblionumber; + + my $barcode = 'mybarcode'; + my $matching_items = Koha::Items->search({ barcode => $barcode }); + + while (my $item = $matching_items->next) { + $item->delete; + } + + $t->post_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items" => json => { external_id => $barcode }) + ->status_is(403, 'Not enough permissions to create an item'); + + # Add permissions + $builder->build( + { + source => 'UserPermission', + value => { + borrowernumber => $patron->borrowernumber, + module_bit => 9, + code => 'edit_catalogue' + } + } + ); + + $t->post_ok("//$userid:$password@/api/v1/biblios/$biblio_id/items" => json => { + external_id => $barcode, + }) + ->status_is(201, 'Item created') + ->json_is('/biblio_id', $biblio_id); + + $schema->storage->txn_rollback; +}; -- 2.25.1