Bug 15494: Update display of renewal errors
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / checkouts.js
1 $(document).ready(function() {
2     $.ajaxSetup ({ cache: false });
3
4     var barcodefield = $("#barcode");
5
6     // Handle the select all/none links for checkouts table columns
7     $("#CheckAllRenewals").on("click",function(){
8         $("#UncheckAllCheckins").click();
9         $(".renew:visible").prop("checked", true);
10         return false;
11     });
12     $("#UncheckAllRenewals").on("click",function(){
13         $(".renew:visible").prop("checked", false);
14         return false;
15     });
16
17     $("#CheckAllCheckins").on("click",function(){
18         $("#UncheckAllRenewals").click();
19         $(".checkin:visible").prop("checked", true);
20         return false;
21     });
22     $("#UncheckAllCheckins").on("click",function(){
23         $(".checkin:visible").prop("checked", false);
24         return false;
25     });
26
27     // Don't allow both return and renew checkboxes to be checked
28     $(document).on("change", '.renew', function(){
29         if ( $(this).is(":checked") ) {
30             $( "#checkin_" + $(this).val() ).prop("checked", false);
31         }
32     });
33     $(document).on("change", '.checkin', function(){
34         if ( $(this).is(":checked") ) {
35             $( "#renew_" + $(this).val() ).prop("checked", false);
36         }
37     });
38
39     $("#output_format > option:first-child").attr("selected", "selected");
40     $("select[name='csv_profile_id']").hide();
41     $(document).on("change", '#issues-table-output-format', function(){
42         if ( $(this).val() == 'csv' ) {
43             $("select[name='csv_profile_id']").show();
44         } else {
45             $("select[name='csv_profile_id']").hide();
46         }
47     });
48
49     // Clicking the table cell checks the checkbox inside it
50     $(document).on("click", 'td', function(e){
51         if(e.target.tagName.toLowerCase() == 'td'){
52           $(this).find("input:checkbox:visible").each( function() {
53             $(this).click();
54           });
55         }
56     });
57
58     // Handle renewals and returns
59     $("#RenewCheckinChecked").on("click",function(){
60         $(".checkin:checked:visible").each(function() {
61             itemnumber = $(this).val();
62
63             $(this).replaceWith("<img id='checkin_" + itemnumber + "' src='" + interface + "/" + theme + "/img/spinner-small.gif' />");
64
65             params = {
66                 itemnumber:     itemnumber,
67                 borrowernumber: borrowernumber,
68                 branchcode:     branchcode,
69                 exempt_fine:    $("#exemptfine").is(':checked')
70             };
71
72             $.post( "/cgi-bin/koha/svc/checkin", params, function( data ) {
73                 id = "#checkin_" + data.itemnumber;
74
75                 content = "";
76                 if ( data.returned ) {
77                     content = CIRCULATION_RETURNED;
78                     $(id).parent().parent().addClass('ok');
79                     $('#date_due_' + data.itemnumber).html(CIRCULATION_RETURNED);
80                     if ( data.patronnote != null ) {
81                         $('.patron_note_' + data.itemnumber).html("Patron note: " + data.patronnote);
82                     }
83                 } else {
84                     content = CIRCULATION_NOT_RETURNED;
85                     $(id).parent().parent().addClass('warn');
86                 }
87
88                 $(id).replaceWith( content );
89             }, "json")
90         });
91
92         $(".renew:checked:visible").each(function() {
93             var override_limit = $("#override_limit").is(':checked') ? 1 : 0;
94
95             var itemnumber = $(this).val();
96
97             $(this).parent().parent().replaceWith("<img id='renew_" + itemnumber + "' src='" + interface + "/" + theme + "/img/spinner-small.gif' />");
98
99             var params = {
100                 itemnumber:     itemnumber,
101                 borrowernumber: borrowernumber,
102                 branchcode:     branchcode,
103                 override_limit: override_limit,
104                 date_due:       $("#newduedate").val()
105             };
106
107             $.post( "/cgi-bin/koha/svc/renew", params, function( data ) {
108                 var id = "#renew_" + data.itemnumber;
109
110                 var content = "";
111                 if ( data.renew_okay ) {
112                     content = CIRCULATION_RENEWED_DUE + " " + data.date_due;
113                     $('#date_due_' + data.itemnumber).replaceWith( data.date_due );
114                 } else {
115                     content = CIRCULATION_RENEW_FAILED + " ";
116                     if ( data.error == "no_checkout" ) {
117                         content += NOT_CHECKED_OUT;
118                     } else if ( data.error == "too_many" ) {
119                         content += TOO_MANY_RENEWALS;
120                     } else if ( data.error == "on_reserve" ) {
121                         content += ON_RESERVE;
122                     } else if ( data.error == "restriction" ) {
123                         content += NOT_RENEWABLE_RESTRICTION;
124                     } else if ( data.error == "overdue" ) {
125                         content += NOT_RENEWABLE_OVERDUE;
126                     } else if ( data.error ) {
127                         content += data.error;
128                     } else {
129                         content += REASON_UNKNOWN;
130                     }
131                 }
132
133                 $(id).replaceWith( content );
134             }, "json")
135         });
136
137         // Refocus on barcode field if it exists
138         if ( $("#barcode").length ) {
139             $("#barcode").focus();
140         }
141
142         // Prevent form submit
143         return false;
144     });
145
146     $("#RenewAll").on("click",function(){
147         $("#CheckAllRenewals").click();
148         $("#UncheckAllCheckins").click();
149         $("#RenewCheckinChecked").click();
150
151         // Prevent form submit
152         return false;
153     });
154
155     var ymd = $.datepicker.formatDate('yy-mm-dd', new Date());
156
157     $('#issues-table').hide();
158     $('#issues-table-actions').hide();
159     $('#issues-table-load-immediately').change(function(){
160         if ( this.checked && typeof issuesTable === 'undefined') {
161             $('#issues-table-load-now-button').click();
162         }
163         barcodefield.focus();
164     });
165     $('#issues-table-load-now-button').click(function(){
166         LoadIssuesTable();
167         barcodefield.focus();
168         return false;
169     });
170
171     if ( $.cookie("issues-table-load-immediately-" + script) == "true" ) {
172         LoadIssuesTable();
173         $('#issues-table-load-immediately').prop('checked', true);
174     }
175     $('#issues-table-load-immediately').on( "change", function(){
176         $.cookie("issues-table-load-immediately-" + script, $(this).is(':checked'), { expires: 365 });
177     });
178
179     function LoadIssuesTable() {
180         $('#issues-table-loading-message').hide();
181         $('#issues-table').show();
182         $('#issues-table-actions').show();
183
184         issuesTable = KohaTable("issues-table", {
185             "oLanguage": {
186                 "sEmptyTable" : MSG_DT_LOADING_RECORDS,
187                 "sProcessing": MSG_DT_LOADING_RECORDS,
188             },
189             "bAutoWidth": false,
190             "dom": 'B<"clearfix">rt',
191             "aoColumns": [
192                 {
193                     "mDataProp": function( oObj ) {
194                         return oObj.sort_order;
195                     }
196                 },
197                 {
198                     "mDataProp": function( oObj ) {
199                         if ( oObj.issued_today ) {
200                             return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
201                         } else {
202                             return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
203                         }
204                     }
205                 },
206                 {
207                     "mDataProp": "date_due",
208                     "bVisible": false,
209                 },
210                 {
211                     "iDataSort": 2, // Sort on hidden unformatted date due column
212                     "mDataProp": function( oObj ) {
213                         var due = oObj.date_due_formatted;
214
215                         if ( oObj.date_due_overdue ) {
216                             due = "<span class='overdue'>" + due + "</span>";
217                         }
218
219                         due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>";
220
221                         if ( oObj.lost ) {
222                             due += "<span class='lost'>" + oObj.lost.escapeHtml() + "</span>";
223                         }
224
225                         if ( oObj.damaged ) {
226                             due += "<span class='dmg'>" + oObj.damaged.escapeHtml() + "</span>";
227                         }
228
229                         var patron_note = " <span class='patron_note_" + oObj.itemnumber + "'></span>";
230                         due +="<br>" + patron_note;
231
232                         return due;
233                     }
234                 },
235                 {
236                     "mDataProp": function ( oObj ) {
237                         title = "<span id='title_" + oObj.itemnumber + "' class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
238                               + oObj.biblionumber
239                               + "'>"
240                               + oObj.title.escapeHtml();
241
242                         $.each(oObj.subtitle, function( index, value ) {
243                                   title += " " + value.subfield.escapeHtml();
244                         });
245
246                         if ( oObj.enumchron ) {
247                             title += " (" + oObj.enumchron.escapeHtml() + ")";
248                         }
249
250                         title += "</a></span>";
251
252                         if ( oObj.author ) {
253                             title += " " + BY.replace( "_AUTHOR_",  " " + oObj.author.escapeHtml() );
254                         }
255
256                         if ( oObj.itemnotes ) {
257                             var span_class = "text-muted";
258                             if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
259                                 span_class = "circ-hlt";
260                             }
261                             title += " - <span class='" + span_class + " item-note-public'>" + oObj.itemnotes.escapeHtml() + "</span>";
262                         }
263
264                         if ( oObj.itemnotes_nonpublic ) {
265                             var span_class = "text-danger";
266                             if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
267                                 span_class = "circ-hlt";
268                             }
269                             title += " - <span class='" + span_class + " item-note-nonpublic'>" + oObj.itemnotes_nonpublic.escapeHtml() + "</span>";
270                         }
271
272                         var onsite_checkout = '';
273                         if ( oObj.onsite_checkout == 1 ) {
274                             onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
275                         }
276
277                         title += " "
278                               + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
279                               + oObj.biblionumber
280                               + "&itemnumber="
281                               + oObj.itemnumber
282                               + "#"
283                               + oObj.itemnumber
284                               + "'>"
285                               + oObj.barcode.escapeHtml()
286                               + "</a>"
287                               + onsite_checkout
288
289                         return title;
290                     },
291                     "sType": "anti-the"
292                 },
293                 {
294                     "mDataProp": function ( oObj ) {
295                         return oObj.itemtype_description.escapeHtml();
296                     }
297                 },
298                 {
299                     "mDataProp": function ( oObj ) {
300                         return ( oObj.collection ? oObj.collection.escapeHtml() : '' );
301                     }
302                 },
303                 {
304                     "mDataProp": function ( oObj ) {
305                         return ( oObj.location ? oObj.location.escapeHtml() : '' );
306                     }
307                 },
308                 {
309                     "mDataProp": function ( oObj ) {
310                         return oObj.homebranch.escapeHtml();
311                     }
312                 },
313                 {
314                     "mDataProp": "issuedate",
315                     "bVisible": false,
316                 },
317                 {
318                     "iDataSort": 9, // Sort on hidden unformatted issuedate column
319                     "mDataProp": "issuedate_formatted",
320                 },
321                 {
322                     "mDataProp": function ( oObj ) {
323                         return oObj.branchname.escapeHtml();
324                     }
325                 },
326                 {
327                     "mDataProp": function ( oObj ) {
328                         return ( oObj.itemcallnumber ? oObj.itemcallnumber.escapeHtml() : '' );
329                     }
330                 },
331                 {
332                     "mDataProp": function ( oObj ) {
333                         if ( ! oObj.charge ) oObj.charge = 0;
334                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.charge).toFixed(2) + '<span>';
335                     }
336                 },
337                 {
338                     "mDataProp": function ( oObj ) {
339                         if ( ! oObj.fine ) oObj.fine = 0;
340                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.fine).toFixed(2)  + '<span>';
341                     }
342                 },
343                 {
344                     "mDataProp": function ( oObj ) {
345                         if ( ! oObj.price ) oObj.price = 0;
346                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.price).toFixed(2) + '<span>';
347                     }
348                 },
349                 {
350                     "bSortable": false,
351                     "bVisible": AllowCirculate ? true : false,
352                     "mDataProp": function ( oObj ) {
353                         var content = "";
354                         var span_style = "";
355                         var span_class = "";
356
357                         content += "<span>";
358                         content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
359
360                         if ( oObj.can_renew ) {
361                             // Do nothing
362                         } else if ( oObj.can_renew_error == "on_reserve" ) {
363                             content += "<span class='renewals-disabled-no-override'>"
364                                     + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
365                                     + "</span>";
366
367                             span_style = "display: none";
368                             span_class = "renewals-allowed";
369                         } else if ( oObj.can_renew_error == "too_many" ) {
370                             content += "<span class='renewals-disabled'>"
371                                     + NOT_RENEWABLE
372                                     + "</span>";
373
374                             span_style = "display: none";
375                             span_class = "renewals-allowed";
376                         } else if ( oObj.can_renew_error == "restriction" ) {
377                             content += "<span class='renewals-disabled'>"
378                                     + NOT_RENEWABLE_RESTRICTION
379                                     + "</span>";
380
381                             span_style = "display: none";
382                             span_class = "renewals-allowed";
383                         } else if ( oObj.can_renew_error == "overdue" ) {
384                             content += "<span class='renewals-disabled'>"
385                                     + NOT_RENEWABLE_OVERDUE
386                                     + "</span>";
387
388                             span_style = "display: none";
389                             span_class = "renewals-allowed";
390                         } else if ( oObj.can_renew_error == "too_soon" ) {
391                             content += "<span class='renewals-disabled'>"
392                                     + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
393                                     + "</span>";
394
395                             span_style = "display: none";
396                             span_class = "renewals-allowed";
397                         } else if ( oObj.can_renew_error == "auto_too_soon" ) {
398                             content += "<span class='renewals-disabled'>"
399                                     + NOT_RENEWABLE_AUTO_TOO_SOON
400                                     + "</span>";
401
402                             span_style = "display: none";
403                             span_class = "renewals-allowed";
404                         } else if ( oObj.can_renew_error == "auto_too_late" ) {
405                             content += "<span class='renewals-disabled'>"
406                                     + NOT_RENEWABLE_AUTO_TOO_LATE
407                                     + "</span>";
408
409                             span_style = "display: none";
410                             span_class = "renewals-allowed";
411                         } else if ( oObj.can_renew_error == "auto_too_much_oweing" ) {
412                             content += "<span class='renewals-disabled'>"
413                                     + NOT_RENEWABLE_AUTO_TOO_MUCH_OWEING
414                                     + "</span>";
415
416                             span_style = "display: none";
417                             span_class = "renewals-allowed";
418                         } else if ( oObj.can_renew_error == "auto_account_expired" ) {
419                             content += "<span class='renewals-disabled'>"
420                                     + NOT_RENEWABLE_AUTO_ACCOUNT_EXPIRED
421                                     + "</span>";
422
423                             span_style = "display: none";
424                             span_class = "renewals-allowed";
425                         } else if ( oObj.can_renew_error == "auto_renew" ) {
426                             content += "<span class='renewals-disabled'>"
427                                     + NOT_RENEWABLE_AUTO_RENEW
428                                     + "</span>";
429
430                             span_style = "display: none";
431                             span_class = "renewals-allowed";
432                         } else if ( oObj.can_renew_error == "onsite_checkout" ) {
433                             // Don't display something if it's an onsite checkout
434                         } else if ( oObj.can_renew_error == "item_denied_renewal" ) {
435                             content += "<span class='renewals-disabled'>"
436                                     + NOT_RENEWABLE_DENIED
437                                     + "</span>";
438
439                             span_style = "display: none";
440                             span_class = "renewals-allowed";
441                         } else {
442                             content += "<span class='renewals-disabled'>"
443                                     + oObj.can_renew_error
444                                     + "</span>";
445
446                             span_style = "display: none";
447                             span_class = "renewals-allowed";
448                         }
449
450                         var can_force_renew = ( oObj.onsite_checkout == 0 ) && ( oObj.can_renew_error != "on_reserve" );
451                         var can_renew = ( oObj.renewals_remaining > 0  && !oObj.can_renew_error );
452                         if ( can_renew || can_force_renew ) {
453                             content += "<span class='" + span_class + "' style='" + span_style + "'>"
454                                     +  "<input type='checkbox' ";
455                             if ( oObj.date_due_overdue && can_renew ) {
456                                 content += "checked='checked' ";
457                             }
458                             content += "class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
459                                     +  "</span>";
460
461                             content += "<span class='renewals'>("
462                                     + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
463                                     + ")</span>";
464                         }
465
466                         content += "</span>";
467
468                         return content;
469                     }
470                 },
471                 {
472                     "bSortable": false,
473                     "bVisible": AllowCirculate ? true : false,
474                     "mDataProp": function ( oObj ) {
475                         if ( oObj.can_renew_error == "on_reserve" ) {
476                             return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
477                         } else {
478                             return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
479                         }
480                     }
481                 },
482                 {
483                     "bVisible": exports_enabled == 1 ? true : false,
484                     "bSortable": false,
485                     "mDataProp": function ( oObj ) {
486                         var s = "<input type='checkbox' name='itemnumbers' value='" + oObj.itemnumber + "' style='visibility:hidden;' />";
487
488                         s += "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
489                         return s;
490                     }
491                 }
492             ],
493             "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
494                 var total_charge = 0;
495                 var total_fine  = 0;
496                 var total_price = 0;
497                 for ( var i=0; i < aaData.length; i++ ) {
498                     total_charge += aaData[i]['charge'] * 1;
499                     total_fine += aaData[i]['fine'] * 1;
500                     total_price  += aaData[i]['price'] * 1;
501                 }
502                 $("#totaldue").html(total_charge.toFixed(2));
503                 $("#totalfine").html(total_fine.toFixed(2));
504                 $("#totalprice").html(total_price.toFixed(2));
505             },
506             "bPaginate": false,
507             "bProcessing": true,
508             "bServerSide": false,
509             "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
510             "fnServerData": function ( sSource, aoData, fnCallback ) {
511                 aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
512
513                 $.getJSON( sSource, aoData, function (json) {
514                     fnCallback(json)
515                 } );
516             },
517             "fnInitComplete": function(oSettings, json) {
518                 // Disable rowGrouping plugin after first use
519                 // so any sorting on the table doesn't use it
520                 var oSettings = issuesTable.fnSettings();
521
522                 for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
523                     if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
524                         oSettings.aoDrawCallback.splice(f, 1);
525                         break;
526                     }
527                 }
528
529                 oSettings.aaSortingFixed = null;
530
531                 // Build a summary of checkouts grouped by itemtype
532                 var checkoutsByItype = json.aaData.reduce(function (obj, row) {
533                     obj[row.itemtype_description] = (obj[row.itemtype_description] || 0) + 1;
534                     return obj;
535                 }, {});
536                 var ul = $('<ul>');
537                 Object.keys(checkoutsByItype).sort().forEach(function (itype) {
538                     var li = $('<li>')
539                         .append($('<strong>').html(itype || MSG_NO_ITEMTYPE))
540                         .append(': ' + checkoutsByItype[itype]);
541                     ul.append(li);
542                 })
543                 $('<details>')
544                     .addClass('checkouts-by-itemtype')
545                     .append($('<summary>').html(MSG_CHECKOUTS_BY_ITEMTYPE))
546                     .append(ul)
547                     .insertBefore(oSettings.nTableWrapper)
548             },
549         }, columns_settings).rowGrouping(
550             {
551                 iGroupingColumnIndex: 1,
552                 iGroupingOrderByColumnIndex: 0,
553                 sGroupingColumnSortDirection: "asc"
554             }
555         );
556
557         if ( $("#issues-table").length ) {
558             $("#issues-table_processing").position({
559                 of: $( "#issues-table" ),
560                 collision: "none"
561             });
562         }
563     }
564
565     // Don't load relatives' issues table unless it is clicked on
566     var relativesIssuesTable;
567     $("#relatives-issues-tab").click( function() {
568         if ( ! relativesIssuesTable ) {
569             relativesIssuesTable = $("#relatives-issues-table").dataTable({
570                 "bAutoWidth": false,
571                 "sDom": "rt",
572                 "aaSorting": [],
573                 "aoColumns": [
574                     {
575                         "mDataProp": "date_due",
576                         "bVisible": false,
577                     },
578                     {
579                         "iDataSort": 0, // Sort on hidden unformatted date due column
580                         "mDataProp": function( oObj ) {
581                             var today = new Date();
582                             var due = new Date( oObj.date_due );
583                             if ( today > due ) {
584                                 return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
585                             } else {
586                                 return oObj.date_due_formatted;
587                             }
588                         }
589                     },
590                     {
591                         "mDataProp": function ( oObj ) {
592                             title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
593                                   + oObj.biblionumber
594                                   + "'>"
595                                   + oObj.title.escapeHtml();
596
597                             $.each(oObj.subtitle, function( index, value ) {
598                                       title += " " + value.subfield.escapeHtml();
599                             });
600
601                             if ( oObj.enumchron ) {
602                                 title += " (" + oObj.enumchron.escapeHtml() + ")";
603                             }
604
605                             title += "</a></span>";
606
607                             if ( oObj.author ) {
608                                 title += " " + BY.replace( "_AUTHOR_", " " + oObj.author.escapeHtml() );
609                             }
610
611                             if ( oObj.itemnotes ) {
612                                 var span_class = "";
613                                 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
614                                     span_class = "circ-hlt";
615                                 }
616                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes.escapeHtml() + "</span>"
617                             }
618
619                             if ( oObj.itemnotes_nonpublic ) {
620                                 var span_class = "";
621                                 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
622                                     span_class = "circ-hlt";
623                                 }
624                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic.escapeHtml() + "</span>"
625                             }
626
627                             var onsite_checkout = '';
628                             if ( oObj.onsite_checkout == 1 ) {
629                                 onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
630                             }
631
632                             title += " "
633                                   + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
634                                   + oObj.biblionumber
635                                   + "&itemnumber="
636                                   + oObj.itemnumber
637                                   + "#"
638                                   + oObj.itemnumber
639                                   + "'>"
640                                   + oObj.barcode.escapeHtml()
641                                   + "</a>"
642                                   + onsite_checkout;
643
644                             return title;
645                         },
646                         "sType": "anti-the"
647                     },
648                     {
649                         "mDataProp": function ( oObj ) {
650                             return oObj.itemtype_description.escapeHtml();
651                         }
652                     },
653                     {
654                         "mDataProp": function ( oObj ) {
655                             return ( oObj.collection ? oObj.collection.escapeHtml() : '' );
656                         }
657                     },
658                     {
659                         "mDataProp": function ( oObj ) {
660                             return ( oObj.location ? oObj.location.escapeHtml() : '' );
661                         }
662                     },
663                     {
664                         "mDataProp": "issuedate",
665                         "bVisible": false,
666                     },
667                     {
668                         "iDataSort": 7, // Sort on hidden unformatted issuedate column
669                         "mDataProp": "issuedate_formatted",
670                     },
671                     {
672                         "mDataProp": function ( oObj ) {
673                             return oObj.branchname.escapeHtml();
674                         }
675                     },
676                     {
677                         "mDataProp": function ( oObj ) {
678                             return ( oObj.itemcallnumber ? oObj.itemcallnumber.escapeHtml() : '' );
679                         }
680                     },
681                     {
682                         "mDataProp": function ( oObj ) {
683                             if ( ! oObj.charge ) oObj.charge = 0;
684                             return parseFloat(oObj.charge).toFixed(2);
685                         }
686                     },
687                     {
688                         "mDataProp": function ( oObj ) {
689                             if ( ! oObj.fine ) oObj.fine = 0;
690                             return parseFloat(oObj.fine).toFixed(2);
691                         }
692                     },
693                     {
694                         "mDataProp": function ( oObj ) {
695                             if ( ! oObj.price ) oObj.price = 0;
696                             return parseFloat(oObj.price).toFixed(2);
697                         }
698                     },
699                     {
700                         "mDataProp": function( oObj ) {
701                             return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>"
702                                 + oObj.borrower.firstname.escapeHtml()
703                                 + " " +
704                                 oObj.borrower.surname.escapeHtml()
705                                 + " (" + oObj.borrower.cardnumber.escapeHtml() + ")</a>"
706                         }
707                     },
708                 ],
709                 "bPaginate": false,
710                 "bProcessing": true,
711                 "bServerSide": false,
712                 "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
713                 "fnServerData": function ( sSource, aoData, fnCallback ) {
714                     $.each(relatives_borrowernumbers, function( index, value ) {
715                         aoData.push( { "name": "borrowernumber", "value": value } );
716                     });
717
718                     $.getJSON( sSource, aoData, function (json) {
719                         fnCallback(json)
720                     } );
721                 },
722             });
723         }
724     });
725
726     if ( $("#relatives-issues-table").length ) {
727         $("#relatives-issues-table_processing").position({
728             of: $( "#relatives-issues-table" ),
729             collision: "none"
730         });
731     }
732
733     if ( AllowRenewalLimitOverride ) {
734         $( '#override_limit' ).click( function () {
735             if ( this.checked ) {
736                 $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
737             } else {
738                 $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
739             }
740         } ).prop('checked', false);
741     }
742  });