use Koha::Libraries;
use Koha::Items;
use Koha::ItemTypes;
+use Koha::Patrons;
use List::MoreUtils qw( firstidx any );
use Carp;
&GetReservesControlBranch
IsItemOnHoldAndFound
+
+ GetMaxPatronHoldsForRecord
);
@EXPORT_OK = qw( MergeHolds );
}
$title, $checkitem, $found, $itemtype
) = @_;
- if ( Koha::Holds->search( { borrowernumber => $borrowernumber, biblionumber => $biblionumber } )->count() > 0 ) {
- carp("AddReserve: borrower $borrowernumber already has a hold for biblionumber $biblionumber");
- return;
- }
-
- my $dbh = C4::Context->dbh;
+ my $dbh = C4::Context->dbh;
$resdate = output_pref( { str => dt_from_string( $resdate ), dateonly => 1, dateformat => 'iso' })
or output_pref({ dt => dt_from_string, dateonly => 1, dateformat => 'iso' });
my $dbh = C4::Context->dbh;
my $ruleitemtype; # itemtype of the matching issuing rule
- my $allowedreserves = 0;
+ my $allowedreserves = 0; # Total number of holds allowed across all records
+ my $holds_per_record = 1; # Total number of holds allowed for this one given record
# we retrieve borrowers and items informations #
# item->{itype} will come for biblioitems if necessery
if ( $item->{damaged}
&& !C4::Context->preference('AllowHoldsOnDamagedItems') );
- #Check for the age restriction
+ # Check for the age restriction
my ( $ageRestriction, $daysToAgeRestriction ) =
C4::Circulation::GetAgeRestriction( $biblioData->{agerestriction}, $borrower );
return 'ageRestricted' if $daysToAgeRestriction && $daysToAgeRestriction > 0;
- my $controlbranch = C4::Context->preference('ReservesControlBranch');
+ # Check that the patron doesn't have an item level hold on this item already
+ return 'itemAlreadyOnHold'
+ if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
- # we retrieve user rights on this itemtype and branchcode
- my $sth = $dbh->prepare(
- q{
- SELECT categorycode, itemtype, branchcode, reservesallowed
- FROM issuingrules
- WHERE (categorycode in (?,'*') )
- AND (itemtype IN (?,'*'))
- AND (branchcode IN (?,'*'))
- ORDER BY categorycode DESC,
- itemtype DESC,
- branchcode DESC
- }
- );
+ my $controlbranch = C4::Context->preference('ReservesControlBranch');
my $querycount = q{
SELECT count(*) AS count
}
# we retrieve rights
- $sth->execute( $borrower->{'categorycode'}, $item->{'itype'}, $branchcode );
- if ( my $rights = $sth->fetchrow_hashref() ) {
- $ruleitemtype = $rights->{itemtype};
- $allowedreserves = $rights->{reservesallowed};
+ if ( my $rights = GetHoldRule( $borrower->{'categorycode'}, $item->{'itype'}, $branchcode ) ) {
+ $ruleitemtype = $rights->{itemtype};
+ $allowedreserves = $rights->{reservesallowed};
+ $holds_per_record = $rights->{holds_per_record};
}
else {
$ruleitemtype = '*';
}
+ my $item = Koha::Items->find( $itemnumber );
+ my $holds = Koha::Holds->search(
+ {
+ borrowernumber => $borrowernumber,
+ biblionumber => $item->biblionumber,
+ found => undef, # Found holds don't count against a patron's holds limit
+ }
+ );
+ if ( $holds->count() >= $holds_per_record ) {
+ return "tooManyHoldsForThisRecord";
+ }
+
# we retrieve count
$querycount .= "AND $branchfield = ?";
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare(
"SELECT reserve_id,borrowernumber,reservedate,itemnumber,timestamp
- FROM reserves
- WHERE priority='0'
+ FROM reserves
+ WHERE priority='0'
AND branchcode=?"
);
$sth->execute( $frombranch );
my $query = "
SELECT reserve_id,borrowernumber,reservedate,itemnumber,waitingdate
- FROM reserves
+ FROM reserves
WHERE priority='0'
AND found='W'
";
my $dbh = C4::Context->dbh;
my $query = "
UPDATE reserves
- SET priority = 0 , itemnumber = ?
+ SET priority = 0 , itemnumber = ?
WHERE reserve_id = ?
";
my $sth_upd = $dbh->prepare($query);
my $sth = $dbh->prepare( "UPDATE reserves SET lowestPriority = NOT lowestPriority WHERE reserve_id = ?");
$sth->execute( $reserve_id );
-
+
_FixPriority({ reserve_id => $reserve_id, rank => '999999' });
}
$priority[$j]->{'reserve_id'}
);
}
-
+
$sth = $dbh->prepare( "SELECT reserve_id FROM reserves WHERE lowestPriority = 1 ORDER BY priority" );
$sth->execute();
if (! $notification_sent) {
&$send_notification('print', 'HOLD');
}
-
+
}
=head2 _ShiftPriorityByDateAndPriority
return $found;
}
+=head2 GetMaxPatronHoldsForRecord
+
+my $holds_per_record = ReservesControlBranch( $borrowernumber, $biblionumber );
+
+For multiple holds on a given record for a given patron, the max
+number of record level holds that a patron can be placed is the highest
+value of the holds_per_record rule for each item if the record for that
+patron. This subroutine finds and returns the highest holds_per_record
+rule value for a given patron id and record id.
+
+=cut
+
+sub GetMaxPatronHoldsForRecord {
+ my ( $borrowernumber, $biblionumber ) = @_;
+
+ my $patron = Koha::Patrons->find($borrowernumber);
+ my @items = Koha::Items->search( { biblionumber => $biblionumber } );
+
+ my $controlbranch = C4::Context->preference('ReservesControlBranch');
+
+ my $categorycode = $patron->categorycode;
+ my $branchcode;
+ $branchcode = $patron->branchcode if ( $controlbranch eq "PatronLibrary" );
+
+ my $max = 0;
+ foreach my $item (@items) {
+ my $itemtype = $item->effective_itemtype();
+
+ $branchcode = $item->homebranch if ( $controlbranch eq "ItemHomeLibrary" );
+
+ my $rule = GetHoldRule( $categorycode, $itemtype, $branchcode );
+ my $holds_per_record = $rule ? $rule->{holds_per_record} : 0;
+ $max = $holds_per_record if $holds_per_record > $max;
+ }
+
+ return $max;
+}
+
+=head2 GetHoldRule
+
+my $rule = GetHoldRule( $categorycode, $itemtype, $branchcode );
+
+Returns the matching hold related issuingrule fields for a given
+patron category, itemtype, and library.
+
+=cut
+
+sub GetHoldRule {
+ my ( $categorycode, $itemtype, $branchcode ) = @_;
+
+ my $dbh = C4::Context->dbh;
+
+ my $sth = $dbh->prepare(
+ q{
+ SELECT categorycode, itemtype, branchcode, reservesallowed, holds_per_record
+ FROM issuingrules
+ WHERE (categorycode in (?,'*') )
+ AND (itemtype IN (?,'*'))
+ AND (branchcode IN (?,'*'))
+ ORDER BY categorycode DESC,
+ itemtype DESC,
+ branchcode DESC
+ }
+ );
+
+ $sth->execute( $categorycode, $itemtype, $branchcode );
+
+ return $sth->fetchrow_hashref();
+}
+
=head1 AUTHOR
Koha Development Team <http://koha-community.org/>
return $self->search( { found => 'W' } );
}
+=head3 forced_hold_level
+
+If a patron has multiple holds for a single record,
+those holds must be either all record level holds,
+or they must all be item level holds.
+
+This method should be used with Hold sets where all
+Hold objects share the same patron and record.
+
+This method will return 'item' if the patron has
+at least one item level hold. It will return 'record'
+if the patron has holds but none are item level,
+Finally, if the patron has no holds, it will return
+undef which indicateds the patron may select either
+record or item level holds, barring any other rules
+that would prevent one or the other.
+=cut
+
+sub forced_hold_level {
+ my ($self) = @_;
+
+ my $force_hold_level;
+
+ if ( $self->count() ) {
+ my $has_item_level_holds;
+ map { $has_item_level_holds ||= $_->itemnumber } $self->as_list();
+ $force_hold_level = $has_item_level_holds ? 'item' : 'record';
+ }
+
+ return $force_hold_level;
+}
+
=head3 type
=cut
});
function check() {
- var msg = "";
- var count_reserv = 0;
- var alreadyreserved = 0;
+ var msg = "";
+ var count_reserv = 0;
// check if we have checkitem form
if (document.form.checkitem){
for (i=0;i<document.form.checkitem.length;i++){
if (document.form.checkitem[i].checked == true) {
- count_reserv++ ;
- }
+ count_reserv++ ;
+ }
}
// for only one item, check the checkitem without consider the loop checkitem
if (i==0){
- if (document.form.checkitem.checked == true) {
- count_reserv++;
- }
- }
- }
-
- if (document.form.request.checked == true){
- count_reserv++ ;
+ if (document.form.checkitem.checked == true) {
+ count_reserv++;
+ }
+ }
}
- if (document.form.alreadyreserved && document.form.alreadyreserved.value == "1"){
- alreadyreserved++ ;
+ if (document.form.requestany.checked == true){
+ count_reserv++ ;
}
if (count_reserv == "0"){
- msg += (_("- Please select an item to place a hold") + "\n");
- }
- if (count_reserv >= "2"){
- msg += (_("- You may only place a hold on one item at a time") + "\n");
+ msg += (_("- Please select an item to place a hold") + "\n");
}
- if (alreadyreserved > "0"){
- msg += (_("- This patron had already placed a hold on this item") + "\n" + _("Please cancel the previous hold first") + "\n");
+ if (msg == "") {
+ $('#hold-request-form').preventDoubleFormSubmit();
+ return(true);
+ } else {
+ alert(msg);
+ return(false);
}
-
- if (msg == "") return(true);
- else {
- alert(msg);
- return(false);
- }
}
function checkMultiHold() {
$("#multi_hold_bibs").val(biblionumbers);
$("#bad_bibs").val(badBibs);
+ $('#hold-request-form').preventDoubleFormSubmit();
+
return true;
}
$("#" + fieldID).val("");
});
- $('#hold-request-form').preventDoubleFormSubmit();
[% UNLESS ( borrowernumber || borrowers || noitems ) %]
[% IF ( CircAutocompl ) %]
[% IF ( exceeded_maxreserves ) %]
<li><strong>Too many holds: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %] </a> can only place a maximum of [% maxreserves %] total holds.</li>
[% ELSIF ( alreadypossession ) %]
- <li> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>is already in possession</strong> of one item</li>
+ <li> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>is already in possession</strong> of one item</lie
[% ELSIF ( alreadyreserved ) %]
<li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>already has a hold</strong> on this item </li>
[% ELSIF ( ageRestricted ) %]
</li>
[% UNLESS ( multi_hold ) %]
- <li> <label for="requestany">Place a hold on the next available item </label>
- <input type="checkbox" id="requestany" name="request" checked="checked" value="Any" />
+ <li> <label for="requestany">Hold next available item </label>
+ [% IF force_hold_level == 'item' %]
+ <input type="checkbox" id="requestany" name="request" disabled="true" />
+ [% ELSIF force_hold_level == 'record' %]
+ <input type="checkbox" id="requestany" checked="checked" value="Any" disabled="true"/>
+ <input type="hidden" name="request" value="Any"/>
+ [% ELSE %]
+ <input type="checkbox" id="requestany" name="request" checked="checked" value="Any" />
+ [% END %]
<input type="hidden" name="biblioitem" value="[% biblioitemnumber %]" />
<input type="hidden" name="alreadyreserved" value="[% alreadyreserved %]" />
</li>
+
+ [% IF max_holds_for_record > 1 %]
+ [% SET count = 1 %]
+ <li>
+ <label for="holds_to_place_count">Holds to place (count)</label>
+ <select name="holds_to_place_count" id="holds_to_place_count">
+ [% WHILE count <= max_holds_for_record %]
+ <option value="[% count %]">[% count %]</option>
+ [% SET count = count + 1 %]
+ [% END %]
+
+ </select>
+ </li>
+ [% ELSE %]
+ <input type="hidden" name="holds_to_place_count" value="1";
+ [% END %]
[% END %]
</ol>
[% IF ( bibitemloo.publicationyear ) %]<li><span class="label">Publication year:</span> [% bibitemloo.publicationyear %]</li>[% END %]
</ol>
- <h2 style="padding: 0 1em;">Place a hold on a specific item</h2>
+ <h2 style="padding: 0 1em;">
+ Place a hold on a specific item
+ [% IF bibitemloo.force_hold_level == 'item' %]
+ <span class="error"><i>(Required)</i></span>
+ [% END %]
+ </h2>
<table id="requestspecific">
<thead>
<tr>
</tr>
</thead>
<tbody>
+ [% SET selected = 0 %]
[% FOREACH itemloo IN bibitemloo.itemloop %]
[% UNLESS ( itemloo.hide ) %]
<tr class="[% itemloo.backgroundcolor %]">
<td>
- [% IF ( itemloo.available ) %]
+ [% IF itemloo.force_hold_level == 'record' # Patron has placed a record level hold previously for this record %]
+ <span class="error">
+ <i class="fa fa-times fa-lg" alt="Cannot be put on hold"></i>
+ Hold must be record level
+ </span>
+ [% ELSIF ( itemloo.available ) %]
<input type="radio" name="checkitem" value="[% itemloo.itemnumber %]" />
[% ELSIF ( itemloo.override ) %]
<input type="radio" name="checkitem" class="needsoverride" value="[% itemloo.itemnumber %]" />
- <img src="[% interface %]/[% theme %]/img/famfamfam/silk/error.png" alt="Requires override of hold policy" />
+ <i class="fa fa-exclamation-triangle fa-lg" style="color:gold" alt="Requires override of hold policy"/></i>
[% ELSE %]
- <input disabled="disabled" type="radio" name="checkitem" value="[% itemloo.itemnumber %]" />
- <img src="[% interface %]/[% theme %]/img/famfamfam/silk/cross.png" alt="Cannot be put on hold" />
+ <span class="error">
+ <i class="fa fa-times fa-lg" alt="Cannot be put on hold"></i>
+ [% IF itemloo.not_holdable %]
+ [% IF itemloo.not_holdable == 'damaged' %]
+ Item damaged
+ [% ELSIF itemloo.not_holdable == 'ageRestricted' %]
+ Age restricted
+ [% ELSIF itemloo.not_holdable == 'tooManyHoldsForThisRecord' %]
+ Exceeded max holds per record
+ [% ELSIF itemloo.not_holdable == 'tooManyReserves' %]
+ Too many holds
+ [% ELSIF itemloo.not_holdable == 'notReservable' %]
+ Not holdable
+ [% ELSIF itemloo.not_holdable == 'cannotReserveFromOtherBranches' %]
+ Patron is from different library
+ [% ELSIF itemloo.not_holdable == 'itemAlreadyOnHold' %]
+ Patron already has hold for this item
+ [% ELSE %]
+ [% itemloo.not_holdable %]
+ [% END %]
+ [% END %]
+ </span>
[% END %]
</td>
[% IF ( item_level_itypes ) %]
}
}
-foreach my $res (@reserves) {
- foreach my $biblionumber (@biblionumbers) {
- if ( $res->{'biblionumber'} == $biblionumber && $res->{'borrowernumber'} == $borrowernumber) {
-# $template->param( message => 1 );
-# $noreserves = 1;
-# $template->param( already_reserved => 1 );
- $biblioDataHash{$biblionumber}->{already_reserved} = 1;
- }
- }
-}
-
unless ($noreserves) {
$template->param( select_item_types => 1 );
}
# the item could be reserved for this borrower vi a host record, flag this
$reservedfor //= '';
- if ($reservedfor eq $borrowernumber){
- $itemLoopIter->{already_reserved} = 1;
- }
if ( defined $reservedate ) {
$itemLoopIter->{backgroundcolor} = 'reserved';
$itemLoopIter->{nocancel} = 1;
}
- # if the items belongs to a host record, show link to host record
- if ($itemInfo->{biblionumber} ne $biblioNum){
- $biblioLoopIter{hostitemsflag} = 1;
- $itemLoopIter->{hostbiblionumber} = $itemInfo->{biblionumber};
- $itemLoopIter->{hosttitle} = GetBiblioData($itemInfo->{biblionumber})->{title};
- }
+ # if the items belongs to a host record, show link to host record
+ if ( $itemInfo->{biblionumber} ne $biblioNum ) {
+ $biblioLoopIter{hostitemsflag} = 1;
+ $itemLoopIter->{hostbiblionumber} = $itemInfo->{biblionumber};
+ $itemLoopIter->{hosttitle} = GetBiblioData( $itemInfo->{biblionumber} )->{title};
+ }
# If there is no loan, return and transfer, we show a checkbox.
$itemLoopIter->{notforloan} = $itemLoopIter->{notforloan} || 0;
$biblioLoopIter{holdable} &&= CanBookBeReserved($borrowernumber,$biblioNum) eq 'OK';
+ # For multiple holds per record, if a patron has previously placed a hold,
+ # the patron can only place more holds of the same type. That is, if the
+ # patron placed a record level hold, all the holds the patron places must
+ # be record level. If the patron placed an item level hold, all holds
+ # the patron places must be item level
+ my $forced_hold_level = Koha::Holds->search(
+ {
+ borrowernumber => $borrowernumber,
+ biblionumber => $biblioNum,
+ found => undef,
+ }
+ )->forced_hold_level();
+ if ($forced_hold_level) {
+ $biblioLoopIter{force_hold} = 1 if $forced_hold_level eq 'item';
+ $biblioLoopIter{itemholdable} = 0 if $forced_hold_level eq 'record';
+ }
+
+
push @$biblioLoop, \%biblioLoopIter;
$anyholdable = 1 if $biblioLoopIter{holdable};
my $multi_hold = $input->param('multi_hold');
my $biblionumbers = $multi_hold ? $input->param('biblionumbers') : ($biblionumber . '/');
my $bad_bibs = $input->param('bad_bibs');
+my $holds_to_place_count = $input->param('holds_to_place_count') || 1;
my %bibinfos = ();
my @biblionumbers = split '/', $biblionumbers;
}
}
-if ($type eq 'str8' && $borrower){
+if ( $type eq 'str8' && $borrower ) {
- foreach my $biblionumber (keys %bibinfos) {
- my $count=@bibitems;
- @bibitems=sort @bibitems;
- my $i2=1;
+ 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];
+ $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++;
}
}
- if (defined $checkitem && $checkitem ne ''){
- my $item = GetItem($checkitem);
- if ($item->{'biblionumber'} ne $biblionumber) {
- $biblionumber = $item->{'biblionumber'};
- }
- }
-
-
+ if ( defined $checkitem && $checkitem ne '' ) {
+ my $item = GetItem($checkitem);
+ if ( $item->{'biblionumber'} ne $biblionumber ) {
+ $biblionumber = $item->{'biblionumber'};
+ }
+ }
if ($multi_hold) {
my $bibinfo = $bibinfos{$biblionumber};
$bibinfo->{rank},$startdate,$expirationdate,$notes,$bibinfo->{title},$checkitem,$found);
} else {
# place a request on 1st available
- AddReserve($branch,$borrower->{'borrowernumber'},$biblionumber,\@realbi,$rank[0],$startdate,$expirationdate,$notes,$title,$checkitem,$found, $itemtype);
+ for ( my $i = 0 ; $i < $holds_to_place_count ; $i++ ) {
+ AddReserve( $branch, $borrower->{'borrowernumber'},
+ $biblionumber, \@realbi, $rank[0], $startdate, $expirationdate, $notes, $title,
+ $checkitem, $found, $itemtype );
+ }
}
}
$biblionumbers .= $bad_bibs;
}
print $input->redirect("request.pl?biblionumbers=$biblionumbers&multi_hold=1");
- } else {
+ }
+ 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;
+}
+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;
}
=cut
-use strict;
-use warnings;
+use Modern::Perl;
+
use C4::Branch;
use CGI qw ( -utf8 );
use List::MoreUtils qw/uniq/;
$biblioloopiter{$canReserve} = 1;
}
- my $alreadypossession;
- if (not C4::Context->preference('AllowHoldsOnPatronsPossessions') and CheckIfIssuedToPatron($borrowerinfo->{borrowernumber},$biblionumber)) {
- $alreadypossession = 1;
+ my $force_hold_level;
+ if ( $borrowerinfo->{borrowernumber} ) {
+ # For multiple holds per record, if a patron has previously placed a hold,
+ # the patron can only place more holds of the same type. That is, if the
+ # patron placed a record level hold, all the holds the patron places must
+ # be record level. If the patron placed an item level hold, all holds
+ # the patron places must be item level
+ my $holds = Koha::Holds->search(
+ {
+ borrowernumber => $borrowerinfo->{borrowernumber},
+ biblionumber => $biblionumber,
+ found => undef,
+ }
+ );
+ $force_hold_level = $holds->forced_hold_level();
+ $biblioloopiter{force_hold_level} = $force_hold_level;
+ $template->param( force_hold_level => $force_hold_level );
+
+ # For a librarian to be able to place multiple record holds for a patron for a record,
+ # we must find out what the maximum number of holds they can place for the patron is
+ my $max_holds_for_record = GetMaxPatronHoldsForRecord( $borrowerinfo->{borrowernumber}, $biblionumber );
+ $max_holds_for_record = $max_holds_for_record - $holds->count();
+ $biblioloopiter{max_holds_for_record} = $max_holds_for_record;
+ $template->param( max_holds_for_record => $max_holds_for_record );
}
- # get existing reserves .....
- my $reserves = GetReservesFromBiblionumber({ biblionumber => $biblionumber, all_dates => 1 });
- my $count = scalar( @$reserves );
- my $totalcount = $count;
- my $holds_count = 0;
- my $alreadyreserved = 0;
-
- foreach my $res (@$reserves) {
- if ( defined $res->{found} ) { # found can be 'W' or 'T'
- $count--;
- }
-
- if ( defined $borrowerinfo && defined($borrowerinfo->{borrowernumber}) && ($borrowerinfo->{borrowernumber} eq $res->{borrowernumber}) ) {
- $holds_count++;
- }
+ # Check to see if patron is allowed to place holds on records where the
+ # patron already has an item from that record checked out
+ my $alreadypossession;
+ if ( !C4::Context->preference('AllowHoldsOnPatronsPossessions')
+ && CheckIfIssuedToPatron( $borrowerinfo->{borrowernumber}, $biblionumber ) )
+ {
+ $template->param( alreadypossession => $alreadypossession, );
}
- if ( $holds_count ) {
- $alreadyreserved = 1;
- $biblioloopiter{warn} = 1;
- $biblioloopiter{alreadyres} = 1;
- }
- $template->param(
- alreadyreserved => $alreadyreserved,
- alreadypossession => $alreadypossession,
- );
+ my $count = Koha::Holds->search( { biblionumber => $biblionumber } )->count();
+ my $totalcount = $count;
# FIXME think @optionloop, is maybe obsolete, or must be switchable by a systeme preference fixed rank or not
# make priorities options
my $num_override = 0;
my $hiddencount = 0;
+ $biblioitem->{force_hold_level} = $force_hold_level;
+
if ( $biblioitem->{biblioitemnumber} ne $biblionumber ) {
$biblioitem->{hostitemsflag} = 1;
}
foreach my $itemnumber ( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} } ) {
my $item = $iteminfos_of->{$itemnumber};
+ $item->{force_hold_level} = $force_hold_level;
+
unless (C4::Context->preference('item-level_itypes')) {
$item->{itype} = $biblioitem->{itemtype};
}
$item->{'holdallowed'} = $branchitemrule->{'holdallowed'};
+ my $can_item_be_reserved = CanItemBeReserved( $borrowerinfo->{borrowernumber}, $itemnumber );
+ $item->{not_holdable} = $can_item_be_reserved unless ( $can_item_be_reserved eq 'OK' );
+
if (
!$item->{cantreserve}
&& !$exceeded_maxreserves
&& IsAvailableForItemLevelRequest($item, $borrowerinfo)
- && CanItemBeReserved(
- $borrowerinfo->{borrowernumber}, $itemnumber
- ) eq 'OK'
+ && $can_item_be_reserved eq 'OK'
)
{
$item->{available} = 1;