Bug 10663: Follow-up - Unit tests for CanBookBeRenewed
[koha.git] / t / db_dependent / Circulation.t
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4
5 use DateTime;
6 use C4::Biblio;
7 use C4::Branch;
8 use C4::Items;
9 use C4::Members;
10 use C4::Reserves;
11
12 use Test::More tests => 30;
13
14 BEGIN {
15     use_ok('C4::Circulation');
16 }
17
18 my $dbh = C4::Context->dbh;
19
20 # Start transaction
21 $dbh->{AutoCommit} = 0;
22 $dbh->{RaiseError} = 1;
23
24 my $CircControl = C4::Context->preference('CircControl');
25 my $HomeOrHoldingBranch = C4::Context->preference('HomeOrHoldingBranch');
26
27 my $item = {
28     homebranch => 'MPL',
29     holdingbranch => 'MPL'
30 };
31
32 my $borrower = {
33     branchcode => 'MPL'
34 };
35
36 # No userenv, PickupLibrary
37 C4::Context->set_preference('CircControl', 'PickupLibrary');
38 is(
39     C4::Context->preference('CircControl'),
40     'PickupLibrary',
41     'CircControl changed to PickupLibrary'
42 );
43 is(
44     C4::Circulation::_GetCircControlBranch($item, $borrower),
45     $item->{$HomeOrHoldingBranch},
46     '_GetCircControlBranch returned item branch (no userenv defined)'
47 );
48
49 # No userenv, PatronLibrary
50 C4::Context->set_preference('CircControl', 'PatronLibrary');
51 is(
52     C4::Context->preference('CircControl'),
53     'PatronLibrary',
54     'CircControl changed to PatronLibrary'
55 );
56 is(
57     C4::Circulation::_GetCircControlBranch($item, $borrower),
58     $borrower->{branchcode},
59     '_GetCircControlBranch returned borrower branch'
60 );
61
62 # No userenv, ItemHomeLibrary
63 C4::Context->set_preference('CircControl', 'ItemHomeLibrary');
64 is(
65     C4::Context->preference('CircControl'),
66     'ItemHomeLibrary',
67     'CircControl changed to ItemHomeLibrary'
68 );
69 is(
70     $item->{$HomeOrHoldingBranch},
71     C4::Circulation::_GetCircControlBranch($item, $borrower),
72     '_GetCircControlBranch returned item branch'
73 );
74
75 diag('Now, set a userenv');
76 C4::Context->_new_userenv('xxx');
77 C4::Context::set_userenv(0,0,0,'firstname','surname', 'MPL', 'Midway Public Library', '', '', '');
78 is(C4::Context->userenv->{branch}, 'MPL', 'userenv set');
79
80 # Userenv set, PickupLibrary
81 C4::Context->set_preference('CircControl', 'PickupLibrary');
82 is(
83     C4::Context->preference('CircControl'),
84     'PickupLibrary',
85     'CircControl changed to PickupLibrary'
86 );
87 is(
88     C4::Circulation::_GetCircControlBranch($item, $borrower),
89     'MPL',
90     '_GetCircControlBranch returned current branch'
91 );
92
93 # Userenv set, PatronLibrary
94 C4::Context->set_preference('CircControl', 'PatronLibrary');
95 is(
96     C4::Context->preference('CircControl'),
97     'PatronLibrary',
98     'CircControl changed to PatronLibrary'
99 );
100 is(
101     C4::Circulation::_GetCircControlBranch($item, $borrower),
102     $borrower->{branchcode},
103     '_GetCircControlBranch returned borrower branch'
104 );
105
106 # Userenv set, ItemHomeLibrary
107 C4::Context->set_preference('CircControl', 'ItemHomeLibrary');
108 is(
109     C4::Context->preference('CircControl'),
110     'ItemHomeLibrary',
111     'CircControl changed to ItemHomeLibrary'
112 );
113 is(
114     C4::Circulation::_GetCircControlBranch($item, $borrower),
115     $item->{$HomeOrHoldingBranch},
116     '_GetCircControlBranch returned item branch'
117 );
118
119 # Reset initial configuration
120 C4::Context->set_preference('CircControl', $CircControl);
121 is(
122     C4::Context->preference('CircControl'),
123     $CircControl,
124     'CircControl reset to its initial value'
125 );
126
127 # Test C4::Circulation::ProcessOfflinePayment
128 my $sth = C4::Context->dbh->prepare("SELECT COUNT(*) FROM accountlines WHERE amount = '-123.45' AND accounttype = 'Pay'");
129 $sth->execute();
130 my ( $original_count ) = $sth->fetchrow_array();
131
132 C4::Context->dbh->do("INSERT INTO borrowers ( cardnumber, surname, firstname, categorycode, branchcode ) VALUES ( '99999999999', 'Hall', 'Kyle', 'S', 'MPL' )");
133
134 C4::Circulation::ProcessOfflinePayment({ cardnumber => '99999999999', amount => '123.45' });
135
136 $sth->execute();
137 my ( $new_count ) = $sth->fetchrow_array();
138
139 ok( $new_count == $original_count  + 1, 'ProcessOfflinePayment makes payment correctly' );
140
141 C4::Context->dbh->do("DELETE FROM accountlines WHERE borrowernumber IN ( SELECT borrowernumber FROM borrowers WHERE cardnumber = '99999999999' )");
142 C4::Context->dbh->do("DELETE FROM borrowers WHERE cardnumber = '99999999999'");
143
144 {
145 # CanBookBeRenewed tests
146
147     # Generate test biblio
148     my $biblio = MARC::Record->new();
149     my $title = 'Silence in the library';
150     $biblio->append_fields(
151         MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
152         MARC::Field->new('245', ' ', ' ', a => $title),
153     );
154
155     my ($biblionumber, $biblioitemnumber) = AddBiblio($biblio, '');
156
157     my $barcode = 'R00000342';
158     my $branch = 'MPL';
159
160     my ($item_bibnum, $item_bibitemnum, $itemnumber) =
161         AddItem({ homebranch => $branch,
162                   holdingbranch => $branch,
163                   barcode => $barcode, } , $biblionumber);
164
165     my $barcode2 = 'R00000343';
166     my ($item_bibnum2, $item_bibitemnum2, $itemnumber2) =
167         AddItem({ homebranch => $branch,
168                   holdingbranch => $branch,
169                   barcode => $barcode2, } , $biblionumber);
170
171     # Create 2 borrowers
172     my %renewing_borrower_data = (
173         firstname =>  'John',
174         surname => 'Renewal',
175         categorycode => 'S',
176         branchcode => $branch,
177     );
178
179     my %reserving_borrower_data = (
180         firstname =>  'Katrin',
181         surname => 'Reservation',
182         categorycode => 'S',
183         branchcode => $branch,
184     );
185
186     my $renewing_borrowernumber = AddMember(%renewing_borrower_data);
187     my $reserving_borrowernumber = AddMember(%reserving_borrower_data);
188
189     my $renewing_borrower = GetMember( borrowernumber => $renewing_borrowernumber );
190
191     my $constraint     = 'a';
192     my $bibitems       = '';
193     my $priority       = '1';
194     my $resdate        = undef;
195     my $expdate        = undef;
196     my $notes          = '';
197     my $checkitem      = undef;
198     my $found          = undef;
199
200     my $datedue = AddIssue( $renewing_borrower, $barcode);
201     is (defined $datedue, 1, "Item 1 checked out, due date: $datedue");
202
203     my $datedue2 = AddIssue( $renewing_borrower, $barcode2);
204     is (defined $datedue2, 1, "Item 2 checked out, due date: $datedue2");
205
206     my $borrowing_borrowernumber = GetItemIssue($itemnumber)->{borrowernumber};
207     is ($borrowing_borrowernumber, $renewing_borrowernumber, "Item checked out to $renewing_borrower->{firstname} $renewing_borrower->{surname}");
208
209     my ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber, 1);
210     is( $renewokay, 1, 'Can renew, no holds for this title or item');
211
212
213     diag("Biblio-level hold, renewal test");
214     AddReserve(
215         $branch, $reserving_borrowernumber, $biblionumber,
216         $constraint, $bibitems,  $priority, $resdate, $expdate, $notes,
217         $title, $checkitem, $found
218     );
219
220     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber);
221     is( $renewokay, 0, '(Bug 10663) Cannot renew, reserved');
222     is( $error, 'on_reserve', '(Bug 10663) Cannot renew, reserved (returned error is on_reserve)');
223
224     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber2);
225     is( $renewokay, 0, '(Bug 10663) Cannot renew, reserved');
226     is( $error, 'on_reserve', '(Bug 10663) Cannot renew, reserved (returned error is on_reserve)');
227
228     my $reserveid = C4::Reserves::GetReserveId({ biblionumber => $biblionumber, borrowernumber => $reserving_borrowernumber});
229     CancelReserve({ reserve_id => $reserveid });
230
231
232     diag("Item-level hold, renewal test");
233     AddReserve(
234         $branch, $reserving_borrowernumber, $biblionumber,
235         $constraint, $bibitems,  $priority, $resdate, $expdate, $notes,
236         $title, $itemnumber, $found
237     );
238
239     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber, 1);
240     is( $renewokay, 0, '(Bug 10663) Cannot renew, item reserved');
241     is( $error, 'on_reserve', '(Bug 10663) Cannot renew, item reserved (returned error is on_reserve)');
242
243     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber2, 1);
244     is( $renewokay, 1, 'Can renew item 2, item-level hold is on item 1');
245
246
247     diag("Items can't fill hold for reasons");
248     ModItem({ notforloan => 1 }, $biblionumber, $itemnumber);
249     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber, 1);
250     is( $renewokay, 1, 'Can renew, item is marked not for loan, hold does not block');
251     ModItem({ notforloan => 0, itype => '' }, $biblionumber, $itemnumber,1);
252
253     # FIXME: Add more for itemtype not for loan etc.
254
255     $reserveid = C4::Reserves::GetReserveId({ biblionumber => $biblionumber, itemnumber => $itemnumber, borrowernumber => $reserving_borrowernumber});
256     CancelReserve({ reserve_id => $reserveid });
257
258
259     diag("Too many renewals");
260
261     # FIXME: Check with circulation rules and renewalsallowed set properly configured
262
263     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber);
264     is( $renewokay, 0, 'Cannot renew, 0 renewals allowed');
265     is( $error, 'too_many', 'Cannot renew, 0 renewals allowed (returned code is too_many)');
266
267 }
268
269 $dbh->rollback;