From 4b1f240358ae1593af2afabc8de2d11d802cc7f7 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Fri, 30 Aug 2024 12:33:56 +0000 Subject: [PATCH] Bug 37774: Make MoveReserve check for patron holds even if none found by CheckReserve This patch moves the check for a patron's holds so that even if CheckReserve does not find the hold due to hold policies it can still be filled. The check will respect 'ConfirmFutureHolds' as per existing tests 1 - Set a "Default holds policy by item type" rule on "Mixed materials" to "No holds allowed" 2 - Add a Mixed Materials item on a record with items of 'Book' item types that are holdable 3 - Place a hold for a patron 4 - Check out the 'Mixed material' book to the patron (they are allowed to borrow these materials) 5 - The hold is not marked filled! Boo 6 - Check in the item and check out again 7 - The hold is filled! Yay 8 - Place another hold for the patron, with a future date set 9 - Checkout the item 10 - The hold is not filled! Yay 11 - Set 'ConfirmFutureHolds' to include the future hold placed above 12 - Checkin and checkout the item 13 - The hold is filled! Yay --- C4/Reserves.pm | 57 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index bc96dc9c3c1..21c1e4a4aea 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -2001,38 +2001,45 @@ sub MoveReserve { $cancelreserve //= 0; - my $lookahead = C4::Context->preference('ConfirmFutureHolds'); #number of days to look for future holds - my $item = Koha::Items->find($itemnumber); + my $lookahead = C4::Context->preference('ConfirmFutureHolds'); #number of days to look for future holds + my $item = Koha::Items->find($itemnumber); + my $biblionumber = $item->biblionumber; + + my $borr_res; my ( $restype, $res, undef ) = CheckReserves( $item, $lookahead ); - return unless $res; - my $biblionumber = $res->{biblionumber}; + # CheckReserves will only find holds that respect hold policies + # so we must check for forced holds if no reserve was found + if( !$res || $res->{borrowernumber} != $borrowernumber ) { + my $resdate = dt_from_string(); + $resdate->add_duration( DateTime::Duration->new( days => $lookahead ) ); + + $borr_res = Koha::Holds->search( + { + borrowernumber => $borrowernumber, + biblionumber => $biblionumber, + reservedate => { '<=' => output_pref({ dt => $resdate, dateonly => 1, dateformat => 'iso' }) } + }, + { order_by => 'priority' } + )->next(); + + # The item is reserved by the current patron + $borr_res->fill( { item_id => $itemnumber } ) if ($borr_res); - if ($res->{borrowernumber} == $borrowernumber) { - my $hold = Koha::Holds->find( $res->{reserve_id} ); - $hold->fill({ item_id => $itemnumber }); } - else { - # warn "Reserved"; - # The item is reserved by someone else. - # Find this item in the reserves + return unless $res; - my $borr_res = Koha::Holds->search({ - borrowernumber => $borrowernumber, - biblionumber => $biblionumber, - },{ - order_by => 'priority' - })->next(); + if ( $res && $res->{borrowernumber} == $borrowernumber ) { + my $hold = Koha::Holds->find( $res->{reserve_id} ); + $hold->fill( { item_id => $itemnumber } ); + } else { - if ( $borr_res ) { - # The item is reserved by the current patron - $borr_res->fill({ item_id => $itemnumber }); - } + # The item is reserved by someone else. + # Find this item in the reserves - if ( $cancelreserve eq 'revert' ) { ## Revert waiting reserve to priority 1 - RevertWaitingStatus({ itemnumber => $itemnumber }); - } - elsif ( $cancelreserve eq 'cancel' || $cancelreserve ) { # cancel reserves on this item + if ( $cancelreserve eq 'revert' ) { ## Revert waiting reserve to priority 1 + RevertWaitingStatus( { itemnumber => $itemnumber } ); + } elsif ( $cancelreserve eq 'cancel' || $cancelreserve ) { # cancel reserves on this item my $hold = Koha::Holds->find( $res->{reserve_id} ); $hold->cancel; } -- 2.39.2