@@ -, +, @@ unavailable" holds": "if all unavailable" for all rules, no "item level holds", and set "holds per record" to 2 for "books" and "0" for "computer files". and "computer file". For example in misc4dev env: /cgi-bin/koha/cataloguing/additem.pl?biblionumber=1#additem in misc4dev: /cgi-bin/koha/circ/circulation.pl?borrowernumber=2&barcode=3999900000001 env (/cgi-bin/koha/reserve/request.pl?biblionumber=1&borrowernumber=1) "Exceeded max holds per record" because of "0" limit set on step 1. but "computer file" still will be red-crossed "Exceeded max holds per record", now that's correct because both items unavailable: one because on load, another because of "0" limit for computer files. but it's now also correct: "book" now returned but "on shelf holds" set to "if all unavailable". --- C4/Reserves.pm | 3 +- .../Holds/DisallowHoldIfItemsAvailable.t | 81 ++++++++++++++++++- 2 files changed, 82 insertions(+), 2 deletions(-) --- a/C4/Reserves.pm +++ a/C4/Reserves.pm @@ -1340,7 +1340,8 @@ sub ItemsAnyAvailableAndNotRestricted { && ! C4::Context->preference('AllowHoldsOnDamagedItems') ) || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan || $branchitemrule->{holdallowed} == 1 && $param->{patron}->branchcode ne $i->homebranch - || $branchitemrule->{holdallowed} == 3 && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } ); + || $branchitemrule->{holdallowed} == 3 && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } ) + || CanItemBeReserved( $param->{patron}->borrowernumber, $i->id )->{status} ne 'OK'; } return 0; --- a/t/db_dependent/Holds/DisallowHoldIfItemsAvailable.t +++ a/t/db_dependent/Holds/DisallowHoldIfItemsAvailable.t @@ -8,7 +8,7 @@ use C4::Items; use Koha::Items; use Koha::CirculationRules; -use Test::More tests => 10; +use Test::More tests => 11; use t::lib::TestBuilder; use t::lib::Mocks; @@ -285,6 +285,85 @@ is( $is, 1, "Items availability: 1 item is available, 1 item held in T" ); $is = IsAvailableForItemLevelRequest( $item3, $patron1); is( $is, 1, "Item can be held, items in transit are not available" ); +subtest 'Check holds availability with different item types' => sub { + plan tests => 6; + + # Check for holds availability when different item types have different + # smart rules assigned both with "if all unavailable" set, + # and $itemtype rule allows holds, $itemtype2 rule disallows holds. + # So, $item should be available for hold when checked out even if $item2 + # is not checked out, because anyway $item2 unavailable for holds by rule + # (Bug 24683): + + my $biblio2 = $builder->build_sample_biblio( { itemtype => $itemtype } ); + my $biblionumber1 = $biblio2->biblionumber; + my $item4 = $builder->build_sample_item( + { biblionumber => $biblionumber1, + itype => $itemtype, + homebranch => $library_A, + holdingbranch => $library_A + } + ); + my $item5 = $builder->build_sample_item( + { biblionumber => $biblionumber1, + itype => $itemtype2, + homebranch => $library_A, + holdingbranch => $library_A + } + ); + + # Test hold_fulfillment_policy + $dbh->do("DELETE FROM circulation_rules"); + Koha::CirculationRules->set_rules( + { categorycode => undef, + itemtype => $itemtype, + branchcode => undef, + rules => { + issuelength => 7, + lengthunit => 8, + reservesallowed => 99, + holds_per_record => 99, + onshelfholds => 2, + } + } + ); + Koha::CirculationRules->set_rules( + { categorycode => undef, + itemtype => $itemtype2, + branchcode => undef, + rules => { + issuelength => 7, + lengthunit => 8, + reservesallowed => 0, + holds_per_record => 0, + onshelfholds => 2, + } + } + ); + + $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber1, patron => $patron1 } ); + is( $is, 1, "Items availability: 2 items, one allowed by smart rule but not checked out, another one not allowed to be held by smart rule" ); + + $is = IsAvailableForItemLevelRequest( $item4, $patron1 ); + is( $is, 0, "Item4 cannot be requested to hold: 2 items, Item4 available, Item5 restricted" ); + + $is = IsAvailableForItemLevelRequest( $item5, $patron1 ); + is( $is, 0, "Item5 cannot be requested to hold: 2 items, Item4 available, Item5 restricted" ); + + AddIssue( $patron2->unblessed, $item4->barcode ); + + $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber1, patron => $patron1 } ); + is( $is, 0, "Items availability: 2 items, one allowed by smart rule and checked out, another one not allowed to be held by smart rule" ); + + $is = IsAvailableForItemLevelRequest( $item4, $patron1 ); + is( $is, 1, "Item4 can be requested to hold, 2 items, Item4 checked out, Item5 restricted" ); + + $is = IsAvailableForItemLevelRequest( $item5, $patron1 ); + # Note: read IsAvailableForItemLevelRequest sub description about CanItemBeReserved/CanBookBeReserved: + is( $is, 1, "Item5 can be requested to hold, 2 items, Item4 checked out, Item5 restricted" ); +}; + + # Cleanup $schema->storage->txn_rollback; --