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

(-)a/C4/Reserves.pm (-24 / +69 lines)
Lines 404-411 sub CanBookBeReserved{ Link Here
404
  current params are:
404
  current params are:
405
  'ignore_hold_counts' - we use this routine to check if an item can fill a hold - on this case we
405
  'ignore_hold_counts' - we use this routine to check if an item can fill a hold - on this case we
406
  should not check if there are too many holds as we only care about reservability
406
  should not check if there are too many holds as we only care about reservability
407
  'ignore_onshelfholds_policy' - if set to a true value, do not check if the
408
  "on shelf holds" policy is satisfied; useful to avoid infinite recursion with
409
  IsOnShelfHoldsPolicySatisfied and ItemsAnyAvailableAndNotRestricted
407
410
408
@RETURNS { status => OK },              if the Item can be reserved.
411
@RETURNS { status => OK },              if the Item can be reserved.
412
         { status => onShelfHoldsNotAllowed },  if onShelfHoldsAllowed parameter and item availability combination doesn't allow holds.
409
         { status => ageRestricted },   if the Item is age restricted for this borrower.
413
         { status => ageRestricted },   if the Item is age restricted for this borrower.
410
         { status => damaged },         if the Item is damaged.
414
         { status => damaged },         if the Item is damaged.
411
         { status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK.
415
         { status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK.
Lines 657-662 sub CanItemBeReserved { Link Here
657
        }
661
        }
658
    }
662
    }
659
663
664
    unless ( $params->{ignore_onshelfholds_policy} ) {
665
        unless ( IsOnShelfHoldsPolicySatisfied( { item => $item, patron => $patron } ) ) {
666
            return _cache { status => 'onShelfHoldsNotAllowed' };
667
        }
668
    }
669
660
    return _cache { status => 'OK' };
670
    return _cache { status => 'OK' };
661
}
671
}
662
672
Lines 1367-1395 sub IsAvailableForItemLevelRequest { Link Here
1367
        return 0 unless $branchitemrule->{hold_fulfillment_policy} ne 'holdgroup' || $home_library->validate_hold_sibling( {branchcode => $pickup_branchcode} );
1377
        return 0 unless $branchitemrule->{hold_fulfillment_policy} ne 'holdgroup' || $home_library->validate_hold_sibling( {branchcode => $pickup_branchcode} );
1368
    }
1378
    }
1369
1379
1370
    my $on_shelf_holds = Koha::CirculationRules->get_onshelfholds_policy( { item => $item, patron => $patron } );
1380
    return IsOnShelfHoldsPolicySatisfied({ item => $item, patron => $patron });
1371
1372
    if ( $on_shelf_holds == 1 ) {
1373
        return 1;
1374
    } elsif ( $on_shelf_holds == 2 ) {
1375
1376
        # These calculations work at the biblio level, and can be expensive
1377
        # we use the in-memory cache to avoid calling once per item when looping items on a biblio
1378
1379
        my $memory_cache = Koha::Cache::Memory::Lite->get_instance();
1380
        my $cache_key    = sprintf "ItemsAnyAvailableAndNotRestricted:%s:%s", $patron->id, $item->biblionumber;
1381
1382
        my $any_available = $memory_cache->get_from_cache($cache_key);
1383
        return $any_available ? 0 : 1 if defined($any_available);
1384
1385
        $any_available =
1386
            ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron } );
1387
        $memory_cache->set_in_cache( $cache_key, $any_available );
1388
        return $any_available ? 0 : 1;
1389
1390
    } else {  # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1391
        return $item->notforloan < 0 || $item->onloan || IsItemOnHoldAndFound( $item->itemnumber );
1392
    }
1393
}
1381
}
1394
1382
1395
=head2 ItemsAnyAvailableAndNotRestricted
1383
=head2 ItemsAnyAvailableAndNotRestricted
Lines 1427-1438 sub ItemsAnyAvailableAndNotRestricted { Link Here
1427
            || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan
1415
            || Koha::ItemTypes->find( $i->effective_itemtype() )->notforloan
1428
            || $branchitemrule->{holdallowed} eq 'from_home_library' && $param->{patron}->branchcode ne $i->homebranch
1416
            || $branchitemrule->{holdallowed} eq 'from_home_library' && $param->{patron}->branchcode ne $i->homebranch
1429
            || $branchitemrule->{holdallowed} eq 'from_local_hold_group' && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } )
1417
            || $branchitemrule->{holdallowed} eq 'from_local_hold_group' && ! $item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } )
1430
            || CanItemBeReserved( $param->{patron}, $i )->{status} ne 'OK';
1418
            || CanItemBeReserved( $param->{patron}, $i, undef, { ignore_onshelfholds_policy => 1 } )->{status} ne 'OK';
1431
    }
1419
    }
1432
1420
1433
    return 0;
1421
    return 0;
1434
}
1422
}
1435
1423
1424
=head2 IsOnShelfHoldsPolicySatisfied
1425
1426
Verifies if a patron can place a hold on an item according to the "on shelf
1427
holds" policy.
1428
1429
Uses in-memory cache.
1430
1431
    $policy_ok = IsOnShelfHoldsPolicySatisfied({ item => $item, patron => $patron })
1432
1433
=head3 Parameters
1434
1435
=over
1436
1437
=item C<$item> - a Koha::Item object
1438
1439
=item C<$patron> - a Koha::Patron object
1440
1441
=back
1442
1443
=head3 Return value
1444
1445
a true value if the hold is possible, a false value otherwise
1446
1447
=cut
1448
1449
sub IsOnShelfHoldsPolicySatisfied {
1450
    my ($args) = @_;
1451
    my ( $item, $patron ) = @$args{qw(item patron)};
1452
1453
    my $on_shelf_holds = Koha::CirculationRules->get_onshelfholds_policy( { item => $item, patron => $patron } );
1454
1455
    if ( $on_shelf_holds == 1 ) {
1456
        return 1;
1457
    }
1458
1459
    if ( $on_shelf_holds == 2 ) {
1460
1461
        # These calculations work at the biblio level, and can be expensive
1462
        # we use the in-memory cache to avoid calling once per item when looping items on a biblio
1463
1464
        my $memory_cache = Koha::Cache::Memory::Lite->get_instance();
1465
        my $cache_key    = sprintf "ItemsAnyAvailableAndNotRestricted:%s:%s", $patron->id, $item->biblionumber;
1466
1467
        my $any_available = $memory_cache->get_from_cache($cache_key);
1468
        unless ( defined $any_available ) {
1469
            $any_available =
1470
                ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron } );
1471
            $memory_cache->set_in_cache( $cache_key, $any_available );
1472
        }
1473
1474
        return $any_available ? 0 : 1;
1475
    }
1476
1477
    # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1478
    return $item->notforloan < 0 || $item->onloan || IsItemOnHoldAndFound( $item->itemnumber );
1479
}
1480
1436
=head2 AlterPriority
1481
=head2 AlterPriority
1437
1482
1438
  AlterPriority( $where, $reserve_id, $prev_priority, $next_priority, $first_priority, $last_priority );
1483
  AlterPriority( $where, $reserve_id, $prev_priority, $next_priority, $first_priority, $last_priority );
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (+1 lines)
Lines 1314-1319 Link Here
1314
            tooManyReserves: _("Too many holds"),
1314
            tooManyReserves: _("Too many holds"),
1315
            notReservable: _("Not holdable"),
1315
            notReservable: _("Not holdable"),
1316
            noReservesAllowed: _("No reserves allowed"),
1316
            noReservesAllowed: _("No reserves allowed"),
1317
            onShelfHoldsNotAllowed: _("Not holdable"),
1317
            cannotReserveFromOtherBranches: _("Patron is from different library"),
1318
            cannotReserveFromOtherBranches: _("Patron is from different library"),
1318
            itemAlreadyOnHold: _("Patron already has hold for this item"),
1319
            itemAlreadyOnHold: _("Patron already has hold for this item"),
1319
            cannotBeTransferred: _("Cannot be transferred to pickup library"),
1320
            cannotBeTransferred: _("Cannot be transferred to pickup library"),
(-)a/t/db_dependent/Holds.t (+30 lines)
Lines 251-256 Koha::CirculationRules->set_rules( Link Here
251
        branchcode   => undef,
251
        branchcode   => undef,
252
        itemtype     => undef,
252
        itemtype     => undef,
253
        rules        => {
253
        rules        => {
254
            onshelfholds     => 1,
254
            reservesallowed  => 25,
255
            reservesallowed  => 25,
255
            holds_per_record => 99,
256
            holds_per_record => 99,
256
        }
257
        }
Lines 262-267 Koha::CirculationRules->set_rules( Link Here
262
        branchcode   => undef,
263
        branchcode   => undef,
263
        itemtype     => 'CANNOT',
264
        itemtype     => 'CANNOT',
264
        rules        => {
265
        rules        => {
266
            onshelfholds     => 1,
265
            reservesallowed  => 0,
267
            reservesallowed  => 0,
266
            holds_per_record => 99,
268
            holds_per_record => 99,
267
        }
269
        }
Lines 430-435 subtest 'CanItemBeReserved' => sub { Link Here
430
            branchcode   => undef,
432
            branchcode   => undef,
431
            itemtype     => $itemtype_cant,
433
            itemtype     => $itemtype_cant,
432
            rules        => {
434
            rules        => {
435
                onshelfholds     => 1,
433
                reservesallowed  => 0,
436
                reservesallowed  => 0,
434
                holds_per_record => 99,
437
                holds_per_record => 99,
435
            }
438
            }
Lines 441-446 subtest 'CanItemBeReserved' => sub { Link Here
441
            branchcode   => undef,
444
            branchcode   => undef,
442
            itemtype     => $itemtype_can,
445
            itemtype     => $itemtype_can,
443
            rules        => {
446
            rules        => {
447
                onshelfholds     => 1,
444
                reservesallowed  => 2,
448
                reservesallowed  => 2,
445
                holds_per_record => 2,
449
                holds_per_record => 2,
446
            }
450
            }
Lines 452-457 subtest 'CanItemBeReserved' => sub { Link Here
452
            branchcode   => undef,
456
            branchcode   => undef,
453
            itemtype     => $itemtype_cant_record,
457
            itemtype     => $itemtype_cant_record,
454
            rules        => {
458
            rules        => {
459
                onshelfholds     => 1,
455
                reservesallowed  => 0,
460
                reservesallowed  => 0,
456
                holds_per_record => 0,
461
                holds_per_record => 0,
457
            }
462
            }
Lines 561-566 subtest 'CanItemBeReserved' => sub { Link Here
561
                branchcode   => undef,
566
                branchcode   => undef,
562
                itemtype     => undef,
567
                itemtype     => undef,
563
                rules        => {
568
                rules        => {
569
                    onshelfholds     => 1,
564
                    reservesallowed  => 5,
570
                    reservesallowed  => 5,
565
                    holds_per_record => 1,
571
                    holds_per_record => 1,
566
                }
572
                }
Lines 639-644 Koha::CirculationRules->set_rules( Link Here
639
        branchcode   => undef,
645
        branchcode   => undef,
640
        itemtype     => undef,
646
        itemtype     => undef,
641
        rules        => {
647
        rules        => {
648
            onshelfholds     => 1,
642
            reservesallowed  => 25,
649
            reservesallowed  => 25,
643
            holds_per_record => 99,
650
            holds_per_record => 99,
644
        }
651
        }
Lines 701-706 Koha::CirculationRules->set_rules( Link Here
701
        branchcode   => undef,
708
        branchcode   => undef,
702
        itemtype     => 'ONLY1',
709
        itemtype     => 'ONLY1',
703
        rules        => {
710
        rules        => {
711
            onshelfholds     => 1,
704
            reservesallowed  => 1,
712
            reservesallowed  => 1,
705
            holds_per_record => 99,
713
            holds_per_record => 99,
706
        }
714
        }
Lines 743-748 subtest 'Test max_holds per library/patron category' => sub { Link Here
743
            branchcode   => undef,
751
            branchcode   => undef,
744
            itemtype     => $biblio->itemtype,
752
            itemtype     => $biblio->itemtype,
745
            rules        => {
753
            rules        => {
754
                onshelfholds     => 1,
746
                reservesallowed  => 99,
755
                reservesallowed  => 99,
747
                holds_per_record => 99,
756
                holds_per_record => 99,
748
            }
757
            }
Lines 822-827 subtest 'Pickup location availability tests' => sub { Link Here
822
            categorycode => undef,
831
            categorycode => undef,
823
            itemtype     => undef,
832
            itemtype     => undef,
824
            rules        => {
833
            rules        => {
834
                onshelfholds     => 1,
825
                reservesallowed  => 25,
835
                reservesallowed  => 25,
826
                holds_per_record => 99,
836
                holds_per_record => 99,
827
            }
837
            }
Lines 882-887 subtest 'CanItemBeReserved / holds_per_day tests' => sub { Link Here
882
            itemtype     => $itemtype->itemtype,
892
            itemtype     => $itemtype->itemtype,
883
            rules        => {
893
            rules        => {
884
                reservesallowed  => 1,
894
                reservesallowed  => 1,
895
                onshelfholds => 1,
885
                holds_per_record => 99,
896
                holds_per_record => 99,
886
                holds_per_day    => 2
897
                holds_per_day    => 2
887
            }
898
            }
Lines 1051-1056 subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub { Link Here
1051
            rule_value   => 25,
1062
            rule_value   => 25,
1052
        }
1063
        }
1053
    );
1064
    );
1065
    Koha::CirculationRules->set_rule(
1066
        {
1067
            branchcode   => undef,
1068
            categorycode => undef,
1069
            itemtype     => undef,
1070
            rule_name    => 'onshelfholds',
1071
            rule_value   => 1,
1072
        }
1073
    );
1054
1074
1055
    # Create item types
1075
    # Create item types
1056
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
1076
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
Lines 1265-1270 subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub { Link Here
1265
            rule_value   => 25,
1285
            rule_value   => 25,
1266
        }
1286
        }
1267
    );
1287
    );
1288
    Koha::CirculationRules->set_rule(
1289
        {
1290
            branchcode   => undef,
1291
            categorycode => undef,
1292
            itemtype     => undef,
1293
            rule_name    => 'onshelfholds',
1294
            rule_value   => 1,
1295
        }
1296
    );
1268
1297
1269
    # Create item types
1298
    # Create item types
1270
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
1299
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
Lines 1613-1618 subtest 'CanItemBeReserved rule precedence tests' => sub { Link Here
1613
            categorycode => $patron->categorycode,
1642
            categorycode => $patron->categorycode,
1614
            itemtype     => $item->itype,
1643
            itemtype     => $item->itype,
1615
            rules        => {
1644
            rules        => {
1645
                onshelfholds     => 1,
1616
                reservesallowed  => 1,
1646
                reservesallowed  => 1,
1617
            }
1647
            }
1618
        }
1648
        }
(-)a/t/db_dependent/ILSDI_Services.t (+28 lines)
Lines 371-376 subtest 'Holds test' => sub { Link Here
371
        }
371
        }
372
    );
372
    );
373
373
374
    Koha::CirculationRules->set_rule(
375
        {
376
            categorycode => undef,
377
            itemtype     => undef,
378
            branchcode   => undef,
379
            rule_name    => 'onshelfholds',
380
            rule_value   => 1,
381
        }
382
    );
383
374
    t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' );
384
    t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' );
375
    Koha::CirculationRules->set_rule(
385
    Koha::CirculationRules->set_rule(
376
        {
386
        {
Lines 547-552 subtest 'Holds test for branch transfer limits' => sub { Link Here
547
            rule_value   => 99,
557
            rule_value   => 99,
548
        }
558
        }
549
    );
559
    );
560
    Koha::CirculationRules->set_rule(
561
        {
562
            categorycode => undef,
563
            itemtype     => undef,
564
            branchcode   => undef,
565
            rule_name    => 'onshelfholds',
566
            rule_value   => 1,
567
        }
568
    );
550
569
551
    my $limit = Koha::Item::Transfer::Limit->new({
570
    my $limit = Koha::Item::Transfer::Limit->new({
552
        toBranch => $pickup_branch->{branchcode},
571
        toBranch => $pickup_branch->{branchcode},
Lines 613-618 subtest 'Holds test with start_date and end_date' => sub { Link Here
613
            rule_value   => 99,
632
            rule_value   => 99,
614
        }
633
        }
615
    );
634
    );
635
    Koha::CirculationRules->set_rule(
636
        {
637
            categorycode => undef,
638
            itemtype     => undef,
639
            branchcode   => undef,
640
            rule_name    => 'onshelfholds',
641
            rule_value   => 1,
642
        }
643
    );
616
644
617
    my $query = CGI->new;
645
    my $query = CGI->new;
618
    $query->param( 'pickup_location', $pickup_library->branchcode );
646
    $query->param( 'pickup_location', $pickup_library->branchcode );
(-)a/t/db_dependent/Reserves.t (-1 / +75 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 77;
20
use Test::More tests => 78;
21
use Test::MockModule;
21
use Test::MockModule;
22
use Test::Warn;
22
use Test::Warn;
23
23
Lines 185-190 Koha::CirculationRules->set_rules( Link Here
185
        rules        => {
185
        rules        => {
186
            reservesallowed => 25,
186
            reservesallowed => 25,
187
            holds_per_record => 1,
187
            holds_per_record => 1,
188
            onshelfholds => 1,
188
        }
189
        }
189
    }
190
    }
190
);
191
);
Lines 1079-1085 subtest 'reserves.item_level_hold' => sub { Link Here
1079
1080
1080
        $hold->delete;
1081
        $hold->delete;
1081
    };
1082
    };
1083
};
1084
1085
subtest 'OnShelfHoldAllowed test' => sub {
1086
    plan tests => 3;
1087
    $dbh->do('DELETE FROM circulation_rules');
1088
    my $biblio = $builder->build_sample_biblio({frameworkcode => $frameworkcode})->biblionumber;
1089
1090
    # Create a helper item instance for testing
1091
    my $item = $builder->build_sample_item({ biblionumber => $biblio, library => $branch_1, itype => $itemtype });
1092
1093
    Koha::CirculationRules->set_rules(
1094
        {
1095
            branchcode   => undef,
1096
            categorycode => undef,
1097
            itemtype     => undef,
1098
            rules        => {
1099
                reservesallowed => 25,
1100
                opacitemholds => 'Y',
1101
                onshelfholds => 1,
1102
            }
1103
        }
1104
        );
1105
1106
    my $canreserve = C4::Reserves::CanItemBeReserved($patron, $item);
1082
1107
1108
    is( $canreserve->{status}, 'OK',
1109
        'item-level holds should be possible with onshelfholdallowed set to "Yes"' );
1110
1111
    Koha::CirculationRules->set_rules(
1112
        {
1113
            branchcode   => undef,
1114
            categorycode => undef,
1115
            itemtype     => undef,
1116
            rules        => {
1117
                reservesallowed => 25,
1118
                opacitemholds => 'Y',
1119
                onshelfholds => '0',
1120
            }
1121
        });
1122
1123
    $canreserve = C4::Reserves::CanItemBeReserved($patron, $item);
1124
1125
    is( $canreserve->{status}, 'onShelfHoldsNotAllowed',
1126
        'item-level holds should not be possible with onshelfholdallowed set to "If any unavailable"' );
1127
1128
    Koha::CirculationRules->set_rules(
1129
        {
1130
            branchcode   => undef,
1131
            categorycode => undef,
1132
            itemtype     => undef,
1133
            rules        => {
1134
                reservesallowed => 25,
1135
                opacitemholds => 'Y',
1136
                onshelfholds => '2',
1137
            }
1138
        });
1139
1140
    $canreserve = C4::Reserves::CanItemBeReserved($patron, $item);
1141
1142
    is( $canreserve->{status}, 'onShelfHoldsNotAllowed',
1143
        'item-level holds should not be possible with onshelfholdallowed set to "If all unavailable"' );
1083
};
1144
};
1084
1145
1085
subtest 'MoveReserve additional test' => sub {
1146
subtest 'MoveReserve additional test' => sub {
Lines 1319-1324 subtest 'AllowHoldOnPatronPossession test' => sub { Link Here
1319
    my $patron = $builder->build_object({ class => "Koha::Patrons",
1380
    my $patron = $builder->build_object({ class => "Koha::Patrons",
1320
                                          value => { branchcode => $item->homebranch }});
1381
                                          value => { branchcode => $item->homebranch }});
1321
1382
1383
    Koha::CirculationRules->set_rules(
1384
        {
1385
            branchcode   => undef,
1386
            categorycode => undef,
1387
            itemtype     => undef,
1388
            rules        => {
1389
                onshelfholds => 1,
1390
            }
1391
        }
1392
    );
1393
1322
    C4::Circulation::AddIssue($patron->unblessed,
1394
    C4::Circulation::AddIssue($patron->unblessed,
1323
                              $item->barcode);
1395
                              $item->barcode);
1324
    t::lib::Mocks::mock_preference('AllowHoldsOnPatronsPossessions', 0);
1396
    t::lib::Mocks::mock_preference('AllowHoldsOnPatronsPossessions', 0);
Lines 1639-1644 subtest 'CanBookBeReserved() tests' => sub { Link Here
1639
            itemtype     => $itype->id,
1711
            itemtype     => $itype->id,
1640
            rules        => {
1712
            rules        => {
1641
                reservesallowed => 2,
1713
                reservesallowed => 2,
1714
                onshelfholds => 1,
1642
            }
1715
            }
1643
        }
1716
        }
1644
    );
1717
    );
Lines 1710-1715 subtest 'CanItemBeReserved() tests' => sub { Link Here
1710
            itemtype     => $itype->id,
1783
            itemtype     => $itype->id,
1711
            rules        => {
1784
            rules        => {
1712
                reservesallowed => 2,
1785
                reservesallowed => 2,
1786
                onshelfholds => 1,
1713
            }
1787
            }
1714
        }
1788
        }
1715
    );
1789
    );
(-)a/t/db_dependent/Reserves/IsOnShelfHoldsPolicySatisfied.t (+111 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
5
use Test::More;
6
7
use t::lib::TestBuilder;
8
use Koha::Database;
9
use Koha::Cache::Memory::Lite;
10
11
use C4::Reserves;
12
13
plan tests => 1;
14
15
my $schema = Koha::Database->schema;
16
my $circulationrule_rs = $schema->resultset('CirculationRule');
17
my $builder = t::lib::TestBuilder->new;
18
19
subtest '2 items, 1 itemtype, 1 library' => sub {
20
    plan tests => 3;
21
    $schema->txn_begin;
22
23
    my $itemtype = $builder->build_object( { class => 'Koha::ItemTypes' } )->itemtype;
24
    my $library  = $builder->build_object( { class => 'Koha::Libraries' } );
25
    my $branchcode = $library->branchcode;
26
    my $biblio   = $builder->build_sample_biblio( { itemtype => $itemtype } );
27
    my $item1 =
28
        $builder->build_sample_item( { biblionumber => $biblio->biblionumber, library => $branchcode } );
29
    my $item2 =
30
        $builder->build_sample_item( { biblionumber => $biblio->biblionumber, library => $branchcode } );
31
    my $patron =
32
        $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $branchcode } } );
33
    my $categorycode = $patron->categorycode;
34
35
    $circulationrule_rs->populate(
36
        [
37
            [ 'branchcode', 'categorycode', 'itemtype', 'rule_name',               'rule_value' ],
38
            [ $branchcode,  undef,          $itemtype,  'holdallowed',             'from_any_library' ],
39
            [ $branchcode,  undef,          $itemtype,  'hold_fulfillment_policy', 'any' ],
40
            [ $branchcode,  $categorycode,  undef,      'max_holds',               '99' ],
41
            [ $branchcode,  $categorycode,  $itemtype,  'holds_per_day',           '99' ],
42
            [ $branchcode,  $categorycode,  $itemtype,  'holds_per_record',        '99' ],
43
            [ $branchcode,  $categorycode,  $itemtype,  'reservesallowed',         '99' ],
44
        ]
45
    );
46
    my $onshelfholds_rule = $circulationrule_rs->create(
47
        {
48
            branchcode   => $branchcode,
49
            categorycode => $categorycode,
50
            itemtype     => $itemtype,
51
            rule_name    => 'onshelfholds',
52
            rule_value   => '0',
53
        }
54
    );
55
56
    subtest 'when all items are available' => sub {
57
        plan tests => 3;
58
59
        $onshelfholds_rule->update({ rule_value => '0' });
60
        Koha::Cache::Memory::Lite->flush();
61
        ok(!C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is not allowed if onshelfholds == 0');
62
63
        $onshelfholds_rule->update({ rule_value => '1' });
64
        Koha::Cache::Memory::Lite->flush();
65
        ok(C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is always allowed if onshelfholds == 1');
66
67
        $onshelfholds_rule->update({ rule_value => '2' });
68
        Koha::Cache::Memory::Lite->flush();
69
        ok(!C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is not allowed if onshelfholds == 2');
70
    };
71
72
    subtest 'when checked item is not available but others are available' => sub {
73
        plan tests => 3;
74
75
        $item1->onloan(DateTime->now)->store;
76
77
        $onshelfholds_rule->update({ rule_value => '0' });
78
        Koha::Cache::Memory::Lite->flush();
79
        ok(C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is allowed if onshelfholds == 0');
80
81
        $onshelfholds_rule->update({ rule_value => '1' });
82
        Koha::Cache::Memory::Lite->flush();
83
        ok(C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is always allowed if onshelfholds == 1');
84
85
        $onshelfholds_rule->update({ rule_value => '2' });
86
        Koha::Cache::Memory::Lite->flush();
87
        ok(!C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is not allowed if onshelfholds == 2');
88
    };
89
90
    subtest 'when all items are unavailable' => sub {
91
        plan tests => 3;
92
93
        $item1->onloan(DateTime->now)->store;
94
        $item2->onloan(DateTime->now)->store;
95
96
        $onshelfholds_rule->update({ rule_value => '0' });
97
        Koha::Cache::Memory::Lite->flush();
98
        ok(C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is allowed if onshelfholds == 0');
99
100
        $onshelfholds_rule->update({ rule_value => '1' });
101
        Koha::Cache::Memory::Lite->flush();
102
        ok(C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is always allowed if onshelfholds == 1');
103
104
        $onshelfholds_rule->update({ rule_value => '2' });
105
        Koha::Cache::Memory::Lite->flush();
106
        ok(C4::Reserves::IsOnShelfHoldsPolicySatisfied({ item => $item1, patron => $patron }), 'on shelf hold is allowed if onshelfholds == 2');
107
    };
108
109
    $schema->txn_rollback;
110
};
111
(-)a/t/db_dependent/Reserves/MultiplePerRecord.t (+1 lines)
Lines 222-227 Koha::CirculationRules->set_rules( Link Here
222
        itemtype     => undef,
222
        itemtype     => undef,
223
        branchcode   => undef,
223
        branchcode   => undef,
224
        rules        => {
224
        rules        => {
225
            onshelfholds     => 1,
225
            reservesallowed  => 3,
226
            reservesallowed  => 3,
226
            holds_per_record => 2,
227
            holds_per_record => 2,
227
        }
228
        }
(-)a/t/db_dependent/api/v1/holds.t (-1 / +2 lines)
Lines 124-129 Koha::CirculationRules->set_rules( Link Here
124
        branchcode   => undef,
124
        branchcode   => undef,
125
        itemtype     => undef,
125
        itemtype     => undef,
126
        rules        => {
126
        rules        => {
127
            onshelfholds => 1,
127
            reservesallowed => 1,
128
            reservesallowed => 1,
128
            holds_per_record => 99
129
            holds_per_record => 99
129
        }
130
        }
Lines 683-688 subtest 'add() tests (maxreserves behaviour)' => sub { Link Here
683
            branchcode   => undef,
684
            branchcode   => undef,
684
            categorycode => undef,
685
            categorycode => undef,
685
            rules        => {
686
            rules        => {
687
                onshelfholds => 1,
686
                reservesallowed => 3
688
                reservesallowed => 3
687
            }
689
            }
688
        }
690
        }
689
- 

Return to bug 20985