Bug 10481: Unit tests for C4::Members::AddEnrolmentFeeIfNeeded
[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 # Set a simple circ policy
128 $dbh->do('DELETE FROM issuingrules');
129 $dbh->do(
130     q{INSERT INTO issuingrules (categorycode, branchcode, itemtype, reservesallowed,
131                                 maxissueqty, issuelength, lengthunit,
132                                 renewalsallowed, renewalperiod)
133       VALUES (?, ?, ?, ?,
134               ?, ?, ?,
135               ?, ?
136              )
137     },
138     {},
139     '*', '*', '*', 25,
140     20, 14, 'days',
141     1, 7
142 );
143
144 # Test C4::Circulation::ProcessOfflinePayment
145 my $sth = C4::Context->dbh->prepare("SELECT COUNT(*) FROM accountlines WHERE amount = '-123.45' AND accounttype = 'Pay'");
146 $sth->execute();
147 my ( $original_count ) = $sth->fetchrow_array();
148
149 C4::Context->dbh->do("INSERT INTO borrowers ( cardnumber, surname, firstname, categorycode, branchcode ) VALUES ( '99999999999', 'Hall', 'Kyle', 'S', 'MPL' )");
150
151 C4::Circulation::ProcessOfflinePayment({ cardnumber => '99999999999', amount => '123.45' });
152
153 $sth->execute();
154 my ( $new_count ) = $sth->fetchrow_array();
155
156 ok( $new_count == $original_count  + 1, 'ProcessOfflinePayment makes payment correctly' );
157
158 C4::Context->dbh->do("DELETE FROM accountlines WHERE borrowernumber IN ( SELECT borrowernumber FROM borrowers WHERE cardnumber = '99999999999' )");
159 C4::Context->dbh->do("DELETE FROM borrowers WHERE cardnumber = '99999999999'");
160
161 {
162 # CanBookBeRenewed tests
163
164     # Generate test biblio
165     my $biblio = MARC::Record->new();
166     my $title = 'Silence in the library';
167     $biblio->append_fields(
168         MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
169         MARC::Field->new('245', ' ', ' ', a => $title),
170     );
171
172     my ($biblionumber, $biblioitemnumber) = AddBiblio($biblio, '');
173
174     my $barcode = 'R00000342';
175     my $branch = 'MPL';
176
177     my ($item_bibnum, $item_bibitemnum, $itemnumber) =
178         AddItem({ homebranch => $branch,
179                   holdingbranch => $branch,
180                   barcode => $barcode, } , $biblionumber);
181
182     my $barcode2 = 'R00000343';
183     my ($item_bibnum2, $item_bibitemnum2, $itemnumber2) =
184         AddItem({ homebranch => $branch,
185                   holdingbranch => $branch,
186                   barcode => $barcode2, } , $biblionumber);
187
188     # Create 2 borrowers
189     my %renewing_borrower_data = (
190         firstname =>  'John',
191         surname => 'Renewal',
192         categorycode => 'S',
193         branchcode => $branch,
194     );
195
196     my %reserving_borrower_data = (
197         firstname =>  'Katrin',
198         surname => 'Reservation',
199         categorycode => 'S',
200         branchcode => $branch,
201     );
202
203     my $renewing_borrowernumber = AddMember(%renewing_borrower_data);
204     my $reserving_borrowernumber = AddMember(%reserving_borrower_data);
205
206     my $renewing_borrower = GetMember( borrowernumber => $renewing_borrowernumber );
207
208     my $constraint     = 'a';
209     my $bibitems       = '';
210     my $priority       = '1';
211     my $resdate        = undef;
212     my $expdate        = undef;
213     my $notes          = '';
214     my $checkitem      = undef;
215     my $found          = undef;
216
217     my $datedue = AddIssue( $renewing_borrower, $barcode);
218     is (defined $datedue, 1, "Item 1 checked out, due date: $datedue");
219
220     my $datedue2 = AddIssue( $renewing_borrower, $barcode2);
221     is (defined $datedue2, 1, "Item 2 checked out, due date: $datedue2");
222
223     my $borrowing_borrowernumber = GetItemIssue($itemnumber)->{borrowernumber};
224     is ($borrowing_borrowernumber, $renewing_borrowernumber, "Item checked out to $renewing_borrower->{firstname} $renewing_borrower->{surname}");
225
226     my ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber, 1);
227     is( $renewokay, 1, 'Can renew, no holds for this title or item');
228
229
230     diag("Biblio-level hold, renewal test");
231     AddReserve(
232         $branch, $reserving_borrowernumber, $biblionumber,
233         $constraint, $bibitems,  $priority, $resdate, $expdate, $notes,
234         $title, $checkitem, $found
235     );
236
237     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber);
238     is( $renewokay, 0, '(Bug 10663) Cannot renew, reserved');
239     is( $error, 'on_reserve', '(Bug 10663) Cannot renew, reserved (returned error is on_reserve)');
240
241     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber2);
242     is( $renewokay, 0, '(Bug 10663) Cannot renew, reserved');
243     is( $error, 'on_reserve', '(Bug 10663) Cannot renew, reserved (returned error is on_reserve)');
244
245     my $reserveid = C4::Reserves::GetReserveId({ biblionumber => $biblionumber, borrowernumber => $reserving_borrowernumber});
246     CancelReserve({ reserve_id => $reserveid });
247
248
249     diag("Item-level hold, renewal test");
250     AddReserve(
251         $branch, $reserving_borrowernumber, $biblionumber,
252         $constraint, $bibitems,  $priority, $resdate, $expdate, $notes,
253         $title, $itemnumber, $found
254     );
255
256     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber, 1);
257     is( $renewokay, 0, '(Bug 10663) Cannot renew, item reserved');
258     is( $error, 'on_reserve', '(Bug 10663) Cannot renew, item reserved (returned error is on_reserve)');
259
260     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber2, 1);
261     is( $renewokay, 1, 'Can renew item 2, item-level hold is on item 1');
262
263
264     diag("Items can't fill hold for reasons");
265     ModItem({ notforloan => 1 }, $biblionumber, $itemnumber);
266     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber, 1);
267     is( $renewokay, 1, 'Can renew, item is marked not for loan, hold does not block');
268     ModItem({ notforloan => 0, itype => '' }, $biblionumber, $itemnumber,1);
269
270     # FIXME: Add more for itemtype not for loan etc.
271
272     $reserveid = C4::Reserves::GetReserveId({ biblionumber => $biblionumber, itemnumber => $itemnumber, borrowernumber => $reserving_borrowernumber});
273     CancelReserve({ reserve_id => $reserveid });
274
275     diag("Too many renewals");
276
277     # set policy to forbid renewals
278     $dbh->do('UPDATE issuingrules SET renewalsallowed = 0');
279
280     ( $renewokay, $error ) = CanBookBeRenewed($renewing_borrowernumber, $itemnumber);
281     is( $renewokay, 0, 'Cannot renew, 0 renewals allowed');
282     is( $error, 'too_many', 'Cannot renew, 0 renewals allowed (returned code is too_many)');
283
284 }
285
286 $dbh->rollback;