From d2f4a964406a0a33f7fef72cb6e767fea7a3b2eb 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 | 411 +++++++++++++++++- 4 files changed, 461 insertions(+), 15 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..4c8ba311bdf 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 %] @@ -1417,8 +1580,250 @@ Note that permanent location is a code, and location may be an authval. var search_value = localStorage.getItem("searchbox_value"); if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)}; 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($('