From 8345edb40cb886a19c10c06fa31f664bd4212bce Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Tue, 29 Oct 2013 10:06:52 +0200 Subject: [PATCH] Bug 11157 - Placing a simple item-level hold for serials. For biblios marked as a serial or if the sysprefs: -OPACShowPlaceItemLevelHold or -ShowPlaceItemLevelHold are enabled. Adds a "Place hold"-link after each item in the detailed biblio view. Uses the template parameter 'norequest', to disable the "Place hold"-link in the sidebar opac-detail-sidebar.inc for serials. Added a new parameter itemnumber to opac-reserve.pl/.tt and reserve.pl/.tt. This causes the reserving module to display only the desired item, preselect it and hide unnecessary buttons. --- C4/Items.pm | 6 ++++++ catalogue/detail.pl | 6 ++++++ installer/data/mysql/sysprefs.sql | 2 ++ .../en/modules/admin/preferences/cataloguing.pref | 7 +++++++ .../prog/en/modules/admin/preferences/opac.pref | 7 +++++++ .../prog/en/modules/catalogue/detail.tt | 8 ++++++++ .../prog/en/modules/reserve/request.tt | 17 ++++++++++++++--- koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 11 ++++++++++- .../opac-tmpl/prog/en/modules/opac-reserve.tt | 9 +++++++-- opac/opac-detail.pl | 9 ++++++++- opac/opac-reserve.pl | 14 +++++++++++--- reserve/request.pl | 22 +++++++++++++++++++++- t/db_dependent/Items.t | 9 +++++++++ 13 files changed, 116 insertions(+), 11 deletions(-) diff --git a/C4/Items.pm b/C4/Items.pm index dc6b44c..7120924 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -1219,6 +1219,7 @@ $filter->{fromDate} = '01/01/2013'; #Filters only serial issues by the serialite $filter->{toDate} = '31/12/2014'; #Filters only serial issues by the serialitems.publisheddate #The ending date in C4::Context->preference('dateformat') format $filter->{limit} = 15; #Limits the returning set to this many items +$filter->{itemnumber} = 165; #Returns the item with this itemnumber Filters are expected to be validated! If a filter is not defined, that filter is not present in the $filter-HASH @@ -1341,6 +1342,11 @@ sub GetItemsInfo { } push @$queryParams, $filter->{toDate}; } + if (exists $filter->{itemnumber}) { + push @$queryParams, $filter->{itemnumber}; + $query .= " AND items.itemnumber = ?"; + } + $query .= "ORDER BY home.branchname, items.enumchron, LPAD( items.copynumber, 8, '0' ), items.dateaccessioned DESC" ; if (exists $filter->{limit}) { diff --git a/catalogue/detail.pl b/catalogue/detail.pl index 72258fd..618455c 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -143,6 +143,10 @@ my $dat = &GetBiblioData($biblionumber); my $subscriptionsnumber = CountSubscriptionFromBiblionumber($biblionumber); my @subscriptions = GetSubscriptions( $dat->{title}, $dat->{issn}, undef, $biblionumber ); my @subs; +if (scalar(@subscriptions)) { + $template->param('isSerial',1); +} + foreach my $subscription (@subscriptions) { my %cell; @@ -412,4 +416,6 @@ if (C4::Context->preference('TagsEnabled') and $tag_quantity = C4::Context->pref my ( $holdcount, $holds ) = C4::Reserves::GetReservesFromBiblionumber($biblionumber,1); $template->param( holdcount => $holdcount, holds => $holds ); +$template->param('ShowPlaceItemLevelHold', C4::Context->preference('ShowPlaceItemLevelHold')); + output_html_with_http_headers $query, $cookie, $template->output; diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 4db2935..5efaf5f 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -270,6 +270,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('OpacShowLibrariesPulldownMobile','1',NULL,'Show the libraries pulldown on the mobile version of the OPAC.','YesNo'), ('OpacShowRecentComments','0',NULL,'If ON a link to recent comments will appear in the OPAC masthead','YesNo'), ('OPACShowUnusedAuthorities','1','','Show authorities that are not being used in the OPAC.','YesNo'), +('OPACShowPlaceItemLevelHold','0',NULL,'Allow placing a item-level hold from the detailed biblio view.','YesNo'), ('opacsmallimage','','','Enter a complete URL to an image to replace the default Koha logo','free'), ('OpacStarRatings','all','disable|all|details',NULL,'Choice'), ('OpacSuppression','0','','Turn ON the OPAC Suppression feature, requires further setup, ask your system administrator for details','YesNo'), @@ -341,6 +342,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` ('ShowPatronImageInWebBasedSelfCheck','0','','If ON, displays patron image when a patron uses web-based self-checkout','YesNo'), ('ShowReviewer','full','none|full|first|surname|firstandinitial|username','Choose how a commenter\'s identity is presented alongside comments in the OPAC','Choice'), ('ShowReviewerPhoto','1','','If ON, photo of reviewer will be shown beside comments in OPAC','YesNo'), +('ShowPlaceItemLevelHold','0',NULL,'Allow placing a item-level hold from the detailed biblio view.','YesNo'), ('singleBranchMode','0',NULL,'Operate in Single-branch mode, hide branch selection in the OPAC','YesNo'), ('SlipCSS','',NULL,'Slips CSS url.','free'), ('SMSSendDriver','','','Sets which SMS::Send driver is used to send SMS messages.','free'), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref index 96f3603..4620462 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/cataloguing.pref @@ -18,6 +18,13 @@ Cataloging: yes: Display no: "Don't Display" - easy ways to create analytical record relationships + - + - pref: ShowPlaceItemLevelHold + default: 0 + choices: + yes: "Allow" + no : "Don't allow" + - placing a item-level hold from the detailed biblio view. This is always enabled for serials because serials need only item-level holds. Spine Labels: - - When using the quick spine label printer, diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref index 28d25c6..91125fa 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref @@ -131,6 +131,13 @@ OPAC: no: "Don't show" - the item's barcode on the holdings tab. - + - pref: OPACShowPlaceItemLevelHold + default: 0 + choices: + yes: "Allow" + no : "Don't allow" + - placing a item-level hold from the detailed biblio view. This is always enabled for serials because serials need only item-level holds. + - - pref: OpacHighlightedWords choices: yes: Highlight 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 d5a006b..39d125a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -422,6 +422,7 @@ function verify_images() { [% IF ( hostrecords ) %]Host records[% END %] [% IF ( analyze ) %]Used in[% END %] [% IF ( ShowCourseReserves ) %]Course Reserves[% END %] + [% IF ( ShowPlaceItemLevelHold || isSerial ) %]Reserve[% END %] @@ -590,6 +591,13 @@ function verify_images() { [% END %] [% END %] + [% IF ( ShowPlaceItemLevelHold || isSerial ) %] + + + Place hold + + + [% END %] [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt index 7f7d05f..b0eb339 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -191,7 +191,9 @@ function checkMultiHold() { [% END %] [% UNLESS ( multi_hold ) %] -

Place a hold on [% INCLUDE 'biblio-default-view.inc' %][% title |html %]

+

Place a hold on [% INCLUDE 'biblio-default-view.inc' %][% title |html %] + [% IF targetItemTitle %] - [% targetItemTitle %][% END %] +

[% ELSE %]

Confirm Holds

[% END %] @@ -208,6 +210,7 @@ function checkMultiHold() { + [% IF targetItemnumber %][% END %] [% ELSE %]
@@ -221,6 +224,7 @@ function checkMultiHold() { [% END %]
+ [% IF targetItemnumber %][% END %] [% END %] [% IF ( multi_hold ) %] @@ -344,8 +348,11 @@ function checkMultiHold() { [% UNLESS ( multi_hold ) %] -
  • +
  • + [% UNLESS targetItemnumber %] + + [% END %]
  • @@ -395,7 +402,11 @@ function checkMultiHold() { [% IF ( itemloo.available ) %] - + [% IF targetItemnumber %] + + [% ELSE %] + + [% END %] [% ELSIF ( itemloo.override ) %] Requires override of hold policy diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt index f0741ed..3f19656 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -70,7 +70,7 @@ [% END %] // ------------------------------ // //>>> Document READY starts here! // -// ------------------------------ // +// ------------------------------ // $(document).ready(function() { $('#bibliodescriptions').tabs(); $(".branch-info-tooltip-trigger").tooltip({ @@ -132,6 +132,7 @@ null, [% END %] [% IF ( ShowCourseReservesHeader ) %]null,[% END %] + [% IF ( isSerial ) %]null,[% END %] ] })); @@ -1550,6 +1551,7 @@ YAHOO.util.Event.onContentReady("furtherm", function () { Item hold queue priority [% END %] [% IF ( ShowCourseReservesHeader ) %]Course reserves[% END %] + [% IF ( isSerial ) %]Reserve[% END %] [% FOREACH ITEM_RESULT IN items %] [% IF ITEM_RESULT.this_branch %] @@ -1630,6 +1632,13 @@ YAHOO.util.Event.onContentReady("furtherm", function () { [% END %] [% END %] + [% IF OPACShowPlaceItemLevelHold || isSerial %] + + + Place hold + + + [% END %] [% END %] diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt index bf334fa..3e317af 100644 --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt +++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt @@ -425,6 +425,7 @@
  • + [% UNLESS singleItemLevelHold %] [% UNLESS ( bibitemloo.holdable ) %] [% END %] + [% END %][%# IF singleItemLevelHold %] [% UNLESS ( bibitemloo.holdable ) %] [% END %] @@ -489,7 +492,9 @@ [% IF ( itemLoo.available ) %] + value="[% itemLoo.itemnumber %]" + [% IF singleItemLevelHold %] checked="checked" [% END %] + /> [% ELSE %] Cannot be put on hold diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl index 0544539..8d17b56 100755 --- a/opac/opac-detail.pl +++ b/opac/opac-detail.pl @@ -691,7 +691,7 @@ if ( $show_holds_count || $show_priority) { } $template->param( show_priority => $has_hold ) ; -my $norequests = 1; +my $norequests = 1; #"No requests"-flag hides the "Place hold"-link in opac-detail-sidebar.inc my %itemfields; my (@itemloop, @otheritemloop); my $currentbranch = C4::Context->userenv ? C4::Context->userenv->{branch} : undef; @@ -756,6 +756,11 @@ for my $itm (@items) { } } +#There is no point in enabling "Place hold" for Serials. +# Placing a title-level hold for a Serial is crazy since we don't want "any" item but instead the specific volume and number. +# Also choosing an item-level hold from opac-reserve.pl is problematic since there could be thousands of items. +$norequests = 1 if $template->{VARS}->{'isSerial'}; + # Display only one tab if one items list is empty if (scalar(@itemloop) == 0 || scalar(@otheritemloop) == 0) { $template->param(SeparateHoldings => 0); @@ -1203,4 +1208,6 @@ if ( length C4::Context->preference('NumberingFormulaParsingRegexp') < 3 ) { } $template->{VARS}->{useFilterIssueInput} = 1 if (C4::Context->preference('FilterSerialsByIssue')); +$template->param('OPACShowPlaceItemLevelHold', C4::Context->preference('OPACShowPlaceItemLevelHold')); + output_html_with_http_headers $query, $cookie, $template->output; diff --git a/opac/opac-reserve.pl b/opac/opac-reserve.pl index 4bba9a6..9007b1a 100755 --- a/opac/opac-reserve.pl +++ b/opac/opac-reserve.pl @@ -73,8 +73,10 @@ if ($borr->{reservefee} > 0){ my $branches = GetBranches(); my $itemTypes = GetItemTypes(); -# There are two ways of calling this script, with a single biblio num -# or multiple biblio nums. +# There are three ways of calling this script, with a single biblio num +# or multiple biblio nums or as a itemhold, where the target item has already been chosen. +my $targetItemnumber = $query->param('itemnumber') ? $query->param('itemnumber') : undef; +$template->param('singleItemLevelHold' => 1); my $biblionumbers = $query->param('biblionumbers'); my $reserveMode = $query->param('reserve_mode'); if ($reserveMode && ($reserveMode eq 'single')) { @@ -127,8 +129,14 @@ foreach my $biblioNumber (@biblionumbers) { my $biblioData = GetBiblioData($biblioNumber); $biblioDataHash{$biblioNumber} = $biblioData; + my @itemInfos; - my @itemInfos = GetItemsInfo($biblioNumber); + if ($targetItemnumber) { #We just want the one item so use the filters to find it! + @itemInfos = GetItemsInfo($biblioNumber, {itemnumber => $targetItemnumber}); + } + else { + @itemInfos = GetItemsInfo($biblioNumber); + } my $marcrecord= GetMarcBiblio($biblioNumber); diff --git a/reserve/request.pl b/reserve/request.pl index c411ce9..4151f54 100755 --- a/reserve/request.pl +++ b/reserve/request.pl @@ -57,10 +57,27 @@ my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user( } ); +my $targetItemnumber = $input->param('itemnumber') ? $input->param('itemnumber') : undef; +if ($targetItemnumber) { + $template->param('targetItemnumber', $targetItemnumber); + my $targetItem = C4::Items::GetItem($targetItemnumber); + if ($targetItem->{enumchron}) { + $template->param('targetItemTitle', $targetItem->{enumchron}); + } + elsif ($targetItem->{barcode}) { + $template->param('targetItemTitle', $targetItem->{barcode}); + } + else { + $template->param('targetItemTitle', $targetItem->{itemnumber}); + } +} + + my $multihold = $input->param('multi_hold'); $template->param(multi_hold => $multihold); my $showallitems = $input->param('showallitems'); + # get Branches and Itemtypes my $branches = GetBranches(); my $itemtypes = GetItemTypes(); @@ -243,7 +260,10 @@ foreach my $biblionumber (@biblionumbers) { my @itemnumbers; ## $items is array of 'item' table numbers - if (my $items = get_itemnumbers_of($biblionumber)->{$biblionumber}){ + if ($targetItemnumber) { #If we just want to place a hold on one item + push @itemnumbers, $targetItemnumber; + } + elsif (my $items = get_itemnumbers_of($biblionumber)->{$biblionumber}){ @itemnumbers = @$items; } my @hostitems = get_hostitemnumbers_of($biblionumber); diff --git a/t/db_dependent/Items.t b/t/db_dependent/Items.t index 1d28525..750e0ba 100755 --- a/t/db_dependent/Items.t +++ b/t/db_dependent/Items.t @@ -165,6 +165,11 @@ subtest 'Filter items tests' => sub { holdingbranch => 'MPL', }, $biblionumber ); + my ($item3_bibnum, $item3_bibitemnum, $item3_itemnumber) = AddItem( + { homebranch => 'IPT', + holdingbranch => 'IPT', }, + $biblionumber + ); # Testing the branch filter my @shouldBeItem2 = C4::Items::GetItemsInfo($biblionumber, {branch => 'MPL'}); @@ -173,6 +178,10 @@ subtest 'Filter items tests' => sub { # Testing the dates filter my @shouldBeEmpty = C4::Items::GetItemsInfo($biblionumber, {toDate => '01/01/1933'}); is( scalar(@shouldBeEmpty), 0, "Filtering by date"); + + # Testing the itemnumber filter + my @shouldBeItem3 = C4::Items::GetItemsInfo($biblionumber, {itemnumber => $item3_itemnumber}); + is( $shouldBeItem3[0]->{itemnumber}, $item3_itemnumber, "Filtering by itemnumber"); }; # Helper method to set up a Biblio. -- 1.8.1.2