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