|
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 => 59; |
10 |
use Test::More tests => 60; |
| 11 |
use MARC::Record; |
11 |
use MARC::Record; |
| 12 |
|
12 |
|
| 13 |
use C4::Biblio; |
13 |
use C4::Biblio; |
|
Lines 24-29
use Koha::IssuingRules;
Link Here
|
| 24 |
use Koha::Item::Transfer::Limits; |
24 |
use Koha::Item::Transfer::Limits; |
| 25 |
use Koha::Items; |
25 |
use Koha::Items; |
| 26 |
use Koha::Libraries; |
26 |
use Koha::Libraries; |
|
|
27 |
use Koha::Library::Groups; |
| 27 |
use Koha::Patrons; |
28 |
use Koha::Patrons; |
| 28 |
|
29 |
|
| 29 |
BEGIN { |
30 |
BEGIN { |
|
Lines 263-268
t::lib::Mocks::mock_preference('item-level_itypes', 1);
Link Here
|
| 263 |
|
264 |
|
| 264 |
# if IndependentBranches is OFF, a $branch_1 patron can reserve an $branch_2 item |
265 |
# if IndependentBranches is OFF, a $branch_1 patron can reserve an $branch_2 item |
| 265 |
t::lib::Mocks::mock_preference('IndependentBranches', 0); |
266 |
t::lib::Mocks::mock_preference('IndependentBranches', 0); |
|
|
267 |
|
| 266 |
ok( |
268 |
ok( |
| 267 |
CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status} eq 'OK', |
269 |
CanItemBeReserved($borrowernumbers[0], $foreign_itemnumber)->{status} eq 'OK', |
| 268 |
'$branch_1 patron allowed to reserve $branch_2 item with IndependentBranches OFF (bug 2394)' |
270 |
'$branch_1 patron allowed to reserve $branch_2 item with IndependentBranches OFF (bug 2394)' |
|
Lines 687-689
subtest 'CanItemBeReserved / holds_per_day tests' => sub {
Link Here
|
| 687 |
|
689 |
|
| 688 |
$schema->storage->txn_rollback; |
690 |
$schema->storage->txn_rollback; |
| 689 |
}; |
691 |
}; |
| 690 |
- |
692 |
|
|
|
693 |
subtest 'CanItemBeReserved / branch_not_in_hold_group' => sub { |
| 694 |
plan tests => 9; |
| 695 |
|
| 696 |
$schema->storage->txn_begin; |
| 697 |
|
| 698 |
# Cleanup database |
| 699 |
Koha::Holds->search->delete; |
| 700 |
$dbh->do('DELETE FROM issues'); |
| 701 |
$dbh->do('DELETE FROM issuingrules'); |
| 702 |
$dbh->do( |
| 703 |
q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed) |
| 704 |
VALUES (?, ?, ?, ?)}, |
| 705 |
{}, |
| 706 |
'*', '*', '*', 25 |
| 707 |
); |
| 708 |
$dbh->do('DELETE FROM branch_item_rules'); |
| 709 |
$dbh->do('DELETE FROM default_branch_circ_rules'); |
| 710 |
$dbh->do('DELETE FROM default_branch_item_rules'); |
| 711 |
$dbh->do('DELETE FROM default_circ_rules'); |
| 712 |
|
| 713 |
Koha::Items->search->delete; |
| 714 |
Koha::Biblios->search->delete; |
| 715 |
|
| 716 |
# Create item types |
| 717 |
my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } ); |
| 718 |
my $itemtype2 = $builder->build_object( { class => 'Koha::ItemTypes' } ); |
| 719 |
|
| 720 |
# Create libraries |
| 721 |
my $library1 = $builder->build_object( { class => 'Koha::Libraries' } ); |
| 722 |
my $library2 = $builder->build_object( { class => 'Koha::Libraries' } ); |
| 723 |
my $library3 = $builder->build_object( { class => 'Koha::Libraries' } ); |
| 724 |
|
| 725 |
# Create library groups hierarchy |
| 726 |
my $rootgroup = $builder->build_object( { class => 'Koha::Library::Groups', value => {ft_local_hold_group => 1} } ); |
| 727 |
my $group1 = $builder->build_object( { class => 'Koha::Library::Groups', value => {parent_id => $rootgroup->id, branchcode => $library1->branchcode}} ); |
| 728 |
my $group2 = $builder->build_object( { class => 'Koha::Library::Groups', value => {parent_id => $rootgroup->id, branchcode => $library2->branchcode} } ); |
| 729 |
|
| 730 |
# Create 2 patrons |
| 731 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons', value => {branchcode => $library1->branchcode} } ); |
| 732 |
my $patron3 = $builder->build_object( { class => 'Koha::Patrons', value => {branchcode => $library3->branchcode} } ); |
| 733 |
|
| 734 |
# Create 3 biblios with items |
| 735 |
my $biblio_1 = $builder->build_sample_biblio({ itemtype => $itemtype1->itemtype }); |
| 736 |
my ( undef, undef, $itemnumber_1 ) = AddItem( |
| 737 |
{ homebranch => $library1->branchcode, |
| 738 |
holdingbranch => $library1->branchcode |
| 739 |
}, |
| 740 |
$biblio_1->biblionumber |
| 741 |
); |
| 742 |
my $biblio_2 = $builder->build_sample_biblio({ itemtype => $itemtype2->itemtype }); |
| 743 |
my ( undef, undef, $itemnumber_2 ) = AddItem( |
| 744 |
{ homebranch => $library2->branchcode, |
| 745 |
holdingbranch => $library2->branchcode |
| 746 |
}, |
| 747 |
$biblio_2->biblionumber |
| 748 |
); |
| 749 |
my $biblio_3 = $builder->build_sample_biblio({ itemtype => $itemtype1->itemtype }); |
| 750 |
my ( undef, undef, $itemnumber_3 ) = AddItem( |
| 751 |
{ homebranch => $library1->branchcode, |
| 752 |
holdingbranch => $library1->branchcode |
| 753 |
}, |
| 754 |
$biblio_3->biblionumber |
| 755 |
); |
| 756 |
|
| 757 |
# Test 1: Patron 3 can place hold |
| 758 |
is_deeply( |
| 759 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 760 |
{ status => 'OK' }, |
| 761 |
'Patron can place hold if no circ_rules where defined' |
| 762 |
); |
| 763 |
|
| 764 |
# Insert default circ rule of holds allowed only from local hold group for all libraries |
| 765 |
$dbh->do( |
| 766 |
q{INSERT INTO default_circ_rules (holdallowed, hold_fulfillment_policy, returnbranch) |
| 767 |
VALUES (?,?,?)}, |
| 768 |
{}, |
| 769 |
3, 'any', 'any' |
| 770 |
); |
| 771 |
|
| 772 |
# Test 2: Patron 1 can place hold |
| 773 |
is_deeply( |
| 774 |
CanItemBeReserved( $patron1->borrowernumber, $itemnumber_2 ), |
| 775 |
{ status => 'OK' }, |
| 776 |
'Patron can place hold because patron\'s home library is part of hold group' |
| 777 |
); |
| 778 |
|
| 779 |
# Test 3: Patron 3 cannot place hold |
| 780 |
is_deeply( |
| 781 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 782 |
{ status => 'branchNotInHoldGroup' }, |
| 783 |
'Patron cannot place hold because patron\'s home library is not part of hold group' |
| 784 |
); |
| 785 |
|
| 786 |
# Cleanup default_cirt_rules |
| 787 |
$dbh->do('DELETE FROM default_circ_rules'); |
| 788 |
|
| 789 |
# Insert default circ rule to "any" for library 2 |
| 790 |
$dbh->do( |
| 791 |
q{INSERT INTO default_branch_circ_rules (branchcode, holdallowed, hold_fulfillment_policy, returnbranch) |
| 792 |
VALUES (?,?,?,?)}, |
| 793 |
{}, |
| 794 |
$library2->branchcode, 2, 'any', 'any' |
| 795 |
); |
| 796 |
|
| 797 |
# Test 4: Patron 3 can place hold |
| 798 |
is_deeply( |
| 799 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 800 |
{ status => 'OK' }, |
| 801 |
'Patron can place hold if holdallowed is set to "any" for library 2' |
| 802 |
); |
| 803 |
|
| 804 |
# Update default circ rule to "hold group" for library 2 |
| 805 |
$dbh->do( |
| 806 |
q{UPDATE default_branch_circ_rules set holdallowed = ? |
| 807 |
WHERE branchcode = ?}, |
| 808 |
{}, |
| 809 |
3, $library2->branchcode |
| 810 |
); |
| 811 |
|
| 812 |
# Test 5: Patron 3 cannot place hold |
| 813 |
is_deeply( |
| 814 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 815 |
{ status => 'branchNotInHoldGroup' }, |
| 816 |
'Patron cannot place hold if holdallowed is set to "hold group" for library 2' |
| 817 |
); |
| 818 |
|
| 819 |
# Cleanup default_branch_cirt_rules |
| 820 |
$dbh->do('DELETE FROM default_branch_circ_rules'); |
| 821 |
|
| 822 |
# Insert default item rule to "any" for itemtype 2 |
| 823 |
$dbh->do( |
| 824 |
q{INSERT INTO default_branch_item_rules (itemtype, holdallowed, hold_fulfillment_policy, returnbranch) |
| 825 |
VALUES (?,?,?,?)}, |
| 826 |
{}, |
| 827 |
$itemtype2->itemtype, 2, 'any', 'any' |
| 828 |
); |
| 829 |
|
| 830 |
# Test 6: Patron 3 can place hold |
| 831 |
is_deeply( |
| 832 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 833 |
{ status => 'OK' }, |
| 834 |
'Patron can place hold if holdallowed is set to "any" for itemtype 2' |
| 835 |
); |
| 836 |
|
| 837 |
# Update default item rule to "hold group" for itemtype 2 |
| 838 |
$dbh->do( |
| 839 |
q{UPDATE default_branch_item_rules set holdallowed = ? |
| 840 |
WHERE itemtype = ?}, |
| 841 |
{}, |
| 842 |
3, $itemtype2->itemtype |
| 843 |
); |
| 844 |
|
| 845 |
# Test 7: Patron 3 cannot place hold |
| 846 |
is_deeply( |
| 847 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 848 |
{ status => 'branchNotInHoldGroup' }, |
| 849 |
'Patron cannot place hold if holdallowed is set to "hold group" for itemtype 2' |
| 850 |
); |
| 851 |
|
| 852 |
# Cleanup default_branch_item_rules |
| 853 |
$dbh->do('DELETE FROM default_branch_item_rules'); |
| 854 |
|
| 855 |
# Insert branch item rule to "any" for itemtype 2 and library 2 |
| 856 |
$dbh->do( |
| 857 |
q{INSERT INTO branch_item_rules (branchcode, itemtype, holdallowed, hold_fulfillment_policy, returnbranch) |
| 858 |
VALUES (?,?,?,?,?)}, |
| 859 |
{}, |
| 860 |
$library2->branchcode, $itemtype2->itemtype, 2, 'any', 'any' |
| 861 |
); |
| 862 |
|
| 863 |
# Test 8: Patron 3 can place hold |
| 864 |
is_deeply( |
| 865 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 866 |
{ status => 'OK' }, |
| 867 |
'Patron can place hold if holdallowed is set to "any" for itemtype 2 and library 2' |
| 868 |
); |
| 869 |
|
| 870 |
# Update branch item rule to "hold group" for itemtype 2 and library 2 |
| 871 |
$dbh->do( |
| 872 |
q{UPDATE branch_item_rules set holdallowed = ? |
| 873 |
WHERE branchcode = ? and itemtype = ?}, |
| 874 |
{}, |
| 875 |
3, $library2->branchcode, $itemtype2->itemtype |
| 876 |
); |
| 877 |
|
| 878 |
# Test 9: Patron 3 cannot place hold |
| 879 |
is_deeply( |
| 880 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2 ), |
| 881 |
{ status => 'branchNotInHoldGroup' }, |
| 882 |
'Patron cannot place hold if holdallowed is set to "hold group" for itemtype 2 and library 2' |
| 883 |
); |
| 884 |
|
| 885 |
$schema->storage->txn_rollback; |
| 886 |
|
| 887 |
}; |
| 888 |
|
| 889 |
subtest 'CanItemBeReserved / pickup_not_in_hold_group' => sub { |
| 890 |
plan tests => 9; |
| 891 |
|
| 892 |
$schema->storage->txn_begin; |
| 893 |
|
| 894 |
# Cleanup database |
| 895 |
Koha::Holds->search->delete; |
| 896 |
$dbh->do('DELETE FROM issues'); |
| 897 |
$dbh->do('DELETE FROM issuingrules'); |
| 898 |
$dbh->do( |
| 899 |
q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed) |
| 900 |
VALUES (?, ?, ?, ?)}, |
| 901 |
{}, |
| 902 |
'*', '*', '*', 25 |
| 903 |
); |
| 904 |
$dbh->do('DELETE FROM branch_item_rules'); |
| 905 |
$dbh->do('DELETE FROM default_branch_circ_rules'); |
| 906 |
$dbh->do('DELETE FROM default_branch_item_rules'); |
| 907 |
$dbh->do('DELETE FROM default_circ_rules'); |
| 908 |
|
| 909 |
Koha::Items->search->delete; |
| 910 |
Koha::Biblios->search->delete; |
| 911 |
|
| 912 |
# Create item types |
| 913 |
my $itemtype1 = $builder->build_object( { class => 'Koha::ItemTypes' } ); |
| 914 |
my $itemtype2 = $builder->build_object( { class => 'Koha::ItemTypes' } ); |
| 915 |
|
| 916 |
# Create libraries |
| 917 |
my $library1 = $builder->build_object( { class => 'Koha::Libraries' } ); |
| 918 |
my $library2 = $builder->build_object( { class => 'Koha::Libraries' } ); |
| 919 |
my $library3 = $builder->build_object( { class => 'Koha::Libraries' } ); |
| 920 |
|
| 921 |
# Create library groups hierarchy |
| 922 |
my $rootgroup = $builder->build_object( { class => 'Koha::Library::Groups', value => {ft_local_hold_group => 1} } ); |
| 923 |
my $group1 = $builder->build_object( { class => 'Koha::Library::Groups', value => {parent_id => $rootgroup->id, branchcode => $library1->branchcode}} ); |
| 924 |
my $group2 = $builder->build_object( { class => 'Koha::Library::Groups', value => {parent_id => $rootgroup->id, branchcode => $library2->branchcode} } ); |
| 925 |
|
| 926 |
# Create 2 patrons |
| 927 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons', value => {branchcode => $library1->branchcode} } ); |
| 928 |
my $patron3 = $builder->build_object( { class => 'Koha::Patrons', value => {branchcode => $library3->branchcode} } ); |
| 929 |
|
| 930 |
# Create 3 biblios with items |
| 931 |
my $biblio_1 = $builder->build_sample_biblio({ itemtype => $itemtype1->itemtype }); |
| 932 |
my ( undef, undef, $itemnumber_1 ) = AddItem( |
| 933 |
{ homebranch => $library1->branchcode, |
| 934 |
holdingbranch => $library1->branchcode |
| 935 |
}, |
| 936 |
$biblio_1->biblionumber |
| 937 |
); |
| 938 |
my $biblio_2 = $builder->build_sample_biblio({ itemtype => $itemtype2->itemtype }); |
| 939 |
my ( undef, undef, $itemnumber_2 ) = AddItem( |
| 940 |
{ homebranch => $library2->branchcode, |
| 941 |
holdingbranch => $library2->branchcode |
| 942 |
}, |
| 943 |
$biblio_2->biblionumber |
| 944 |
); |
| 945 |
my $biblio_3 = $builder->build_sample_biblio({ itemtype => $itemtype1->itemtype }); |
| 946 |
my ( undef, undef, $itemnumber_3 ) = AddItem( |
| 947 |
{ homebranch => $library1->branchcode, |
| 948 |
holdingbranch => $library1->branchcode |
| 949 |
}, |
| 950 |
$biblio_3->biblionumber |
| 951 |
); |
| 952 |
|
| 953 |
# Test 1: Patron 3 can place hold |
| 954 |
is_deeply( |
| 955 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 956 |
{ status => 'OK' }, |
| 957 |
'Patron can place hold if no circ_rules where defined' |
| 958 |
); |
| 959 |
|
| 960 |
# Insert default circ rule of holds allowed only from local hold group for all libraries |
| 961 |
$dbh->do( |
| 962 |
q{INSERT INTO default_circ_rules (holdallowed, hold_fulfillment_policy, returnbranch) |
| 963 |
VALUES (?,?,?)}, |
| 964 |
{}, |
| 965 |
2, 'holdgroup', 'any' |
| 966 |
); |
| 967 |
|
| 968 |
# Test 2: Patron 1 can place hold |
| 969 |
is_deeply( |
| 970 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library1->branchcode ), |
| 971 |
{ status => 'OK' }, |
| 972 |
'Patron can place hold because pickup location is part of hold group' |
| 973 |
); |
| 974 |
|
| 975 |
# Test 3: Patron 3 cannot place hold |
| 976 |
is_deeply( |
| 977 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 978 |
{ status => 'pickupNotInHoldGroup' }, |
| 979 |
'Patron cannot place hold because pickup location is not part of hold group' |
| 980 |
); |
| 981 |
|
| 982 |
# Cleanup default_cirt_rules |
| 983 |
$dbh->do('DELETE FROM default_circ_rules'); |
| 984 |
|
| 985 |
# Insert default circ rule to "any" for library 2 |
| 986 |
$dbh->do( |
| 987 |
q{INSERT INTO default_branch_circ_rules (branchcode, holdallowed, hold_fulfillment_policy, returnbranch) |
| 988 |
VALUES (?,?,?,?)}, |
| 989 |
{}, |
| 990 |
$library2->branchcode, 2, 'any', 'any' |
| 991 |
); |
| 992 |
|
| 993 |
# Test 4: Patron 3 can place hold |
| 994 |
is_deeply( |
| 995 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 996 |
{ status => 'OK' }, |
| 997 |
'Patron can place hold if default_branch_circ_rules is set to "any" for library 2' |
| 998 |
); |
| 999 |
|
| 1000 |
# Update default circ rule to "hold group" for library 2 |
| 1001 |
$dbh->do( |
| 1002 |
q{UPDATE default_branch_circ_rules set hold_fulfillment_policy = ? |
| 1003 |
WHERE branchcode = ?}, |
| 1004 |
{}, |
| 1005 |
'holdgroup', $library2->branchcode |
| 1006 |
); |
| 1007 |
|
| 1008 |
# Test 5: Patron 3 cannot place hold |
| 1009 |
is_deeply( |
| 1010 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 1011 |
{ status => 'pickupNotInHoldGroup' }, |
| 1012 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for library 2' |
| 1013 |
); |
| 1014 |
|
| 1015 |
# Cleanup default_branch_cirt_rules |
| 1016 |
$dbh->do('DELETE FROM default_branch_circ_rules'); |
| 1017 |
|
| 1018 |
# Insert default item rule to "any" for itemtype 2 |
| 1019 |
$dbh->do( |
| 1020 |
q{INSERT INTO default_branch_item_rules (itemtype, holdallowed, hold_fulfillment_policy, returnbranch) |
| 1021 |
VALUES (?,?,?,?)}, |
| 1022 |
{}, |
| 1023 |
$itemtype2->itemtype, 2, 'any', 'any' |
| 1024 |
); |
| 1025 |
|
| 1026 |
# Test 6: Patron 3 can place hold |
| 1027 |
is_deeply( |
| 1028 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 1029 |
{ status => 'OK' }, |
| 1030 |
'Patron can place hold if hold_fulfillment_policy is set to "any" for itemtype 2' |
| 1031 |
); |
| 1032 |
|
| 1033 |
# Update default item rule to "hold group" for itemtype 2 |
| 1034 |
$dbh->do( |
| 1035 |
q{UPDATE default_branch_item_rules set hold_fulfillment_policy = ? |
| 1036 |
WHERE itemtype = ?}, |
| 1037 |
{}, |
| 1038 |
'holdgroup', $itemtype2->itemtype |
| 1039 |
); |
| 1040 |
|
| 1041 |
# Test 7: Patron 3 cannot place hold |
| 1042 |
is_deeply( |
| 1043 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 1044 |
{ status => 'pickupNotInHoldGroup' }, |
| 1045 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for itemtype 2' |
| 1046 |
); |
| 1047 |
|
| 1048 |
# Cleanup default_branch_item_rules |
| 1049 |
$dbh->do('DELETE FROM default_branch_item_rules'); |
| 1050 |
|
| 1051 |
# Insert branch item rule to "any" for itemtype 2 and library 2 |
| 1052 |
$dbh->do( |
| 1053 |
q{INSERT INTO branch_item_rules (branchcode, itemtype, holdallowed, hold_fulfillment_policy, returnbranch) |
| 1054 |
VALUES (?,?,?,?,?)}, |
| 1055 |
{}, |
| 1056 |
$library2->branchcode, $itemtype2->itemtype, 2, 'any', 'any' |
| 1057 |
); |
| 1058 |
|
| 1059 |
# Test 8: Patron 3 can place hold |
| 1060 |
is_deeply( |
| 1061 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 1062 |
{ status => 'OK' }, |
| 1063 |
'Patron can place hold if hold_fulfillment_policy is set to "any" for itemtype 2 and library 2' |
| 1064 |
); |
| 1065 |
|
| 1066 |
# Update branch item rule to "hold group" for itemtype 2 and library 2 |
| 1067 |
$dbh->do( |
| 1068 |
q{UPDATE branch_item_rules set hold_fulfillment_policy = ? |
| 1069 |
WHERE branchcode = ? and itemtype = ?}, |
| 1070 |
{}, |
| 1071 |
'holdgroup', $library2->branchcode, $itemtype2->itemtype |
| 1072 |
); |
| 1073 |
|
| 1074 |
# Test 9: Patron 3 cannot place hold |
| 1075 |
is_deeply( |
| 1076 |
CanItemBeReserved( $patron3->borrowernumber, $itemnumber_2, $library3->branchcode ), |
| 1077 |
{ status => 'pickupNotInHoldGroup' }, |
| 1078 |
'Patron cannot place hold if hold_fulfillment_policy is set to "hold group" for itemtype 2 and library 2' |
| 1079 |
); |
| 1080 |
|
| 1081 |
$schema->storage->txn_rollback; |
| 1082 |
}; |