Bug 21395: Make perlcritic happy
[koha.git] / t / db_dependent / Serials.t
blob53c697e2d0b9fd25a8fefb3e215c2a1fce103adc
1 #!/usr/bin/perl
3 # This Koha test module is a stub!
4 # Add more tests here!!!
6 use Modern::Perl;
7 use YAML;
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 => 49;
23 BEGIN {
24 use_ok('C4::Serials');
27 my $schema = Koha::Database->new->schema;
28 $schema->storage->txn_begin;
29 my $dbh = C4::Context->dbh;
31 my $builder = t::lib::TestBuilder->new();
33 # This could/should be used for all untested methods
34 my @methods = ('updateClaim');
35 can_ok('C4::Serials', @methods);
37 $dbh->do(q|UPDATE marc_subfield_structure SET value_builder="callnumber.pl" where kohafield="items.itemcallnumber" and frameworkcode=''|);
39 my $bookseller = Koha::Acquisition::Bookseller->new(
41 name => "my vendor",
42 address1 => "bookseller's address",
43 phone => "0123456",
44 active => 1
48 my ($biblionumber, $biblioitemnumber) = AddBiblio(MARC::Record->new, '');
50 my $bpid = AddBudgetPeriod({
51 budget_period_startdate => '2015-01-01',
52 budget_period_enddate => '2015-12-31',
53 budget_period_description => "budget desc"
54 });
56 my $budget_id = AddBudget({
57 budget_code => "ABCD",
58 budget_amount => "123.132",
59 budget_name => "Périodiques",
60 budget_notes => "This is a note",
61 budget_period_id => $bpid
62 });
64 my $frequency_id = AddSubscriptionFrequency({ description => "Test frequency 1" });
65 my $pattern_id = AddSubscriptionNumberpattern({
66 label => 'Test numberpattern 1',
67 description => 'Description for numberpattern 1',
68 numberingmethod => '{X}',
69 label1 => q{},
70 add1 => 1,
71 every1 => 1,
72 every1 => 1,
73 numbering1 => 1,
74 whenmorethan1 => 1,
75 });
77 my $notes = "a\nnote\non\nseveral\nlines";
78 my $internalnotes = 'intnotes';
79 my $subscriptionid = NewSubscription(
80 undef, "", undef, undef, $budget_id, $biblionumber,
81 '2013-01-01', $frequency_id, undef, undef, undef,
82 undef, undef, undef, undef, undef, undef,
83 1, $notes, ,undef, '2013-01-01', undef, $pattern_id,
84 undef, undef, 0, $internalnotes, 0,
85 undef, undef, 0, undef, '2013-12-31', 0
88 my $subscriptioninformation = GetSubscription( $subscriptionid );
90 is( $subscriptioninformation->{notes}, $notes, 'NewSubscription should set notes' );
91 is( $subscriptioninformation->{internalnotes}, $internalnotes, 'NewSubscription should set internalnotes' );
93 my $subscription_history = C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid);
94 is( $subscription_history->{opacnote}, undef, 'NewSubscription should not set subscriptionhistory opacnotes' );
95 is( $subscription_history->{librariannote}, undef, 'NewSubscription should not set subscriptionhistory librariannotes' );
97 my @subscriptions = SearchSubscriptions({string => $subscriptioninformation->{bibliotitle}, orderby => 'title' });
98 isa_ok( \@subscriptions, 'ARRAY' );
100 @subscriptions = SearchSubscriptions({ issn => $subscriptioninformation->{issn}, orderby => 'title' });
101 isa_ok( \@subscriptions, 'ARRAY' );
103 @subscriptions = SearchSubscriptions({ ean => $subscriptioninformation->{ean}, orderby => 'title' });
104 isa_ok( \@subscriptions, 'ARRAY' );
106 @subscriptions = SearchSubscriptions({ biblionumber => $subscriptioninformation->{bibnum}, orderby => 'title' });
107 isa_ok( \@subscriptions, 'ARRAY' );
109 my $frequency = GetSubscriptionFrequency($subscriptioninformation->{periodicity});
110 my $old_frequency;
111 if (not $frequency->{unit}) {
112 $old_frequency = $frequency->{id};
113 $frequency->{unit} = "month";
114 $frequency->{unitsperissue} = 1;
115 $frequency->{issuesperunit} = 1;
116 $frequency->{description} = "Frequency created by t/db_dependant/Serials.t";
117 $subscriptioninformation->{periodicity} = AddSubscriptionFrequency($frequency);
118 $subscriptioninformation->{serialsadditems} = 1;
120 ModSubscription( @$subscriptioninformation{qw(
121 librarian branchcode aqbooksellerid cost aqbudgetid startdate
122 periodicity firstacquidate irregularity numberpattern locale
123 numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
124 innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
125 letter manualhistory internalnotes serialsadditems staffdisplaycount
126 opacdisplaycount graceperiod location enddate subscriptionid
127 skip_serialseq
128 )} );
130 my $expirationdate = GetExpirationDate($subscriptionid) ;
131 ok( $expirationdate, "expiration date is not NULL" );
133 ok(C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid), 'test getting history from sub-scription');
135 my ($serials_count, @serials) = GetSerials($subscriptionid);
136 ok($serials_count > 0, 'Subscription has at least one serial');
137 my $serial = $serials[0];
139 isa_ok(C4::Serials::GetSerialInformation($serial->{serialid}), 'HASH', 'test getting Serial Information');
141 subtest 'Values should not be erased on editing' => sub {
143 plan tests => 1;
145 my $biblio = $builder->build_sample_biblio();
146 my $biblionumber = $biblio->biblionumber;
147 my ( $icn_tag, $icn_sf ) = GetMarcFromKohaField( 'items.itemcallnumber' );
148 my ( $it_tag, $it_sf ) = GetMarcFromKohaField( 'items.itype' );
150 my $itemtype = $builder->build( { source => 'Itemtype' } )->{itemtype};
151 my $itemcallnumber = 'XXXmy itemcallnumberXXX';
153 my $item_record = new MARC::Record;
155 $item_record->append_fields(
156 MARC::Field->new( '080', '', '', "a" => "default" ),
157 MARC::Field->new(
158 $icn_tag, '', '',
159 $icn_sf => $itemcallnumber,
160 $it_sf => $itemtype
163 my ( undef, undef, $itemnumber ) = C4::Items::AddItemFromMarc( $item_record, $biblionumber );
164 my $serialid = C4::Serials::NewIssue( "serialseq", $subscriptionid, $biblionumber,
165 1, undef, undef, "publisheddatetext", "notes", "routingnotes" );
166 C4::Serials::AddItem2Serial( $serialid, $itemnumber );
167 my $serial_info = C4::Serials::GetSerialInformation($serialid);
168 my ($itemcallnumber_info) = grep { $_->{kohafield} eq 'items.itemcallnumber' }
169 @{ $serial_info->{items}[0]->{iteminformation} };
170 like( $itemcallnumber_info->{marc_value}, qr|value="$itemcallnumber"| );
173 # Delete created frequency
174 if ($old_frequency) {
175 my $freq_to_delete = $subscriptioninformation->{periodicity};
176 $subscriptioninformation->{periodicity} = $old_frequency;
178 ModSubscription( @$subscriptioninformation{qw(
179 librarian branchcode aqbooksellerid cost aqbudgetid startdate
180 periodicity firstacquidate irregularity numberpattern locale
181 numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
182 innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
183 letter manualhistory internalnotes serialsadditems staffdisplaycount
184 opacdisplaycount graceperiod location enddate subscriptionid
185 skip_serialseq
186 )} );
188 DelSubscriptionFrequency($freq_to_delete);
191 # Test calling subs without parameters
192 is(C4::Serials::AddItem2Serial(), undef, 'test adding item to serial');
193 is(C4::Serials::GetFullSubscription(), undef, 'test getting full subscription');
194 is(C4::Serials::PrepareSerialsData(), undef, 'test preparing serial data');
196 subtest 'GetSubscriptionsFromBiblionumber' => sub {
197 plan tests => 4;
199 is( C4::Serials::GetSubscriptionsFromBiblionumber(),
200 undef, 'test getting subscriptions form biblio number' );
202 my $subscriptions = C4::Serials::GetSubscriptionsFromBiblionumber($biblionumber);
203 ModSubscriptionHistory( $subscriptions->[0]->{subscriptionid},
204 undef, undef, $notes, $notes, $notes );
206 $subscriptions = C4::Serials::GetSubscriptionsFromBiblionumber($biblionumber);
207 is( $subscriptions->[0]->{opacnote}, $notes,
208 'GetSubscriptionsFromBiblionumber should have returned the opacnote as it is in DB, ie. without br tags'
210 is( $subscriptions->[0]->{recievedlist}, $notes,
211 'GetSubscriptionsFromBiblionumber should have returned recievedlist as it is in DB, ie. without br tags'
213 is( $subscriptions->[0]->{missinglist}, $notes,
214 'GetSubscriptionsFromBiblionumber should have returned missinglist as it is in DB, ie. without br tags'
218 is(C4::Serials::GetSerials(), undef, 'test getting serials when you enter nothing');
219 is(C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing');
221 is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
223 is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
225 is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
227 is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
229 is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
231 is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
233 is(C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters');
235 is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
237 is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
238 is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
240 is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
242 subtest 'test_updateClaim' => sub {
243 plan tests => 11;
245 my $today = output_pref({ dt => dt_from_string, dateonly => 1 });
246 # Given ... nothing much
247 # When ... Then ...
248 my $result_0 = C4::Serials::updateClaim(undef);
249 is($result_0, undef, 'Got the expected undef from update claim with nothin');
251 # Given ... 3 serial. 2 of them updated.
252 my $claimdate_1 = dt_from_string('2001-01-13'); # arbitrary date some time in the past.
253 my $claim_count_1 = 5;
254 my $biblio = $builder->build_sample_biblio;
255 my $serial1 = $builder->build_object(
257 class => 'Koha::Serials',
258 value => {
259 serialseq => 'serialseq',
260 subscriptionid => $subscriptionid,
261 status => 3,
262 biblionumber => $biblio->biblionumber,
263 claimdate => $claimdate_1,
264 claims_count => $claim_count_1,
268 my $serial2 = $builder->build_object(
270 class => 'Koha::Serials',
271 value => {
272 serialseq => 'serialseq',
273 subscriptionid => $subscriptionid,
274 status => 3,
275 biblionumber => $biblio->biblionumber,
276 claimdate => $claimdate_1,
277 claims_count => $claim_count_1,
281 my $serial3 = $builder->build_object(
283 class => 'Koha::Serials',
284 value => {
285 serialseq => 'serialseq',
286 subscriptionid => $subscriptionid,
287 status => 3,
288 biblionumber => $biblio->biblionumber,
289 claimdate => $claimdate_1,
290 claims_count => $claim_count_1,
295 # When ...
296 my $result_1 = C4::Serials::updateClaim([$serial1->serialid, $serial2->serialid]);
298 # Then ...
299 is($result_1, 2, 'Got the expected 2 from update claim with 2 serial ids');
301 my @late_or_missing_issues_1_0 = C4::Serials::GetLateOrMissingIssues(undef, $serial1->serialid);
302 is($late_or_missing_issues_1_0[0]->{claimdate}, $today, 'Got the expected first different claim date from update claim');
303 is($late_or_missing_issues_1_0[0]->{claims_count}, $claim_count_1+1, 'Got the expected first claim count from update claim');
304 is($late_or_missing_issues_1_0[0]->{status}, 7, 'Got the expected first claim status from update claim');
306 my @late_or_missing_issues_1_1 = C4::Serials::GetLateOrMissingIssues(undef, $serial2->serialid);
307 is($late_or_missing_issues_1_1[0]->{claimdate}, $today, 'Got the expected second different claim date from update claim');
308 is($late_or_missing_issues_1_1[0]->{claims_count}, $claim_count_1+1, 'Got the expected second claim count from update claim');
309 is($late_or_missing_issues_1_1[0]->{status}, 7, 'Got the expected second claim status from update claim');
311 my @late_or_missing_issues_1_2 = C4::Serials::GetLateOrMissingIssues(undef, $serial3->serialid);
312 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');
313 is($late_or_missing_issues_1_2[0]->{claims_count}, $claim_count_1, 'Got the expected unchanged claim count from update claim');
314 is($late_or_missing_issues_1_2[0]->{status}, 3, 'Got the expected unchanged claim status from update claim');
317 is(C4::Serials::check_routing(), undef, 'test checking route');
318 is(C4::Serials::check_routing($subscriptionid), 0, 'There should not have any routing list for the subscription');
319 # TODO really test this check_routing subroutine
321 is(C4::Serials::addroutingmember(),undef, 'test adding route member');
324 # Unit tests for statuses management (Bug 11689)
325 $subscriptionid = NewSubscription(
326 undef, "", undef, undef, $budget_id, $biblionumber,
327 '2013-01-01', $frequency_id, undef, undef, undef,
328 undef, undef, undef, undef, undef, undef,
329 1, $notes,undef, '2013-01-01', undef, $pattern_id,
330 undef, undef, 0, $internalnotes, 0,
331 undef, undef, 0, undef, '2013-12-31', 0
333 my $total_issues;
334 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
335 is( $total_issues, 1, "NewSubscription created a first serial" );
336 is( @serials, 1, "GetSerials returns the serial" );
337 my $subscription = C4::Serials::GetSubscription($subscriptionid);
338 my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
339 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
340 my $publisheddate = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 });
341 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
342 $frequency = C4::Serials::Frequency::GetSubscriptionFrequency($subscription->{periodicity});
343 my $nextpublisheddate = C4::Serials::GetNextDate($subscription, $publisheddate, $frequency, 1);
344 my @statuses = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
345 # Add 14 serials
346 my $counter = 0;
347 for my $status ( @statuses ) {
348 my $serialseq = "No.".$counter;
349 my ( $expected_serial ) = GetSerials2( $subscriptionid, [1] );
350 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, $serialseq, $publisheddate, $publisheddate, $publisheddate, $statuses[$counter], 'an useless note' );
351 $counter++;
353 # 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
354 my @serialsByStatus = C4::Serials::findSerialsByStatus(2,$subscriptionid);
355 is(@serialsByStatus,2,"findSerialsByStatus returns all serials with chosen status");
356 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
357 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
358 my @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
359 my @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
360 is( @arrived_missing, 5, "GetSerials returns 5 arrived/missing by default" );
361 is( @others, 6, "GetSerials returns all serials not arrived and not missing" );
363 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid, 10 );
364 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
365 @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
366 @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
367 is( @arrived_missing, 9, "GetSerials returns all arrived/missing if count given" );
368 is( @others, 6, "GetSerials returns all serials not arrived and not missing if count given" );
370 $subscription = C4::Serials::GetSubscription($subscriptionid); # Retrieve the updated subscription
372 my @serialseqs;
373 for my $am ( @arrived_missing ) {
374 if ( grep {/^$am->{status}$/} qw( 4 41 42 43 44 ) ) {
375 push @serialseqs, $am->{serialseq}
376 } elsif ( grep {/^$am->{status}$/} qw( 5 ) ) {
377 push @serialseqs, 'not issued ' . $am->{serialseq};
380 is( $subscription->{missinglist}, join('; ', @serialseqs), "subscription missinglist is updated after ModSerialStatus" );
382 subtest "Do not generate an expected if one already exists" => sub {
383 plan tests => 2;
384 my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
386 #Find serialid for serial with status Expected
387 my $serialexpected = ( C4::Serials::findSerialsByStatus( 1, $subscriptionid ) )[0];
389 #delete serial with status Expected
390 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
391 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
392 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and create another if not exist" );
394 # add 1 serial with status=Expected 1
395 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
397 #Now we have two serials it have status expected
398 #put status delete for last serial
399 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
401 #try if create or not another serial with status is expected
402 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
403 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and not create another if exists" );
406 subtest "PreserveSerialNotes preference" => sub {
407 plan tests => 2;
408 my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
410 t::lib::Mocks::mock_preference( 'PreserveSerialNotes', 1 );
412 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
413 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
414 is( $serialsByStatus[0]->{note},$expected_serial->{note}, "note passed through if supposed to");
416 t::lib::Mocks::mock_preference( 'PreserveSerialNotes', 0 );
417 $expected_serial = $serialsByStatus[0];
418 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
419 is( $serialsByStatus[0]->{note},$expected_serial->{note}, "note not passed through if not supposed to");
423 subtest "NewSubscription" => sub {
424 plan tests => 1;
425 my $subscriptionid = NewSubscription(
426 "", "", "", "", $budget_id, $biblionumber,
427 '2013-01-01', $frequency_id, "", "", "",
428 "", "", "", "", "", "",
429 1, $notes,"", '2013-01-01', "", $pattern_id,
430 "", "", 0, $internalnotes, 0,
431 "", "", 0, "", '2013-12-31', 0
433 ok($subscriptionid, "Sending empty string instead of undef to reflect use of the interface");