Bug 12178: Fix tests not to depend on dateformat syspref
[koha.git] / t / db_dependent / Serials.t
1 #!/usr/bin/perl
2 #
3 # This Koha test module is a stub!
4 # Add more tests here!!!
5
6 use Modern::Perl;
7 use YAML;
8
9 use CGI qw ( -utf8 );
10 use C4::Serials;
11 use C4::Serials::Frequency;
12 use C4::Serials::Numberpattern;
13 use C4::Debug;
14 use C4::Bookseller;
15 use C4::Biblio;
16 use C4::Budgets;
17 use Koha::DateUtils;
18 use t::lib::Mocks;
19 use Test::More tests => 48;
20
21 BEGIN {
22     use_ok('C4::Serials');
23 }
24
25 my $dbh = C4::Context->dbh;
26
27 # Start transaction
28 $dbh->{AutoCommit} = 0;
29 $dbh->{RaiseError} = 1;
30
31 # This could/should be used for all untested methods
32 my @methods = ('updateClaim');
33 can_ok('C4::Serials', @methods);
34
35 my $booksellerid = C4::Bookseller::AddBookseller(
36     {
37         name => "my vendor",
38         address1 => "bookseller's address",
39         phone => "0123456",
40         active => 1
41     }
42 );
43
44 my ($biblionumber, $biblioitemnumber) = AddBiblio(MARC::Record->new, '');
45
46 my $budgetid;
47 my $bpid = AddBudgetPeriod({
48     budget_period_startdate   => '01-01-2015',
49     budget_period_enddate     => '31-12-2015',
50     budget_period_description => "budget desc"
51 });
52
53 my $budget_id = AddBudget({
54     budget_code        => "ABCD",
55     budget_amount      => "123.132",
56     budget_name        => "Périodiques",
57     budget_notes       => "This is a note",
58     budget_period_id   => $bpid
59 });
60
61 my $frequency_id = AddSubscriptionFrequency({ description => "Test frequency 1" });
62 my $pattern_id = AddSubscriptionNumberpattern({
63     label => 'Test numberpattern 1',
64     numberingmethod => '{X}',
65     label1 => q{},
66     add1 => 1,
67     every1 => 1,
68     every1 => 1,
69     numbering1 => 1,
70     whenmorethan1 => 1,
71 });
72
73 my $notes = 'notes';
74 my $internalnotes = 'intnotes';
75 my $subscriptionid = NewSubscription(
76     undef,      "",     undef, undef, $budget_id, $biblionumber,
77     '2013-01-01', $frequency_id, undef, undef,  undef,
78     undef,      undef,  undef, undef, undef, undef,
79     1,          $notes,undef, '2013-01-01', undef, $pattern_id,
80     undef,       undef,  0,    $internalnotes,  0,
81     undef, undef, 0,          undef,         '2013-12-31', 0
82 );
83
84 my $subscriptioninformation = GetSubscription( $subscriptionid );
85
86 is( $subscriptioninformation->{notes}, $notes, 'NewSubscription should set notes' );
87 is( $subscriptioninformation->{internalnotes}, $internalnotes, 'NewSubscription should set internalnotes' );
88
89 my $subscription_history = C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid);
90 is( $subscription_history->{opacnote}, '', 'NewSubscription should not set subscriptionhistory opacnotes' );
91 is( $subscription_history->{librariannote}, '', 'NewSubscription should not set subscriptionhistory librariannotes' );
92
93 my @subscriptions = SearchSubscriptions({string => $subscriptioninformation->{bibliotitle}, orderby => 'title' });
94 isa_ok( \@subscriptions, 'ARRAY' );
95
96 @subscriptions = SearchSubscriptions({ issn => $subscriptioninformation->{issn}, orderby => 'title' });
97 isa_ok( \@subscriptions, 'ARRAY' );
98
99 @subscriptions = SearchSubscriptions({ ean => $subscriptioninformation->{ean}, orderby => 'title' });
100 isa_ok( \@subscriptions, 'ARRAY' );
101
102 @subscriptions = SearchSubscriptions({ biblionumber => $subscriptioninformation->{bibnum}, orderby => 'title' });
103 isa_ok( \@subscriptions, 'ARRAY' );
104
105 my $frequency = GetSubscriptionFrequency($subscriptioninformation->{periodicity});
106 my $old_frequency;
107 if (not $frequency->{unit}) {
108     $old_frequency = $frequency->{id};
109     $frequency->{unit} = "month";
110     $frequency->{unitsperissue} = 1;
111     $frequency->{issuesperunit} = 1;
112     $frequency->{description} = "Frequency created by t/db_dependant/Serials.t";
113     $subscriptioninformation->{periodicity} = AddSubscriptionFrequency($frequency);
114
115     ModSubscription( @$subscriptioninformation{qw(
116         librarian branchcode aqbooksellerid cost aqbudgetid startdate
117         periodicity firstacquidate irregularity numberpattern locale
118         numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
119         innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
120         letter manualhistory internalnotes serialsadditems staffdisplaycount
121         opacdisplaycount graceperiod location enddate subscriptionid
122         skip_serialseq
123     )} );
124 }
125 my $expirationdate = GetExpirationDate($subscriptionid) ;
126 ok( $expirationdate, "expiration date is not NULL" );
127
128 ok(C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid), 'test getting history from sub-scription');
129
130 my ($serials_count, @serials) = GetSerials($subscriptionid);
131 ok($serials_count > 0, 'Subscription has at least one serial');
132 my $serial = $serials[0];
133
134 ok(C4::Serials::GetSerialStatusFromSerialId($serial->{serialid}), 'test getting Serial Status From Serial Id');
135
136 isa_ok(C4::Serials::GetSerialInformation($serial->{serialid}), 'HASH', 'test getting Serial Information');
137
138 # Delete created frequency
139 if ($old_frequency) {
140     my $freq_to_delete = $subscriptioninformation->{periodicity};
141     $subscriptioninformation->{periodicity} = $old_frequency;
142
143     ModSubscription( @$subscriptioninformation{qw(
144         librarian branchcode aqbooksellerid cost aqbudgetid startdate
145         periodicity firstacquidate irregularity numberpattern locale
146         numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
147         innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
148         letter manualhistory internalnotes serialsadditems staffdisplaycount
149         opacdisplaycount graceperiod location enddate subscriptionid
150         skip_serialseq
151     )} );
152
153     DelSubscriptionFrequency($freq_to_delete);
154 }
155
156
157 # Test calling subs without parameters
158 is(C4::Serials::AddItem2Serial(), undef, 'test adding item to serial');
159 is(C4::Serials::GetFullSubscription(), undef, 'test getting full subscription');
160 is(C4::Serials::PrepareSerialsData(), undef, 'test preparing serial data');
161 is(C4::Serials::GetSubscriptionsFromBiblionumber(), undef, 'test getting subscriptions form biblio number');
162
163 is(C4::Serials::GetSerials(), undef, 'test getting serials when you enter nothing');
164 is(C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing');
165
166 is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
167
168 is(C4::Serials::GetDistributedTo(), undef, 'test getting distributed when nothing is entered');
169
170 is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
171
172 is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
173
174 is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
175
176 is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
177
178 is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
179
180 is(C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters');
181
182 is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
183
184 is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
185 is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
186
187 is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
188
189 subtest 'test_updateClaim' => sub {
190     plan tests => 11;
191
192     my $today = output_pref({ dt => dt_from_string, dateonly => 1 });
193     # Given ... nothing much
194     # When ... Then ...
195     my $result_0 = C4::Serials::updateClaim(undef);
196     is($result_0, undef, 'Got the expected undef from update claim with nothin');
197
198     # Given ... 3 serial. 2 of them updated.
199     my $serialids_1   = [90980, 90981];
200     my $claimdate_1   = dt_from_string('2001-01-13'); # arbitrary date some time in the past.
201     my $claim_count_1 = 5;
202     Koha::Serial->new( { serialid => $serialids_1->[0], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
203                          biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
204     Koha::Serial->new( { serialid => $serialids_1->[1], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
205                          biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1,  } )->store();
206     Koha::Serial->new( { serialid => 90982, serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
207                          biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1,  } )->store();
208
209     # When ...
210     my $result_1 = C4::Serials::updateClaim($serialids_1);
211
212     # Then ...
213     is($result_1, 2, 'Got the expected 2 from update claim with 2 serial ids');
214
215     my @late_or_missing_issues_1_0 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[0]);
216     is($late_or_missing_issues_1_0[0]->{claimdate}, $today, 'Got the expected first different claim date from update claim');
217     is($late_or_missing_issues_1_0[0]->{claims_count}, $claim_count_1+1, 'Got the expected first claim count from update claim');
218     is($late_or_missing_issues_1_0[0]->{status}, 7, 'Got the expected first claim status from update claim');
219
220     my @late_or_missing_issues_1_1 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[1]);
221     is($late_or_missing_issues_1_1[0]->{claimdate}, $today, 'Got the expected second different claim date from update claim');
222     is($late_or_missing_issues_1_1[0]->{claims_count}, $claim_count_1+1, 'Got the expected second claim count from update claim');
223     is($late_or_missing_issues_1_1[0]->{status}, 7, 'Got the expected second claim status from update claim');
224
225     my @late_or_missing_issues_1_2 = C4::Serials::GetLateOrMissingIssues(undef, 90982);
226     is($late_or_missing_issues_1_2[0]->{claimdate}, output_pref({ dt => $claimdate_1, dateonly => 1}), 'Got the expected unchanged claim date from update claim');
227     is($late_or_missing_issues_1_2[0]->{claims_count}, $claim_count_1, 'Got the expected unchanged claim count from update claim');
228     is($late_or_missing_issues_1_2[0]->{status}, 3, 'Got the expected unchanged claim status from update claim');
229 };
230
231 is(C4::Serials::getsupplierbyserialid(),undef, 'test getting supplier idea');
232
233 is(C4::Serials::check_routing(), undef, 'test checking route');
234
235 is(C4::Serials::addroutingmember(),undef, 'test adding route member');
236
237
238 # Unit tests for statuses management (Bug 11689)
239 $subscriptionid = NewSubscription(
240     undef,      "",     undef, undef, $budget_id, $biblionumber,
241     '2013-01-01', $frequency_id, undef, undef,  undef,
242     undef,      undef,  undef, undef, undef, undef,
243     1,          $notes,undef, '2013-01-01', undef, $pattern_id,
244     undef,       undef,  0,    $internalnotes,  0,
245     undef, undef, 0,          undef,         '2013-12-31', 0
246 );
247 my $total_issues;
248 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
249 is( $total_issues, 1, "NewSubscription created a first serial" );
250 is( @serials, 1, "GetSerials returns the serial" );
251 my $subscription = C4::Serials::GetSubscription($subscriptionid);
252 my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
253 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
254 my $publisheddate = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 });
255 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
256 my $nextpublisheddate = C4::Serials::GetNextDate($subscription, $publisheddate, 1);
257 my @statuses = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
258 # Add 14 serials
259 my $counter = 0;
260 for my $status ( @statuses ) {
261     my $serialseq = "No.".$counter;
262     my ( $expected_serial ) = GetSerials2( $subscriptionid, [1] );
263     C4::Serials::ModSerialStatus( $expected_serial->{serialid}, $serialseq, $publisheddate, $publisheddate, $publisheddate, $statuses[$counter], 'an useless note' );
264     $counter++;
265 }
266 # Here we have 15 serials with statuses : 2*2 + 5*3 + 2*4 + 1*41 + 1*42 + 1*43 + 1*44 + 1*5 + 1*1
267 my @serialsByStatus = C4::Serials::findSerialsByStatus(2,$subscriptionid);
268 is(@serialsByStatus,2,"findSerialsByStatus returns all serials with chosen status");
269 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
270 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
271 my @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
272 my @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
273 is( @arrived_missing, 5, "GetSerials returns 5 arrived/missing by default" );
274 is( @others, 6, "GetSerials returns all serials not arrived and not missing" );
275
276 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid, 10 );
277 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
278 @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
279 @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
280 is( @arrived_missing, 9, "GetSerials returns all arrived/missing if count given" );
281 is( @others, 6, "GetSerials returns all serials not arrived and not missing if count given" );
282
283 $subscription = C4::Serials::GetSubscription($subscriptionid); # Retrieve the updated subscription
284
285 my @serialseqs;
286 for my $am ( @arrived_missing ) {
287     if ( grep {/^$am->{status}$/} qw( 4 41 42 43 44 ) ) {
288         push @serialseqs, $am->{serialseq}
289     } elsif ( grep {/^$am->{status}$/} qw( 5 ) ) {
290         push @serialseqs, 'not issued ' . $am->{serialseq};
291     }
292 }
293 is( $subscription->{missinglist}, join('; ', @serialseqs), "subscription missinglist is updated after ModSerialStatus" );
294
295 subtest "Do not generate an expected if one already exists" => sub {
296     plan tests => 2;
297     my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
298
299     #Find serialid for serial with status Expected
300     my $serialexpected = ( C4::Serials::findSerialsByStatus( 1, $subscriptionid ) )[0];
301
302     #delete serial with status Expected
303     C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
304     @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
305     is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and create another if not exist" );
306
307     # add 1 serial with status=Expected 1
308     C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
309
310     #Now we have two serials it have status expected
311     #put status delete for last serial
312     C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
313
314     #try if create or not another serial with status is expected
315     @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
316     is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and not create another if exists" );
317 };
318
319 $dbh->rollback;