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 | <a href="#" class="SelectAll" data-tab="[% tab | html %]"><i class="fa fa-check"></i> Select all</a> |
322 <a href="#" class="ClearAll" data-tab="[% tab | html %]"><i class="fa fa-times"></i> Clear all</a>
323 <span class="itemselection_actions">
325 [% IF CAN_user_tools_items_batchdel %]
326 <a class="itemselection_action_delete"><i class="fa fa-trash-can"></i> Delete selected items</a>
328 [% IF CAN_user_tools_items_batchmod %]
329 <a class="itemselection_action_modify"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Modify selected items</a>
331 [% IF CAN_user_editcatalogue_manage_item_groups && biblio.item_groups.count %]
332 <a class="itemselection_action_item_group_set" href="#"><i class="fa fa-book"></i> Add/move to item group</a>
333 <a class="itemselection_action_item_group_unset" href="#"><i class="fa fa-unlink"></i> Remove from item group</a>
339 <table class="items_table" id="[% tab | html %]_table">
341 [% IF (StaffDetailItemSelection) %]<th id="[% tab | html %]_checkbox" data-colname="[% tab | html %]_checkbox" class="NoSort"></th>[% END %]
342 [% IF Koha.Preference('LocalCoverImages') %]
343 <th id="[% tab | html %]_cover_image" data-colname="[% tab | html %]_cover_image">Cover image</th>
345 [% IF ( item_level_itypes ) %]<th id="[% tab | html %]_itype" data-colname="[% tab | html %]_itype">Item type</th>[% END %]
346 <th id="[% tab | html %]_holdingbranch" data-colname="[% tab | html %]_holdingbranch">Current library</th>
347 <th id="[% tab | html %]_homebranch" data-colname="[% tab | html %]_homebranch">Home library</th>
348 <th id="[% tab | html %]_ccode" data-colname="[% tab | html %]_ccode">Collection</th>
349 [% IF Koha.Preference('EnableItemGroups') %]
350 <th id="[% tab | html %]_item_group" data-colname="[% tab | html %]_item_group">Item group</th>
352 <th id="[% tab | html %]_itemcallnumber" data-colname="[% tab | html %]_itemcallnumber">Call number</th>
353 <th id="[% tab | html %]_enumchron" data-colname="[% tab | html %]_enumchron">Serial enumeration / chronology</th>
354 <th id="[% tab | html %]_status" data-colname="[% tab | html %]_status">Status</th>
355 <th id="[% tab | html %]_lastseen" data-colname="[% tab | html %]_lastseen">Last seen</th>
356 <th id="[% tab | html %]_issues" data-colname="[% tab | html %]_issues">Checkouts</th>
357 <th id="[% tab | html %]_renewals" data-colname="[% tab | html %]_renewals">Renewals</th>
358 <th id="[% tab | html %]_dateaccessioned" data-colname="[% tab | html %]_dateaccessioned">Date accessioned</th>
359 <th id="[% tab | html %]_datelastborrowed" data-colname="[% tab | html %]_datelastborrowed">Date last borrowed</th>
360 <th id="[% tab | html %]_barcode" data-colname="[% tab | html %]_barcode">Barcode</th>
361 <th id="[% tab | html %]_uri" data-colname="[% tab | html %]_uri">URL</th>
362 <th id="[% tab | html %]_copynumber" data-colname="[% tab | html %]_copynumber">Copy number</th>
363 <th id="[% tab | html %]_stocknumber" data-colname="[% tab | html %]_stocknumber">Inventory number</th>
364 <th id="[% tab | html %]_materials" data-colname="[% tab | html %]_materials">Materials specified</th>
365 <th id="[% tab | html %]_itemnotes" data-colname="[% tab | html %]_itemnotes">Public notes</th>
366 <th id="[% tab | html %]_itemnotes_nonpublic" data-colname="[% tab | html %]_itemnotes_nonpublic">Non-public notes</th>
367 [% IF ( hostrecords ) %]<th id="[% tab | html %]_hostrecord" data-colname="[% tab | html %]_hostrecord">Host records</th>[% END %]
368 [% IF ( analyze ) %]<th id="[% tab | html %]_usedin" data-colname="[% tab | html %]_usedin">Used in</th><th></th>[% END %]
369 [% IF Koha.Preference('UseCourseReserves') %]<th id="[% tab | html %]_course_reserves" data-colname="[% tab | html %]_course_reserves">Course reserves</th>[% END %]
370 [% IF ( SpineLabelShowPrintOnBibDetails ) %]<th id="[% tab | html %]_spinelabel" data-colname="[% tab | html %]_spinelabel" class="NoSort">Spine label</th>[% END %]
371 [% IF ( CAN_user_editcatalogue_edit_items ) %]<th id="[% tab | html %]_actions" data-colname="[% tab | html %]_actions"class="NoSort noExport"> </th>[% END %]
375 [% END %][%# end of block items_table %]
377 [% IF Koha.Preference('EnableItemGroups') %]
378 <div role="tabpanel" class="tab-pane" id="item_groups">
379 [% IF CAN_user_editcatalogue_manage_item_groups %]
380 <div class="item_groups_table_table_controls">
381 <a href="#" class="item-group-create btn btn-default btn-xs"><i class="fa fa-plus"></i> New item group</a>
384 <table class="items-group-table" id="items-group-table">
387 <th>Display order</th>
389 <th class="NoSort"> </th>
397 <div role="tabpanel" class="tab-pane" id="holdings">
399 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'above' ) %]
400 <span class="results_summary NovelistSelect" style="display:none;">
401 <span class="label">Novelist Select: </span>
402 <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
406 [% SET hidden_count = all_items_count - items_to_display_count %]
407 [% IF all_items_count %]
408 [% PROCESS items_table tab="holdings" %]
410 [% IF hidden_count %]
411 [%# FIXME We could deal with that in JS and prevent a full refresh %]
412 <p><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% biblionumber | uri %]&showallitems=1">Show all items ([% hidden_count | html %] hidden)</a>
415 [% IF ( ALTERNATEHOLDINGS ) %]
416 [% FOREACH ALTERNATEHOLDING IN ALTERNATEHOLDINGS %]
417 <div id="alternateholdings"><span class="holdings_label">Holdings:</span> [% ALTERNATEHOLDING.holding | html %]</div>
420 <div id="noitems">No physical items for this record</div>
424 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'below' ) %]
425 <span class="results_summary NovelistSelect" style="display:none;">
426 <span class="label">Novelist Select: </span>
427 <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
432 [% IF Koha.Preference('SeparateHoldings') %]
433 <div role="tabpanel" class="tab-pane" id="otherholdings">
434 [% PROCESS items_table tab="otherholdings" %]
438 [% IF ( MARCNOTES ) %]
440 <div role="tabpanel" class="tab-pane" id="description">
441 <div class="content_set">
443 [% FOREACH MARCNOTE IN MARCNOTES %]
444 <p class="marcnote marcnote-[% MARCNOTE.tag | html %]" id="marcnote-[% MARCNOTE.tag | html %]-[% loop.count | html %]">
445 [% IF MARCNOTE.marcnote.match('^https?://\S+$') %]
446 <a href="[% MARCNOTE.marcnote | url %]">[% MARCNOTE.marcnote | html %]</a>
448 [% MARCNOTE.marcnote | html | html_line_break %]
457 [% IF ComponentParts && ComponentParts.size %]
458 <div role="tabpanel" class="tab-pane" id="components">
459 <div class="content_set">
461 [% FOR PART IN ComponentParts %]
469 [% IF ComponentParts.size == Koha.Preference('MaxComponentRecords')%]
470 <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>
472 </div> <!-- /.content_set -->
473 </div> <!-- /#components -->
477 [% IF ( subscriptionsnumber ) %]
478 <div role="tabpanel" class="tab-pane" id="subscriptions">
479 <div id="catalogue_detail_subscriptions">
480 <h2>This is a serial subscription</h2>
481 <p> (There are [% subscriptionsnumber | html %] subscriptions associated with this title).</p>
482 [% FOREACH subscription IN subscriptions %]
483 [% IF subscription.branchcode %]
484 <h3>At library: [% Branches.GetName(subscription.branchcode) || subscription.branchcode | html %]</h3>
486 [% IF ( subscription.closed ) %]<p>This subscription is closed.</p>[% END %]
487 [% IF ( subscription.location ) %]<p class="subscription_location">Location: [% AuthorisedValues.GetDescriptionByKohaField( kohafield => 'items.location', authorised_value => subscription.location ) | html %]</p>[% END %]
488 [% IF ( subscription.callnumber ) %]<p>Callnumber: [% subscription.callnumber | html %] </p>[% END %]
489 [% IF ( subscription.subscriptionnotes ) %]<p>[% subscription.subscriptionnotes | html | html_line_break %] </p>[% END %]
490 [% IF ( subscription.missinglist ) %]<p>Missing issues: [% subscription.missinglist | html %] </p>[% END %]
491 [% IF ( subscription.librariannote ) %]<p>([% subscription.librariannote | html %])</p>[% END %]
492 [% IF ( subscription.latestserials ) %]
493 <p> The [% subscription.staffdisplaycount | html %] latest issues related to this subscription:</p>
497 <th>Date arrived</th>
498 <th>Date published</th>
499 <th>Date published (text)</th>
503 [% FOREACH latestserial IN subscription.latestserials %]
505 <td>[% latestserial.serialseq | html %]</td>
506 <td data-order="[% latestserial.planneddate | html %]">[% latestserial.planneddate | $KohaDates %]</td>
507 <td data-order="[% latestserial.publisheddate | html %]">[% latestserial.publisheddate | $KohaDates %]</td>
508 <td>[% latestserial.publisheddatetext | html %]</td>
510 [% INCLUDE 'serial-status.inc' serial = latestserial %]
512 <td>[% latestserial.notes | html %]</td>
517 [% IF ( CAN_user_serials ) %]
519 <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>
527 [% IF Koha.Preference('AcquisitionDetails') %]
528 <div role="tabpanel" class="tab-pane" id="acq_details">
529 [% IF orders.count %]
535 <th>Basket group</th>
537 <th>Order number</th>
538 <th>Creation date</th>
539 <th>Receive date</th>
542 <th title="Estimated cost tax incl. while pending, actual cost tax incl. once received">Price</th>
543 <th>Internal note</th>
544 <th>Subscription</th>
545 <th>Subscription call number</th>
549 [% FOR order IN orders %]
550 [% SET basket = order.basket %]
551 [% SET vendor = basket.bookseller %]
554 <a href="/cgi-bin/koha/acqui/supplier.pl?booksellerid=[% vendor.id | uri %]" title="Vendor detail page">[% vendor.name | html %]</a>
557 [% IF order.invoiceid %]
558 [% IF CAN_user_acquisition %]
559 <div><a href="/cgi-bin/koha/acqui/invoice.pl?invoiceid=[% order.invoiceid | uri %]"
560 title="Invoice detail page">
561 [% order.invoice.invoicenumber | html %]</a></div>
563 <div>[% order.invoice.invoicenumber | html %]</div>
566 [% IF ( Koha.Preference('EDIFACT') && CAN_user_acquisition_edi_manage && order.invoice.message_id ) %]
567 <div><a href="/cgi-bin/koha/acqui/edimsg.pl?id=[% order.invoice.message_id | uri %]" title="EDI INVOICE message">EDI message</a></div>
572 [% IF basket.basketgroupid %]
573 [% SET basket_group = basket.basket_group %]
574 [% IF CAN_user_acquisition_group_manage %]
575 <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>
577 [% basket_group.name | html %] ([% basket_group.id | html %])
581 <td>[% IF CAN_user_acquisition_order_manage %]
582 <a href="/cgi-bin/koha/acqui/basket.pl?basketno=[% basket.basketno | uri %]">[% basket.basketname | html %] ([% basket.basketno | html %])</a>
584 [% basket.basketname | html %] ([% basket.basketno | html %])
586 <td>[% order.ordernumber | html %]</td>
587 <td data-order="[% basket.creationdate | uri %]">[% basket.creationdate | $KohaDates%]</td>
588 <td data-order="[% order.datereceived | uri %]">[% order.datereceived | $KohaDates%]</td>
590 [% SWITCH order.orderstatus %]
591 [% CASE 'new' %]<span>New</span>
592 [% CASE 'ordered' %]<span>Ordered</span>
593 [% CASE 'partial' %]<span>Partial</span>
594 [% CASE 'complete' %]<span>Complete</span>
595 [% CASE 'cancelled' %]<span>Cancelled</span>
598 <td>[% order.quantity | html %]</td>
599 <td>[% IF ( order.orderstatus == "complete" ) %][% order.unitprice_tax_included | $Price %][% ELSE %][% order.ecost_tax_included | $Price %][% END %]
600 <td>[% order.order_internalnote | html %]</td>
602 [% IF order.subscriptionid %]
603 <a href="/cgi-bin/koha/serials/subscription-detail.pl?subscriptionid=[% order.subscriptionid | uri %]">[% order.subscriptionid | html %]</a>
607 [% IF order.subscriptionid %]
608 [% order.subscription.callnumber | html %]
616 <span class="noorder">There is no order for this bibliographic record.</span>
621 [% IF suggestions.count %]
622 <div role="tabpanel" class="tab-pane" id="suggestion_details">
623 [% IF nb_archived_suggestions > 0 %]
624 <p>[% tnpx('pluralization', 'There is one archived suggestion.', 'There are {count} archived suggestions.', nb_archived_suggestions, { count = nb_archived_suggestions }) | $raw %]
626 <table id="suggestions" class="sorted">
629 <th class="NoSort"> </th>
630 <th class="anti-the">Suggestion</th>
631 <th>Suggested by - on</th>
632 <th>Managed by - on</th>
633 <th>Last modification by - on</th>
640 [% FOREACH suggestion IN suggestions %]
642 <td>[% suggestion.suggestionid | html %]</td>
644 <a href="/cgi-bin/koha/suggestion/suggestion.pl?suggestionid=[% suggestion.suggestionid | uri %]&op=show" title="suggestion" >
645 [% suggestion.title | html %][% IF ( suggestion.author ) %], by [% suggestion.author | html %][% END %]</a>
647 [% IF ( suggestion.copyrightdate ) %]© [% suggestion.copyrightdate | html %] [% END %]
648 [% IF ( suggestion.volumedesc ) %]; Volume:<em>[% suggestion.volumedesc | html %]</em> [% END %]
649 [% 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 %]
652 <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.suggestedby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.suggester %]</a>
653 [% IF suggestion.suggesteddate %] - [% suggestion.suggesteddate | $KohaDates %][% END %]
656 <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.managedby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.manager %]</a>
657 [% IF suggestion.manageddate %] - [% suggestion.manageddate | $KohaDates %][% END %]
660 <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% suggestion.lastmodificationby | uri %]">[% INCLUDE 'patron-title.inc' patron => suggestion.last_modifier %]</a>
661 [% IF suggestion.lastmodificationdate %] - [% suggestion.lastmodificationdate | $KohaDates %][% END %]
664 [% Branches.GetName( suggestion.branchcode ) | html %]
667 [% suggestion.fund.budget_name | html %]
670 [% IF suggestion.STATUS == 'ASKED' %]<span>Pending</span>
671 [% ELSIF suggestion.STATUS == 'ACCEPTED' %]<span>Accepted</span>
672 [% ELSIF suggestion.STATUS == 'ORDERED' %]<span>Ordered</span>
673 [% ELSIF suggestion.STATUS == 'REJECTED' %]<span>Rejected</span>
674 [% ELSIF suggestion.STATUS == 'CHECKED' %]<span>Checked</span>
675 [% ELSIF suggestion.STATUS == 'AVAILABLE' %]<span>Available</span>
676 [% ELSIF AuthorisedValues.GetByCode( 'SUGGEST_STATUS', suggestion.STATUS ) %]
677 [% AuthorisedValues.GetByCode( 'SUGGEST_STATUS', suggestion.STATUS ) | html %]
678 [% ELSE %]<span>Status unknown</span>
680 [% IF suggestion.reason %]
681 <br />([% suggestion.reason | html %])
691 [% IF ( FRBRizeEditions ) %][% IF ( XISBNS ) %]
692 <div role="tabpanel" class="tab-pane" id="editions"><h4>Editions</h4>
694 [% 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 %]
695 [% 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 %]
696 <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 %]
697 [% IF ( XISBN.publishercode ) %]
698 [% 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 %]
700 [% IF ( XISBN.pages ) %] [% END %][% XISBN.pages | html %] [% IF ( XISBN.illus ) %][% XISBN.illus | html %][% END %]
701 [% IF ( XISBN.size ) %], [% END %][% XISBN.size | html %]
705 </table></div>[% END %]
708 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
709 <div role="tabpanel" class="tab-pane" id="concerns">
710 <fieldset class="action" style="cursor:pointer;">
711 <a id="hideResolved"><i class="fa fa-minus-square"></i> Hide resolved</a>
712 | <a id="showAll"><i class="fa fa-bars"></i> Show all</a>
715 <table id="table_concerns" width="100%">
721 <th data-class-name="actions noExport">Actions</th>
728 [% IF ( LocalCoverImages ) %]
729 <div role="tabpanel" class="tab-pane" id="images">
730 [% IF localimages.count %]
731 <p>Click on an image to view it in the image viewer</p>
732 <ul class="thumbnails">
733 [% FOREACH image IN localimages %]
735 <li id="imagenumber-[% image.imagenumber | html %]" class="thumbnail">
736 <a href="/cgi-bin/koha/catalogue/imageviewer.pl?biblionumber=[% biblionumber | uri %]&imagenumber=[% image.imagenumber | uri %]">
737 <img src="/cgi-bin/koha/catalogue/image.pl?thumbnail=1&imagenumber=[% image.imagenumber | uri %]" />
739 [% IF CAN_user_tools_upload_local_cover_images %]
740 <a href="#" class="remove"><i class="fa fa-trash-can"></i> Delete image</a>
746 [% ELSE # - No image passed JavaScript takes care %]
747 <span class="noimagesuploaded">No images have been uploaded for this bibliographic record yet.</span>
749 [% IF ( CAN_user_tools_upload_local_cover_images ) %]
750 <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>
756 [% IF ( HTML5MediaEnabled ) %]
757 <div role="tabpanel" class="tab-pane" id="html5media">
758 [% FOREACH HTML5MediaSet IN HTML5MediaSets %]
760 [% IF HTML5MediaSet.is_youtube %]
761 <iframe id="player" width="640" height="360" src="[% HTML5MediaSet.srcblock | url %]"></iframe>
763 <[% HTML5MediaParent | html %] controls preload=none>
764 <[% HTML5MediaSet.child | html %] src="[% HTML5MediaSet.srcblock | url %]"[% HTML5MediaSet.typeblock | html %] />
765 [[% HTML5MediaParent | html %] tag not supported by your browser.]
766 </[% HTML5MediaParent | html %]>
774 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && Koha.Preference('NovelistSelectStaffView') == 'tab' ) %]
775 <div role="tabpanel" class="tab-pane" id="NovelistSelect" class="novelistSelect">
776 <div data-novelist-novelistselect=[% normalized_isbn | html %]></div>
780 [% FOREACH plugins_intranet_catalog_biblio_tab IN plugins_intranet_catalog_biblio_tabs %]
781 <div role="tabpanel" class="tab-pane" id="[% plugins_intranet_catalog_biblio_tab.id | html %]">
782 [% plugins_intranet_catalog_biblio_tab.content | $raw %]
786 </div><!-- /tab-content -->
787 </div><!-- /bibliodetails -->
789 <div id="export" style="margin-top: 1em;">
790 <form method="get" action="/cgi-bin/koha/catalogue/export.pl">
792 <th>Save record</th> </tr>
793 <tr><td> Select download format: <select name="format">
794 <option value="mods">MODS (XML)</option>
795 <option data-toggle="modal" data-target="#exportModal_">Dublin Core</option>
796 <option value="marcxml">MARCXML</option>
797 <option value="marc8">MARC (non-Unicode/MARC-8)</option>
798 <option value="utf8">MARC (Unicode/UTF-8)</option> </select>
799 <input type="submit" name="save" class="btn btn-primary" value="Download record" /></td>
802 <input type="hidden" name="op" value="export" /><input type="hidden" name="bib" value="[% biblionumber | html %]" />
808 <div id="marcPreview" class="modal" tabindex="-1" role="dialog" aria-labelledby="marcPreviewLabel" aria-hidden="true">
809 <div class="modal-dialog modal-lg">
810 <div class="modal-content">
811 <div class="modal-header">
812 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
813 <h3 id="marcPreviewLabel">MARC preview</h3>
815 <div class="modal-body">
816 <div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
818 <div class="modal-footer">
819 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
825 <div id="elasticPreview" class="modal" tabindex="-1" role="dialog" aria-labelledby="elasticPreviewLabel" aria-hidden="true">
826 <div class="modal-dialog modal-lg">
827 <div class="modal-content">
828 <div class="modal-header">
829 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
830 <h3 id="elasticPreviewLabel">Elasticsearch record</h3>
832 <div class="modal-body">
833 <div id="loading"> <img src="[% interface | html %]/[% theme | html %]/img/spinner-small.gif" alt="" /> Loading </div>
835 <div class="modal-footer">
836 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
843 </div> <!-- /.col-sm-10.col-sm-push-2 -->
845 <div class="col-sm-2 col-sm-pull-10">
847 [% INCLUDE 'biblio-view-menu.inc' %]
849 </div> <!-- /.col-sm-2.col-sm-pull-10 -->
850 </div> <!-- /.row -->
854 <div class="modal fade" id="modal-item-group-create" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-create-label">
855 <div class="modal-dialog">
856 <div class="modal-content">
857 <div class="modal-header">
858 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
859 <h3 id="modal-item-group-create-label"><i class="fa fa-plus"></i> Create a new item group</h3>
861 <form method="get" id="modal-item-group-create-form" class="validated">
862 <div class="modal-body">
865 <label for="item_group_description" class="required">Name: </label>
866 <input name="description" id="modal-item-group-create-form-description" type="text" size="30" required="required" class="required" />
867 <span class="required">Required</span>
870 <label for="item_group_display_order" class="required">Display order: </label>
871 <input name="display_order" id="modal-item-group-create-form-display_order" value="0" size="5" required="required" class="required" />
872 <span class="required">Required</span>
874 <span class="hint">Numbers only, item groups will be displayed in counting order</span>
878 <div class="modal-footer">
879 <button id="modal-item-group-create-submit" class="btn btn-default"><i class="fa fa-plus"></i> Submit</button>
880 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
887 <div class="modal fade" id="modal-item-group-edit" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-edit-label">
888 <div class="modal-dialog">
889 <div class="modal-content">
890 <div class="modal-header">
891 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
892 <h3 id="modal-item-group-edit-label"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Edit item group</h3>
894 <form method="get" id="modal-item-group-edit-form" class="validated">
895 <div class="modal-body">
898 <label for="item_group_description" class="required">Name: </label>
899 <input name="description" id="modal-item-group-edit-form-description" type="text" size="30" required="required" class="required" />
900 <span class="required">Required</span>
903 <label for="item_group_display_order" class="required">Sort order: </label>
904 <input name="display_order" id="modal-item-group-edit-form-display_order" size="5" />
905 <span class="hint">Numbers only, item groups will be displayed in counting order</span>
909 <div class="modal-footer">
910 <button id="modal-item-group-edit-submit" class="btn btn-default"><i class="fa-solid fa-pencil" aria-hidden="true"></i> Submit</button>
911 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
918 <div class="modal fade" id="modal-item-group-delete" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-delete-label">
919 <div class="modal-dialog">
920 <div class="modal-content">
921 <div class="modal-header">
922 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
923 <h3 id="modal-item-group-delete-label"><i class='fa fa-trash-can'></i> Delete item group</h3>
925 <div class="modal-body">
926 Are you sure you want to delete this item group?
928 <div class="modal-footer">
929 <button id="modal-item-group-delete-submit" class="btn btn-danger"><i class='fa fa-trash-can'></i> Delete</button>
930 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
936 <div class="modal fade" id="modal-item-group-set" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-set-label">
937 <div class="modal-dialog">
938 <div class="modal-content">
939 <div class="modal-header">
940 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
941 <h3 id="modal-item-group-set-label"><i class='fa fa-book'></i> Set item group for items</h3>
943 <form method="get" id="modal-item-group-set-form" class="validated">
944 <div class="modal-body">
947 <label for="item_group" class="required">Item group: </label>
948 <select name="item_group" id="item-group-add-form-select">
949 [% FOREACH ig IN biblio.item_groups.search({}, {order_by => 'display_order'}) %]
950 <option value="[% ig.id | html %]">[% ig.description | html %]</option>
953 <span class="required">Required</span>
957 <div class="modal-footer">
958 <button id="modal-item-group-set-submit" class="btn btn-default"><i class='fa fa-book'></i> Set item group</button>
959 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
966 <div class="modal fade" id="modal-item-group-unset" tabindex="-1" role="dialog" aria-labelledby="modal-item-group-unset-label">
967 <div class="modal-dialog">
968 <div class="modal-content">
969 <div class="modal-header">
970 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
971 <h3 id="modal-item-group-unset-label"><i class='fa fa-unlink'></i> Remove item from item group</h3>
973 <div class="modal-body">
974 Are you sure you want to remove these item(s) from their item group(s)?
976 <div class="modal-footer">
977 <button id="modal-item-group-unset-submit" class="btn btn-danger"><i class='fa fa-unlink'></i> Remove</button>
978 <button class="btn btn-link" data-dismiss="modal" aria-hidden="true">Cancel</button>
984 [% IF bundlesEnabled %]
985 <div class="modal" id="addToBundleModal" tabindex="-1" role="dialog" aria-labelledby="addToBundleLabel">
986 <form method="get" id="addToBundleForm" action="">
987 <div class="modal-dialog" role="document">
988 <div class="modal-content">
989 <div class="modal-header">
990 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
991 <h3 id="addToBundleLabel">Add to bundle</h3>
993 <div class="modal-body">
994 <div id="addResult"></div>
995 <fieldset class="rows">
998 <label class="required" for="external_id">Item barcode: </label>
999 <input type="text" id="external_id" name="external_id" required="required">
1000 <span class="required">Required</span>
1005 <div class="modal-footer">
1006 <button type="submit" class="btn btn-default">Submit</button>
1007 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1014 <div class="modal" id="removeFromBundleModal" tabindex="-1" role="dialog" aria-labelledby="removeFromBundleLabel">
1015 <form method="get" id="removeFromBundleForm" action="">
1016 <div class="modal-dialog" role="document">
1017 <div class="modal-content">
1018 <div class="modal-header">
1019 <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
1020 <h3 id="removeFromBundleLabel">Remove from bundle</h3>
1022 <div class="modal-body">
1023 <div id="removeResult"></div>
1024 <fieldset class="rows">
1027 <label class="required" for="external_id">Item barcode: </label>
1028 <input type="text" id="rm_external_id" name="external_id" required="required">
1029 <span class="required">Required</span>
1034 <div class="modal-footer">
1035 <button type="submit" class="btn btn-default">Submit</button>
1036 <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
1044 [% IF ( Koha.Preference('CatalogConcerns') ) %]
1045 [% INCLUDE 'modals/add_catalog_concern.inc' %]
1048 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
1049 [% INCLUDE 'modals/display_ticket.inc' %]
1052 [% MACRO jsinclude BLOCK %]
1053 [% INCLUDE 'catalog-strings.inc' %]
1054 [% INCLUDE 'calendar.inc' %]
1055 [% INCLUDE 'select2.inc' %]
1056 [% INCLUDE 'js-date-format.inc' %]
1057 [% Asset.js("js/catalog.js") | $raw %]
1058 [% Asset.js("js/recalls.js") | $raw %]
1059 [% Asset.js("js/coce.js") | $raw %]
1060 [% Asset.js("lib/Chocolat/js/chocolat.js") | $raw %]
1061 [% IF ( Koha.Preference('CatalogConcerns') ) %]
1063 /* Set a variable needed by add_catalog_concern.js */
1064 var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]";
1066 [% Asset.js("js/modals/add_catalog_concern.js") | $raw %]
1068 [% IF ( ( Koha.Preference('CatalogConcerns') || Koha.Preference('OpacCatalogConcerns') ) && CAN_user_editcatalogue_edit_catalogue ) %]
1070 $(document).ready(function() {
1071 var table_settings = [% TablesSettings.GetTableSettings( 'cataloguing', 'concerns', 'table_concerns', 'json' ) | $raw %];
1073 var filtered = false;
1074 let additional_filters = {
1075 resolved_date: function(){
1077 return { "=": null };
1082 biblio_id: [% biblionumber | uri %]
1085 var tickets_url = '/api/v1/tickets';
1086 var tickets = $("#table_concerns").kohaTable({
1095 'emptyTable': '<div class="dialog message">' + _("Congratulations, there are no catalog concerns.") + '</div>',
1098 "render": function (data, type, row, meta) {
1099 if ( type == 'display' ) {
1100 if ( data != null ) {
1101 return data.escapeHtml();
1112 "data": "reported_date:reporter.firstname",
1113 "render": function(data, type, row, meta) {
1114 let reported = '<span class="date clearfix">' + $datetime(row.reported_date) + '</span>';
1115 reported += '<span class="reporter clearfix">' + $patron_to_html(row.reporter, {
1116 display_cardnumber: false,
1125 "data": "title:body",
1126 "render": function(data, type, row, meta) {
1127 let resolved = ( row.resolved_date ) ? true : false;
1128 let result = '<a role="button" href="#" data-toggle="modal" data-target="#ticketDetailsModal" data-concern="' + encodeURIComponent(row.ticket_id) + '" data-resolved="' + resolved + '">' + row.title + '</a>';
1129 if (row.updates_count) {
1130 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>';
1132 result += '<div id="detail_' + row.ticket_id + '" class="hidden">' + row.body + '</div>';
1139 "data": "resolved_date",
1140 "render": function(data, type, row, meta) {
1142 if (row.resolved_date) {
1143 result += _("Resolved by:") + ' <span>' + $patron_to_html(row.resolver, {
1144 display_cardnumber: false,
1147 result += '<span class="clearfix">' + $datetime(row.resolved_date) + '</span>';
1149 result += _("Open");
1157 "data": function(row, type, val, meta) {
1158 let resolved = ( row.resolved_date ) ? true : false;
1159 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>';
1162 "searchable": false,
1166 }, table_settings, 0, additional_filters);
1168 $('#hideResolved').on("click", function() {
1170 tickets.DataTable().draw();
1173 $('#showAll').on("click", function() {
1175 tickets.DataTable().draw();
1179 [% Asset.js("js/modals/display_ticket.js") | $raw %]
1182 var interface = "[% interface | html %]";
1183 var theme = "[% theme | html %]";
1184 // http://www.oreillynet.com/pub/a/javascript/2003/10/21/amazonhacks.html
1185 function verify_cover_images() {
1186 // Loop over each container in the template which contains covers
1187 $(".cover-slider").each(function(){
1188 var lightbox_descriptions = [];
1189 var first_shown = 0;
1190 $(this).find(".cover-image").each( function( index ){
1192 // Find the image in the container
1193 var img = div.find("img")[0];
1194 if( $(img).length > 0 ){
1195 var description = "";
1196 // All slides start hidden. If this is the first one, show it.
1197 if( first_shown == 0 ){
1201 // Check if Amazon image is present
1202 if ( div.attr("id") == "amazon-bookcoverimg" ) {
1205 if ((w == 1) || (h == 1)) {
1206 // Amazon returned single-pixel placeholder
1207 // Remove the container
1210 lightbox_descriptions.push(_("Amazon cover image (<a href='%s'>see the original image</a>)").format($(img).data('link')));
1212 } else if( div.attr("id") == "custom-coverimg" ){
1213 if ( (img.complete != null) && (!img.complete) || img.naturalHeight == 0 ) {
1214 // No image was loaded via the CustomCoverImages system preference
1215 // Remove the container
1218 lightbox_descriptions.push( _("Custom cover image") );
1220 } else if ( div.attr("id") == "syndetics-bookcoverimg" ){
1221 lightbox_descriptions.push(_("Syndetics cover image (<a href='%s'>see the original image</a>)").format($(img).data('link')));
1223 else if( div.hasClass("coce-coverimg" ) ){
1224 // Identify which service's image is being loaded by Coce
1225 var coce_description;
1226 if( $(img).attr("src").indexOf('amazon.com') >= 0 ){
1227 coce_description = _("Coce image from Amazon.com");
1228 } else if( $(img).attr("src").indexOf('google.com') >= 0 ){
1229 coce_description = _("Coce image from Google Books");
1230 } else if( $(img).attr("src").indexOf('openlibrary.org') >= 0 ){
1231 coce_description = _("Coce image from Open Library");
1233 div.find(".hint").html(coce_description);
1234 lightbox_descriptions.push(coce_description);
1235 } else if ( div.attr("class") == "cover-image local-coverimg" ) {
1236 lightbox_descriptions.push(_("Local cover image (<a href='%s'>edit</a>)").format($(img).data('link')));
1238 lightbox_descriptions.push(_("Cover image source unknown"));
1243 // Lightbox for cover images
1244 Chocolat(this.querySelectorAll('.cover-image a'), {
1245 description: function(){
1246 return lightbox_descriptions[this.settings.currentImageIndex];
1252 $(".cover-slider").each(function(){
1253 var coverSlide = this;
1254 var coverImages = $(this).find(".cover-image");
1255 if( coverImages.length > 1 ){
1256 coverImages.each(function( index ){
1257 // If more that one image is present, add a navigation link
1258 // for activating the slide
1259 var covernav = $("<a href=\"#\" data-num=\"" + index + "\" class=\"cover-nav\"></a>");
1261 // Set the first navigation link as active
1262 $(covernav).addClass("nav-active");
1264 $(covernav).html("<i class=\"fa fa-circle\"></i>");
1265 $(coverSlide).append( covernav );
1269 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
1270 && $(coverSlide).find(".cover-image:visible").length < 1 ){
1271 $(coverSlide).remove();
1273 $(coverSlide).addClass("cover-slides");
1274 var img = $(coverSlide).find(".cover-image:visible").find("img")[0];
1275 if( $(img).length > 0 && img.complete && img.naturalHeight > 0 ){
1276 $(".cover-slides").css({"background-image":"none"});
1281 $("#editions img").each(function(i){
1282 if ( this.src.indexOf('amazon.com') >= 0 ) {
1285 if ((w == 1) || (h == 1)) {
1286 this.src = 'https://images-na.ssl-images-amazon.com/images/G/01/x-site/icons/no-img-sm.gif';
1287 } else if ( (this.complete != null) && (!this.complete) || this.naturalHeight == 0 ) {
1288 this.src = 'https://images-na.ssl-images-amazon.com/images/G/01/x-site/icons/no-img-sm.gif';
1294 function removeLocalImage(imagenumber) {
1295 var thumbnail = $("#imagenumber-" + imagenumber );
1296 var copy = thumbnail.html();
1297 thumbnail.find("img").css("opacity", ".2");
1298 thumbnail.find("a.remove").html("<img style='display:inline-block' src='" + interface + "/" + theme + "/img/spinner-small.gif' alt='' />");
1299 const client = APIClient.cover_image;
1300 client.cover_images.delete(imagenumber).then(
1302 if ( success.deleted == 1 ) {
1305 thumbnail.html( copy );
1306 alert(_("An error occurred on deleting this image"));
1308 if ( $('ul.thumbnails > li').length == 0 ) {
1309 showNoImageMessage();
1313 thumbnail.html( copy );
1314 alert(_("An error occurred on deleting this image"));
1315 console.warn("Something wrong happened: %s".format(error));
1320 function showNoImageMessage() {
1321 var no_images_msg = _("No images have been uploaded for this bibliographic record yet.");
1322 no_images_msg = '<p>' + no_images_msg + '</p>';
1323 [% IF ( CAN_user_tools_upload_local_cover_images ) %]
1324 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>");
1325 no_images_msg += "<p id='upload_image'>" + please_upload + '</p>';
1327 $('#images').html(no_images_msg);
1330 [% IF StaffDetailItemSelection %]
1331 function itemSelectionBuildDeleteLink(div) {
1332 var itemnumbers = new Array();
1333 $("input[name='itemnumber'][type='checkbox']:checked", div).each(function() {
1334 itemnumbers.push($(this).val());
1336 if (itemnumbers.length > 0) {
1337 var url = '/cgi-bin/koha/tools/batchMod.pl?op=show&del=1';
1338 url += '&itemnumber=' + itemnumbers.join('&itemnumber=');
1339 url += '&biblionumber=[% biblionumber | uri %]';
1340 url += '&src=CATALOGUING';
1341 $('a.itemselection_action_delete').attr('href', url);
1348 function itemSelectionBuildModifyLink(div) {
1349 var itemnumbers = new Array();
1350 $("input[name='itemnumber'][type='checkbox']:checked", div).each(function() {
1351 itemnumbers.push($(this).val());
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) {
1366 var div = $("#" + tab);
1367 var delete_link_ok = itemSelectionBuildDeleteLink(div);
1368 var modify_link_ok = itemSelectionBuildModifyLink(div);
1369 if (modify_link_ok || delete_link_ok) {
1370 $('.itemselection_actions', div).show();
1372 $('.itemselection_actions', div).hide();
1376 $(document).ready(function() {
1377 $('table.items_table').each(function() {
1378 var div = $(this).parent().attr("id");
1379 itemSelectionBuildActionLinks(div);
1382 $("input[name='itemnumber'][type='checkbox']").change(function() {
1383 var div = $(this).parents('table').parent().parent().attr("id");
1384 itemSelectionBuildActionLinks(div);
1387 $(".SelectAll").on("click",function(e){
1389 var tab = $(this).data("tab");
1390 $("input[name='itemnumber'][type='checkbox']", $("#"+tab)).prop('checked', true);
1391 itemSelectionBuildActionLinks(tab);
1394 $(".ClearAll").on("click",function(e){
1396 var tab = $(this).data("tab");
1397 $("input[name='itemnumber'][type='checkbox']", $("#"+tab)).prop('checked', false);
1398 itemSelectionBuildActionLinks(tab);
1403 $(document).ready(function() {
1404 // Pick details tab to display by default
1406 [% IF ( Koha.Preference('HTML5MediaEnabled') == 'staff' or Koha.Preference('HTML5MediaEnabled') == 'both' ) && HTML5MediaSets.size %]
1407 $(".nav-tabs a[href='#html5media']").tab("show");
1408 [% ELSIF ComponentParts && ComponentParts.size %]
1409 $(".nav-tabs a[href='#components']").tab("show");
1411 $(".nav-tabs a[href='#holdings']").tab("show");
1414 $(".nav-tabs a[href='#holdings']").tab("show");
1416 $('#search-form').focus();
1417 $('.thumbnails > li > .remove').click(function() {
1418 var result = confirm(_("Are you sure you want to delete this cover image?"));
1420 if ( result == true ) {
1421 var imagenumber = $(this).parent().attr('id').split('-')[1];
1422 removeLocalImage(imagenumber);
1427 [% IF ( IntranetCoce && CoceProviders ) %]
1428 KOHA.coce.getURL('[% CoceHost | html %]', '[% CoceProviders | html %]');
1431 $("body").on("click",".previewMARC", function(e){
1433 var page = $(this).attr("href");
1434 $("#marcPreview .modal-body").load(page + " table");
1435 $('#marcPreview').modal({show:true});
1439 [% IF ( Koha.Preference('SearchEngine') == 'Elasticsearch' ) %]
1440 $("body").on("click",".previewElastic", function(e){
1442 var pageElastic = $(this).attr("href");
1443 $("#elasticPreview .modal-body").load(pageElastic, function( response, status, xhr ) {
1444 if( status == 'error' ){
1445 $("#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>");
1448 $('#elasticPreview').modal({show:true});
1452 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && ( normalized_isbn || normalized_upc ) ) %]
1453 novSelect.loadContentForQuery({
1454 ClientIdentifier : '[% IF normalized_isbn %][% normalized_isbn | html %][% ELSE %][% normalized_upc | html %][% END %]',
1455 ISBN : '[% IF normalized_isbn %][% normalized_isbn | html %][% ELSE %][% normalized_upc | html %][% END %]',
1458 '[% Koha.Preference('NovelistSelectStaffProfile') | html %]',
1459 '[% Koha.Preference('NovelistSelectPassword') | html %]',
1461 if ( d.length > 0 ){ //If no content
1462 $(".NovelistSelect").show();
1466 $(".print-label").on("click", function(e){
1468 link = $(this).attr("href");
1469 openWindow(link,"Print spine label",400,400);
1471 $(".cover-slider").on("click",".cover-nav", function(e){
1473 var cover_slider = $(this).parent();
1474 // Adding click handler for cover image navigation links
1475 var num = $(this).data("num");
1476 $(cover_slider).find(".cover-nav").removeClass("nav-active");
1477 $(this).addClass("nav-active");
1478 $(cover_slider).find(".cover-image").hide();
1479 $(cover_slider).find(".cover-image").eq( num ).show();
1484 [% IF ( IntranetCoce && CoceProviders ) %]
1485 let counter_wait = 0;
1486 function wait_for_images(cb){
1492 loaded = KOHA.coce.done;
1495 if (!loaded && counter_wait < 50) {// Do not wait more than 5 seconds
1496 window.setTimeout(function(){wait_for_images(cb);}, 100);
1498 if (counter_wait >= 50 ) {
1499 console.log("Could not retrieve the images")
1505 $(window).load(function() {
1506 wait_for_images(verify_cover_images);
1509 $(window).load(function() {
1510 verify_cover_images();
1514 [% IF ( Koha.Preference('NovelistSelectStaffEnabled') && Koha.Preference('NovelistSelectStaffProfile') && ( normalized_isbn || normalized_upc ) ) %]
1515 <script src="https://imageserver.ebscohost.com/novelistselect/ns2init.js"></script>
1517 [% INCLUDE 'datatables.inc' %]
1518 [% Asset.js("lib/jquery/plugins/jquery.dataTables.columnFilter.js") | $raw %]
1519 [% INCLUDE 'columns_settings.inc' %]
1520 [% INCLUDE 'js-date-format.inc' %]
1521 [% INCLUDE 'js-patron-format.inc' %]
1522 [% INCLUDE 'js-biblio-format.inc' %]
1523 [% Asset.js("js/browser.js") | $raw %]
1524 [% Asset.js("js/table_filters.js") | $raw %]
1525 [% Asset.js("js/place_booking_modal.js") | $raw %]
1528 browser = KOHA.browser('[% searchid | html %]', parseInt(biblionumber, 10));
1531 [% IF bundlesEnabled %]
1532 var bundle_settings = [% TablesSettings.GetTableSettings('catalogue', 'detail','bundle_tables','json') | $raw %];
1533 var bundle_lost_value = [% Koha.Preference('BundleLostValue') | html %];
1535 $(document).ready(function() {
1537 [% IF bundlesEnabled %] // Bundle handling
1538 function createChild ( row, itemnumber, duedate ) {
1541 var bundle_toolbar = $('<div id="toolbar" class="btn-toolbar"></div>');
1542 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>');
1543 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>');
1545 // Disable management if there's a duedate
1547 bundle_toolbar.children('.btn').addClass("disabled");
1548 bundle_toolbar.attr("title", _("This bundle is checked out, it cannot be modified"));
1551 // This is the table we'll convert into a DataTable
1552 var bundles_table = $('<table class="display tbundle" data-itemnumber="'+itemnumber+'" id="bundle_table_'+itemnumber+'" width="100%"/>');
1554 // Display it the child row
1555 row.child( bundle_toolbar.add(bundles_table), 'bundle' ).show();
1557 // Initialise as a DataTable
1558 var bundle_table_url = "/api/v1/items/" + itemnumber + "/bundled_items?";
1559 var bundle_table = bundles_table.kohaTable({
1561 "url": bundle_table_url
1565 "return_claim.patron"
1567 "order": [[ 1, "asc" ]],
1569 "targets": [0,1,2,3],
1570 "render": function (data, type, row, meta) {
1571 if ( data && type == 'display' ) {
1572 return data.escapeHtml();
1579 "data": "biblio.title:biblio.subtitle:biblio.medium",
1580 "title": _("Title"),
1583 "render": function(data, type, row, meta) {
1584 return $biblio_to_html(row.biblio, { link: 1 });
1588 "data": "biblio.author",
1589 "title": _("Author"),
1594 "data": "callnumber",
1595 "title": _("Callnumber"),
1600 "data": "external_id",
1601 "title": _("Barcode"),
1606 "data": "lost_status:last_seen_date:return_claim.patron",
1607 "title": _("Status"),
1608 "searchable": false,
1610 "render": function(data, type, row, meta) {
1611 if ( row.lost_status == bundle_lost_value ) {
1612 let out = '<span class="lost">' + _("Last seen") + ': ' + $date(row.last_seen_date) + '</span>';
1613 if ( row.return_claim ) {
1614 out = out + '<span class="claims_return">' + _("Claims returned by") + ': ' + $patron_to_html( row.return_claim.patron, { display_cardnumber: false, url: true } ) + '</span>';
1618 else if ( row.lost_status !== 0 ) {
1619 return '<span class="lost">' + _("Lost") + ': ' + row.lost_status + '</span>';
1621 return '<span class="available">' + _("Present") + '</span>';
1625 "data": function( row, type, val, meta ) {
1628 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"));
1630 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';
1634 "title": _("Actions"),
1635 "searchable": false,
1640 }, bundle_settings, 1);
1641 $(".tbundle").on("click", ".remove:not(.disabled)", function(){
1642 var bundle_table = $(this).closest('table');
1643 var host_itemnumber = bundle_table.data('itemnumber');
1644 var component_itemnumber = $(this).data('itemnumber');
1645 var unlink_item_url = "/api/v1/items/" + host_itemnumber + "/bundled_items/" + component_itemnumber;
1648 url: unlink_item_url,
1649 success: function(){
1650 bundle_table.DataTable({ 'retrieve': true }).draw(false);
1659 var bundle_form_active;
1660 $("#addToBundleModal").on("shown.bs.modal", function(e){
1661 var button = $(e.relatedTarget);
1662 var item_id = button.data('item');
1663 $("#addResult").replaceWith('<div id="addResult"></div>');
1664 $("#addToBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items');
1665 $("#external_id").focus();
1667 bundle_form_active = item_id;
1670 function addToBundle (url, data) {
1671 /* Send the data using post with external_id */
1672 var posting = $.post({
1674 data: JSON.stringify(data),
1675 contentType: "application/json; charset=utf-8",
1679 const barcode = data.external_id;
1681 /* Report the results */
1682 posting.done(function(data) {
1683 $('#addResult').replaceWith('<div id="addResult" class="alert alert-success">'+_("Success: Added '%s'").format(barcode)+'</div>');
1684 $('#external_id').val('').focus();
1687 posting.fail(function(data) {
1688 if ( data.status === 409 ) {
1689 var response = data.responseJSON;
1690 if ( response.error_code === 'already_bundled' ) {
1691 $('#addResult').replaceWith('<div id="addResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
1692 } else if (response.error_code === 'bundle_checkout_out') {
1693 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
1694 } else if (response.error_code === 'checked_out') {
1695 const button = $('<button type="button">')
1696 .addClass('btn btn-xs')
1697 .text(_("Check in and add to bundle"))
1698 .on('click', function () {
1699 addToBundle(url, { external_id: barcode, force_checkin: true });
1703 .attr('class', 'alert alert-warning')
1704 .append(__x('Warning: Item {barcode} is checked out', { barcode }))
1705 .append(' ', button);
1706 } else if (response.error_code === 'failed_checkin') {
1709 .attr('class', 'alert alert-danger')
1710 .append(__x('Failure: Item {barcode} cannot be checked in', { barcode }))
1711 } else if (response.error_code === 'reserved') {
1712 const button = $('<button type="button">')
1713 .addClass('btn btn-xs')
1714 .text(_("Ignore holds and add to bundle"))
1715 .on('click', function () {
1716 addToBundle(url, { external_id: barcode, ignore_holds: true });
1720 .attr('class', 'alert alert-warning')
1721 .append(__x('Warning: Item {barcode} is on hold', { barcode }))
1722 .append(' ', button);
1724 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
1726 } else if ( data.status === 404 ) {
1727 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
1728 } else if ( data.status === 400 ) {
1729 var response = data.responseJSON;
1730 if ( response.error_code === "failed_nesting" ) {
1731 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' is a bundle and bundles cannot be nested").format(barcode)+'</div>');
1733 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
1736 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Check the logs for details.")+'</div>');
1738 $('#external_id').val('').focus();
1742 $("#addToBundleForm").submit(function(event) {
1743 /* stop form from submitting normally */
1744 event.preventDefault();
1746 const url = this.action;
1747 const data = { external_id: this.elements.external_id.value };
1749 addToBundle(url, data);
1752 $("#addToBundleModal").on("hidden.bs.modal", function(e){
1753 if ( bundle_changed ) {
1754 $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
1756 bundle_form_active = 0;
1760 $("#removeFromBundleModal").on("shown.bs.modal", function(e){
1761 var button = $(e.relatedTarget);
1762 var item_id = button.data('item');
1763 $("#removeResult").replaceWith('<div id="removeResult"></div>');
1764 $("#removeFromBundleForm").attr('action', '/api/v1/items/' + item_id + '/bundled_items/');
1765 $("#rm_external_id").focus();
1767 bundle_form_active = item_id;
1770 $("#removeFromBundleForm").submit(function(event) {
1772 /* stop form from submitting normally */
1773 event.preventDefault();
1775 /* get the action attribute from the <form action=""> element */
1776 var $form = $(this),
1777 url = $form.attr('action');
1779 var barcode = $('#rm_external_id').val();
1781 /* Fetch itemnumber using rm_external_id */
1782 var itemReq = $.get('/api/v1/items', { q: JSON.stringify({
1783 external_id: barcode
1784 }) }, null, "json");
1787 itemReq.done(function(data) {
1788 if (data.length === 1) {
1789 itemnumber = data[0].item_id;
1791 /* Remove link using fetch itemnumber */
1792 var deleteReq = $.ajax( url + itemnumber, {
1796 /* Report the results */
1797 deleteReq.done(function(data) {
1798 var barcode = $('#rm_external_id').val();
1799 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-success">'+_("Success: Removed '%s'").format(barcode)+'</div>');
1800 $('#rm_external_id').val('').focus();
1803 deleteReq.fail(function(data) {
1804 var barcode = $('#rm_external_id').val();
1805 if ( data.status === 409 ) {
1806 var response = data.responseJSON;
1807 if (response.error_code === 'bundle_checkout_out') {
1808 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Bundle is currently checked out")+'</div>');
1809 } else if ( response.key === "PRIMARY" ) {
1810 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-warning">'+_("Warning: Item '%s' already attached").format(barcode)+'</div>');
1812 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Item '%s' belongs to another bundle").format(barcode)+'</div>');
1814 } else if ( data.status === 404 ) {
1815 $('#addResult').replaceWith('<div id="addResult" class="alert alert-danger">'+_("Failure: Item '%s' not found").format(barcode)+'</div>');
1817 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failure: Check the logs for details")+'</div>');
1819 $('#rm_external_id').val('').focus();
1822 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Barcode matched more than one item '%s'").format(barcode)+'</div>');
1825 itemReq.fail(function(data) {
1826 $('#removeResult').replaceWith('<div id="removeResult" class="alert alert-danger">'+_("Failed: Item not found '%s'").format(barcode)+'</div>');
1827 $('#rm_external_id').val('').focus();
1832 $("#removeFromBundleModal").on("hidden.bs.modal", function(e){
1833 if ( bundle_changed ) {
1834 $('#bundle_table_'+bundle_form_active).DataTable({ 'retrieve': true }).ajax.reload();
1836 bundle_form_active = 0;
1839 // End bundle handling
1842 var table_ids = [ 'holdings_table', 'otherholdings_table' ];
1843 var table_settings = [ [% TablesSettings.GetTableSettings('catalogue', 'detail','holdings_table','json') | $raw %], [% TablesSettings.GetTableSettings('catalogue', 'detail','otherholdings_table','json') | $raw %] ];
1844 table_ids.forEach( function( table_id, index ) {
1846 [% IF Koha.Preference('SeparateHoldings') %]
1847 [% SET SeparateHoldingsBranch = Koha.Preference('SeparateHoldingsBranch') || 'homebranch' %];
1848 let branch = '[% IF SeparateHoldingsBranch == 'homebranch' %]home_library_id[% ELSE %]holding_library_id[% END %]';
1849 if ( table_id == 'holdings_table' ) {
1850 filters[branch] = '[% Branches.GetLoggedInBranchcode() | html %]';
1852 filters[branch] = { '!=': '[% Branches.GetLoggedInBranchcode() | html %]' };
1856 var table = build_table(table_id, table_settings[index], filters);
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,first_hold,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.patron')
2189 embed.push('in_bundle', 'bundle_host');
2190 [% IF Koha.Preference('UseCourseReserves') %]
2191 embed.push('course_item.course_reserves.course');
2194 function build_table (table_id, table_settings, filters) {
2195 [% IF hidden_count %]
2196 filters.lost_status = "0";
2198 var items_table = $("#" + table_id).kohaTable({
2199 ajax: { url: item_table_url },
2200 order: [[ 0, "asc" ]],
2203 bKohaColumnsUseNames: true, // FIXME We should not need that now, do we?
2205 [% IF (StaffDetailItemSelection) %]
2210 render: function (data, type, row, meta) {
2211 if ( can_edit_items_from[row.holding_library_id] ){
2212 return '<input type="checkbox" value="%s" name="itemnumber" />'.format(row.item_id);
2219 [% IF Koha.Preference('LocalCoverImages') %]
2225 render: function (data, type, row, meta) {
2226 if ( !row.cover_image_ids.length > 0 ) {
2229 let node = '<div class="bookcoverimg">';
2230 node += '<div class="cover-slider">';
2231 row.cover_image_ids.forEach(id => {
2232 node += '<div class="cover-image local-coverimg">';
2233 node += '<a href="/cgi-bin/koha/catalogue/image.pl?itemnumber=%s&imagenumber=%s" title="Local cover image">'.format(id, id);
2234 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);
2244 [% IF ( item_level_itypes ) %]
2246 data: "me.itype:biblioitem.itemtype",
2250 render: function (data, type, row, meta) {
2252 [% UNLESS noItemTypeImages %]
2253 let image_location = item_type_image_locations[row.item_type_id];
2254 let item_type_description = row._strings.item_type_id.str;
2255 node += image_location
2256 ? '<img src="%s" alt="%s" title="%s" /> '.format(image_location, item_type_description, item_type_description)
2259 node += '<span class="itypedesc itypetext">%s</span>'.format(item_type_description);
2265 data: "me.holding_library_id",
2266 className: "location",
2269 render: function (data, type, row, meta) {
2270 return row._strings.holding_library_id.str;
2274 data: "me.home_library_id",
2275 className: "homebranch",
2278 render: function (data, type, row, meta) {
2279 let nodes = '<span class="homebranchdesc">%s</span>'.format(row._strings.home_library_id.str);
2280 nodes += '<span class="shelvingloc">'
2281 [%# If permanent location is defined, show description or code and %]
2282 [%# display current location in parentheses. If not, display current location. %]
2283 [%# Note that permanent location is a code, and location may be an authval. %]
2284 let loc_str = row._strings.location.str;
2285 if ( row.permanent_location && row.permanent_location != row.location ) {
2286 let permanent_loc_str = av_loc[row.permanent_location];
2287 nodes += '%s (%s)'.format(permanent_loc_str, loc_str);
2296 data: "me.collection_code",
2299 render: function (data, type, row, meta) {
2300 return row._strings.collection_code.str;
2303 [% IF Koha.Preference('EnableItemGroups') %]
2305 data: "item_group_item.item_group.description",
2306 className: "item_group",
2309 render: function (data, type, row, meta) {
2310 if ( row.item_group_item ) {
2311 return row.item_group_item.item_group.description;
2319 data: "me.callnumber",
2320 className: "itemcallnumber",
2323 render: function (data, type, row, meta) {
2324 return row.callnumber;
2329 data: "me.serial_issue_number",
2330 className: "enumchron",
2333 render: function (data, type, row, meta) {
2335 [%# 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? %]
2336 let serial = row.serialitem ? row.serialitem.serial : null;
2337 if ( row.serial_issue_number && serial && serial.serialseq ) {
2338 nodes += '<span class="enum">%s</span>'.format(row.serial_issue_number);
2339 if ( serial.serialseq && row.serial_issue_number != serial.serialseq ) {
2340 nodes += ' <span class="sep"> -- </span>'
2341 nodes += ' <span class="serialseq">%s</span>'.format(serial.serialseq);
2343 } else if ( row.serial_issue_number ) {
2344 nodes += ' <span class="enum">%s</span>'.format(row.serial_issue_number);
2345 } else if ( serial && serial.serialseq ) {
2346 nodes += '<span class="serialseq">%s</span>'.format(serial.serialseq);
2348 if ( serial && serial.publisheddate ) {
2349 nodes += ' <span class="pubdate">(%s)</span>'.format($date(serial.publisheddate));
2355 data: "me.lost_status",
2356 className: "status",
2357 searchable: false, // FIXME We are losing the ability to search on the status
2359 render: function (data, type, row, meta) {
2361 if ( row.checkout ) {
2363 if ( row.checkout.onsite_checkout ) {
2364 let patron_to_html = $patron_to_html(row.checkout.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2365 nodes += _("Currently in local use by %s").format(patron_to_html);
2367 nodes += '<span class="datedue">';
2368 let patron_to_html = $patron_to_html(row.checkout.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2369 nodes += _("Checked out to %s").format(patron_to_html);
2372 nodes += _("due %s").format($date(row.checkout.due_date)); [%# FIXME Missing due date formatting here, $date do not have as_due_date option %]
2374 } else if ( row.transfer ) {
2375 if ( row.transfer.datesent ) {
2376 nodes += '<span class="intransit">%s</span>'.format(_("In transit from %s to %s since %s").format(row.transfer.frombranch, row.transfer.tobranch, $date(row.transfer.datesent))); [%# FIXME display library names, not codes, do we use _strings here? %]
2378 nodes += '<span class="transitrequested">%s</span>'.format(_("Transit pending from %s to %s since %s").format(row.transfer.frombranch, row.transfer.tobranch, $date(row.transfer.daterequested))); [%# FIXME See above %]
2382 if ( row.lost_status ) {
2383 let lost_lib = av_lost.get(row.lost_status.toString()) || _("Unavailable (lost or missing");
2384 nodes += '<span class="lost">%s</span>'.format(lost_lib);
2387 if ( row.withdrawn ) {
2388 let withdrawn_lib = av_withdrawn.get(row.withdrawn.toString()) || _("Withdrawn");
2389 nodes += '<span class="wdn">%s</span>'.format(withdrawn_lib);
2392 if ( row.damaged ) {
2393 let damaged_lib = av_damaged.get(row.damaged.toString()) || _("Damaged");
2394 nodes += '<span class="dmg">%s</span>'.format(damaged_lib);
2397 if ( row.not_for_loan_status || row.item_type.notforloan ) {
2398 let not_for_loan_lib = av_not_for_loan.get(row.not_for_loan_status.toString());
2399 nodes += '<span class="notforloan">%s'.format(_("Not for loan")) + ( not_for_loan_lib ? '<span class="reason"> (%s)</span>'.format(not_for_loan_lib) : '' ) + '</span>';
2402 if ( row.first_hold ) {
2403 if ( row.first_hold.waiting_date ) {
2404 [%# FIXME Display library names instead of codes %]
2405 [%# FIXME We lost the desk name, we need an additional embed %]
2406 nodes += '<span class="waitingat">%s</span>'.format(_("Waiting at %s since %s.".format(row.first_hold.pickup_library_id, $date(row.first_hold.waiting_date))));
2407 [% IF Koha.Preference('canreservefromotherbranches') %]
2408 if ( row.first_hold.waiting_date || row.first_hold.priority == 1 ) {
2409 let patron_to_html = $patron_to_html(row.first_hold.patron); [%# FIXME What about hide_patron_infos_if_needed?? %]
2410 nodes += ' <span class="heldfor">%s</span>'.format(_("Hold for: %s").format(patron_to_html));
2414 nodes += '<span class="holdonitem">%s</span>'.format(_("There is an item level hold on this item (priority = %s).").format(row.first_hold.priority));
2418 [% IF Koha.Preference('UseRecalls') %]
2420 if ( row.recall.waiting_date ) {
2421 nodes += '<span>%s</span>'.format(_("Waiting at %s since %s").format(row.recall.pickup_library_id, $date(row.recall.waiting_date))); # FIXME Display library names instead of codes
2423 let patron_to_html = $patron_to_html(row.recall.patron);
2424 nodes += '<span>%s</span>'.format(_("recalled by %s on %s").format(patron_to_html, row.recall.created_date))
2429 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 ) ) {
2430 nodes += ' <span>%s</span>'.format(_("Available"))
2433 if ( row.restricted_status ) {
2434 nodes += '<span class="restricted">(%s)</span>'.format(av_restricted.get(row.restricted_status.toString()));
2437 if ( row.in_bundle ) {
2438 nodes += '<span class="bundled">%s</span>'.format(_("In bundle: %s").format($biblio_to_html(row.bundle_host.biblio, { link: true })));
2444 data: "me.last_seen_date",
2445 className: "datelastseen",
2448 render: function (data, type, row, meta) {
2449 return $date(row.last_seen_date);
2453 data: "me.checkouts_count",
2454 className: "issues",
2457 render: function (data, type, row, meta) {
2458 return row.checkouts_count || 0;
2462 data: "me.renewals_count",
2463 className: "renewals",
2466 render: function (data, type, row, meta) {
2467 return row.renewals_count || 0;
2471 data: "me.acquisition_date",
2472 className: "dateaccessioned",
2475 render: function (data, type, row, meta) {
2476 return $date(row.acquisition_date);
2480 data: "me.last_checkout_date",
2481 className: "datelastborrowed",
2484 render: function (data, type, row, meta) {
2485 return $date(row.last_checkout_date);
2489 data: "me.external_id",
2493 render: function (data, type, row, meta) {
2494 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);
2502 render: function (data, type, row, meta) {
2503 if ( !row.uri ) return "";
2506 if ( row.uri.split(' \| ').length > 1 ) {
2507 row.uri.split(' \| ').forEach((uri, i) => {
2508 nodes += '<a href="%s">%s</a><br/>'.format(uri, uri);
2511 nodes += '<a href="%s">%s</a><br/>'.format(row.uri, url_link_text);
2517 data: "me.copy_number",
2518 className: "copynumber",
2521 render: function (data, type, row, meta) {
2522 return row._strings.copy_number ? row._strings.copy_number.str : row.copy_number;
2526 data: "me.inventory_number",
2527 className: "stocknumber",
2530 render: function (data, type, row, meta) {
2531 return row.inventory_number;
2535 data: "me.materials_notes",
2536 className: "materials",
2539 render: function (data, type, row, meta) {
2540 return row.materials_notes;
2544 data: "me.public_notes",
2545 className: "itemnotes",
2548 render: function (data, type, row, meta) {
2549 return row.public_notes ? row.public_notes.replaceAll('\n', '<br />') : '';
2553 data: "me.internal_notes",
2554 className: "nonpublicnote",
2557 render: function (data, type, row, meta) {
2558 return row.internal_notes;
2561 [% IF ( hostrecords ) %]
2563 data: "biblio.biblio_id",
2564 searchable: false, // FIXME
2566 render: function (data, type, row, meta) {
2567 if ( row.biblio_id == [% biblio.biblionumber | html %] ) return "";
2568 return '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=%s>%s</a>'.format(row.biblio_id, row.biblio.title);
2572 [% IF ( analyze ) %]
2575 searchable: false, // FIXME
2577 render: function (data, type, row, meta) {
2578 return ""; // FIXME Display analytic count + link
2582 [% IF Koha.Preference('UseCourseReserves') %]
2584 data: "course_item.course_reserves.course.course_name",
2587 render: function (data, type, row, meta) {
2589 if (!row.course_item) return nodes;
2590 row.course_item.course_reserves.forEach((cr, i) => {
2592 if ( c.enabled != 'yes' ) return;
2594 nodes += '<a href="/cgi-bin/koha/course_reserves/course-details.pl?course_id=%s">'.format(c.course_id);
2595 nodes += c.course_name;
2597 nodes += ' ' + c.section;
2600 nodes += ' ' + av_courses_term.get(c.term.toString());
2608 [% IF ( SpineLabelShowPrintOnBibDetails ) %]
2613 render: function (data, type, row, meta) {
2614 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(row.external_id);
2618 [% IF CAN_user_editcatalogue_edit_items %]
2620 data: function( row, type, val, meta ) {
2622 if ( can_edit_items_from[row.holding_library_id] ){
2623 [% IF Koha.Preference('LocalCoverImages') OR Koha.Preference('OPACLocalCoverImages') %]
2624 nodes += '<div class="btn-group">';
2625 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);
2626 nodes += ' <ul class="dropdown-menu pull-right">';
2627 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);
2631 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);
2634 [% IF bundlesEnabled %]
2635 // FIXME How do we handle that correctly?
2636 //nodes += '<button class="btn btn-default btn-xs details-control"><i class="fa fa-folder"></i> Manage bundle (%s|%s)</button>'.format(row.bundled, row.bundled_lost);
2641 className: "actions",
2647 initComplete: function( settings, json ){
2648 let table = settings.oInstance.api();
2649 table.columns().every(function(i){
2650 let is_empty = true;
2651 let nodes = this.nodes();
2652 nodes.each((td, ii) => {
2653 if ( $(td).html() !== '' ) {
2659 table.columns(i).visible(false);
2671 [% CoverImagePlugins | $raw %]
2673 [% INCLUDE 'intranet-bottom.inc' %]