From ecf44b4ea79e034f45cfe2a28b4f2e61be8087cb 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 | 404 +++++++++++++++++- 4 files changed, 456 insertions(+), 13 deletions(-) diff --git a/admin/columns_settings.yml b/admin/columns_settings.yml index 394b5d346e..e85f21428c 100644 --- a/admin/columns_settings.yml +++ b/admin/columns_settings.yml @@ -316,6 +316,8 @@ modules: columnname: holdings_homebranch - columnname: holdings_ccode + - + columnname: holdings_volume - columnname: holdings_itemcallnumber - @@ -373,6 +375,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 75aeed0e96..720fe8ea2d 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; @@ -98,6 +101,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 ) { @@ -335,6 +371,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 4f4f461e0e..a81919b4c4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/html_helpers.inc @@ -88,12 +88,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 %] @@ -110,19 +110,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 %] @@ -132,15 +132,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 70a22e7262..a92bb351f8 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -268,7 +268,8 @@ 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 %]
  • Components ([% ComponentParts.size | html %])
  • [% END %] [% IF ( subscriptionsnumber ) %]
  • Subscriptions
  • [% END %] [% IF Koha.Preference('AcquisitionDetails') %]
  • Acquisition details
  • [% END %] @@ -303,6 +304,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 %] @@ -317,6 +322,9 @@ Current library Home library [% IF ( itemdata_ccode ) %]Collection[% END %] + [% IF Koha.Preference('EnableItemGroups') %] + Item group + [% END %] Call number [% IF volinfo %] Serial enumeration / chronology @@ -391,6 +399,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 %] @@ -596,6 +605,25 @@ 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' ) %] @@ -1027,6 +1055,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 %] @@ -1378,6 +1536,250 @@ Note that permanent location is a code, and location may be an authval. if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)}; if ( search_value ){ $('#cat-search-block #search-form').val(search_value)}; }); + + [% 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($('