|
Lines 1662-1762
priority adjusted to ensure that they remain at the end of the line.
Link Here
|
| 1662 |
=cut |
1662 |
=cut |
| 1663 |
|
1663 |
|
| 1664 |
sub FixPriority { |
1664 |
sub FixPriority { |
| 1665 |
my ($params) = @_; |
1665 |
my ($params) = @_; |
| 1666 |
my $reserve_id = $params->{reserve_id}; |
|
|
| 1667 |
my $rank = $params->{rank} // ''; |
| 1668 |
my $biblionumber = $params->{biblionumber}; |
| 1669 |
|
| 1670 |
my $dbh = C4::Context->dbh; |
| 1671 |
|
1666 |
|
| 1672 |
my $hold; |
1667 |
Koha::Database->new->schema->txn_do( |
| 1673 |
if ($reserve_id) { |
1668 |
sub { |
| 1674 |
$hold = Koha::Holds->find($reserve_id); |
1669 |
my $reserve_id = $params->{reserve_id}; |
| 1675 |
if ( !defined $hold ) { |
1670 |
my $rank = $params->{rank} // ''; |
|
|
1671 |
my $biblionumber = $params->{biblionumber}; |
| 1676 |
|
1672 |
|
| 1677 |
# may have already been checked out and hold fulfilled |
1673 |
my $dbh = C4::Context->dbh; |
| 1678 |
require Koha::Old::Holds; |
|
|
| 1679 |
$hold = Koha::Old::Holds->find($reserve_id); |
| 1680 |
} |
| 1681 |
return unless $hold; |
| 1682 |
} |
| 1683 |
|
1674 |
|
| 1684 |
unless ($biblionumber) { # FIXME This is a very weird API |
1675 |
my $hold; |
| 1685 |
$biblionumber = $hold->biblionumber; |
1676 |
if ($reserve_id) { |
| 1686 |
} |
1677 |
$hold = Koha::Holds->find($reserve_id); |
|
|
1678 |
if ( !defined $hold ) { |
| 1687 |
|
1679 |
|
| 1688 |
if ( $rank eq "del" ) { # FIXME will crash if called without $hold |
1680 |
# may have already been checked out and hold fulfilled |
| 1689 |
$hold->cancel; |
1681 |
require Koha::Old::Holds; |
| 1690 |
} elsif ( $reserve_id && ( $rank eq "W" || $rank eq "0" ) ) { |
1682 |
$hold = Koha::Old::Holds->find($reserve_id); |
| 1691 |
|
1683 |
} |
| 1692 |
# make sure priority for waiting or in-transit items is 0 |
1684 |
return unless $hold; |
| 1693 |
my $query = " |
1685 |
} |
| 1694 |
UPDATE reserves |
|
|
| 1695 |
SET priority = 0 |
| 1696 |
WHERE reserve_id = ? |
| 1697 |
AND found IN ('W', 'T', 'P') |
| 1698 |
"; |
| 1699 |
my $sth = $dbh->prepare($query); |
| 1700 |
$sth->execute($reserve_id); |
| 1701 |
} |
| 1702 |
my @priority; |
| 1703 |
|
1686 |
|
| 1704 |
# get what's left, sorting lowestPriority holds to the bottom |
1687 |
unless ($biblionumber) { # FIXME This is a very weird API |
| 1705 |
my $query = " |
1688 |
$biblionumber = $hold->biblionumber; |
| 1706 |
SELECT reserve_id, borrowernumber, reservedate, lowestPriority |
1689 |
} |
| 1707 |
FROM reserves |
|
|
| 1708 |
WHERE biblionumber = ? |
| 1709 |
AND ((found <> 'W' AND found <> 'T' AND found <> 'P') OR found IS NULL) |
| 1710 |
ORDER BY lowestPriority ASC, priority ASC |
| 1711 |
"; |
| 1712 |
my $sth = $dbh->prepare($query); |
| 1713 |
$sth->execute($biblionumber); |
| 1714 |
while ( my $line = $sth->fetchrow_hashref ) { |
| 1715 |
push( @priority, $line ); |
| 1716 |
} |
| 1717 |
|
1690 |
|
| 1718 |
# FIXME This whole sub must be rewritten, especially to highlight what is done when reserve_id is not given |
1691 |
if ( $rank eq "del" ) { # FIXME will crash if called without $hold |
| 1719 |
# To find the matching index |
1692 |
$hold->cancel; |
| 1720 |
my $i; |
1693 |
} elsif ( $reserve_id && ( $rank eq "W" || $rank eq "0" ) ) { |
| 1721 |
my $key = -1; # to allow for 0 to be a valid result |
1694 |
|
| 1722 |
for ( $i = 0 ; $i < @priority ; $i++ ) { |
1695 |
# make sure priority for waiting or in-transit items is 0 |
| 1723 |
if ( $reserve_id && $reserve_id == $priority[$i]->{'reserve_id'} ) { |
1696 |
my $query = " |
| 1724 |
$key = $i; # save the index |
1697 |
UPDATE reserves |
| 1725 |
last; |
1698 |
SET priority = 0 |
| 1726 |
} |
1699 |
WHERE reserve_id = ? |
| 1727 |
} |
1700 |
AND found IN ('W', 'T', 'P') |
|
|
1701 |
"; |
| 1702 |
my $sth = $dbh->prepare($query); |
| 1703 |
$sth->execute($reserve_id); |
| 1704 |
} |
| 1705 |
my @priority; |
| 1706 |
|
| 1707 |
# Lock all active holds for this bib so concurrent FixPriority calls |
| 1708 |
# for the same hold set cannot interleave their read-modify-write cycle. |
| 1709 |
# FOR UPDATE is effective inside the enclosing txn_do transaction. |
| 1710 |
my $query = " |
| 1711 |
SELECT reserve_id, borrowernumber, reservedate, lowestPriority |
| 1712 |
FROM reserves |
| 1713 |
WHERE biblionumber = ? |
| 1714 |
AND ((found <> 'W' AND found <> 'T' AND found <> 'P') OR found IS NULL) |
| 1715 |
ORDER BY lowestPriority ASC, priority ASC |
| 1716 |
FOR UPDATE |
| 1717 |
"; |
| 1718 |
my $sth = $dbh->prepare($query); |
| 1719 |
$sth->execute($biblionumber); |
| 1720 |
while ( my $line = $sth->fetchrow_hashref ) { |
| 1721 |
push( @priority, $line ); |
| 1722 |
} |
| 1728 |
|
1723 |
|
| 1729 |
# if this hold is marked lowest priority, we can only move it so far; |
1724 |
# FIXME This whole sub must be rewritten, especially to highlight what is done when reserve_id is not given |
| 1730 |
# cap rank to just after the last non-lowestPriority hold using the |
1725 |
# To find the matching index |
| 1731 |
# already-fetched @priority array (avoids a second DB query and stale data) |
1726 |
my $i; |
| 1732 |
if ( $hold && $hold->lowestPriority && $rank ne 'del' && $rank > 0 ) { |
1727 |
my $key = -1; # to allow for 0 to be a valid result |
| 1733 |
my $non_lowest_count = scalar grep { !$_->{lowestPriority} } @priority; |
1728 |
for ( $i = 0 ; $i < @priority ; $i++ ) { |
| 1734 |
$rank = $non_lowest_count + 1 if $non_lowest_count && $rank <= $non_lowest_count; |
1729 |
if ( $reserve_id && $reserve_id == $priority[$i]->{'reserve_id'} ) { |
| 1735 |
} |
1730 |
$key = $i; # save the index |
|
|
1731 |
last; |
| 1732 |
} |
| 1733 |
} |
| 1736 |
|
1734 |
|
| 1737 |
# if index exists in array then move it to new position |
1735 |
# if this hold is marked lowest priority, we can only move it so far; |
| 1738 |
if ( $key > -1 && $rank ne 'del' && $rank > 0 ) { |
1736 |
# cap rank to just after the last non-lowestPriority hold using the |
| 1739 |
my $new_rank = $rank - 1; # $new_rank is what you want the new index to be in the array |
1737 |
# already-fetched @priority array (avoids a second DB query and stale data) |
| 1740 |
my $moving_item = splice( @priority, $key, 1 ); |
1738 |
if ( $hold && $hold->lowestPriority && $rank ne 'del' && $rank > 0 ) { |
| 1741 |
$new_rank = scalar @priority if $new_rank > scalar @priority; |
1739 |
my $non_lowest_count = scalar grep { !$_->{lowestPriority} } @priority; |
| 1742 |
splice( @priority, $new_rank, 0, $moving_item ); |
1740 |
$rank = $non_lowest_count + 1 if $non_lowest_count && $rank <= $non_lowest_count; |
| 1743 |
} |
1741 |
} |
| 1744 |
|
1742 |
|
| 1745 |
# now fix the priority on those that are left.... |
1743 |
# if index exists in array then move it to new position |
| 1746 |
# only updating if changed |
1744 |
if ( $key > -1 && $rank ne 'del' && $rank > 0 ) { |
| 1747 |
$query = " |
1745 |
my $new_rank = $rank - 1; # $new_rank is what you want the new index to be in the array |
| 1748 |
UPDATE reserves |
1746 |
my $moving_item = splice( @priority, $key, 1 ); |
| 1749 |
SET priority = ? |
1747 |
$new_rank = scalar @priority if $new_rank > scalar @priority; |
| 1750 |
WHERE reserve_id = ? AND priority != ? |
1748 |
splice( @priority, $new_rank, 0, $moving_item ); |
| 1751 |
"; |
1749 |
} |
| 1752 |
$sth = $dbh->prepare($query); |
|
|
| 1753 |
for ( my $j = 0 ; $j < @priority ; $j++ ) { |
| 1754 |
$sth->execute( |
| 1755 |
$j + 1, |
| 1756 |
$priority[$j]->{'reserve_id'}, $j + 1 |
| 1757 |
); |
| 1758 |
} |
| 1759 |
|
1750 |
|
|
|
1751 |
# now fix the priority on those that are left.... |
| 1752 |
# only updating if changed |
| 1753 |
$query = " |
| 1754 |
UPDATE reserves |
| 1755 |
SET priority = ? |
| 1756 |
WHERE reserve_id = ? AND priority != ? |
| 1757 |
"; |
| 1758 |
$sth = $dbh->prepare($query); |
| 1759 |
for ( my $j = 0 ; $j < @priority ; $j++ ) { |
| 1760 |
$sth->execute( |
| 1761 |
$j + 1, |
| 1762 |
$priority[$j]->{'reserve_id'}, $j + 1 |
| 1763 |
); |
| 1764 |
} |
| 1765 |
} |
| 1766 |
); |
| 1760 |
} |
1767 |
} |
| 1761 |
|
1768 |
|
| 1762 |
=head2 _Findgroupreserve |
1769 |
=head2 _Findgroupreserve |
| 1763 |
- |
|
|