Bug 12803 - Add ability to skip closed libraries when generating the holds queue
[koha.git] / t / db_dependent / Circulation_Branch.t
1 #!/usr/bin/perl
2
3 use Modern::Perl;
4 use C4::Biblio;
5 use C4::Members;
6 use C4::Circulation;
7 use C4::Items;
8 use C4::Context;
9 use Koha::Library;
10
11 use Test::More tests => 14;
12
13 BEGIN {
14     use_ok('C4::Circulation');
15 }
16
17 can_ok( 'C4::Circulation', qw(
18     AddIssue
19     AddReturn
20     GetBranchBorrowerCircRule
21     GetBranchItemRule
22     GetIssuingRule
23     )
24 );
25
26 #Start transaction
27 my $dbh = C4::Context->dbh;
28 $dbh->{RaiseError} = 1;
29 $dbh->{AutoCommit} = 0;
30
31 $dbh->do(q|DELETE FROM issues|);
32 $dbh->do(q|DELETE FROM items|);
33 $dbh->do(q|DELETE FROM borrowers|);
34 $dbh->do(q|DELETE FROM branches|);
35 $dbh->do(q|DELETE FROM categories|);
36 $dbh->do(q|DELETE FROM accountlines|);
37 $dbh->do(q|DELETE FROM itemtypes|);
38 $dbh->do(q|DELETE FROM branch_item_rules|);
39 $dbh->do(q|DELETE FROM branch_borrower_circ_rules|);
40 $dbh->do(q|DELETE FROM default_branch_circ_rules|);
41 $dbh->do(q|DELETE FROM default_circ_rules|);
42 $dbh->do(q|DELETE FROM default_branch_item_rules|);
43
44 #Add branch and category
45 my $samplebranch1 = {
46     branchcode     => 'SAB1',
47     branchname     => 'Sample Branch',
48     branchaddress1 => 'sample adr1',
49     branchaddress2 => 'sample adr2',
50     branchaddress3 => 'sample adr3',
51     branchzip      => 'sample zip',
52     branchcity     => 'sample city',
53     branchstate    => 'sample state',
54     branchcountry  => 'sample country',
55     branchphone    => 'sample phone',
56     branchfax      => 'sample fax',
57     branchemail    => 'sample email',
58     branchurl      => 'sample url',
59     branchip       => 'sample ip',
60     branchprinter  => undef,
61     opac_info      => 'sample opac',
62 };
63 my $samplebranch2 = {
64     branchcode     => 'SAB2',
65     branchname     => 'Sample Branch2',
66     branchaddress1 => 'sample adr1_2',
67     branchaddress2 => 'sample adr2_2',
68     branchaddress3 => 'sample adr3_2',
69     branchzip      => 'sample zip2',
70     branchcity     => 'sample city2',
71     branchstate    => 'sample state2',
72     branchcountry  => 'sample country2',
73     branchphone    => 'sample phone2',
74     branchfax      => 'sample fax2',
75     branchemail    => 'sample email2',
76     branchurl      => 'sample url2',
77     branchip       => 'sample ip2',
78     branchprinter  => undef,
79     opac_info      => 'sample opac2',
80 };
81 Koha::Library->new($samplebranch1)->store;
82 Koha::Library->new($samplebranch2)->store;
83
84 my $samplecat = {
85     categorycode          => 'CAT1',
86     description           => 'Description1',
87     enrolmentperiod       => 'Null',
88     enrolmentperioddate   => 'Null',
89     dateofbirthrequired   => 'Null',
90     finetype              => 'Null',
91     bulk                  => 'Null',
92     enrolmentfee          => 'Null',
93     overduenoticerequired => 'Null',
94     issuelimit            => 'Null',
95     reservefee            => 'Null',
96     hidelostitems         => 0,
97     category_type         => 'Null'
98 };
99 my $query =
100 "INSERT INTO categories (categorycode,
101                         description,
102                         enrolmentperiod,
103                         enrolmentperioddate,
104                         dateofbirthrequired ,
105                         finetype,
106                         bulk,
107                         enrolmentfee,
108                         overduenoticerequired,
109                         issuelimit,
110                         reservefee,
111                         hidelostitems,
112                         category_type
113                         )
114 VALUES( ?,?,?,?,?,?,?,?,?,?,?,?,?)";
115 $dbh->do(
116     $query, {},
117     $samplecat->{categorycode},          $samplecat->{description},
118     $samplecat->{enrolmentperiod},       $samplecat->{enrolmentperioddate},
119     $samplecat->{dateofbirthrequired},   $samplecat->{finetype},
120     $samplecat->{bulk},                  $samplecat->{enrolmentfee},
121     $samplecat->{overduenoticerequired}, $samplecat->{issuelimit},
122     $samplecat->{reservefee},            $samplecat->{hidelostitems},
123     $samplecat->{category_type}
124 );
125
126 #Add itemtypes
127 my $sampleitemtype1 = {
128     itemtype     => 'BOOK',
129     description  => 'BookDescription',
130     rentalcharge => '10.0',
131     notforloan   => 1,
132     imageurl     => 'Null',
133     summary      => 'BookSummary'
134 };
135 my $sampleitemtype2 = {
136     itemtype     => 'DVD',
137     description  => 'DvdDescription',
138     rentalcharge => '5.0',
139     notforloan   => 0,
140     imageurl     => 'Null',
141     summary      => 'DvdSummary'
142 };
143 $query =
144 "INSERT INTO itemtypes (itemtype,
145                     description,
146                     rentalcharge,
147                     notforloan,
148                     imageurl,
149                     summary
150                     )
151  VALUES( ?,?,?,?,?,?)";
152 my $sth = $dbh->prepare($query);
153 $sth->execute(
154     $sampleitemtype1->{itemtype},     $sampleitemtype1->{description},
155     $sampleitemtype1->{rentalcharge}, $sampleitemtype1->{notforloan},
156     $sampleitemtype1->{imageurl},     $sampleitemtype1->{summary}
157 );
158 $sth->execute(
159     $sampleitemtype2->{itemtype},     $sampleitemtype2->{description},
160     $sampleitemtype2->{rentalcharge}, $sampleitemtype2->{notforloan},
161     $sampleitemtype2->{imageurl},     $sampleitemtype2->{summary}
162 );
163
164 #Add biblio and item
165 my $record = MARC::Record->new();
166 $record->append_fields(
167     MARC::Field->new( '952', '0', '0', a => $samplebranch1->{branchcode} ) );
168 my ( $biblionumber, $biblioitemnumber ) = C4::Biblio::AddBiblio( $record, '' );
169
170 # item 2 has home branch and holding branch samplebranch1
171 my @sampleitem1 = C4::Items::AddItem(
172     {
173         barcode        => 'barcode_1',
174         itemcallnumber => 'callnumber1',
175         homebranch     => $samplebranch1->{branchcode},
176         holdingbranch  => $samplebranch1->{branchcode}
177     },
178     $biblionumber
179 );
180 my $item_id1    = $sampleitem1[2];
181
182 # item 2 has holding branch samplebranch2
183 my @sampleitem2 = C4::Items::AddItem(
184     {
185         barcode        => 'barcode_2',
186         itemcallnumber => 'callnumber2',
187         homebranch     => $samplebranch2->{branchcode},
188         holdingbranch  => $samplebranch1->{branchcode}
189     },
190     $biblionumber
191 );
192 my $item_id2 = $sampleitem2[2];
193
194 # item 3 has item type sampleitemtype2 with noreturn policy
195 my @sampleitem3 = C4::Items::AddItem(
196     {
197         barcode        => 'barcode_3',
198         itemcallnumber => 'callnumber3',
199         homebranch     => $samplebranch2->{branchcode},
200         holdingbranch  => $samplebranch2->{branchcode},
201         itype          => $sampleitemtype2->{itemtype}
202     },
203     $biblionumber
204 );
205 my $item_id3 = $sampleitem3[2];
206
207 #Add borrower
208 my $borrower_id1 = C4::Members::AddMember(
209     firstname    => 'firstname1',
210     surname      => 'surname1 ',
211     categorycode => $samplecat->{categorycode},
212     branchcode   => $samplebranch1->{branchcode},
213 );
214 my $borrower_1 = C4::Members::GetMember(borrowernumber => $borrower_id1);
215
216 is_deeply(
217     GetBranchBorrowerCircRule(),
218     { maxissueqty => undef, maxonsiteissueqty => undef },
219 "Without parameter, GetBranchBorrower returns undef (unilimited) for maxissueqty and maxonsiteissueqty if no rules defined"
220 );
221
222 $query = q|
223     INSERT INTO branch_borrower_circ_rules
224     (branchcode, categorycode, maxissueqty, maxonsiteissueqty)
225     VALUES( ?, ?, ?, ? )
226 |;
227
228 $dbh->do(
229     $query, {},
230     $samplebranch1->{branchcode},
231     $samplecat->{categorycode}, 5, 6
232 );
233
234 $query = q|
235     INSERT INTO default_branch_circ_rules
236     (branchcode, maxissueqty, maxonsiteissueqty, holdallowed, returnbranch)
237     VALUES( ?, ?, ?, ?, ? )
238 |;
239 $dbh->do( $query, {}, $samplebranch2->{branchcode},
240     3, 2, 1, 'holdingbranch' );
241 $query = q|
242     INSERT INTO default_circ_rules
243     (singleton, maxissueqty, maxonsiteissueqty, holdallowed, returnbranch)
244     VALUES( ?, ?, ?, ?, ? )
245 |;
246 $dbh->do( $query, {}, 'singleton', 4, 5, 3, 'homebranch' );
247
248 $query =
249 "INSERT INTO branch_item_rules (branchcode,itemtype,holdallowed,returnbranch) VALUES( ?,?,?,?)";
250 $sth = $dbh->prepare($query);
251 $sth->execute(
252     $samplebranch1->{branchcode},
253     $sampleitemtype1->{itemtype},
254     5, 'homebranch'
255 );
256 $sth->execute(
257     $samplebranch2->{branchcode},
258     $sampleitemtype1->{itemtype},
259     5, 'holdingbranch'
260 );
261 $sth->execute(
262     $samplebranch2->{branchcode},
263     $sampleitemtype2->{itemtype},
264     5, 'noreturn'
265 );
266
267 #Test GetBranchBorrowerCircRule
268 is_deeply(
269     GetBranchBorrowerCircRule(),
270     { maxissueqty => 4, maxonsiteissueqty => 5 },
271 "Without parameter, GetBranchBorrower returns the maxissueqty and maxonsiteissueqty of default_circ_rules"
272 );
273 is_deeply(
274     GetBranchBorrowerCircRule( $samplebranch2->{branchcode} ),
275     { maxissueqty => 3, maxonsiteissueqty => 2 },
276 "Without only the branchcode specified, GetBranchBorrower returns the maxissueqty and maxonsiteissueqty corresponding"
277 );
278 is_deeply(
279     GetBranchBorrowerCircRule(
280         $samplebranch1->{branchcode},
281         $samplecat->{categorycode}
282     ),
283     { maxissueqty => 5, maxonsiteissueqty => 6 },
284     "GetBranchBorrower returns the maxissueqty and maxonsiteissueqty of the branch1 and the category1"
285 );
286 is_deeply(
287     GetBranchBorrowerCircRule( -1, -1 ),
288     { maxissueqty => 4, maxonsiteissueqty => 5 },
289 "GetBranchBorrower with wrong parameters returns the maxissueqty and maxonsiteissueqty of default_circ_rules"
290 );
291
292 #Test GetBranchItemRule
293 is_deeply(
294     GetBranchItemRule(
295         $samplebranch1->{branchcode},
296         $sampleitemtype1->{itemtype}
297     ),
298     { returnbranch => 'homebranch', holdallowed => 5 },
299     "GetBranchitem returns holdallowed and return branch"
300 );
301 is_deeply(
302     GetBranchItemRule(),
303     { returnbranch => 'homebranch', holdallowed => 3 },
304 "Without parameters GetBranchItemRule returns the values in default_circ_rules"
305 );
306 is_deeply(
307     GetBranchItemRule( $samplebranch2->{branchcode} ),
308     { returnbranch => 'holdingbranch', holdallowed => 1 },
309 "With only a branchcode GetBranchItemRule returns values in default_branch_circ_rules"
310 );
311 is_deeply(
312     GetBranchItemRule( -1, -1 ),
313     { returnbranch => 'homebranch', holdallowed => 3 },
314     "With only one parametern GetBranchItemRule returns default values"
315 );
316
317 # Test return policies
318 C4::Context->set_preference('AutomaticItemReturn','0');
319
320 # item1 returned at branch2 should trigger transfer to homebranch
321 $query =
322 "INSERT INTO issues (borrowernumber,itemnumber,branchcode) VALUES( ?,?,? )";
323 $dbh->do( $query, {}, $borrower_id1, $item_id1, $samplebranch1->{branchcode} );
324
325 my ($doreturn, $messages, $iteminformation, $borrower) = AddReturn('barcode_1',
326     $samplebranch2->{branchcode});
327 is( $messages->{NeedsTransfer}, $samplebranch1->{branchcode}, "AddReturn respects default return policy - return to homebranch" );
328
329 # item2 returned at branch2 should trigger transfer to holding branch
330 $query =
331 "INSERT INTO issues (borrowernumber,itemnumber,branchcode) VALUES( ?,?,? )";
332 $dbh->do( $query, {}, $borrower_id1, $item_id2, $samplebranch2->{branchcode} );
333 ($doreturn, $messages, $iteminformation, $borrower) = AddReturn('barcode_2',
334     $samplebranch2->{branchcode});
335 is( $messages->{NeedsTransfer}, $samplebranch1->{branchcode}, "AddReturn respects branch return policy - item2->homebranch policy = 'holdingbranch'" );
336
337 # item3 should not trigger transfer - floating collection
338 $query =
339 "INSERT INTO issues (borrowernumber,itemnumber,branchcode) VALUES( ?,?,? )";
340 $dbh->do( $query, {}, $borrower_id1, $item_id3, $samplebranch1->{branchcode} );
341 ($doreturn, $messages, $iteminformation, $borrower) = AddReturn('barcode_3',
342     $samplebranch1->{branchcode});
343 is($messages->{NeedsTransfer},undef,"AddReturn respects branch item return policy - noreturn");
344
345
346 $dbh->rollback;