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