Bug 19977: Open only .pref files in Local Use tab (sysprefs)
[koha.git] / t / db_dependent / Serials.t
blobde623fe73112b473e6fe02a64a84296d6f7642f8
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 => 48;
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 => '01-01-2015',
55 budget_period_enddate => '31-12-2015',
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 numberingmethod => '{X}',
71 label1 => q{},
72 add1 => 1,
73 every1 => 1,
74 every1 => 1,
75 numbering1 => 1,
76 whenmorethan1 => 1,
77 });
79 my $notes = 'notes';
80 my $internalnotes = 'intnotes';
81 my $subscriptionid = NewSubscription(
82 undef, "", undef, undef, $budget_id, $biblionumber,
83 '2013-01-01', $frequency_id, undef, undef, undef,
84 undef, undef, undef, undef, undef, undef,
85 1, $notes,undef, '2013-01-01', undef, $pattern_id,
86 undef, undef, 0, $internalnotes, 0,
87 undef, undef, 0, undef, '2013-12-31', 0
90 my $subscriptioninformation = GetSubscription( $subscriptionid );
92 is( $subscriptioninformation->{notes}, $notes, 'NewSubscription should set notes' );
93 is( $subscriptioninformation->{internalnotes}, $internalnotes, 'NewSubscription should set internalnotes' );
95 my $subscription_history = C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid);
96 is( $subscription_history->{opacnote}, '', 'NewSubscription should not set subscriptionhistory opacnotes' );
97 is( $subscription_history->{librariannote}, '', 'NewSubscription should not set subscriptionhistory librariannotes' );
99 my @subscriptions = SearchSubscriptions({string => $subscriptioninformation->{bibliotitle}, orderby => 'title' });
100 isa_ok( \@subscriptions, 'ARRAY' );
102 @subscriptions = SearchSubscriptions({ issn => $subscriptioninformation->{issn}, orderby => 'title' });
103 isa_ok( \@subscriptions, 'ARRAY' );
105 @subscriptions = SearchSubscriptions({ ean => $subscriptioninformation->{ean}, orderby => 'title' });
106 isa_ok( \@subscriptions, 'ARRAY' );
108 @subscriptions = SearchSubscriptions({ biblionumber => $subscriptioninformation->{bibnum}, orderby => 'title' });
109 isa_ok( \@subscriptions, 'ARRAY' );
111 my $frequency = GetSubscriptionFrequency($subscriptioninformation->{periodicity});
112 my $old_frequency;
113 if (not $frequency->{unit}) {
114 $old_frequency = $frequency->{id};
115 $frequency->{unit} = "month";
116 $frequency->{unitsperissue} = 1;
117 $frequency->{issuesperunit} = 1;
118 $frequency->{description} = "Frequency created by t/db_dependant/Serials.t";
119 $subscriptioninformation->{periodicity} = AddSubscriptionFrequency($frequency);
120 $subscriptioninformation->{serialsadditems} = 1;
122 ModSubscription( @$subscriptioninformation{qw(
123 librarian branchcode aqbooksellerid cost aqbudgetid startdate
124 periodicity firstacquidate irregularity numberpattern locale
125 numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
126 innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
127 letter manualhistory internalnotes serialsadditems staffdisplaycount
128 opacdisplaycount graceperiod location enddate subscriptionid
129 skip_serialseq
130 )} );
132 my $expirationdate = GetExpirationDate($subscriptionid) ;
133 ok( $expirationdate, "expiration date is not NULL" );
135 ok(C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid), 'test getting history from sub-scription');
137 my ($serials_count, @serials) = GetSerials($subscriptionid);
138 ok($serials_count > 0, 'Subscription has at least one serial');
139 my $serial = $serials[0];
141 ok(C4::Serials::GetSerialStatusFromSerialId($serial->{serialid}), 'test getting Serial Status From Serial Id');
143 isa_ok(C4::Serials::GetSerialInformation($serial->{serialid}), 'HASH', 'test getting Serial Information');
145 subtest 'Values should not be erased on editing' => sub {
147 plan tests => 1;
149 ( $biblionumber, $biblioitemnumber ) = get_biblio();
150 my ( $icn_tag, $icn_sf ) = GetMarcFromKohaField( 'items.itemcallnumber', '' );
151 my ( $it_tag, $it_sf ) = GetMarcFromKohaField( 'items.itype', '' );
153 my $itemtype = $builder->build( { source => 'Itemtype' } )->{itemtype};
154 my $itemcallnumber = 'XXXmy itemcallnumberXXX';
156 my $item_record = new MARC::Record;
158 $item_record->append_fields(
159 MARC::Field->new( '080', '', '', "a" => "default" ),
160 MARC::Field->new(
161 $icn_tag, '', '',
162 $icn_sf => $itemcallnumber,
163 $it_sf => $itemtype
166 my ( undef, undef, $itemnumber ) = C4::Items::AddItemFromMarc( $item_record, $biblionumber );
167 my $serialid = C4::Serials::NewIssue( "serialseq", $subscriptionid, $biblionumber,
168 1, undef, undef, "publisheddatetext", "notes" );
169 C4::Serials::AddItem2Serial( $serialid, $itemnumber );
170 my $serial_info = C4::Serials::GetSerialInformation($serialid);
171 my ($itemcallnumber_info) = grep { $_->{kohafield} eq 'items.itemcallnumber' }
172 @{ $serial_info->{items}[0]->{iteminformation} };
173 like( $itemcallnumber_info->{marc_value}, qr|value="$itemcallnumber"| );
176 # Delete created frequency
177 if ($old_frequency) {
178 my $freq_to_delete = $subscriptioninformation->{periodicity};
179 $subscriptioninformation->{periodicity} = $old_frequency;
181 ModSubscription( @$subscriptioninformation{qw(
182 librarian branchcode aqbooksellerid cost aqbudgetid startdate
183 periodicity firstacquidate irregularity numberpattern locale
184 numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
185 innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
186 letter manualhistory internalnotes serialsadditems staffdisplaycount
187 opacdisplaycount graceperiod location enddate subscriptionid
188 skip_serialseq
189 )} );
191 DelSubscriptionFrequency($freq_to_delete);
194 # Test calling subs without parameters
195 is(C4::Serials::AddItem2Serial(), undef, 'test adding item to serial');
196 is(C4::Serials::GetFullSubscription(), undef, 'test getting full subscription');
197 is(C4::Serials::PrepareSerialsData(), undef, 'test preparing serial data');
198 is(C4::Serials::GetSubscriptionsFromBiblionumber(), undef, 'test getting subscriptions form biblio number');
200 is(C4::Serials::GetSerials(), undef, 'test getting serials when you enter nothing');
201 is(C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing');
203 is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
205 is(C4::Serials::GetDistributedTo(), undef, 'test getting distributed when nothing is entered');
207 is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
209 is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
211 is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
213 is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
215 is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
217 is(C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters');
219 is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
221 is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
222 is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
224 is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
226 subtest 'test_updateClaim' => sub {
227 plan tests => 11;
229 my $today = output_pref({ dt => dt_from_string, dateonly => 1 });
230 # Given ... nothing much
231 # When ... Then ...
232 my $result_0 = C4::Serials::updateClaim(undef);
233 is($result_0, undef, 'Got the expected undef from update claim with nothin');
235 # Given ... 3 serial. 2 of them updated.
236 my $serialids_1 = [90980, 90981];
237 my $claimdate_1 = dt_from_string('2001-01-13'); # arbitrary date some time in the past.
238 my $claim_count_1 = 5;
239 Koha::Serial->new( { serialid => $serialids_1->[0], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
240 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
241 Koha::Serial->new( { serialid => $serialids_1->[1], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
242 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
243 Koha::Serial->new( { serialid => 90982, serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
244 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
246 # When ...
247 my $result_1 = C4::Serials::updateClaim($serialids_1);
249 # Then ...
250 is($result_1, 2, 'Got the expected 2 from update claim with 2 serial ids');
252 my @late_or_missing_issues_1_0 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[0]);
253 is($late_or_missing_issues_1_0[0]->{claimdate}, $today, 'Got the expected first different claim date from update claim');
254 is($late_or_missing_issues_1_0[0]->{claims_count}, $claim_count_1+1, 'Got the expected first claim count from update claim');
255 is($late_or_missing_issues_1_0[0]->{status}, 7, 'Got the expected first claim status from update claim');
257 my @late_or_missing_issues_1_1 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[1]);
258 is($late_or_missing_issues_1_1[0]->{claimdate}, $today, 'Got the expected second different claim date from update claim');
259 is($late_or_missing_issues_1_1[0]->{claims_count}, $claim_count_1+1, 'Got the expected second claim count from update claim');
260 is($late_or_missing_issues_1_1[0]->{status}, 7, 'Got the expected second claim status from update claim');
262 my @late_or_missing_issues_1_2 = C4::Serials::GetLateOrMissingIssues(undef, 90982);
263 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');
264 is($late_or_missing_issues_1_2[0]->{claims_count}, $claim_count_1, 'Got the expected unchanged claim count from update claim');
265 is($late_or_missing_issues_1_2[0]->{status}, 3, 'Got the expected unchanged claim status from update claim');
268 is(C4::Serials::check_routing(), undef, 'test checking route');
270 is(C4::Serials::addroutingmember(),undef, 'test adding route member');
273 # Unit tests for statuses management (Bug 11689)
274 $subscriptionid = NewSubscription(
275 undef, "", undef, undef, $budget_id, $biblionumber,
276 '2013-01-01', $frequency_id, undef, undef, undef,
277 undef, undef, undef, undef, undef, undef,
278 1, $notes,undef, '2013-01-01', undef, $pattern_id,
279 undef, undef, 0, $internalnotes, 0,
280 undef, undef, 0, undef, '2013-12-31', 0
282 my $total_issues;
283 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
284 is( $total_issues, 1, "NewSubscription created a first serial" );
285 is( @serials, 1, "GetSerials returns the serial" );
286 my $subscription = C4::Serials::GetSubscription($subscriptionid);
287 my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
288 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
289 my $publisheddate = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 });
290 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
291 my $nextpublisheddate = C4::Serials::GetNextDate($subscription, $publisheddate, 1);
292 my @statuses = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
293 # Add 14 serials
294 my $counter = 0;
295 for my $status ( @statuses ) {
296 my $serialseq = "No.".$counter;
297 my ( $expected_serial ) = GetSerials2( $subscriptionid, [1] );
298 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, $serialseq, $publisheddate, $publisheddate, $publisheddate, $statuses[$counter], 'an useless note' );
299 $counter++;
301 # 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
302 my @serialsByStatus = C4::Serials::findSerialsByStatus(2,$subscriptionid);
303 is(@serialsByStatus,2,"findSerialsByStatus returns all serials with chosen status");
304 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
305 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
306 my @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
307 my @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
308 is( @arrived_missing, 5, "GetSerials returns 5 arrived/missing by default" );
309 is( @others, 6, "GetSerials returns all serials not arrived and not missing" );
311 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid, 10 );
312 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
313 @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
314 @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
315 is( @arrived_missing, 9, "GetSerials returns all arrived/missing if count given" );
316 is( @others, 6, "GetSerials returns all serials not arrived and not missing if count given" );
318 $subscription = C4::Serials::GetSubscription($subscriptionid); # Retrieve the updated subscription
320 my @serialseqs;
321 for my $am ( @arrived_missing ) {
322 if ( grep {/^$am->{status}$/} qw( 4 41 42 43 44 ) ) {
323 push @serialseqs, $am->{serialseq}
324 } elsif ( grep {/^$am->{status}$/} qw( 5 ) ) {
325 push @serialseqs, 'not issued ' . $am->{serialseq};
328 is( $subscription->{missinglist}, join('; ', @serialseqs), "subscription missinglist is updated after ModSerialStatus" );
330 subtest "Do not generate an expected if one already exists" => sub {
331 plan tests => 2;
332 my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
334 #Find serialid for serial with status Expected
335 my $serialexpected = ( C4::Serials::findSerialsByStatus( 1, $subscriptionid ) )[0];
337 #delete serial with status Expected
338 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
339 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
340 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and create another if not exist" );
342 # add 1 serial with status=Expected 1
343 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
345 #Now we have two serials it have status expected
346 #put status delete for last serial
347 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
349 #try if create or not another serial with status is expected
350 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
351 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and not create another if exists" );
354 $dbh->rollback;
356 sub get_biblio {
357 my $bib = MARC::Record->new();
358 $bib->append_fields(
359 MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
360 MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
362 my ($bibnum, $bibitemnum) = AddBiblio($bib, '');
363 return ($bibnum, $bibitemnum);