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

(-)a/C4/Reserves.pm (-1 / +34 lines)
Lines 291-296 See CanItemBeReserved() for possible return values. Link Here
291
sub CanBookBeReserved{
291
sub CanBookBeReserved{
292
    my ($borrowernumber, $biblionumber) = @_;
292
    my ($borrowernumber, $biblionumber) = @_;
293
293
294
    # Check if borrower already has reserved the same biblio.
295
    my $patron = Koha::Patrons->find($borrowernumber);
296
    my $holds = $patron->holds;
297
    while (my $hold = $holds->next) {
298
        if ($hold->biblionumber == $biblionumber) {
299
            return 'alreadyReserved';
300
        }
301
    }
302
303
    # Check if borrower has reached the maximum number of holds allowed
304
    my $maxreserves = C4::Context->preference('maxreserves');
305
    if ($maxreserves && $holds->count >= $maxreserves) {
306
        return 'tooManyReserves';
307
    }
308
294
    my $items = GetItemnumbersForBiblio($biblionumber);
309
    my $items = GetItemnumbersForBiblio($biblionumber);
295
    #get items linked via host records
310
    #get items linked via host records
296
    my @hostitems = get_hostitemnumbers_of($biblionumber);
311
    my @hostitems = get_hostitemnumbers_of($biblionumber);
Lines 303-309 sub CanBookBeReserved{ Link Here
303
        $canReserve = CanItemBeReserved( $borrowernumber, $item );
318
        $canReserve = CanItemBeReserved( $borrowernumber, $item );
304
        return 'OK' if $canReserve eq 'OK';
319
        return 'OK' if $canReserve eq 'OK';
305
    }
320
    }
306
    return $canReserve;
321
322
    return 'none_available';
307
}
323
}
308
324
309
=head2 CanItemBeReserved
325
=head2 CanItemBeReserved
Lines 317-322 sub CanBookBeReserved{ Link Here
317
         cannotReserveFromOtherBranches, if syspref 'canreservefromotherbranches' is OK.
333
         cannotReserveFromOtherBranches, if syspref 'canreservefromotherbranches' is OK.
318
         tooManyReserves, if the borrower has exceeded his maximum reserve amount.
334
         tooManyReserves, if the borrower has exceeded his maximum reserve amount.
319
         notReservable,   if holds on this item are not allowed
335
         notReservable,   if holds on this item are not allowed
336
         alreadyReserved, if the borrower has already reserved this item.
320
337
321
=cut
338
=cut
322
339
Lines 349-354 sub CanItemBeReserved { Link Here
349
    return 'itemAlreadyOnHold'
366
    return 'itemAlreadyOnHold'
350
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
367
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
351
368
369
    # Check if borrower already has reserved the same item or biblio.
370
    my $holds = $patron->holds;
371
    while (my $hold = $holds->next) {
372
        if (   $hold->itemnumber == $itemnumber
373
            or $hold->biblionumber == $item->{biblionumber} )
374
        {
375
            return 'alreadyReserved';
376
        }
377
    }
378
379
    # Check if borrower has reached the maximum number of holds allowed
380
    my $maxreserves = C4::Context->preference('maxreserves');
381
    if ($maxreserves && $holds->count >= $maxreserves) {
382
        return 'tooManyReserves';
383
    }
384
352
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
385
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
353
386
354
    my $querycount = q{
387
    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 233-239 foreach my $biblionumber (@biblionumbers) { Link Here
233
                $exceeded_holds_per_record = 1;
233
                $exceeded_holds_per_record = 1;
234
                $biblioloopiter{$canReserve} = 1;
234
                $biblioloopiter{$canReserve} = 1;
235
            }
235
            }
236
            elsif ( $canReserve eq 'ageRestricted' ) {
236
            elsif ( grep { $canReserve eq $_ }
237
                (qw(ageRestricted alreadyReserved none_available)) )
238
            {
237
                $template->param( $canReserve => 1 );
239
                $template->param( $canReserve => 1 );
238
                $biblioloopiter{$canReserve} = 1;
240
                $biblioloopiter{$canReserve} = 1;
239
            }
241
            }
(-)a/t/db_dependent/Holds.t (-16 / +37 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 348-357 ModReserve({ reserve_id => $reserveid2, rank => 'del' }); Link Here
348
$reserve3 = GetReserve( $reserveid3 );
348
$reserve3 = GetReserve( $reserveid3 );
349
is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
349
is( $reserve3->{priority}, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
350
350
351
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
352
351
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
353
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
354
CancelReserve({reserve_id => $reserveid3});
352
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
355
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
353
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
356
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
354
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
355
357
356
$hold = Koha::Hold->new(
358
$hold = Koha::Hold->new(
357
    {
359
    {
Lines 379-401 AddReserve( Link Here
379
    '',
381
    '',
380
    1,
382
    1,
381
);
383
);
384
my ($bibnum2, $title2, $bibitemnum2) = create_helper_biblio('CANNOT');
385
my ($item_bibnum2, $item_bibitemnum2, $itemnumber2) = AddItem({ homebranch => $branch_1, holdingbranch => $branch_1, itype => 'CANNOT' } , $bibnum2);
382
is(
386
is(
383
    CanItemBeReserved( $borrowernumbers[0], $itemnumber), 'tooManyReserves',
387
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2), 'tooManyReserves',
384
    "cannot request item if policy that matches on item-level item type forbids it"
388
    "cannot request item if policy that matches on item-level item type forbids it"
385
);
389
);
386
ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
390
ModItem({ itype => 'CAN' }, $item_bibnum2, $itemnumber2);
387
ok(
391
ok(
388
    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'OK',
392
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2) eq 'OK',
389
    "can request item if policy that matches on item type allows it"
393
    "can request item if policy that matches on item type allows it"
390
);
394
);
391
395
392
t::lib::Mocks::mock_preference('item-level_itypes', 0);
396
t::lib::Mocks::mock_preference('item-level_itypes', 0);
393
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
397
ModItem({ itype => undef }, $item_bibnum2, $itemnumber2);
394
ok(
398
is(
395
    CanItemBeReserved( $borrowernumbers[0], $itemnumber) eq 'tooManyReserves',
399
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2), 'tooManyReserves',
396
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
400
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
397
);
401
);
398
402
403
is(CanBookBeReserved($borrowernumbers[0], $bibnum), 'OK');
404
405
C4::Context->set_preference('maxreserves', 1);
406
ok(CanBookBeReserved($borrowernumbers[0], $biblionumber) eq 'tooManyReserves');
407
408
C4::Context->set_preference('maxreserves', 0);
409
t::lib::Mocks::mock_preference('IndependentBranches', 1);
410
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
411
ok(CanBookBeReserved($borrowernumbers[0], $foreign_bibnum) eq 'none_available');
399
412
400
# Test branch item rules
413
# Test branch item rules
401
414
Lines 460-466 is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ), Link Here
460
my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, );
473
my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $bibnum, '', 1, );
461
474
462
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
475
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
463
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
476
    'tooManyHoldsForThisRecord', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
464
477
465
478
466
# Helper method to set up a Biblio.
479
# Helper method to set up a Biblio.
Lines 468-477 sub create_helper_biblio { Link Here
468
    my $itemtype = shift;
481
    my $itemtype = shift;
469
    my $bib = MARC::Record->new();
482
    my $bib = MARC::Record->new();
470
    my $title = 'Silence in the library';
483
    my $title = 'Silence in the library';
471
    $bib->append_fields(
484
    if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
472
        MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
485
        $bib->append_fields(
473
        MARC::Field->new('245', ' ', ' ', a => $title),
486
            MARC::Field->new('700', ' ', '0', a => 'Moffat, Steven'),
474
        MARC::Field->new('942', ' ', ' ', c => $itemtype),
487
            MARC::Field->new('200', ' ', ' ', a => $title),
475
    );
488
            MARC::Field->new('099', ' ', ' ', t => $itemtype),
476
    return ($bibnum, $title, $bibitemnum) = AddBiblio($bib, '');
489
        );
490
    } else {
491
        $bib->append_fields(
492
            MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
493
            MARC::Field->new('245', ' ', ' ', a => $title),
494
            MARC::Field->new('942', ' ', ' ', c => $itemtype),
495
        );
496
    }
497
498
    return AddBiblio($bib, '');
477
}
499
}
478
- 

Return to bug 11999