7 [% USE AuthorisedValues %]
12 [% USE TablesSettings %]
13 [% PROCESS 'i18n.inc' %]
14 [% SET CoverImagePlugins = KohaPlugins.get_plugins_intranet_cover_images %]
16 [% IF Koha.Preference('AmazonAssocTag') %]
17 [% AmazonAssocTag = '?tag=' _ Koha.Preference('AmazonAssocTag') %]
19 [% AmazonAssocTag = '' %]
22 [% SET plugins_intranet_catalog_biblio_tabs = KohaPlugins.get_plugins_intranet_catalog_biblio_tab({ biblio => biblio, biblio_id => biblionumber }) %]
24 [% SET footerjs = 1 %]
25 [% INCLUDE 'doc-head-open.inc' %]
26 <title>[% FILTER collapse %]
27 [% IF ( unknownbiblionumber ) %]
28 [% t("Unknown record") | html %]
30 [% title_in_title = INCLUDE 'biblio-title-head.inc' %]
31 [% tx("Details for {title}", { title = title_in_title }) | html %]
33 [% t("Catalog") | html %] ›
34 [% t("Koha") | html %]
36 [% Asset.css("lib/Chocolat/css/chocolat.css") | $raw %]
37 [% INCLUDE 'doc-head-close.inc' %]
40 <body id="catalog_detail" class="catalog">
42 [% WRAPPER 'header.inc' %]
43 [% INCLUDE 'cat-search.inc' %]
46 [% WRAPPER 'sub-header.inc' %]
47 [% WRAPPER breadcrumbs %]
48 [% WRAPPER breadcrumb_item %]
49 <a href="/cgi-bin/koha/catalogue/search.pl">Catalog</a>
52 [% IF ( unknownbiblionumber ) %]
53 [% WRAPPER breadcrumb_item bc_active= 1 %]
54 <span>Unknown record</span>
57 [% WRAPPER breadcrumb_item %]
58 [% INCLUDE 'biblio-title.inc' link = 1 %]
60 [% WRAPPER breadcrumb_item bc_active= 1 %]
64 [% END #/ WRAPPER breadcrumbs %]
65 [% END #/ WRAPPER sub-header.inc %]
67 <div class="main container-fluid">
69 <div class="col-sm-10 col-sm-push-2">
71 [% INCLUDE 'messages.inc' %]
74 [% IF ( unknownbiblionumber ) %]
75 <div class="dialog message">The record you requested does not exist ([% biblionumber | html %]).</div>
78 [% IntranetCoce = Koha.Preference('IntranetCoce') %]
79 [% CoceProviders = Koha.Preference('CoceProviders') %]
80 [% CoceHost = Koha.Preference('CoceHost') %]
81 [% SyndeticsCovers = Koha.Preference('SyndeticsEnabled') && Koha.Preference('SyndeticsCoverImages') %]
83 [% INCLUDE 'cat-toolbar.inc' %]
85 <!-- COinS / OpenURL -->
86 <span class="Z3988" title="[% ocoins | html %]"></span>
89 [% IF ( CoverImagePlugins || AmazonCoverImages || LocalCoverImages || IntranetCoce || ( SyndeticsCovers ) || (Koha.Preference('CustomCoverImages') && Koha.Preference('CustomCoverImagesURL')) ) %]
90 <div id="catalogue_detail_biblio" class="col-xs-9">
92 <div id="catalogue_detail_biblio" class="col-xs-12">
94 [% IF decoding_error || analytics_error %]
95 <div class="page-section bg-danger">
97 [% IF decoding_error %]
98 <h2>Encoding errors</h2>
99 <p class="biberror">There is at least one encoding error with this bibliographic record, the view may be degraded.</p>
100 <pre class="error">[% decoding_error | html %]</pre>
102 [% IF analytics_error %]
103 <h2>Analytics errors</h2>
104 <p class="analytics_error">There was an error searching for analytic records, please see the logs for details.</p>
109 <div class="page-section">
111 [% XSLTBloc | $raw %]
113 [% IF shelves.count %]
114 <span class="results_summary"><span class="label">Lists that include this title: </span>
115 [% FOREACH s IN shelves %]
116 <a href="/cgi-bin/koha/virtualshelves/shelves.pl?op=view&shelfnumber=[% s.shelfnumber | uri %]">[% s.shelfname | html %]</a>
117 [% IF ( loop.last ) %][% ELSE %]|[% END %]
121 [% IF ( TagsEnabled && TagsShowOnDetail && TagLoop ) %]
122 <span class="results_summary"><span class="label">Tags:</span>
123 [% FOREACH TagLoo IN TagLoop %]
124 [% IF ( CAN_user_tools_moderate_tags ) %]
125 <a href="/cgi-bin/koha/tags/list.pl?tag=[% TagLoo.term |uri %]">[% TagLoo.term | html %]</a>
127 [% TagLoo.term | html %]
129 <span class="weight">([% TagLoo.weight_total | html %])</span>[% IF ( loop.last ) %][% ELSE %], [% END %]
133 <span id="catalogue_detail_marc_preview" class="results_summary"><span class="label">MARC preview:</span> <a href="/cgi-bin/koha/catalogue/showmarc.pl?id=[% biblionumber | uri %]&viewas=html" title="MARC" class="previewMARC">Show</a></span>
134 <span id="catalogue_detail_framework" class="results_summary">
135 <span class="label">MARC framework:</span>
136 <span class="frameworkcode">[% Frameworks.GetName(biblio.frameworkcode) | html %]</span>
138 [% IF !item_level_itypes || Koha.Preference("BiblioItemtypeInfo") %]
139 <span class="results_summary itemtype"><span class="label">Itemtype:</span>
140 [% IF ( !noItemTypeImages && imageurl ) %]
141 <img src="[% imageurl | html %]" alt="" />
143 [% IF ( description ) %]
144 <span class="itypetext">[% description | html %]</span>
146 <span class="itypetext">[% itemtype | html %]</span>
151 [% IF ( Koha.Preference('SearchEngine') == 'Elasticsearch' ) %]
152 <span id="catalogue_detail_elastic_record" class="results_summary"><span class="label">Elasticsearch record:</span> <a href="/cgi-bin/koha/catalogue/showelastic.pl?id=[% biblionumber | uri %]" title="Elasticsearch record" class="previewElastic">Show</a></span>
155 [% IF ( holdcount ) %]
156 <span class="results_summary">
157 <span class="label">Holds:</span>
158 <span class="number_box">
159 [% IF CAN_user_reserveforothers_place_holds %]
160 <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=[% biblionumber | uri %]">[% holdcount | html %]</a>
162 <span>[% holdcount | html %]</span>
168 [% IF illrequests.count %]
169 <span class="results_summary">
170 <span class="label">ILL requests:</span>
171 [% IF CAN_user_ill %]
172 [% FOREACH ill IN illrequests %]
173 <a href="/cgi-bin/koha/ill/ill-requests.pl?method=illview&illrequest_id=[% ill.illrequest_id | uri %]">Request [% ill.illrequest_id | html %]</a>[% IF ! loop.last %], [% END %]
176 [% FOREACH ill IN illrequests %]
177 <span>Request [% ill.illrequest_id | html %]</span>[% IF ! loop.last %], [% END %]
183 [% IF ( article_requests_count = biblio.article_requests.filter_by_current.count ) %]
184 <span class="results_summary">
185 <span class="label">Article requests:</span>
186 <span class="number_box">
187 <a href="/cgi-bin/koha/circ/request-article.pl?biblionumber=[% biblionumber | uri %]">[% article_requests_count | html %]</a>
192 [% IF course_reserves %]
193 <span class="results_summary"><span class="label">Courses that have reserved this title: </span>
194 [% FOREACH c IN course_reserves %]
195 <a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=[% c.course_id | uri %]">[% c.course.course_name | html %]</a>
196 [% IF ( loop.last ) %][% ELSE %]|[% END %]
200 </div> [%# .page-section %]
202 [% IF ( CoverImagePlugins || AmazonCoverImages || LocalCoverImages || IntranetCoce || ( SyndeticsCovers ) || (Koha.Preference('CustomCoverImages') && Koha.Preference('CustomCoverImagesURL')) ) %]
204 <div class="col-xs-3 bookcoverimg">
205 <div id="biblio-cover-slider" class="cover-slider" data-isbn="[% normalized_isbn | html %]">
206 [% IF ( LocalCoverImages ) %]
207 [% IF localimages.count %]
208 [% FOREACH image IN localimages %]
209 <div class="cover-image local-coverimg">
210 <a href="/cgi-bin/koha/catalogue/image.pl?imagenumber=[% image.imagenumber | uri %]" title="Local cover image">
211 <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&imagenumber=[% image.imagenumber | uri %]" alt="Local cover image" data-link="/cgi-bin/koha/catalogue/imageviewer.pl?biblionumber=[% biblionumber | uri %]&imagenumber=[% image.imagenumber | uri %]" />
213 <div class="hint">Local cover image</div>
219 [% IF ( AmazonCoverImages && normalized_isbn) %]
220 <div class="cover-image" id="amazon-bookcoverimg">
221 <a href="https://images-na.ssl-images-amazon.com/images/P/[% normalized_isbn | uri %].01.LZZZZZZZ.jpg" title="Amazon cover image">
222 <img src="https://images-na.ssl-images-amazon.com/images/P/[% normalized_isbn | uri %].01.MZZZZZZZ.jpg" alt="Amazon cover image" data-link="http://www.amazon[% AmazonTld | uri %]/gp/reader/[% normalized_isbn | uri %][% AmazonAssocTag | uri %]#reader-link"/>
224 <div class="hint">Image from Amazon.com</div>
228 [% IF ( IntranetCoce && CoceProviders && normalized_isbn ) %]
229 [% coce_id = normalized_ean || normalized_isbn %]
230 <div class="cover-image coce-coverimg">
232 <a title="Image from Coce" class="[% coce_id | html %]" id="coce-thumbnail-preview"></a>
234 <span class="no-image">No cover image available</span>
236 <div class="hint">Image from Coce</div>
240 [% IF ( SyndeticsCovers ) %]
241 [% IF ( content_identifier_exists ) %]
242 <div class="cover-image" id="syndetics-bookcoverimg">
243 <a href="https://secure.syndetics.com/index.aspx?isbn=[% normalized_isbn | url %]/LC.GIF&client=[% Koha.Preference('SyndeticsClientCode') | url %]&type=xw10&upc=[% normalized_upc | url %]&oclc=[% normalized_oclc | url %]" title="Syndetics cover image">
244 <img src="https://secure.syndetics.com/index.aspx?isbn=[% normalized_isbn | url %]/[% Koha.Preference('SyndeticsCoverImageSize') | url %].GIF&client=[% Koha.Preference('SyndeticsClientCode') | url %]&type=xw10&upc=[% normalized_upc | url %]&oclc=[% normalized_oclc | url %]" alt="" class="thumbnail" />
246 <div class="hint">Image from Syndetics</div>
249 <span class="no-image">No cover image available</span>
253 [% IF Koha.Preference('CustomCoverImages') && Koha.Preference('CustomCoverImagesURL') %]
254 [% SET custom_cover_image_url = biblio.custom_cover_image_url %]
255 [% IF custom_cover_image_url %]
256 <div class="cover-image" id="custom-coverimg">
257 <a class="custom_cover_image" href="[% custom_cover_image_url | url %]" title="Custom cover image">
258 <img id="custom-img" alt="Custom cover image" src="[% custom_cover_image_url | url %]" />
260 <div class="hint">Custom cover image</div>
264 </div> <!-- /.cover-slider -->
265 </div> <!-- /.bookcoverimg.col-xs-3 -->
267 </div> <!-- /.col-xs-* -->
268 [% END # /IF ( AmazonCoverImages, etc ) %]
271 <div id="bibliodetails" class="toptabs">
273 <ul class="nav nav-tabs" role="tablist">
274 [% IF Koha.Preference('SeparateHoldings') %]
275 <li role="presentation">
276 [%# FIXME We could build the numbers from DataTable's info %]
277 <a href="#holdings" aria-controls="holdings" role="tab" data-toggle="tab">[% Branches.GetLoggedInBranchname | html %] holdings ([% items_to_display_count - ( other_holdings_count || 0 ) - ( hidden_count || 0 ) || 0 | html %])</a>
279 <li role="presentation">
280 <a href="#otherholdings" aria-controls="otherholdings" role="tab" data-toggle="tab">Other holdings ([% other_holdings_count || 0 | html %])</a>
283 <li role="presentation">
284 <a href="#holdings" aria-controls="holdings" role="tab" data-toggle="tab">Holdings ([% items_to_display_count || 0 | html %])</a>
287 [% IF Koha.Preference('EnableItemGroups') %]
288 <li role="presentation">
289 <a href="#item_groups" aria-controls="item_groups" role="tab" data-toggle="tab">Item groups</a>
292 [% IF ( MARCNOTES || notes ) %]<li role="presentation"><a href="#description" aria-controls="description" role="tab" data-toggle="tab">Descriptions ([% ( MARCNOTES.size || 1 ) | html %])</a></li>[% END %]
293 [% IF ComponentParts && ComponentParts.size %]<li id="components_tab" role="presentation"><a href="#components" aria-controls="components" role="tab" data-toggle="tab">Components ([% ComponentParts.size | html %])</a></li>[% END %]
294 [% IF ( subscriptionsnumber ) %]<li role="presentation"><a href="#subscriptions" aria-controls="subscriptions" role="tab" data-toggle="tab">Subscriptions</a></li>[% END %]
295 [% IF Koha.Preference('AcquisitionDetails') %]<li role="presentation"><a href="#acq_details" aria-controls="acq_details" role="tab" data-toggle="tab">Acquisition details</a></li>[% END %]
296 [% IF suggestions.count %]<li role="presentation"><a href="#suggestion_details" aria-controls="suggestion_details" role="tab" data-toggle="tab">Suggestion details</a></li>[% END %]
297 [% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]<li role="presentation"><a href="#editions" aria-controls="editions" role="tab" data-toggle="tab">Editions</a></li>[% END %][% END %]
298 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]<li role="presentation"><a href="#concerns" aria-controls="concerns" role="tab" data-toggle="tab">Concerns ([% biblio.tickets.count | html %])</a></li>[% END %]
299 [% IF ( LocalCoverImages ) %]
300 <li role="presentation">
301 <a href="#images" aria-controls="images" role="tab" data-toggle="tab">Images ([% localimages.count || 0 | html %])</a>
304 [% IF HTML5MediaEnabled && HTML5MediaSets.size %]
305 <li id="media_tab" role="presentation"><a href="#html5media" aria-controls="html5media" role="tab" data-toggle="tab">Play media</a></li>
307 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'tab' ) %]
308 <li class="NovelistSelect" style="display:none;" role="presentation"><a href="#NovelistSelect" aria-controls="NovelistSelect" role="tab" data-toggle="tab">NoveList Select</a></li>
310 [% FOREACH plugins_intranet_catalog_biblio_tab IN plugins_intranet_catalog_biblio_tabs %]
311 <li role="presentation"><a href="#[% plugins_intranet_catalog_biblio_tab.id | uri %]" aria-controls="[% plugins_intranet_catalog_biblio_tab.id | uri %]" role="tab" data-toggle="tab">[% plugins_intranet_catalog_biblio_tab.title | html %]</a></li>
315 <div class="tab-content">
316 [% items_table_block_iter = 0 %]
317 [% BLOCK items_table %]
318 [% items_table_block_iter = items_table_block_iter + 1 %]
319 <div class="[% tab | html %]_table_table_controls">
320 [% IF (StaffDetailItemSelection) %]
321 <span class="show_hide_filters">
322 <a href="#" class="show_filters" data-tab="[% tab | html %]"><i class="fa fa-filter"></i> Show filters</a>
323 <a href="#" class="hide_filters" data-tab="[% tab | html %]" style="display: none;"><i class="fa fa-filter"></i> Hide filters</a>
325 | <a href="#" class="SelectAll" data-tab="[% tab | html %]"><i class="fa fa-check"></i> Select all</a>
326 | <a href="#" class="ClearAll" data-tab="[% tab | html %]"><i class="fa fa-times"></i> Clear all</a>
327 <span class="itemselection_actions">
329 [% IF CAN_user_tools_items_batchdel %]
330 <a class="itemselection_action_delete"><i class="fa fa-trash-can"></i> Delete selected items</a>
332 [% IF CAN_user_tools_items_batchmod %]
333 <a class="itemselection_action_modify"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Modify selected items</a>
335 [% IF CAN_user_editcatalogue_manage_item_groups && biblio.item_groups.count %]
336 <a class="itemselection_action_item_group_set" href="#"><i class="fa fa-book"></i> Add/move to item group</a>
337 <a class="itemselection_action_item_group_unset" href="#"><i class="fa fa-unlink"></i> Remove from item group</a>
343 <table class="items_table" id="[% tab | html %]_table">
345 [% IF (StaffDetailItemSelection) %]<th id="[% tab | html %]_checkbox" data-colname="[% tab | html %]_checkbox" class="NoSort"></th>[% END %]
346 [% IF Koha.Preference('LocalCoverImages') %]
347 <th id="[% tab | html %]_cover_image" data-colname="[% tab | html %]_cover_image">Cover image</th>
349 [% IF ( item_level_itypes ) %]<th id="[% tab | html %]_itype" data-colname="[% tab | html %]_itype">Item type</th>[% END %]
350 <th id="[% tab | html %]_holdingbranch" data-colname="[% tab | html %]_holdingbranch">Current library</th>
351 <th id="[% tab | html %]_homebranch" data-colname="[% tab | html %]_homebranch">Home library</th>
352 <th id="[% tab | html %]_ccode" data-colname="[% tab | html %]_ccode">Collection</th>
353 [% IF Koha.Preference('EnableItemGroups') %]
354 <th id="[% tab | html %]_item_group" data-colname="[% tab | html %]_item_group">Item group</th>
356 <th id="[% tab | html %]_itemcallnumber" data-colname="[% tab | html %]_itemcallnumber">Call number</th>
357 <th id="[% tab | html %]_enumchron" data-colname="[% tab | html %]_enumchron">Serial enumeration / chronology</th>
358 <th id="[% tab | html %]_status" data-colname="[% tab | html %]_status">Status</th>
359 <th id="[% tab | html %]_lastseen" data-colname="[% tab | html %]_lastseen">Last seen</th>
360 <th id="[% tab | html %]_issues" data-colname="[% tab | html %]_issues">Checkouts</th>
361 <th id="[% tab | html %]_renewals" data-colname="[% tab | html %]_renewals">Renewals</th>
362 <th id="[% tab | html %]_dateaccessioned" data-colname="[% tab | html %]_dateaccessioned">Date accessioned</th>
363 <th id="[% tab | html %]_datelastborrowed" data-colname="[% tab | html %]_datelastborrowed">Date last borrowed</th>
364 <th id="[% tab | html %]_barcode" data-colname="[% tab | html %]_barcode">Barcode</th>
365 <th id="[% tab | html %]_uri" data-colname="[% tab | html %]_uri">URL</th>
366 <th id="[% tab | html %]_copynumber" data-colname="[% tab | html %]_copynumber">Copy number</th>
367 <th id="[% tab | html %]_stocknumber" data-colname="[% tab | html %]_stocknumber">Inventory number</th>
368 <th id="[% tab | html %]_materials" data-colname="[% tab | html %]_materials">Materials specified</th>
369 <th id="[% tab | html %]_itemnotes" data-colname="[% tab | html %]_itemnotes">Public notes</th>
370 <th id="[% tab | html %]_itemnotes_nonpublic" data-colname="[% tab | html %]_itemnotes_nonpublic">Non-public notes</th>
371 [% IF ( hostrecords ) %]<th id="[% tab | html %]_hostrecord" data-colname="[% tab | html %]_hostrecord">Host records</th>[% END %]
372 [% IF ( analyze ) %]<th id="[% tab | html %]_usedin" data-colname="[% tab | html %]_usedin">Used in</th><th></th>[% END %]
373 [% IF Koha.Preference('UseCourseReserves') %]<th id="[% tab | html %]_course_reserves" data-colname="[% tab | html %]_course_reserves">Course reserves</th>[% END %]
374 [% IF ( SpineLabelShowPrintOnBibDetails ) %]<th id="[% tab | html %]_spinelabel" data-colname="[% tab | html %]_spinelabel" class="NoSort">Spine label</th>[% END %]
375 [% IF ( CAN_user_editcatalogue_edit_items ) %]<th id="[% tab | html %]_actions" data-colname="[% tab | html %]_actions"class="NoSort noExport"> </th>[% END %]
379 [% END %][%# end of block items_table %]
381 [% IF Koha.Preference('EnableItemGroups') %]
382 <div role="tabpanel" class="tab-pane" id="item_groups">
383 [% IF CAN_user_editcatalogue_manage_item_groups %]
384 <div class="item_groups_table_table_controls">
385 <a href="#" class="item-group-create btn btn-default btn-xs"><i class="fa fa-plus"></i> New item group</a>
388 <table class="items-group-table" id="items-group-table">
391 <th>Display order</th>
393 <th class="NoSort"> </th>
401 <div role="tabpanel" class="tab-pane" id="holdings">
403 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'above' ) %]
404 <span class="results_summary NovelistSelect" style="display:none;">
405 <span class="label">Novelist Select: </span>
406 <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
410 [% SET hidden_count = all_items_count - items_to_display_count %]
411 [% IF all_items_count %]
412 [% PROCESS items_table tab="holdings" %]
414 [% IF hidden_count %]
415 [%# FIXME We could deal with that in JS and prevent a full refresh %]
416 <p><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblionumber | uri %]&showallitems=1">Show all items ([% hidden_count | html %] hidden)</a>
419 [% IF ( ALTERNATEHOLDINGS ) %]
420 [% FOREACH ALTERNATEHOLDING IN ALTERNATEHOLDINGS %]
421 <div id="alternateholdings"><span class="holdings_label">Holdings:</span> [% ALTERNATEHOLDING.holding | html %]</div>
424 <div id="noitems">No physical items for this record</div>
428 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'below' ) %]
429 <span class="results_summary NovelistSelect" style="display:none;">
430 <span class="label">Novelist Select: </span>
431 <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
436 [% IF Koha.Preference('SeparateHoldings') %]
437 <div role="tabpanel" class="tab-pane" id="otherholdings">
438 [% PROCESS items_table tab="otherholdings" %]
442 [% IF ( MARCNOTES ) %]
444 <div role="tabpanel" class="tab-pane" id="description">
445 <div class="content_set">
447 [% FOREACH MARCNOTE IN MARCNOTES %]
448 <p class="marcnote marcnote-[% MARCNOTE.tag | html %]" id="marcnote-[% MARCNOTE.tag | html %]-[% loop.count | html %]">
449 [% IF MARCNOTE.marcnote.match('^https?://\S+$') %]
450 <a href="[% MARCNOTE.marcnote | url %]">[% MARCNOTE.marcnote | html %]</a>
452 [% MARCNOTE.marcnote | html | html_line_break %]
461 [% IF ComponentParts && ComponentParts.size %]
462 <div role="tabpanel" class="tab-pane" id="components">
463 <div class="content_set">
465 [% FOR PART IN ComponentParts %]
473 [% IF ComponentParts.size == Koha.Preference('MaxComponentRecords')%]
474 <p>Only [% ComponentParts.size | html %] results are shown: <a href="/cgi-bin/koha/catalogue/search.pl?q=[% ComponentPartsQuery | url %]"/>show all component parts</a></p>
476 </div> <!-- /.content_set -->
477 </div> <!-- /#components -->
481 [% IF ( subscriptionsnumber ) %]
482 <div role="tabpanel" class="tab-pane" id="subscriptions">
483 <div id="catalogue_detail_subscriptions">
484 <h2>This is a serial subscription</h2>
485 <p> (There are [% subscriptionsnumber | html %] subscriptions associated with this title).</p>
486 [% FOREACH subscription IN subscriptions %]
487 [% IF subscription.branchcode %]
488 <h3>At library: [% Branches.GetName(subscription.branchcode) || subscription.branchcode | html %]</h3>
490 [% IF ( subscription.closed ) %]<p>This subscription is closed.</p>[% END %]
491 [% IF ( subscription.location ) %]<p class="subscription_location">Location: [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => subscription.location ) | html %]</p>[% END %]
492 [% IF ( subscription.callnumber ) %]<p>Callnumber: [% subscription.callnumber | html %] </p>[% END %]
493 [% IF ( subscription.subscriptionnotes ) %]<p>[% subscription.subscriptionnotes | html | html_line_break %] </p>[% END %]
494 [% IF ( subscription.missinglist ) %]<p>Missing issues: [% subscription.missinglist | html %] </p>[% END %]
495 [% IF ( subscription.librariannote ) %]<p>([% subscription.librariannote | html %])</p>[% END %]
496 [% IF ( subscription.latestserials ) %]
497 <p> The [% subscription.staffdisplaycount | html %] latest issues related to this subscription:</p>
501 <th>Date arrived</th>
502 <th>Date published</th>
503 <th>Date published (text)</th>
507 [% FOREACH latestserial IN subscription.latestserials %]
509 <td>[% latestserial.serialseq | html %]</td>
510 <td data-order="[% latestserial.planneddate | html %]">[% latestserial.planneddate | $KohaDates %]</td>
511 <td data-order="[% latestserial.publisheddate | html %]">[% latestserial.publisheddate | $KohaDates %]</td>
512 <td>[% latestserial.publisheddatetext | html %]</td>
514 [% INCLUDE 'serial-status.inc' serial = latestserial %]
516 <td>[% latestserial.notes | html %]</td>
521 [% IF ( CAN_user_serials ) %]
523 <a class="btn btn-link" href="/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=[% subscription.subscriptionid | uri %]"><i class="fa fa-list" aria-hidden="true"></i> Subscription details</a>
531 [% IF Koha.Preference('AcquisitionDetails') %]
532 <div role="tabpanel" class="tab-pane" id="acq_details">
533 [% IF orders.count %]
539 <th>Basket group</th>
541 <th>Order number</th>
542 <th>Creation date</th>
543 <th>Receive date</th>
546 <th title="Estimated cost tax incl. while pending, actual cost tax incl. once received">Price</th>
547 <th>Internal note</th>
548 <th>Subscription</th>
549 <th>Subscription call number</th>
553 [% FOR order IN orders %]
554 [% SET basket = order.basket %]
555 [% SET vendor = basket.bookseller %]
558 <a href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% vendor.id | uri %]" title="Vendor detail page">[% vendor.name | html %]</a>
561 [% IF order.invoiceid %]
562 [% IF CAN_user_acquisition %]
563 <div><a href="/cgi-bin/koha/acqui/invoice.pl?invoiceid=[% order.invoiceid | uri %]"
564 title="Invoice detail page">
565 [% order.invoice.invoicenumber | html %]</a></div>
567 <div>[% order.invoice.invoicenumber | html %]</div>
570 [% IF ( Koha.Preference('EDIFACT') && CAN_user_acquisition_edi_manage && order.invoice.message_id ) %]
571 <div><a href="/cgi-bin/koha/acqui/edimsg.pl?id=[% order.invoice.message_id | uri %]" title="EDI INVOICE message">EDI message</a></div>
576 [% IF basket.basketgroupid %]
577 [% SET basket_group = basket.basket_group %]
578 [% IF CAN_user_acquisition_group_manage %]
579 <a href="/cgi-bin/koha/acqui/basketgroup.pl?op=add&booksellerid=[% vendor.id | uri %]&basketgroupid=[% basket_group.id | uri %]">[% basket_group.name | html%] ([% basket_group.id | html %])</a>
581 [% basket_group.name | html %] ([% basket_group.id | html %])
585 <td>[% IF CAN_user_acquisition_order_manage %]
586 <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basket.basketno | uri %]">[% basket.basketname | html %] ([% basket.basketno | html %])</a>
588 [% basket.basketname | html %] ([% basket.basketno | html %])
590 <td>[% order.ordernumber | html %]</td>
591 <td data-order="[% basket.creationdate | uri %]">[% basket.creationdate | $KohaDates%]</td>
592 <td data-order="[% order.datereceived | uri %]">[% order.datereceived | $KohaDates%]</td>
594 [% SWITCH order.orderstatus %]
595 [% CASE 'new' %]<span>New</span>
596 [% CASE 'ordered' %]<span>Ordered</span>
597 [% CASE 'partial' %]<span>Partial</span>
598 [% CASE 'complete' %]<span>Complete</span>
599 [% CASE 'cancelled' %]<span>Cancelled</span>
602 <td>[% order.quantity | html %]</td>
603 <td>[% IF ( order.orderstatus == "complete" ) %][% order.unitprice_tax_included | $Price %][% ELSE %][% order.ecost_tax_included | $Price %][% END %]
604 <td>[% order.order_internalnote | html %]</td>
606 [% IF order.subscriptionid %]
607 <a href="/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=[% order.subscriptionid | uri %]">[% order.subscriptionid | html %]</a>
611 [% IF order.subscriptionid %]
612 [% order.subscription.callnumber | html %]
620 <span class="noorder">There is no order for this bibliographic record.</span>
625 [% IF suggestions.count %]
626 <div role="tabpanel" class="tab-pane" id="suggestion_details">
627 [% IF nb_archived_suggestions > 0 %]
628 <p>[% tnpx('pluralization', 'There is one archived suggestion.', 'There are {count} archived suggestions.', nb_archived_suggestions, { count = nb_archived_suggestions }) | $raw %]
630 <table id="suggestions" class="sorted">
633 <th class="NoSort"> </th>
634 <th class="anti-the">Suggestion</th>
635 <th>Suggested by - on</th>
636 <th>Managed by - on</th>
637 <th>Last modification by - on</th>
644 [% FOREACH suggestion IN suggestions %]
646 <td>[% suggestion.suggestionid | html %]</td>
648 <a href="/cgi-bin/koha/suggestion/suggestion.pl?suggestionid=[% suggestion.suggestionid | uri %]&op=show" title="suggestion" >
649 [% suggestion.title | html %][% IF ( suggestion.author ) %], by [% suggestion.author | html %][% END %]</a>
651 [% IF ( suggestion.copyrightdate ) %]© [% suggestion.copyrightdate | html %] [% END %]
652 [% IF ( suggestion.volumedesc ) %]; Volume:<em>[% suggestion.volumedesc | html %]</em> [% END %]
653 [% IF ( suggestion.isbn ) %]; ISBN:<em>[% suggestion.isbn | html %]</em> [% END %][% IF ( suggestion.publishercode ) %]; Published by [% suggestion.publishercode | html %] [% END %][% IF ( suggestion.publicationyear ) %] in <em>[% suggestion.publicationyear | html %]</em> [% END %][% IF ( suggestion.place ) %] in <em>[% suggestion.place | html %]</em> [% END %][% IF ( suggestion.collectiontitle ) %]; [% suggestion.collectiontitle | html %] [% END %][% IF ( suggestion.itemtype ) %]; [% AuthorisedValues.GetByCode( 'SUGGEST_FORMAT', suggestion.itemtype, 0 ) | html %] [% END %]<br />[% IF ( suggestion.note ) %]<div class="suggestion_note"><i class="fa fa-comment"></i> [% suggestion.note | html %]</div>[% END %]
656 <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.suggestedby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.suggester %]</a>
657 [% IF suggestion.suggesteddate %] - [% suggestion.suggesteddate | $KohaDates %][% END %]
660 <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.managedby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.manager %]</a>
661 [% IF suggestion.manageddate %] - [% suggestion.manageddate | $KohaDates %][% END %]
664 <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.lastmodificationby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.last_modifier %]</a>
665 [% IF suggestion.lastmodificationdate %] - [% suggestion.lastmodificationdate | $KohaDates %][% END %]
668 [% Branches.GetName( suggestion.branchcode ) | html %]
671 [% suggestion.fund.budget_name | html %]
674 [% IF suggestion.STATUS == 'ASKED' %]<span>Pending</span>
675 [% ELSIF suggestion.STATUS == 'ACCEPTED' %]<span>Accepted</span>
676 [% ELSIF suggestion.STATUS == 'ORDERED' %]<span>Ordered</span>
677 [% ELSIF suggestion.STATUS == 'REJECTED' %]<span>Rejected</span>
678 [% ELSIF suggestion.STATUS == 'CHECKED' %]<span>Checked</span>
679 [% ELSIF suggestion.STATUS == 'AVAILABLE' %]<span>Available</span>
680 [% ELSIF AuthorisedValues.GetByCode( 'SUGGEST_STATUS', suggestion.STATUS ) %]
681 [% AuthorisedValues.GetByCode( 'SUGGEST_STATUS', suggestion.STATUS ) | html %]
682 [% ELSE %]<span>Status unknown</span>
684 [% IF suggestion.reason %]
685 <br />([% suggestion.reason | html %])
695 [% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]
696 <div role="tabpanel" class="tab-pane" id="editions"><h4>Editions</h4>
698 [% FOREACH XISBN IN XISBNS %]<tr>[% IF ( AmazonCoverImages ) %]<td><a href="http://www.amazon.com/gp/reader/[% XISBN.normalized_isbn | uri %][% AmazonAssocTag | uri %]#reader-link"><img src="https://images-na.ssl-images-amazon.com/images/P/[% XISBN.normalized_isbn | html %].01._AA75_PU_PU-5_.jpg" /></a></td>[% END %]
699 [% IF ( !item_level_itypes || Koha.Preference('BiblioItemtypeInfo') ) %]<td>[% IF ( noItemTypeImages ) %]<span class="itypetext">[% XISBN.description | html %]</span>[% ELSE %]<img src="[% XISBN.imageurl | html %]" alt="[% XISBN.description | html %]" title="[% XISBN.description | html %]">[% END %]</td>[% END %]
700 <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% XISBN.biblionumber | uri %]">[% XISBN.title | html %]</a> <span>by</span> [% XISBN.author | html %] ©[% XISBN.copyrightdate | html %]
701 [% IF ( XISBN.publishercode ) %]
702 [% XISBN.publishercode | html %] [% IF ( XISBN.place ) %]([% XISBN.place | html %])[% END %] [% IF ( XISBN.publicationyear ) %], [% XISBN.publicationyear | html %][% END %] [% IF ( XISBN.editionstatement ) %][% XISBN.editionstatement | html %][% END %] [% IF ( XISBN.editionresponsibility ) %][% XISBN.editionresponsibility | html %][% END %]
704 [% IF ( XISBN.pages ) %] [% END %][% XISBN.pages | html %] [% IF ( XISBN.illus ) %][% XISBN.illus | html %][% END %]
705 [% IF ( XISBN.size ) %], [% END %][% XISBN.size | html %]
709 </table></div>[% END %]
712 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
713 <div role="tabpanel" class="tab-pane" id="concerns">
714 <fieldset class="action" style="cursor:pointer;">
715 <a id="hideResolved"><i class="fa fa-minus-square"></i> Hide resolved</a>
716 | <a id="showAll"><i class="fa fa-bars"></i> Show all</a>
719 <table id="table_concerns" width="100%">
725 <th data-class-name="actions noExport">Actions</th>
732 [% IF ( LocalCoverImages ) %]
733 <div role="tabpanel" class="tab-pane" id="images">
734 [% IF localimages.count %]
735 <p>Click on an image to view it in the image viewer</p>
736 <ul class="thumbnails">
737 [% FOREACH image IN localimages %]
739 <li id="imagenumber-[% image.imagenumber | html %]" class="thumbnail">
740 <a href="/cgi-bin/koha/catalogue/imageviewer.pl?biblionumber=[% biblionumber | uri %]&imagenumber=[% image.imagenumber | uri %]">
741 <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&imagenumber=[% image.imagenumber | uri %]" />
743 [% IF CAN_user_tools_upload_local_cover_images %]
744 <a href="#" class="remove"><i class="fa fa-trash-can"></i> Delete image</a>
750 [% ELSE # - No image passed JavaScript takes care %]
751 <span class="noimagesuploaded">No images have been uploaded for this bibliographic record yet.</span>
753 [% IF ( CAN_user_tools_upload_local_cover_images ) %]
754 <p>Upload an image file: <a class="btn btn-default btn-xs" href="/cgi-bin/koha/tools/upload-cover-image.pl?biblionumber=[% biblionumber | uri %]&filetype=image"><i class="fa fa-upload" aria-hidden="true"></i> Upload</a>
760 [% IF ( HTML5MediaEnabled ) %]
761 <div role="tabpanel" class="tab-pane" id="html5media">
762 [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
764 [% IF HTML5MediaSet.is_youtube %]
765 <iframe id="player" width="640" height="360" src="[% HTML5MediaSet.srcblock | url %]"></iframe>
767 <[% HTML5MediaParent | html %] controls preload=none>
768 <[% HTML5MediaSet.child | html %] src="[% HTML5MediaSet.srcblock | url %]"[% HTML5MediaSet.typeblock | html %] />
769 [[% HTML5MediaParent | html %] tag not supported by your browser.]
770 </[% HTML5MediaParent | html %]>
778 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'tab' ) %]
779 <div role="tabpanel" class="tab-pane" id="NovelistSelect" class="novelistSelect">
780 <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
784 [% FOREACH plugins_intranet_catalog_biblio_tab IN plugins_intranet_catalog_biblio_tabs %]
785 <div role="tabpanel" class="tab-pane" id="[% plugins_intranet_catalog_biblio_tab.id | html %]">
786 [% plugins_intranet_catalog_biblio_tab.content | $raw %]
790 </div><!-- /tab-content -->
791 </div><!-- /bibliodetails -->
793 <div id="export" style="margin-top: 1em;">
794 <form method="get" action="/cgi-bin/koha/catalogue/export.pl">
796 <th>Save record</th> </tr>
797 <tr><td> Select download format: <select name="format">
798 <option value="mods">MODS (XML)</option>
799 <option data-toggle="modal" data-target="#exportModal_">Dublin Core</option>
800 <option value="marcxml">MARCXML</option>
801 <option value="marc8">MARC (non-Unicode/MARC-8)</option>
802 <option value="utf8">MARC (Unicode/UTF-8)</option> </select>
803 <input type="submit" name="save" class="btn btn-primary" value="Download record" /></td>
806 <input type="hidden" name="op" value="export" /><input type="hidden" name="bib" value="[% biblionumber | html %]" />
812 <div id="marcPreview" class="modal" tabindex="-1" role="dialog" aria-labelledby="marcPreviewLabel" aria-hidden="true">
813 <div class="modal-dialog modal-lg">
814 <div class="modal-content">
815 <div class="modal-header">
816 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
817 <h3 id="marcPreviewLabel">MARC preview</h3>
819 <div class="modal-body">
820 <div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
822 <div class="modal-footer">
823 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
829 <div id="elasticPreview" class="modal" tabindex="-1" role="dialog" aria-labelledby="elasticPreviewLabel" aria-hidden="true">
830 <div class="modal-dialog modal-lg">
831 <div class="modal-content">
832 <div class="modal-header">
833 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
834 <h3 id="elasticPreviewLabel">Elasticsearch record</h3>
836 <div class="modal-body">
837 <div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
839 <div class="modal-footer">
840 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
847 </div> <!-- /.col-sm-10.col-sm-push-2 -->
849 <div class="col-sm-2 col-sm-pull-10">
851 [% INCLUDE 'biblio-view-menu.inc' %]
853 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
854 </div> <!-- /.row -->
858 <div class="modal fade" id="modal-item-group-create" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-create-label">
859 <div class="modal-dialog">
860 <div class="modal-content">
861 <div class="modal-header">
862 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
863 <h3 id="modal-item-group-create-label"><i class="fa fa-plus"></i> Create a new item group</h3>
865 <form method="get" id="modal-item-group-create-form" class="validated">
866 <div class="modal-body">
869 <label for="item_group_description" class="required">Name: </label>
870 <input name="description" id="modal-item-group-create-form-description" type="text" size="30" required="required" class="required" />
871 <span class="required">Required</span>
874 <label for="item_group_display_order" class="required">Display order: </label>
875 <input name="display_order" id="modal-item-group-create-form-display_order" value="0" size="5" required="required" class="required" />
876 <span class="required">Required</span>
878 <span class="hint">Numbers only, item groups will be displayed in counting order</span>
882 <div class="modal-footer">
883 <button id="modal-item-group-create-submit" class="btn btn-default"><i class="fa fa-plus"></i> Submit</button>
884 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
891 <div class="modal fade" id="modal-item-group-edit" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-edit-label">
892 <div class="modal-dialog">
893 <div class="modal-content">
894 <div class="modal-header">
895 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
896 <h3 id="modal-item-group-edit-label"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit item group</h3>
898 <form method="get" id="modal-item-group-edit-form" class="validated">
899 <div class="modal-body">
902 <label for="item_group_description" class="required">Name: </label>
903 <input name="description" id="modal-item-group-edit-form-description" type="text" size="30" required="required" class="required" />
904 <span class="required">Required</span>
907 <label for="item_group_display_order" class="required">Sort order: </label>
908 <input name="display_order" id="modal-item-group-edit-form-display_order" size="5" />
909 <span class="hint">Numbers only, item groups will be displayed in counting order</span>
913 <div class="modal-footer">
914 <button id="modal-item-group-edit-submit" class="btn btn-default"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Submit</button>
915 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
922 <div class="modal fade" id="modal-item-group-delete" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-delete-label">
923 <div class="modal-dialog">
924 <div class="modal-content">
925 <div class="modal-header">
926 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
927 <h3 id="modal-item-group-delete-label"><i class='fa fa-trash-can'></i> Delete item group</h3>
929 <div class="modal-body">
930 Are you sure you want to delete this item group?
932 <div class="modal-footer">
933 <button id="modal-item-group-delete-submit" class="btn btn-danger"><i class='fa fa-trash-can'></i> Delete</button>
934 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
940 <div class="modal fade" id="modal-item-group-set" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-set-label">
941 <div class="modal-dialog">
942 <div class="modal-content">
943 <div class="modal-header">
944 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
945 <h3 id="modal-item-group-set-label"><i class='fa fa-book'></i> Set item group for items</h3>
947 <form method="get" id="modal-item-group-set-form" class="validated">
948 <div class="modal-body">
951 <label for="item_group" class="required">Item group: </label>
952 <select name="item_group" id="item-group-add-form-select">
953 [% FOREACH ig IN biblio.item_groups.search({}, {order_by => 'display_order'}) %]
954 <option value="[% ig.id | html %]">[% ig.description | html %]</option>
957 <span class="required">Required</span>
961 <div class="modal-footer">
962 <button id="modal-item-group-set-submit" class="btn btn-default"><i class='fa fa-book'></i> Set item group</button>
963 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
970 <div class="modal fade" id="modal-item-group-unset" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-unset-label">
971 <div class="modal-dialog">
972 <div class="modal-content">
973 <div class="modal-header">
974 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
975 <h3 id="modal-item-group-unset-label"><i class='fa fa-unlink'></i> Remove item from item group</h3>
977 <div class="modal-body">
978 Are you sure you want to remove these item(s) from their item group(s)?
980 <div class="modal-footer">
981 <button id="modal-item-group-unset-submit" class="btn btn-danger"><i class='fa fa-unlink'></i> Remove</button>
982 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
988 [% IF bundlesEnabled %]
989 <div class="modal" id="addToBundleModal" tabindex="-1" role="dialog" aria-labelledby="addToBundleLabel">
990 <form method="get" id="addToBundleForm" action="">
991 <div class="modal-dialog" role="document">
992 <div class="modal-content">
993 <div class="modal-header">
994 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
995 <h3 id="addToBundleLabel">Add to bundle</h3>
997 <div class="modal-body">
998 <div id="addResult"></div>
999 <fieldset class="rows">
1002 <label class="required" for="external_id">Item barcode: </label>
1003 <input type="text" id="external_id" name="external_id" required="required">
1004 <span class="required">Required</span>
1009 <div class="modal-footer">
1010 <button type="submit" class="btn btn-default">Submit</button>
1011 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1018 <div class="modal" id="removeFromBundleModal" tabindex="-1" role="dialog" aria-labelledby="removeFromBundleLabel">
1019 <form method="get" id="removeFromBundleForm" action="">
1020 <div class="modal-dialog" role="document">
1021 <div class="modal-content">
1022 <div class="modal-header">
1023 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1024 <h3 id="removeFromBundleLabel">Remove from bundle</h3>
1026 <div class="modal-body">
1027 <div id="removeResult"></div>
1028 <fieldset class="rows">
1031 <label class="required" for="external_id">Item barcode: </label>
1032 <input type="text" id="rm_external_id" name="external_id" required="required">
1033 <span class="required">Required</span>
1038 <div class="modal-footer">
1039 <button type="submit" class="btn btn-default">Submit</button>
1040 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1048 [% IF ( Koha.Preference('CatalogConcerns') ) %]
1049 [% INCLUDE 'modals/add_catalog_concern.inc' %]
1052 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
1053 [% INCLUDE 'modals/display_ticket.inc' %]
1056 [% MACRO jsinclude BLOCK %]
1057 [% INCLUDE 'catalog-strings.inc' %]
1058 [% INCLUDE 'calendar.inc' %]
1059 [% INCLUDE 'select2.inc' %]
1060 [% INCLUDE 'js-date-format.inc' %]
1061 [% Asset.js("js/catalog.js") | $raw %]
1062 [% Asset.js("js/recalls.js") | $raw %]
1063 [% Asset.js("js/coce.js") | $raw %]
1064 [% Asset.js("lib/Chocolat/js/chocolat.js") | $raw %]
1065 [% IF ( Koha.Preference('CatalogConcerns') ) %]
1067 /* Set a variable needed by add_catalog_concern.js */
1068 var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
1070 [% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
1072 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
1074 $(document).ready(function() {
1075 var table_settings = [% TablesSettings.GetTableSettings( 'cataloguing', 'concerns', 'table_concerns', 'json' ) | $raw %];
1077 var filtered = false;
1078 let additional_filters = {
1079 resolved_date: function(){
1081 return { "=": null };
1086 biblio_id: [% biblionumber | uri %]
1089 var tickets_url = '/api/v1/tickets';
1090 var tickets = $("#table_concerns").kohaTable({
1099 'emptyTable': '<div class="dialog message">' + _("Congratulations, there are no catalog concerns.") + '</div>',
1102 "render": function (data, type, row, meta) {
1103 if ( type == 'display' ) {
1104 if ( data != null ) {
1105 return data.escapeHtml();
1116 "data": "reported_date:reporter.firstname",
1117 "render": function(data, type, row, meta) {
1118 let reported = '<span class="date clearfix">' + $datetime(row.reported_date) + '</span>';
1119 reported += '<span class="reporter clearfix">' + $patron_to_html(row.reporter, {
1120 display_cardnumber: false,
1129 "data": "title:body",
1130 "render": function(data, type, row, meta) {
1131 let resolved = ( row.resolved_date ) ? true : false;
1132 let result = '<a role="button" href="#" data-toggle="modal" data-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '" data-resolved="' + resolved + '">' + row.title + '</a>';
1133 if (row.updates_count) {
1134 result += '<span class="pull-right"><a role="button" href="#" data-toggle="modal" data-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '"><i class="fa fa-comment" aria-hidden="true"></i> ' + row.updates_count + '</a></span>';
1136 result += '<div id="detail_' + row.ticket_id + '" class="hidden">' + row.body + '</div>';
1143 "data": "resolved_date",
1144 "render": function(data, type, row, meta) {
1146 if (row.resolved_date) {
1147 result += _("Resolved by:") + ' <span>' + $patron_to_html(row.resolver, {
1148 display_cardnumber: false,
1151 result += '<span class="clearfix">' + $datetime(row.resolved_date) + '</span>';
1153 result += _("Open");
1161 "data": function(row, type, val, meta) {
1162 let resolved = ( row.resolved_date ) ? true : false;
1163 let result = '<a class="btn btn-default btn-xs" role="button" href="#" data-toggle="modal" data-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '" data-resolved="' + resolved + '"><i class="fa-solid fa-eye" aria-hidden="true"></i> ' + _("Details") + '</a>';
1166 "searchable": false,
1170 }, table_settings, 0, additional_filters);
1172 $('#hideResolved').on("click", function() {
1174 tickets.DataTable().draw();
1177 $('#showAll').on("click", function() {
1179 tickets.DataTable().draw();
1183 [% Asset.js("js/modals/display_ticket.js") | $raw %]
1186 var interface = "[% interface | html %]";
1187 var theme = "[% theme | html %]";
1188 // http://www.oreillynet.com/pub/a/javascript/2003/10/21/amazonhacks.html
1189 function verify_cover_images() {
1190 // Loop over each container in the template which contains covers
1191 $(".cover-slider").each(function(){
1192 var lightbox_descriptions = [];
1193 var first_shown = 0;
1194 $(this).find(".cover-image").each( function( index ){
1196 // Find the image in the container
1197 var img = div.find("img")[0];
1198 if( $(img).length > 0 ){
1199 var description = "";
1200 // All slides start hidden. If this is the first one, show it.
1201 if( first_shown == 0 ){
1205 // Check if Amazon image is present
1206 if ( div.attr("id") == "amazon-bookcoverimg" ) {
1209 if ((w == 1) || (h == 1)) {
1210 // Amazon returned single-pixel placeholder
1211 // Remove the container
1214 lightbox_descriptions.push(_("Amazon cover image (<a href='%s'>see the original image</a>)").format($(img).data('link')));
1216 } else if( div.attr("id") == "custom-coverimg" ){
1217 if ( (img.complete != null) && (!img.complete) || img.naturalHeight == 0 ) {
1218 // No image was loaded via the CustomCoverImages system preference
1219 // Remove the container
1222 lightbox_descriptions.push( _("Custom cover image") );
1224 } else if ( div.attr("id") == "syndetics-bookcoverimg" ){
1225 lightbox_descriptions.push(_("Syndetics cover image (<a href='%s'>see the original image</a>)").format($(img).data('link')));
1227 else if( div.hasClass("coce-coverimg" ) ){
1228 // Identify which service's image is being loaded by Coce
1229 var coce_description;
1230 if( $(img).attr("src").indexOf('amazon.com') >= 0 ){
1231 coce_description = _("Coce image from Amazon.com");
1232 } else if( $(img).attr("src").indexOf('google.com') >= 0 ){
1233 coce_description = _("Coce image from Google Books");
1234 } else if( $(img).attr("src").indexOf('openlibrary.org') >= 0 ){
1235 coce_description = _("Coce image from Open Library");
1237 div.find(".hint").html(coce_description);
1238 lightbox_descriptions.push(coce_description);
1239 } else if ( div.attr("class") == "cover-image local-coverimg" ) {
1240 lightbox_descriptions.push(_("Local cover image (<a href='%s'>edit</a>)").format($(img).data('link')));
1242 lightbox_descriptions.push(_("Cover image source unknown"));
1247 // Lightbox for cover images
1248 Chocolat(this.querySelectorAll('.cover-image a'), {
1249 description: function(){
1250 return lightbox_descriptions[this.settings.currentImageIndex];
1256 $(".cover-slider").each(function(){
1257 var coverSlide = this;
1258 var coverImages = $(this).find(".cover-image");
1259 if( coverImages.length > 1 ){
1260 coverImages.each(function( index ){
1261 // If more that one image is present, add a navigation link
1262 // for activating the slide
1263 var covernav = $("<a href=\"#\" data-num=\"" + index + "\" class=\"cover-nav\"></a>");
1265 // Set the first navigation link as active
1266 $(covernav).addClass("nav-active");
1268 $(covernav).html("<i class=\"fa fa-circle\"></i>");
1269 $(coverSlide).append( covernav );
1273 if( $(coverSlide).attr('id') == 'biblio-cover-slider' // Hide if not visible, but only for the biblio images. Images for items are only local cover images
1274 && $(coverSlide).find(".cover-image:visible").length < 1 ){
1275 $(coverSlide).remove();
1277 $(coverSlide).addClass("cover-slides");
1278 var img = $(coverSlide).find(".cover-image:visible").find("img")[0];
1279 if( $(img).length > 0 && img.complete && img.naturalHeight > 0 ){
1280 $(".cover-slides").css({"background-image":"none"});
1285 $("#editions img").each(function(i){
1286 if ( this.src.indexOf('amazon.com') >= 0 ) {
1289 if ((w == 1) || (h == 1)) {
1290 this.src = 'https://images-na.ssl-images-amazon.com/images/G/01/x-site/icons/no-img-sm.gif';
1291 } else if ( (this.complete != null) && (!this.complete) || this.naturalHeight == 0 ) {
1292 this.src = 'https://images-na.ssl-images-amazon.com/images/G/01/x-site/icons/no-img-sm.gif';
1298 function removeLocalImage(imagenumber) {
1299 var thumbnail = $("#imagenumber-" + imagenumber );
1300 var copy = thumbnail.html();
1301 thumbnail.find("img").css("opacity", ".2");
1302 thumbnail.find("a.remove").html("<img style='display:inline-block' src='" + interface + "/" + theme + "/img/spinner-small.gif' alt='' />");
1303 const client = APIClient.cover_image;
1304 client.cover_images.delete(imagenumber).then(
1306 if ( success.deleted == 1 ) {
1309 thumbnail.html( copy );
1310 alert(_("An error occurred on deleting this image"));
1312 if ( $('ul.thumbnails > li').length == 0 ) {
1313 showNoImageMessage();
1317 thumbnail.html( copy );
1318 alert(_("An error occurred on deleting this image"));
1319 console.warn("Something wrong happened: %s".format(error));
1324 function showNoImageMessage() {
1325 var no_images_msg = _("No images have been uploaded for this bibliographic record yet.");
1326 no_images_msg = '<p>' + no_images_msg + '</p>';
1327 [% IF ( CAN_user_tools_upload_local_cover_images ) %]
1328 var please_upload = _("Upload an image file: %sUpload%s").format("<a class='btn btn-default btn-xs' href='/cgi-bin/koha/tools/upload-cover-image.pl?biblionumber=" + biblionumber + "&filetype=image'><i class='fa fa-upload' aria-hidden='true'></i> ","</a>");
1329 no_images_msg += "<p id='upload_image'>" + please_upload + '</p>';
1331 $('#images').html(no_images_msg);
1334 [% IF StaffDetailItemSelection %]
1336 let items_selection = {};
1337 function itemSelectionBuildDeleteLink(tab_id) {
1338 var itemnumbers = items_selection[tab_id];
1339 if (itemnumbers.length > 0) {
1340 var url = '/cgi-bin/koha/tools/batchMod.pl?op=show&del=1';
1341 url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
1342 url += '&biblionumber=[% biblionumber | uri %]';
1343 url += '&src=CATALOGUING';
1344 $('a.itemselection_action_delete').attr('href', url);
1351 function itemSelectionBuildModifyLink(tab_id) {
1352 var itemnumbers = items_selection[tab_id];
1353 if (itemnumbers.length > 0) {
1354 var url = '/cgi-bin/koha/tools/batchMod.pl?op=show';
1355 url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
1356 url += '&biblionumber=[% biblionumber | uri %]';
1357 url += '&src=CATALOGUING';
1358 $('a.itemselection_action_modify').attr('href', url);
1365 function itemSelectionBuildActionLinks(tab_id) {
1366 var delete_link_ok = itemSelectionBuildDeleteLink(tab_id);
1367 var modify_link_ok = itemSelectionBuildModifyLink(tab_id);
1368 var div = $("#" + tab_id);
1369 if (modify_link_ok || delete_link_ok) {
1370 $('.itemselection_actions', div).show();
1372 $('.itemselection_actions', div).hide();
1376 $(document).ready(function() {
1378 $(".SelectAll").on("click",function(e){
1380 var tab = $(this).data("tab");
1381 $("input[name='itemnumber'][type='checkbox']", $("#"+tab)).prop('checked', true);
1382 itemSelectionBuildActionLinks(tab);
1385 $(".ClearAll").on("click",function(e){
1387 var tab = $(this).data("tab");
1388 $("input[name='itemnumber'][type='checkbox']", $("#"+tab)).prop('checked', false);
1389 itemSelectionBuildActionLinks(tab);
1392 $(".show_filters").on("click",function(e){
1394 let tab_id = $(this).data("tab");
1395 let tab = $("#"+tab_id);
1396 tab.find(".show_filters").hide();
1397 tab.find(".hide_filters").show();
1398 $("#"+tab_id+"_table thead tr:eq(1)").remove();
1399 build_items_table(tab_id, true, { dom: dataTablesDefaults.dom, destroy: true } );
1402 $(".hide_filters").on("click",function(e){
1404 let tab_id = $(this).data("tab");
1405 let tab = $("#"+tab_id);
1406 tab.find(".hide_filters").hide();
1407 tab.find(".show_filters").show();
1408 $("#"+tab_id+"_table thead tr:eq(1)").remove();
1409 build_items_table(tab_id, false, { dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>', destroy: true } );
1414 $(document).ready(function() {
1415 // Pick details tab to display by default
1417 [% IF ( Koha.Preference('HTML5MediaEnabled') == 'staff' or Koha.Preference('HTML5MediaEnabled') == 'both' ) && HTML5MediaSets.size %]
1418 $(".nav-tabs a[href='#html5media']").tab("show");
1419 [% ELSIF ComponentParts && ComponentParts.size %]
1420 $(".nav-tabs a[href='#components']").tab("show");
1422 $(".nav-tabs a[href='#holdings']").tab("show");
1425 $(".nav-tabs a[href='#holdings']").tab("show");
1427 $('#search-form').focus();
1428 $('.thumbnails > li > .remove').click(function() {
1429 var result = confirm(_("Are you sure you want to delete this cover image?"));
1431 if ( result == true ) {
1432 var imagenumber = $(this).parent().attr('id').split('-')[1];
1433 removeLocalImage(imagenumber);
1438 [% IF ( IntranetCoce && CoceProviders ) %]
1439 KOHA.coce.getURL('[% CoceHost | html %]', '[% CoceProviders | html %]');
1442 $("body").on("click",".previewMARC", function(e){
1444 var page = $(this).attr("href");
1445 $("#marcPreview .modal-body").load(page + " table");
1446 $('#marcPreview').modal({show:true});
1450 [% IF ( Koha.Preference('SearchEngine') == 'Elasticsearch' ) %]
1451 $("body").on("click",".previewElastic", function(e){
1453 var pageElastic = $(this).attr("href");
1454 $("#elasticPreview .modal-body").load(pageElastic, function( response, status, xhr ) {
1455 if( status == 'error' ){
1456 $("#elasticPreview .modal-body").html("<h1>"+_("An error has occurred!")+"</h1><h2><em>"+_("Error 404")+"</em></h2><ul><li>"+_("An internal link in the staff interface is broken and the page does not exist")+"</li></ul><h3>"+_("What's next?")+"</h3><ul style='margin-bottom: 1em; padding-bottom: 1em; border-bottom: 1px solid #CCC;'><li>"+_("Use top menu bar to navigate to another part of Koha.")+"</li><li>"+_("To report a broken link or any other issue, please contact the Koha administrator.")+" <a href='mailto:[% Koha.Preference("KohaAdminEmailAddress") | uri %]'>"+_("Send email")+"</a></li></ul>");
1459 $('#elasticPreview').modal({show:true});
1463 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && ( normalized_isbn || normalized_upc ) ) %]
1464 novSelect.loadContentForQuery({
1465 ClientIdentifier : '[% IF normalized_isbn %][% normalized_isbn | html %][% ELSE %][% normalized_upc | html %][% END %]',
1466 ISBN : '[% IF normalized_isbn %][% normalized_isbn | html %][% ELSE %][% normalized_upc | html %][% END %]',
1469 '[% Koha.Preference('NovelistSelectStaffProfile') | html %]',
1470 '[% Koha.Preference('NovelistSelectPassword') | html %]',
1472 if ( d.length > 0 ){ //If no content
1473 $(".NovelistSelect").show();
1477 $(".print-label").on("click", function(e){
1479 link = $(this).attr("href");
1480 openWindow(link,"Print spine label",400,400);
1482 $(".cover-slider").on("click",".cover-nav", function(e){
1484 var cover_slider = $(this).parent();
1485 // Adding click handler for cover image navigation links
1486 var num = $(this).data("num");
1487 $(cover_slider).find(".cover-nav").removeClass("nav-active");
1488 $(this).addClass("nav-active");
1489 $(cover_slider).find(".cover-image").hide();
1490 $(cover_slider).find(".cover-image").eq( num ).show();
1495 [% IF ( IntranetCoce && CoceProviders ) %]
1496 let counter_wait = 0;
1497 function wait_for_images(cb){
1503 loaded = KOHA.coce.done;
1506 if (!loaded && counter_wait < 50) {// Do not wait more than 5 seconds
1507 window.setTimeout(function(){wait_for_images(cb);}, 100);
1509 if (counter_wait >= 50 ) {
1510 console.log("Could not retrieve the images")
1516 $(window).load(function() {
1517 wait_for_images(verify_cover_images);
1520 $(window).load(function() {
1521 verify_cover_images();
1525 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && ( normalized_isbn || normalized_upc ) ) %]
1526 <script src="https://imageserver.ebscohost.com/novelistselect/ns2init.js"></script>
1528 [% INCLUDE 'datatables.inc' %]
1529 [% Asset.js("lib/jquery/plugins/jquery.dataTables.columnFilter.js") | $raw %]
1530 [% INCLUDE 'columns_settings.inc' %]
1531 [% INCLUDE 'js-date-format.inc' %]
1532 [% INCLUDE 'js-patron-format.inc' %]
1533 [% INCLUDE 'js-biblio-format.inc' %]
1534 [% Asset.js("js/browser.js") | $raw %]
1535 [% Asset.js("js/table_filters.js") | $raw %]
1536 [% Asset.js("js/place_booking_modal.js") | $raw %]
1539 browser = KOHA.browser('[% searchid | html %]', parseInt(biblionumber, 10));
1542 [% IF bundlesEnabled %]
1543 var bundle_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail','bundle_tables','json') | $raw %];
1544 var bundle_lost_value = [% Koha.Preference('BundleLostValue') | html %];
1547 $(document).ready(function() {
1549 [% IF bundlesEnabled %] // Bundle handling
1550 function createChild ( row, itemnumber, duedate ) {
1553 var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1554 bundle_toolbar.append('<a class="btn btn-default" data-toggle="modal" data-target="#addToBundleModal" data-item="' + itemnumber + '"><i class="fa fa-plus"></i> ' + _("Add to bundle") + '</a>');
1555 bundle_toolbar.append('<a class="btn btn-default" data-toggle="modal" data-target="#removeFromBundleModal" data-item="' + itemnumber + '"><i class="fa fa-minus"></i> ' + _("Remove from bundle") + '</a>');
1557 // Disable management if there's a duedate
1559 bundle_toolbar.children('.btn').addClass("disabled");
1560 bundle_toolbar.attr("title", _("This bundle is checked out, it cannot be modified"));
1563 // This is the table we'll convert into a DataTable
1564 var bundles_table = $('<table class="display tbundle" data-itemnumber="'+itemnumber+'" id="bundle_table_'+itemnumber+'" width="100%"/>');
1566 // Display it the child row
1567 row.child( bundle_toolbar.add(bundles_table), 'bundle' ).show();
1569 // Initialise as a DataTable
1570 var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?";
1571 var bundle_table = bundles_table.kohaTable({
1573 "url": bundle_table_url
1577 "return_claim.patron"
1579 "order": [[ 1, "asc" ]],
1581 "targets": [0,1,2,3],
1582 "render": function (data, type, row, meta) {
1583 if ( data && type == 'display' ) {
1584 return data.escapeHtml();
1591 "data": "biblio.title:biblio.subtitle:biblio.medium",
1592 "title": _("Title"),
1595 "render": function(data, type, row, meta) {
1596 return $biblio_to_html(row.biblio, { link: 1 });
1600 "data": "biblio.author",
1601 "title": _("Author"),
1606 "data": "callnumber",
1607 "title": _("Callnumber"),
1612 "data": "external_id",
1613 "title": _("Barcode"),
1618 "data": "lost_status:last_seen_date:return_claim.patron",
1619 "title": _("Status"),
1620 "searchable": false,
1622 "render": function(data, type, row, meta) {
1623 if ( row.lost_status == bundle_lost_value ) {
1624 let out = '<span class="lost">' + _("Last seen") + ': ' + $date(row.last_seen_date) + '</span>';
1625 if ( row.return_claim ) {
1626 out = out + '<span class="claims_return">' + _("Claims returned by") + ': ' + $patron_to_html( row.return_claim.patron, { display_cardnumber: false, url: true } ) + '</span>';
1630 else if ( row.lost_status !== 0 ) {
1631 return '<span class="lost">' + _("Lost") + ': ' + row.lost_status + '</span>';
1633 return '<span class="available">' + _("Present") + '</span>';
1637 "data": function( row, type, val, meta ) {
1640 result = '<button class="btn btn-default btn-xs remove disabled" role="button" data-itemnumber="'+row.item_id+'" title="%s"><i class="fa fa-minus" aria-hidden="true"></i> %s</button>\n'.format(_("This bundle is checked out, it cannot be modified"), _("Remove"));
1642 result = '<button class="btn btn-default btn-xs remove" role="button" data-itemnumber="'+row.item_id+'"><i class="fa fa-minus" aria-hidden="true"></i> '+_("Remove")+'</button>\n';
1646 "title": _("Actions"),
1647 "searchable": false,
1652 }, bundle_settings, 1);
1653 $(".tbundle").on("click", ".remove:not(.disabled)", function(){
1654 var bundle_table = $(this).closest('table');
1655 var host_itemnumber = bundle_table.data('itemnumber');
1656 var component_itemnumber = $(this).data('itemnumber');
1657 var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber;
1660 url: unlink_item_url,
1661 success: function(){
1662 bundle_table.DataTable({ 'retrieve': true }).draw(false);
1671 var bundle_form_active;
1672 $("#addToBundleModal").on("shown.bs.modal", function(e){
1673 var button = $(e.relatedTarget);
1674 var item_id = button.data('item');
1675 $("#addResult").replaceWith('<div id="addResult"></div>');
1676 $("#addToBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items');
1677 $("#external_id").focus();
1679 bundle_form_active = item_id;
1682 function addToBundle (url, data) {
1683 /* Send the data using post with external_id */
1684 var posting = $.post({
1686 data: JSON.stringify(data),
1687 contentType: "application/json; charset=utf-8",
1691 const barcode = data.external_id;
1693 /* Report the results */
1694 posting.done(function(data) {
1695 $('#addResult').replaceWith('<div id="addResult" class="alert alert-success">'+_("Success: Added '%s'").format(barcode)+'</div>');
1696 $('#external_id').val('').focus();
1699 posting.fail(function(data) {
1700 if ( data.status === 409 ) {
1701 var response = data.responseJSON;
1702 if ( response.error_code === 'already_bundled' ) {
1703 $('#addResult').replaceWith('<div id="addResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
1704 } else if (response.error_code === 'bundle_checkout_out') {
1705 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
1706 } else if (response.error_code === 'checked_out') {
1707 const button = $('<button type="button">')
1708 .addClass('btn btn-xs')
1709 .text(_("Check in and add to bundle"))
1710 .on('click', function () {
1711 addToBundle(url, { external_id: barcode, force_checkin: true });
1715 .attr('class', 'alert alert-warning')
1716 .append(__x('Warning: Item {barcode} is checked out', { barcode }))
1717 .append(' ', button);
1718 } else if (response.error_code === 'failed_checkin') {
1721 .attr('class', 'alert alert-danger')
1722 .append(__x('Failure: Item {barcode} cannot be checked in', { barcode }))
1723 } else if (response.error_code === 'reserved') {
1724 const button = $('<button type="button">')
1725 .addClass('btn btn-xs')
1726 .text(_("Ignore holds and add to bundle"))
1727 .on('click', function () {
1728 addToBundle(url, { external_id: barcode, ignore_holds: true });
1732 .attr('class', 'alert alert-warning')
1733 .append(__x('Warning: Item {barcode} is on hold', { barcode }))
1734 .append(' ', button);
1736 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
1738 } else if ( data.status === 404 ) {
1739 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
1740 } else if ( data.status === 400 ) {
1741 var response = data.responseJSON;
1742 if ( response.error_code === "failed_nesting" ) {
1743 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode)+'</div>');
1745 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
1748 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
1750 $('#external_id').val('').focus();
1754 $("#addToBundleForm").submit(function(event) {
1755 /* stop form from submitting normally */
1756 event.preventDefault();
1758 const url = this.action;
1759 const data = { external_id: this.elements.external_id.value };
1761 addToBundle(url, data);
1764 $("#addToBundleModal").on("hidden.bs.modal", function(e){
1765 if ( bundle_changed ) {
1766 $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
1768 bundle_form_active = 0;
1772 $("#removeFromBundleModal").on("shown.bs.modal", function(e){
1773 var button = $(e.relatedTarget);
1774 var item_id = button.data('item');
1775 $("#removeResult").replaceWith('<div id="removeResult"></div>');
1776 $("#removeFromBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items/');
1777 $("#rm_external_id").focus();
1779 bundle_form_active = item_id;
1782 $("#removeFromBundleForm").submit(function(event) {
1784 /* stop form from submitting normally */
1785 event.preventDefault();
1787 /* get the action attribute from the <form action=""> element */
1788 var $form = $(this),
1789 url = $form.attr('action');
1791 var barcode = $('#rm_external_id').val();
1793 /* Fetch itemnumber using rm_external_id */
1794 var itemReq = $.get('/api/v1/items', { q: JSON.stringify({
1795 external_id: barcode
1796 }) }, null, "json");
1799 itemReq.done(function(data) {
1800 if (data.length === 1) {
1801 itemnumber = data[0].item_id;
1803 /* Remove link using fetch itemnumber */
1804 var deleteReq = $.ajax( url + itemnumber, {
1808 /* Report the results */
1809 deleteReq.done(function(data) {
1810 var barcode = $('#rm_external_id').val();
1811 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-success">'+_("Success: Removed '%s'").format(barcode)+'</div>');
1812 $('#rm_external_id').val('').focus();
1815 deleteReq.fail(function(data) {
1816 var barcode = $('#rm_external_id').val();
1817 if ( data.status === 409 ) {
1818 var response = data.responseJSON;
1819 if (response.error_code === 'bundle_checkout_out') {
1820 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
1821 } else if ( response.key === "PRIMARY" ) {
1822 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
1824 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
1826 } else if ( data.status === 404 ) {
1827 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
1829 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Check the logs for details")+'</div>');
1831 $('#rm_external_id').val('').focus();
1834 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Barcode matched more than one item '%s'").format(barcode)+'</div>');
1837 itemReq.fail(function(data) {
1838 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Item not found '%s'").format(barcode)+'</div>');
1839 $('#rm_external_id').val('').focus();
1844 $("#removeFromBundleModal").on("hidden.bs.modal", function(e){
1845 if ( bundle_changed ) {
1846 $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
1848 bundle_form_active = 0;
1851 // End bundle handling
1854 let items_tab_ids = [ 'holdings', 'otherholdings' ];
1855 items_tab_ids.forEach( function( tab_id, index ) {
1856 build_items_table(tab_id, false, { dom: 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>' });
1858 [% IF bundlesEnabled %]
1859 // Add event listener for opening and closing bundle details
1860 $('#' + table_name + ' tbody').on('click', 'button.details-control', function () {
1861 var button = $(this);
1862 var tr = button.closest('tr');
1863 var dTable = button.closest('table').DataTable({ 'retrieve': true });
1865 var itemnumber = tr.data('itemnumber');
1866 var duedate = tr.data('duedate');
1867 var row = dTable.row( tr );
1869 if ( row.child.isShown() ) {
1870 // This row is already open - close it
1872 tr.removeClass('shown');
1873 button.removeClass('active');
1877 createChild(row, itemnumber, duedate);
1878 tr.addClass('shown');
1879 button.addClass('active');
1885 [% IF Koha.Preference('AcquisitionDetails') %]
1886 var table_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail', 'acquisitiondetails-table', 'json') | $raw %];
1887 var acquisitiondetails_table = KohaTable("orders", {
1888 "dom": 'C<"top pager"ilpfB><"#filter_c">tr<"bottom pager"ip>',
1891 "order": [[ 4, "desc" ]],
1895 [% IF suggestions.count %]
1896 $(".sorted").dataTable($.extend(true, {}, dataTablesDefaults, {
1898 { "orderable": false, "searchable": false, "targets": [ 'NoSort' ] },
1899 { "type": "anti-the", "targets": [ "anti-the" ] }
1901 "pagingType": "full"
1907 [% IF found1 && Koha.Preference('RetainCatalogSearchTerms') %]
1908 $(document).ready(function() {
1909 var search_index = localStorage.getItem("cat_search_pulldown_selection");
1910 var search_value = localStorage.getItem("searchbox_value");
1911 if ( search_index ){ $('#cat-search-block select.advsearch').val(search_index)};
1912 if ( search_value ){ $('#cat-search-block #search-form').val(search_value)};
1916 [% IF Koha.Preference('EnableItemGroups') %]
1917 // Load item groups table
1918 var itemGroupsTable = $("#items-group-table").kohaTable({
1920 dom: '<"top pager"ilp>t<"bottom pager"ip>r',
1923 data: "display_order",
1924 title: _("Display order"),
1929 data: "description",
1930 title: _("Description"),
1935 data: function( oObj ) {
1936 [% IF CAN_user_editcatalogue_manage_item_groups %]
1937 return `<button class='item-group-edit btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
1938 <i class="fa-solid fa-pencil" aria-hidden="true"></i> ${_("Edit")}
1941 + `<button class='item-group-delete btn btn-default btn-xs' data-item-group-id='${oObj.item_group_id}'>
1942 <i class='fa fa-trash-can'></i> ${('Delete')}
1953 ajax: { url: `/api/v1/biblios/${biblionumber}/item_groups?_per_page=-1` },
1956 // Create new item groups
1957 $('.item-group-create').on('click', function(){
1958 $('#modal-item-group-create-form-description').val("");
1959 $('#modal-item-group-create-submit').removeAttr('disabled');
1960 $('#modal-item-group-create').modal('show');
1963 $("#modal-item-group-create-form").validate({
1964 submitHandler: function(form) {
1966 url: `/api/v1/biblios/${biblionumber}/item_groups`,
1967 headers: { "x-koha-embed": "items" },
1968 success: function(item_groups){
1969 $('#modal-item-group-create-submit').attr('disabled', 'disabled');
1972 "url": `/api/v1/biblios/${biblionumber}/item_groups`,
1975 "Content-Type": "application/json"
1977 "data": JSON.stringify(
1979 "description": $("#modal-item-group-create-form-description").val(),
1980 "display_order": $("#modal-item-group-create-form-display_order").val(),
1986 .done(function (response) {
1987 $('#item-group-add-form-select').append($('<option>', {
1988 value: response.item_group_id,
1989 text: response.description
1992 $('#modal-item-group-create').modal('hide');
1993 if ( item_groups.length == 0 ) {
1994 // This bib has no previous item groups, reload the page
1995 window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
1997 // Has other item groups, just reload the table
1998 itemGroupsTable.api().ajax.reload();
2001 .fail(function(err) {
2002 var message = err.responseJSON.error;
2010 $('#modal-item-group-create').on('shown.bs.modal', function () {
2011 $('#modal-item-group-create-form-description').focus();
2014 // Edit existing item groups
2015 $('body').on( 'click', '.item-group-edit', function(){
2016 const item_group_id = $(this).data('item-group-id');
2017 const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2018 $.get( url, function( data ) {
2019 $('#modal-item-group-edit-form-description').val( data.description );
2020 $('#modal-item-group-edit-form-display_order').val( data.display_order );
2021 $('#modal-item-group-edit-submit').data('item-group-id', item_group_id );
2022 $('#modal-item-group-edit-submit').removeAttr('disabled');
2023 $('#modal-item-group-edit').modal('show');
2027 $("#modal-item-group-edit-form").validate({
2028 submitHandler: function(form) {
2029 $('#modal-item-group-edit-submit').attr('disabled', 'disabled');
2031 const item_group_id = $('#modal-item-group-edit-submit').data('item-group-id');
2032 const url = `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`;
2038 "Content-Type": "application/json"
2040 "data": JSON.stringify(
2042 "description": $("#modal-item-group-edit-form-description").val(),
2043 "display_order": $("#modal-item-group-edit-form-display_order").val(),
2049 .done(function (response) {
2050 $('#modal-item-group-edit').modal('hide');
2051 itemGroupsTable.api().ajax.reload();
2053 .fail(function(err) {
2054 var message = err.responseJSON.error;
2060 $('#modal-item-group-edit').on('shown.bs.modal', function () {
2061 $('#modal-item-group-edit-form-description').focus();
2064 // Delete existing item groups
2065 $('body').on( 'click', '.item-group-delete', function(){
2066 const item_group_id = $(this).data('item-group-id');
2067 $('#modal-item-group-delete-submit').data('item-group-id', item_group_id );
2068 $('#modal-item-group-delete-submit').removeAttr('disabled');
2069 $('#modal-item-group-delete').modal('show');
2071 $("#modal-item-group-delete-submit").on('click', function(){
2072 $('#modal-item-group-delete-submit').attr('disabled', 'disabled');
2073 const item_group_id = $("#modal-item-group-delete-submit").data('item-group-id');
2076 url: `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2077 headers: { "x-koha-embed": "items" },
2078 success: function(item_group_data){
2080 "url": `/api/v1/biblios/${biblionumber}/item_groups/${item_group_id}`,
2083 .done(function (response) {
2084 $('#modal-item-group-delete').modal('hide');
2085 $(`#item-group-add-form-select option[value='${item_group_id}']`).remove();
2086 if ( item_group_data.items === null ) {
2087 // No items for this item group, we can just refresh the table
2088 itemGroupsTable.api().ajax.reload();
2090 // This item group had items attached to it, we need to reload the page
2091 window.location.replace(`/cgi-bin/koha/catalogue/detail.pl?biblionumber=${biblionumber}`);
2094 .fail(function(err) {
2095 var message = err.responseJSON.error;
2102 // Add item(s) to a item group
2103 $('.itemselection_action_item_group_set').on('click', function(){
2104 $('#modal-item-group-set').modal('show');
2107 $("#modal-item-group-set-form").validate({
2108 submitHandler: function(form) {
2109 $('#modal-item-group-set-submit').attr('disabled', 'disabled');
2111 const item_group_id = $('#item-group-add-form-select').val();
2113 let itemnumbers = new Array();
2114 $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2115 const itemnumber = $(this).val();
2116 itemnumbers.push( itemnumber );
2118 if (itemnumbers.length > 0) {
2119 let url = '/cgi-bin/koha/catalogue/detail.pl?op=set_item_group';
2120 url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2121 url += '&biblionumber=[% biblionumber | uri %]';
2122 url += `&item_group_id=${item_group_id}`;
2124 window.location.replace(url);
2127 $('#modal-item-group-set').modal('hide');
2131 // Remove item(s) from an item group
2132 $('.itemselection_action_item_group_unset').on('click', function(){
2133 $('#modal-item-group-unset').modal('show');
2136 $("#modal-item-group-unset-submit").on('click', function(){
2137 $('#modal-item-group-unset-submit').attr('disabled', 'disabled');
2139 let itemnumbers = new Array();
2140 $("input[name='itemnumber'][type='checkbox']:checked").each(function() {
2141 const itemnumber = $(this).val();
2142 itemnumbers.push( itemnumber );
2144 if (itemnumbers.length > 0) {
2145 let url = '/cgi-bin/koha/catalogue/detail.pl?op=unset_item_group';
2146 url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
2147 url += '&biblionumber=[% biblionumber | uri %]';
2149 window.location.replace(url);
2152 $('#modal-item-group-unset').modal('hide');
2156 const can_edit_items_from = [% To.json(can_edit_items_from || {}) | $raw %];
2157 const item_type_image_locations = [% To.json(item_type_image_locations) | $raw %];
2158 const av_loc = new Map([% To.json(AuthorisedValues.Get('LOC')) | $raw %].map( av => [av.authorised_value, av.lib]));
2159 const av_lost = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.itemlost' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2160 const av_withdrawn = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.withdrawn' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2161 const av_damaged = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.damaged' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2162 const av_not_for_loan= new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.notforloan' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2163 const av_restricted = new Map([% To.json(AuthorisedValues.GetDescriptionsByKohaField({ kohafield => 'items.restricted' })) | $raw %].map( av => [av.authorised_value, av.lib]));
2164 [% IF Koha.Preference('UseCourseReserves') %]
2165 const av_courses_term = new Map([% To.json(AuthorisedValues.Get('TERM')) | $raw %].map( av => [av.authorised_value, av.lib]));
2167 [% IF Koha.Preference('URLLinkText') %]
2168 const url_link_text = "[% Koha.Preference('URLLinkText') | html %]";
2170 const url_link_text = _("Link to resource");
2172 [%# FIXME The X-Base-Total-Count will be the number of items of the biblios %]
2173 [%# In case or SeparateHoldings we may need to display the number of biblios in each tab %]
2174 [%# Do we need separate/new endpoints or do we hack the somewhere client-side? %]
2175 let item_table_url = "/api/v1/biblios/[% biblio.biblionumber | uri %]/items?";
2176 let embed = ["+strings,checkout,checkout.patron,transfer,transfer+strings,first_hold,first_hold+strings,first_hold.patron,item_type"];
2177 [% IF Koha.Preference('LocalCoverImages') %]
2178 embed.push('cover_image_ids');
2180 [% IF Koha.Preference('EnableItemGroups') %]
2181 embed.push('item_group_item.item_group.description');
2183 [% IF biblio.serial %]
2184 embed.push('serialitem.serial');
2186 [% IF Koha.Preference('UseRecalls') %]
2187 embed.push('recall', 'recall+strings', 'recall.patron')
2189 embed.push('in_bundle', 'bundle_host');
2190 [% IF Koha.Preference('UseCourseReserves') %]
2191 embed.push('course_item.course_reserves.course');
2194 let items_table_settings = {
2195 holdings: [% TablesSettings.GetTableSettings('catalogue', 'detail','holdings_table','json') | $raw %],
2196 otherholdings: [% TablesSettings.GetTableSettings('catalogue', 'detail','otherholdings_table','json') | $raw %],
2199 function build_items_table (tab_id, add_filters, dt_options) {
2201 let default_filters = {};
2202 [% IF Koha.Preference('SeparateHoldings') %]
2203 [% SET SeparateHoldingsBranch = Koha.Preference('SeparateHoldingsBranch') || 'homebranch' %];
2204 let branch = '[% IF SeparateHoldingsBranch == 'homebranch' %]me.home_library_id[% ELSE %]me.holding_library_id[% END %]';
2205 if ( tab_id == 'holdings' ) {
2206 default_filters[branch] = '[% Branches.GetLoggedInBranchcode() | html %]';
2208 default_filters[branch] = { '!=': '[% Branches.GetLoggedInBranchcode() | html %]' };
2212 [% IF hidden_count %]
2213 default_filters.lost_status = "0";
2215 if ( !items_selection.hasOwnProperty(tab_id) ){
2216 items_selection[tab_id] = [];
2218 var items_table = $("#" + tab_id + '_table').kohaTable({
2219 ajax: { url: item_table_url },
2220 order: [[ 0, "asc" ]],
2223 bKohaColumnsUseNames: true,
2225 [% IF (StaffDetailItemSelection) %]
2230 render: function (data, type, row, meta) {
2231 if ( can_edit_items_from[row.holding_library_id] ){
2232 if ( items_selection[tab_id].includes(row.item_id) ) {
2233 return '<input type="checkbox" value="%s" name="itemnumber" checked />'.format(row.item_id);
2235 return '<input type="checkbox" value="%s" name="itemnumber" />'.format(row.item_id);
2243 [% IF Koha.Preference('LocalCoverImages') %]
2249 render: function (data, type, row, meta) {
2250 if ( !row.cover_image_ids.length > 0 ) {
2253 let node = '<div class="bookcoverimg">';
2254 node += '<div class="cover-slider">';
2255 row.cover_image_ids.forEach(id => {
2256 node += '<div class="cover-image local-coverimg">';
2257 node += '<a href="/cgi-bin/koha/catalogue/image.pl?itemnumber=%s&imagenumber=%s" title="Local cover image">'.format(id, id);
2258 node += '<img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&imagenumber=%s" alt="Local cover image" data-link="/cgi-bin/koha/catalogue/imageviewer.pl?itemnumber=[% item.itemnumber | uri %]&imagenumber=%s" />'.format(id, id);
2268 [% IF ( item_level_itypes ) %]
2270 data: "me.itype:biblioitem.itemtype",
2274 render: function (data, type, row, meta) {
2276 [% UNLESS noItemTypeImages %]
2277 let image_location = item_type_image_locations[row.item_type_id];
2278 let item_type_description = row._strings.item_type_id.str;
2279 node += image_location
2280 ? '<img src="%s" alt="%s" title="%s" /> '.format(escape_str(image_location), escape_str(item_type_description), escape_str(item_type_description))
2283 node += '<span class="itypedesc itypetext">%s</span>'.format(escape_str(item_type_description));
2289 data: "me.holding_library_id",
2290 className: "location",
2293 render: function (data, type, row, meta) {
2294 return escape_str(row._strings.holding_library_id.str);
2298 data: "me.home_library_id",
2299 className: "homebranch",
2302 render: function (data, type, row, meta) {
2303 let nodes = '<span class="homebranchdesc">%s</span>'.format(escape_str(row._strings.home_library_id.str));
2304 nodes += '<span class="shelvingloc">'
2305 [%# If permanent location is defined, show description or code and %]
2306 [%# display current location in parentheses. If not, display current location. %]
2307 [%# Note that permanent location is a code, and location may be an authval. %]
2308 let loc_str = row._strings.location.str;
2309 if ( row.permanent_location && row.permanent_location != row.location ) {
2310 let permanent_loc_str = av_loc[row.permanent_location];
2311 nodes += '%s (%s)'.format(escape_str(permanent_loc_str), escape_str(loc_str));
2313 nodes += escape_str(loc_str);
2320 data: "me.collection_code",
2323 render: function (data, type, row, meta) {
2324 return escape_str(row._strings.collection_code.str);
2327 [% IF Koha.Preference('EnableItemGroups') %]
2329 data: "item_group_item.item_group.description",
2330 className: "item_group",
2333 render: function (data, type, row, meta) {
2334 if ( row.item_group_item ) {
2335 return escape_str(row.item_group_item.item_group.description);
2343 data: "me.callnumber",
2344 className: "itemcallnumber",
2347 render: function (data, type, row, meta) {
2348 return escape_str(row.callnumber);
2353 data: "me.serial_issue_number",
2354 className: "enumchron",
2357 render: function (data, type, row, meta) {
2359 [%# FIXME Previously we displayed the column if at least one item of the biblio had an enumchron/serial_issue_number. Now it's only if one item of the ones displayed on the current page, how is that bad? How can it be fixed in an elegant way? Should we display the column only if biblio.serial? %]
2360 let serial = row.serialitem ? row.serialitem.serial : null;
2361 if ( row.serial_issue_number && serial && serial.serialseq ) {
2362 nodes += '<span class="enum">%s</span>'.format(escape_str(row.serial_issue_number));
2363 if ( serial.serialseq && row.serial_issue_number != serial.serialseq ) {
2364 nodes += ' <span class="sep"> -- </span>'
2365 nodes += ' <span class="serialseq">%s</span>'.format(escape_str(serial.serialseq));
2367 } else if ( row.serial_issue_number ) {
2368 nodes += ' <span class="enum">%s</span>'.format(escape_str(row.serial_issue_number));
2369 } else if ( serial && serial.serialseq ) {
2370 nodes += '<span class="serialseq">%s</span>'.format(escape_str(serial.serialseq));
2372 if ( serial && serial.publisheddate ) {
2373 nodes += ' <span class="pubdate">(%s)</span>'.format($date(serial.publisheddate));
2379 data: "me.lost_status",
2380 className: "status",
2381 searchable: false, // FIXME We are losing the ability to search on the status
2383 render: function (data, type, row, meta) {
2385 if ( row.checkout ) {
2387 if ( row.checkout.onsite_checkout ) {
2388 let patron_to_html = $patron_to_html(row.checkout.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2389 nodes += _("Currently in local use by %s").format(patron_to_html);
2391 nodes += '<span class="datedue">';
2392 let patron_to_html = $patron_to_html(row.checkout.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2393 nodes += _("Checked out to %s").format(patron_to_html);
2396 nodes += _("due %s").format($date(row.checkout.due_date, { as_due_date: true }));
2398 } else if ( row.transfer ) {
2399 if ( row.transfer.datesent ) {
2400 nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(escape_str(row.transfer._strings.from_library.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.datesent)));
2402 nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(escape_str(row.transfer._strings.from_library_.str), escape_str(row.transfer._strings.to_library.str), $date(row.transfer.daterequested)));
2406 if ( row.lost_status ) {
2407 let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing");
2408 nodes += '<span class="lost">%s</span>'.format(escape_str(lost_lib));
2411 if ( row.withdrawn ) {
2412 let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn");
2413 nodes += '<span class="wdn">%s</span>'.format(escape_str(withdrawn_lib));
2416 if ( row.damaged ) {
2417 let damaged_lib = av_damaged.get(row.damaged.toString()) || _("Damaged");
2418 nodes += '<span class="dmg">%s</span>'.format(escape_str(damaged_lib));
2421 if ( row.not_for_loan_status || row.item_type.notforloan ) {
2422 let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString());
2423 nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(escape_str(not_for_loan_lib)) : '' ) + '</span>';
2426 if ( row.first_hold ) {
2427 if ( row.first_hold.waiting_date ) {
2428 [%# FIXME We lost the desk name, we need an additional embed %]
2429 nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.".format(row.first_hold._strings.pickup_library_id.str, $date(row.first_hold.waiting_date))));
2430 [% IF Koha.Preference('canreservefromotherbranches') %]
2431 if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) {
2432 let patron_to_html = $patron_to_html(row.first_hold.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2433 nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html));
2437 nodes += '<span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority));
2441 [% IF Koha.Preference('UseRecalls') %]
2443 if ( row.recall.waiting_date ) {
2444 nodes += '<span>%s</span>'.format(_("Waiting at %s since %s").format(escape_str(row.recall.pickup_library_id.str), $date(row.recall.waiting_date)));
2446 let patron_to_html = $patron_to_html(row.recall.patron);
2447 nodes += '<span>%s</span>'.format(_("recalled by %s on %s").format(patron_to_html, $date(row.recall.created_date)))
2452 if ( ! ( row.not_for_loan_status || row.item_type.notforloan || row.checked_out_date || row.lost_status || row.withdrawn || row.damaged || row.transfer || row.first_hold || row.recall ) ) {
2453 nodes += ' <span>%s</span>'.format(_("Available"))
2456 if ( row.restricted_status ) {
2457 nodes += '<span class="restricted">(%s)</span>'.format(escape_str(av_restricted.get(row.restricted_status.toString())));
2460 if ( row.in_bundle ) {
2461 nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true })));
2467 data: "me.last_seen_date",
2468 className: "datelastseen",
2471 render: function (data, type, row, meta) {
2472 return $date(row.last_seen_date);
2476 data: "me.checkouts_count",
2477 className: "issues",
2480 render: function (data, type, row, meta) {
2481 return row.checkouts_count || 0;
2485 data: "me.renewals_count",
2486 className: "renewals",
2489 render: function (data, type, row, meta) {
2490 return row.renewals_count || 0;
2494 data: "me.acquisition_date",
2495 className: "dateaccessioned",
2498 render: function (data, type, row, meta) {
2499 return $date(row.acquisition_date);
2503 data: "me.last_checkout_date",
2504 className: "datelastborrowed",
2507 render: function (data, type, row, meta) {
2508 return $date(row.last_checkout_date);
2512 data: "me.external_id",
2516 render: function (data, type, row, meta) {
2517 return '<a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=%s#item%s">%s</a>'.format(row.biblio_id, row.item_id, row.external_id);
2525 render: function (data, type, row, meta) {
2526 if ( !row.uri ) return "";
2529 if ( row.uri.split(' \| ').length > 1 ) {
2530 row.uri.split(' \| ').forEach((uri, i) => {
2531 nodes += '<a href="%s">%s</a><br/>'.format(escape_str(uri), escape_str(uri));
2534 nodes += '<a href="%s">%s</a><br/>'.format(escape_str(row.uri), escape_str(url_link_text));
2540 data: "me.copy_number",
2541 className: "copynumber",
2544 render: function (data, type, row, meta) {
2545 return escape_str(row._strings.copy_number ? row._strings.copy_number.str : row.copy_number);
2549 data: "me.inventory_number",
2550 className: "stocknumber",
2553 render: function (data, type, row, meta) {
2554 return escape_str(row.inventory_number);
2558 data: "me.materials_notes",
2559 className: "materials",
2562 render: function (data, type, row, meta) {
2563 return escape_str(row.materials_notes);
2567 data: "me.public_notes",
2568 className: "itemnotes",
2571 render: function (data, type, row, meta) {
2572 return row.public_notes ? escape_str(row.public_notes).replaceAll('\n', '<br />') : '';
2576 data: "me.internal_notes",
2577 className: "nonpublicnote",
2580 render: function (data, type, row, meta) {
2581 return escape_str(row.internal_notes);
2584 [% IF ( hostrecords ) %]
2586 data: "biblio.biblio_id",
2587 searchable: false, // FIXME
2589 render: function (data, type, row, meta) {
2590 if ( row.biblio_id == [% biblio.biblionumber | html %] ) return "";
2591 return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s>%s</a>'.format(row.biblio_id, row.biblio.title);
2595 [% IF ( analyze ) %]
2598 searchable: false, // FIXME
2600 render: function (data, type, row, meta) {
2601 return ""; // FIXME Display analytic count + link
2605 [% IF Koha.Preference('UseCourseReserves') %]
2607 data: "course_item.course_reserves.course.course_name",
2610 render: function (data, type, row, meta) {
2612 if (!row.course_item) return nodes;
2613 row.course_item.course_reserves.forEach((cr, i) => {
2615 if ( c.enabled != 'yes' ) return;
2617 nodes += '<a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=%s">'.format(c.course_id);
2618 nodes += escape_str(c.course_name);
2620 nodes += ' ' + escape_str(c.section);
2623 nodes += ' ' + av_courses_term.get(c.term.toString());
2631 [% IF ( SpineLabelShowPrintOnBibDetails ) %]
2636 render: function (data, type, row, meta) {
2637 return '<a class="btn btn-default btn-xs print-label" href="/cgi-bin/koha/labels/spinelabel-print.pl?barcode=%s"><i class="fa fa-print"></i> Print label</a>'.format(escape_str(row.external_id));
2641 [% IF CAN_user_editcatalogue_edit_items %]
2643 data: function( row, type, val, meta ) {
2645 if ( can_edit_items_from[row.holding_library_id] ){
2646 [% IF Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %]
2647 nodes += '<div class="btn-group">';
2648 nodes += ' <a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa-solid fa-pencil"></i> Edit</a><a class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown"><span class="caret"></span></a>'.format(row.biblio_id, row.item_id);
2649 nodes += ' <ul class="dropdown-menu pull-right">';
2650 nodes += ' <li><a href="/cgi-bin/koha/tools/upload-cover-image.pl?itemnumber=%s&filetype=image"><i class="fa fa-upload"></i> Upload image</a></li>'.format(row.item_id);
2654 nodes += '<a class="btn btn-default btn-xs" href="/cgi-bin/koha/cataloguing/additem.pl?op=edititem&biblionumber=%s&itemnumber=%s#edititem"><i class="fa-solid fa-pencil"></i> Edit</a>'.format(row.biblio_id, row.item_id);
2657 [% IF bundlesEnabled %]
2658 // FIXME How do we handle that correctly?
2659 //nodes += '<button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> Manage bundle (%s|%s)</button>'.format(escape_str(row.bundled), escape_str(row.bundled_lost));
2664 className: "actions",
2670 initComplete: function( settings, json ){
2671 let table = settings.oInstance.api();
2672 table.columns().every(function(i){
2673 let is_empty = true;
2674 let nodes = this.nodes();
2675 nodes.each((td, ii) => {
2676 if ( $(td).html() !== '' ) {
2682 table.columns(i).visible(false);
2685 itemSelectionBuildActionLinks(tab_id);
2687 [% IF StaffDetailItemSelection %]
2688 drawCallback: function(settings){
2689 var api = new $.fn.dataTable.Api(settings)
2691 $(this).find("tbody tr td:first-child"),
2692 function (index, e) {
2693 let tr = $(this).parent()
2694 let row = api.row(tr).data()
2695 if (!row) return // Happen if the table is empty
2696 $(this).find("input[name='itemnumber'][type='checkbox']").on("change", function(){
2697 let itemnumber = parseInt($(this).val());
2698 if( $(this).prop("checked") ){
2699 items_selection[tab_id].push(itemnumber);
2701 items_selection[tab_id] = items_selection[tab_id].filter( id => id != itemnumber );
2703 itemSelectionBuildActionLinks(tab_id);
2711 items_table_settings[tab_id],
2719 [% CoverImagePlugins | $raw %]
2721 [% INCLUDE 'intranet-bottom.inc' %]