Bug 17646: Remove itemtype-related IssueSlip.t warnings
[koha.git] / t / db_dependent / Members / IssueSlip.t
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
19 use Modern::Perl;
20
21 use Test::More tests => 3;
22 use Test::MockModule;
23 use t::lib::TestBuilder;
24
25 use C4::Biblio;
26 use C4::Items;
27 use C4::Members;
28 use C4::Circulation;
29
30 use Koha::DateUtils qw( dt_from_string output_pref );
31 use Koha::Library;
32 use DateTime::Duration;
33
34 use MARC::Record;
35
36 my $schema = Koha::Database->schema;
37 $schema->storage->txn_begin;
38 my $dbh = C4::Context->dbh;
39
40 $dbh->do(q|DELETE FROM issues|);
41 $dbh->do(q|DELETE FROM borrowers|);
42 $dbh->do(q|DELETE FROM items|);
43 $dbh->do(q|DELETE FROM branches|);
44 $dbh->do(q|DELETE FROM biblio|);
45 $dbh->do(q|DELETE FROM categories|);
46 $dbh->do(q|DELETE FROM letter|);
47
48 my $builder = t::lib::TestBuilder->new;
49
50 my $branchcode   = $builder->build({ source => 'Branch' })->{ branchcode };
51 my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
52 my $itemtype     = $builder->build({ source => 'Itemtype' })->{ itemtype };
53
54 my %item_infos = (
55     homebranch    => $branchcode,
56     holdingbranch => $branchcode,
57     itype         => $itemtype
58 );
59
60
61 my $slip_content = <<EOS;
62 Checked out:
63 <checkedout>
64 Title: <<biblio.title>>
65 Barcode: <<items.barcode>>
66 Date due: <<issues.date_due>>
67 </checkedout>
68
69 Overdues:
70 <overdue>
71 Title: <<biblio.title>>
72 Barcode: <<items.barcode>>
73 Date due: <<issues.date_due>>
74 </overdue>
75 EOS
76
77 $dbh->do(q|
78     INSERT INTO letter( module, code, branchcode, name, is_html, title, content, message_transport_type) VALUES ('circulation', 'ISSUESLIP', '', 'Issue Slip', 0, 'Issue Slip', ?, 'email')
79 |, {}, $slip_content);
80
81 my $quick_slip_content = <<EOS;
82 Checked out today:
83 <checkedout>
84 Title: <<biblio.title>>
85 Barcode: <<items.barcode>>
86 Date due: <<issues.date_due>>
87 </checkedout>
88 EOS
89
90 $dbh->do(q|
91     INSERT INTO letter( module, code, branchcode, name, is_html, title, content, message_transport_type) VALUES ('circulation', 'ISSUEQSLIP', '', 'Issue Quick Slip', 0, 'Issue Quick Slip', ?, 'email')
92 |, {}, $quick_slip_content);
93
94 my ( $title1, $title2 ) = ( 'My title 1', 'My title 2' );
95 my ( $barcode1, $barcode2 ) = ('BC0101', 'BC0202' );
96 my $record = MARC::Record->new;
97 $record->append_fields(
98     MARC::Field->new(
99         245, '1', '4',
100             a => $title1,
101     ),
102 );
103 my ($biblionumber1) = AddBiblio( $record, '' );
104 my $itemnumber1 =
105   AddItem( { barcode => $barcode1, %item_infos }, $biblionumber1 );
106
107 $record = MARC::Record->new;
108 $record->append_fields(
109     MARC::Field->new(
110         245, '1', '4',
111             a => $title2,
112     ),
113 );
114 my ($biblionumber2) = AddBiblio( $record, '' );
115 my $itemnumber2 =
116   AddItem( { barcode => $barcode2, %item_infos }, $biblionumber2 );
117
118 my $borrowernumber =
119   AddMember( categorycode => $categorycode, branchcode => $branchcode );
120 my $borrower = GetMember( borrowernumber => $borrowernumber );
121
122 my $module = new Test::MockModule('C4::Context');
123 $module->mock( 'userenv', sub { { branch => $branchcode } } );
124
125 my $today = dt_from_string;
126 my $yesterday = dt_from_string->subtract_duration( DateTime::Duration->new( days => 1 ) );
127
128 subtest 'Issue slip' => sub {
129     plan tests => 3;
130
131     subtest 'Empty slip' => sub {
132         plan tests => 1;
133         my $slip = IssueSlip( $branchcode, $borrowernumber );
134         my $empty_slip = <<EOS;
135 Checked out:
136
137
138 Overdues:
139
140 EOS
141         is( $slip->{content}, $empty_slip, 'No checked out or overdues return an empty slip, it should return undef (FIXME)' );
142     };
143
144     subtest 'Daily loans' => sub {
145         plan tests => 2;
146         skip "It's 23:59!", 2 if $today->hour == 23 and $today->minute == 59;
147         # Test 1: No overdue
148         my $today_daily = $today->clone->set( hour => 23, minute => 59 );
149         my $today_daily_as_formatted = output_pref( $today_daily );
150         my $yesterday_daily = $yesterday->clone->set( hour => 23, minute => 59 );
151         my $yesterday_daily_as_formatted = output_pref( $yesterday_daily );
152
153         my ( $date_due, $issue_date, $slip, $expected_slip );
154         $date_due = $today_daily;
155         $issue_date = $today_daily->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
156         AddIssue( $borrower, $barcode1, $date_due, undef, $issue_date );
157         $date_due = $today_daily;
158         $issue_date = $yesterday_daily;
159         AddIssue( $borrower, $barcode2, $date_due, undef, $issue_date );
160
161         $expected_slip = <<EOS;
162 Checked out:
163
164 Title: $title1
165 Barcode: $barcode1
166 Date due: $today_daily_as_formatted
167
168
169 Title: $title2
170 Barcode: $barcode2
171 Date due: $today_daily_as_formatted
172
173
174 Overdues:
175
176 EOS
177         $slip = IssueSlip( $branchcode, $borrowernumber );
178         is( $slip->{content}, $expected_slip , 'IssueSlip should return a slip with 2 checkouts');
179
180         AddReturn( $barcode1, $branchcode );
181         AddReturn( $barcode2, $branchcode );
182
183         # Test 2: 1 Overdue
184         $date_due = $today_daily;
185         $issue_date = $today_daily->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
186         AddIssue( $borrower, $barcode1, $date_due, undef, $issue_date );
187         $date_due = $yesterday_daily;
188         $issue_date = $yesterday_daily;
189         AddIssue( $borrower, $barcode2, $date_due, undef, $issue_date );
190
191         $expected_slip = <<EOS;
192 Checked out:
193
194 Title: $title1
195 Barcode: $barcode1
196 Date due: $today_daily_as_formatted
197
198
199 Overdues:
200
201 Title: $title2
202 Barcode: $barcode2
203 Date due: $yesterday_daily_as_formatted
204
205 EOS
206         $slip = IssueSlip( $branchcode, $borrowernumber );
207         is( $slip->{content}, $expected_slip, 'IssueSlip should return a slip with 1 checkout and 1 overdue');
208
209         AddReturn( $barcode1, $branchcode );
210         AddReturn( $barcode2, $branchcode );
211     };
212
213     subtest 'Hourly loans' => sub {
214         plan tests => 2;
215         skip "It's 23:59!", 2 if $today->hour == 23 and $today->minute == 59;
216         # Test 1: No overdue
217         my ( $date_due_in_time, $date_due_in_time_as_formatted, $date_due_in_late, $date_due_in_late_as_formatted, $issue_date, $slip, $expected_slip );
218         # Assuming today is not hour = 23 and minute = 59
219         $date_due_in_time = $today->clone->set(hour => ($today->hour < 23 ? $today->hour + 1 : 23), minute => 59);
220         $date_due_in_time_as_formatted = output_pref( $date_due_in_time );
221         $issue_date = $date_due_in_time->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
222         AddIssue( $borrower, $barcode1, $date_due_in_time, undef, $issue_date );
223         $issue_date = $yesterday->clone;
224         AddIssue( $borrower, $barcode2, $date_due_in_time, undef, $issue_date );
225
226         $expected_slip = <<EOS;
227 Checked out:
228
229 Title: $title1
230 Barcode: $barcode1
231 Date due: $date_due_in_time_as_formatted
232
233
234 Title: $title2
235 Barcode: $barcode2
236 Date due: $date_due_in_time_as_formatted
237
238
239 Overdues:
240
241 EOS
242         $slip = IssueSlip( $branchcode, $borrowernumber );
243         is( $slip->{content}, $expected_slip, 'IssueSlip should return a slip with 2 checkouts' );
244
245         AddReturn( $barcode1, $branchcode );
246         AddReturn( $barcode2, $branchcode );
247
248         # Test 2: 1 Overdue
249         $date_due_in_time = $today->clone->set(hour => ($today->hour < 23 ? $today->hour + 1 : 23), minute => 59);
250         $date_due_in_time_as_formatted = output_pref( $date_due_in_time );
251         $issue_date = $date_due_in_time->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
252         AddIssue( $borrower, $barcode1, $date_due_in_time, undef, $issue_date );
253         $date_due_in_late = $today->clone->set(hour => $today->hour - 1);
254         $date_due_in_late_as_formatted = output_pref( $date_due_in_late );
255         $issue_date = $yesterday->clone;
256         AddIssue( $borrower, $barcode2, $date_due_in_late, undef, $issue_date );
257
258         $expected_slip = <<EOS;
259 Checked out:
260
261 Title: $title1
262 Barcode: $barcode1
263 Date due: $date_due_in_time_as_formatted
264
265
266 Overdues:
267
268 Title: $title2
269 Barcode: $barcode2
270 Date due: $date_due_in_late_as_formatted
271
272 EOS
273         $slip = IssueSlip( $branchcode, $borrowernumber );
274         is( $slip->{content}, $expected_slip, 'IssueSlip should return a slip with 1 checkout and 1 overdue' );
275
276         AddReturn( $barcode1, $branchcode );
277         AddReturn( $barcode2, $branchcode );
278     };
279
280 };
281
282 subtest 'Quick slip' => sub {
283     plan tests => 3;
284
285     subtest 'Empty slip' => sub {
286         plan tests => 1;
287         my $slip = IssueSlip( $branchcode, $borrowernumber, 'quick slip' );
288         my $empty_slip = <<EOS;
289 Checked out today:
290
291 EOS
292         is( $slip->{content}, $empty_slip, 'No checked out or overdues return an empty slip, it should return undef (FIXME)' );
293     };
294
295     subtest 'Daily loans' => sub {
296         plan tests => 2;
297         skip "It's 23:59!", 2 if $today->hour == 23 and $today->minute == 59;
298         # Test 1: No overdue
299         my $today_daily = $today->clone->set( hour => 23, minute => 59 );
300         my $today_daily_as_formatted = output_pref( $today_daily );
301         my $yesterday_daily = $yesterday->clone->set( hour => 23, minute => 59 );
302         my $yesterday_daily_as_formatted = output_pref( $yesterday_daily );
303
304         my ( $date_due, $issue_date, $slip, $expected_slip );
305         $date_due = $today_daily;
306         $issue_date = $today_daily->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
307         AddIssue( $borrower, $barcode1, $date_due, undef, $issue_date );
308         $date_due = $today_daily;
309         $issue_date = $yesterday_daily;
310         AddIssue( $borrower, $barcode2, $date_due, undef, $issue_date );
311
312         $expected_slip = <<EOS;
313 Checked out today:
314
315 Title: $title1
316 Barcode: $barcode1
317 Date due: $today_daily_as_formatted
318
319 EOS
320         $slip = IssueSlip( $branchcode, $borrowernumber, 'quick slip' );
321         is( $slip->{content}, $expected_slip, 'IssueSlip should return 2 checkouts for today');
322
323         AddReturn( $barcode1, $branchcode );
324         AddReturn( $barcode2, $branchcode );
325
326         # Test 2: 1 Overdue
327         $date_due = $today_daily;
328         $issue_date = $today_daily->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
329         AddIssue( $borrower, $barcode1, $date_due, undef, $issue_date );
330         $date_due = $yesterday_daily;
331         $issue_date = $yesterday_daily;
332         AddIssue( $borrower, $barcode2, $date_due, undef, $issue_date );
333
334         $expected_slip = <<EOS;
335 Checked out today:
336
337 Title: $title1
338 Barcode: $barcode1
339 Date due: $today_daily_as_formatted
340
341 EOS
342         $slip = IssueSlip( $branchcode, $borrowernumber, 'quickslip' );
343         is( $slip->{content}, $expected_slip );
344     };
345
346     subtest 'Hourly loans' => sub {
347         plan tests => 2;
348         # Test 1: No overdue
349         my ( $date_due_in_time, $date_due_in_time_as_formatted, $date_due_in_late, $date_due_in_late_as_formatted, $issue_date, $slip, $expected_slip );
350         # Assuming today is not hour = 23 and minute = 59
351         $date_due_in_time = $today->clone->set(hour => ($today->hour < 23 ? $today->hour + 1 : 23), minute => 59);
352         $date_due_in_time_as_formatted = output_pref( $date_due_in_time );
353         $issue_date = $date_due_in_time->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
354         AddIssue( $borrower, $barcode1, $date_due_in_time, undef, $issue_date );
355         $issue_date = $yesterday->clone;
356         AddIssue( $borrower, $barcode2, $date_due_in_time, undef, $issue_date );
357
358         $expected_slip = <<EOS;
359 Checked out today:
360
361 Title: $title1
362 Barcode: $barcode1
363 Date due: $date_due_in_time_as_formatted
364
365 EOS
366         $slip = IssueSlip( $branchcode, $borrowernumber, 'quickslip' );
367         is( $slip->{content}, $expected_slip );
368
369         AddReturn( $barcode1, $branchcode );
370         AddReturn( $barcode2, $branchcode );
371
372         # Test 2: 1 Overdue
373         $date_due_in_time = $today->clone->set(hour => ($today->hour < 23 ? $today->hour + 1 : 23), minute => 59);
374         $date_due_in_time_as_formatted = output_pref( $date_due_in_time );
375         $issue_date = $date_due_in_time->clone->subtract_duration( DateTime::Duration->new( minutes => 1 ) );
376         AddIssue( $borrower, $barcode1, $date_due_in_time, undef, $issue_date );
377         $date_due_in_late = $today->clone->set(hour => $today->hour - 1);
378         $date_due_in_late_as_formatted = output_pref( $date_due_in_late );
379         $issue_date = $yesterday->clone;
380         AddIssue( $borrower, $barcode2, $date_due_in_late, undef, $issue_date );
381
382         $expected_slip = <<EOS;
383 Checked out today:
384
385 Title: $title1
386 Barcode: $barcode1
387 Date due: $date_due_in_time_as_formatted
388
389 EOS
390         $slip = IssueSlip( $branchcode, $borrowernumber, 'quickslip' );
391         is( $slip->{content}, $expected_slip );
392
393         AddReturn( $barcode1, $branchcode );
394         AddReturn( $barcode2, $branchcode );
395     };
396
397 };
398
399 subtest 'bad calls' => sub {
400     plan tests => 2;
401     AddIssue( $borrower, $barcode1, $today, undef, $yesterday );
402     my $slip = IssueSlip();
403     isnt( $slip, undef, 'IssueSlip should return if no param passed FIXME, should return undef' );
404     my $empty_slip = <<EOS;
405 Checked out:
406
407
408 Overdues:
409
410 EOS
411
412     $slip = IssueSlip(undef, $borrowernumber+1);
413     is( $slip->{content}, $empty_slip, 'IssueSlip should not return an empty slip if the borrowernumber passed in param does not exist. But it is what it does for now (FIXME)' );
414 };
415
416 $schema->storage->txn_rollback;
417
418 1;