From b791431e8c8ff05587d7a1ea7c3ea4d751d91233 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 Signed-off-by: Tomas Cohen Arazi --- 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 3c4f7c2d32..7e68c4d0b5 100644 --- a/admin/columns_settings.yml +++ b/admin/columns_settings.yml @@ -359,6 +359,8 @@ modules: - columnname: holdings_ccode - + columnname: holdings_volume + - columnname: holdings_itemcallnumber - columnname: holdings_status @@ -422,6 +424,8 @@ modules: - columnname: otherholdings_ccode - + columnname: otherholdings_volume + - columnname: otherholdings_itemcallnumber - columnname: otherholdings_status diff --git a/catalogue/detail.pl b/catalogue/detail.pl index a5f2ede6ba..34447566b5 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 97b64abd0a..fdcc6eadfa 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 117046cd6d..eeecfd1669 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($('