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

(-)a/C4/Reserves.pm (-24 / +65 lines)
Lines 435-442 sub CanBookBeReserved { Link Here
435
  current params are:
435
  current params are:
436
  'ignore_hold_counts' - we use this routine to check if an item can fill a hold - on this case we
436
  'ignore_hold_counts' - we use this routine to check if an item can fill a hold - on this case we
437
  should not check if there are too many holds as we only care about reservability
437
  should not check if there are too many holds as we only care about reservability
438
  'ignore_onshelfholds_policy' - if set to a true value, do not check if the
439
  "on shelf holds" policy is satisfied; useful to avoid infinite recursion with
440
  IsOnShelfHoldsPolicySatisfied and ItemsAnyAvailableAndNotRestricted
438
441
439
@RETURNS { status => OK },              if the Item can be reserved.
442
@RETURNS { status => OK },              if the Item can be reserved.
443
         { status => onShelfHoldsNotAllowed },  if onShelfHoldsAllowed parameter and item availability combination doesn't allow holds.
440
         { status => ageRestricted },   if the Item is age restricted for this borrower.
444
         { status => ageRestricted },   if the Item is age restricted for this borrower.
441
         { status => damaged },         if the Item is damaged.
445
         { status => damaged },         if the Item is damaged.
442
         { status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK.
446
         { status => cannotReserveFromOtherBranches }, if syspref 'canreservefromotherbranches' is OK.
Lines 701-706 sub CanItemBeReserved { Link Here
701
        }
705
        }
702
    }
706
    }
703
707
708
    unless ( $params->{ignore_onshelfholds_policy} ) {
709
        unless ( IsOnShelfHoldsPolicySatisfied( { item => $item, patron => $patron } ) ) {
710
            return _cache { status => 'onShelfHoldsNotAllowed' };
711
        }
712
    }
713
704
    return _cache { status => 'OK' };
714
    return _cache { status => 'OK' };
705
}
715
}
706
716
Lines 1409-1437 sub IsAvailableForItemLevelRequest { Link Here
1409
            || $home_library->validate_hold_sibling( { branchcode => $pickup_branchcode } );
1419
            || $home_library->validate_hold_sibling( { branchcode => $pickup_branchcode } );
1410
    }
1420
    }
1411
1421
1412
    my $on_shelf_holds = Koha::CirculationRules->get_onshelfholds_policy( { item => $item, patron => $patron } );
1422
    return IsOnShelfHoldsPolicySatisfied( { item => $item, patron => $patron } );
1413
1414
    if ( $on_shelf_holds == 1 ) {
1415
        return 1;
1416
    } elsif ( $on_shelf_holds == 2 ) {
1417
1418
        # These calculations work at the biblio level, and can be expensive
1419
        # we use the in-memory cache to avoid calling once per item when looping items on a biblio
1420
1421
        my $memory_cache = Koha::Cache::Memory::Lite->get_instance();
1422
        my $cache_key    = sprintf "ItemsAnyAvailableAndNotRestricted:%s:%s", $patron->id, $item->biblionumber;
1423
1424
        my $any_available = $memory_cache->get_from_cache($cache_key);
1425
        return $any_available ? 0 : 1 if defined($any_available);
1426
1427
        $any_available =
1428
            ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron } );
1429
        $memory_cache->set_in_cache( $cache_key, $any_available );
1430
        return $any_available ? 0 : 1;
1431
1432
    } else {  # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1433
        return $item->notforloan < 0 || $item->onloan || $item->holds->filter_by_found->count;
1434
    }
1435
}
1423
}
1436
1424
1437
=head2 ItemsAnyAvailableAndNotRestricted
1425
=head2 ItemsAnyAvailableAndNotRestricted
Lines 1468-1479 sub ItemsAnyAvailableAndNotRestricted { Link Here
1468
            || $branchitemrule->{holdallowed} eq 'from_home_library' && $param->{patron}->branchcode ne $i->homebranch
1456
            || $branchitemrule->{holdallowed} eq 'from_home_library' && $param->{patron}->branchcode ne $i->homebranch
1469
            || $branchitemrule->{holdallowed} eq 'from_local_hold_group'
1457
            || $branchitemrule->{holdallowed} eq 'from_local_hold_group'
1470
            && !$item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } )
1458
            && !$item_library->validate_hold_sibling( { branchcode => $param->{patron}->branchcode } )
1471
            || CanItemBeReserved( $param->{patron}, $i )->{status} ne 'OK';
1459
            || CanItemBeReserved( $param->{patron}, $i, undef, { ignore_onshelfholds_policy => 1 } )->{status} ne 'OK';
1472
    }
1460
    }
1473
1461
1474
    return 0;
1462
    return 0;
1475
}
1463
}
1476
1464
1465
=head2 IsOnShelfHoldsPolicySatisfied
1466
1467
Verifies if a patron can place a hold on an item according to the "on shelf
1468
holds" policy.
1469
1470
Uses in-memory cache.
1471
1472
    $policy_ok = IsOnShelfHoldsPolicySatisfied({ item => $item, patron => $patron })
1473
1474
=head3 Parameters
1475
1476
=over
1477
1478
=item C<$item> - a Koha::Item object
1479
1480
=item C<$patron> - a Koha::Patron object
1481
1482
=back
1483
1484
=head3 Return value
1485
1486
a true value if the hold is possible, a false value otherwise
1487
1488
=cut
1489
1490
sub IsOnShelfHoldsPolicySatisfied {
1491
    my ($args) = @_;
1492
    my ( $item, $patron ) = @$args{qw(item patron)};
1493
1494
    my $on_shelf_holds = Koha::CirculationRules->get_onshelfholds_policy( { item => $item, patron => $patron } );
1495
1496
    if ( $on_shelf_holds == 1 ) {
1497
        return 1;
1498
    } elsif ( $on_shelf_holds == 2 ) {
1499
1500
        # These calculations work at the biblio level, and can be expensive
1501
        # we use the in-memory cache to avoid calling once per item when looping items on a biblio
1502
1503
        my $memory_cache = Koha::Cache::Memory::Lite->get_instance();
1504
        my $cache_key    = sprintf "IsOnShelfHoldsPolicySatisfied:%s:%s", $patron->id, $item->biblionumber;
1505
1506
        my $any_available = $memory_cache->get_from_cache($cache_key);
1507
        return $any_available ? 0 : 1 if defined($any_available);
1508
1509
        $any_available =
1510
            ItemsAnyAvailableAndNotRestricted( { biblionumber => $item->biblionumber, patron => $patron } );
1511
        $memory_cache->set_in_cache( $cache_key, $any_available );
1512
        return $any_available ? 0 : 1;
1513
    } else {  # on_shelf_holds == 0 "If any unavailable" (the description is rather cryptic and could still be improved)
1514
        return $item->notforloan < 0 || $item->onloan || $item->holds->filter_by_found->count;
1515
    }
1516
}
1517
1477
=head2 AlterPriority
1518
=head2 AlterPriority
1478
1519
1479
  AlterPriority( $where, $reserve_id, $prev_priority, $next_priority, $first_priority, $last_priority );
1520
  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 1430-1435 Link Here
1430
            tooManyReserves: _("Too many holds"),
1430
            tooManyReserves: _("Too many holds"),
1431
            notReservable: _("Not holdable"),
1431
            notReservable: _("Not holdable"),
1432
            noReservesAllowed: _("No reserves allowed"),
1432
            noReservesAllowed: _("No reserves allowed"),
1433
            onShelfHoldsNotAllowed: _("Not holdable"),
1433
            cannotReserveFromOtherBranches: _("Patron is from different library"),
1434
            cannotReserveFromOtherBranches: _("Patron is from different library"),
1434
            itemAlreadyOnHold: _("Patron already has hold for this item"),
1435
            itemAlreadyOnHold: _("Patron already has hold for this item"),
1435
            cannotBeTransferred: _("Cannot be transferred to pickup library"),
1436
            cannotBeTransferred: _("Cannot be transferred to pickup library"),
(-)a/t/db_dependent/Holds.t (+30 lines)
Lines 253-258 Koha::CirculationRules->set_rules( Link Here
253
        branchcode   => undef,
253
        branchcode   => undef,
254
        itemtype     => undef,
254
        itemtype     => undef,
255
        rules        => {
255
        rules        => {
256
            onshelfholds     => 1,
256
            reservesallowed  => 25,
257
            reservesallowed  => 25,
257
            holds_per_record => 99,
258
            holds_per_record => 99,
258
        }
259
        }
Lines 264-269 Koha::CirculationRules->set_rules( Link Here
264
        branchcode   => undef,
265
        branchcode   => undef,
265
        itemtype     => 'CANNOT',
266
        itemtype     => 'CANNOT',
266
        rules        => {
267
        rules        => {
268
            onshelfholds     => 1,
267
            reservesallowed  => 0,
269
            reservesallowed  => 0,
268
            holds_per_record => 99,
270
            holds_per_record => 99,
269
        }
271
        }
Lines 468-473 subtest 'CanItemBeReserved' => sub { Link Here
468
            branchcode   => undef,
470
            branchcode   => undef,
469
            itemtype     => $itemtype_cant,
471
            itemtype     => $itemtype_cant,
470
            rules        => {
472
            rules        => {
473
                onshelfholds     => 1,
471
                reservesallowed  => 0,
474
                reservesallowed  => 0,
472
                holds_per_record => 99,
475
                holds_per_record => 99,
473
            }
476
            }
Lines 479-484 subtest 'CanItemBeReserved' => sub { Link Here
479
            branchcode   => undef,
482
            branchcode   => undef,
480
            itemtype     => $itemtype_can,
483
            itemtype     => $itemtype_can,
481
            rules        => {
484
            rules        => {
485
                onshelfholds     => 1,
482
                reservesallowed  => 2,
486
                reservesallowed  => 2,
483
                holds_per_record => 2,
487
                holds_per_record => 2,
484
            }
488
            }
Lines 490-495 subtest 'CanItemBeReserved' => sub { Link Here
490
            branchcode   => undef,
494
            branchcode   => undef,
491
            itemtype     => $itemtype_cant_record,
495
            itemtype     => $itemtype_cant_record,
492
            rules        => {
496
            rules        => {
497
                onshelfholds     => 1,
493
                reservesallowed  => 0,
498
                reservesallowed  => 0,
494
                holds_per_record => 0,
499
                holds_per_record => 0,
495
            }
500
            }
Lines 650-655 subtest 'CanItemBeReserved' => sub { Link Here
650
                branchcode   => undef,
655
                branchcode   => undef,
651
                itemtype     => undef,
656
                itemtype     => undef,
652
                rules        => {
657
                rules        => {
658
                    onshelfholds     => 1,
653
                    reservesallowed  => 5,
659
                    reservesallowed  => 5,
654
                    holds_per_record => 1,
660
                    holds_per_record => 1,
655
                }
661
                }
Lines 729-734 Koha::CirculationRules->set_rules( Link Here
729
        branchcode   => undef,
735
        branchcode   => undef,
730
        itemtype     => undef,
736
        itemtype     => undef,
731
        rules        => {
737
        rules        => {
738
            onshelfholds     => 1,
732
            reservesallowed  => 25,
739
            reservesallowed  => 25,
733
            holds_per_record => 99,
740
            holds_per_record => 99,
734
        }
741
        }
Lines 802-807 Koha::CirculationRules->set_rules( Link Here
802
        branchcode   => undef,
809
        branchcode   => undef,
803
        itemtype     => 'ONLY1',
810
        itemtype     => 'ONLY1',
804
        rules        => {
811
        rules        => {
812
            onshelfholds     => 1,
805
            reservesallowed  => 1,
813
            reservesallowed  => 1,
806
            holds_per_record => 99,
814
            holds_per_record => 99,
807
        }
815
        }
Lines 853-858 subtest 'Test max_holds per library/patron category' => sub { Link Here
853
            branchcode   => undef,
861
            branchcode   => undef,
854
            itemtype     => $biblio->itemtype,
862
            itemtype     => $biblio->itemtype,
855
            rules        => {
863
            rules        => {
864
                onshelfholds     => 1,
856
                reservesallowed  => 99,
865
                reservesallowed  => 99,
857
                holds_per_record => 99,
866
                holds_per_record => 99,
858
            }
867
            }
Lines 933-938 subtest 'Pickup location availability tests' => sub { Link Here
933
            categorycode => undef,
942
            categorycode => undef,
934
            itemtype     => undef,
943
            itemtype     => undef,
935
            rules        => {
944
            rules        => {
945
                onshelfholds     => 1,
936
                reservesallowed  => 25,
946
                reservesallowed  => 25,
937
                holds_per_record => 99,
947
                holds_per_record => 99,
938
            }
948
            }
Lines 1006-1011 subtest 'CanItemBeReserved / holds_per_day tests' => sub { Link Here
1006
            itemtype     => $itemtype->itemtype,
1016
            itemtype     => $itemtype->itemtype,
1007
            rules        => {
1017
            rules        => {
1008
                reservesallowed  => 1,
1018
                reservesallowed  => 1,
1019
                onshelfholds     => 1,
1009
                holds_per_record => 99,
1020
                holds_per_record => 99,
1010
                holds_per_day    => 2
1021
                holds_per_day    => 2
1011
            }
1022
            }
Lines 1175-1180 subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub { Link Here
1175
            rule_value   => 25,
1186
            rule_value   => 25,
1176
        }
1187
        }
1177
    );
1188
    );
1189
    Koha::CirculationRules->set_rule(
1190
        {
1191
            branchcode   => undef,
1192
            categorycode => undef,
1193
            itemtype     => undef,
1194
            rule_name    => 'onshelfholds',
1195
            rule_value   => 1,
1196
        }
1197
    );
1178
1198
1179
    # Create item types
1199
    # Create item types
1180
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
1200
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
Lines 1402-1407 subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub { Link Here
1402
            rule_value   => 25,
1422
            rule_value   => 25,
1403
        }
1423
        }
1404
    );
1424
    );
1425
    Koha::CirculationRules->set_rule(
1426
        {
1427
            branchcode   => undef,
1428
            categorycode => undef,
1429
            itemtype     => undef,
1430
            rule_name    => 'onshelfholds',
1431
            rule_value   => 1,
1432
        }
1433
    );
1405
1434
1406
    # Create item types
1435
    # Create item types
1407
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
1436
    my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } );
Lines 1774-1779 subtest 'CanItemBeReserved rule precedence tests' => sub { Link Here
1774
            categorycode => $patron->categorycode,
1803
            categorycode => $patron->categorycode,
1775
            itemtype     => $item->itype,
1804
            itemtype     => $item->itype,
1776
            rules        => {
1805
            rules        => {
1806
                onshelfholds    => 1,
1777
                reservesallowed => 1,
1807
                reservesallowed => 1,
1778
            }
1808
            }
1779
        }
1809
        }
(-)a/t/db_dependent/ILSDI_Services.t (+28 lines)
Lines 512-517 subtest 'Holds test' => sub { Link Here
512
        }
512
        }
513
    );
513
    );
514
514
515
    Koha::CirculationRules->set_rule(
516
        {
517
            categorycode => undef,
518
            itemtype     => undef,
519
            branchcode   => undef,
520
            rule_name    => 'onshelfholds',
521
            rule_value   => 1,
522
        }
523
    );
524
515
    t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' );
525
    t::lib::Mocks::mock_preference( 'ReservesControlBranch', 'PatronLibrary' );
516
    Koha::CirculationRules->set_rule(
526
    Koha::CirculationRules->set_rule(
517
        {
527
        {
Lines 698-703 subtest 'Holds test for branch transfer limits' => sub { Link Here
698
            rule_value   => 99,
708
            rule_value   => 99,
699
        }
709
        }
700
    );
710
    );
711
    Koha::CirculationRules->set_rule(
712
        {
713
            categorycode => undef,
714
            itemtype     => undef,
715
            branchcode   => undef,
716
            rule_name    => 'onshelfholds',
717
            rule_value   => 1,
718
        }
719
    );
701
720
702
    my $limit = Koha::Item::Transfer::Limit->new(
721
    my $limit = Koha::Item::Transfer::Limit->new(
703
        {
722
        {
Lines 770-775 subtest 'Holds test with start_date and end_date' => sub { Link Here
770
            rule_value   => 99,
789
            rule_value   => 99,
771
        }
790
        }
772
    );
791
    );
792
    Koha::CirculationRules->set_rule(
793
        {
794
            categorycode => undef,
795
            itemtype     => undef,
796
            branchcode   => undef,
797
            rule_name    => 'onshelfholds',
798
            rule_value   => 1,
799
        }
800
    );
773
801
774
    my $query = CGI->new;
802
    my $query = CGI->new;
775
    $query->param( 'pickup_location', $pickup_library->branchcode );
803
    $query->param( 'pickup_location', $pickup_library->branchcode );
(-)a/t/db_dependent/Reserves.t (-1 / +84 lines)
Lines 17-23 Link Here
17
17
18
use Modern::Perl;
18
use Modern::Perl;
19
19
20
use Test::More tests => 70;
20
use Test::More tests => 71;
21
use Test::NoWarnings;
21
use Test::NoWarnings;
22
use Test::MockModule;
22
use Test::MockModule;
23
use Test::Warn;
23
use Test::Warn;
Lines 181-186 Koha::CirculationRules->set_rules( Link Here
181
        rules        => {
181
        rules        => {
182
            reservesallowed  => 25,
182
            reservesallowed  => 25,
183
            holds_per_record => 1,
183
            holds_per_record => 1,
184
            onshelfholds     => 1,
184
        }
185
        }
185
    }
186
    }
186
);
187
);
Lines 1024-1029 subtest 'ChargeReserveFee tests' => sub { Link Here
1024
    is( $line->branchcode,        $library->id, "Library id is picked from userenv and stored correctly" );
1025
    is( $line->branchcode,        $library->id, "Library id is picked from userenv and stored correctly" );
1025
};
1026
};
1026
1027
1028
subtest 'OnShelfHoldAllowed test' => sub {
1029
    plan tests => 3;
1030
    $dbh->do('DELETE FROM circulation_rules');
1031
    my $biblio = $builder->build_sample_biblio( { frameworkcode => $frameworkcode } )->biblionumber;
1032
1033
    # Create a helper item instance for testing
1034
    my $item = $builder->build_sample_item( { biblionumber => $biblio, library => $branch_1, itype => $itemtype } );
1035
1036
    Koha::CirculationRules->set_rules(
1037
        {
1038
            branchcode   => undef,
1039
            categorycode => undef,
1040
            itemtype     => undef,
1041
            rules        => {
1042
                reservesallowed => 25,
1043
                opacitemholds   => 'Y',
1044
                onshelfholds    => 1,
1045
            }
1046
        }
1047
    );
1048
1049
    my $canreserve = C4::Reserves::CanItemBeReserved( $patron, $item );
1050
1051
    is(
1052
        $canreserve->{status}, 'OK',
1053
        'item-level holds should be possible with onshelfholdallowed set to "Yes"'
1054
    );
1055
1056
    Koha::CirculationRules->set_rules(
1057
        {
1058
            branchcode   => undef,
1059
            categorycode => undef,
1060
            itemtype     => undef,
1061
            rules        => {
1062
                reservesallowed => 25,
1063
                opacitemholds   => 'Y',
1064
                onshelfholds    => '0',
1065
            }
1066
        }
1067
    );
1068
1069
    $canreserve = C4::Reserves::CanItemBeReserved( $patron, $item );
1070
1071
    is(
1072
        $canreserve->{status}, 'onShelfHoldsNotAllowed',
1073
        'item-level holds should not be possible with onshelfholdallowed set to "If any unavailable"'
1074
    );
1075
1076
    Koha::CirculationRules->set_rules(
1077
        {
1078
            branchcode   => undef,
1079
            categorycode => undef,
1080
            itemtype     => undef,
1081
            rules        => {
1082
                reservesallowed => 25,
1083
                opacitemholds   => 'Y',
1084
                onshelfholds    => '2',
1085
            }
1086
        }
1087
    );
1088
1089
    $canreserve = C4::Reserves::CanItemBeReserved( $patron, $item );
1090
1091
    is(
1092
        $canreserve->{status}, 'onShelfHoldsNotAllowed',
1093
        'item-level holds should not be possible with onshelfholdallowed set to "If all unavailable"'
1094
    );
1095
};
1096
1027
subtest 'MoveReserve additional test' => sub {
1097
subtest 'MoveReserve additional test' => sub {
1028
1098
1029
    plan tests => 8;
1099
    plan tests => 8;
Lines 1307-1312 subtest 'AllowHoldOnPatronPossession test' => sub { Link Here
1307
        }
1377
        }
1308
    );
1378
    );
1309
1379
1380
    Koha::CirculationRules->set_rules(
1381
        {
1382
            branchcode   => undef,
1383
            categorycode => undef,
1384
            itemtype     => undef,
1385
            rules        => {
1386
                onshelfholds => 1,
1387
            }
1388
        }
1389
    );
1390
1310
    C4::Circulation::AddIssue(
1391
    C4::Circulation::AddIssue(
1311
        $patron,
1392
        $patron,
1312
        $item->barcode
1393
        $item->barcode
Lines 1650-1655 subtest 'CanBookBeReserved() tests' => sub { Link Here
1650
            itemtype     => $itype->id,
1731
            itemtype     => $itype->id,
1651
            rules        => {
1732
            rules        => {
1652
                reservesallowed => 2,
1733
                reservesallowed => 2,
1734
                onshelfholds    => 1,
1653
            }
1735
            }
1654
        }
1736
        }
1655
    );
1737
    );
Lines 1729-1734 subtest 'CanItemBeReserved() tests' => sub { Link Here
1729
            itemtype     => $itype->id,
1811
            itemtype     => $itype->id,
1730
            rules        => {
1812
            rules        => {
1731
                reservesallowed => 2,
1813
                reservesallowed => 2,
1814
                onshelfholds    => 1,
1732
            }
1815
            }
1733
        }
1816
        }
1734
    );
1817
    );
(-)a/t/db_dependent/Reserves/IsOnShelfHoldsPolicySatisfied.t (+135 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
use Koha::DateUtils qw( dt_from_string );
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      = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, library => $branchcode } );
28
    my $item2      = $builder->build_sample_item( { biblionumber => $biblio->biblionumber, library => $branchcode } );
29
    my $patron =
30
        $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $branchcode } } );
31
    my $categorycode = $patron->categorycode;
32
33
    $circulationrule_rs->populate(
34
        [
35
            [ 'branchcode', 'categorycode', 'itemtype', 'rule_name',               'rule_value' ],
36
            [ $branchcode,  undef,          $itemtype,  'holdallowed',             'from_any_library' ],
37
            [ $branchcode,  undef,          $itemtype,  'hold_fulfillment_policy', 'any' ],
38
            [ $branchcode,  $categorycode,  undef,      'max_holds',               '99' ],
39
            [ $branchcode,  $categorycode,  $itemtype,  'holds_per_day',           '99' ],
40
            [ $branchcode,  $categorycode,  $itemtype,  'holds_per_record',        '99' ],
41
            [ $branchcode,  $categorycode,  $itemtype,  'reservesallowed',         '99' ],
42
        ]
43
    );
44
    my $onshelfholds_rule = $circulationrule_rs->create(
45
        {
46
            branchcode   => $branchcode,
47
            categorycode => $categorycode,
48
            itemtype     => $itemtype,
49
            rule_name    => 'onshelfholds',
50
            rule_value   => '0',
51
        }
52
    );
53
54
    subtest 'when all items are available' => sub {
55
        plan tests => 3;
56
57
        $onshelfholds_rule->update( { rule_value => '0' } );
58
        Koha::Cache::Memory::Lite->flush();
59
        ok(
60
            !C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
61
            'on shelf hold is not allowed if onshelfholds == 0'
62
        );
63
64
        $onshelfholds_rule->update( { rule_value => '1' } );
65
        Koha::Cache::Memory::Lite->flush();
66
        ok(
67
            C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
68
            'on shelf hold is always allowed if onshelfholds == 1'
69
        );
70
71
        $onshelfholds_rule->update( { rule_value => '2' } );
72
        Koha::Cache::Memory::Lite->flush();
73
        ok(
74
            !C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
75
            'on shelf hold is not allowed if onshelfholds == 2'
76
        );
77
    };
78
79
    subtest 'when checked item is not available but others are available' => sub {
80
        plan tests => 3;
81
82
        $item1->onloan( dt_from_string() )->store;
83
84
        $onshelfholds_rule->update( { rule_value => '0' } );
85
        Koha::Cache::Memory::Lite->flush();
86
        ok(
87
            C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
88
            'on shelf hold is allowed if onshelfholds == 0'
89
        );
90
91
        $onshelfholds_rule->update( { rule_value => '1' } );
92
        Koha::Cache::Memory::Lite->flush();
93
        ok(
94
            C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
95
            'on shelf hold is always allowed if onshelfholds == 1'
96
        );
97
98
        $onshelfholds_rule->update( { rule_value => '2' } );
99
        Koha::Cache::Memory::Lite->flush();
100
        ok(
101
            !C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
102
            'on shelf hold is not allowed if onshelfholds == 2'
103
        );
104
    };
105
106
    subtest 'when all items are unavailable' => sub {
107
        plan tests => 3;
108
109
        $item1->onloan( dt_from_string() )->store;
110
        $item2->onloan( dt_from_string() )->store;
111
112
        $onshelfholds_rule->update( { rule_value => '0' } );
113
        Koha::Cache::Memory::Lite->flush();
114
        ok(
115
            C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
116
            'on shelf hold is allowed if onshelfholds == 0'
117
        );
118
119
        $onshelfholds_rule->update( { rule_value => '1' } );
120
        Koha::Cache::Memory::Lite->flush();
121
        ok(
122
            C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
123
            'on shelf hold is always allowed if onshelfholds == 1'
124
        );
125
126
        $onshelfholds_rule->update( { rule_value => '2' } );
127
        Koha::Cache::Memory::Lite->flush();
128
        ok(
129
            C4::Reserves::IsOnShelfHoldsPolicySatisfied( { item => $item1, patron => $patron } ),
130
            'on shelf hold is allowed if onshelfholds == 2'
131
        );
132
    };
133
134
    $schema->txn_rollback;
135
};
(-)a/t/db_dependent/Reserves/MultiplePerRecord.t (+1 lines)
Lines 220-225 Koha::CirculationRules->set_rules( Link Here
220
        itemtype     => undef,
220
        itemtype     => undef,
221
        branchcode   => undef,
221
        branchcode   => undef,
222
        rules        => {
222
        rules        => {
223
            onshelfholds     => 1,
223
            reservesallowed  => 3,
224
            reservesallowed  => 3,
224
            holds_per_record => 2,
225
            holds_per_record => 2,
225
        }
226
        }
(-)a/t/db_dependent/api/v1/holds.t (-2 / +5 lines)
Lines 128-133 Koha::CirculationRules->set_rules( Link Here
128
        branchcode   => undef,
128
        branchcode   => undef,
129
        itemtype     => undef,
129
        itemtype     => undef,
130
        rules        => {
130
        rules        => {
131
            onshelfholds     => 1,
131
            reservesallowed  => 1,
132
            reservesallowed  => 1,
132
            holds_per_record => 99
133
            holds_per_record => 99
133
        }
134
        }
Lines 729-735 subtest 'add() tests (maxreserves behaviour)' => sub { Link Here
729
            itemtype     => undef,
730
            itemtype     => undef,
730
            branchcode   => undef,
731
            branchcode   => undef,
731
            categorycode => undef,
732
            categorycode => undef,
732
            rules        => { reservesallowed => 3 }
733
            rules        => {
734
                onshelfholds    => 1,
735
                reservesallowed => 3
736
            }
733
        }
737
        }
734
    );
738
    );
735
739
736
- 

Return to bug 20985