View | Details | Raw Unified | Return to bug 24683
Collapse All | Expand All

(-)a/C4/Reserves.pm (-9 / +10 lines)
Lines 123-129 BEGIN { Link Here
123
        &AutoUnsuspendReserves
123
        &AutoUnsuspendReserves
124
124
125
        &IsAvailableForItemLevelRequest
125
        &IsAvailableForItemLevelRequest
126
        ItemsAnyAvailableForHold
126
        ItemsAnyAvailableAndNotRestricted
127
127
128
        &AlterPriority
128
        &AlterPriority
129
        &ToggleLowestPriority
129
        &ToggleLowestPriority
Lines 1302-1325 sub IsAvailableForItemLevelRequest { Link Here
1302
        return  $items_any_available ? 0 : 1
1302
        return  $items_any_available ? 0 : 1
1303
            if defined $items_any_available;
1303
            if defined $items_any_available;
1304
1304
1305
        my $any_available = ItemsAnyAvailableForHold( { biblionumber => $item->biblionumber, patron => $patron });
1305
        my $any_available = ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron });
1306
        return $any_available ? 0 : 1;
1306
        return $any_available ? 0 : 1;
1307
    } else { # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1307
    } else { # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1308
        return $item->onloan || IsItemOnHoldAndFound( $item->itemnumber );
1308
        return $item->onloan || IsItemOnHoldAndFound( $item->itemnumber );
1309
    }
1309
    }
1310
}
1310
}
1311
1311
1312
=head2 ItemsAnyAvailableForHold
1312
=head2 ItemsAnyAvailableAndNotRestricted
1313
1313
1314
  ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron });
1314
  ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron });
1315
1315
1316
This function checks all items for specified biblionumber (num) / patron (object)
1316
This function checks all items for specified biblionumber (numeric) against patron (object)
1317
and returns true (1) or false (0) depending if any of rules allows at least of
1317
and returns true (1) if at least one item available for loan/check out/present/not held
1318
one item to be available for hold including lots of parameters/logic
1318
and also checks other parameters logic which not restricts item for hold at all (for ex.
1319
AllowHoldsOnDamagedItems or 'holdallowed' own/sibling library)
1319
1320
1320
=cut
1321
=cut
1321
1322
1322
sub ItemsAnyAvailableForHold {
1323
sub ItemsAnyAvailableAndNotRestricted {
1323
    my $param = shift;
1324
    my $param = shift;
1324
1325
1325
    my @items = Koha::Items->search( { biblionumber => $param->{biblionumber} } );
1326
    my @items = Koha::Items->search( { biblionumber => $param->{biblionumber} } );
Lines 1340-1346 sub ItemsAnyAvailableForHold { Link Here
1340
            || $i->onloan
1341
            || $i->onloan
1341
            || IsItemOnHoldAndFound( $i->id )
1342
            || IsItemOnHoldAndFound( $i->id )
1342
            || ( $i->damaged
1343
            || ( $i->damaged
1343
            && ! C4::Context->preference('AllowHoldsOnDamagedItems') )
1344
                 && ! C4::Context->preference('AllowHoldsOnDamagedItems') )
1344
            || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan
1345
            || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan
1345
            || $branchitemrule->{holdallowed} == 1 && $param->{patron}->branchcode ne $i->homebranch
1346
            || $branchitemrule->{holdallowed} == 1 && $param->{patron}->branchcode ne $i->homebranch
1346
            || $branchitemrule->{holdallowed} == 3 && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } );
1347
            || $branchitemrule->{holdallowed} == 3 && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } );
(-)a/reserve/request.pl (-1 / +1 lines)
Lines 450-456 foreach my $biblionumber (@biblionumbers) { Link Here
450
        # (before this loop was inside that sub loop so it was O(n^2) )
450
        # (before this loop was inside that sub loop so it was O(n^2) )
451
        my $items_any_available;
451
        my $items_any_available;
452
452
453
        $items_any_available = ItemsAnyAvailableForHold( { biblionumber => $biblioitemnumber, patron => $patron })
453
        $items_any_available = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblioitemnumber, patron => $patron })
454
            if $patron;
454
            if $patron;
455
455
456
        foreach my $itemnumber ( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} } )    {
456
        foreach my $itemnumber ( @{ $itemnumbers_of_biblioitem{$biblioitemnumber} } )    {
(-)a/t/db_dependent/Holds/DisallowHoldIfItemsAvailable.t (-15 / +14 lines)
Lines 98-104 Koha::CirculationRules->set_rules( Link Here
98
98
99
my $is;
99
my $is;
100
100
101
$is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 });
101
$is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 });
102
is( $is, 1, "Items availability: both of 2 items are available" );
102
is( $is, 1, "Items availability: both of 2 items are available" );
103
103
104
$is = IsAvailableForItemLevelRequest( $item1, $patron1);
104
$is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 106-112 is( $is, 0, "Item cannot be held, 2 items available" ); Link Here
106
106
107
my $issue1 = AddIssue( $patron2->unblessed, $item1->barcode );
107
my $issue1 = AddIssue( $patron2->unblessed, $item1->barcode );
108
108
109
$is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 });
109
$is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 });
110
is( $is, 1, "Items availability: one item is available" );
110
is( $is, 1, "Items availability: one item is available" );
111
111
112
$is = IsAvailableForItemLevelRequest( $item1, $patron1);
112
$is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 114-120 is( $is, 0, "Item cannot be held, 1 item available" ); Link Here
114
114
115
AddIssue( $patron2->unblessed, $item2->barcode );
115
AddIssue( $patron2->unblessed, $item2->barcode );
116
116
117
$is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 });
117
$is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 });
118
is( $is, 0, "Items availability: none of items are available" );
118
is( $is, 0, "Items availability: none of items are available" );
119
119
120
$is = IsAvailableForItemLevelRequest( $item1, $patron1);
120
$is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 144-150 AddReturn( $item1->barcode ); Link Here
144
144
145
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
145
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
146
146
147
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
147
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
148
                is( $is, 0, "Items availability: hold allowed from home + ReservesControlBranch=ItemHomeLibrary + one item is available at different library" );
148
                is( $is, 0, "Items availability: hold allowed from home + ReservesControlBranch=ItemHomeLibrary + one item is available at different library" );
149
149
150
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
150
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 154-160 AddReturn( $item1->barcode ); Link Here
154
                set_holdallowed_rule( $hold_allowed_from_any_libraries, $library_B );
154
                set_holdallowed_rule( $hold_allowed_from_any_libraries, $library_B );
155
                #Adding a rule for the item's home library affects the availability for a borrower from another library because ReservesControlBranch is set to ItemHomeLibrary
155
                #Adding a rule for the item's home library affects the availability for a borrower from another library because ReservesControlBranch is set to ItemHomeLibrary
156
156
157
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
157
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
158
                is( $is, 1, "Items availability: hold allowed from any library for library B + ReservesControlBranch=ItemHomeLibrary + one item is available at different library" );
158
                is( $is, 1, "Items availability: hold allowed from any library for library B + ReservesControlBranch=ItemHomeLibrary + one item is available at different library" );
159
159
160
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
160
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 162-168 AddReturn( $item1->barcode ); Link Here
162
162
163
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
163
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
164
164
165
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
165
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
166
                is( $is, 0, "Items availability: hold allowed from any library for library B + ReservesControlBranch=PatronLibrary + one item is available at different library" );
166
                is( $is, 0, "Items availability: hold allowed from any library for library B + ReservesControlBranch=PatronLibrary + one item is available at different library" );
167
167
168
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
168
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 170-176 AddReturn( $item1->barcode ); Link Here
170
                #Adding a rule for the patron's home library affects the availability for an item from another library because ReservesControlBranch is set to PatronLibrary
170
                #Adding a rule for the patron's home library affects the availability for an item from another library because ReservesControlBranch is set to PatronLibrary
171
                set_holdallowed_rule( $hold_allowed_from_any_libraries, $library_A );
171
                set_holdallowed_rule( $hold_allowed_from_any_libraries, $library_A );
172
172
173
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
173
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
174
                is( $is, 1, "Items availability: hold allowed from any library for library A + ReservesControlBranch=PatronLibrary + one item is available at different library" );
174
                is( $is, 1, "Items availability: hold allowed from any library for library A + ReservesControlBranch=PatronLibrary + one item is available at different library" );
175
175
176
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
176
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 182-188 AddReturn( $item1->barcode ); Link Here
182
182
183
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
183
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
184
184
185
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
185
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
186
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=ItemHomeLibrary + one item is available at different library" );
186
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=ItemHomeLibrary + one item is available at different library" );
187
187
188
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
188
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 190-196 AddReturn( $item1->barcode ); Link Here
190
190
191
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
191
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
192
192
193
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
193
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 0 items, library B 1 item
194
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=PatronLibrary + one item is available at different library" );
194
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=PatronLibrary + one item is available at different library" );
195
195
196
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
196
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 215-221 AddReturn( $item1->barcode ); Link Here
215
215
216
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
216
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
217
217
218
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
218
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
219
                is( $is, 1, "Items availability: hold allowed from home library + ReservesControlBranch=ItemHomeLibrary + one item is available at home library" );
219
                is( $is, 1, "Items availability: hold allowed from home library + ReservesControlBranch=ItemHomeLibrary + one item is available at home library" );
220
220
221
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
221
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 223-229 AddReturn( $item1->barcode ); Link Here
223
223
224
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
224
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
225
225
226
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
226
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
227
                is( $is, 1, "Items availability: hold allowed from home library + ReservesControlBranch=PatronLibrary + one item is available at home library" );
227
                is( $is, 1, "Items availability: hold allowed from home library + ReservesControlBranch=PatronLibrary + one item is available at home library" );
228
228
229
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
229
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 235-241 AddReturn( $item1->barcode ); Link Here
235
235
236
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
236
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'ItemHomeLibrary');
237
237
238
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
238
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
239
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=ItemHomeLibrary + one item is available at home library" );
239
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=ItemHomeLibrary + one item is available at home library" );
240
240
241
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
241
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 243-249 AddReturn( $item1->barcode ); Link Here
243
243
244
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
244
                t::lib::Mocks::mock_preference('ReservesControlBranch', 'PatronLibrary');
245
245
246
                $is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
246
                $is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
247
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=PatronLibrary + one item is available at home library" );
247
                is( $is, 1, "Items availability: hold allowed from any library + ReservesControlBranch=PatronLibrary + one item is available at home library" );
248
248
249
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
249
                $is = IsAvailableForItemLevelRequest( $item1, $patron1);
Lines 279-285 Koha::CirculationRules->set_rules( Link Here
279
    }
279
    }
280
);
280
);
281
281
282
$is = ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
282
$is = ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron1 }); # patron1 in library A, library A 1 item
283
is( $is, 1, "Items availability: 1 item is available, 1 item held in T" );
283
is( $is, 1, "Items availability: 1 item is available, 1 item held in T" );
284
284
285
$is = IsAvailableForItemLevelRequest( $item3, $patron1);
285
$is = IsAvailableForItemLevelRequest( $item3, $patron1);
286
- 

Return to bug 24683