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

(-)a/C4/Reserves.pm (-1 / +44 lines)
Lines 274-280 See CanItemBeReserved() for possible return values. Link Here
274
sub CanBookBeReserved{
274
sub CanBookBeReserved{
275
    my ($borrowernumber, $biblionumber, $pickup_branchcode) = @_;
275
    my ($borrowernumber, $biblionumber, $pickup_branchcode) = @_;
276
276
277
    # Check if borrower already has reserved the same biblio.
278
    my $patron = Koha::Patrons->find($borrowernumber);
279
    my $holds = $patron->holds;
280
    while (my $hold = $holds->next) {
281
        if ($hold->biblionumber == $biblionumber) {
282
            return { status => 'alreadyReserved' };
283
        }
284
    }
285
286
    # Check if borrower has reached the maximum number of holds allowed
287
    my $maxreserves = C4::Context->preference('maxreserves');
288
    if ($maxreserves && $holds->count >= $maxreserves) {
289
        return { status => 'tooManyReserves' };
290
    }
291
277
    my @itemnumbers = Koha::Items->search({ biblionumber => $biblionumber})->get_column("itemnumber");
292
    my @itemnumbers = Koha::Items->search({ biblionumber => $biblionumber})->get_column("itemnumber");
293
278
    #get items linked via host records
294
    #get items linked via host records
279
    my @hostitems = get_hostitemnumbers_of($biblionumber);
295
    my @hostitems = get_hostitemnumbers_of($biblionumber);
280
    if (@hostitems){
296
    if (@hostitems){
Lines 286-292 sub CanBookBeReserved{ Link Here
286
        $canReserve = CanItemBeReserved( $borrowernumber, $itemnumber, $pickup_branchcode );
302
        $canReserve = CanItemBeReserved( $borrowernumber, $itemnumber, $pickup_branchcode );
287
        return { status => 'OK' } if $canReserve->{status} eq 'OK';
303
        return { status => 'OK' } if $canReserve->{status} eq 'OK';
288
    }
304
    }
289
    return $canReserve;
305
306
    return { status => 'none_available' };
290
}
307
}
291
308
292
=head2 CanItemBeReserved
309
=head2 CanItemBeReserved
Lines 294-299 sub CanBookBeReserved{ Link Here
294
  $canReserve = &CanItemBeReserved($borrowernumber, $itemnumber, $branchcode)
311
  $canReserve = &CanItemBeReserved($borrowernumber, $itemnumber, $branchcode)
295
  if ($canReserve->{status} eq 'OK') { #We can reserve this Item! }
312
  if ($canReserve->{status} eq 'OK') { #We can reserve this Item! }
296
313
314
<<<<<<< HEAD
297
@RETURNS { status => OK },              if the Item can be reserved.
315
@RETURNS { status => OK },              if the Item can be reserved.
298
         { status => ageRestricted },   if the Item is age restricted for this borrower.
316
         { status => ageRestricted },   if the Item is age restricted for this borrower.
299
         { status => damaged },         if the Item is damaged.
317
         { status => damaged },         if the Item is damaged.
Lines 303-308 sub CanBookBeReserved{ Link Here
303
         { status => libraryNotFound },   if given branchcode is not an existing library
321
         { status => libraryNotFound },   if given branchcode is not an existing library
304
         { status => libraryNotPickupLocation },   if given branchcode is not configured to be a pickup location
322
         { status => libraryNotPickupLocation },   if given branchcode is not configured to be a pickup location
305
         { status => cannotBeTransferred }, if branch transfer limit applies on given item and branchcode
323
         { status => cannotBeTransferred }, if branch transfer limit applies on given item and branchcode
324
=======
325
@RETURNS OK,              if the Item can be reserved.
326
         ageRestricted,   if the Item is age restricted for this borrower.
327
         damaged,         if the Item is damaged.
328
         cannotReserveFromOtherBranches, if syspref 'canreservefromotherbranches' is OK.
329
         tooManyReserves, if the borrower has exceeded his maximum reserve amount.
330
         notReservable,   if holds on this item are not allowed
331
         alreadyReserved, if the borrower has already reserved this item.
332
>>>>>>> Bug 11999: Add two checks in CanBookBeReserved and CanItemBeReserved
306
333
307
=cut
334
=cut
308
335
Lines 336-341 sub CanItemBeReserved { Link Here
336
    return { status =>'itemAlreadyOnHold' }
363
    return { status =>'itemAlreadyOnHold' }
337
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
364
      if Koha::Holds->search( { borrowernumber => $borrowernumber, itemnumber => $itemnumber } )->count();
338
365
366
    # Check if borrower already has reserved the same item or biblio.
367
    my $holds = $patron->holds;
368
    while (my $hold = $holds->next) {
369
        if (   $hold->itemnumber == $itemnumber
370
            or $hold->biblionumber == $item->{biblionumber} )
371
        {
372
            return 'alreadyReserved';
373
        }
374
    }
375
376
    # Check if borrower has reached the maximum number of holds allowed
377
    my $maxreserves = C4::Context->preference('maxreserves');
378
    if ($maxreserves && $holds->count >= $maxreserves) {
379
        return 'tooManyReserves';
380
    }
381
339
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
382
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
340
383
341
    my $querycount = q{
384
    my $querycount = q{
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-1 / +1 lines)
Lines 90-96 Link Here
90
    </form>
90
    </form>
91
  [% ELSIF NOT noitems %]
91
  [% ELSIF NOT noitems %]
92
92
93
[% IF ( exceeded_maxreserves || exceeded_holds_per_record || alreadyreserved || none_available || alreadypossession || ageRestricted ) %]
93
[% IF ( exceeded_maxreserves || exceeded_holds_per_record || alreadyReserved || none_available || alreadypossession || ageRestricted ) %]
94
    <div class="dialog alert">
94
    <div class="dialog alert">
95
95
96
    [% UNLESS ( multi_hold ) %]
96
    [% UNLESS ( multi_hold ) %]
(-)a/reserve/request.pl (-2 / +4 lines)
Lines 235-242 foreach my $biblionumber (@biblionumbers) { Link Here
235
                $exceeded_holds_per_record = 1;
235
                $exceeded_holds_per_record = 1;
236
                $biblioloopiter{ $canReserve->{status} } = 1;
236
                $biblioloopiter{ $canReserve->{status} } = 1;
237
            }
237
            }
238
            elsif ( $canReserve->{status} eq 'ageRestricted' ) {
238
            elsif ( grep { $canReserve->{status} eq $_ }
239
                $template->param( $canReserve->{status} => 1 );
239
                (qw(ageRestricted alreadyReserved none_available)) )
240
	    {
241
		$template->param( $canReserve->{status} => 1 );
240
                $biblioloopiter{ $canReserve->{status} } = 1;
242
                $biblioloopiter{ $canReserve->{status} } = 1;
241
            }
243
            }
242
            else {
244
            else {
(-)a/t/db_dependent/Holds.t (-3 / +59 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
12
13
use C4::Biblio;
13
use C4::Biblio;
Lines 299-305 ok( Link Here
299
    is( $hold3->discard_changes->priority, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
299
    is( $hold3->discard_changes->priority, 1, "After ModReserve, the 3rd reserve becomes the first on the waiting list" );
300
}
300
}
301
301
302
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
303
302
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
304
ModItem({ damaged => 1 }, $item_bibnum, $itemnumber);
305
CancelReserve({reserve_id => $reserveid3});
303
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
306
t::lib::Mocks::mock_preference( 'AllowHoldsOnDamagedItems', 1 );
304
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
307
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'OK', "Patron can reserve damaged item with AllowHoldsOnDamagedItems enabled" );
305
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
308
ok( defined( ( CheckReserves($itemnumber) )[1] ), "Hold can be trapped for damaged item with AllowHoldsOnDamagedItems enabled" );
Lines 330-352 AddReserve( Link Here
330
    '',
333
    '',
331
    1,
334
    1,
332
);
335
);
336
my ($bibnum2, $title2, $bibitemnum2) = create_helper_biblio('CANNOT');
337
my ($item_bibnum2, $item_bibitemnum2, $itemnumber2) = AddItem({ homebranch => $branch_1, holdingbranch => $branch_1, itype => 'CANNOT' } , $bibnum2);
333
is(
338
is(
339
<<<<<<< HEAD
334
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'tooManyReserves',
340
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status}, 'tooManyReserves',
341
=======
342
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2), 'tooManyReserves',
343
>>>>>>> Bug 11999: Add two checks in CanBookBeReserved and CanItemBeReserved
335
    "cannot request item if policy that matches on item-level item type forbids it"
344
    "cannot request item if policy that matches on item-level item type forbids it"
336
);
345
);
337
ModItem({ itype => 'CAN' }, $item_bibnum, $itemnumber);
346
ModItem({ itype => 'CAN' }, $item_bibnum2, $itemnumber2);
338
ok(
347
ok(
348
<<<<<<< HEAD
339
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'OK',
349
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'OK',
350
=======
351
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2) eq 'OK',
352
>>>>>>> Bug 11999: Add two checks in CanBookBeReserved and CanItemBeReserved
340
    "can request item if policy that matches on item type allows it"
353
    "can request item if policy that matches on item type allows it"
341
);
354
);
342
355
343
t::lib::Mocks::mock_preference('item-level_itypes', 0);
356
t::lib::Mocks::mock_preference('item-level_itypes', 0);
357
<<<<<<< HEAD
344
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
358
ModItem({ itype => undef }, $item_bibnum, $itemnumber);
345
ok(
359
ok(
346
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'tooManyReserves',
360
    CanItemBeReserved( $borrowernumbers[0], $itemnumber)->{status} eq 'tooManyReserves',
361
=======
362
ModItem({ itype => undef }, $item_bibnum2, $itemnumber2);
363
is(
364
    CanItemBeReserved( $borrowernumbers[0], $itemnumber2), 'tooManyReserves',
365
>>>>>>> Bug 11999: Add two checks in CanBookBeReserved and CanItemBeReserved
347
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
366
    "cannot request item if policy that matches on bib-level item type forbids it (bug 9532)"
348
);
367
);
349
368
369
is(CanBookBeReserved($borrowernumbers[0], $bibnum), 'OK');
370
371
C4::Context->set_preference('maxreserves', 1);
372
ok(CanBookBeReserved($borrowernumbers[0], $biblionumber) eq 'tooManyReserves');
373
374
C4::Context->set_preference('maxreserves', 0);
375
t::lib::Mocks::mock_preference('IndependentBranches', 1);
376
t::lib::Mocks::mock_preference('canreservefromotherbranches', 0);
377
ok(CanBookBeReserved($borrowernumbers[0], $foreign_bibnum) eq 'none_available');
350
378
351
# Test branch item rules
379
# Test branch item rules
352
380
Lines 410-417 is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status}, Link Here
410
438
411
my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $biblio->biblionumber, '', 1, );
439
my $res_id = AddReserve( $branch_1, $borrowernumbers[0], $biblio->biblionumber, '', 1, );
412
440
441
<<<<<<< HEAD
413
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status},
442
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status},
414
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
443
    'tooManyReserves', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
444
=======
445
is( CanItemBeReserved( $borrowernumbers[0], $itemnumber ),
446
    'tooManyHoldsForThisRecord', 'Patron cannot reserve item with hold limit of 1, 1 bib level hold placed' );
447
>>>>>>> Bug 11999: Add two checks in CanBookBeReserved and CanItemBeReserved
415
448
416
    #results should be the same for both ReservesControlBranch settings
449
    #results should be the same for both ReservesControlBranch settings
417
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'ItemHomeLibrary' );
450
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'ItemHomeLibrary' );
Lines 420-425 is( CanItemBeReserved( $borrowernumbers[0], $itemnumber )->{status}, Link Here
420
#reset for further tests
453
#reset for further tests
421
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' );
454
t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' );
422
455
456
<<<<<<< HEAD
423
subtest 'Test max_holds per library/patron category' => sub {
457
subtest 'Test max_holds per library/patron category' => sub {
424
    plan tests => 6;
458
    plan tests => 6;
425
459
Lines 670-672 subtest 'CanItemBeReserved / holds_per_day tests' => sub { Link Here
670
704
671
    $schema->storage->txn_rollback;
705
    $schema->storage->txn_rollback;
672
};
706
};
673
- 
707
=======
708
# Helper method to set up a Biblio.
709
sub create_helper_biblio {
710
    my $itemtype = shift;
711
    my $bib = MARC::Record->new();
712
    my $title = 'Silence in the library';
713
    if (C4::Context->preference('marcflavour') eq 'UNIMARC') {
714
        $bib->append_fields(
715
            MARC::Field->new('700', ' ', '0', a => 'Moffat, Steven'),
716
            MARC::Field->new('200', ' ', ' ', a => $title),
717
            MARC::Field->new('099', ' ', ' ', t => $itemtype),
718
        );
719
    } else {
720
        $bib->append_fields(
721
            MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
722
            MARC::Field->new('245', ' ', ' ', a => $title),
723
            MARC::Field->new('942', ' ', ' ', c => $itemtype),
724
        );
725
    }
726
727
    return AddBiblio($bib, '');
728
}
729
>>>>>>> Bug 11999: Add two checks in CanBookBeReserved and CanItemBeReserved

Return to bug 11999