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

(-)a/C4/ILSDI/Services.pm (-3 / +3 lines)
Lines 542-548 sub GetServices { Link Here
542
    # Reserve level management
542
    # Reserve level management
543
    my $biblionumber = $item->{'biblionumber'};
543
    my $biblionumber = $item->{'biblionumber'};
544
    my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
544
    my $canbookbereserved = CanBookBeReserved( $borrower, $biblionumber );
545
    if ($canbookbereserved eq 'OK') {
545
    if ($canbookbereserved->{status} eq 'OK') {
546
        push @availablefor, 'title level hold';
546
        push @availablefor, 'title level hold';
547
        my $canitembereserved = IsAvailableForItemLevelRequest($item, $borrower);
547
        my $canitembereserved = IsAvailableForItemLevelRequest($item, $borrower);
548
        if ($canitembereserved) {
548
        if ($canitembereserved) {
Lines 662-668 sub HoldTitle { Link Here
662
    my $title = $biblio ? $biblio->title : '';
662
    my $title = $biblio ? $biblio->title : '';
663
663
664
    # Check if the biblio can be reserved
664
    # Check if the biblio can be reserved
665
    return { code => 'NotHoldable' } unless CanBookBeReserved( $borrowernumber, $biblionumber ) eq 'OK';
665
    return { code => 'NotHoldable' } unless CanBookBeReserved( $borrowernumber, $biblionumber )->{status} eq 'OK';
666
666
667
    my $branch;
667
    my $branch;
668
668
Lines 740-746 sub HoldItem { Link Here
740
    # Check for item disponibility
740
    # Check for item disponibility
741
    my $canitembereserved = C4::Reserves::CanItemBeReserved( $borrowernumber, $itemnumber );
741
    my $canitembereserved = C4::Reserves::CanItemBeReserved( $borrowernumber, $itemnumber );
742
    my $canbookbereserved = C4::Reserves::CanBookBeReserved( $borrowernumber, $biblionumber );
742
    my $canbookbereserved = C4::Reserves::CanBookBeReserved( $borrowernumber, $biblionumber );
743
    return { code => 'NotHoldable' } unless $canbookbereserved eq 'OK' and $canitembereserved eq 'OK';
743
    return { code => 'NotHoldable' } unless $canbookbereserved->{status} eq 'OK' and $canitembereserved->{status} eq 'OK';
744
744
745
    # Pickup branch management
745
    # Pickup branch management
746
    my $branch;
746
    my $branch;
(-)a/C4/Reserves.pm (-18 / +18 lines)
Lines 285-291 sub CanBookBeReserved{ Link Here
285
    my $canReserve;
285
    my $canReserve;
286
    foreach my $item (@$items) {
286
    foreach my $item (@$items) {
287
        $canReserve = CanItemBeReserved( $borrowernumber, $item );
287
        $canReserve = CanItemBeReserved( $borrowernumber, $item );
288
        return 'OK' if $canReserve eq 'OK';
288
        return $canReserve if $canReserve->{status} eq 'OK';
289
    }
289
    }
290
    return $canReserve;
290
    return $canReserve;
291
}
291
}
Lines 293-306 sub CanBookBeReserved{ Link Here
293
=head2 CanItemBeReserved
293
=head2 CanItemBeReserved
294
294
295
  $canReserve = &CanItemBeReserved($borrowernumber, $itemnumber)
295
  $canReserve = &CanItemBeReserved($borrowernumber, $itemnumber)
296
  if ($canReserve eq 'OK') { #We can reserve this Item! }
296
  if ($canReserve->{status} eq 'OK') { #We can reserve this Item! }
297
297
298
@RETURNS OK,              if the Item can be reserved.
298
@RETURNS { status => OK },              if the Item can be reserved.
299
         ageRestricted,   if the Item is age restricted for this borrower.
299
         { status => ageRestricted },   if the Item is age restricted for this borrower.
300
         damaged,         if the Item is damaged.
300
         { status => damaged },         if the Item is damaged.
301
         cannotReserveFromOtherBranches, if syspref 'canreservefromotherbranches' is OK.
301
         { status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK.
302
         tooManyReserves, if the borrower has exceeded his maximum reserve amount.
302
         { status => tooManyReserves, limit => $limit }, if the borrower has exceeded his maximum reserve amount.
303
         notReservable,   if holds on this item are not allowed
303
         { status => notReservable },   if holds on this item are not allowed
304
304
305
=cut
305
=cut
306
306
Lines 320-336 sub CanItemBeReserved { Link Here
320
    my $borrower = $patron->unblessed;
320
    my $borrower = $patron->unblessed;
321
321
322
    # If an item is damaged and we don't allow holds on damaged items, we can stop right here
322
    # If an item is damaged and we don't allow holds on damaged items, we can stop right here
323
    return 'damaged'
323
    return { status =>'damaged' }
324
      if ( $item->{damaged}
324
      if ( $item->{damaged}
325
        && !C4::Context->preference('AllowHoldsOnDamagedItems') );
325
        && !C4::Context->preference('AllowHoldsOnDamagedItems') );
326
326
327
    # Check for the age restriction
327
    # Check for the age restriction
328
    my ( $ageRestriction, $daysToAgeRestriction ) =
328
    my ( $ageRestriction, $daysToAgeRestriction ) =
329
      C4::Circulation::GetAgeRestriction( $biblio->biblioitem->agerestriction, $borrower );
329
      C4::Circulation::GetAgeRestriction( $biblio->biblioitem->agerestriction, $borrower );
330
    return 'ageRestricted' if $daysToAgeRestriction && $daysToAgeRestriction > 0;
330
    return { status => 'ageRestricted' } if $daysToAgeRestriction && $daysToAgeRestriction > 0;
331
331
332
    # Check that the patron doesn't have an item level hold on this item already
332
    # Check that the patron doesn't have an item level hold on this item already
333
    return 'itemAlreadyOnHold'
333
    return { status =>'itemAlreadyOnHold' }
334
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
334
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
335
335
336
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
336
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
Lines 375-381 sub CanItemBeReserved { Link Here
375
        }
375
        }
376
    );
376
    );
377
    if ( $holds->count() >= $holds_per_record ) {
377
    if ( $holds->count() >= $holds_per_record ) {
378
        return "tooManyHoldsForThisRecord";
378
        return { status => "tooManyHoldsForThisRecord", limit => $holds_per_record };
379
    }
379
    }
380
380
381
    # we retrieve count
381
    # we retrieve count
Lines 406-412 sub CanItemBeReserved { Link Here
406
406
407
    # we check if it's ok or not
407
    # we check if it's ok or not
408
    if ( $reservecount >= $allowedreserves ) {
408
    if ( $reservecount >= $allowedreserves ) {
409
        return 'tooManyReserves';
409
        return { status => 'tooManyReserves', limit => $allowedreserves };
410
    }
410
    }
411
411
412
    # Now we need to check hold limits by patron category
412
    # Now we need to check hold limits by patron category
Lines 429-435 sub CanItemBeReserved { Link Here
429
            }
429
            }
430
        )->count();
430
        )->count();
431
431
432
        return 'tooManyReserves' if $total_holds_count >= $rule->max_holds;
432
        return { status => 'tooManyReserves', limit => $rule->max_holds } if $total_holds_count >= $rule->max_holds;
433
    }
433
    }
434
434
435
    my $circ_control_branch =
435
    my $circ_control_branch =
Lines 438-450 sub CanItemBeReserved { Link Here
438
      C4::Circulation::GetBranchItemRule( $circ_control_branch, $item->itype );
438
      C4::Circulation::GetBranchItemRule( $circ_control_branch, $item->itype );
439
439
440
    if ( $branchitemrule->{holdallowed} == 0 ) {
440
    if ( $branchitemrule->{holdallowed} == 0 ) {
441
        return 'notReservable';
441
        return { status => 'notReservable' };
442
    }
442
    }
443
443
444
    if (   $branchitemrule->{holdallowed} == 1
444
    if (   $branchitemrule->{holdallowed} == 1
445
        && $borrower->{branchcode} ne $item->homebranch )
445
        && $borrower->{branchcode} ne $item->homebranch )
446
    {
446
    {
447
        return 'cannotReserveFromOtherBranches';
447
        return { status => 'cannotReserveFromOtherBranches' };
448
    }
448
    }
449
449
450
    # If reservecount is ok, we check item branch if IndependentBranches is ON
450
    # If reservecount is ok, we check item branch if IndependentBranches is ON
Lines 454-464 sub CanItemBeReserved { Link Here
454
    {
454
    {
455
        my $itembranch = $item->homebranch;
455
        my $itembranch = $item->homebranch;
456
        if ( $itembranch ne $borrower->{branchcode} ) {
456
        if ( $itembranch ne $borrower->{branchcode} ) {
457
            return 'cannotReserveFromOtherBranches';
457
            return { status => 'cannotReserveFromOtherBranches' };
458
        }
458
        }
459
    }
459
    }
460
460
461
    return 'OK';
461
    return { status => 'OK' };
462
}
462
}
463
463
464
=head2 CanReserveBeCanceledFromOpac
464
=head2 CanReserveBeCanceledFromOpac
(-)a/Koha/REST/V1/Hold.pm (-1 / +1 lines)
Lines 89-95 sub add { Link Here
89
      ? CanItemBeReserved( $borrowernumber, $itemnumber )
89
      ? CanItemBeReserved( $borrowernumber, $itemnumber )
90
      : CanBookBeReserved( $borrowernumber, $biblionumber );
90
      : CanBookBeReserved( $borrowernumber, $biblionumber );
91
91
92
    unless ($can_reserve eq 'OK') {
92
    unless ($can_reserve->{status} eq 'OK') {
93
        return $c->render( status => 403, openapi => {
93
        return $c->render( status => 403, openapi => {
94
            error => "Reserve cannot be placed. Reason: $can_reserve"
94
            error => "Reserve cannot be placed. Reason: $can_reserve"
95
        } );
95
        } );
(-)a/opac/opac-reserve.pl (-4 / +4 lines)
Lines 269-278 if ( $query->param('place_reserve') ) { Link Here
269
269
270
        my $rank = $biblioData->{rank};
270
        my $rank = $biblioData->{rank};
271
        if ( $itemNum ne '' ) {
271
        if ( $itemNum ne '' ) {
272
            $canreserve = 1 if CanItemBeReserved( $borrowernumber, $itemNum ) eq 'OK';
272
            $canreserve = 1 if CanItemBeReserved( $borrowernumber, $itemNum )->{status} eq 'OK';
273
        }
273
        }
274
        else {
274
        else {
275
            $canreserve = 1 if CanBookBeReserved( $borrowernumber, $biblioNum ) eq 'OK';
275
            $canreserve = 1 if CanBookBeReserved( $borrowernumber, $biblioNum )->{status} eq 'OK';
276
276
277
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
277
            # Inserts a null into the 'itemnumber' field of 'reserves' table.
278
            $itemNum = undef;
278
            $itemNum = undef;
Lines 525-531 foreach my $biblioNum (@biblionumbers) { Link Here
525
        my $policy_holdallowed = !$itemLoopIter->{already_reserved};
525
        my $policy_holdallowed = !$itemLoopIter->{already_reserved};
526
        $policy_holdallowed &&=
526
        $policy_holdallowed &&=
527
            IsAvailableForItemLevelRequest($itemInfo,$patron_unblessed) &&
527
            IsAvailableForItemLevelRequest($itemInfo,$patron_unblessed) &&
528
            CanItemBeReserved($borrowernumber,$itemNum) eq 'OK';
528
            CanItemBeReserved($borrowernumber,$itemNum)->{status} eq 'OK';
529
529
530
        if ($policy_holdallowed) {
530
        if ($policy_holdallowed) {
531
            my $opac_hold_policy = Koha::IssuingRules->get_opacitemholds_policy( { item => $item, patron => $patron } );
531
            my $opac_hold_policy = Koha::IssuingRules->get_opacitemholds_policy( { item => $item, patron => $patron } );
Lines 585-591 foreach my $biblioNum (@biblionumbers) { Link Here
585
        }
585
        }
586
    }
586
    }
587
587
588
    $biblioLoopIter{holdable} &&= CanBookBeReserved($borrowernumber,$biblioNum) eq 'OK';
588
    $biblioLoopIter{holdable} &&= CanBookBeReserved($borrowernumber,$biblioNum)->{status} eq 'OK';
589
589
590
    # For multiple holds per record, if a patron has previously placed a hold,
590
    # For multiple holds per record, if a patron has previously placed a hold,
591
    # the patron can only place more holds of the same type. That is, if the
591
    # the patron can only place more holds of the same type. That is, if the
(-)a/reserve/request.pl (-10 / +11 lines)
Lines 211-234 foreach my $biblionumber (@biblionumbers) { Link Here
211
    if ( $patron ) {
211
    if ( $patron ) {
212
        { # CanBookBeReserved
212
        { # CanBookBeReserved
213
            my $canReserve = CanBookBeReserved( $patron->borrowernumber, $biblionumber );
213
            my $canReserve = CanBookBeReserved( $patron->borrowernumber, $biblionumber );
214
            $canReserve //= '';
214
            $canReserve->{status} //= '';
215
            if ( $canReserve eq 'OK' ) {
215
            if ( $canReserve->{status} eq 'OK' ) {
216
216
217
                #All is OK and we can continue
217
                #All is OK and we can continue
218
            }
218
            }
219
            elsif ( $canReserve eq 'tooManyReserves' ) {
219
            elsif ( $canReserve->{status} eq 'tooManyReserves' ) {
220
                $exceeded_maxreserves = 1;
220
                $exceeded_maxreserves = 1;
221
                $template->param( maxreserves => $canReserve->{limit} );
221
            }
222
            }
222
            elsif ( $canReserve eq 'tooManyHoldsForThisRecord' ) {
223
            elsif ( $canReserve->{status} eq 'tooManyHoldsForThisRecord' ) {
223
                $exceeded_holds_per_record = 1;
224
                $exceeded_holds_per_record = 1;
224
                $biblioloopiter{$canReserve} = 1;
225
                $biblioloopiter{ $canReserve->{status} } = 1;
225
            }
226
            }
226
            elsif ( $canReserve eq 'ageRestricted' ) {
227
            elsif ( $canReserve->{status} eq 'ageRestricted' ) {
227
                $template->param( $canReserve => 1 );
228
                $template->param( $canReserve->{status} => 1 );
228
                $biblioloopiter{$canReserve} = 1;
229
                $biblioloopiter{ $canReserve->{status} } = 1;
229
            }
230
            }
230
            else {
231
            else {
231
                $biblioloopiter{$canReserve} = 1;
232
                $biblioloopiter{ $canReserve->{status} } = 1;
232
            }
233
            }
233
        }
234
        }
234
235
Lines 462-468 foreach my $biblionumber (@biblionumbers) { Link Here
462
                $item->{'holdallowed'} = $branchitemrule->{'holdallowed'};
463
                $item->{'holdallowed'} = $branchitemrule->{'holdallowed'};
463
464
464
                my $can_item_be_reserved = CanItemBeReserved( $patron->borrowernumber, $itemnumber );
465
                my $can_item_be_reserved = CanItemBeReserved( $patron->borrowernumber, $itemnumber );
465
                $item->{not_holdable} = $can_item_be_reserved unless ( $can_item_be_reserved eq 'OK' );
466
                $item->{not_holdable} = $can_item_be_reserved->{status} unless ( $can_item_be_reserved->{status} eq 'OK' );
466
467
467
                $item->{item_level_holds} = Koha::IssuingRules->get_opacitemholds_policy( { item => $item_object, patron => $patron } );
468
                $item->{item_level_holds} = Koha::IssuingRules->get_opacitemholds_policy( { item => $item_object, patron => $patron } );
468
469
(-)a/t/db_dependent/Holds.t (-20 / +20 lines)
Lines 7-13 use t::lib::TestBuilder; Link Here
7
7
8
use C4::Context;
8
use C4::Context;
9
9
10
use Test::More tests => 56;
10
use Test::More tests => 55;
11
use MARC::Record;
11
use MARC::Record;
12
use Koha::Patrons;
12
use Koha::Patrons;
13
use C4::Items;
13
use C4::Items;
Lines 261-267 t::lib::Mocks::mock_preference('item-level_itypes', 1); Link Here
261
# if IndependentBranches is OFF, a $branch_1 patron can reserve an $branch_2 item
261
# if IndependentBranches is OFF, a $branch_1 patron can reserve an $branch_2 item
262
t::lib::Mocks::mock_preference('IndependentBranches', 0);
262
t::lib::Mocks::mock_preference('IndependentBranches', 0);
263
ok(
263
ok(
264
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber) eq 'OK',
264
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status} eq 'OK',
265
    '$branch_1 patron allowed to reserve $branch_2 item with IndependentBranches OFF (bug 2394)'
265
    '$branch_1 patron allowed to reserve $branch_2 item with IndependentBranches OFF (bug 2394)'
266
);
266
);
267
267
Lines 269-282 ok( Link Here
269
t::lib::Mocks::mock_preference('IndependentBranches', 1);
269
t::lib::Mocks::mock_preference('IndependentBranches', 1);
270
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
270
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
271
ok(
271
ok(
272
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber) eq 'cannotReserveFromOtherBranches',
272
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status} eq 'cannotReserveFromOtherBranches',
273
    '$branch_1 patron NOT allowed to reserve $branch_2 item with IndependentBranches ON ... (bug 2394)'
273
    '$branch_1 patron NOT allowed to reserve $branch_2 item with IndependentBranches ON ... (bug 2394)'
274
);
274
);
275
275
276
# ... unless canreservefromotherbranches is ON
276
# ... unless canreservefromotherbranches is ON
277
t::lib::Mocks::mock_preference('canreservefromotherbranches', 1);
277
t::lib::Mocks::mock_preference('canreservefromotherbranches', 1);
278
ok(
278
ok(
279
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber) eq 'OK',
279
    CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status} eq 'OK',
280
    '... unless canreservefromotherbranches is ON (bug 2394)'
280
    '... unless canreservefromotherbranches is ON (bug 2394)'
281
);
281
);
282
282
Lines 299-305 ok( Link Here
299
299
300
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
300
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
301
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
301
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
302
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
302
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
303
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
303
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
304
304
305
$hold = Koha::Hold->new(
305
$hold = Koha::Hold->new(
Lines 309-321 $hold = Koha::Hold->new( Link Here
309
        biblionumber   => $item_bibnum,
309
        biblionumber   => $item_bibnum,
310
    }
310
    }
311
)->store();
311
)->store();
312
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
312
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status},
313
    'itemAlreadyOnHold',
313
    'itemAlreadyOnHold',
314
    "Patron cannot place a second item level hold for a given item" );
314
    "Patron cannot place a second item level hold for a given item" );
315
$hold->delete();
315
$hold->delete();
316
316
317
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 0 );
317
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 0 );
318
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
318
ok( CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'damaged', "Patron cannot reserve damaged item with AllowHoldsOnDamagedItems disabled" );
319
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for damaged item with AllowHoldsOnDamagedItems disabled" );
319
ok( !defined( ( CheckReserves($itemnumber) )[1] ), "Hold cannot be trapped for damaged item with AllowHoldsOnDamagedItems disabled" );
320
320
321
# Regression test for bug 9532
321
# Regression test for bug 9532
Lines 329-347 AddReserve( Link Here
329
    1,
329
    1,
330
);
330
);
331
is(
331
is(
332
    CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'tooManyReserves',
332
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'tooManyReserves',
333
    "cannot request item if policy that matches on item-level item type forbids it"
333
    "cannot request item if policy that matches on item-level item type forbids it"
334
);
334
);
335
ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
335
ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
336
ok(
336
ok(
337
    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'OK',
337
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'OK',
338
    "can request item if policy that matches on item type allows it"
338
    "can request item if policy that matches on item type allows it"
339
);
339
);
340
340
341
t::lib::Mocks::mock_preference('item-level_itypes', 0);
341
t::lib::Mocks::mock_preference('item-level_itypes', 0);
342
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
342
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
343
ok(
343
ok(
344
    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'tooManyReserves',
344
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'tooManyReserves',
345
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
345
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
346
);
346
);
347
347
Lines 370-387 $dbh->do(q{ Link Here
370
($bibnum, $title, $bibitemnum) = create_helper_biblio('CANNOT');
370
($bibnum, $title, $bibitemnum) = create_helper_biblio('CANNOT');
371
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem(
371
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem(
372
    { homebranch => $branch_1, holdingbranch => $branch_1, itype => 'CANNOT' } , $bibnum);
372
    { homebranch => $branch_1, holdingbranch => $branch_1, itype => 'CANNOT' } , $bibnum);
373
is(CanItemBeReserved($borrowernumbers[0], $itemnumber), 'notReservable',
373
is(CanItemBeReserved($borrowernumbers[0], $itemnumber)->{status}, 'notReservable',
374
    "CanItemBeReserved should return 'notReservable'");
374
    "CanItemBeReserved should return 'notReservable'");
375
375
376
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem(
376
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem(
377
    { homebranch => $branch_2, holdingbranch => $branch_1, itype => 'CAN' } , $bibnum);
377
    { homebranch => $branch_2, holdingbranch => $branch_1, itype => 'CAN' } , $bibnum);
378
is(CanItemBeReserved($borrowernumbers[0], $itemnumber),
378
is(CanItemBeReserved($borrowernumbers[0], $itemnumber)->{status},
379
    'cannotReserveFromOtherBranches',
379
    'cannotReserveFromOtherBranches',
380
    "CanItemBeReserved should return 'cannotReserveFromOtherBranches'");
380
    "CanItemBeReserved should return 'cannotReserveFromOtherBranches'");
381
381
382
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem(
382
($item_bibnum, $item_bibitemnum, $itemnumber) = AddItem(
383
    { homebranch => $branch_1, holdingbranch => $branch_1, itype => 'CAN' } , $bibnum);
383
    { homebranch => $branch_1, holdingbranch => $branch_1, itype => 'CAN' } , $bibnum);
384
is(CanItemBeReserved($borrowernumbers[0], $itemnumber), 'OK',
384
is(CanItemBeReserved($borrowernumbers[0], $itemnumber)->{status}, 'OK',
385
    "CanItemBeReserved should return 'OK'");
385
    "CanItemBeReserved should return 'OK'");
386
386
387
# Bug 12632
387
# Bug 12632
Lines 403-414 $dbh->do( Link Here
403
    {},
403
    {},
404
    '*', '*', 'ONLY1', 1, 99
404
    '*', '*', 'ONLY1', 1, 99
405
);
405
);
406
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
406
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status},
407
    'OK', 'Patron can reserve item with hold limit of 1, no holds placed' );
407
    'OK', 'Patron can reserve item with hold limit of 1, no holds placed' );
408
408
409
my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, );
409
my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, );
410
410
411
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
411
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status},
412
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
412
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
413
413
414
subtest 'Test max_holds per library/patron category' => sub {
414
subtest 'Test max_holds per library/patron category' => sub {
Lines 438-444 subtest 'Test max_holds per library/patron category' => sub { Link Here
438
    is( $count, 3, 'Patron now has 3 holds' );
438
    is( $count, 3, 'Patron now has 3 holds' );
439
439
440
    my $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
440
    my $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
441
    is( $ret, 'OK', 'Patron can place hold with no borrower circ rules' );
441
    is( $ret->{status}, 'OK', 'Patron can place hold with no borrower circ rules' );
442
442
443
    my $rule_all = $schema->resultset('DefaultBorrowerCircRule')->new(
443
    my $rule_all = $schema->resultset('DefaultBorrowerCircRule')->new(
444
        {
444
        {
Lines 456-474 subtest 'Test max_holds per library/patron category' => sub { Link Here
456
    )->insert();
456
    )->insert();
457
457
458
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
458
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
459
    is( $ret, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 3' );
459
    is( $ret->{status}, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 3' );
460
460
461
    $rule_branch->delete();
461
    $rule_branch->delete();
462
462
463
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
463
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
464
    is( $ret, 'tooManyReserves', 'Patron cannot place hold with only a category rule of 3' );
464
    is( $ret->{status}, 'tooManyReserves', 'Patron cannot place hold with only a category rule of 3' );
465
465
466
    $rule_all->delete();
466
    $rule_all->delete();
467
    $rule_branch->max_holds(3);
467
    $rule_branch->max_holds(3);
468
    $rule_branch->insert();
468
    $rule_branch->insert();
469
469
470
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
470
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
471
    is( $ret, 'tooManyReserves', 'Patron cannot place hold with only a branch/category rule of 3' );
471
    is( $ret->{status}, 'tooManyReserves', 'Patron cannot place hold with only a branch/category rule of 3' );
472
472
473
    $rule_branch->max_holds(5);
473
    $rule_branch->max_holds(5);
474
    $rule_branch->update();
474
    $rule_branch->update();
Lines 476-482 subtest 'Test max_holds per library/patron category' => sub { Link Here
476
    $rule_all->insert();
476
    $rule_all->insert();
477
477
478
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
478
    $ret = CanItemBeReserved( $borrowernumbers[0], $itemnumber );
479
    is( $ret, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 5' );
479
    is( $ret->{status}, 'OK', 'Patron can place hold with branch/category rule of 5, category rule of 5' );
480
};
480
};
481
481
482
# Helper method to set up a Biblio.
482
# Helper method to set up a Biblio.
(-)a/t/db_dependent/Reserves.t (-3 / +3 lines)
Lines 522-540 my ( $ageres_tagid, $ageres_subfieldid ) = GetMarcFromKohaField( "biblioitems.ag Link Here
522
$record->append_fields(  MARC::Field->new($ageres_tagid, '', '', $ageres_subfieldid => 'PEGI 16')  );
522
$record->append_fields(  MARC::Field->new($ageres_tagid, '', '', $ageres_subfieldid => 'PEGI 16')  );
523
C4::Biblio::ModBiblio( $record, $bibnum, $frameworkcode );
523
C4::Biblio::ModBiblio( $record, $bibnum, $frameworkcode );
524
524
525
is( C4::Reserves::CanBookBeReserved($borrowernumber, $biblionumber) , 'OK', "Reserving an ageRestricted Biblio without a borrower dateofbirth succeeds" );
525
is( C4::Reserves::CanBookBeReserved($borrowernumber, $biblionumber)->{status} , 'OK', "Reserving an ageRestricted Biblio without a borrower dateofbirth succeeds" );
526
526
527
#Set the dateofbirth for the Borrower making them "too young".
527
#Set the dateofbirth for the Borrower making them "too young".
528
$borrower->{dateofbirth} = DateTime->now->add( years => -15 );
528
$borrower->{dateofbirth} = DateTime->now->add( years => -15 );
529
Koha::Patrons->find( $borrowernumber )->set({ dateofbirth => $borrower->{dateofbirth} })->store;
529
Koha::Patrons->find( $borrowernumber )->set({ dateofbirth => $borrower->{dateofbirth} })->store;
530
530
531
is( C4::Reserves::CanBookBeReserved($borrowernumber, $biblionumber) , 'ageRestricted', "Reserving a 'PEGI 16' Biblio by a 15 year old borrower fails");
531
is( C4::Reserves::CanBookBeReserved($borrowernumber, $biblionumber)->{status} , 'ageRestricted', "Reserving a 'PEGI 16' Biblio by a 15 year old borrower fails");
532
532
533
#Set the dateofbirth for the Borrower making them "too old".
533
#Set the dateofbirth for the Borrower making them "too old".
534
$borrower->{dateofbirth} = DateTime->now->add( years => -30 );
534
$borrower->{dateofbirth} = DateTime->now->add( years => -30 );
535
Koha::Patrons->find( $borrowernumber )->set({ dateofbirth => $borrower->{dateofbirth} })->store;
535
Koha::Patrons->find( $borrowernumber )->set({ dateofbirth => $borrower->{dateofbirth} })->store;
536
536
537
is( C4::Reserves::CanBookBeReserved($borrowernumber, $biblionumber) , 'OK', "Reserving a 'PEGI 16' Biblio by a 30 year old borrower succeeds");
537
is( C4::Reserves::CanBookBeReserved($borrowernumber, $biblionumber)->{status} , 'OK', "Reserving a 'PEGI 16' Biblio by a 30 year old borrower succeeds");
538
       ####
538
       ####
539
####### EO Bug 13113 <<<
539
####### EO Bug 13113 <<<
540
       ####
540
       ####
(-)a/t/db_dependent/Reserves/MultiplePerRecord.t (-4 / +3 lines)
Lines 277-293 $rule = $rules_rs->new( Link Here
277
)->insert();
277
)->insert();
278
278
279
my $can = CanBookBeReserved($patron->{borrowernumber}, $biblio->{biblionumber});
279
my $can = CanBookBeReserved($patron->{borrowernumber}, $biblio->{biblionumber});
280
is( $can, 'OK', 'Hold can be placed with 0 holds' );
280
is( $can->{status}, 'OK', 'Hold can be placed with 0 holds' );
281
my $hold_id = AddReserve( $library->{branchcode}, $patron->{borrowernumber}, $biblio->{biblionumber}, '', 1 );
281
my $hold_id = AddReserve( $library->{branchcode}, $patron->{borrowernumber}, $biblio->{biblionumber}, '', 1 );
282
ok( $hold_id, 'First hold was placed' );
282
ok( $hold_id, 'First hold was placed' );
283
283
284
$can = CanBookBeReserved($patron->{borrowernumber}, $biblio->{biblionumber});
284
$can = CanBookBeReserved($patron->{borrowernumber}, $biblio->{biblionumber});
285
is( $can, 'OK', 'Hold can be placed with 1 hold' );
285
is( $can->{status}, 'OK', 'Hold can be placed with 1 hold' );
286
$hold_id = AddReserve( $library->{branchcode}, $patron->{borrowernumber}, $biblio->{biblionumber}, '', 1 );
286
$hold_id = AddReserve( $library->{branchcode}, $patron->{borrowernumber}, $biblio->{biblionumber}, '', 1 );
287
ok( $hold_id, 'Second hold was placed' );
287
ok( $hold_id, 'Second hold was placed' );
288
288
289
$can = CanBookBeReserved($patron->{borrowernumber}, $biblio->{biblionumber});
289
$can = CanBookBeReserved($patron->{borrowernumber}, $biblio->{biblionumber});
290
is( $can, 'tooManyHoldsForThisRecord', 'Third hold exceeds limit of holds per record' );
290
is( $can->{status}, 'tooManyHoldsForThisRecord', 'Third hold exceeds limit of holds per record' );
291
291
292
$schema->storage->txn_rollback;
292
$schema->storage->txn_rollback;
293
293
294
- 

Return to bug 15524