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