3 # This Koha test module is a stub!
4 # Add more tests here!!!
10 use C4::Serials::Frequency;
11 use C4::Serials::Numberpattern;
18 use Koha::Acquisition::Booksellers;
20 use t::lib::TestBuilder;
21 use Test::More tests => 46;
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(
42 address1 => "bookseller's address",
48 my ($biblionumber, $biblioitemnumber) = AddBiblio(MARC::Record->new, '');
51 my $bpid = AddBudgetPeriod({
52 budget_period_startdate => '2015-01-01',
53 budget_period_enddate => '2015-12-31',
54 budget_period_description => "budget desc"
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
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}',
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
89 my $subscriptioninformation = GetSubscription( $subscriptionid );
91 is( $subscriptioninformation->{notes}, $notes, 'NewSubscription should set notes' );
92 is( $subscriptioninformation->{internalnotes}, $internalnotes, 'NewSubscription should set internalnotes' );
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' );
98 my @subscriptions = SearchSubscriptions({string => $subscriptioninformation->{bibliotitle}, orderby => 'title' });
99 isa_ok( \@subscriptions, 'ARRAY' );
101 @subscriptions = SearchSubscriptions({ issn => $subscriptioninformation->{issn}, orderby => 'title' });
102 isa_ok( \@subscriptions, 'ARRAY' );
104 @subscriptions = SearchSubscriptions({ ean => $subscriptioninformation->{ean}, orderby => 'title' });
105 isa_ok( \@subscriptions, 'ARRAY' );
107 @subscriptions = SearchSubscriptions({ biblionumber => $subscriptioninformation->{bibnum}, orderby => 'title' });
108 isa_ok( \@subscriptions, 'ARRAY' );
110 my $frequency = GetSubscriptionFrequency($subscriptioninformation->{periodicity});
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;
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
131 my $expirationdate = GetExpirationDate($subscriptionid) ;
132 ok( $expirationdate, "expiration date is not NULL" );
134 ok(C4::Serials::GetSubscriptionHistoryFromSubscriptionId($subscriptionid), 'test getting history from sub-scription');
136 my ($serials_count, @serials) = GetSerials($subscriptionid);
137 ok($serials_count > 0, 'Subscription has at least one serial');
138 my $serial = $serials[0];
140 isa_ok(C4::Serials::GetSerialInformation($serial->{serialid}), 'HASH', 'test getting Serial Information');
142 subtest 'Values should not be erased on editing' => sub {
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', '' );
151 my $itemtype = $builder->build( { source => 'Itemtype' } )->{itemtype};
152 my $itemcallnumber = 'XXXmy itemcallnumberXXX';
154 my $item_record = new MARC::Record;
156 $item_record->append_fields(
157 MARC::Field->new( '080', '', '', "a" => "default" ),
160 $icn_sf => $itemcallnumber,
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"| );
174 # Delete created frequency
175 if ($old_frequency) {
176 my $freq_to_delete = $subscriptioninformation->{periodicity};
177 $subscriptioninformation->{periodicity} = $old_frequency;
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
189 DelSubscriptionFrequency($freq_to_delete);
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');
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');
201 is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
203 is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
205 is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
207 is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
209 is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
211 is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
213 is(C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters');
215 is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
217 is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
218 is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
220 is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
222 subtest 'test_updateClaim' => sub {
225 my $today = output_pref({ dt => dt_from_string, dateonly => 1 });
226 # Given ... nothing much
228 my $result_0 = C4::Serials::updateClaim(undef);
229 is($result_0, undef, 'Got the expected undef from update claim with nothin');
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();
243 my $result_1 = C4::Serials::updateClaim($serialids_1);
246 is($result_1, 2, 'Got the expected 2 from update claim with 2 serial ids');
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');
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');
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');
264 is(C4::Serials::check_routing(), undef, 'test checking route');
266 is(C4::Serials::addroutingmember(),undef, 'test adding route member');
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
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 $frequency = C4::Serials::Frequency::GetSubscriptionFrequency($subscription->{periodicity});
288 my $nextpublisheddate = C4::Serials::GetNextDate($subscription, $publisheddate, $frequency, 1);
289 my @statuses = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
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' );
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
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 {
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" );