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

(-)a/C4/Reserves.pm (-9 / +10 lines)
Lines 122-128 BEGIN { Link Here
122
        &AutoUnsuspendReserves
122
        &AutoUnsuspendReserves
123
123
124
        &IsAvailableForItemLevelRequest
124
        &IsAvailableForItemLevelRequest
125
        ItemsAnyAvailableForHold
125
        ItemsAnyAvailableAndNotRestricted
126
126
127
        &AlterPriority
127
        &AlterPriority
128
        &ToggleLowestPriority
128
        &ToggleLowestPriority
Lines 1299-1322 sub IsAvailableForItemLevelRequest { Link Here
1299
        return  $items_any_available ? 0 : 1
1299
        return  $items_any_available ? 0 : 1
1300
            if defined $items_any_available;
1300
            if defined $items_any_available;
1301
1301
1302
        my $any_available = ItemsAnyAvailableForHold( { biblionumber => $item->biblionumber, patron => $patron });
1302
        my $any_available = ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron });
1303
        return $any_available ? 0 : 1;
1303
        return $any_available ? 0 : 1;
1304
    } else { # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1304
    } else { # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1305
        return $item->onloan || IsItemOnHoldAndFound( $item->itemnumber );
1305
        return $item->onloan || IsItemOnHoldAndFound( $item->itemnumber );
1306
    }
1306
    }
1307
}
1307
}
1308
1308
1309
=head2 ItemsAnyAvailableForHold
1309
=head2 ItemsAnyAvailableAndNotRestricted
1310
1310
1311
  ItemsAnyAvailableForHold( { biblionumber => $biblionumber, patron => $patron });
1311
  ItemsAnyAvailableAndNotRestricted( { biblionumber => $biblionumber, patron => $patron });
1312
1312
1313
This function checks all items for specified biblionumber (num) / patron (object)
1313
This function checks all items for specified biblionumber (numeric) against patron (object)
1314
and returns true (1) or false (0) depending if any of rules allows at least of
1314
and returns true (1) if at least one item available for loan/check out/present/not held
1315
one item to be available for hold including lots of parameters/logic
1315
and also checks other parameters logic which not restricts item for hold at all (for ex.
1316
AllowHoldsOnDamagedItems or 'holdallowed' own/sibling library)
1316
1317
1317
=cut
1318
=cut
1318
1319
1319
sub ItemsAnyAvailableForHold {
1320
sub ItemsAnyAvailableAndNotRestricted {
1320
    my $param = shift;
1321
    my $param = shift;
1321
1322
1322
    my @items = Koha::Items->search( { biblionumber => $param->{biblionumber} } );
1323
    my @items = Koha::Items->search( { biblionumber => $param->{biblionumber} } );
Lines 1337-1343 sub ItemsAnyAvailableForHold { Link Here
1337
            || $i->onloan
1338
            || $i->onloan
1338
            || IsItemOnHoldAndFound( $i->id )
1339
            || IsItemOnHoldAndFound( $i->id )
1339
            || ( $i->damaged
1340
            || ( $i->damaged
1340
            && ! C4::Context->preference('AllowHoldsOnDamagedItems') )
1341
                 && ! C4::Context->preference('AllowHoldsOnDamagedItems') )
1341
            || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan
1342
            || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan
1342
            || $branchitemrule->{holdallowed} == 1 && $param->{patron}->branchcode ne $i->homebranch
1343
            || $branchitemrule->{holdallowed} == 1 && $param->{patron}->branchcode ne $i->homebranch
1343
            || $branchitemrule->{holdallowed} == 3 && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } );
1344
            || $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