From 61b21aaebc853f70c9d19ffcaca34a9cf304ef8d Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Mon, 6 Nov 2023 18:17:54 +0000 Subject: [PATCH] Bug 34784: (QA follow-up) Signed-off-by: Katrin Fischer --- Koha/REST/V1/Biblios.pm | 50 +++++++++++++- api/v1/swagger/paths/biblios.yaml | 46 +++++++++++++ api/v1/swagger/swagger.yaml | 2 + .../prog/en/includes/cat-toolbar.inc | 12 ++-- .../prog/en/modules/catalogue/detail.tt | 14 ++-- koha-tmpl/intranet-tmpl/prog/js/catalog.js | 67 ++++++++++--------- t/db_dependent/api/v1/biblios.t | 7 +- 7 files changed, 152 insertions(+), 46 deletions(-) diff --git a/Koha/REST/V1/Biblios.pm b/Koha/REST/V1/Biblios.pm index 00dc73d209..727a2e4445 100644 --- a/Koha/REST/V1/Biblios.pm +++ b/Koha/REST/V1/Biblios.pm @@ -154,7 +154,9 @@ sub delete { =head3 populate_empty_callnumbers -Controller function that handles deleting a biblio object +Controller function that populates the item callnumbers of any items +for the record that currently have no callnumber. The generated callnumbers +will be based on the 'itemcallnumber' system preference. =cut @@ -237,6 +239,52 @@ sub populate_empty_callnumbers { }; } +=head3 default_item_callnumber + +Return the callnumber generated for the given record based on the "itemcallnumber" system preference. +=cut + +sub default_item_callnumber { + my $c = shift->openapi->valid_input or return; + + my $biblio = Koha::Biblios->find( $c->param('biblio_id') ); + + if ( not defined $biblio ) { + return $c->render( + status => 404, + openapi => { error => "Biblio not found" } + ); + } + + my $cn_fields = C4::Context->preference('itemcallnumber'); + return $c->render( + status => 404, + openapi => { error => "Callnumber fields not found" } + ) unless $cn_fields; + + my $record = $biblio->record; + my $callnumber; + + foreach my $callnumber_marc_field ( split( /,/, $cn_fields ) ) { + my $callnumber_tag = substr( $callnumber_marc_field, 0, 3 ); + my $callnumber_subfields = substr( $callnumber_marc_field, 3 ); + + next unless $callnumber_tag && $callnumber_subfields; + + my $field = $record->field($callnumber_tag); + + next unless $field; + + $callnumber = $field->as_string( $callnumber_subfields, ' ' ); + last if $callnumber; + } + + return $c->render( + status => 200, + openapi => { callnumber => $callnumber }, + ); +} + =head3 get_public Controller function that handles retrieving a single biblio object diff --git a/api/v1/swagger/paths/biblios.yaml b/api/v1/swagger/paths/biblios.yaml index f934451951..5b7681f487 100644 --- a/api/v1/swagger/paths/biblios.yaml +++ b/api/v1/swagger/paths/biblios.yaml @@ -950,3 +950,49 @@ description: Under maintenance schema: $ref: "../swagger.yaml#/definitions/error" +"/biblios/{biblio_id}/default_item_callnumber": + get: + x-mojo-to: Biblios#default_item_callnumber + operationId: getBiblioDefaultItemCallnumber + tags: + - biblios + summary: Get default item callnumber for a biblio + parameters: + - $ref: "../swagger.yaml#/parameters/biblio_id_pp" + produces: + - application/json + responses: + "200": + description: Generated call number + schema: + type: object + properties: + callnumber: + description: Item call number benerated for biblio + type: string + "401": + description: Authentication required + schema: + $ref: "../swagger.yaml#/definitions/error" + "403": + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + "404": + description: Biblio 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: + catalogue: "1" diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index f9fafc4688..925015b439 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -231,6 +231,8 @@ paths: $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1checkouts" "/biblios/{biblio_id}/items": $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1items" + "/biblios/{biblio_id}/default_item_callnumber": + $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1default_item_callnumber" "/biblios/{biblio_id}/items/populate_empty_callnumbers": $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}~1items~1populate_empty_callnumbers" "/biblios/{biblio_id}/items/{item_id}/populate_empty_callnumbers": diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc index 6a64686b92..45bc205a9c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/cat-toolbar.inc @@ -43,6 +43,10 @@
  • Modify record using template
  • [% END %] + [% IF Koha.Preference('EnablePopulateCallnumbers') && ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items || CAN_user_tools_items_batchmod || CAN_user_tools_items_batchdel ) or ( frameworkcode == 'FA' and CAN_user_editcatalogue_fast_cataloging ) %] +
  • Populate call numbers
  • + [% END %] + [% IF CAN_user_editcatalogue_edit_items or ( frameworkcode == 'FA' and CAN_user_editcatalogue_fast_cataloging ) %]
  • Edit items
  • [% END %] @@ -211,14 +215,6 @@ [% END %] [% END %] -[% IF Koha.Preference('EnablePopulateCallnumbers') %] -[% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items || CAN_user_tools_items_batchmod || CAN_user_tools_items_batchdel ) or ( frameworkcode == 'FA' and CAN_user_editcatalogue_fast_cataloging ) %] -
    - -
    -[% END %] -[% END %] - [% FOREACH p IN plugins %] [% p.intranet_catalog_biblio_enhancements_toolbar_button | $raw %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index 9fc75ebf99..0f0fba3d7b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -642,19 +642,23 @@ [% IF CAN_user_editcatalogue_edit_items %] [% IF item.can_be_edited %] - [% IF Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %] + [% SET show_itemcallnumber_link = !item.itemcallnumber && Koha.Preference('EnablePopulateCallnumbers') %] + [% SET show_local_covers_link = Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %] + [% IF show_itemcallnumber_link || show_itemcallnumber_link %]
    Edit
    [% ELSE %] Edit [% END %] - [% IF !item.itemcallnumber && Koha.Preference('EnablePopulateCallnumbers') %] - - [% END %] [% END %] [% IF bundlesEnabled %] diff --git a/koha-tmpl/intranet-tmpl/prog/js/catalog.js b/koha-tmpl/intranet-tmpl/prog/js/catalog.js index d04a71c25f..c159cdcae3 100644 --- a/koha-tmpl/intranet-tmpl/prog/js/catalog.js +++ b/koha-tmpl/intranet-tmpl/prog/js/catalog.js @@ -126,41 +126,48 @@ $(document).ready(function() { $("#populate-callnumbers-biblio") .on('click', function() { - if ( confirm(__('Are you sure you want to populate callnumbers for all items without a callnumber on this record?')) ) { - const biblionumber = $(this).data('biblionumber'); - $.post( `/api/v1/biblios/${biblionumber}/items/populate_empty_callnumbers`, function( data ) { - const items_updated = data.items_updated; - const callnumber = data.callnumber; - let msg = __('Items populated with the callnumber "%s": %s').format(callnumber, items_updated); - - if ( items_updated ) { - msg += __('\nReload the page?'); - if( confirm(msg) ) { - location.reload(true); + $.getJSON( `/api/v1/biblios/${biblionumber}/default_item_callnumber`, function( cn ) { + const callnumber = cn.callnumber; + if ( confirm(__(`Are you sure you want to populate callnumbers for all items without a callnumber on this record to the following value: ${callnumber}`)) ) { + const biblionumber = $(this).data('biblionumber'); + $.post( `/api/v1/biblios/${biblionumber}/items/populate_empty_callnumbers`, function( data ) { + const items_updated = data.items_updated; + const callnumber = data.callnumber; + let msg = __('Items populated with the callnumber "%s": %s').format(callnumber, items_updated); + + if ( items_updated ) { + msg += " " + __('Reload the page?'); + if( confirm(msg) ) { + location.reload(true); + } + } else { + alert(msg); } - } else { - alert(msg); - } - }); - } + }); + } + }); }).tooltip(); $(".populate-callnumber-item") .on('click', function() { - if ( confirm(__('Are you sure you want to populate the callnumber for this item?')) ) { - const biblionumber = $(this).data('biblionumber'); - const itemnumber = $(this).data('itemnumber'); - const button = $(this); - $.post( `/api/v1/biblios/${biblionumber}/items/${itemnumber}/populate_empty_callnumbers`, function( data ) { - const callnumber = data.callnumber; - let msg = __('Item populated with the callnumber "%s"\nReload the page?').format(callnumber); - if( confirm(msg) ) { - location.reload(true); - } else { - button.hide(); - } - }); - } + $.getJSON( `/api/v1/biblios/${biblionumber}/default_item_callnumber`, function( cn ) { + const callnumber = cn.callnumber; + if ( confirm(__(`Are you sure you want to populate the callnumber for this item to the following value: ${callnumber}`)) ) { + const biblionumber = $(this).data('biblionumber'); + const itemnumber = $(this).data('itemnumber'); + const button = $(this); + $.post( `/api/v1/biblios/${biblionumber}/items/${itemnumber}/populate_empty_callnumbers`, function( data ) { + const callnumber = data.callnumber; + let msg = __('Item populated with the callnumber "%s"').format(callnumber); + msg += " " + __('Reload the page?'); + if( confirm(msg) ) { + location.reload(true); + } else { + button.hide(); + } + }); + } + }); }).tooltip(); $(".addtolist").on("click", function (e) { diff --git a/t/db_dependent/api/v1/biblios.t b/t/db_dependent/api/v1/biblios.t index dcdcd694d1..9d44600023 100755 --- a/t/db_dependent/api/v1/biblios.t +++ b/t/db_dependent/api/v1/biblios.t @@ -1813,7 +1813,7 @@ subtest 'update_item() tests' => sub { }; subtest 'populate_empty_callnumbers() tests' => sub { - plan tests => 23; + plan tests => 26; t::lib::Mocks::mock_preference( 'itemcallnumber', '245a' ); @@ -1824,7 +1824,7 @@ subtest 'populate_empty_callnumbers() tests' => sub { my $patron = $builder->build_object( { class => 'Koha::Patrons', - value => { flags => 0 } + value => { flags => 2**2 } } ); my $password = 'thePassword123'; @@ -1885,6 +1885,9 @@ subtest 'populate_empty_callnumbers() tests' => sub { $t->post_ok( "//$userid:$password@/api/v1/biblios/0/items/$item1_id/populate_empty_callnumbers" => json => {} ) ->status_is( 404, 'Record not found' ); + $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/default_item_callnumber" => json => {} ) + ->status_is( 200, 'Items updated' )->json_is( '/callnumber', 'Some boring read' ); + $schema->storage->txn_rollback; }; -- 2.30.2