From 69cc24cae2a9821c5b927df3ff1189ec9f2c4db3 Mon Sep 17 00:00:00 2001 From: Olli-Antti Kivilahti Date: Tue, 15 Oct 2013 13:16:05 +0300 Subject: [PATCH] Bug 11020 - Transfer limits should be checked when placing a hold/reservation in Staff client Extended bug 11005. Extended C4/Reserves.pm to support checking BranchTransferLimits when requested. Extension does in no way disturb existing functionality. Modified the templates to show branch transfer blocks to the user. Modified the business layer to re-check branch transfer limits in case user fools the POST-request. Created manual test plans. Formatted using perltidy and Perl::Critic --- C4/Reserves.pm | 40 +- .../prog/en/modules/reserve/request.tt | 110 +- reserve/placerequest.pl | 224 +++-- reserve/request.pl | 1059 +++++++++++--------- 4 files changed, 822 insertions(+), 611 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index d1bca25..a7ffe23 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -117,7 +117,7 @@ BEGIN { &CheckReserves &CanBookBeReserved - &CanItemBeReserved + &CanItemBeReserved &CancelReserve &CancelExpiredReserves @@ -162,8 +162,8 @@ sub AddReserve { undef $expdate; # make reserves.expirationdate default to null rather than '0000-00-00' } if ( C4::Context->preference( 'AllowHoldDateInFuture' ) ) { - # Make room in reserves for this before those of a later reserve date - $priority = _ShiftPriorityByDateAndPriority( $biblionumber, $resdate, $priority ); + # Make room in reserves for this before those of a later reserve date + $priority = _ShiftPriorityByDateAndPriority( $biblionumber, $resdate, $priority ); } my $waitingdate; @@ -372,7 +372,7 @@ sub GetReservesFromItemnumber { WHERE itemnumber=? "; unless ( $all_dates ) { - $query .= " AND reservedate <= CURRENT_DATE()"; + $query .= " AND reservedate <= CURRENT_DATE()"; } my $sth_res = $dbh->prepare($query); $sth_res->execute($itemnumber); @@ -416,22 +416,34 @@ sub GetReservesFromBorrowernumber { #------------------------------------------------------------------------------------- =head2 CanBookBeReserved - $error = &CanBookBeReserved($borrowernumber, $biblionumber) + $error = &CanBookBeReserved($borrowernumber, $biblionumber, $pickupLibrary) + +C<$pickupLibrary> OPTIONAL, undef OR the branchcode of the item transfer destination. =cut sub CanBookBeReserved{ - my ($borrowernumber, $biblionumber) = @_; + my ($borrowernumber, $biblionumber, $pickupLibrary) = @_; - my $items = GetItemnumbersForBiblio($biblionumber); + my $itemNumbers = GetItemnumbersForBiblio($biblionumber); #get items linked via host records - my @hostitems = get_hostitemnumbers_of($biblionumber); + my @hostitems = get_hostit +emnumbers_of($biblionumber); if (@hostitems){ - push (@$items,@hostitems); + push (@$itemNumbers,@hostitems); } - foreach my $item (@$items){ - return 1 if CanItemBeReserved($borrowernumber, $item); + foreach my $itemNumber (@$itemNumbers){ + + if (defined $pickupLibrary) { + return 0 if (! CanItemBeReserved($borrowernumber, $itemNumber) ); + my $item = GetItem($itemNumber); + my ($transferOk, $errorMsg) = C4::Circulation::CanItemBeTransferred($pickupLibrary, $item->{holdingbranch}, $item, undef); + return 1 if ($transferOk); + } + else { + return 1 if ( CanItemBeReserved($borrowernumber, $itemNumber) ); + } } return 0; } @@ -849,7 +861,7 @@ sub CheckReserves { my $sth; my $select; if (C4::Context->preference('item-level_itypes')){ - $select = " + $select = " SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan, @@ -861,7 +873,7 @@ sub CheckReserves { "; } else { - $select = " + $select = " SELECT items.biblionumber, items.biblioitemnumber, itemtypes.notforloan, @@ -1957,7 +1969,7 @@ sub _ShiftPriorityByDateAndPriority { $sth = $dbh->prepare( $query ); $sth->execute( $new_priority, $biblio ); while ( my $row = $sth->fetchrow_hashref ) { - $sth_update->execute( $biblio, $row->{borrowernumber}, $row->{reservedate} ); + $sth_update->execute( $biblio, $row->{borrowernumber}, $row->{reservedate} ); } return $new_priority; # so the caller knows what priority they wind up receiving 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..9421e9b 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -130,6 +130,19 @@ function checkMultiHold() { }); $('#hold-request-form').preventDoubleFormSubmit(); + $('#reloadPickupLocationForm').preventDoubleFormSubmit(); + + //Setting the trigger to reload branchTransferLimits + $('#pickup').change(function() { + var newSelection = $(this).val(); + + //Make sure the pickup location is changed to the first select as well. + // The branch selection uses only the first given pickuplocations branch value. + $('#reloadPickupLocationForm > input[name="pickup"]').val(newSelection); + + $('#reloadPickupLocationForm').submit(); + }); + [% UNLESS ( borrowernumber || borrower_list ) %] [% IF ( CircAutocompl ) %] @@ -352,10 +365,15 @@ function checkMultiHold() { [% END %] - [% UNLESS ( multi_hold ) %] + + + + [% UNLESS ( multi_hold ) %]
[% IF ( borrowernumber ) %] - [% IF ( override_required ) %] + [% IF ( bookBranchTransferDenied ) %] + + [% ELSIF ( override_required ) %] [% ELSIF ( none_available ) %] @@ -367,12 +385,18 @@ function checkMultiHold() { [% FOREACH bibitemloo IN bibitemloop %]
    [% UNLESS ( item_level_itypes ) %] -
  1. Item type: [% bibitemloo.description %]
  2. +
  3. Item type: [% bibitemloo.description %]
  4. [% END %] - [% IF ( bibitemloo.publicationyear ) %]
  5. Publication year: [% bibitemloo.publicationyear %]
  6. [% END %] + [% IF ( bibitemloo.publicationyear ) %] +
  7. Publication year: [% bibitemloo.publicationyear %]
  8. + [% END %]
+ [% IF ( bibitemloo.suggestAnotherPickupLocation ) %] +
None of the available items can be transferred to your pickup location. You could try another pickup location.
+ [% END %] + @@ -396,12 +420,15 @@ function checkMultiHold() { [% IF ( item_level_itypes ) %] @@ -476,6 +503,7 @@ function checkMultiHold() { [% ELSE %] +
Place a hold on a specific copy
[% IF ( itemloo.available ) %] + [% ELSIF ( itemloo.branchTransferDenied ) %] + + Cannot transfer this item to your pickup location [% ELSIF ( itemloo.override ) %] - Requires override of hold policy + Requires override of hold policy [% ELSE %] - Cannot be put on hold + Cannot be put on hold [% END %]
@@ -493,7 +521,12 @@ function checkMultiHold() { [% END %]
Title
    -
  • [% biblioloo.title |html %]
  • +
  • + [% IF ( biblioloo.suggestAnotherPickupLocation ) %] + Cannot transfer this item to your pickup location + [% END %] + [% biblioloo.title |html %] +
  • [% IF ( biblioloo.publicationyear ) %]
  • Publication year: [% biblioloo.publicationyear %]
  • [% END %] @@ -539,11 +572,19 @@ function checkMultiHold() { [% END %]
+ [% IF ( bookBranchTransferDenied ) %] +
+ Some books cannot be transferred to your pickup location. Please try another pickup location, or reserve fewer items at once. +
+ [% END %] + [% END %]
[% IF ( borrowernumber ) %] - [% IF ( override_required ) %] + [% IF ( bookBranchTransferDenied ) %] + + [% ELSIF ( override_required ) %] [% ELSIF ( none_available ) %] @@ -600,26 +641,17 @@ function checkMultiHold() { @@ -774,4 +806,26 @@ function checkMultiHold() { +[% IF ( multi_hold ) %] +
+ + + + + + + + [% FOREACH biblioloo IN biblioloop %] + + + [% END %] +
+[% ELSE %] +
+ + + +
+[% END %] + [% INCLUDE 'intranet-bottom.inc' %] diff --git a/reserve/placerequest.pl b/reserve/placerequest.pl index 3fe459c..a1791c8 100755 --- a/reserve/placerequest.pl +++ b/reserve/placerequest.pl @@ -3,7 +3,6 @@ #script to place reserves/requests #writen 2/1/00 by chris@katipo.oc.nz - # Copyright 2000-2002 Katipo Communications # # This file is part of Koha. @@ -35,108 +34,169 @@ use C4::Auth qw/checkauth/; my $input = CGI->new(); -checkauth($input, 0, { reserveforothers => 'place_holds' }, 'intranet'); +checkauth( $input, 0, { reserveforothers => 'place_holds' }, 'intranet' ); + +my @bibitems = $input->param('biblioitem'); -my @bibitems=$input->param('biblioitem'); # FIXME I think reqbib does not exist anymore, it's used in line 82, to AddReserve of contraint type 'o' # I bet it's a 2.x feature, reserving a given biblioitem, that is useless in Koha 3.0 # we can remove this line, the AddReserve of constrainttype 'o', # and probably remove the reserveconstraint table as well, I never could fill anything in this table. -my @reqbib=$input->param('reqbib'); -my $biblionumber=$input->param('biblionumber'); -my $borrowernumber=$input->param('borrowernumber'); -my $notes=$input->param('notes'); -my $branch=$input->param('pickup'); -my $startdate=$input->param('reserve_date') || ''; -my @rank=$input->param('rank-request'); -my $type=$input->param('type'); -my $title=$input->param('title'); -my $borrower=GetMember('borrowernumber'=>$borrowernumber); -my $checkitem=$input->param('checkitem'); +my @reqbib = $input->param('reqbib'); +my $biblionumber = $input->param('biblionumber'); +my $borrowernumber = $input->param('borrowernumber'); +my $notes = $input->param('notes'); +my $branch = $input->param('pickup'); +my $startdate = $input->param('reserve_date') || ''; +my @rank = $input->param('rank-request'); +my $type = $input->param('type'); +my $title = $input->param('title'); +my $borrower = GetMember( 'borrowernumber' => $borrowernumber ); +my $checkitem = $input->param('checkitem'); my $expirationdate = $input->param('expiration_date'); my $multi_hold = $input->param('multi_hold'); -my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/'); +my $biblionumbers = + $multi_hold ? $input->param('biblionumbers') : ( $biblionumber . '/' ); my $bad_bibs = $input->param('bad_bibs'); +my $transferOk + ; # Used to check if this reservation passes UseBranchTransferLimits check. +my $errorMessages + ; # Used to concatenate generated error messages from multiple biblios. + my %bibinfos = (); my @biblionumbers = split '/', $biblionumbers; foreach my $bibnum (@biblionumbers) { - my %bibinfo = (); - $bibinfo{title} = $input->param("title_$bibnum"); - $bibinfo{rank} = $input->param("rank_$bibnum"); - $bibinfos{$bibnum} = \%bibinfo; + my %bibinfo = (); + $bibinfo{title} = $input->param("title_$bibnum"); + $bibinfo{rank} = $input->param("rank_$bibnum"); + $bibinfos{$bibnum} = \%bibinfo; } - my $found; # if we have an item selectionned, and the pickup branch is the same as the holdingbranch # of the document, we force the value $rank and $found . -if ($checkitem ne ''){ - $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns'); - my $item = $checkitem; - $item = GetItem($item); - if ( $item->{'holdingbranch'} eq $branch ){ - $found = 'W' unless C4::Context->preference('ReservesNeedReturns'); - } +if ( defined $checkitem && $checkitem ne '' ) { + $rank[0] = '0' unless C4::Context->preference('ReservesNeedReturns'); + my $item = $checkitem; + $item = GetItem($item); + if ( $item->{'holdingbranch'} eq $branch ) { + $found = 'W' unless C4::Context->preference('ReservesNeedReturns'); + } } -if ($type eq 'str8' && $borrower){ - - foreach my $biblionumber (keys %bibinfos) { - my $count=@bibitems; - @bibitems=sort @bibitems; - my $i2=1; - my @realbi; - $realbi[0]=$bibitems[0]; - for (my $i=1;$i<$count;$i++) { - my $i3=$i2-1; - if ($realbi[$i3] ne $bibitems[$i]) { - $realbi[$i2]=$bibitems[$i]; - $i2++; - } - } - my $const; - - if ($checkitem ne ''){ - my $item = GetItem($checkitem); - if ($item->{'biblionumber'} ne $biblionumber) { - $biblionumber = $item->{'biblionumber'}; - } +if ( $type eq 'str8' && $borrower ) { + + foreach my $biblionumber ( keys %bibinfos ) { + my $count = @bibitems; + @bibitems = sort @bibitems; + my $i2 = 1; + my @realbi; + $realbi[0] = $bibitems[0]; + for ( my $i = 1 ; $i < $count ; $i++ ) { + my $i3 = $i2 - 1; + if ( $realbi[$i3] ne $bibitems[$i] ) { + $realbi[$i2] = $bibitems[$i]; + $i2++; + } + } + my $const; + + if ( defined $checkitem && $checkitem ne '' ) { + my $item = GetItem($checkitem); + + #Making sure the biblionumber is present. Pretty robust! And possibly scary? + if ( $item->{'biblionumber'} ne $biblionumber ) { + $biblionumber = $item->{'biblionumber'}; + } + my $errorMsg; + ( $transferOk, $errorMsg ) = + CanItemBeTransferred( $branch, $item->{holdingbranch}, + $item, undef ); + if ( !$transferOk ) { + $errorMessages .= $errorMsg . ', '; + } + } + else { + #Final check if UseBranchTransferLimits validate for this Biblio. + $transferOk = + CanBookBeReserved( $borrowernumber, $biblionumber, $branch ); + } + + if ($transferOk) { + + if ($multi_hold) { + my $bibinfo = $bibinfos{$biblionumber}; + AddReserve( + $branch, $borrower->{'borrowernumber'}, + $biblionumber, 'a', + [$biblionumber], $bibinfo->{rank}, + $startdate, $expirationdate, + $notes, $bibinfo->{title}, + $checkitem, $found + ); + } + else { + if ( $input->param('request') eq 'any' ) { + + # place a request on 1st available + AddReserve( + $branch, $borrower->{'borrowernumber'}, + $biblionumber, 'a', + \@realbi, $rank[0], + $startdate, $expirationdate, + $notes, $title, + $checkitem, $found + ); + } + elsif ( $reqbib[0] ne '' ) { + + # FIXME : elsif probably never reached, (see top of the script) + # place a request on a given item + AddReserve( + $branch, $borrower->{'borrowernumber'}, + $biblionumber, 'o', + \@reqbib, $rank[0], + $startdate, $expirationdate, + $notes, $title, + $checkitem, $found + ); + } + else { + AddReserve( + $branch, $borrower->{'borrowernumber'}, + $biblionumber, 'a', + \@realbi, $rank[0], + $startdate, $expirationdate, + $notes, $title, + $checkitem, $found + ); + } + } + } } - - - - if ($multi_hold) { - my $bibinfo = $bibinfos{$biblionumber}; - AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,'a',[$biblionumber], - $bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found); - } else { - if ($input->param('request') eq 'any'){ - # place a request on 1st available - AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem,$found); - } elsif ($reqbib[0] ne ''){ - # FIXME : elsif probably never reached, (see top of the script) - # place a request on a given item - AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,'o',\@reqbib,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem, $found); - } else { - AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,'a',\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem, $found); - } - } - } - - if ($multi_hold) { - if ($bad_bibs) { - $biblionumbers .= $bad_bibs; - } - print $input->redirect("request.pl?biblionumbers=$biblionumbers&multi_hold=1"); - } else { - print $input->redirect("request.pl?biblionumber=$biblionumber"); - } -} elsif ($borrower eq ''){ + if ($errorMessages) { + print $input->header(); + print "The following branch transfer limits are blocked:\n" + . $errorMessages; + } + elsif ($multi_hold) { + if ($bad_bibs) { + $biblionumbers .= $bad_bibs; + } + print $input->redirect( + "request.pl?biblionumbers=$biblionumbers&multi_hold=1"); + } + else { + print $input->redirect("request.pl?biblionumber=$biblionumber"); + } +} +elsif ( $borrower eq '' ) { print $input->header(); print "Invalid borrower number please try again"; -# Not sure that Dump() does HTML escaping. Use firebug or something to trace -# instead. -# print $input->Dump; + + # Not sure that Dump() does HTML escaping. Use firebug or something to trace + # instead. + # print $input->Dump; } diff --git a/reserve/request.pl b/reserve/request.pl index c411ce9..79c017b 100755 --- a/reserve/request.pl +++ b/reserve/request.pl @@ -1,6 +1,5 @@ #!/usr/bin/perl - #writen 2/1/00 by chris@katipo.oc.nz # Copyright 2000-2002 Katipo Communications # Parts Copyright 2011 Catalyst IT @@ -41,35 +40,36 @@ use C4::Koha; use C4::Circulation; use C4::Dates qw/format_date/; use C4::Members; -use C4::Search; # enabled_staff_search_views +use C4::Search; # enabled_staff_search_views use Koha::DateUtils; my $dbh = C4::Context->dbh; my $sth; my $input = new CGI; my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user( - { - template_name => "reserve/request.tmpl", - query => $input, - type => "intranet", - authnotrequired => 0, - flagsrequired => { reserveforothers => 'place_holds' }, - } + { + template_name => "reserve/request.tmpl", + query => $input, + type => "intranet", + authnotrequired => 0, + flagsrequired => { reserveforothers => 'place_holds' }, + } ); my $multihold = $input->param('multi_hold'); -$template->param(multi_hold => $multihold); +$template->param( multi_hold => $multihold ); my $showallitems = $input->param('showallitems'); # get Branches and Itemtypes -my $branches = GetBranches(); +my $branches = GetBranches(); my $itemtypes = GetItemTypes(); my $userbranch = ''; -if (C4::Context->userenv && C4::Context->userenv->{'branch'}) { - $userbranch = C4::Context->userenv->{'branch'}; +if ( C4::Context->userenv && C4::Context->userenv->{'branch'} ) { + $userbranch = C4::Context->userenv->{'branch'}; } - +my $pickupBranch = + $input->param('pickup') ? $input->param('pickup') : $userbranch; # Select borrowers infos my $findborrower = $input->param('findborrower'); @@ -79,90 +79,98 @@ my $borrowernumber_hold = $input->param('borrowernumber') || ''; my $messageborrower; my $maxreserves; -my $date = C4::Dates->today('iso'); +my $date = C4::Dates->today('iso'); my $action = $input->param('action'); $action ||= q{}; if ( $action eq 'move' ) { - my $where = $input->param('where'); - my $reserve_id = $input->param('reserve_id'); - AlterPriority( $where, $reserve_id ); -} elsif ( $action eq 'cancel' ) { - my $reserve_id = $input->param('reserve_id'); - CancelReserve({ reserve_id => $reserve_id }); -} elsif ( $action eq 'setLowestPriority' ) { - my $reserve_id = $input->param('reserve_id'); - ToggleLowestPriority( $reserve_id ); -} elsif ( $action eq 'toggleSuspend' ) { - my $reserve_id = $input->param('reserve_id'); - my $suspend_until = $input->param('suspend_until'); - ToggleSuspend( $reserve_id, $suspend_until ); + my $where = $input->param('where'); + my $reserve_id = $input->param('reserve_id'); + AlterPriority( $where, $reserve_id ); +} +elsif ( $action eq 'cancel' ) { + my $reserve_id = $input->param('reserve_id'); + CancelReserve( { reserve_id => $reserve_id } ); +} +elsif ( $action eq 'setLowestPriority' ) { + my $reserve_id = $input->param('reserve_id'); + ToggleLowestPriority($reserve_id); +} +elsif ( $action eq 'toggleSuspend' ) { + my $reserve_id = $input->param('reserve_id'); + my $suspend_until = $input->param('suspend_until'); + ToggleSuspend( $reserve_id, $suspend_until ); } if ($findborrower) { - my $borrowers = Search($findborrower, 'cardnumber'); - - if ($borrowers && @$borrowers) { - if ( @$borrowers == 1 ) { - $borrowernumber_hold = $borrowers->[0]->{'borrowernumber'}; - } - else { - $template->param( borrower_list => sort_borrowerlist($borrowers)); - } - } else { - $messageborrower = "'$findborrower'"; - } + my $borrowers = Search( $findborrower, 'cardnumber' ); + + if ( $borrowers && @$borrowers ) { + if ( @$borrowers == 1 ) { + $borrowernumber_hold = $borrowers->[0]->{'borrowernumber'}; + } + else { + $template->param( borrower_list => sort_borrowerlist($borrowers) ); + } + } + else { + $messageborrower = "'$findborrower'"; + } } # If we have the borrowernumber because we've performed an action, then we # don't want to try to place another reserve. -if ($borrowernumber_hold && !$action) { - my $borrowerinfo = GetMember( borrowernumber => $borrowernumber_hold ); - my $diffbranch; - my @getreservloop; - my $count_reserv = 0; +if ( $borrowernumber_hold && !$action ) { + my $borrowerinfo = GetMember( borrowernumber => $borrowernumber_hold ); + my $diffbranch; + my @getreservloop; + my $count_reserv = 0; # we check the reserves of the borrower, and if he can reserv a document # FIXME At this time we have a simple count of reservs, but, later, we could improve the infos "title" ... - my $number_reserves = - GetReserveCount( $borrowerinfo->{'borrowernumber'} ); - - if ( C4::Context->preference('maxreserves') && ($number_reserves >= C4::Context->preference('maxreserves')) ) { - $maxreserves = 1; - } - - # we check the date expiry of the borrower (only if there is an expiry date, otherwise, set to 1 (warn) - my $expiry_date = $borrowerinfo->{dateexpiry}; - my $expiry = 0; # flag set if patron account has expired - if ($expiry_date and $expiry_date ne '0000-00-00' and - Date_to_Days(split /-/,$date) > Date_to_Days(split /-/,$expiry_date)) { - $expiry = 1; - } - - # check if the borrower make the reserv in a different branch - if ( $borrowerinfo->{'branchcode'} ne C4::Context->userenv->{'branch'} ) { - $diffbranch = 1; - } - - $template->param( - borrowernumber => $borrowerinfo->{'borrowernumber'}, - borrowersurname => $borrowerinfo->{'surname'}, - borrowerfirstname => $borrowerinfo->{'firstname'}, - borrowerstreetaddress => $borrowerinfo->{'address'}, - borrowercity => $borrowerinfo->{'city'}, - borrowerphone => $borrowerinfo->{'phone'}, - borrowermobile => $borrowerinfo->{'mobile'}, - borrowerfax => $borrowerinfo->{'fax'}, - borrowerphonepro => $borrowerinfo->{'phonepro'}, - borroweremail => $borrowerinfo->{'email'}, - borroweremailpro => $borrowerinfo->{'emailpro'}, - borrowercategory => $borrowerinfo->{'category'}, - borrowerreservs => $count_reserv, - cardnumber => $borrowerinfo->{'cardnumber'}, - expiry => $expiry, - diffbranch => $diffbranch, - ); + my $number_reserves = GetReserveCount( $borrowerinfo->{'borrowernumber'} ); + + if ( C4::Context->preference('maxreserves') + && ( $number_reserves >= C4::Context->preference('maxreserves') ) ) + { + $maxreserves = 1; + } + +# we check the date expiry of the borrower (only if there is an expiry date, otherwise, set to 1 (warn) + my $expiry_date = $borrowerinfo->{dateexpiry}; + my $expiry = 0; # flag set if patron account has expired + if ( $expiry_date + and $expiry_date ne '0000-00-00' + and Date_to_Days( split /-/, $date ) > + Date_to_Days( split /-/, $expiry_date ) ) + { + $expiry = 1; + } + + # check if the borrower make the reserv in a different branch + if ( $borrowerinfo->{'branchcode'} ne C4::Context->userenv->{'branch'} ) { + $diffbranch = 1; + } + + $template->param( + borrowernumber => $borrowerinfo->{'borrowernumber'}, + borrowersurname => $borrowerinfo->{'surname'}, + borrowerfirstname => $borrowerinfo->{'firstname'}, + borrowerstreetaddress => $borrowerinfo->{'address'}, + borrowercity => $borrowerinfo->{'city'}, + borrowerphone => $borrowerinfo->{'phone'}, + borrowermobile => $borrowerinfo->{'mobile'}, + borrowerfax => $borrowerinfo->{'fax'}, + borrowerphonepro => $borrowerinfo->{'phonepro'}, + borroweremail => $borrowerinfo->{'email'}, + borroweremailpro => $borrowerinfo->{'emailpro'}, + borrowercategory => $borrowerinfo->{'category'}, + borrowerreservs => $count_reserv, + cardnumber => $borrowerinfo->{'cardnumber'}, + expiry => $expiry, + diffbranch => $diffbranch, + ); } $template->param( messageborrower => $messageborrower ); @@ -173,434 +181,511 @@ my $borrowerinfo = GetMember( borrowernumber => $borrowernumber_hold ); my @biblionumbers = (); my $biblionumbers = $input->param('biblionumbers'); if ($multihold) { - @biblionumbers = split '/', $biblionumbers; -} else { - push @biblionumbers, $input->param('biblionumber'); + @biblionumbers = split '/', $biblionumbers; +} +else { + push @biblionumbers, $input->param('biblionumber'); } my $itemdata_enumchron = 0; -my @biblioloop = (); +my @biblioloop = (); foreach my $biblionumber (@biblionumbers) { - my %biblioloopiter = (); - - my $dat = GetBiblioData($biblionumber); - - unless ( CanBookBeReserved($borrowerinfo->{borrowernumber}, $biblionumber) ) { - $maxreserves = 1; - } - - my $alreadypossession; - if (not C4::Context->preference('AllowHoldsOnPatronsPossessions') and CheckIfIssuedToPatron($borrowerinfo->{borrowernumber},$biblionumber)) { - $alreadypossession = 1; - } - - # get existing reserves ..... - my ( $count, $reserves ) = GetReservesFromBiblionumber($biblionumber,1); - my $totalcount = $count; - my $holds_count = 0; - my $alreadyreserved = 0; - - foreach my $res (@$reserves) { - if ( defined $res->{found} && $res->{found} eq 'W' ) { - $count--; - } - - if ( defined $borrowerinfo && defined($borrowerinfo->{borrowernumber}) && ($borrowerinfo->{borrowernumber} eq $res->{borrowernumber}) ) { - $holds_count++; - } - } - - if ( $holds_count ) { - $alreadyreserved = 1; - $biblioloopiter{warn} = 1; - $biblioloopiter{alreadyres} = 1; - } - - $template->param( - alreadyreserved => $alreadyreserved, - alreadypossession => $alreadypossession, - ); - - # FIXME think @optionloop, is maybe obsolete, or must be switchable by a systeme preference fixed rank or not - # make priorities options - - my @optionloop; - for ( 1 .. $count + 1 ) { - push( - @optionloop, - { - num => $_, - selected => ( $_ == $count + 1 ), - } - ); - } - # adding a fixed value for priority options - my $fixedRank = $count+1; - - my @branchcodes; - my %itemnumbers_of_biblioitem; - my @itemnumbers; - - ## $items is array of 'item' table numbers - if (my $items = get_itemnumbers_of($biblionumber)->{$biblionumber}){ - @itemnumbers = @$items; - } - my @hostitems = get_hostitemnumbers_of($biblionumber); - if (@hostitems){ - $template->param('hostitemsflag' => 1); - push(@itemnumbers, @hostitems); - } - - if (!@itemnumbers) { - $template->param('noitems' => 1); - $biblioloopiter{noitems} = 1; - } - - ## Hash of item number to 'item' table fields - my $iteminfos_of = GetItemInfosOf(@itemnumbers); - - ## Here we go backwards again to create hash of biblioitemnumber to itemnumbers, - ## when by definition all of the itemnumber have the same biblioitemnumber - foreach my $itemnumber (@itemnumbers) { - my $biblioitemnumber = $iteminfos_of->{$itemnumber}->{biblioitemnumber}; - push( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} }, $itemnumber ); - } - - ## Should be same as biblionumber - my @biblioitemnumbers = keys %itemnumbers_of_biblioitem; - - my $notforloan_label_of = get_notforloan_label_of(); - - ## Hash of biblioitemnumber to 'biblioitem' table records - my $biblioiteminfos_of = GetBiblioItemInfosOf(@biblioitemnumbers); - - my @bibitemloop; - - foreach my $biblioitemnumber (@biblioitemnumbers) { - my $biblioitem = $biblioiteminfos_of->{$biblioitemnumber}; - my $num_available = 0; - my $num_override = 0; - my $hiddencount = 0; - - $biblioitem->{description} = - $itemtypes->{ $biblioitem->{itemtype} }{description}; - if($biblioitem->{biblioitemnumber} ne $biblionumber){ - $biblioitem->{hostitemsflag}=1; + my %biblioloopiter = (); + + my $dat = GetBiblioData($biblionumber); + + unless ( + CanBookBeReserved( $borrowerinfo->{borrowernumber}, $biblionumber ) ) + { + $maxreserves = 1; + } + + my $alreadypossession; + if ( not C4::Context->preference('AllowHoldsOnPatronsPossessions') + and + CheckIfIssuedToPatron( $borrowerinfo->{borrowernumber}, $biblionumber ) + ) + { + $alreadypossession = 1; + } + + # get existing reserves ..... + my ( $count, $reserves ) = GetReservesFromBiblionumber( $biblionumber, 1 ); + my $totalcount = $count; + my $holds_count = 0; + my $alreadyreserved = 0; + + foreach my $res (@$reserves) { + if ( defined $res->{found} && $res->{found} eq 'W' ) { + $count--; + } + + if ( defined $borrowerinfo + && defined( $borrowerinfo->{borrowernumber} ) + && ( $borrowerinfo->{borrowernumber} eq $res->{borrowernumber} ) ) + { + $holds_count++; + } + } + + if ($holds_count) { + $alreadyreserved = 1; + $biblioloopiter{warn} = 1; + $biblioloopiter{alreadyres} = 1; + } + + $template->param( + alreadyreserved => $alreadyreserved, + alreadypossession => $alreadypossession, + ); + +# FIXME think @optionloop, is maybe obsolete, or must be switchable by a systeme preference fixed rank or not +# make priorities options + + my @optionloop; + for ( 1 .. $count + 1 ) { + push( + @optionloop, + { + num => $_, + selected => ( $_ == $count + 1 ), + } + ); + } + + # adding a fixed value for priority options + my $fixedRank = $count + 1; + + my @branchcodes; + my %itemnumbers_of_biblioitem; + my @itemnumbers; + + ## $items is array of 'item' table numbers + if ( my $items = get_itemnumbers_of($biblionumber)->{$biblionumber} ) { + @itemnumbers = @$items; } - $biblioloopiter{description} = $biblioitem->{description}; - $biblioloopiter{itypename} = $biblioitem->{description}; - $biblioloopiter{imageurl} = - getitemtypeimagelocation('intranet', $itemtypes->{$biblioitem->{itemtype}}{imageurl}); - - foreach my $itemnumber ( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} } ) { - my $item = $iteminfos_of->{$itemnumber}; - - unless (C4::Context->preference('item-level_itypes')) { - $item->{itype} = $biblioitem->{itemtype}; - } - - $item->{itypename} = $itemtypes->{ $item->{itype} }{description}; - $item->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtypes->{ $item->{itype} }{imageurl} ); - $item->{homebranchname} = $branches->{ $item->{homebranch} }{branchname}; - - # if the holdingbranch is different than the homebranch, we show the - # holdingbranch of the document too - if ( $item->{homebranch} ne $item->{holdingbranch} ) { - $item->{holdingbranchname} = - $branches->{ $item->{holdingbranch} }{branchname}; - } - - if($item->{biblionumber} ne $biblionumber){ - $item->{hostitemsflag}=1; - $item->{hosttitle} = GetBiblioData($item->{biblionumber})->{title}; + my @hostitems = get_hostitemnumbers_of($biblionumber); + if (@hostitems) { + $template->param( 'hostitemsflag' => 1 ); + push( @itemnumbers, @hostitems ); + } + + if ( !@itemnumbers ) { + $template->param( 'noitems' => 1 ); + $biblioloopiter{noitems} = 1; + } + + ## Hash of item number to 'item' table fields + my $iteminfos_of = GetItemInfosOf(@itemnumbers); + + ## Here we go backwards again to create hash of biblioitemnumber to itemnumbers, + ## when by definition all of the itemnumber have the same biblioitemnumber + foreach my $itemnumber (@itemnumbers) { + my $biblioitemnumber = $iteminfos_of->{$itemnumber}->{biblioitemnumber}; + push( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} }, $itemnumber ); + } + + ## Should be same as biblionumber + my @biblioitemnumbers = keys %itemnumbers_of_biblioitem; + + my $notforloan_label_of = get_notforloan_label_of(); + + ## Hash of biblioitemnumber to 'biblioitem' table records + my $biblioiteminfos_of = GetBiblioItemInfosOf(@biblioitemnumbers); + + my @bibitemloop; + + foreach my $biblioitemnumber (@biblioitemnumbers) { + my $biblioitem = $biblioiteminfos_of->{$biblioitemnumber}; + my $num_available = 0; + my $num_override = 0; + my $hiddencount = 0; + +#Collect the amout of items that pass the CanItemBeTransferred-check. This is needed to tell +# the user if some or all Items cannot be transferred to the pickup location. + my $branchTransferableItemsCount = 0; + + $biblioitem->{description} = + $itemtypes->{ $biblioitem->{itemtype} }{description}; + if ( $biblioitem->{biblioitemnumber} ne $biblionumber ) { + $biblioitem->{hostitemsflag} = 1; } - - # add information - $item->{itemcallnumber} = $item->{itemcallnumber}; - - # if the item is currently on loan, we display its return date and - # change the background color - my $issues= GetItemIssue($itemnumber); - if ( $issues->{'date_due'} ) { - $item->{date_due} = format_sqldatetime($issues->{date_due}); - $item->{backgroundcolor} = 'onloan'; - } - - # checking reserve - my ($reservedate,$reservedfor,$expectedAt,$reserve_id) = GetReservesFromItemnumber($itemnumber); - my $ItemBorrowerReserveInfo = GetMember( borrowernumber => $reservedfor ); - - if ( defined $reservedate ) { - $item->{backgroundcolor} = 'reserved'; - $item->{reservedate} = format_date($reservedate); - $item->{ReservedForBorrowernumber} = $reservedfor; - $item->{ReservedForSurname} = $ItemBorrowerReserveInfo->{'surname'}; - $item->{ReservedForFirstname} = $ItemBorrowerReserveInfo->{'firstname'}; - $item->{ExpectedAtLibrary} = $branches->{$expectedAt}{branchname}; - - } - - # Management of the notforloan document - if ( $item->{notforloan} ) { - $item->{backgroundcolor} = 'other'; - $item->{notforloanvalue} = - $notforloan_label_of->{ $item->{notforloan} }; - } - - # Management of lost or long overdue items - if ( $item->{itemlost} ) { - - # FIXME localized strings should never be in Perl code - $item->{message} = - $item->{itemlost} == 1 ? "(lost)" - : $item->{itemlost} == 2 ? "(long overdue)" - : ""; - $item->{backgroundcolor} = 'other'; - if (GetHideLostItemsPreference($borrowernumber) && !$showallitems) { - $item->{hide} = 1; - $hiddencount++; - } - } - - # Check the transit status - my ( $transfertwhen, $transfertfrom, $transfertto ) = - GetTransfers($itemnumber); - - if ( defined $transfertwhen && $transfertwhen ne '' ) { - $item->{transfertwhen} = format_date($transfertwhen); - $item->{transfertfrom} = - $branches->{$transfertfrom}{branchname}; - $item->{transfertto} = $branches->{$transfertto}{branchname}; - $item->{nocancel} = 1; - } - - # If there is no loan, return and transfer, we show a checkbox. - $item->{notforloan} = $item->{notforloan} || 0; - - # if independent branches is on we need to check if the person can reserve - # for branches they arent logged in to - if ( C4::Context->preference("IndependentBranches") ) { - if (! C4::Context->preference("canreservefromotherbranches")){ - # cant reserve items so need to check if item homebranch and userenv branch match if not we cant reserve - my $userenv = C4::Context->userenv; - if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) { - $item->{cantreserve} = 1 if ( $item->{homebranch} ne $userenv->{branch} ); - } - } - } - - my $branch = C4::Circulation::_GetCircControlBranch($item, $borrowerinfo); - - my $branchitemrule = GetBranchItemRule( $branch, $item->{'itype'} ); - my $policy_holdallowed = 1; - - $item->{'holdallowed'} = $branchitemrule->{'holdallowed'}; - - if ( $branchitemrule->{'holdallowed'} == 0 || - ( $branchitemrule->{'holdallowed'} == 1 && - $borrowerinfo->{'branchcode'} ne $item->{'homebranch'} ) ) { - $policy_holdallowed = 0; - } - - if ( - $policy_holdallowed - && !$item->{cantreserve} - && IsAvailableForItemLevelRequest($itemnumber) - && CanItemBeReserved( - $borrowerinfo->{borrowernumber}, $itemnumber - ) - ) - { - $item->{available} = 1; - $num_available++; - } - elsif ( C4::Context->preference('AllowHoldPolicyOverride') ) { + $biblioloopiter{description} = $biblioitem->{description}; + $biblioloopiter{itypename} = $biblioitem->{description}; + $biblioloopiter{imageurl} = + getitemtypeimagelocation( 'intranet', + $itemtypes->{ $biblioitem->{itemtype} }{imageurl} ); + + foreach + my $itemnumber ( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} } ) + { + my $item = $iteminfos_of->{$itemnumber}; + + unless ( C4::Context->preference('item-level_itypes') ) { + $item->{itype} = $biblioitem->{itemtype}; + } + + $item->{itypename} = $itemtypes->{ $item->{itype} }{description}; + $item->{imageurl} = getitemtypeimagelocation( 'intranet', + $itemtypes->{ $item->{itype} }{imageurl} ); + $item->{homebranchname} = + $branches->{ $item->{homebranch} }{branchname}; + + # if the holdingbranch is different than the homebranch, we show the + # holdingbranch of the document too + if ( $item->{homebranch} ne $item->{holdingbranch} ) { + $item->{holdingbranchname} = + $branches->{ $item->{holdingbranch} }{branchname}; + } + + if ( $item->{biblionumber} ne $biblionumber ) { + $item->{hostitemsflag} = 1; + $item->{hosttitle} = + GetBiblioData( $item->{biblionumber} )->{title}; + } + + # add information + $item->{itemcallnumber} = $item->{itemcallnumber}; + + # if the item is currently on loan, we display its return date and + # change the background color + my $issues = GetItemIssue($itemnumber); + if ( $issues->{'date_due'} ) { + $item->{date_due} = format_sqldatetime( $issues->{date_due} ); + $item->{backgroundcolor} = 'onloan'; + } + + # checking reserve + my ( $reservedate, $reservedfor, $expectedAt, $reserve_id ) = + GetReservesFromItemnumber($itemnumber); + my $ItemBorrowerReserveInfo = + GetMember( borrowernumber => $reservedfor ); + + if ( defined $reservedate ) { + $item->{backgroundcolor} = 'reserved'; + $item->{reservedate} = format_date($reservedate); + $item->{ReservedForBorrowernumber} = $reservedfor; + $item->{ReservedForSurname} = + $ItemBorrowerReserveInfo->{'surname'}; + $item->{ReservedForFirstname} = + $ItemBorrowerReserveInfo->{'firstname'}; + $item->{ExpectedAtLibrary} = + $branches->{$expectedAt}{branchname}; + + } + + # Management of the notforloan document + if ( $item->{notforloan} ) { + $item->{backgroundcolor} = 'other'; + $item->{notforloanvalue} = + $notforloan_label_of->{ $item->{notforloan} }; + } + + # Management of lost or long overdue items + if ( $item->{itemlost} ) { + + # FIXME localized strings should never be in Perl code + $item->{message} = + $item->{itemlost} == 1 ? "(lost)" + : $item->{itemlost} == 2 ? "(long overdue)" + : ""; + $item->{backgroundcolor} = 'other'; + if ( GetHideLostItemsPreference($borrowernumber) + && !$showallitems ) + { + $item->{hide} = 1; + $hiddencount++; + } + } + + # Check the transit status + my ( $transfertwhen, $transfertfrom, $transfertto ) = + GetTransfers($itemnumber); + + if ( defined $transfertwhen && $transfertwhen ne '' ) { + $item->{transfertwhen} = format_date($transfertwhen); + $item->{transfertfrom} = + $branches->{$transfertfrom}{branchname}; + $item->{transfertto} = $branches->{$transfertto}{branchname}; + $item->{nocancel} = 1; + } + + # If there is no loan, return and transfer, we show a checkbox. + $item->{notforloan} = $item->{notforloan} || 0; + + # if independent branches is on we need to check if the person can reserve + # for branches they arent logged in to + if ( C4::Context->preference("IndependentBranches") ) { + if ( !C4::Context->preference("canreservefromotherbranches") ) { + +# cant reserve items so need to check if item homebranch and userenv branch match if not we cant reserve + my $userenv = C4::Context->userenv; + if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) { + $item->{cantreserve} = 1 + if ( $item->{homebranch} ne $userenv->{branch} ); + } + } + } + + # UseBranchTransferLimits checking + my ( $transferOk, $errorMessage ) = + CanItemBeTransferred( $pickupBranch, $item->{holdingbranch}, + $item, undef ); + if ( !$transferOk ) { + $item->{cantreserve} = 1; + $item->{branchTransferDenied} = 1; + } + else { + $branchTransferableItemsCount++; + } + + my $branch = + C4::Circulation::_GetCircControlBranch( $item, $borrowerinfo ); + + my $branchitemrule = GetBranchItemRule( $branch, $item->{'itype'} ); + my $policy_holdallowed = 1; + + $item->{'holdallowed'} = $branchitemrule->{'holdallowed'}; + + if ( + $branchitemrule->{'holdallowed'} == 0 + || ( $branchitemrule->{'holdallowed'} == 1 + && $borrowerinfo->{'branchcode'} ne $item->{'homebranch'} ) + ) + { + $policy_holdallowed = 0; + } + + if ( + $policy_holdallowed + && !$item->{cantreserve} + && IsAvailableForItemLevelRequest($itemnumber) + && CanItemBeReserved( + $borrowerinfo->{borrowernumber}, $itemnumber + ) + ) + { + $item->{available} = 1; + $num_available++; + } + elsif ( C4::Context->preference('AllowHoldPolicyOverride') ) { # If AllowHoldPolicyOverride is set, it should override EVERY restriction, not just branch item rules - $item->{override} = 1; - $num_override++; - } - - # If none of the conditions hold true, then neither override nor available is set and the item cannot be checked - - # FIXME: move this to a pm - my $sth2 = $dbh->prepare("SELECT * FROM reserves WHERE borrowernumber=? AND itemnumber=? AND found='W'"); - $sth2->execute($item->{ReservedForBorrowernumber},$item->{itemnumber}); - while (my $wait_hashref = $sth2->fetchrow_hashref) { - $item->{waitingdate} = format_date($wait_hashref->{waitingdate}); - } - - # Show serial enumeration when needed - if ($item->{enumchron}) { - $itemdata_enumchron = 1; - } - - push @{ $biblioitem->{itemloop} }, $item; - } - - if ( $num_override == scalar( @{ $biblioitem->{itemloop} } ) ) { # That is, if all items require an override - $template->param( override_required => 1 ); - } elsif ( $num_available == 0 ) { - $template->param( none_available => 1 ); - $biblioloopiter{warn} = 1; - $biblioloopiter{none_avail} = 1; - } - $template->param( hiddencount => $hiddencount); - - push @bibitemloop, $biblioitem; - } - - # existingreserves building - my @reserveloop; - ( $count, $reserves ) = GetReservesFromBiblionumber($biblionumber,1); - foreach my $res ( sort { - my $a_found = $a->{found} || ''; - my $b_found = $a->{found} || ''; - $a_found cmp $b_found; - } @$reserves ) { - my %reserve; - my @optionloop; - for ( my $i = 1 ; $i <= $totalcount ; $i++ ) { - push( - @optionloop, - { - num => $i, - selected => ( $i == $res->{priority} ), - } - ); - } - - if ( defined $res->{'found'} && ($res->{'found'} eq 'W' || $res->{'found'} eq 'T' )) { - my $item = $res->{'itemnumber'}; - $item = GetBiblioFromItemNumber($item,undef); - $reserve{'wait'}= 1; - $reserve{'holdingbranch'}=$item->{'holdingbranch'}; - $reserve{'biblionumber'}=$item->{'biblionumber'}; - $reserve{'barcodenumber'} = $item->{'barcode'}; - $reserve{'wbrcode'} = $res->{'branchcode'}; - $reserve{'itemnumber'} = $res->{'itemnumber'}; - $reserve{'wbrname'} = $branches->{$res->{'branchcode'}}->{'branchname'}; - if($reserve{'holdingbranch'} eq $reserve{'wbrcode'}){ - $reserve{'atdestination'} = 1; - } - # set found to 1 if reserve is waiting for patron pickup - $reserve{'found'} = 1 if $res->{'found'} eq 'W'; - $reserve{'intransit'} = 1 if $res->{'found'} eq 'T'; - } elsif ($res->{priority} > 0) { - if (defined($res->{itemnumber})) { - my $item = GetItem($res->{itemnumber}); - $reserve{'itemnumber'} = $res->{'itemnumber'}; - $reserve{'barcodenumber'} = $item->{'barcode'}; - $reserve{'item_level_hold'} = 1; - } - } - - # get borrowers reserve info - my $reserveborrowerinfo = GetMember( borrowernumber => $res->{'borrowernumber'} ); - if (C4::Context->preference('HidePatronName')){ - $reserve{'hidename'} = 1; - $reserve{'cardnumber'} = $reserveborrowerinfo->{'cardnumber'}; + $item->{override} = 1; + $num_override++; + } + +# If none of the conditions hold true, then neither override nor available is set and the item cannot be checked + + # FIXME: move this to a pm + my $sth2 = $dbh->prepare( +"SELECT * FROM reserves WHERE borrowernumber=? AND itemnumber=? AND found='W'" + ); + $sth2->execute( $item->{ReservedForBorrowernumber}, + $item->{itemnumber} ); + while ( my $wait_hashref = $sth2->fetchrow_hashref ) { + $item->{waitingdate} = + format_date( $wait_hashref->{waitingdate} ); + } + + # Show serial enumeration when needed + if ( $item->{enumchron} ) { + $itemdata_enumchron = 1; + } + + push @{ $biblioitem->{itemloop} }, $item; + } + + if ( $num_override == scalar( @{ $biblioitem->{itemloop} } ) ) + { # That is, if all items require an override + $template->param( override_required => 1 ); + } + elsif ( $num_available == 0 ) { + $template->param( none_available => 1 ); + $biblioloopiter{warn} = 1; + $biblioloopiter{none_avail} = 1; + } + if ( $branchTransferableItemsCount == 0 ) { + $biblioloopiter{suggestAnotherPickupLocation} = 1; + $biblioitem->{suggestAnotherPickupLocation} = 1; + $template->param( bookBranchTransferDenied => 1 ); + } + + $template->param( hiddencount => $hiddencount ); + + push @bibitemloop, $biblioitem; + } + + # existingreserves building + my @reserveloop; + ( $count, $reserves ) = GetReservesFromBiblionumber( $biblionumber, 1 ); + foreach my $res ( + sort { + my $a_found = $a->{found} || ''; + my $b_found = $a->{found} || ''; + $a_found cmp $b_found; + } @$reserves + ) + { + my %reserve; + my @optionloop; + for ( my $i = 1 ; $i <= $totalcount ; $i++ ) { + push( + @optionloop, + { + num => $i, + selected => ( $i == $res->{priority} ), + } + ); + } + + if ( defined $res->{'found'} + && ( $res->{'found'} eq 'W' || $res->{'found'} eq 'T' ) ) + { + my $item = $res->{'itemnumber'}; + $item = GetBiblioFromItemNumber( $item, undef ); + $reserve{'wait'} = 1; + $reserve{'holdingbranch'} = $item->{'holdingbranch'}; + $reserve{'biblionumber'} = $item->{'biblionumber'}; + $reserve{'barcodenumber'} = $item->{'barcode'}; + $reserve{'wbrcode'} = $res->{'branchcode'}; + $reserve{'itemnumber'} = $res->{'itemnumber'}; + $reserve{'wbrname'} = + $branches->{ $res->{'branchcode'} }->{'branchname'}; + + if ( $reserve{'holdingbranch'} eq $reserve{'wbrcode'} ) { + $reserve{'atdestination'} = 1; + } + + # set found to 1 if reserve is waiting for patron pickup + $reserve{'found'} = 1 if $res->{'found'} eq 'W'; + $reserve{'intransit'} = 1 if $res->{'found'} eq 'T'; + } + elsif ( $res->{priority} > 0 ) { + if ( defined( $res->{itemnumber} ) ) { + my $item = GetItem( $res->{itemnumber} ); + $reserve{'itemnumber'} = $res->{'itemnumber'}; + $reserve{'barcodenumber'} = $item->{'barcode'}; + $reserve{'item_level_hold'} = 1; + } + } + + # get borrowers reserve info + my $reserveborrowerinfo = + GetMember( borrowernumber => $res->{'borrowernumber'} ); + if ( C4::Context->preference('HidePatronName') ) { + $reserve{'hidename'} = 1; + $reserve{'cardnumber'} = $reserveborrowerinfo->{'cardnumber'}; + } + $reserve{'expirationdate'} = format_date( $res->{'expirationdate'} ) + unless ( !defined( $res->{'expirationdate'} ) + || $res->{'expirationdate'} eq '0000-00-00' ); + $reserve{'date'} = format_date( $res->{'reservedate'} ); + $reserve{'borrowernumber'} = $res->{'borrowernumber'}; + $reserve{'biblionumber'} = $res->{'biblionumber'}; + $reserve{'borrowernumber'} = $res->{'borrowernumber'}; + $reserve{'firstname'} = $reserveborrowerinfo->{'firstname'}; + $reserve{'surname'} = $reserveborrowerinfo->{'surname'}; + $reserve{'notes'} = $res->{'reservenotes'}; + $reserve{'wait'} = ( + ( defined $res->{'found'} and $res->{'found'} eq 'W' ) + or ( $res->{'priority'} eq '0' ) + ); + $reserve{'constrainttypea'} = ( $res->{'constrainttype'} eq 'a' ); + $reserve{'constrainttypeo'} = ( $res->{'constrainttype'} eq 'o' ); + $reserve{'voldesc'} = $res->{'volumeddesc'}; + $reserve{'ccode'} = $res->{'ccode'}; + $reserve{'barcode'} = $res->{'barcode'}; + $reserve{'priority'} = $res->{'priority'}; + $reserve{'lowestPriority'} = $res->{'lowestPriority'}; + $reserve{'optionloop'} = \@optionloop; + $reserve{'suspend'} = $res->{'suspend'}; + $reserve{'suspend_until'} = $res->{'suspend_until'}; + $reserve{'reserve_id'} = $res->{'reserve_id'}; + + if ( C4::Context->preference('IndependentBranches') + && $flags->{'superlibrarian'} != 1 ) + { + $reserve{'branchloop'} = + [ GetBranchDetail( $res->{'branchcode'} ) ]; + } + else { + $reserve{'branchloop'} = GetBranchesLoop( $res->{'branchcode'} ); + } + + push( @reserveloop, \%reserve ); + } + + # get the time for the form name... + my $time = time(); + + $template->param( + branchloop => GetBranchesLoop($pickupBranch), + time => $time, + fixedRank => $fixedRank, + ); + + # display infos + $template->param( + optionloop => \@optionloop, + bibitemloop => \@bibitemloop, + itemdata_enumchron => $itemdata_enumchron, + date => $date, + biblionumber => $biblionumber, + findborrower => $findborrower, + title => $dat->{title}, + author => $dat->{author}, + holdsview => 1, + C4::Search::enabled_staff_search_views, + ); + if ( defined $borrowerinfo && exists $borrowerinfo->{'branchcode'} ) { + $template->param( + borrower_branchname => + $branches->{ $borrowerinfo->{'branchcode'} }->{'branchname'}, + borrower_branchcode => $borrowerinfo->{'branchcode'}, + ); } - $reserve{'expirationdate'} = format_date( $res->{'expirationdate'} ) - unless ( !defined($res->{'expirationdate'}) || $res->{'expirationdate'} eq '0000-00-00' ); - $reserve{'date'} = format_date( $res->{'reservedate'} ); - $reserve{'borrowernumber'} = $res->{'borrowernumber'}; - $reserve{'biblionumber'} = $res->{'biblionumber'}; - $reserve{'borrowernumber'} = $res->{'borrowernumber'}; - $reserve{'firstname'} = $reserveborrowerinfo->{'firstname'}; - $reserve{'surname'} = $reserveborrowerinfo->{'surname'}; - $reserve{'notes'} = $res->{'reservenotes'}; - $reserve{'wait'} = - ( ( defined $res->{'found'} and $res->{'found'} eq 'W' ) or ( $res->{'priority'} eq '0' ) ); - $reserve{'constrainttypea'} = ( $res->{'constrainttype'} eq 'a' ); - $reserve{'constrainttypeo'} = ( $res->{'constrainttype'} eq 'o' ); - $reserve{'voldesc'} = $res->{'volumeddesc'}; - $reserve{'ccode'} = $res->{'ccode'}; - $reserve{'barcode'} = $res->{'barcode'}; - $reserve{'priority'} = $res->{'priority'}; - $reserve{'lowestPriority'} = $res->{'lowestPriority'}; - $reserve{'optionloop'} = \@optionloop; - $reserve{'suspend'} = $res->{'suspend'}; - $reserve{'suspend_until'} = $res->{'suspend_until'}; - $reserve{'reserve_id'} = $res->{'reserve_id'}; - - if ( C4::Context->preference('IndependentBranches') && $flags->{'superlibrarian'} != 1 ) { - $reserve{'branchloop'} = [ GetBranchDetail($res->{'branchcode'}) ]; - } else { - $reserve{'branchloop'} = GetBranchesLoop($res->{'branchcode'}); - } - - push( @reserveloop, \%reserve ); - } - - # get the time for the form name... - my $time = time(); - - $template->param( - branchloop => GetBranchesLoop($userbranch), - time => $time, - fixedRank => $fixedRank, - ); - - # display infos - $template->param( - optionloop => \@optionloop, - bibitemloop => \@bibitemloop, - itemdata_enumchron => $itemdata_enumchron, - date => $date, - biblionumber => $biblionumber, - findborrower => $findborrower, - title => $dat->{title}, - author => $dat->{author}, - holdsview => 1, - C4::Search::enabled_staff_search_views, - ); - if (defined $borrowerinfo && exists $borrowerinfo->{'branchcode'}) { - $template->param( - borrower_branchname => $branches->{$borrowerinfo->{'branchcode'}}->{'branchname'}, - borrower_branchcode => $borrowerinfo->{'branchcode'}, - ); - } - - $biblioloopiter{biblionumber} = $biblionumber; - $biblioloopiter{title} = $dat->{title}; - $biblioloopiter{rank} = $fixedRank; - $biblioloopiter{reserveloop} = \@reserveloop; - - if (@reserveloop) { - $template->param( reserveloop => \@reserveloop ); - } - - push @biblioloop, \%biblioloopiter; + + $biblioloopiter{biblionumber} = $biblionumber; + $biblioloopiter{title} = $dat->{title}; + $biblioloopiter{rank} = $fixedRank; + $biblioloopiter{reserveloop} = \@reserveloop; + + if (@reserveloop) { + $template->param( reserveloop => \@reserveloop ); + } + + push @biblioloop, \%biblioloopiter; } -$template->param( biblioloop => \@biblioloop ); +$template->param( biblioloop => \@biblioloop ); $template->param( biblionumbers => $biblionumbers ); -$template->param( maxreserves => $maxreserves ); +$template->param( maxreserves => $maxreserves ); if ($multihold) { - $template->param( multi_hold => 1 ); + $template->param( multi_hold => 1 ); } -if ( C4::Context->preference( 'AllowHoldDateInFuture' ) ) { - $template->param( reserve_in_future => 1 ); +if ( C4::Context->preference('AllowHoldDateInFuture') ) { + $template->param( reserve_in_future => 1 ); } $template->param( - SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'), - AutoResumeSuspendedHolds => C4::Context->preference('AutoResumeSuspendedHolds'), + SuspendHoldsIntranet => C4::Context->preference('SuspendHoldsIntranet'), + AutoResumeSuspendedHolds => + C4::Context->preference('AutoResumeSuspendedHolds'), ); # printout the page output_html_with_http_headers $input, $cookie, $template->output; sub sort_borrowerlist { - my $borrowerslist = shift; - my $ref = []; - push @{$ref}, sort { - uc( $a->{surname} . $a->{firstname} ) cmp - uc( $b->{surname} . $b->{firstname} ) - } @{$borrowerslist}; - return $ref; + my $borrowerslist = shift; + my $ref = []; + push @{$ref}, sort { + uc( $a->{surname} . $a->{firstname} ) cmp + uc( $b->{surname} . $b->{firstname} ) + } @{$borrowerslist}; + return $ref; } -- 1.8.1.2