Bugzilla – Attachment 23165 Details for
Bug 11020
Transfer limits should be checked when placing a hold/reservation in Staff client
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 11020 - Transfer limits should be checked when placing a hold/reservation in Staff client
Bug-11020---Transfer-limits-should-be-checked-when.patch (text/plain), 63.33 KB, created by
Olli-Antti Kivilahti
on 2013-11-26 16:48:18 UTC
(
hide
)
Description:
Bug 11020 - Transfer limits should be checked when placing a hold/reservation in Staff client
Filename:
MIME Type:
Creator:
Olli-Antti Kivilahti
Created:
2013-11-26 16:48:18 UTC
Size:
63.33 KB
patch
obsolete
>From 69cc24cae2a9821c5b927df3ff1189ec9f2c4db3 Mon Sep 17 00:00:00 2001 >From: Olli-Antti Kivilahti <olli-antti.kivilahti@jns.fi> >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 %] > > </ol> >- [% UNLESS ( multi_hold ) %] >+ >+ >+ >+ [% UNLESS ( multi_hold ) %] > <fieldset class="action"> > [% IF ( borrowernumber ) %] >- [% IF ( override_required ) %] >+ [% IF ( bookBranchTransferDenied ) %] >+ <input type="submit" disabled="disabled" value="Place hold" /> >+ [% ELSIF ( override_required ) %] > <input type="submit" class="warning" value="Place hold" /> > [% ELSIF ( none_available ) %] > <input type="submit" disabled="disabled" value="Place hold" /> >@@ -367,12 +385,18 @@ function checkMultiHold() { > [% FOREACH bibitemloo IN bibitemloop %] > <ol> > [% UNLESS ( item_level_itypes ) %] >- <li><span class="label">Item type:</span> [% bibitemloo.description %]</li> >+ <li><span class="label">Item type:</span> [% bibitemloo.description %]</li> > [% END %] > >- [% IF ( bibitemloo.publicationyear ) %]<li><span class="label">Publication year:</span> [% bibitemloo.publicationyear %]</li>[% END %] >+ [% IF ( bibitemloo.publicationyear ) %] >+ <li><span class="label">Publication year:</span> [% bibitemloo.publicationyear %]</li> >+ [% END %] > </ol> > >+ [% IF ( bibitemloo.suggestAnotherPickupLocation ) %] >+ <div id="suggestAnotherPickupLocation_[% bibitemloo.biblionumber %]" class="dialog alert">None of the available items can be transferred to your pickup location. You could try another pickup location.</div> >+ [% END %] >+ > <table id="requestspecific"> > <caption>Place a hold on a specific copy</caption> > <tr> >@@ -396,12 +420,15 @@ function checkMultiHold() { > <td> > [% IF ( itemloo.available ) %] > <input type="radio" name="checkitem" value="[% itemloo.itemnumber %]" /> >+ [% ELSIF ( itemloo.branchTransferDenied ) %] >+ <input disabled="disabled" type="radio" name="checkitem" value="[% itemloo.itemnumber %]" /> >+ <img src="/intranet-tmpl/[% theme %]/img/famfamfam/silk/cross.png" title="Cannot transfer this item to your pickup location" alt="Cannot transfer this item to your pickup location" /> > [% ELSIF ( itemloo.override ) %] > <input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber %]" /> >- <img src="/intranet-tmpl/[% theme %]/img/famfamfam/silk/error.png" alt="Requires override of hold policy" /> >+ <img src="/intranet-tmpl/[% theme %]/img/famfamfam/silk/error.png" title="Requires override of hold policy" alt="Requires override of hold policy" /> > [% ELSE %] > <input disabled="disabled" type="radio" name="checkitem" value="[% itemloo.itemnumber %]" /> >- <img src="/intranet-tmpl/[% theme %]/img/famfamfam/silk/cross.png" alt="Cannot be put on hold" /> >+ <img src="/intranet-tmpl/[% theme %]/img/famfamfam/silk/cross.png" title="Cannot be put on hold" alt="Cannot be put on hold" /> > [% END %] > </td> > [% IF ( item_level_itypes ) %] >@@ -476,6 +503,7 @@ function checkMultiHold() { > > [% ELSE %]<!-- UNLESS multi_hold --> > >+ > <table id="requesttitles"> > <tr> > <th>Title</th> >@@ -493,7 +521,12 @@ function checkMultiHold() { > [% END %] > <td> > <ul> >- <li><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber %]">[% biblioloo.title |html %]</a></li> >+ <li> >+ [% IF ( biblioloo.suggestAnotherPickupLocation ) %] >+ <img src="/intranet-tmpl/[% theme %]/img/famfamfam/silk/cross.png" title="Cannot transfer this item to your pickup location" alt="Cannot transfer this item to your pickup location" /> >+ [% END %] >+ <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblioloo.biblionumber %]">[% biblioloo.title |html %]</a> >+ </li> > [% IF ( biblioloo.publicationyear ) %] > <li><span class="label">Publication year:</span> [% biblioloo.publicationyear %]</li> > [% END %] >@@ -539,11 +572,19 @@ function checkMultiHold() { > [% END %] > </table> > >+ [% IF ( bookBranchTransferDenied ) %] >+ <div class="dialog alert"> >+ Some books cannot be transferred to your pickup location. Please try another pickup location, or reserve fewer items at once. >+ </div> >+ [% END %] >+ > [% END %]<!-- /multi_hold --> > > <fieldset class="action"> > [% IF ( borrowernumber ) %] >- [% IF ( override_required ) %] >+ [% IF ( bookBranchTransferDenied ) %] >+ <input type="submit" disabled="disabled" value="Place hold" /> >+ [% ELSIF ( override_required ) %] > <input type="submit" class="warning" value="Place hold" /> > [% ELSIF ( none_available ) %] > <input type="submit" disabled="disabled" value="Place hold" /> >@@ -600,26 +641,17 @@ function checkMultiHold() { > <input type="hidden" name="borrowernumber" value="[% reserveloo.borrowernumber %]" /> > <input type="hidden" name="biblionumber" value="[% reserveloo.biblionumber %]" /> > <select name="rank-request"> >- [% IF ( reserveloo.wait ) %] >- [% IF ( reserveloo.intransit ) %] >- <option value="T" selected="selected">In transit</option> >- [% ELSE %] >- <option value="W" selected="selected">Waiting</option> >- [% END %] >- [% END %] >- >- [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %] >- [% FOREACH optionloo IN reserveloo.optionloop %] >- [% IF ( optionloo.selected ) %] >- <option value="[% optionloo.num %]" selected="selected">[% optionloo.num %]</option> >- [% ELSE %] >- <option value="[% optionloo.num %]">[% optionloo.num %]</option> >- [% END %] >- [% END %] >- [% ELSIF !reserveloo.wait %] >- <option value="[% reserveloo.priority %]" selected="selected">[% reserveloo.priority %]</option> >- [% END %] >- <option value="del">del</option> >+ [% IF ( reserveloo.wait ) %] >+ [% IF ( reserveloo.intransit ) %] >+ <option value="T" selected="selected">In transit</option> >+ [% ELSE %] >+ <option value="W" selected="selected">Waiting</option> >+ [% END %] >+ [% END %] >+ [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %][% FOREACH optionloo IN reserveloo.optionloop %] >+ [% IF ( optionloo.selected ) %]<option value="[% optionloo.num %]" selected="selected">[% optionloo.num %]</option>[% ELSE %]<option value="[% optionloo.num %]">[% optionloo.num %]</option>[% END %] >+ [% END %][% ELSE %]<option value=""></option>[% END %] >+ <option value="del">del</option> > </select> > </td> > >@@ -774,4 +806,26 @@ function checkMultiHold() { > > </div> > </div> >+[% IF ( multi_hold ) %] >+<form id="reloadPickupLocationForm" name="reloadPickupLocationForm" method="post" action="request.pl"> >+ <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" /> >+ <input type="hidden" name="type" value="str8" /> >+ <input type="hidden" name="multi_hold" value="[% multi_hold %]"/> >+ <input type="hidden" name="biblionumbers" id="multi_hold_bibs" value="[% biblionumbers %]"/> >+ <input type="hidden" name="bad_bibs" id="bad_bibs" value=""/> >+ <input type="hidden" name="request" value="any"/> >+ <input type="hidden" name="pickup" value="fromJavascript" /> >+ [% FOREACH biblioloo IN biblioloop %] >+ <input type="hidden" name="title_[% biblioloo.biblionumber %]" value="[% biblioloo.title |html %]"/> >+ <input type="hidden" name="rank_[% biblioloo.biblionumber %]" value="[% biblioloo.rank %]"/> >+ [% END %] >+</form> >+[% ELSE %] >+<form id="reloadPickupLocationForm" name="reloadPickupLocationForm" method="post" action="request.pl"> >+ <input type="hidden" name="borrowernumber" value="[% borrowernumber %]" /> >+ <input type="hidden" name="biblionumber" value="[% biblionumber %]" /> >+ <input type="hidden" name="pickup" value="fromJavascript" /> >+</form> >+[% 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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 11020
:
21924
|
21925
|
21997
|
21998
|
22321
| 23165