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 ( $biblionumber, $biblioitemnumber ) = get_biblio();
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" ),
159 $icn_sf => $itemcallnumber,
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" );
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
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');
195 is(C4::Serials::GetSubscriptionsFromBiblionumber(), undef, 'test getting subscriptions form biblio number');
197 is(C4::Serials::GetSerials(), undef, 'test getting serials when you enter nothing');
198 is(C4::Serials::GetSerials2(), undef, 'test getting serials when you enter nothing');
200 is(C4::Serials::GetLatestSerials(), undef, 'test getting lastest serials');
202 is(C4::Serials::GetNextSeq(), undef, 'test getting next seq when you enter nothing');
204 is(C4::Serials::GetSeq(), undef, 'test getting seq when you enter nothing');
206 is(C4::Serials::CountSubscriptionFromBiblionumber(), undef, 'test counting subscription when nothing is entered');
208 is(C4::Serials::ModSubscriptionHistory(), undef, 'test modding subscription history');
210 is(C4::Serials::ModSerialStatus(),undef, 'test modding serials');
212 is(C4::Serials::findSerialsByStatus(), 0, 'test finding serial by status with no parameters');
214 is(C4::Serials::NewIssue(), undef, 'test getting 0 when nothing is entered');
216 is(C4::Serials::HasSubscriptionStrictlyExpired(), undef, 'test if the subscriptions has expired');
217 is(C4::Serials::HasSubscriptionExpired(), undef, 'test if the subscriptions has expired');
219 is(C4::Serials::GetLateOrMissingIssues(), undef, 'test getting last or missing issues');
221 subtest 'test_updateClaim' => sub {
224 my $today = output_pref({ dt => dt_from_string, dateonly => 1 });
225 # Given ... nothing much
227 my $result_0 = C4::Serials::updateClaim(undef);
228 is($result_0, undef, 'Got the expected undef from update claim with nothin');
230 # Given ... 3 serial. 2 of them updated.
231 my $serialids_1 = [90980, 90981];
232 my $claimdate_1 = dt_from_string('2001-01-13'); # arbitrary date some time in the past.
233 my $claim_count_1 = 5;
234 Koha::Serial->new( { serialid => $serialids_1->[0], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
235 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
236 Koha::Serial->new( { serialid => $serialids_1->[1], serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
237 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
238 Koha::Serial->new( { serialid => 90982, serialseq => 'serialseq', subscriptionid => $subscriptionid, status => 3,
239 biblionumber => 12345, claimdate => $claimdate_1, claims_count => $claim_count_1, } )->store();
242 my $result_1 = C4::Serials::updateClaim($serialids_1);
245 is($result_1, 2, 'Got the expected 2 from update claim with 2 serial ids');
247 my @late_or_missing_issues_1_0 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[0]);
248 is($late_or_missing_issues_1_0[0]->{claimdate}, $today, 'Got the expected first different claim date from update claim');
249 is($late_or_missing_issues_1_0[0]->{claims_count}, $claim_count_1+1, 'Got the expected first claim count from update claim');
250 is($late_or_missing_issues_1_0[0]->{status}, 7, 'Got the expected first claim status from update claim');
252 my @late_or_missing_issues_1_1 = C4::Serials::GetLateOrMissingIssues(undef, $serialids_1->[1]);
253 is($late_or_missing_issues_1_1[0]->{claimdate}, $today, 'Got the expected second different claim date from update claim');
254 is($late_or_missing_issues_1_1[0]->{claims_count}, $claim_count_1+1, 'Got the expected second claim count from update claim');
255 is($late_or_missing_issues_1_1[0]->{status}, 7, 'Got the expected second claim status from update claim');
257 my @late_or_missing_issues_1_2 = C4::Serials::GetLateOrMissingIssues(undef, 90982);
258 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');
259 is($late_or_missing_issues_1_2[0]->{claims_count}, $claim_count_1, 'Got the expected unchanged claim count from update claim');
260 is($late_or_missing_issues_1_2[0]->{status}, 3, 'Got the expected unchanged claim status from update claim');
263 is(C4::Serials::check_routing(), undef, 'test checking route');
265 is(C4::Serials::addroutingmember(),undef, 'test adding route member');
268 # Unit tests for statuses management (Bug 11689)
269 $subscriptionid = NewSubscription(
270 undef, "", undef, undef, $budget_id, $biblionumber,
271 '2013-01-01', $frequency_id, undef, undef, undef,
272 undef, undef, undef, undef, undef, undef,
273 1, $notes,undef, '2013-01-01', undef, $pattern_id,
274 undef, undef, 0, $internalnotes, 0,
275 undef, undef, 0, undef, '2013-12-31', 0
278 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
279 is( $total_issues, 1, "NewSubscription created a first serial" );
280 is( @serials, 1, "GetSerials returns the serial" );
281 my $subscription = C4::Serials::GetSubscription($subscriptionid);
282 my $pattern = C4::Serials::Numberpattern::GetSubscriptionNumberpattern($subscription->{numberpattern});
283 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
284 my $publisheddate = output_pref({ dt => dt_from_string, dateformat => 'iso', dateonly => 1 });
285 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
286 my $nextpublisheddate = C4::Serials::GetNextDate($subscription, $publisheddate, 1);
287 my @statuses = qw( 2 2 3 3 3 3 3 4 4 41 42 43 44 5 );
290 for my $status ( @statuses ) {
291 my $serialseq = "No.".$counter;
292 my ( $expected_serial ) = GetSerials2( $subscriptionid, [1] );
293 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, $serialseq, $publisheddate, $publisheddate, $publisheddate, $statuses[$counter], 'an useless note' );
296 # 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
297 my @serialsByStatus = C4::Serials::findSerialsByStatus(2,$subscriptionid);
298 is(@serialsByStatus,2,"findSerialsByStatus returns all serials with chosen status");
299 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid );
300 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
301 my @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
302 my @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
303 is( @arrived_missing, 5, "GetSerials returns 5 arrived/missing by default" );
304 is( @others, 6, "GetSerials returns all serials not arrived and not missing" );
306 ( $total_issues, @serials ) = C4::Serials::GetSerials( $subscriptionid, 10 );
307 is( $total_issues, @statuses + 1, "GetSerials returns total_issues" );
308 @arrived_missing = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? $_ : () } @serials;
309 @others = map { my $status = $_->{status}; ( grep { /^$status$/ } qw( 2 4 41 42 43 44 5 ) ) ? () : $_ } @serials;
310 is( @arrived_missing, 9, "GetSerials returns all arrived/missing if count given" );
311 is( @others, 6, "GetSerials returns all serials not arrived and not missing if count given" );
313 $subscription = C4::Serials::GetSubscription($subscriptionid); # Retrieve the updated subscription
316 for my $am ( @arrived_missing ) {
317 if ( grep {/^$am->{status}$/} qw( 4 41 42 43 44 ) ) {
318 push @serialseqs, $am->{serialseq}
319 } elsif ( grep {/^$am->{status}$/} qw( 5 ) ) {
320 push @serialseqs, 'not issued ' . $am->{serialseq};
323 is( $subscription->{missinglist}, join('; ', @serialseqs), "subscription missinglist is updated after ModSerialStatus" );
325 subtest "Do not generate an expected if one already exists" => sub {
327 my ($expected_serial) = GetSerials2( $subscriptionid, [1] );
329 #Find serialid for serial with status Expected
330 my $serialexpected = ( C4::Serials::findSerialsByStatus( 1, $subscriptionid ) )[0];
332 #delete serial with status Expected
333 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
334 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
335 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and create another if not exist" );
337 # add 1 serial with status=Expected 1
338 C4::Serials::ModSerialStatus( $expected_serial->{serialid}, 'NO.20', $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
340 #Now we have two serials it have status expected
341 #put status delete for last serial
342 C4::Serials::ModSerialStatus( $serialexpected->{serialid}, $serialexpected->{serialseq}, $publisheddate, $publisheddate, $publisheddate, '1', 'an useless note' );
344 #try if create or not another serial with status is expected
345 @serialsByStatus = C4::Serials::findSerialsByStatus( 1, $subscriptionid );
346 is( @serialsByStatus, 1, "ModSerialStatus delete corectly serial expected and not create another if exists" );
350 my $bib = MARC::Record->new();
352 MARC::Field->new('100', ' ', ' ', a => 'Moffat, Steven'),
353 MARC::Field->new('245', ' ', ' ', a => 'Silence in the library'),
355 my ($bibnum, $bibitemnum) = AddBiblio($bib, '');
356 return ($bibnum, $bibitemnum);