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