From e73817ea1ed2f28753220ab44461a3d2a25408c6 Mon Sep 17 00:00:00 2001
From: Olli-Antti Kivilahti <olli-antti.kivilahti@jns.fi>
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.
Adds a "Place hold"-link after each item in the opac-detail.tt holdings-tab.
Uses the template parameter 'norequest', to disable the "Place hold"-link in
the sidebar opac-detail-sidebar.inc.

Added a new parameter itemnumber to opac-reserve.pl/.tt.
This causes the opac-reserve.tt to display only the desired item, preselect it
and hide unnecessary radio buttons.
---
 C4/Items.pm                                         |  6 ++++++
 koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt  | 11 ++++++++++-
 koha-tmpl/opac-tmpl/prog/en/modules/opac-reserve.tt |  9 +++++++--
 opac/opac-detail.pl                                 |  7 ++++++-
 opac/opac-reserve.pl                                | 14 +++++++++++---
 t/db_dependent/Items.t                              |  9 +++++++++
 6 files changed, 49 insertions(+), 7 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/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt
index f0741ed..d54479c 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 () {
             <th>Item hold queue priority</th>
         [% END %]
         [% IF ( ShowCourseReservesHeader ) %]<th id="item_coursereserves">Course reserves</th>[% END %]
+        [% IF ( isSerial ) %]<th id="placeItemLevelHoldTh">Reserve</th>[% END %]
         </tr></thead>
 	    <tbody>[% FOREACH ITEM_RESULT IN items %]
       [% IF ITEM_RESULT.this_branch %]
@@ -1630,6 +1632,13 @@ YAHOO.util.Event.onContentReady("furtherm", function () {
                 [% END %]
             </td>
         [% END %]
+        [% IF isSerial %]
+            <td>
+                <a href="opac-reserve.pl?biblionumber=[% biblionumber %]&itemnumber=[% ITEM_RESULT.itemnumber %]">
+                    Place hold
+                </a>
+            </td>
+        [% END %]
 	    </tr>
 	    [% END %]</tbody>
 	</table>
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 @@
                             <!-- ITEM HOLDS -->
 
                                 <li class="radio">
+                                 [% UNLESS singleItemLevelHold %]
                                   [% UNLESS ( bibitemloo.holdable ) %]
                                     <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
                                            id="reqany_[% bibitemloo.biblionumber %]"
@@ -437,11 +438,12 @@
                                            id="reqany_[% bibitemloo.biblionumber %]"
                                            class="selectany"
                                            value="Any"
-                                           checked="checked"
+                                           [% UNLESS singleItemLevelHold %] checked="checked" [% END %]
                                     />
                                   [% END %]
 
                                   <label for="reqany_[% bibitemloo.biblionumber %]">Next available copy</label>
+                                 [% END %][%# IF singleItemLevelHold %]
                                   [% UNLESS ( bibitemloo.holdable ) %]
                                     <input type="radio" name="reqtype_[% bibitemloo.biblionumber %]"
                                            id="reqspecific_[% bibitemloo.biblionumber %]"
@@ -454,6 +456,7 @@
                                            id="reqspecific_[% bibitemloo.biblionumber %]"
                                            class="selectspecific"
                                            value="Specific"
+                                           [% IF singleItemLevelHold %] checked="checked" [% END %]
                                     />
                                   [% END %]
                                   <label for="reqspecific_[% bibitemloo.biblionumber %]">A specific copy</label>
@@ -489,7 +492,9 @@
                               <td class="copy">
                                 [% IF ( itemLoo.available ) %]
                                   <input type="radio" class="checkitem checkitem_[% bibitemloo.biblionumber %]" name="checkitem_[% bibitemloo.biblionumber %]"
-                                         value="[% itemLoo.itemnumber %]" />
+                                         value="[% itemLoo.itemnumber %]"
+                                         [% IF singleItemLevelHold %] checked="checked" [% END %]
+                                         />
                                 [% ELSE %]
                                   <input disabled="disabled" type="radio" class="checkitem" name="checkitem" value="[% itemLoo.itemnumber %]" />
                                   <img src="/opac-tmpl/lib/famfamfam/silk/cross.png" alt="Cannot be put on hold" title="Cannot be put on hold" />
diff --git a/opac/opac-detail.pl b/opac/opac-detail.pl
index 0544539..e01eb3d 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);
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/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