From d74bfabf59170abdb0aacea3ca5b016135f63ce7 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Tue, 8 Mar 2022 12:01:48 +0000 Subject: [PATCH] Bug 24857: Add item group management to detail.pl Test Plan: 1) Apply the patches for this bug 2) Run updatedatabase.pl 3) Restart all the things! 4) Enable the new syspref EnableItemGroups 5) Browse to detail.pl for a record with items 6) Note the new Item Groups tab 7) Test creating, editing and deleting groups 8) On the Holdings tab, select one or more items using the checkboxes 8) Note new selection options for setting an item group for items, and for clearing an item group for items. 9) Test adding and clearing the item group for items --- admin/columns_settings.yml | 4 + catalogue/detail.pl | 37 ++ .../prog/en/includes/html_helpers.inc | 24 +- .../prog/en/modules/catalogue/detail.tt | 410 +++++++++++++++++- 4 files changed, 462 insertions(+), 13 deletions(-) diff --git a/admin/columns_settings.yml b/admin/columns_settings.yml index 3c4f7c2d320..7e68c4d0b5f 100644 --- a/admin/columns_settings.yml +++ b/admin/columns_settings.yml @@ -358,6 +358,8 @@ modules: columnname: holdings_homebranch - columnname: holdings_ccode + - + columnname: holdings_volume - columnname: holdings_itemcallnumber - @@ -421,6 +423,8 @@ modules: columnname: otherholdings_homebranch - columnname: otherholdings_ccode + - + columnname: otherholdings_volume - columnname: otherholdings_itemcallnumber - diff --git a/catalogue/detail.pl b/catalogue/detail.pl index a5f2ede6ba0..34447566b57 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -47,7 +47,10 @@ use C4::HTML5Media; use C4::CourseReserves qw( GetItemCourseReservesInfo ); use Koha::AuthorisedValues; use Koha::Biblios; +use Koha::Biblio::ItemGroup::Items; +use Koha::Biblio::ItemGroups; use Koha::CoverImages; +use Koha::DateUtils; use Koha::Illrequests; use Koha::Items; use Koha::ItemTypes; @@ -99,6 +102,39 @@ if ( not defined $record ) { my $marc_record = eval { $biblio->metadata->record }; $template->param( decoding_error => $@ ); +my $op = $query->param('op') || q{}; +if ( $op eq 'set_item_group' ) { + my $item_group_id = $query->param('item_group_id'); + my @itemnumbers = $query->multi_param('itemnumber'); + + foreach my $item_id (@itemnumbers) { + my $item_group_item = Koha::Biblio::ItemGroup::Items->find( { item_id => $item_id } ); + + if ($item_group_item) { + $item_group_item->item_group_id($item_group_id); + } + else { + $item_group_item = Koha::Biblio::ItemGroup::Item->new( + { + item_id => $item_id, + item_group_id => $item_group_id, + } + ); + } + + $item_group_item->store(); + } +} +elsif ( $op eq 'unset_item_group' ) { + my $item_group_id = $query->param('item_group_id'); + my @itemnumbers = $query->multi_param('itemnumber'); + + foreach my $item_id (@itemnumbers) { + my $item_group_item = Koha::Biblio::ItemGroup::Items->find( { item_id => $item_id } ); + $item_group_item->delete() if $item_group_item; + } +} + if($query->cookie("holdfor")){ my $holdfor_patron = Koha::Patrons->find( $query->cookie("holdfor") ); if ( $holdfor_patron ) { @@ -340,6 +376,7 @@ foreach my $item (@items) { # checking for holds my $item_object = Koha::Items->find( $item->{itemnumber} ); + $item->{object} = $item_object; my $holds = $item_object->current_holds; if ( my $first_hold = $holds->next ) { $item->{first_hold} = $first_hold; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc index 97b64abd0a4..fdcc6eadfa9 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc @@ -101,12 +101,12 @@ [% SET mv = subfield.marc_value %] [% IF ( mv.type == 'hidden' ) %] - + [% ELSIF ( mv.type == 'select' ) %] [% IF ( mv.readonly || subfield.IS_RETURN_CLAIM ) %] - [% ELSE %] - [% END %] [% FOREACH aval IN mv.values %] @@ -123,19 +123,19 @@ [% ELSIF ( mv.type == 'text_auth' ) %] [% IF mv.readonly %] - + [% ELSE %] - + [% SET dopop = "Dopop('/cgi-bin/koha/authorities/auth_finder.pl?authtypecode=\"${mv.authtypecode}\"&index=${mv.id}','${mv.id}')" %] ... [% END %] [% ELSIF ( mv.type == 'text_plugin' ) %] [% IF mv.readonly %] - + [% ELSE %] - + [% IF ( mv.nopopup ) %] - ... + ... [% ELSE %] ... [% END %] @@ -145,15 +145,15 @@ [% END %] [% ELSIF ( mv.type == 'text' ) %] [% IF mv.readonly %] - + [% ELSE %] - + [% END %] [% ELSIF ( mv.type == 'textarea' ) %] [% IF mv.readonly %] - + [% ELSE %] - + [% END %] [% 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 117046cd6d8..eeecfd16692 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -283,7 +283,12 @@ Holdings ([% itemloop.size() || 0 | html %]) [% END %] -[% IF ( MARCNOTES ) %]
  • Descriptions ([% ( MARCNOTES.size || 1 ) | html %])
  • [% END %] + [% IF Koha.Preference('EnableItemGroups') %] +
  • + Item groups +
  • + [% END %] +[% IF ( MARCNOTES || notes ) %]
  • Descriptions ([% ( MARCNOTES.size || 1 ) | html %])
  • [% END %] [% IF ComponentParts && ComponentParts.size %][% END %] [% IF ( subscriptionsnumber ) %]
  • Subscriptions
  • [% END %] [% IF Koha.Preference('AcquisitionDetails') %]
  • Acquisition details
  • [% END %] @@ -321,6 +326,10 @@ [% IF CAN_user_tools_items_batchmod %] Modify selected items [% END %] + [% IF CAN_user_editcatalogue_manage_item_groups && biblio.item_groups.count %] + Add/move to item group + Remove from item group + [% END %] [% END %] @@ -335,6 +344,9 @@ Current library Home library [% IF ( itemdata_ccode ) %]Collection[% END %] + [% IF Koha.Preference('EnableItemGroups') %] + Item group + [% END %] Call number [% IF volinfo %] Serial enumeration / chronology @@ -411,6 +423,7 @@ Note that permanent location is a code, and location may be an authval. [% IF ( itemdata_ccode ) %][% item.ccode | html %][% END %] + [% IF Koha.Preference('EnableItemGroups') %][% item.object.item_group.description | html %][% END %] [% IF ( item.itemcallnumber ) %] [% item.itemcallnumber | html %][% END %] [% IF ( volinfo ) %] [% IF itemdata_publisheddate #If there is at least one published date, use it for sorting %] @@ -627,6 +640,26 @@ Note that permanent location is a code, and location may be an authval. [% END %][%# end of block items_table %] +[% IF Koha.Preference('EnableItemGroups') %] +
    + [% IF CAN_user_editcatalogue_manage_item_groups %] + + [% END %] + + + + + + + + +
    Display OrderDescription 
    +
    +[% END %] + +
    [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'above' ) %] @@ -1059,6 +1092,136 @@ Note that permanent location is a code, and location may be an authval. [% END %] + + + + + + + + + + [% MACRO jsinclude BLOCK %] [% INCLUDE 'catalog-strings.inc' %] [% Asset.js("js/catalog.js") | $raw %] @@ -1419,6 +1582,251 @@ Note that permanent location is a code, and location may be an authval. if ( search_value ){ $('#cat-search-block #search-form').val(search_value)}; }); [% END %] + + [% IF Koha.Preference('EnableItemGroups') %] + // Load item groups table + var itemGroupsTable = KohaTable("items-group-table", { + "bAutoWidth": false, + 'sDom': '<"top pager"ilp>t<"bottom pager"ip>r', + "aoColumns": [ + { + "mDataProp": function( oObj ) { + return oObj.display_order; + }, + }, + { + "mDataProp": function( oObj ) { + return oObj.description; + }, + }, + { + "mDataProp": function( oObj ) { + [% IF CAN_user_editcatalogue_manage_item_groups %] + return `` + + ' ' + + ``; + [% ELSE %] + return ""; + [% END %] + }, + }, + ], + "bPaginate": false, + "bProcessing": true, + "bServerSide": false, + "sAjaxSource": `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1`, + "sAjaxDataProp": "", + "fnServerData": function ( sSource, aoData, fnCallback ) { + $.getJSON( sSource, aoData, function (json) { + fnCallback(json) + } ); + }, + }); + + // Create new item groups + $('.item-group-create').on('click', function(){ + $('#modal-item-group-create-form-description').val(""); + $('#modal-item-group-create-submit').removeAttr('disabled'); + $('#modal-item-group-create').modal('show'); + }); + + $("#modal-item-group-create-form").validate({ + submitHandler: function(form) { + $.ajax({ + url: `/api/v1/biblios/${biblionumber}/item_groups`, + headers: { "x-koha-embed": "items" }, + success: function(item_groups){ + $('#modal-item-group-create-submit').attr('disabled', 'disabled'); + + var settings = { + "url": `/api/v1/biblios/${biblionumber}/item_groups`, + "method": "POST", + "headers": { + "Content-Type": "application/json" + }, + "data": JSON.stringify( + { + "description": $("#modal-item-group-create-form-description").val(), + "display_order": $("#modal-item-group-create-form-display_order").val(), + } + ), + }; + + $.ajax(settings) + .done(function (response) { + $('#item-group-add-form-select').append($('