From 3b7b883401e012fc4618049ccfc54981d770f6e4 Mon Sep 17 00:00:00 2001 From: Tomas Cohen Arazi Date: Fri, 3 Sep 2021 09:55:01 -0300 Subject: [PATCH] Bug 28529: Make biblio-level hold itemtype count against max rules The current situation is that biblio-level holds can be assigned an item type, so they can only be fulfilled by items matching that specified item type (be it item-level itype or the fallback to biblio-level). But there's the situation in which max holds limits for a specific item type can be overridden by using biblio-level holds with item type selection (AllowHoldItemTypeSelection) enabled. To test: 1. Have a patron of category 'Staff' (S) 2. Have 3 records with items with the 'BK' item type, and maybe others 3. Enable AllowHoldItemTypeSelection 4. Set a limit of 2 max holds for that category+item type 5. In the OPAC. Place bibio-level holds, with item type contraint to 'BK' on those 3 records => FAIL: You can place the 3 holds 6. Cancel the holds 7. Apply this patch and restart all 8. Repeat 5 => SUCCESS: You can only place 2 holds 9. Run: $ kshell t/db_dependent/Reserves.t => SUCCESS: Tests pass! 10. Sign off :-D --- C4/Reserves.pm | 63 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index f2ee463979..233f7e5361 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -331,6 +331,35 @@ sub CanBookBeReserved{ return { status =>'alreadypossession' }; } + if ( $params->{itemtype} + and C4::Context->preference('BiblioHoldItemTypeUseForRules') ) + { + # biblio-level, item type-contrained + my $patron = Koha::Patrons->find($borrowernumber); + my $reservesallowed = Koha::CirculationRules->get_effective_rule( + { + itemtype => $params->{itemtype}, + categorycode => $patron->categorycode, + branchcode => $pickup_branchcode, + rule_name => 'reservesallowed', + } + )->rule_value; + my $count = $patron->holds->search( + { + '-or' => [ + { 'me.itemtype' => $params->{itemtype} }, + { 'item.itype' => $params->{itemtype} } + ] + }, + { + join => ['item'] + } + )->count; + + return { status => '' } + unless $reservesallowed > $count; + } + my @itemnumbers = Koha::Items->search({ biblionumber => $biblionumber})->get_column("itemnumber"); #get items linked via host records my @hostitems = get_hostitemnumbers_of($biblionumber); @@ -485,17 +514,35 @@ sub CanItemBeReserved { $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 - $querycount .= - C4::Context->preference('item-level_itypes') - ? " AND COALESCE( items.itype, biblioitems.itemtype ) = ?" - : " AND biblioitems.itemtype = ?" - if defined $ruleitemtype; + if ( defined $ruleitemtype and C4::Context->preference('BiblioHoldItemTypeUseForRules') ) { + if ( C4::Context->preference('item-level_itypes') ) { + $querycount .= q{ + AND ( COALESCE( items.itype, biblioitems.itemtype ) = ? + OR reserves.itemtype = ? ) + }; + } + else { + $querycount .= q{ + AND ( biblioitems.itemtype = ? + OR reserves.itemtype = ? ) + }; + } + } + elsif ( defined $ruleitemtype ) { + # If using item-level itypes, fall back to the record + # level itemtype if the hold has no associated item + $querycount .= + C4::Context->preference('item-level_itypes') + ? " AND COALESCE( items.itype, biblioitems.itemtype ) = ?" + : " AND biblioitems.itemtype = ?"; + } my $sthcount = $dbh->prepare($querycount); - if ( defined $ruleitemtype ) { + if ( defined $ruleitemtype and C4::Context->preference('BiblioHoldItemTypeUseForRules') ) { + $sthcount->execute( $borrowernumber, $branchcode, $ruleitemtype, $ruleitemtype ); + } + elsif ( defined $ruleitemtype ) { $sthcount->execute( $borrowernumber, $branchcode, $ruleitemtype ); } else { -- 2.33.0