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

(-)a/C4/ILSDI/Services.pm (-4 / +5 lines)
Lines 488-494 sub GetServices { Link Here
488
488
489
    # Reserve level management
489
    # Reserve level management
490
    my $biblionumber = $item->{'biblionumber'};
490
    my $biblionumber = $item->{'biblionumber'};
491
    my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
491
    my ($canbookbereserved) = CanBookBeReserved( $borrowernumber, $biblionumber );
492
    if ($canbookbereserved) {
492
    if ($canbookbereserved) {
493
        push @availablefor, 'title level hold';
493
        push @availablefor, 'title level hold';
494
        my $canitembereserved = IsAvailableForItemLevelRequest($itemnumber);
494
        my $canitembereserved = IsAvailableForItemLevelRequest($itemnumber);
Lines 609-615 sub HoldTitle { Link Here
609
    my $title = $$biblio{title};
609
    my $title = $$biblio{title};
610
610
611
    # Check if the biblio can be reserved
611
    # Check if the biblio can be reserved
612
    return { code => 'NotHoldable' } unless CanBookBeReserved( $borrowernumber, $biblionumber );
612
    my ($canbookbereserved) = CanBookBeReserved($borrowernumber, $biblionumber);
613
    return { code => 'NotHoldable' } unless $canbookbereserved;
613
614
614
    my $branch;
615
    my $branch;
615
616
Lines 685-692 sub HoldItem { Link Here
685
    return { code => 'RecordNotFound' } if $$item{biblionumber} ne $$biblio{biblionumber};
686
    return { code => 'RecordNotFound' } if $$item{biblionumber} ne $$biblio{biblionumber};
686
687
687
    # Check for item disponibility
688
    # Check for item disponibility
688
    my $canitembereserved = C4::Reserves::CanItemBeReserved( $borrowernumber, $itemnumber );
689
    my ($canitembereserved) = C4::Reserves::CanItemBeReserved( $borrowernumber, $itemnumber );
689
    my $canbookbereserved = C4::Reserves::CanBookBeReserved( $borrowernumber, $biblionumber );
690
    my ($canbookbereserved) = C4::Reserves::CanBookBeReserved( $borrowernumber, $biblionumber );
690
    return { code => 'NotHoldable' } unless $canbookbereserved and $canitembereserved;
691
    return { code => 'NotHoldable' } unless $canbookbereserved and $canitembereserved;
691
692
692
    # Pickup branch management
693
    # Pickup branch management
(-)a/C4/Reserves.pm (-10 / +51 lines)
Lines 431-443 sub GetReservesFromBorrowernumber { Link Here
431
#-------------------------------------------------------------------------------------
431
#-------------------------------------------------------------------------------------
432
=head2 CanBookBeReserved
432
=head2 CanBookBeReserved
433
433
434
  $error = &CanBookBeReserved($borrowernumber, $biblionumber)
434
  ($can_be_reserved, $reasons) = &CanBookBeReserved($borrowernumber, $biblionumber)
435
436
$can_be_reserved is true if book can be reserved, false otherwise.
437
438
$reasons is a hashref where keys are reasons why a book cannot be reserved
439
(undef if $can_be_reserved is true)
440
$reasons keys can be: alreadyreserved, maxreserves or noholdableitems.
435
441
436
=cut
442
=cut
437
443
438
sub CanBookBeReserved{
444
sub CanBookBeReserved{
439
    my ($borrowernumber, $biblionumber) = @_;
445
    my ($borrowernumber, $biblionumber) = @_;
440
446
447
    # Check if borrower already has reserved the same biblio.
448
    my @reserves = GetReservesFromBorrowernumber($borrowernumber);
449
    foreach my $reserve (@reserves) {
450
        if ($reserve->{biblionumber} == $biblionumber) {
451
            return (0, {alreadyreserved => 1});
452
        }
453
    }
454
455
    # Check if borrower has reached the maximum number of holds allowed
456
    my $maxreserves = C4::Context->preference('maxreserves');
457
    if ($maxreserves && scalar(@reserves) >= $maxreserves) {
458
        return (0, {maxreserves => 1});
459
    }
460
441
    my $items = GetItemnumbersForBiblio($biblionumber);
461
    my $items = GetItemnumbersForBiblio($biblionumber);
442
    #get items linked via host records
462
    #get items linked via host records
443
    my @hostitems = get_hostitemnumbers_of($biblionumber);
463
    my @hostitems = get_hostitemnumbers_of($biblionumber);
Lines 446-461 sub CanBookBeReserved{ Link Here
446
    }
466
    }
447
467
448
    foreach my $item (@$items){
468
    foreach my $item (@$items){
449
        return 1 if CanItemBeReserved($borrowernumber, $item);
469
        my ($canitembereserved) = CanItemBeReserved($borrowernumber, $item);
470
        return 1 if $canitembereserved;
450
    }
471
    }
451
    return 0;
472
    return (0, {noholdableitems => 1});
452
}
473
}
453
474
454
=head2 CanItemBeReserved
475
=head2 CanItemBeReserved
455
476
456
  $error = &CanItemBeReserved($borrowernumber, $itemnumber)
477
  ($can_be_reserved, $reasons) = &CanItemBeReserved($borrowernumber, $itemnumber)
457
478
458
This function return 1 if an item can be issued by this borrower.
479
$can_be_reserved is true if book can be reserved, false otherwise.
480
481
$reasons is a hashref where keys are reasons why an item cannot be reserved
482
(undef if $can_be_reserved is true)
483
$reasons keys can be: damaged, alreadyreserved, maxreserves or wrongbranch.
459
484
460
=cut
485
=cut
461
486
Lines 465-480 sub CanItemBeReserved{ Link Here
465
    my $dbh             = C4::Context->dbh;
490
    my $dbh             = C4::Context->dbh;
466
    my $ruleitemtype; # itemtype of the matching issuing rule
491
    my $ruleitemtype; # itemtype of the matching issuing rule
467
    my $allowedreserves = 0;
492
    my $allowedreserves = 0;
468
            
493
469
    # we retrieve borrowers and items informations #
494
    # we retrieve borrowers and items informations #
470
    # item->{itype} will come for biblioitems if necessery
495
    # item->{itype} will come for biblioitems if necessery
471
    my $item = GetItem($itemnumber);
496
    my $item = GetItem($itemnumber);
472
497
473
    # If an item is damaged and we don't allow holds on damaged items, we can stop right here
498
    # If an item is damaged and we don't allow holds on damaged items, we can stop right here
474
    return 0 if ( $item->{damaged} && !C4::Context->preference('AllowHoldsOnDamagedItems') );
499
    return (0, {damaged => 1}) if ( $item->{damaged} && !C4::Context->preference('AllowHoldsOnDamagedItems') );
475
500
476
    my $borrower = C4::Members::GetMember('borrowernumber'=>$borrowernumber);     
501
    my $borrower = C4::Members::GetMember('borrowernumber'=>$borrowernumber);     
477
    
502
503
    # Check if borrower already has reserved the same item or biblio.
504
    my @reserves = GetReservesFromBorrowernumber($borrowernumber);
505
    foreach my $reserve (@reserves) {
506
        if (   $reserve->{itemnumber} == $itemnumber
507
            or $reserve->{biblionumber} == $item->{biblionumber} )
508
        {
509
            return (0, {alreadyreserved => 1});
510
        }
511
    }
512
513
    # Check if borrower has reached the maximum number of holds allowed
514
    my $maxreserves = C4::Context->preference('maxreserves');
515
    if ($maxreserves && scalar(@reserves) >= $maxreserves) {
516
        return (0, {maxreserves => 1});
517
    }
518
478
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
519
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
479
    my $itemtypefield = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype";
520
    my $itemtypefield = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype";
480
521
Lines 540-546 sub CanItemBeReserved{ Link Here
540
    
581
    
541
    # we check if it's ok or not
582
    # we check if it's ok or not
542
    if( $reservecount >= $allowedreserves ){
583
    if( $reservecount >= $allowedreserves ){
543
        return 0;
584
        return (0, {maxreserves => 1});
544
    }
585
    }
545
586
546
    # If reservecount is ok, we check item branch if IndependentBranches is ON
587
    # If reservecount is ok, we check item branch if IndependentBranches is ON
Lines 550-556 sub CanItemBeReserved{ Link Here
550
    {
591
    {
551
        my $itembranch = $item->{homebranch};
592
        my $itembranch = $item->{homebranch};
552
        if ($itembranch ne $borrower->{branchcode}) {
593
        if ($itembranch ne $borrower->{branchcode}) {
553
            return 0;
594
            return (0, {wrongbranch => 1});
554
        }
595
        }
555
    }
596
    }
556
597
(-)a/opac/opac-reserve.pl (-17 / +14 lines)
Lines 38-45 use Koha::DateUtils; Link Here
38
use Date::Calc qw/Today Date_to_Days/;
38
use Date::Calc qw/Today Date_to_Days/;
39
# use Data::Dumper;
39
# use Data::Dumper;
40
40
41
my $MAXIMUM_NUMBER_OF_RESERVES = C4::Context->preference("maxreserves");
42
43
my $query = new CGI;
41
my $query = new CGI;
44
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
42
my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
45
    {
43
    {
Lines 181-191 foreach my $biblioNumber (@biblionumbers) { Link Here
181
# with a specific item for each biblionumber.
179
# with a specific item for each biblionumber.
182
#
180
#
183
#
181
#
182
my $maxreserves = 0;
184
if ( $query->param('place_reserve') ) {
183
if ( $query->param('place_reserve') ) {
185
    my $reserve_cnt = 0;
184
    my $reserve_cnt = 0;
186
    if ($MAXIMUM_NUMBER_OF_RESERVES) {
187
        $reserve_cnt = GetReservesFromBorrowernumber( $borrowernumber );
188
    }
189
185
190
    # List is composed of alternating biblio/item/branch
186
    # List is composed of alternating biblio/item/branch
191
    my $selectedItems = $query->param('selecteditems');
187
    my $selectedItems = $query->param('selecteditems');
Lines 250-257 if ( $query->param('place_reserve') ) { Link Here
250
      # If a specific item was selected and the pickup branch is the same as the
246
      # If a specific item was selected and the pickup branch is the same as the
251
      # holdingbranch, force the value $rank and $found.
247
      # holdingbranch, force the value $rank and $found.
252
        my $rank = $biblioData->{rank};
248
        my $rank = $biblioData->{rank};
249
        my $reasons;
253
        if ( $itemNum ne '' ) {
250
        if ( $itemNum ne '' ) {
254
            $canreserve = 1 if CanItemBeReserved( $borrowernumber, $itemNum );
251
            ($canreserve, $reasons) = CanItemBeReserved( $borrowernumber, $itemNum );
255
            $rank = '0' unless C4::Context->preference('ReservesNeedReturns');
252
            $rank = '0' unless C4::Context->preference('ReservesNeedReturns');
256
            my $item = GetItem($itemNum);
253
            my $item = GetItem($itemNum);
257
            if ( $item->{'holdingbranch'} eq $branch ) {
254
            if ( $item->{'holdingbranch'} eq $branch ) {
Lines 260-277 if ( $query->param('place_reserve') ) { Link Here
260
            }
257
            }
261
        }
258
        }
262
        else {
259
        else {
263
            $canreserve = 1 if CanBookBeReserved( $borrowernumber, $biblioNum );
260
            ($canreserve, $reasons) = CanBookBeReserved( $borrowernumber, $biblioNum );
264
261
265
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
262
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
266
            $itemNum = undef;
263
            $itemNum = undef;
267
        }
264
        }
268
        my $notes = $query->param('notes_'.$biblioNum)||'';
269
265
270
        if (   $MAXIMUM_NUMBER_OF_RESERVES
266
        my $notes = $query->param('notes_'.$biblioNum)||'';
271
            && $reserve_cnt >= $MAXIMUM_NUMBER_OF_RESERVES )
272
        {
273
            $canreserve = 0;
274
        }
275
267
276
        # Here we actually do the reserveration. Stage 3.
268
        # Here we actually do the reserveration. Stage 3.
277
        if ($canreserve) {
269
        if ($canreserve) {
Lines 283-289 if ( $query->param('place_reserve') ) { Link Here
283
                $notes,       $biblioData->{title},
275
                $notes,       $biblioData->{title},
284
                $itemNum,     $found
276
                $itemNum,     $found
285
            );
277
            );
286
            ++$reserve_cnt;
278
        } else {
279
            if ( $reasons->{maxreserves} ) {
280
                $maxreserves = 1;
281
            }
287
        }
282
        }
288
    }
283
    }
289
284
Lines 329-335 if ( $borr->{'debarred'} ) { Link Here
329
324
330
my @reserves = GetReservesFromBorrowernumber( $borrowernumber );
325
my @reserves = GetReservesFromBorrowernumber( $borrowernumber );
331
$template->param( RESERVES => \@reserves );
326
$template->param( RESERVES => \@reserves );
332
if ( $MAXIMUM_NUMBER_OF_RESERVES && (scalar(@reserves) >= $MAXIMUM_NUMBER_OF_RESERVES) ) {
327
if ($maxreserves) {
333
    $template->param( message => 1 );
328
    $template->param( message => 1 );
334
    $noreserves = 1;
329
    $noreserves = 1;
335
    $template->param( too_many_reserves => scalar(@reserves));
330
    $template->param( too_many_reserves => scalar(@reserves));
Lines 514-520 foreach my $biblioNum (@biblionumbers) { Link Here
514
            $policy_holdallowed = 0;
509
            $policy_holdallowed = 0;
515
        }
510
        }
516
511
517
        if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and CanItemBeReserved($borrowernumber,$itemNum) and ($itemLoopIter->{already_reserved} ne 1)) {
512
        my ($canitembereserved) = CanItemBeReserved($borrowernumber, $itemNum);
513
        if (IsAvailableForItemLevelRequest($itemNum) and $policy_holdallowed and $canitembereserved and ($itemLoopIter->{already_reserved} ne 1)) {
518
            $itemLoopIter->{available} = 1;
514
            $itemLoopIter->{available} = 1;
519
            $numCopiesAvailable++;
515
            $numCopiesAvailable++;
520
        }
516
        }
Lines 538-544 foreach my $biblioNum (@biblionumbers) { Link Here
538
    if ($biblioLoopIter{already_reserved}) {
534
    if ($biblioLoopIter{already_reserved}) {
539
        $biblioLoopIter{holdable} = undef;
535
        $biblioLoopIter{holdable} = undef;
540
    }
536
    }
541
    if(not CanBookBeReserved($borrowernumber,$biblioNum)){
537
    my ($canbookbereserved) = CanBookBeReserved($borrowernumber, $biblioNum);
538
    if(not $canbookbereserved){
542
        $biblioLoopIter{holdable} = undef;
539
        $biblioLoopIter{holdable} = undef;
543
    }
540
    }
544
    if(not C4::Context->preference('AllowHoldsOnPatronsPossessions') and CheckIfIssuedToPatron($borrowernumber,$biblioNum)) {
541
    if(not C4::Context->preference('AllowHoldsOnPatronsPossessions') and CheckIfIssuedToPatron($borrowernumber,$biblioNum)) {
(-)a/reserve/request.pl (-18 / +18 lines)
Lines 186-193 foreach my $biblionumber (@biblionumbers) { Link Here
186
186
187
    my $dat = GetBiblioData($biblionumber);
187
    my $dat = GetBiblioData($biblionumber);
188
188
189
    unless ( CanBookBeReserved($borrowerinfo->{borrowernumber}, $biblionumber) ) {
189
    my $alreadyreserved = 0;
190
        $maxreserves = 1;
190
191
    my ($can_book_be_reserved, $reasons) =
192
      CanBookBeReserved( $borrowerinfo->{borrowernumber}, $biblionumber );
193
194
    unless ($can_book_be_reserved) {
195
        if ($reasons->{alreadyreserved}) {
196
            $alreadyreserved = 1;
197
            $biblioloopiter{warn} = 1;
198
            $biblioloopiter{alreadyres} = 1;
199
        } else {
200
            $maxreserves = 1;
201
        }
191
    }
202
    }
192
203
193
    my $alreadypossession;
204
    my $alreadypossession;
Lines 199-221 foreach my $biblionumber (@biblionumbers) { Link Here
199
    my $reserves = GetReservesFromBiblionumber({ biblionumber => $biblionumber, all_dates => 1 });
210
    my $reserves = GetReservesFromBiblionumber({ biblionumber => $biblionumber, all_dates => 1 });
200
    my $count = scalar( @$reserves );
211
    my $count = scalar( @$reserves );
201
    my $totalcount = $count;
212
    my $totalcount = $count;
202
    my $holds_count = 0;
203
    my $alreadyreserved = 0;
204
213
205
    foreach my $res (@$reserves) {
214
    foreach my $res (@$reserves) {
206
        if ( defined $res->{found} && $res->{found} eq 'W' ) {
215
        if ( defined $res->{found} && $res->{found} eq 'W' ) {
207
            $count--;
216
            $count--;
208
        }
217
        }
209
210
        if ( defined $borrowerinfo && defined($borrowerinfo->{borrowernumber}) && ($borrowerinfo->{borrowernumber} eq $res->{borrowernumber}) ) {
211
            $holds_count++;
212
        }
213
    }
214
215
    if ( $holds_count ) {
216
            $alreadyreserved = 1;
217
            $biblioloopiter{warn} = 1;
218
            $biblioloopiter{alreadyres} = 1;
219
    }
218
    }
220
219
221
    $template->param(
220
    $template->param(
Lines 403-416 foreach my $biblionumber (@biblionumbers) { Link Here
403
                     $borrowerinfo->{'branchcode'} ne $item->{'homebranch'} ) ) {
402
                     $borrowerinfo->{'branchcode'} ne $item->{'homebranch'} ) ) {
404
                $policy_holdallowed = 0;
403
                $policy_holdallowed = 0;
405
            }
404
            }
406
            
405
406
            my ($canitembereserved) =
407
              CanItemBeReserved( $borrowerinfo->{borrowernumber}, $itemnumber );
408
407
            if (
409
            if (
408
                   $policy_holdallowed
410
                   $policy_holdallowed
409
                && !$item->{cantreserve}
411
                && !$item->{cantreserve}
410
                && IsAvailableForItemLevelRequest($itemnumber)
412
                && IsAvailableForItemLevelRequest($itemnumber)
411
                && CanItemBeReserved(
413
                && $canitembereserved
412
                    $borrowerinfo->{borrowernumber}, $itemnumber
413
                )
414
              )
414
              )
415
            {
415
            {
416
                $item->{available} = 1;
416
                $item->{available} = 1;
(-)a/t/db_dependent/Holds.t (-25 / +67 lines)
Lines 6-12 use t::lib::Mocks; Link Here
6
use C4::Context;
6
use C4::Context;
7
use C4::Branch;
7
use C4::Branch;
8
8
9
use Test::More tests => 32;
9
use Test::More tests => 43;
10
use MARC::Record;
10
use MARC::Record;
11
use C4::Biblio;
11
use C4::Biblio;
12
use C4::Items;
12
use C4::Items;
Lines 54-61 foreach (1..$borrowers_count) { Link Here
54
54
55
my $biblionumber   = $bibnum;
55
my $biblionumber   = $bibnum;
56
56
57
my @branches = GetBranchesLoop();
57
my $branches = GetBranchesLoop();
58
my $branch = $branches[0][0]{value};
58
my $branch = $branches->[0]{value};
59
59
60
# Create five item level holds
60
# Create five item level holds
61
foreach my $borrowernumber ( @borrowernumbers ) {
61
foreach my $borrowernumber ( @borrowernumbers ) {
Lines 205-229 t::lib::Mocks::mock_preference('item-level_itypes', 1); Link Here
205
205
206
# if IndependentBranches is OFF, a CPL patron can reserve an MPL item
206
# if IndependentBranches is OFF, a CPL patron can reserve an MPL item
207
t::lib::Mocks::mock_preference('IndependentBranches', 0);
207
t::lib::Mocks::mock_preference('IndependentBranches', 0);
208
my ($canitembereserved, $reasons) = CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber);
208
ok(
209
ok(
209
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber),
210
    $canitembereserved,
210
    'CPL patron allowed to reserve MPL item with IndependentBranches OFF (bug 2394)'
211
    'CPL patron allowed to reserve MPL item with IndependentBranches OFF (bug 2394)'
211
);
212
);
213
is($reasons, undef);
212
214
213
# if IndependentBranches is OFF, a CPL patron cannot reserve an MPL item
215
# if IndependentBranches is OFF, a CPL patron cannot reserve an MPL item
214
t::lib::Mocks::mock_preference('IndependentBranches', 1);
216
t::lib::Mocks::mock_preference('IndependentBranches', 1);
215
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
217
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
218
($canitembereserved, $reasons) = CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber);
216
ok(
219
ok(
217
    ! CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber),
220
    ! $canitembereserved,
218
    'CPL patron NOT allowed to reserve MPL item with IndependentBranches ON ... (bug 2394)'
221
    'CPL patron NOT allowed to reserve MPL item with IndependentBranches ON ... (bug 2394)'
219
);
222
);
223
ok($reasons->{wrongbranch});
220
224
221
# ... unless canreservefromotherbranches is ON
225
# ... unless canreservefromotherbranches is ON
222
t::lib::Mocks::mock_preference('canreservefromotherbranches', 1);
226
t::lib::Mocks::mock_preference('canreservefromotherbranches', 1);
227
($canitembereserved, $reasons) = CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber);
223
ok(
228
ok(
224
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber),
229
    $canitembereserved,
225
    '... unless canreservefromotherbranches is ON (bug 2394)'
230
    '... unless canreservefromotherbranches is ON (bug 2394)'
226
);
231
);
232
is($reasons, undef);
227
233
228
# Regression test for bug 11336
234
# Regression test for bug 11336
229
($bibnum, $title, $bibitemnum) = create_helper_biblio();
235
($bibnum, $title, $bibitemnum) = create_helper_biblio();
Lines 288-304 ModReserve({ reserve_id => $reserveid2, rank => 'del' }); Link Here
288
$reserve3 = GetReserve( $reserveid3 );
294
$reserve3 = GetReserve( $reserveid3 );
289
is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
295
is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
290
296
291
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
292
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 1 );
297
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 1 );
293
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber), "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
294
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
298
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
299
300
CancelReserve({reserve_id => $reserveid3});
301
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
302
($canitembereserved, $reasons) = CanItemBeReserved($borrowernumbers[0], $itemnumber);
303
ok( $canitembereserved, "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
304
is($reasons, undef);
305
295
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 0 );
306
C4::Context->set_preference( 'AllowHoldsOnDamagedItems', 0 );
296
ok( !CanItemBeReserved( $borrowernumbers[0], $itemnumber), "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
307
($canitembereserved, $reasons) = CanItemBeReserved($borrowernumbers[0], $itemnumber);
308
ok( !$canitembereserved, "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
309
ok($reasons->{damaged});
297
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for damaged item with AllowHoldsOnDamagedItems disabled" );
310
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for damaged item with AllowHoldsOnDamagedItems disabled" );
298
311
299
# Regression test for bug 9532
312
# Regression test for bug 9532
300
($bibnum, $title, $bibitemnum) = create_helper_biblio('CANNOT');
313
($bibnum, $title, $bibitemnum) = create_helper_biblio('CANNOT');
301
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => 'CPL', holdingbranch => 'CPL', itype => 'CANNOT' } , $bibnum);
314
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem({ homebranch => 'CPL', holdingbranch => 'CPL', itype => 'CANNOT' } , $bibnum);
315
($canitembereserved) = CanItemBeReserved( $borrowernumbers[0], $itemnumber);
316
ok(
317
    !$canitembereserved,
318
    "cannot request item if policy that matches on item-level item type forbids it"
319
);
320
ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
321
($canitembereserved, $reasons) = CanItemBeReserved( $borrowernumbers[0], $itemnumber);
322
ok(
323
    $canitembereserved,
324
    "can request item if policy that matches on item type allows it"
325
);
326
302
AddReserve(
327
AddReserve(
303
    $branch,
328
    $branch,
304
    $borrowernumbers[0],
329
    $borrowernumbers[0],
Lines 307-338 AddReserve( Link Here
307
    '',
332
    '',
308
    1,
333
    1,
309
);
334
);
310
ok(
311
    !CanItemBeReserved( $borrowernumbers[0], $itemnumber),
312
    "cannot request item if policy that matches on item-level item type forbids it"
313
);
314
ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
315
ok(
316
    CanItemBeReserved( $borrowernumbers[0], $itemnumber),
317
    "can request item if policy that matches on item type allows it"
318
);
319
335
320
t::lib::Mocks::mock_preference('item-level_itypes', 0);
336
t::lib::Mocks::mock_preference('item-level_itypes', 0);
321
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
337
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
338
($canitembereserved) = CanItemBeReserved( $borrowernumbers[0], $itemnumber);
322
ok(
339
ok(
323
    !CanItemBeReserved( $borrowernumbers[0], $itemnumber),
340
    !$canitembereserved,
324
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
341
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
325
);
342
);
326
343
344
my $canbookbereserved;
345
($canbookbereserved, $reasons) = CanBookBeReserved($borrowernumbers[0], $bibnum);
346
ok(!$canbookbereserved);
347
ok($reasons->{alreadyreserved});
348
349
C4::Context->set_preference('maxreserves', 1);
350
($canbookbereserved, $reasons) = CanBookBeReserved($borrowernumbers[0], $biblionumber);
351
ok(!$canbookbereserved);
352
ok($reasons->{maxreserves});
353
354
C4::Context->set_preference('maxreserves', 0);
355
t::lib::Mocks::mock_preference('IndependentBranches', 1);
356
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
357
($canbookbereserved, $reasons) = CanBookBeReserved($borrowernumbers[0], $foreign_bibnum);
358
ok(!$canbookbereserved);
359
ok($reasons->{noholdableitems});
360
361
327
# Helper method to set up a Biblio.
362
# Helper method to set up a Biblio.
328
sub create_helper_biblio {
363
sub create_helper_biblio {
329
    my $itemtype = shift;
364
    my $itemtype = shift;
330
    my $bib = MARC::Record->new();
365
    my $bib = MARC::Record->new();
331
    my $title = 'Silence in the library';
366
    my $title = 'Silence in the library';
332
    $bib->append_fields(
367
    if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
333
        MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
368
        $bib->append_fields(
334
        MARC::Field->new('245', ' ', ' ', a => $title),
369
            MARC::Field->new('600', '', '1', a => 'Moffat, Steven'),
335
        MARC::Field->new('942', ' ', ' ', c => $itemtype),
370
            MARC::Field->new('200', '', '', a => $title),
336
    );
371
            MARC::Field->new('099', '', '', t => $itemtype),
372
        );
373
    } else {
374
        $bib->append_fields(
375
            MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
376
            MARC::Field->new('245', ' ', ' ', a => $title),
377
            MARC::Field->new('942', ' ', ' ', c => $itemtype),
378
        );
379
    }
337
    return ($bibnum, $title, $bibitemnum) = AddBiblio($bib, '');
380
    return ($bibnum, $title, $bibitemnum) = AddBiblio($bib, '');
338
}
381
}
339
- 

Return to bug 11999