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

Signed-off-by: Martin Renvoize <martin.renvoize@openfifth.co.uk>
This commit is contained in:
Nick Clemens 2026-02-09 15:41:25 +00:00 committed by Martin Renvoize
parent 2af497f1eb
commit 1f089c41c1
No known key found for this signature in database
GPG Key ID: 2D86E0EAEC83711B
1 changed files with 21 additions and 18 deletions

View File

@ -1709,13 +1709,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);
@ -1734,6 +1734,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
@ -1743,33 +1759,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