From a6add45455ad4d7a4e011ae34f72e880fffe5354 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Mon, 9 Feb 2026 15:41:25 +0000 Subject: [PATCH] Bug 41801: Remove recursive calls from FixPriority This patch removes the recursive calls that set each 'lowestPriority' hold to the bottom of the priority list and replaces it them by simply ordering the list of 'remaining' holds by lowestPriorty, then priority. A check is also added to ensure that if a lowestPriority hold is being adjusted, it cannot be moved above holds not marked as lowest priority. To test: 1 - Place many holds on a record, 50 - 150 https://github.com/kidclamp/handy-koha-script/blob/main/randhold.pl This will randomly make some of the holds lowest priority 2 - View the record in the staff interface: http://localhost:8081/cgi-bin/koha/catalogue/detail.pl?biblionumber=312 3 - Click on the 'Holds' tab 4 - Adjust the priority of several holds using the dropdowns 5 - Note the timing 6 - Apply the patch 7 - Adjust the priority of several holds using the dropdowns 8 - Confirm the timing is improved 9 - Confirm that holds adjust as expected 10 - Confirm you cannot move a lowest priority hold above a hold not marked lowest priority 11 - Confirm holds move correctly on a record where all holds are lowestPriority 12 - Confirm holds move correctly on a record where no holds are lowestPriority --- C4/Reserves.pm | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 9bbeabadec9..8e278eb516b 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -1788,13 +1788,13 @@ sub FixPriority { } my @priority; - # get what's left + # get what's left, sorting lowestPriority holds to the bottom my $query = " SELECT reserve_id, borrowernumber, reservedate FROM reserves WHERE biblionumber = ? AND ((found <> 'W' AND found <> 'T' AND found <> 'P') OR found IS NULL) - ORDER BY priority ASC + ORDER BY lowestPriority ASC, priority ASC "; my $sth = $dbh->prepare($query); $sth->execute($biblionumber); @@ -1813,6 +1813,22 @@ sub FixPriority { } } + # if this hold is marked lowest priority, we can only move it so far + if ( $hold && $hold->lowestPriority && $rank ne 'del' ) { + my $query = " + SELECT max(priority) + FROM reserves + WHERE biblionumber = ? + AND ((found <> 'W' AND found <> 'T' AND found <> 'P') OR found IS NULL) + AND lowestPriority = 0; + "; + my $sth = $dbh->prepare($query); + $sth->execute($biblionumber); + my ($highest_non_lowest_priority) = $sth->fetchrow_array(); + $rank = $highest_non_lowest_priority + 1 + if ( $highest_non_lowest_priority && $rank <= $highest_non_lowest_priority ); + } + # if index exists in array then move it to new position if ( $key > -1 && $rank ne 'del' && $rank > 0 ) { my $new_rank = $rank - 1; # $new_rank is what you want the new index to be in the array @@ -1822,33 +1838,20 @@ sub FixPriority { } # now fix the priority on those that are left.... + # only updating if changed $query = " UPDATE reserves SET priority = ? - WHERE reserve_id = ? + WHERE reserve_id = ? AND priority != ? "; $sth = $dbh->prepare($query); for ( my $j = 0 ; $j < @priority ; $j++ ) { $sth->execute( $j + 1, - $priority[$j]->{'reserve_id'} + $priority[$j]->{'reserve_id'}, $j + 1 ); } - unless ($ignoreSetLowestRank) { - $sth = $dbh->prepare( - "SELECT reserve_id FROM reserves WHERE lowestPriority = 1 AND biblionumber = ? ORDER BY priority"); - $sth->execute($biblionumber); - while ( my $res = $sth->fetchrow_hashref() ) { - FixPriority( - { - reserve_id => $res->{'reserve_id'}, - rank => '999999', - ignoreSetLowestRank => 1 - } - ); - } - } } =head2 _Findgroupreserve -- 2.39.5