f7595b0c2d0dada72ff5eaf902b2daea86de3141
[srvgit] / catalogue / detail.pl
1 #!/usr/bin/perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
19 use Modern::Perl;
20
21 use CGI qw ( -utf8 );
22 use HTML::Entities;
23 use C4::Auth qw( get_template_and_user );
24 use C4::Context;
25 use C4::Koha qw(
26     GetAuthorisedValues
27     getitemtypeimagelocation
28     GetNormalizedEAN
29     GetNormalizedISBN
30     GetNormalizedOCLCNumber
31     GetNormalizedUPC
32 );
33 use C4::Serials qw( CountSubscriptionFromBiblionumber SearchSubscriptions GetLatestSerials );
34 use C4::Output qw( output_html_with_http_headers );
35 use C4::Biblio qw( GetBiblioData GetFrameworkCode );
36 use C4::Items qw( GetAnalyticsCount );
37 use C4::Circulation qw( GetTransfers );
38 use C4::Reserves;
39 use C4::Serials qw( CountSubscriptionFromBiblionumber SearchSubscriptions GetLatestSerials );
40 use C4::XISBN qw( get_xisbns );
41 use C4::External::Amazon qw( get_amazon_tld );
42 use C4::Search qw( z3950_search_args enabled_staff_search_views new_record_from_zebra );
43 use C4::Tags qw( get_tags );
44 use C4::XSLT qw( XSLTParse4Display );
45 use Koha::DateUtils qw( format_sqldatetime );
46 use C4::HTML5Media;
47 use C4::CourseReserves qw( GetItemCourseReservesInfo );
48 use Koha::AuthorisedValues;
49 use Koha::Biblios;
50 use Koha::Biblio::ItemGroup::Items;
51 use Koha::Biblio::ItemGroups;
52 use Koha::CoverImages;
53 use Koha::DateUtils;
54 use Koha::Illrequests;
55 use Koha::Items;
56 use Koha::ItemTypes;
57 use Koha::Patrons;
58 use Koha::Virtualshelves;
59 use Koha::Plugins;
60 use Koha::Recalls;
61 use Koha::SearchEngine::Search;
62 use Koha::SearchEngine::QueryBuilder;
63 use Koha::Serial::Items;
64
65 my $query = CGI->new();
66
67 my $analyze = $query->param('analyze');
68
69 my ( $template, $borrowernumber, $cookie, $flags ) = get_template_and_user(
70     {
71     template_name   =>  'catalogue/detail.tt',
72         query           => $query,
73         type            => "intranet",
74         flagsrequired   => { catalogue => 1 },
75     }
76 );
77
78 # Determine if we should be offering any enhancement plugin buttons
79 if ( C4::Context->config('enable_plugins') ) {
80     # Only pass plugins that can offer a toolbar button
81     my @plugins = Koha::Plugins->new()->GetPlugins({
82         method => 'intranet_catalog_biblio_enhancements_toolbar_button'
83     });
84     $template->param(
85         plugins => \@plugins,
86     );
87 }
88
89 my $biblionumber = $query->param('biblionumber');
90 $biblionumber = HTML::Entities::encode($biblionumber);
91 my $biblio = Koha::Biblios->find( $biblionumber );
92 $template->param( 'biblio', $biblio );
93
94 unless ( $biblio ) {
95     # biblionumber invalid -> report and exit
96     $template->param( unknownbiblionumber => 1,
97                       biblionumber => $biblionumber );
98     output_html_with_http_headers $query, $cookie, $template->output;
99     exit;
100 }
101
102 my $marc_record = eval { $biblio->metadata->record };
103 my $invalid_marc_record = $@ || !$marc_record;
104 if ($invalid_marc_record) {
105     $template->param( decoding_error => $@ );
106     my $marc_xml = C4::Charset::StripNonXmlChars( $biblio->metadata->metadata );
107
108     $marc_record = eval {
109         MARC::Record::new_from_xml( $marc_xml, 'UTF-8',
110             C4::Context->preference('marcflavour') );
111     };
112 }
113
114 my $op = $query->param('op') || q{};
115 if ( $op eq 'set_item_group' ) {
116     my $item_group_id = $query->param('item_group_id');
117     my @itemnumbers   = $query->multi_param('itemnumber');
118
119     foreach my $item_id (@itemnumbers) {
120         my $item_group_item = Koha::Biblio::ItemGroup::Items->find( { item_id => $item_id } );
121
122         if ($item_group_item) {
123             $item_group_item->item_group_id($item_group_id);
124         }
125         else {
126             $item_group_item = Koha::Biblio::ItemGroup::Item->new(
127                 {
128                     item_id        => $item_id,
129                     item_group_id  => $item_group_id,
130                 }
131             );
132         }
133
134         $item_group_item->store();
135     }
136 }
137 elsif ( $op eq 'unset_item_group' ) {
138     my $item_group_id   = $query->param('item_group_id');
139     my @itemnumbers = $query->multi_param('itemnumber');
140
141     foreach my $item_id (@itemnumbers) {
142         my $item_group_item = Koha::Biblio::ItemGroup::Items->find( { item_id => $item_id } );
143         $item_group_item->delete() if $item_group_item;
144     }
145 }
146
147 if($query->cookie("holdfor")){
148     my $holdfor_patron = Koha::Patrons->find( $query->cookie("holdfor") );
149     if ( $holdfor_patron ) {
150         $template->param(
151             holdfor        => $query->cookie("holdfor"),
152             holdfor_patron => $holdfor_patron,
153         );
154     }
155 }
156
157 if($query->cookie("searchToOrder")){
158     my ( $basketno, $vendorid ) = split( /\//, $query->cookie("searchToOrder") );
159     $template->param(
160         searchtoorder_basketno => $basketno,
161         searchtoorder_vendorid => $vendorid
162     );
163 }
164
165 my $fw           = GetFrameworkCode($biblionumber);
166 my $showallitems = $query->param('showallitems');
167 my $marcflavour  = C4::Context->preference("marcflavour");
168
169 $template->param( 'SpineLabelShowPrintOnBibDetails' => C4::Context->preference("SpineLabelShowPrintOnBibDetails") );
170
171 $template->param( ocoins => !$invalid_marc_record ? $biblio->get_coins : undef );
172
173 # some useful variables for enhanced content;
174 # in each case, we're grabbing the first value we find in
175 # the record and normalizing it
176 my $upc = GetNormalizedUPC($marc_record,$marcflavour);
177 my $ean = GetNormalizedEAN($marc_record,$marcflavour);
178 my $oclc = GetNormalizedOCLCNumber($marc_record,$marcflavour);
179 my $isbn = GetNormalizedISBN(undef,$marc_record,$marcflavour);
180 my $content_identifier_exists;
181 if ( $isbn or $ean or $oclc or $upc ) {
182     $content_identifier_exists = 1;
183 }
184
185 $template->param(
186     normalized_upc => $upc,
187     normalized_ean => $ean,
188     normalized_oclc => $oclc,
189     normalized_isbn => $isbn,
190     content_identifier_exists =>  $content_identifier_exists,
191 );
192
193 my $itemtypes = { map { $_->itemtype => $_ } @{ Koha::ItemTypes->search_with_localization->as_list } };
194 my $all_items = $biblio->items->search_ordered;
195 my @items;
196 my $patron = Koha::Patrons->find( $borrowernumber );
197 while ( my $item = $all_items->next ) {
198     push @items, $item
199       unless $item->itemlost
200       && $patron->category->hidelostitems
201       && !$showallitems;
202 }
203
204 # flag indicating existence of at least one item linked via a host record
205 my $hostrecords;
206 # adding items linked via host biblios
207 my $hostitems = $biblio->host_items;
208 if ( $hostitems->count ) {
209     $hostrecords = 1;
210     push @items, $hostitems->as_list;
211 }
212
213 my $dat = &GetBiblioData($biblionumber);
214
215 #is biblio a collection and are bundles enabled
216 my $leader = $marc_record->leader();
217 $dat->{bundlesEnabled} = ( ( substr( $leader, 7, 1 ) eq 'c' )
218       && C4::Context->preference('BundleNotLoanValue') ) ? 1 : 0;
219
220 #coping with subscriptions
221 my $subscriptionsnumber = CountSubscriptionFromBiblionumber($biblionumber);
222 my @subscriptions       = SearchSubscriptions({ biblionumber => $biblionumber, orderby => 'title' });
223 my @subs;
224
225 foreach my $subscription (@subscriptions) {
226     my %cell;
227     my $serials_to_display;
228     $cell{subscriptionid}    = $subscription->{subscriptionid};
229     $cell{subscriptionnotes} = $subscription->{internalnotes};
230     $cell{missinglist}       = $subscription->{missinglist};
231     $cell{librariannote}     = $subscription->{librariannote};
232     $cell{branchcode}        = $subscription->{branchcode};
233     $cell{hasalert}          = $subscription->{hasalert};
234     $cell{callnumber}        = $subscription->{callnumber};
235     $cell{location}          = $subscription->{location};
236     $cell{closed}            = $subscription->{closed};
237     #get the three latest serials.
238     $serials_to_display = $subscription->{staffdisplaycount};
239     $serials_to_display = C4::Context->preference('StaffSerialIssueDisplayCount') unless $serials_to_display;
240     $cell{staffdisplaycount} = $serials_to_display;
241     $cell{latestserials} =
242       GetLatestSerials( $subscription->{subscriptionid}, $serials_to_display );
243     push @subs, \%cell;
244 }
245
246 # Get component parts details
247 my $showcomp = C4::Context->preference('ShowComponentRecords');
248 my $show_analytics;
249 if ( $showcomp eq 'both' || $showcomp eq 'staff' ) {
250     if ( my $components = !$invalid_marc_record ? $biblio->get_marc_components(C4::Context->preference('MaxComponentRecords')) : undef ) {
251         $show_analytics = 1 if @{$components}; # just show link when having results
252         $template->param( analytics_error => 1 ) if grep { $_->message eq 'component_search' } @{$biblio->object_messages};
253         my $parts;
254         for my $part ( @{$components} ) {
255             $part = C4::Search::new_record_from_zebra( 'biblioserver', $part );
256             my $id = Koha::SearchEngine::Search::extract_biblionumber( $part );
257
258             push @{$parts},
259               XSLTParse4Display(
260                 {
261                     biblionumber => $id,
262                     record       => $part,
263                     xsl_syspref  => "XSLTResultsDisplay",
264                     fix_amps     => 1,
265                 }
266               );
267         }
268         $template->param( ComponentParts => $parts );
269         my ( $comp_query, $comp_sort ) = $biblio->get_components_query;
270         my $cpq = $comp_query . "&sort_by=" . $comp_sort;
271         $template->param( ComponentPartsQuery => $cpq );
272     }
273 } else { # check if we should show analytics anyway
274     $show_analytics = 1 if !$invalid_marc_record && @{$biblio->get_marc_components(1)}; # count matters here, results does not
275     $template->param( analytics_error => 1 ) if grep { $_->message eq 'component_search' } @{$biblio->object_messages};
276 }
277
278 # XSLT processing of some stuff
279 my $xslt_variables = { show_analytics_link => $show_analytics };
280 $template->param(
281     XSLTDetailsDisplay => '1',
282     XSLTBloc => XSLTParse4Display({
283         biblionumber   => $biblionumber,
284         record         => $marc_record,
285         xsl_syspref    => "XSLTDetailsDisplay",
286         fix_amps       => 1,
287         xslt_variables => $xslt_variables,
288     }),
289 );
290
291 # Get acquisition details
292 if ( C4::Context->preference('AcquisitionDetails') ) {
293     my $orders = Koha::Acquisition::Orders->search(
294         { biblionumber => $biblionumber },
295         {
296             join => 'basketno',
297             order_by => 'basketno.booksellerid'
298         }
299     );    # GetHistory sorted by aqbooksellerid, but does it make sense?
300
301     $template->param(
302         orders => $orders,
303     );
304 }
305
306 if ( C4::Context->preference('suggestion') ) {
307     my $suggestions = Koha::Suggestions->search(
308         {
309             biblionumber => $biblionumber,
310             archived     => 0,
311         },
312         {
313             order_by => { -desc => 'suggesteddate' }
314         }
315     );
316     my $nb_archived_suggestions = Koha::Suggestions->search({ biblionumber => $biblionumber, archived => 1 })->count;
317     $template->param( suggestions => $suggestions, nb_archived_suggestions => $nb_archived_suggestions );
318 }
319
320 if ( defined $dat->{'itemtype'} ) {
321     $dat->{imageurl} = getitemtypeimagelocation( 'intranet', $itemtypes->{ $dat->{itemtype} }->imageurl );
322 }
323
324 $dat->{'count'} = $all_items->count + $hostitems->count;
325 $dat->{'showncount'} = scalar @items + $hostitems->count;
326 $dat->{'hiddencount'} = $all_items->count + $hostitems->count - scalar @items;
327
328 my $shelflocations =
329   { map { $_->{authorised_value} => $_->{lib} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => $fw, kohafield => 'items.location' } ) };
330 my $collections =
331   { map { $_->{authorised_value} => $_->{lib} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => $fw, kohafield => 'items.ccode' } ) };
332 my $copynumbers =
333   { map { $_->{authorised_value} => $_->{lib} } Koha::AuthorisedValues->get_descriptions_by_koha_field( { frameworkcode => $fw, kohafield => 'items.copynumber' } ) };
334 my (@itemloop, @otheritemloop, %itemfields);
335
336 my $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => $fw, kohafield => 'items.itemlost', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] });
337 if ( $mss->count ) {
338     $template->param( itemlostloop => GetAuthorisedValues( $mss->next->authorised_value ) );
339 }
340 $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => $fw, kohafield => 'items.damaged', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] });
341 if ( $mss->count ) {
342     $template->param( itemdamagedloop => GetAuthorisedValues( $mss->next->authorised_value ) );
343 }
344 $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => $fw, kohafield => 'items.withdrawn', authorised_value => { not => undef } });
345 if ( $mss->count ) {
346     $template->param( itemwithdrawnloop => GetAuthorisedValues( $mss->next->authorised_value) );
347 }
348
349 $mss = Koha::MarcSubfieldStructures->search({ frameworkcode => $fw, kohafield => 'items.materials', authorised_value => [ -and => {'!=' => undef }, {'!=' => ''}] });
350 my %materials_map;
351 if ($mss->count) {
352     my $materials_authvals = GetAuthorisedValues($mss->next->authorised_value);
353     if ($materials_authvals) {
354         foreach my $value (@$materials_authvals) {
355             $materials_map{$value->{authorised_value}} = $value->{lib};
356         }
357     }
358 }
359
360 my $analytics_flag;
361 my $materials_flag; # set this if the items have anything in the materials field
362 my $currentbranch = C4::Context->userenv ? C4::Context->userenv->{branch} : undef;
363 if ($currentbranch and C4::Context->preference('SeparateHoldings')) {
364     $template->param(SeparateHoldings => 1);
365 }
366 my $separatebranch = C4::Context->preference('SeparateHoldingsBranch') || 'homebranch';
367 my ( $itemloop_has_images, $otheritemloop_has_images );
368
369 foreach my $item (@items) {
370     my $itembranchcode = $item->$separatebranch;
371
372     my $item_info = $item->unblessed;
373     $item_info->{itemtype} = $itemtypes->{$item->effective_itemtype};
374
375     #get shelf location and collection code description if they are authorised value.
376     # same thing for copy number
377     my $shelfcode = $item->location;
378     $item_info->{'location'} = $shelflocations->{$shelfcode} if ( defined( $shelfcode ) && defined($shelflocations) && exists( $shelflocations->{$shelfcode} ) );
379     my $ccode = $item->ccode;
380     $item_info->{'ccode'} = $collections->{$ccode} if ( defined( $ccode ) && defined($collections) && exists( $collections->{$ccode} ) );
381     my $copynumber = $item->copynumber;
382     $item_info->{'copynumber'} = $copynumbers->{$copynumber} if ( defined($copynumber) && defined($copynumbers) && exists( $copynumbers->{$copynumber} ) );
383     foreach (qw(ccode enumchron copynumber stocknumber itemnotes itemnotes_nonpublic uri )) {
384         $itemfields{$_} = 1 if $item->$_;
385     }
386
387     # FIXME The following must be Koha::Item->serial
388     my $serial_item = Koha::Serial::Items->find($item->itemnumber);
389     if ( $serial_item ) {
390         $item_info->{serial} = $serial_item;
391         $itemfields{publisheddate} = 1;
392     }
393
394     $item_info->{object} = $item;
395
396     # checking for holds
397     my $holds = $item->current_holds;
398     if ( my $first_hold = $holds->next ) {
399         $item_info->{first_hold} = $first_hold;
400     }
401
402     $item_info->{checkout} = $item->checkout;
403
404     # Check the transit status
405     my $transfer = $item->get_transfer;
406     if ( $transfer ) {
407         $item_info->{transfertwhen} = $transfer->datesent;
408         $item_info->{transfertfrom} = $transfer->frombranch;
409         $item_info->{transfertto}   = $transfer->tobranch;
410         $item_info->{nocancel} = 1;
411     }
412
413     foreach my $f (qw( itemnotes )) {
414         if ($item_info->{$f}) {
415             $item_info->{$f} =~ s|\n|<br />|g;
416             $itemfields{$f} = 1;
417         }
418     }
419
420     #item has a host number if its biblio number does not match the current bib
421
422     if ($item->biblionumber ne $biblionumber){
423         $item_info->{hostbiblionumber} = $item->biblionumber;
424         $item_info->{hosttitle} = $item->biblio->title;
425     }
426
427
428     if ( $analyze ) {
429         # count if item is used in analytical bibliorecords
430         # The 'countanalytics' flag is only used in the templates if analyze is set
431         my $countanalytics = GetAnalyticsCount( $item->itemnumber );
432         if ($countanalytics > 0){
433             $analytics_flag=1;
434             $item_info->{countanalytics} = $countanalytics;
435         }
436     }
437
438     if (defined($item->materials) && $item->materials =~ /\S/){
439         $materials_flag = 1;
440         if (defined $materials_map{ $item->materials }) {
441             $item_info->{materials} = $materials_map{ $item->materials };
442         }
443     }
444
445     if ( C4::Context->preference('UseCourseReserves') ) {
446         $item_info->{'course_reserves'} = GetItemCourseReservesInfo( itemnumber => $item->itemnumber );
447     }
448
449     if ( C4::Context->preference("LocalCoverImages") == 1 ) {
450         $item_info->{cover_images} = $item->cover_images;
451     }
452
453     if ( C4::Context->preference('UseRecalls') ) {
454         $item_info->{recall} = $item->recall;
455     }
456
457     if ( C4::Context->preference('IndependentBranches') ) {
458         my $userenv = C4::Context->userenv();
459         if ( not C4::Context->IsSuperLibrarian()
460             and $userenv->{branch} ne $item->homebranch ) {
461             $item_info->{cannot_be_edited} = 1;
462             $item_info->{not_same_branch} = 1;
463         }
464     }
465
466     if ( $item->is_bundle ) {
467         $item_info->{bundled} =
468           $item->bundle_items->search( { itemlost => { '!=' => 0 } } )
469           ->count;
470         $item_info->{bundled_lost} =
471           $item->bundle_items->search( { itemlost => 0 } )->count;
472         $item_info->{is_bundle} = 1;
473     }
474
475     if ($item->in_bundle) {
476         $item_info->{bundle_host} = $item->bundle_host;
477     }
478
479     if ($currentbranch and C4::Context->preference('SeparateHoldings')) {
480         if ($itembranchcode and $itembranchcode eq $currentbranch) {
481             push @itemloop, $item_info;
482             $itemloop_has_images++ if $item->cover_images->count;
483         } else {
484             push @otheritemloop, $item_info;
485             $otheritemloop_has_images++ if $item->cover_images->count;
486         }
487     } else {
488         push @itemloop, $item_info;
489         $itemloop_has_images++ if $item->cover_images->count;
490     }
491 }
492
493 $template->param(
494     itemloop_has_images      => $itemloop_has_images,
495     otheritemloop_has_images => $otheritemloop_has_images,
496 );
497
498 # Display only one tab if one items list is empty
499 if (scalar(@itemloop) == 0 || scalar(@otheritemloop) == 0) {
500     $template->param(SeparateHoldings => 0);
501     if (scalar(@itemloop) == 0) {
502         @itemloop = @otheritemloop;
503     }
504 }
505
506 my $some_private_shelves = Koha::Virtualshelves->get_some_shelves(
507     {
508         borrowernumber => $borrowernumber,
509         add_allowed    => 1,
510         public         => 0,
511     }
512 );
513 my $some_public_shelves = Koha::Virtualshelves->get_some_shelves(
514     {
515         borrowernumber => $borrowernumber,
516         add_allowed    => 1,
517         public         => 1,
518     }
519 );
520
521
522 $template->param(
523     add_to_some_private_shelves => $some_private_shelves,
524     add_to_some_public_shelves  => $some_public_shelves,
525 );
526
527 $template->param(
528     MARCNOTES               => !$invalid_marc_record ? $biblio->get_marc_notes() : undef,
529     itemdata_ccode          => $itemfields{ccode},
530     itemdata_enumchron      => $itemfields{enumchron},
531     itemdata_uri            => $itemfields{uri},
532     itemdata_copynumber     => $itemfields{copynumber},
533     itemdata_stocknumber    => $itemfields{stocknumber},
534     itemdata_publisheddate  => $itemfields{publisheddate},
535     volinfo                 => $itemfields{enumchron},
536     itemdata_itemnotes      => $itemfields{itemnotes},
537     itemdata_nonpublicnotes => $itemfields{itemnotes_nonpublic},
538     z3950_search_params     => C4::Search::z3950_search_args($dat),
539     hostrecords             => $hostrecords,
540     analytics_flag          => $analytics_flag,
541     C4::Search::enabled_staff_search_views,
542     materials => $materials_flag,
543 );
544
545 if (C4::Context->preference("AlternateHoldingsField") && scalar @items == 0) {
546     my $fieldspec = C4::Context->preference("AlternateHoldingsField");
547     my $subfields = substr $fieldspec, 3;
548     my $holdingsep = C4::Context->preference("AlternateHoldingsSeparator") || ' ';
549     my @alternateholdingsinfo = ();
550     my @holdingsfields = $marc_record->field(substr $fieldspec, 0, 3);
551
552     for my $field (@holdingsfields) {
553         my %holding = ( holding => '' );
554         my $havesubfield = 0;
555         for my $subfield ($field->subfields()) {
556             if ((index $subfields, $$subfield[0]) >= 0) {
557                 $holding{'holding'} .= $holdingsep if (length $holding{'holding'} > 0);
558                 $holding{'holding'} .= $$subfield[1];
559                 $havesubfield++;
560             }
561         }
562         if ($havesubfield) {
563             push(@alternateholdingsinfo, \%holding);
564         }
565     }
566
567     $template->param(
568         ALTERNATEHOLDINGS   => \@alternateholdingsinfo,
569         );
570 }
571
572 my @results = ( $dat, );
573 foreach ( keys %{$dat} ) {
574     $template->param( "$_" => defined $dat->{$_} ? $dat->{$_} : '' );
575 }
576
577 # does not work: my %views_enabled = map { $_ => 1 } $template->query(loop => 'EnableViews');
578 # method query not found?!?!
579 $template->param( AmazonTld => get_amazon_tld() ) if ( C4::Context->preference("AmazonCoverImages"));
580 $template->param(
581     itemloop        => \@itemloop,
582     otheritemloop   => \@otheritemloop,
583     biblionumber        => $biblionumber,
584     ($analyze? 'analyze':'detailview') =>1,
585     subscriptions       => \@subs,
586     subscriptionsnumber => $subscriptionsnumber,
587     subscriptiontitle   => $dat->{title},
588     searchid            => scalar $query->param('searchid'),
589 );
590
591 # Lists
592
593 if (C4::Context->preference("virtualshelves") ) {
594     my $shelves = Koha::Virtualshelves->search(
595         {
596             biblionumber => $biblionumber,
597             public => 1,
598         },
599         {
600             join => 'virtualshelfcontents',
601         }
602     );
603     $template->param( 'shelves' => $shelves );
604 }
605
606 # XISBN Stuff
607 if (C4::Context->preference("FRBRizeEditions")==1) {
608     eval {
609         $template->param(
610             XISBNS => scalar get_xisbns($isbn, $biblionumber)
611         );
612     };
613     if ($@) { warn "XISBN Failed $@"; }
614 }
615
616 if ( C4::Context->preference("LocalCoverImages") == 1 ) {
617     my $images = $biblio->cover_images;
618     $template->param(
619         localimages => $biblio->cover_images->search(
620             {}, { order_by => [ \"COALESCE(itemnumber, 0, 1)", 'timestamp' ] }
621         ),
622     );
623 }
624
625 # HTML5 Media
626 if ( (C4::Context->preference("HTML5MediaEnabled") eq 'both') or (C4::Context->preference("HTML5MediaEnabled") eq 'staff') ) {
627     $template->param( C4::HTML5Media->gethtml5media($marc_record));
628 }
629
630 # Displaying tags
631 my $tag_quantity;
632 if (C4::Context->preference('TagsEnabled') and $tag_quantity = C4::Context->preference('TagsShowOnDetail')) {
633     $template->param(
634         TagsEnabled => 1,
635         TagsShowOnDetail => $tag_quantity
636     );
637     $template->param(TagLoop => get_tags({biblionumber=>$biblionumber, approved=>1,
638                                 'sort'=>'-weight', limit=>$tag_quantity}));
639 }
640
641 #we only need to pass the number of holds to the template
642 my $holds = $biblio->holds;
643 $template->param( holdcount => $holds->count );
644
645 # Check if there are any ILL requests connected to the biblio
646 my $illrequests =
647     C4::Context->preference('ILLModule')
648   ? Koha::Illrequests->search( { biblio_id => $biblionumber } )
649   : [];
650 $template->param( illrequests => $illrequests );
651
652 my $StaffDetailItemSelection = C4::Context->preference('StaffDetailItemSelection');
653 if ($StaffDetailItemSelection) {
654     # Only enable item selection if user can execute at least one action
655     if (
656         $flags->{superlibrarian}
657         || (
658             ref $flags->{tools} eq 'HASH' && (
659                 $flags->{tools}->{items_batchmod}       # Modify selected items
660                 || $flags->{tools}->{items_batchdel}    # Delete selected items
661             )
662         )
663         || ( ref $flags->{tools} eq '' && $flags->{tools} )
664       )
665     {
666         $template->param(
667             StaffDetailItemSelection => $StaffDetailItemSelection );
668     }
669 }
670
671 # get biblionumbers stored in the cart
672 my @cart_list;
673
674 if($query->cookie("intranet_bib_list")){
675     my $cart_list = $query->cookie("intranet_bib_list");
676     @cart_list = split(/\//, $cart_list);
677     if ( grep {$_ eq $biblionumber} @cart_list) {
678         $template->param( incart => 1 );
679     }
680 }
681
682 if ( C4::Context->preference('UseCourseReserves') ) {
683     my $course_reserves = GetItemCourseReservesInfo( biblionumber => $biblionumber );
684     $template->param( course_reserves => $course_reserves );
685 }
686
687 $template->param(found1 => scalar $query->param('found1') );
688
689 $template->param(biblio => $biblio);
690
691 output_html_with_http_headers $query, $cookie, $template->output;