1 $(document).ready(function() {
2 $.ajaxSetup ({ cache: false });
4 var barcodefield = $("#barcode");
6 var onHoldDueDateSet = false;
8 var onHoldChecked = function() {
10 $('input[data-on-reserve]').each(function() {
11 if ($(this).is(':checked')) {
18 var showHideOnHoldRenewal = function() {
19 // Display the date input
20 if (onHoldChecked()) {
21 $('#newonholdduedate').show()
23 $('#newonholdduedate').hide();
27 // Handle the select all/none links for checkouts table columns
28 $("#CheckAllRenewals").on("click",function(){
29 $("#UncheckAllCheckins").click();
30 $(".renew:visible").prop("checked", true);
31 showHideOnHoldRenewal();
34 $("#UncheckAllRenewals").on("click",function(){
35 $(".renew:visible").prop("checked", false);
36 showHideOnHoldRenewal();
40 $("#CheckAllCheckins").on("click",function(){
41 $("#UncheckAllRenewals").click();
42 $(".checkin:visible").prop("checked", true);
45 $("#UncheckAllCheckins").on("click",function(){
46 $(".checkin:visible").prop("checked", false);
50 $("#newduedate").on("change", function() {
51 if (!onHoldDueDateSet) {
52 $('#newonholdduedate input').val($('#newduedate').val());
56 $("#newonholdduedate").on("change", function() {
57 onHoldDueDateSet = true;
60 // Don't allow both return and renew checkboxes to be checked
61 $(document).on("change", '.renew', function(){
62 if ( $(this).is(":checked") ) {
63 $( "#checkin_" + $(this).val() ).prop("checked", false);
66 $(document).on("change", '.checkin', function(){
67 if ( $(this).is(":checked") ) {
68 $( "#renew_" + $(this).val() ).prop("checked", false);
72 // Display on hold due dates input when an on hold item is
74 $(document).on('change', '.renew', function(){
75 showHideOnHoldRenewal();
78 $("#output_format > option:first-child").attr("selected", "selected");
79 $("select[name='csv_profile_id']").hide();
80 $(document).on("change", '#issues-table-output-format', function(){
81 if ( $(this).val() == 'csv' ) {
82 $("select[name='csv_profile_id']").show();
84 $("select[name='csv_profile_id']").hide();
88 // Clicking the table cell checks the checkbox inside it
89 $(document).on("click", 'td', function(e){
90 if(e.target.tagName.toLowerCase() == 'td'){
91 $(this).find("input:checkbox:visible").each( function() {
97 // Handle renewals and returns
98 $("#RenewCheckinChecked").on("click",function(){
99 $(".checkin:checked:visible").each(function() {
100 itemnumber = $(this).val();
102 $(this).replaceWith("<img id='checkin_" + itemnumber + "' src='" + interface + "/" + theme + "/img/spinner-small.gif' />");
105 itemnumber: itemnumber,
106 borrowernumber: borrowernumber,
107 branchcode: branchcode,
108 exempt_fine: $("#exemptfine").is(':checked')
111 $.post( "/cgi-bin/koha/svc/checkin", params, function( data ) {
112 id = "#checkin_" + data.itemnumber;
115 if ( data.returned ) {
116 content = CIRCULATION_RETURNED;
117 $(id).parent().parent().addClass('ok');
118 $('#date_due_' + data.itemnumber).html(CIRCULATION_RETURNED);
119 if ( data.patronnote != null ) {
120 $('.patron_note_' + data.itemnumber).html("Patron note: " + data.patronnote);
123 content = CIRCULATION_NOT_RETURNED;
124 $(id).parent().parent().addClass('warn');
127 $(id).replaceWith( content );
131 $(".renew:checked:visible").each(function() {
132 var override_limit = $("#override_limit").is(':checked') ? 1 : 0;
134 var isOnReserve = $(this).data().hasOwnProperty('onReserve');
136 var itemnumber = $(this).val();
138 $(this).parent().parent().replaceWith("<img id='renew_" + itemnumber + "' src='" + interface + "/" + theme + "/img/spinner-small.gif' />");
141 itemnumber: itemnumber,
142 borrowernumber: borrowernumber,
143 branchcode: branchcode,
144 override_limit: override_limit,
147 // Determine which due date we need to use
148 var dueDate = isOnReserve ?
149 $("#newonholdduedate input").val() :
150 $("#newduedate").val();
152 if (dueDate && dueDate.length > 0) {
153 params.date_due = dueDate
156 $.post( "/cgi-bin/koha/svc/renew", params, function( data ) {
157 var id = "#renew_" + data.itemnumber;
160 if ( data.renew_okay ) {
161 content = CIRCULATION_RENEWED_DUE + " " + data.date_due;
162 $('#date_due_' + data.itemnumber).replaceWith( data.date_due );
164 content = CIRCULATION_RENEW_FAILED + " ";
165 if ( data.error == "no_checkout" ) {
166 content += NOT_CHECKED_OUT;
167 } else if ( data.error == "too_many" ) {
168 content += TOO_MANY_RENEWALS;
169 } else if ( data.error == "on_reserve" ) {
170 content += ON_RESERVE;
171 } else if ( data.error == "restriction" ) {
172 content += NOT_RENEWABLE_RESTRICTION;
173 } else if ( data.error == "overdue" ) {
174 content += NOT_RENEWABLE_OVERDUE;
175 } else if ( data.error ) {
176 content += data.error;
178 content += REASON_UNKNOWN;
182 $(id).replaceWith( content );
186 // Refocus on barcode field if it exists
187 if ( $("#barcode").length ) {
188 $("#barcode").focus();
191 // Prevent form submit
195 $("#RenewAll").on("click",function(){
196 $("#CheckAllRenewals").click();
197 $("#UncheckAllCheckins").click();
198 showHideOnHoldRenewal();
199 $("#RenewCheckinChecked").click();
201 // Prevent form submit
205 var ymd = $.datepicker.formatDate('yy-mm-dd', new Date());
207 $('#issues-table').hide();
208 $('#issues-table-actions').hide();
209 $('#issues-table-load-immediately').change(function(){
210 if ( this.checked && typeof issuesTable === 'undefined') {
211 $('#issues-table-load-now-button').click();
213 barcodefield.focus();
215 $('#issues-table-load-now-button').click(function(){
217 barcodefield.focus();
221 if ( $.cookie("issues-table-load-immediately-" + script) == "true" ) {
223 $('#issues-table-load-immediately').prop('checked', true);
225 $('#issues-table-load-immediately').on( "change", function(){
226 $.cookie("issues-table-load-immediately-" + script, $(this).is(':checked'), { expires: 365 });
229 function LoadIssuesTable() {
230 $('#issues-table-loading-message').hide();
231 $('#issues-table').show();
232 $('#issues-table-actions').show();
234 issuesTable = KohaTable("issues-table", {
236 "sEmptyTable" : MSG_DT_LOADING_RECORDS,
237 "sProcessing": MSG_DT_LOADING_RECORDS,
240 "dom": 'B<"clearfix">rt',
243 "mDataProp": function( oObj ) {
244 return oObj.sort_order;
248 "mDataProp": function( oObj ) {
249 if ( oObj.issued_today ) {
250 return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
252 return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
257 "mDataProp": "date_due",
261 "iDataSort": 2, // Sort on hidden unformatted date due column
262 "mDataProp": function( oObj ) {
263 var due = oObj.date_due_formatted;
265 if ( oObj.date_due_overdue ) {
266 due = "<span class='overdue'>" + due + "</span>";
269 due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>";
272 due += "<span class='lost'>" + oObj.lost.escapeHtml() + "</span>";
275 if ( oObj.damaged ) {
276 due += "<span class='dmg'>" + oObj.damaged.escapeHtml() + "</span>";
279 var patron_note = " <span class='patron_note_" + oObj.itemnumber + "'></span>";
280 due +="<br>" + patron_note;
286 "mDataProp": function ( oObj ) {
287 title = "<span id='title_" + oObj.itemnumber + "' class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
290 + oObj.title.escapeHtml();
292 $.each(oObj.subtitle, function( index, value ) {
293 title += " " + value.escapeHtml();
296 title += " " + oObj.part_number + " " + oObj.part_name;
298 if ( oObj.enumchron ) {
299 title += " (" + oObj.enumchron.escapeHtml() + ")";
302 title += "</a></span>";
305 title += " " + BY.replace( "_AUTHOR_", " " + oObj.author.escapeHtml() );
308 if ( oObj.itemnotes ) {
309 var span_class = "text-muted";
310 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
311 span_class = "circ-hlt";
313 title += " - <span class='" + span_class + " item-note-public'>" + oObj.itemnotes.escapeHtml() + "</span>";
316 if ( oObj.itemnotes_nonpublic ) {
317 var span_class = "text-danger";
318 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
319 span_class = "circ-hlt";
321 title += " - <span class='" + span_class + " item-note-nonpublic'>" + oObj.itemnotes_nonpublic.escapeHtml() + "</span>";
324 var onsite_checkout = '';
325 if ( oObj.onsite_checkout == 1 ) {
326 onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
330 + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
337 + oObj.barcode.escapeHtml()
346 "mDataProp": function ( oObj ) {
347 return oObj.itemtype_description.escapeHtml();
351 "mDataProp": function ( oObj ) {
352 return ( oObj.collection ? oObj.collection.escapeHtml() : '' );
356 "mDataProp": function ( oObj ) {
357 return ( oObj.location ? oObj.location.escapeHtml() : '' );
361 "mDataProp": function ( oObj ) {
362 return oObj.homebranch.escapeHtml();
366 "mDataProp": "issuedate",
370 "iDataSort": 9, // Sort on hidden unformatted issuedate column
371 "mDataProp": "issuedate_formatted",
374 "mDataProp": function ( oObj ) {
375 return oObj.branchname.escapeHtml();
379 "mDataProp": function ( oObj ) {
380 return ( oObj.itemcallnumber ? oObj.itemcallnumber.escapeHtml() : '' );
384 "mDataProp": function ( oObj ) {
385 if ( ! oObj.charge ) oObj.charge = 0;
386 return '<span style="text-align: right; display: block;">' + parseFloat(oObj.charge).toFixed(2) + '<span>';
390 "mDataProp": function ( oObj ) {
391 if ( ! oObj.fine ) oObj.fine = 0;
392 return '<span style="text-align: right; display: block;">' + parseFloat(oObj.fine).toFixed(2) + '<span>';
396 "mDataProp": function ( oObj ) {
397 if ( ! oObj.price ) oObj.price = 0;
398 return '<span style="text-align: right; display: block;">' + parseFloat(oObj.price).toFixed(2) + '<span>';
403 "bVisible": AllowCirculate ? true : false,
404 "mDataProp": function ( oObj ) {
410 if ( oObj.can_renew ) {
412 } else if ( oObj.can_renew_error == "on_reserve" ) {
414 + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
417 span_style = "display: none";
418 span_class = "renewals-allowed-on_reserve";
419 } else if ( oObj.can_renew_error == "too_many" ) {
420 msg += "<span class='renewals-disabled'>"
424 span_style = "display: none";
425 span_class = "renewals-allowed";
426 } else if ( oObj.can_renew_error == "restriction" ) {
427 msg += "<span class='renewals-disabled'>"
428 + NOT_RENEWABLE_RESTRICTION
431 span_style = "display: none";
432 span_class = "renewals-allowed";
433 } else if ( oObj.can_renew_error == "overdue" ) {
434 msg += "<span class='renewals-disabled'>"
435 + NOT_RENEWABLE_OVERDUE
438 span_style = "display: none";
439 span_class = "renewals-allowed";
440 } else if ( oObj.can_renew_error == "too_soon" ) {
441 msg += "<span class='renewals-disabled'>"
442 + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
445 span_style = "display: none";
446 span_class = "renewals-allowed";
447 } else if ( oObj.can_renew_error == "auto_too_soon" ) {
448 msg += "<span class='renewals-disabled'>"
449 + NOT_RENEWABLE_AUTO_TOO_SOON
452 span_style = "display: none";
453 span_class = "renewals-allowed";
454 } else if ( oObj.can_renew_error == "auto_too_late" ) {
455 msg += "<span class='renewals-disabled'>"
456 + NOT_RENEWABLE_AUTO_TOO_LATE
459 span_style = "display: none";
460 span_class = "renewals-allowed";
461 } else if ( oObj.can_renew_error == "auto_too_much_oweing" ) {
462 msg += "<span class='renewals-disabled'>"
463 + NOT_RENEWABLE_AUTO_TOO_MUCH_OWEING
466 span_style = "display: none";
467 span_class = "renewals-allowed";
468 } else if ( oObj.can_renew_error == "auto_account_expired" ) {
469 msg += "<span class='renewals-disabled'>"
470 + NOT_RENEWABLE_AUTO_ACCOUNT_EXPIRED
473 span_style = "display: none";
474 span_class = "renewals-allowed";
475 } else if ( oObj.can_renew_error == "auto_renew" ) {
476 msg += "<span class='renewals-disabled'>"
477 + NOT_RENEWABLE_AUTO_RENEW
480 span_style = "display: none";
481 span_class = "renewals-allowed";
482 } else if ( oObj.can_renew_error == "onsite_checkout" ) {
483 // Don't display something if it's an onsite checkout
484 } else if ( oObj.can_renew_error == "item_denied_renewal" ) {
485 content += "<span class='renewals-disabled'>"
486 + NOT_RENEWABLE_DENIED
489 span_style = "display: none";
490 span_class = "renewals-allowed";
492 msg += "<span class='renewals-disabled'>"
493 + oObj.can_renew_error
496 span_style = "display: none";
497 span_class = "renewals-allowed";
500 var can_force_renew = ( oObj.onsite_checkout == 0 ) &&
501 ( oObj.can_renew_error != "on_reserve" || (oObj.can_renew_error == "on_reserve" && AllowRenewalOnHoldOverride))
503 var can_renew = ( oObj.renewals_remaining > 0 && !oObj.can_renew_error );
505 if ( can_renew || can_force_renew ) {
506 content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
507 content += "<span class='" + span_class + "' style='" + span_style + "'>"
508 + "<input type='checkbox' ";
509 if ( oObj.date_due_overdue && can_renew ) {
510 content += "checked='checked' ";
512 if (oObj.can_renew_error == "on_reserve") {
513 content += "data-on-reserve ";
515 content += "class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
519 if ( can_renew || can_force_renew ) {
520 content += "<span class='renewals'>("
521 + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
525 content += "</span>";
532 "bVisible": AllowCirculate ? true : false,
533 "mDataProp": function ( oObj ) {
534 if ( oObj.can_renew_error == "on_reserve" ) {
535 return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
537 return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
542 "bVisible": exports_enabled == 1 ? true : false,
544 "mDataProp": function ( oObj ) {
545 var s = "<input type='checkbox' name='itemnumbers' value='" + oObj.itemnumber + "' style='visibility:hidden;' />";
547 s += "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
552 "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
553 var total_charge = 0;
556 for ( var i=0; i < aaData.length; i++ ) {
557 total_charge += aaData[i]['charge'] * 1;
558 total_fine += aaData[i]['fine'] * 1;
559 total_price += aaData[i]['price'] * 1;
561 $("#totaldue").html(total_charge.toFixed(2));
562 $("#totalfine").html(total_fine.toFixed(2));
563 $("#totalprice").html(total_price.toFixed(2));
567 "bServerSide": false,
568 "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
569 "fnServerData": function ( sSource, aoData, fnCallback ) {
570 aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
572 $.getJSON( sSource, aoData, function (json) {
576 "fnInitComplete": function(oSettings, json) {
577 // Disable rowGrouping plugin after first use
578 // so any sorting on the table doesn't use it
579 var oSettings = issuesTable.fnSettings();
581 for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
582 if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
583 oSettings.aoDrawCallback.splice(f, 1);
588 oSettings.aaSortingFixed = null;
590 // Build a summary of checkouts grouped by itemtype
591 var checkoutsByItype = json.aaData.reduce(function (obj, row) {
592 obj[row.itemtype_description] = (obj[row.itemtype_description] || 0) + 1;
596 Object.keys(checkoutsByItype).sort().forEach(function (itype) {
598 .append($('<strong>').html(itype || MSG_NO_ITEMTYPE))
599 .append(': ' + checkoutsByItype[itype]);
603 .addClass('checkouts-by-itemtype')
604 .append($('<summary>').html(MSG_CHECKOUTS_BY_ITEMTYPE))
606 .insertBefore(oSettings.nTableWrapper)
608 }, columns_settings_issues_table).rowGrouping(
610 iGroupingColumnIndex: 1,
611 iGroupingOrderByColumnIndex: 0,
612 sGroupingColumnSortDirection: "asc"
616 if ( $("#issues-table").length ) {
617 $("#issues-table_processing").position({
618 of: $( "#issues-table" ),
624 // Don't load relatives' issues table unless it is clicked on
625 var relativesIssuesTable;
626 $("#relatives-issues-tab").click( function() {
627 if ( ! relativesIssuesTable ) {
628 relativesIssuesTable = $("#relatives-issues-table").dataTable({
634 "mDataProp": "date_due",
638 "iDataSort": 0, // Sort on hidden unformatted date due column
639 "mDataProp": function( oObj ) {
640 var today = new Date();
641 var due = new Date( oObj.date_due );
643 return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
645 return oObj.date_due_formatted;
650 "mDataProp": function ( oObj ) {
651 title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
654 + oObj.title.escapeHtml();
656 $.each(oObj.subtitle, function( index, value ) {
657 title += " " + value.escapeHtml();
660 title += " " + oObj.part_number + " " + oObj.part_name;
662 if ( oObj.enumchron ) {
663 title += " (" + oObj.enumchron.escapeHtml() + ")";
666 title += "</a></span>";
669 title += " " + BY.replace( "_AUTHOR_", " " + oObj.author.escapeHtml() );
672 if ( oObj.itemnotes ) {
674 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
675 span_class = "circ-hlt";
677 title += " - <span class='" + span_class + "'>" + oObj.itemnotes.escapeHtml() + "</span>"
680 if ( oObj.itemnotes_nonpublic ) {
682 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
683 span_class = "circ-hlt";
685 title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic.escapeHtml() + "</span>"
688 var onsite_checkout = '';
689 if ( oObj.onsite_checkout == 1 ) {
690 onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
694 + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
701 + oObj.barcode.escapeHtml()
710 "mDataProp": function ( oObj ) {
711 return oObj.itemtype_description.escapeHtml();
715 "mDataProp": function ( oObj ) {
716 return ( oObj.collection ? oObj.collection.escapeHtml() : '' );
720 "mDataProp": function ( oObj ) {
721 return ( oObj.location ? oObj.location.escapeHtml() : '' );
725 "mDataProp": "issuedate",
729 "iDataSort": 7, // Sort on hidden unformatted issuedate column
730 "mDataProp": "issuedate_formatted",
733 "mDataProp": function ( oObj ) {
734 return oObj.branchname.escapeHtml();
738 "mDataProp": function ( oObj ) {
739 return ( oObj.itemcallnumber ? oObj.itemcallnumber.escapeHtml() : '' );
743 "mDataProp": function ( oObj ) {
744 if ( ! oObj.charge ) oObj.charge = 0;
745 return parseFloat(oObj.charge).toFixed(2);
749 "mDataProp": function ( oObj ) {
750 if ( ! oObj.fine ) oObj.fine = 0;
751 return parseFloat(oObj.fine).toFixed(2);
755 "mDataProp": function ( oObj ) {
756 if ( ! oObj.price ) oObj.price = 0;
757 return parseFloat(oObj.price).toFixed(2);
761 "mDataProp": function( oObj ) {
762 return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>"
763 + oObj.borrower.firstname.escapeHtml()
765 oObj.borrower.surname.escapeHtml()
766 + " (" + oObj.borrower.cardnumber.escapeHtml() + ")</a>"
772 "bServerSide": false,
773 "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
774 "fnServerData": function ( sSource, aoData, fnCallback ) {
775 $.each(relatives_borrowernumbers, function( index, value ) {
776 aoData.push( { "name": "borrowernumber", "value": value } );
779 $.getJSON( sSource, aoData, function (json) {
787 if ( $("#relatives-issues-table").length ) {
788 $("#relatives-issues-table_processing").position({
789 of: $( "#relatives-issues-table" ),
794 if ( AllowRenewalLimitOverride || AllowRenewalOnHoldOverride ) {
795 $( '#override_limit' ).click( function () {
796 if ( this.checked ) {
797 if ( AllowRenewalLimitOverride ) {
798 $( '.renewals-allowed' ).show();
799 $( '.renewals-disabled' ).hide();
801 if ( AllowRenewalOnHoldOverride ) {
802 $( '.renewals-allowed-on_reserve' ).show();
805 $( '.renewals-allowed' ).hide();
806 $( '.renewals-allowed-on_reserve' ).hide();
807 $( '.renewals-disabled' ).show();
809 } ).prop('checked', false);