X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FReserves.pm;h=503771e914e9786779956d4215ad4f2741fa7f9a;hb=4fcf7af117153690cc4aca55eb47290dfc5814f6;hp=3c3e15831ee6862ca1c25ee4529d39546259417b;hpb=fb0ab55fd09457a4d7559d2af9774de9456bb2f2;p=koha-ffzg.git diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 3c3e15831e..503771e914 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -21,38 +21,35 @@ package C4::Reserves; # along with Koha; if not, see . -use strict; -#use warnings; FIXME - Bug 2505 -use C4::Context; +use Modern::Perl; + +use C4::Accounts; use C4::Biblio; -use C4::Members; -use C4::Items; use C4::Circulation; -use C4::Accounts; - -# for _koha_notify_reserve -use C4::Members::Messaging; -use C4::Members qw(); +use C4::Context; +use C4::Items; use C4::Letters; use C4::Log; - +use C4::Members::Messaging; +use C4::Members; +use Koha::Account::Lines; use Koha::Biblios; -use Koha::DateUtils; use Koha::Calendar; +use Koha::CirculationRules; use Koha::Database; +use Koha::DateUtils; use Koha::Hold; -use Koha::Old::Hold; use Koha::Holds; -use Koha::Libraries; use Koha::IssuingRules; -use Koha::Items; use Koha::ItemTypes; +use Koha::Items; +use Koha::Libraries; +use Koha::Old::Hold; use Koha::Patrons; -use Koha::CirculationRules; -use List::MoreUtils qw( firstidx any ); use Carp; use Data::Dumper; +use List::MoreUtils qw( firstidx any ); use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); @@ -175,9 +172,25 @@ sub AddReserve { # if we have an item selectionned, and the pickup branch is the same as the holdingbranch # of the document, we force the value $priority and $found . if ( $checkitem and not C4::Context->preference('ReservesNeedReturns') ) { - $priority = 0; my $item = Koha::Items->find( $checkitem ); # FIXME Prevent bad calls - if ( $item->holdingbranch eq $branch ) { + + if ( + # If item is already checked out, it cannot be set waiting + !$item->onloan + + # The item can't be waiting if it needs a transfer + && $item->holdingbranch eq $branch + + # Similarly, if in transit it can't be waiting + && !$item->get_transfer + + # If we can't hold damaged items, and it is damaged, it can't be waiting + && ( $item->damaged && C4::Context->preference('AllowHoldsOnDamagedItems') || !$item->damaged ) + + # Lastly, if this already has holds, we shouldn't make it waiting for the new hold + && !$item->current_holds->count ) + { + $priority = 0; $found = 'W'; } } @@ -191,7 +204,7 @@ sub AddReserve { my $waitingdate; # If the reserv had the waiting status, we had the value of the resdate - if ( $found eq 'W' ) { + if ( $found && $found eq 'W' ) { $waitingdate = $resdate; } @@ -212,9 +225,10 @@ sub AddReserve { waitingdate => $waitingdate, expirationdate => $expdate, itemtype => $itemtype, + item_level_hold => $checkitem ? 1 : 0, } )->store(); - $hold->set_waiting() if $found eq 'W'; + $hold->set_waiting() if $found && $found eq 'W'; logaction( 'HOLDS', 'CREATE', $hold->id, Dumper($hold->unblessed) ) if C4::Context->preference('HoldsLog'); @@ -283,7 +297,7 @@ sub CanBookBeReserved{ push (@itemnumbers, @hostitems); } - my $canReserve; + my $canReserve = { status => '' }; foreach my $itemnumber (@itemnumbers) { $canReserve = CanItemBeReserved( $borrowernumber, $itemnumber, $pickup_branchcode ); return { status => 'OK' } if $canReserve->{status} eq 'OK'; @@ -300,10 +314,13 @@ sub CanBookBeReserved{ { status => ageRestricted }, if the Item is age restricted for this borrower. { status => damaged }, if the Item is damaged. { status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK. + { status => branchNotInHoldGroup }, if borrower home library is not in hold group, and holds are only allowed from hold groups. { status => tooManyReserves, limit => $limit }, if the borrower has exceeded their maximum reserve amount. { status => notReservable }, if holds on this item are not allowed { status => libraryNotFound }, if given branchcode is not an existing library { status => libraryNotPickupLocation }, if given branchcode is not configured to be a pickup location + { status => cannotBeTransferred }, if branch transfer limit applies on given item and branchcode + { status => pickupNotInHoldGroup }, pickup location is not in hold group, and pickup locations are only allowed from hold groups. =cut @@ -314,18 +331,18 @@ sub CanItemBeReserved { my $ruleitemtype; # itemtype of the matching issuing rule 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 - my $holds_per_day = 0; # Total number of holds allowed per day for the given patron + my $holds_per_day; # Default to unlimited # we retrieve borrowers and items informations # # item->{itype} will come for biblioitems if necessery - my $item = C4::Items::GetItem($itemnumber); - my $biblio = Koha::Biblios->find( $item->{biblionumber} ); + my $item = Koha::Items->find($itemnumber); + my $biblio = $item->biblio; my $patron = Koha::Patrons->find( $borrowernumber ); my $borrower = $patron->unblessed; # If an item is damaged and we don't allow holds on damaged items, we can stop right here return { status =>'damaged' } - if ( $item->{damaged} + if ( $item->damaged && !C4::Context->preference('AllowHoldsOnDamagedItems') ); # Check for the age restriction @@ -353,7 +370,7 @@ sub CanItemBeReserved { if ( $controlbranch eq "ItemHomeLibrary" ) { $branchfield = "items.homebranch"; - $branchcode = $item->{homebranch}; + $branchcode = $item->homebranch; } elsif ( $controlbranch eq "PatronLibrary" ) { $branchfield = "borrowers.branchcode"; @@ -361,7 +378,7 @@ sub CanItemBeReserved { } # we retrieve rights - if ( my $rights = GetHoldRule( $borrower->{'categorycode'}, $item->{'itype'}, $branchcode ) ) { + if ( my $rights = GetHoldRule( $borrower->{'categorycode'}, $item->effective_itemtype, $branchcode ) ) { $ruleitemtype = $rights->{itemtype}; $allowedreserves = $rights->{reservesallowed}; $holds_per_record = $rights->{holds_per_record}; @@ -371,7 +388,6 @@ sub CanItemBeReserved { $ruleitemtype = '*'; } - $item = Koha::Items->find( $itemnumber ); my $holds = Koha::Holds->search( { borrowernumber => $borrowernumber, @@ -397,7 +413,7 @@ sub CanItemBeReserved { # we retrieve count - $querycount .= "AND $branchfield = ?"; + $querycount .= "AND ( $branchfield = ? OR $branchfield IS NULL )"; # If using item-level itypes, fall back to the record # level itemtype if the hold has no associated item @@ -444,10 +460,10 @@ sub CanItemBeReserved { return { status => 'tooManyReserves', limit => $rule->rule_value} if $total_holds_count >= $rule->rule_value; } - my $circ_control_branch = - C4::Circulation::_GetCircControlBranch( $item->unblessed(), $borrower ); + my $reserves_control_branch = + GetReservesControlBranch( $item->unblessed(), $borrower ); my $branchitemrule = - C4::Circulation::GetBranchItemRule( $circ_control_branch, $item->itype ); + C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->itype ); # FIXME Should not be item->effective_itemtype? if ( $branchitemrule->{holdallowed} == 0 ) { return { status => 'notReservable' }; @@ -459,13 +475,19 @@ sub CanItemBeReserved { return { status => 'cannotReserveFromOtherBranches' }; } + my $item_library = Koha::Libraries->find( {branchcode => $item->homebranch} ); + if ( $branchitemrule->{holdallowed} == 3) { + if($borrower->{branchcode} ne $item->homebranch && !$item_library->validate_hold_sibling( {branchcode => $borrower->{branchcode}} )) { + return { status => 'branchNotInHoldGroup' }; + } + } + # If reservecount is ok, we check item branch if IndependentBranches is ON # and canreservefromotherbranches is OFF if ( C4::Context->preference('IndependentBranches') and !C4::Context->preference('canreservefromotherbranches') ) { - my $itembranch = $item->homebranch; - if ( $itembranch ne $borrower->{branchcode} ) { + if ( $item->homebranch ne $borrower->{branchcode} ) { return { status => 'cannotReserveFromOtherBranches' }; } } @@ -474,12 +496,22 @@ sub CanItemBeReserved { my $destination = Koha::Libraries->find({ branchcode => $pickup_branchcode, }); + unless ($destination) { return { status => 'libraryNotFound' }; } unless ($destination->pickup_location) { return { status => 'libraryNotPickupLocation' }; } + unless ($item->can_be_transferred({ to => $destination })) { + return { status => 'cannotBeTransferred' }; + } + unless ($branchitemrule->{hold_fulfillment_policy} ne 'holdgroup' || $item_library->validate_hold_sibling( {branchcode => $pickup_branchcode} )) { + return { status => 'pickupNotInHoldGroup' }; + } + unless ($branchitemrule->{hold_fulfillment_policy} ne 'patrongroup' || Koha::Libraries->find({branchcode => $borrower->{branchcode}})->validate_hold_sibling({branchcode => $pickup_branchcode})) { + return { status => 'pickupNotInHoldGroup' }; + } } return { status => 'OK' }; @@ -522,8 +554,8 @@ sub GetOtherReserves { my $nextreservinfo; my ( undef, $checkreserves, undef ) = CheckReserves($itemnumber); if ($checkreserves) { - my $iteminfo = GetItem($itemnumber); - if ( $iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'} ) { + my $item = Koha::Items->find($itemnumber); + if ( $item->holdingbranch ne $checkreserves->{'branchcode'} ) { $messages->{'transfert'} = $checkreserves->{'branchcode'}; #minus priorities of others reservs ModReserveMinusPriority( @@ -534,7 +566,7 @@ sub GetOtherReserves { #launch the subroutine dotransfer C4::Items::ModItemTransfer( $itemnumber, - $iteminfo->{'holdingbranch'}, + $item->holdingbranch, $checkreserves->{'branchcode'} ), ; @@ -566,13 +598,20 @@ sub GetOtherReserves { sub ChargeReserveFee { my ( $borrowernumber, $fee, $title ) = @_; - return if !$fee || $fee==0; # the last test is needed to include 0.00 - my $accquery = qq{ -INSERT INTO accountlines ( borrowernumber, accountno, date, amount, description, accounttype, amountoutstanding ) VALUES (?, ?, NOW(), ?, ?, 'Res', ?) - }; - my $dbh = C4::Context->dbh; - my $nextacctno = &getnextacctno( $borrowernumber ); - $dbh->do( $accquery, undef, ( $borrowernumber, $nextacctno, $fee, "Reserve Charge - $title", $fee ) ); + return if !$fee || $fee == 0; # the last test is needed to include 0.00 + Koha::Account->new( { patron_id => $borrowernumber } )->add_debit( + { + amount => $fee, + description => $title, + note => undef, + user_id => C4::Context->userenv ? C4::Context->userenv->{'number'} : undef, + library_id => C4::Context->userenv ? C4::Context->userenv->{'branch'} : undef, + interface => C4::Context->interface, + invoice_type => undef, + type => 'RESERVE', + item_id => undef + } + ); } =head2 GetReserveFee @@ -654,9 +693,9 @@ sub GetReserveStatus { =head2 CheckReserves - ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber); - ($status, $reserve, $all_reserves) = &CheckReserves(undef, $barcode); - ($status, $reserve, $all_reserves) = &CheckReserves($itemnumber,undef,$lookahead); + ($status, $matched_reserve, $possible_reserves) = &CheckReserves($itemnumber); + ($status, $matched_reserve, $possible_reserves) = &CheckReserves(undef, $barcode); + ($status, $matched_reserve, $possible_reserves) = &CheckReserves($itemnumber,undef,$lookahead); Find a book in the reserves. @@ -727,11 +766,9 @@ sub CheckReserves { } # note: we get the itemnumber because we might have started w/ just the barcode. Now we know for sure we have it. my ( $biblio, $bibitem, $notforloan_per_itemtype, $notforloan_per_item, $itemnumber, $damaged, $item_homebranch, $item_holdingbranch ) = $sth->fetchrow_array; - return if ( $damaged && !C4::Context->preference('AllowHoldsOnDamagedItems') ); return unless $itemnumber; # bail if we got nothing. - # if item is not for loan it cannot be reserved either..... # except where items.notforloan < 0 : This indicates the item is holdable. return if ( $notforloan_per_item > 0 ) or $notforloan_per_itemtype; @@ -759,15 +796,15 @@ sub CheckReserves { } } else { my $patron; - my $iteminfo; + my $item; my $local_hold_match; if ($LocalHoldsPriority) { $patron = Koha::Patrons->find( $res->{borrowernumber} ); - $iteminfo = C4::Items::GetItem($itemnumber); + $item = Koha::Items->find($itemnumber); my $local_holds_priority_item_branchcode = - $iteminfo->{$LocalHoldsPriorityItemControl}; + $item->$LocalHoldsPriorityItemControl; my $local_holds_priority_patron_branchcode = ( $LocalHoldsPriorityPatronControl eq 'PickupLibrary' ) ? $res->{branchcode} @@ -781,14 +818,20 @@ sub CheckReserves { # See if this item is more important than what we've got so far if ( ( $res->{'priority'} && $res->{'priority'} < $priority ) || $local_hold_match ) { - $iteminfo ||= C4::Items::GetItem($itemnumber); - next if $res->{itemtype} && $res->{itemtype} ne _get_itype( $iteminfo ); + $item ||= Koha::Items->find($itemnumber); + next if $res->{itemtype} && $res->{itemtype} ne $item->effective_itemtype; $patron ||= Koha::Patrons->find( $res->{borrowernumber} ); - my $branch = GetReservesControlBranch( $iteminfo, $patron->unblessed ); - my $branchitemrule = C4::Circulation::GetBranchItemRule($branch,$iteminfo->{'itype'}); + my $branch = GetReservesControlBranch( $item->unblessed, $patron->unblessed ); + my $branchitemrule = C4::Circulation::GetBranchItemRule($branch,$item->effective_itemtype); next if ($branchitemrule->{'holdallowed'} == 0); next if (($branchitemrule->{'holdallowed'} == 1) && ($branch ne $patron->branchcode)); - next if ( ($branchitemrule->{hold_fulfillment_policy} ne 'any') && ($res->{branchcode} ne $iteminfo->{ $branchitemrule->{hold_fulfillment_policy} }) ); + my $library = Koha::Libraries->find({branchcode=>$item->homebranch}); + next if (($branchitemrule->{'holdallowed'} == 3) && (!$library->validate_hold_sibling({branchcode => $patron->branchcode}) )); + my $hold_fulfillment_policy = $branchitemrule->{hold_fulfillment_policy}; + next if ( ($hold_fulfillment_policy eq 'holdgroup') && (!$library->validate_hold_sibling({branchcode => $res->{branchcode}})) ); + next if ( ($hold_fulfillment_policy eq 'homebranch') && ($res->{branchcode} ne $item->$hold_fulfillment_policy) ); + next if ( ($hold_fulfillment_policy eq 'holdingbranch') && ($res->{branchcode} ne $item->$hold_fulfillment_policy) ); + next unless $item->can_be_transferred( { to => scalar Koha::Libraries->find( $res->{branchcode} ) } ); $priority = $res->{'priority'}; $highest = $res; last if $local_hold_match; @@ -822,7 +865,7 @@ sub CancelExpiredReserves { my $dtf = Koha::Database->new->schema->storage->datetime_parser; my $params = { expirationdate => { '<', $dtf->format_date($today) } }; - $params->{found} = undef unless $expireWaiting; + $params->{found} = [ { '!=', 'W' }, undef ] unless $expireWaiting; # FIXME To move to Koha::Holds->search_expired (?) my $holds = Koha::Holds->search( $params ); @@ -853,7 +896,7 @@ sub AutoUnsuspendReserves { my @holds = Koha::Holds->search( { suspend_until => { '<=' => $today->ymd() } } ); - map { $_->suspend(0)->suspend_until(undef)->store() } @holds; + map { $_->resume() } @holds; } =head2 ModReserve @@ -925,15 +968,21 @@ sub ModReserve { logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, Dumper($hold->unblessed) ) if C4::Context->preference('HoldsLog'); - $hold->set( - { - priority => $rank, - branchcode => $branchcode, - itemnumber => $itemnumber, - found => undef, - waitingdate => undef - } - )->store(); + my $properties = { + priority => $rank, + branchcode => $branchcode, + itemnumber => $itemnumber, + found => undef, + waitingdate => undef + }; + if (exists $params->{reservedate}) { + $properties->{reservedate} = $params->{reservedate} || undef; + } + if (exists $params->{expirationdate}) { + $properties->{expirationdate} = $params->{expirationdate} || undef; + } + + $hold->set($properties)->store(); if ( defined( $suspend_until ) ) { if ( $suspend_until ) { @@ -967,7 +1016,6 @@ sub ModReserveFill { my $reserve_id = $res->{'reserve_id'}; my $hold = Koha::Holds->find($reserve_id); - # get the priority on this record.... my $priority = $hold->priority; @@ -1018,7 +1066,10 @@ sub ModReserveStatus { my $sth_set = $dbh->prepare($query); $sth_set->execute( $newstatus, $itemnumber ); - if ( C4::Context->preference("ReturnToShelvingCart") && $newstatus ) { + my $item = Koha::Items->find($itemnumber); + if ( $item->location && $item->location eq 'CART' + && ( !$item->permanent_location || $item->permanent_location ne 'CART' ) + && $newstatus ) { CartToShelf( $itemnumber ); } } @@ -1070,9 +1121,10 @@ sub ModReserveAffect { if ( !$transferToDo && !$already_on_shelf ); _FixPriority( { biblionumber => $biblionumber } ); - - if ( C4::Context->preference("ReturnToShelvingCart") ) { - CartToShelf($itemnumber); + my $item = Koha::Items->find($itemnumber); + if ( $item->location && $item->location eq 'CART' + && ( !$item->permanent_location || $item->permanent_location ne 'CART' ) ) { + CartToShelf( $itemnumber ); } return; @@ -1128,7 +1180,7 @@ sub ModReserveMinusPriority { =head2 IsAvailableForItemLevelRequest - my $is_available = IsAvailableForItemLevelRequest($item_record,$borrower_record); + my $is_available = IsAvailableForItemLevelRequest( $item_record, $borrower_record, $pickup_branchcode ); Checks whether a given item record is available for an item-level hold request. An item is available if @@ -1151,42 +1203,51 @@ and canreservefromotherbranches. =cut sub IsAvailableForItemLevelRequest { - my $item = shift; - my $borrower = shift; + my ( $item, $patron, $pickup_branchcode ) = @_; my $dbh = C4::Context->dbh; # must check the notforloan setting of the itemtype # FIXME - a lot of places in the code do this # or something similar - need to be # consolidated - my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ); - my $item_object = Koha::Items->find( $item->{itemnumber } ); - my $itemtype = $item_object->effective_itemtype; - my $notforloan_per_itemtype - = $dbh->selectrow_array("SELECT notforloan FROM itemtypes WHERE itemtype = ?", - undef, $itemtype); + my $itemtype = $item->effective_itemtype; + my $notforloan_per_itemtype = Koha::ItemTypes->find($itemtype)->notforloan; return 0 if $notforloan_per_itemtype || - $item->{itemlost} || - $item->{notforloan} > 0 || - $item->{withdrawn} || - ($item->{damaged} && !C4::Context->preference('AllowHoldsOnDamagedItems')); + $item->itemlost || + $item->notforloan > 0 || + $item->withdrawn || + ($item->damaged && !C4::Context->preference('AllowHoldsOnDamagedItems')); - my $on_shelf_holds = Koha::IssuingRules->get_onshelfholds_policy( { item => $item_object, patron => $patron } ); + my $on_shelf_holds = Koha::IssuingRules->get_onshelfholds_policy( { item => $item, patron => $patron } ); + + if ($pickup_branchcode) { + my $destination = Koha::Libraries->find($pickup_branchcode); + return 0 unless $destination; + return 0 unless $destination->pickup_location; + return 0 unless $item->can_be_transferred( { to => $destination } ); + my $reserves_control_branch = + GetReservesControlBranch( $item->unblessed(), $patron->unblessed() ); + my $branchitemrule = + C4::Circulation::GetBranchItemRule( $reserves_control_branch, $item->itype ); + my $home_library = Koka::Libraries->find( {branchcode => $item->homebranch} ); + return 0 unless $branchitemrule->{hold_fulfillment_policy} ne 'holdgroup' || $home_library->validate_hold_sibling( {branchcode => $pickup_branchcode} ); + } if ( $on_shelf_holds == 1 ) { return 1; } elsif ( $on_shelf_holds == 2 ) { my @items = - Koha::Items->search( { biblionumber => $item->{biblionumber} } ); + Koha::Items->search( { biblionumber => $item->biblionumber } ); my $any_available = 0; foreach my $i (@items) { + my $reserves_control_branch = GetReservesControlBranch( $i->unblessed(), $patron->unblessed ); + my $branchitemrule = C4::Circulation::GetBranchItemRule( $reserves_control_branch, $i->itype ); + my $item_library = Koha::Libraries->find( {branchcode => $i->homebranch} ); - my $circ_control_branch = C4::Circulation::_GetCircControlBranch( $i->unblessed(), $borrower ); - my $branchitemrule = C4::Circulation::GetBranchItemRule( $circ_control_branch, $i->itype ); $any_available = 1 unless $i->itemlost @@ -1197,12 +1258,13 @@ sub IsAvailableForItemLevelRequest { || ( $i->damaged && !C4::Context->preference('AllowHoldsOnDamagedItems') ) || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan - || $branchitemrule->{holdallowed} == 1 && $borrower->{branchcode} ne $i->homebranch; + || $branchitemrule->{holdallowed} == 1 && $patron->branchcode ne $i->homebranch + || $branchitemrule->{holdallowed} == 3 && !$item_library->validate_hold_sibling( {branchcode => $patron->branchcode} ); } return $any_available ? 0 : 1; } else { # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved) - return $item->{onloan} || IsItemOnHoldAndFound( $item->{itemnumber} ); + return $item->onloan || IsItemOnHoldAndFound( $item->itemnumber ); } } @@ -1413,7 +1475,7 @@ sub _FixPriority { if ( $rank eq "del" ) { # FIXME will crash if called without $hold $hold->cancel; } - elsif ( $rank eq "W" || $rank eq "0" ) { + elsif ( $reserve_id && ( $rank eq "W" || $rank eq "0" ) ) { # make sure priority for waiting or in-transit items is 0 my $query = " @@ -1441,11 +1503,12 @@ sub _FixPriority { push( @priority, $line ); } + # FIXME This whole sub must be rewritten, especially to highlight what is done when reserve_id is not given # To find the matching index my $i; my $key = -1; # to allow for 0 to be a valid result for ( $i = 0 ; $i < @priority ; $i++ ) { - if ( $reserve_id == $priority[$i]->{'reserve_id'} ) { + if ( $reserve_id && $reserve_id == $priority[$i]->{'reserve_id'} ) { $key = $i; # save the index last; } @@ -1500,6 +1563,13 @@ C<@results> is an array of references-to-hash whose keys are mostly fields from the reserves table of the Koha database, plus C. +This routine with either return: +1 - Item specific holds from the holds queue +2 - Title level holds from the holds queue +3 - All holds for this biblionumber + +All return values will respect any borrowernumbers passed as arrayref in $ignore_borrowers + =cut sub _Findgroupreserve { @@ -1768,7 +1838,7 @@ sub MoveReserve { my ( $itemnumber, $borrowernumber, $cancelreserve ) = @_; my $lookahead = C4::Context->preference('ConfirmFutureHolds'); #number of days to look for future holds - my ( $restype, $res, $all_reserves ) = CheckReserves( $itemnumber, undef, $lookahead ); + my ( $restype, $res, undef ) = CheckReserves( $itemnumber, undef, $lookahead ); return unless $res; my $biblionumber = $res->{biblionumber}; @@ -1781,18 +1851,16 @@ sub MoveReserve { # The item is reserved by someone else. # Find this item in the reserves - my $borr_res; - foreach (@$all_reserves) { - $_->{'borrowernumber'} == $borrowernumber or next; - $_->{'biblionumber'} == $biblionumber or next; - - $borr_res = $_; - last; - } + my $borr_res = Koha::Holds->search({ + borrowernumber => $borrowernumber, + biblionumber => $biblionumber, + },{ + order_by => 'priority' + })->next(); if ( $borr_res ) { # The item is reserved by the current patron - ModReserveFill($borr_res); + ModReserveFill($borr_res->unblessed); } if ( $cancelreserve eq 'revert' ) { ## Revert waiting reserve to priority 1 @@ -1881,6 +1949,8 @@ sub RevertWaitingStatus { $sth->execute( $itemnumber ); my $reserve = $sth->fetchrow_hashref(); + my $hold = Koha::Holds->find( $reserve->{reserve_id} ); # TODO Remove the next raw SQL statements and use this instead + ## Increment the priority of all other non-waiting ## reserves for this bib record $query = " @@ -1907,6 +1977,11 @@ sub RevertWaitingStatus { "; $sth = $dbh->prepare( $query ); $sth->execute( $reserve->{'reserve_id'} ); + + unless ( $hold->item_level_hold ) { + $hold->itemnumber(undef)->store; + } + _FixPriority( { biblionumber => $reserve->{biblionumber} } ); }