Bug 20568: (QA follow-up) Get rid of the id column
[koha.git] / t / db_dependent / Serials.t
blob6e65ee3098648562c81eacf35e5b9d143c1caf5e
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 => '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 ok(C4::Serials::GetSerialStatusFromSerialId($serial->{serialid}), 'test getting Serial Status From Serial Id');
144 isa_ok(C4::Serials::GetSerialInformation($serial->{serialid}), 'HASH', 'test getting Serial Information');
146 subtest 'Values should not be erased on editing' => sub {
148 plan tests => 1;
150 ( $biblionumber, $biblioitemnumber ) = get_biblio();
151 my ( $icn_tag, $icn_sf ) = GetMarcFromKohaField( 'items.itemcallnumber', '' );
152 my ( $it_tag, $it_sf ) = GetMarcFromKohaField( 'items.itype', '' );
154 my $itemtype = $builder->build( { source => 'Itemtype' } )->{itemtype};
155 my $itemcallnumber = 'XXXmy itemcallnumberXXX';
157 my $item_record = new MARC::Record;
159 $item_record->append_fields(
160 MARC::Field->new( '080', '', '', "a" => "default" ),
161 MARC::Field->new(
162 $icn_tag, '', '',
163 $icn_sf => $itemcallnumber,
164 $it_sf => $itemtype
167 my ( undef, undef, $itemnumber ) = C4::Items::AddItemFromMarc( $item_record, $biblionumber );
168 my $serialid = C4::Serials::NewIssue( "serialseq", $subscriptionid, $biblionumber,
169 1, undef, undef, "publisheddatetext", "notes" );
170 C4::Serials::AddItem2Serial( $serialid, $itemnumber );
171 my $serial_info = C4::Serials::GetSerialInformation($serialid);
172 my ($itemcallnumber_info) = grep { $_->{kohafield} eq 'items.itemcallnumber' }
173 @{ $serial_info->{items}[0]->{iteminformation} };
174 like( $itemcallnumber_info->{marc_value}, qr|value="$itemcallnumber"| );
177 # Delete created frequency
178 if ($old_frequency) {
179 my $freq_to_delete = $subscriptioninformation->{periodicity};
180 $subscriptioninformation->{periodicity} = $old_frequency;
182 ModSubscription( @$subscriptioninformation{qw(
183 librarian branchcode aqbooksellerid cost aqbudgetid startdate
184 periodicity firstacquidate irregularity numberpattern locale
185 numberlength weeklength monthlength lastvalue1 innerloop1 lastvalue2
186 innerloop2 lastvalue3 innerloop3 status biblionumber callnumber notes
187 letter manualhistory internalnotes serialsadditems staffdisplaycount
188 opacdisplaycount graceperiod location enddate subscriptionid
189 skip_serialseq
190 )} );
192 DelSubscriptionFrequency($freq_to_delete);
195 # Test calling subs without parameters
196 is(C4::Serials::AddItem2Serial(), undef, 'test adding item to serial');
197 is(C4::Serials::GetFullSubscription(), undef, 'test getting full subscription');
198 is(C4::Serials::PrepareSerialsData(), undef, 'test preparing serial data');
199 is(C4::Serials::GetSubscriptionsFromBiblionumber(), undef, 'test getting subscriptions form biblio number');
201 is(C4::Serials::GetSerials(), undef, 'test getting serials when you enter nothing');
202 is(C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing');
204 is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
206 is(C4::Serials::GetDistributedTo(), undef, 'test getting distributed when nothing is entered');
208 is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
210 is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
212 is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
214 is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
216 is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
218 is(C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters');
220 is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
222 is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
223 is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
225 is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
227 subtest 'test_updateClaim' => sub {
228 plan tests => 11;
230 my $today = output_pref({ dt => dt_from_string, dateonly => 1 });
231 # Given ... nothing much
232 # When ... Then ...
233 my $result_0 = C4::Serials::updateClaim(undef);
234 is($result_0, undef, 'Got the expected undef from update claim with nothin');
236 # Given ... 3 serial. 2 of them updated.
237 my $serialids_1 = [90980, 90981];
238 my $claimdate_1 = dt_from_string('2001-01-13'); # arbitrary date some time in the past.
239 my $claim_count_1 = 5;
240 Koha::Serial->new( { serialid => $serialids_1->[0], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
241 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
242 Koha::Serial->new( { serialid => $serialids_1->[1], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
243 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
244 Koha::Serial->new( { serialid => 90982, serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
245 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
247 # When ...
248 my $result_1 = C4::Serials::updateClaim($serialids_1);
250 # Then ...
251 is($result_1, 2, 'Got the expected 2 from update claim with 2 serial ids');
253 my @late_or_missing_issues_1_0 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[0]);
254 is($late_or_missing_issues_1_0[0]->{claimdate}, $today, 'Got the expected first different claim date from update claim');
255 is($late_or_missing_issues_1_0[0]->{claims_count}, $claim_count_1+1, 'Got the expected first claim count from update claim');
256 is($late_or_missing_issues_1_0[0]->{status}, 7, 'Got the expected first claim status from update claim');
258 my @late_or_missing_issues_1_1 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[1]);
259 is($late_or_missing_issues_1_1[0]->{claimdate}, $today, 'Got the expected second different claim date from update claim');
260 is($late_or_missing_issues_1_1[0]->{claims_count}, $claim_count_1+1, 'Got the expected second claim count from update claim');
261 is($late_or_missing_issues_1_1[0]->{status}, 7, 'Got the expected second claim status from update claim');
263 my @late_or_missing_issues_1_2 = C4::Serials::GetLateOrMissingIssues(undef, 90982);
264 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');
265 is($late_or_missing_issues_1_2[0]->{claims_count}, $claim_count_1, 'Got the expected unchanged claim count from update claim');
266 is($late_or_missing_issues_1_2[0]->{status}, 3, 'Got the expected unchanged claim status from update claim');
269 is(C4::Serials::check_routing(), undef, 'test checking route');
271 is(C4::Serials::addroutingmember(),undef, 'test adding route member');
274 # Unit tests for statuses management (Bug 11689)
275 $subscriptionid = NewSubscription(
276 undef, "", undef, undef, $budget_id, $biblionumber,
277 '2013-01-01', $frequency_id, undef, undef, undef,
278 undef, undef, undef, undef, undef, undef,
279 1, $notes,undef, '2013-01-01', undef, $pattern_id,
280 undef, undef, 0, $internalnotes, 0,
281 undef, undef, 0, undef, '2013-12-31', 0
283 my $total_issues;
284 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
285 is( $total_issues, 1, "NewSubscription created a first serial" );
286 is( @serials, 1, "GetSerials returns the serial" );
287 my $subscription = C4::Serials::GetSubscription($subscriptionid);
288 my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
289 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
290 my $publisheddate = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 });
291 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
292 my $nextpublisheddate = C4::Serials::GetNextDate($subscription, $publisheddate, 1);
293 my @statuses = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
294 # Add 14 serials
295 my $counter = 0;
296 for my $status ( @statuses ) {
297 my $serialseq = "No.".$counter;
298 my ( $expected_serial ) = GetSerials2( $subscriptionid, [1] );
299 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, $serialseq, $publisheddate, $publisheddate, $publisheddate, $statuses[$counter], 'an useless note' );
300 $counter++;
302 # 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
303 my @serialsByStatus = C4::Serials::findSerialsByStatus(2,$subscriptionid);
304 is(@serialsByStatus,2,"findSerialsByStatus returns all serials with chosen status");
305 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
306 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
307 my @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
308 my @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
309 is( @arrived_missing, 5, "GetSerials returns 5 arrived/missing by default" );
310 is( @others, 6, "GetSerials returns all serials not arrived and not missing" );
312 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid, 10 );
313 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
314 @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
315 @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
316 is( @arrived_missing, 9, "GetSerials returns all arrived/missing if count given" );
317 is( @others, 6, "GetSerials returns all serials not arrived and not missing if count given" );
319 $subscription = C4::Serials::GetSubscription($subscriptionid); # Retrieve the updated subscription
321 my @serialseqs;
322 for my $am ( @arrived_missing ) {
323 if ( grep {/^$am->{status}$/} qw( 4 41 42 43 44 ) ) {
324 push @serialseqs, $am->{serialseq}
325 } elsif ( grep {/^$am->{status}$/} qw( 5 ) ) {
326 push @serialseqs, 'not issued ' . $am->{serialseq};
329 is( $subscription->{missinglist}, join('; ', @serialseqs), "subscription missinglist is updated after ModSerialStatus" );
331 subtest "Do not generate an expected if one already exists" => sub {
332 plan tests => 2;
333 my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
335 #Find serialid for serial with status Expected
336 my $serialexpected = ( C4::Serials::findSerialsByStatus( 1, $subscriptionid ) )[0];
338 #delete serial with status Expected
339 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
340 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
341 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and create another if not exist" );
343 # add 1 serial with status=Expected 1
344 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
346 #Now we have two serials it have status expected
347 #put status delete for last serial
348 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
350 #try if create or not another serial with status is expected
351 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
352 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and not create another if exists" );
355 $dbh->rollback;
357 sub get_biblio {
358 my $bib = MARC::Record->new();
359 $bib->append_fields(
360 MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
361 MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
363 my ($bibnum, $bibitemnum) = AddBiblio($bib, '');
364 return ($bibnum, $bibitemnum);