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

(-)a/C4/Reserves.pm (-1 / +33 lines)
Lines 325-330 See CanItemBeReserved() for possible return values. Link Here
325
sub CanBookBeReserved{
325
sub CanBookBeReserved{
326
    my ($borrowernumber, $biblionumber) = @_;
326
    my ($borrowernumber, $biblionumber) = @_;
327
327
328
    # Check if borrower already has reserved the same biblio.
329
    my @reserves = GetReservesFromBorrowernumber($borrowernumber);
330
    foreach my $reserve (@reserves) {
331
        if ($reserve->{biblionumber} == $biblionumber) {
332
            return 'alreadyReserved';
333
        }
334
    }
335
336
    # Check if borrower has reached the maximum number of holds allowed
337
    my $maxreserves = C4::Context->preference('maxreserves');
338
    if ($maxreserves && scalar(@reserves) >= $maxreserves) {
339
        return 'tooManyReserves';
340
    }
341
328
    my $items = GetItemnumbersForBiblio($biblionumber);
342
    my $items = GetItemnumbersForBiblio($biblionumber);
329
    #get items linked via host records
343
    #get items linked via host records
330
    my @hostitems = get_hostitemnumbers_of($biblionumber);
344
    my @hostitems = get_hostitemnumbers_of($biblionumber);
Lines 337-343 sub CanBookBeReserved{ Link Here
337
        $canReserve = CanItemBeReserved( $borrowernumber, $item );
351
        $canReserve = CanItemBeReserved( $borrowernumber, $item );
338
        return 'OK' if $canReserve eq 'OK';
352
        return 'OK' if $canReserve eq 'OK';
339
    }
353
    }
340
    return $canReserve;
354
355
    return 'none_available';
341
}
356
}
342
357
343
=head2 CanItemBeReserved
358
=head2 CanItemBeReserved
Lines 351-356 sub CanBookBeReserved{ Link Here
351
         cannotReserveFromOtherBranches, if syspref 'canreservefromotherbranches' is OK.
366
         cannotReserveFromOtherBranches, if syspref 'canreservefromotherbranches' is OK.
352
         tooManyReserves, if the borrower has exceeded his maximum reserve amount.
367
         tooManyReserves, if the borrower has exceeded his maximum reserve amount.
353
         notReservable,   if holds on this item are not allowed
368
         notReservable,   if holds on this item are not allowed
369
         alreadyReserved, if the borrower has already reserved this item.
354
370
355
=cut
371
=cut
356
372
Lines 382-387 sub CanItemBeReserved { Link Here
382
    return 'itemAlreadyOnHold'
398
    return 'itemAlreadyOnHold'
383
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
399
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
384
400
401
    # Check if borrower already has reserved the same item or biblio.
402
    my @reserves = GetReservesFromBorrowernumber($borrowernumber);
403
    foreach my $reserve (@reserves) {
404
        if (   $reserve->{itemnumber} == $itemnumber
405
            or $reserve->{biblionumber} == $item->{biblionumber} )
406
        {
407
            return 'alreadyReserved';
408
        }
409
    }
410
411
    # Check if borrower has reached the maximum number of holds allowed
412
    my $maxreserves = C4::Context->preference('maxreserves');
413
    if ($maxreserves && scalar(@reserves) >= $maxreserves) {
414
        return 'tooManyReserves';
415
    }
416
385
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
417
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
386
418
387
    my $querycount = q{
419
    my $querycount = q{
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-2 / +2 lines)
Lines 270-276 function checkMultiHold() { Link Here
270
    </form>
270
    </form>
271
  [% ELSIF NOT noitems %]
271
  [% ELSIF NOT noitems %]
272
272
273
[% IF ( exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || alreadypossession || ageRestricted ) %]
273
[% IF ( exceeded_maxreserves || exceeded_holds_per_record || alreadyReserved || none_available || alreadypossession || ageRestricted ) %]
274
    <div class="dialog alert">
274
    <div class="dialog alert">
275
275
276
    [% UNLESS ( multi_hold ) %]
276
    [% UNLESS ( multi_hold ) %]
Lines 282-288 function checkMultiHold() { Link Here
282
          <li><strong>Too many holds for this record: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %] </a> can only place a maximum of [% max_holds_for_record %] hold(s) on this record.</li>
282
          <li><strong>Too many holds for this record: </strong> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %] </a> can only place a maximum of [% max_holds_for_record %] hold(s) on this record.</li>
283
        [% ELSIF ( alreadypossession ) %]
283
        [% ELSIF ( alreadypossession ) %]
284
          <li> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>is already in possession</strong> of one item.</li>
284
          <li> <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>is already in possession</strong> of one item.</li>
285
        [% ELSIF ( alreadyreserved ) %]
285
        [% ELSIF ( alreadyReserved ) %]
286
          <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>already has a hold</strong> on this item.</li>
286
          <li><a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% borrowernumber %]">[% borrowerfirstname %] [% borrowersurname %]</a> <strong>already has a hold</strong> on this item.</li>
287
        [% ELSIF ( ageRestricted ) %]
287
        [% ELSIF ( ageRestricted ) %]
288
          <li><strong>Age restricted</strong></li>
288
          <li><strong>Age restricted</strong></li>
(-)a/reserve/request.pl (-1 / +3 lines)
Lines 228-234 foreach my $biblionumber (@biblionumbers) { Link Here
228
        $exceeded_holds_per_record = 1;
228
        $exceeded_holds_per_record = 1;
229
        $biblioloopiter{$canReserve} = 1;
229
        $biblioloopiter{$canReserve} = 1;
230
    }
230
    }
231
    elsif ( $canReserve eq 'ageRestricted' ) {
231
    elsif ( grep { $canReserve eq $_ }
232
        (qw(ageRestricted alreadyReserved none_available)) )
233
    {
232
        $template->param( $canReserve => 1 );
234
        $template->param( $canReserve => 1 );
233
        $biblioloopiter{$canReserve} = 1;
235
        $biblioloopiter{$canReserve} = 1;
234
    }
236
    }
(-)a/t/db_dependent/Holds.t (-14 / +35 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 => 58;
10
use Test::More tests => 61;
11
use MARC::Record;
11
use MARC::Record;
12
use C4::Biblio;
12
use C4::Biblio;
13
use C4::Items;
13
use C4::Items;
Lines 345-354 ModReserve({ reserve_id => $reserveid2, rank => 'del' }); Link Here
345
$reserve3 = GetReserve( $reserveid3 );
345
$reserve3 = GetReserve( $reserveid3 );
346
is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
346
is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
347
347
348
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
349
348
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
350
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
351
CancelReserve({reserve_id => $reserveid3});
349
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
352
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
350
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
353
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
351
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
352
354
353
$hold = Koha::Hold->new(
355
$hold = Koha::Hold->new(
354
    {
356
    {
Lines 376-398 AddReserve( Link Here
376
    '',
378
    '',
377
    1,
379
    1,
378
);
380
);
381
my ($bibnum2, $title2, $bibitemnum2) = create_helper_biblio('CANNOT');
382
my ($item_bibnum2, $item_bibitemnum2, $itemnumber2) = AddItem({ homebranch => $branch_1, holdingbranch => $branch_1, itype => 'CANNOT' } , $bibnum2);
379
is(
383
is(
380
    CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'tooManyReserves',
384
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2), 'tooManyReserves',
381
    "cannot request item if policy that matches on item-level item type forbids it"
385
    "cannot request item if policy that matches on item-level item type forbids it"
382
);
386
);
383
ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
387
ModItem({ itype => 'CAN' }, $item_bibnum2, $itemnumber2);
384
ok(
388
ok(
385
    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'OK',
389
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2) eq 'OK',
386
    "can request item if policy that matches on item type allows it"
390
    "can request item if policy that matches on item type allows it"
387
);
391
);
388
392
389
t::lib::Mocks::mock_preference('item-level_itypes', 0);
393
t::lib::Mocks::mock_preference('item-level_itypes', 0);
390
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
394
ModItem({ itype => undef }, $item_bibnum2, $itemnumber2);
391
ok(
395
ok(
392
    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'tooManyReserves',
396
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2) eq 'tooManyReserves',
393
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
397
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
394
);
398
);
395
399
400
is(CanBookBeReserved($borrowernumbers[0], $bibnum), 'alreadyReserved');
401
402
C4::Context->set_preference('maxreserves', 1);
403
ok(CanBookBeReserved($borrowernumbers[0], $biblionumber) eq 'tooManyReserves');
404
405
C4::Context->set_preference('maxreserves', 0);
406
t::lib::Mocks::mock_preference('IndependentBranches', 1);
407
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
408
ok(CanBookBeReserved($borrowernumbers[0], $foreign_bibnum) eq 'none_available');
396
409
397
# Test branch item rules
410
# Test branch item rules
398
411
Lines 465-474 sub create_helper_biblio { Link Here
465
    my $itemtype = shift;
478
    my $itemtype = shift;
466
    my $bib = MARC::Record->new();
479
    my $bib = MARC::Record->new();
467
    my $title = 'Silence in the library';
480
    my $title = 'Silence in the library';
468
    $bib->append_fields(
481
    if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
469
        MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
482
        $bib->append_fields(
470
        MARC::Field->new('245', ' ', ' ', a => $title),
483
            MARC::Field->new('700', ' ', '0', a => 'Moffat, Steven'),
471
        MARC::Field->new('942', ' ', ' ', c => $itemtype),
484
            MARC::Field->new('200', ' ', ' ', a => $title),
472
    );
485
            MARC::Field->new('099', ' ', ' ', t => $itemtype),
473
    return ($bibnum, $title, $bibitemnum) = AddBiblio($bib, '');
486
        );
487
    } else {
488
        $bib->append_fields(
489
            MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
490
            MARC::Field->new('245', ' ', ' ', a => $title),
491
            MARC::Field->new('942', ' ', ' ', c => $itemtype),
492
        );
493
    }
494
495
    return AddBiblio($bib, '');
474
}
496
}
475
- 

Return to bug 11999