Bug 15498: Let the user choose the CSV profile to export circ history
[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']").hide();
41     $(document).on("change", '#output_format', function(){
42         if ( $(this).val() == 'csv' ) {
43             $("select[name='csv_profile']").show();
44         } else {
45             $("select[name='csv_profile']").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                 } else {
81                     content = CIRCULATION_NOT_RETURNED;
82                     $(id).parent().parent().addClass('warn');
83                 }
84
85                 $(id).replaceWith( content );
86             }, "json")
87         });
88
89         $(".renew:checked:visible").each(function() {
90             var override_limit = $("#override_limit").is(':checked') ? 1 : 0;
91
92             var itemnumber = $(this).val();
93
94             $(this).parent().parent().replaceWith("<img id='renew_" + itemnumber + "' src='" + interface + "/" + theme + "/img/spinner-small.gif' />");
95
96             var params = {
97                 itemnumber:     itemnumber,
98                 borrowernumber: borrowernumber,
99                 branchcode:     branchcode,
100                 override_limit: override_limit,
101                 date_due:       $("#newduedate").val()
102             };
103
104             $.post( "/cgi-bin/koha/svc/renew", params, function( data ) {
105                 var id = "#renew_" + data.itemnumber;
106
107                 var content = "";
108                 if ( data.renew_okay ) {
109                     content = CIRCULATION_RENEWED_DUE + " " + data.date_due;
110                     $('#date_due_' + data.itemnumber).replaceWith( data.date_due );
111                 } else {
112                     content = CIRCULATION_RENEW_FAILED + " ";
113                     if ( data.error == "no_checkout" ) {
114                         content += NOT_CHECKED_OUT;
115                     } else if ( data.error == "too_many" ) {
116                         content += TOO_MANY_RENEWALS;
117                     } else if ( data.error == "on_reserve" ) {
118                         content += ON_RESERVE;
119                     } else if ( data.error == "restriction" ) {
120                         content += NOT_RENEWABLE_RESTRICTION;
121                     } else if ( data.error == "overdue" ) {
122                         content += NOT_RENEWABLE_OVERDUE;
123                     } else if ( data.error ) {
124                         content += data.error;
125                     } else {
126                         content += REASON_UNKNOWN;
127                     }
128                 }
129
130                 $(id).replaceWith( content );
131             }, "json")
132         });
133
134         // Refocus on barcode field if it exists
135         if ( $("#barcode").length ) {
136             $("#barcode").focus();
137         }
138
139         // Prevent form submit
140         return false;
141     });
142
143     $("#RenewAll").on("click",function(){
144         $("#CheckAllRenewals").click();
145         $("#UncheckAllCheckins").click();
146         $("#RenewCheckinChecked").click();
147
148         // Prevent form submit
149         return false;
150     });
151
152     var ymd = $.datepicker.formatDate('yy-mm-dd', new Date());
153
154     $('#issues-table').hide();
155     $('#issues-table-actions').hide();
156     $('#issues-table-load-immediately').change(function(){
157         if ( this.checked && typeof issuesTable === 'undefined') {
158             $('#issues-table-load-now-button').click();
159         }
160         barcodefield.focus();
161     });
162     $('#issues-table-load-now-button').click(function(){
163         LoadIssuesTable();
164         barcodefield.focus();
165         return false;
166     });
167
168     if ( $.cookie("issues-table-load-immediately-" + script) == "true" ) {
169         LoadIssuesTable();
170         $('#issues-table-load-immediately').prop('checked', true);
171     }
172     $('#issues-table-load-immediately').on( "change", function(){
173         $.cookie("issues-table-load-immediately-" + script, $(this).is(':checked'), { expires: 365 });
174     });
175
176     function LoadIssuesTable() {
177         $('#issues-table-loading-message').hide();
178         $('#issues-table').show();
179         $('#issues-table-actions').show();
180
181         issuesTable = KohaTable("#issues-table", {
182             "oLanguage": {
183                 "sEmptyTable" : MSG_DT_LOADING_RECORDS,
184                 "sProcessing": MSG_DT_LOADING_RECORDS,
185             },
186             "bAutoWidth": false,
187             "dom": 'B<"clearfix">rt',
188             "aoColumns": [
189                 {
190                     "mDataProp": function( oObj ) {
191                         return oObj.sort_order;
192                     }
193                 },
194                 {
195                     "mDataProp": function( oObj ) {
196                         if ( oObj.issued_today ) {
197                             return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
198                         } else {
199                             return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
200                         }
201                     }
202                 },
203                 {
204                     "mDataProp": "date_due",
205                     "bVisible": false,
206                 },
207                 {
208                     "iDataSort": 2, // Sort on hidden unformatted date due column
209                     "mDataProp": function( oObj ) {
210                         var due = oObj.date_due_formatted;
211
212                         if ( oObj.date_due_overdue ) {
213                             due = "<span class='overdue'>" + due + "</span>";
214                         }
215
216                         due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>";
217
218                         if ( oObj.lost ) {
219                             due += "<span class='lost'>" + oObj.lost + "</span>";
220                         }
221
222                         if ( oObj.damaged ) {
223                             due += "<span class='dmg'>" + oObj.damaged + "</span>";
224                         }
225
226
227                         return due;
228                     }
229                 },
230                 {
231                     "mDataProp": function ( oObj ) {
232                         title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
233                               + oObj.biblionumber
234                               + "'>"
235                               + oObj.title;
236
237                         $.each(oObj.subtitle, function( index, value ) {
238                                   title += " " + value.subfield;
239                         });
240
241                         if ( oObj.enumchron ) {
242                             title += " (" + oObj.enumchron + ")";
243                         }
244
245                         title += "</a></span>";
246
247                         if ( oObj.author ) {
248                             title += " " + BY.replace( "_AUTHOR_",  " " + oObj.author );
249                         }
250
251                         if ( oObj.itemnotes ) {
252                             var span_class = "text-muted";
253                             title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
254                         }
255
256                         if ( oObj.itemnotes_nonpublic ) {
257                             var span_class = "text-danger";
258                             title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic + "</span>"
259                         }
260
261                         var onsite_checkout = '';
262                         if ( oObj.onsite_checkout == 1 ) {
263                             onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
264                         }
265
266                         title += " "
267                               + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
268                               + oObj.biblionumber
269                               + "&itemnumber="
270                               + oObj.itemnumber
271                               + "#"
272                               + oObj.itemnumber
273                               + "'>"
274                               + oObj.barcode
275                               + "</a>"
276                               + onsite_checkout;
277
278                         return title;
279                     },
280                     "sType": "anti-the"
281                 },
282                 { "mDataProp": "itemtype_description" },
283                 { "mDataProp": "location" },
284                 { "mDataProp": "homebranch" },
285                 { "mDataProp": "issuedate_formatted" },
286                 { "mDataProp": "branchname" },
287                 { "mDataProp": "itemcallnumber" },
288                 {
289                     "mDataProp": function ( oObj ) {
290                         if ( ! oObj.charge ) oObj.charge = 0;
291                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.charge).toFixed(2) + '<span>';
292                     }
293                 },
294                 {
295                     "mDataProp": function ( oObj ) {
296                         if ( ! oObj.fine ) oObj.fine = 0;
297                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.fine).toFixed(2)  + '<span>';
298                     }
299                 },
300                 {
301                     "mDataProp": function ( oObj ) {
302                         if ( ! oObj.price ) oObj.price = 0;
303                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.price).toFixed(2) + '<span>';
304                     }
305                 },
306                 {
307                     "bSortable": false,
308                     "bVisible": AllowCirculate ? true : false,
309                     "mDataProp": function ( oObj ) {
310                         var content = "";
311                         var span_style = "";
312                         var span_class = "";
313
314                         content += "<span>";
315                         content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
316
317                         if ( oObj.can_renew ) {
318                             // Do nothing
319                         } else if ( oObj.can_renew_error == "on_reserve" ) {
320                             content += "<span class='renewals-disabled-no-override'>"
321                                     + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
322                                     + "</span>";
323
324                             span_style = "display: none";
325                             span_class = "renewals-allowed";
326                         } else if ( oObj.can_renew_error == "too_many" ) {
327                             content += "<span class='renewals-disabled'>"
328                                     + NOT_RENEWABLE
329                                     + "</span>";
330
331                             span_style = "display: none";
332                             span_class = "renewals-allowed";
333                         } else if ( oObj.can_renew_error == "restriction" ) {
334                             content += "<span class='renewals-disabled'>"
335                                     + NOT_RENEWABLE_RESTRICTION
336                                     + "</span>";
337
338                             span_style = "display: none";
339                             span_class = "renewals-allowed";
340                         } else if ( oObj.can_renew_error == "overdue" ) {
341                             content += "<span class='renewals-disabled'>"
342                                     + NOT_RENEWABLE_OVERDUE
343                                     + "</span>";
344
345                             span_style = "display: none";
346                             span_class = "renewals-allowed";
347                         } else if ( oObj.can_renew_error == "too_soon" ) {
348                             content += "<span class='renewals-disabled'>"
349                                     + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
350                                     + "</span>";
351
352                             span_style = "display: none";
353                             span_class = "renewals-allowed";
354                         } else if ( oObj.can_renew_error == "auto_too_soon" ) {
355                             content += "<span class='renewals-disabled'>"
356                                     + NOT_RENEWABLE_AUTO_TOO_SOON
357                                     + "</span>";
358
359                             span_style = "display: none";
360                             span_class = "renewals-allowed";
361                         } else if ( oObj.can_renew_error == "auto_too_late" ) {
362                             content += "<span class='renewals-disabled'>"
363                                     + NOT_RENEWABLE_AUTO_TOO_LATE
364                                     + "</span>";
365
366                             span_style = "display: none";
367                             span_class = "renewals-allowed";
368                         } else if ( oObj.can_renew_error == "auto_renew" ) {
369                             content += "<span class='renewals-disabled'>"
370                                     + NOT_RENEWABLE_AUTO_RENEW
371                                     + "</span>";
372
373                             span_style = "display: none";
374                             span_class = "renewals-allowed";
375                         } else if ( oObj.can_renew_error == "onsite_checkout" ) {
376                             // Don't display something if it's an onsite checkout
377                         } else {
378                             content += "<span class='renewals-disabled'>"
379                                     + oObj.can_renew_error
380                                     + "</span>";
381
382                             span_style = "display: none";
383                             span_class = "renewals-allowed";
384                         }
385
386                         var can_force_renew = ( oObj.onsite_checkout == 0 ) && ( oObj.can_renew_error != "on_reserve" );
387                         var can_renew = ( oObj.renewals_remaining > 0  && !oObj.can_renew_error );
388                         if ( can_renew || can_force_renew ) {
389                             content += "<span class='" + span_class + "' style='" + span_style + "'>"
390                                     +  "<input type='checkbox' ";
391                             if ( oObj.date_due_overdue && can_renew ) {
392                                 content += "checked='checked' ";
393                             }
394                             content += "class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
395                                     +  "</span>";
396
397                             content += "<span class='renewals'>("
398                                     + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
399                                     + ")</span>";
400                         }
401
402                         content += "</span>";
403
404                         return content;
405                     }
406                 },
407                 {
408                     "bSortable": false,
409                     "bVisible": AllowCirculate ? true : false,
410                     "mDataProp": function ( oObj ) {
411                         if ( oObj.can_renew_error == "on_reserve" ) {
412                             return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
413                         } else {
414                             return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
415                         }
416                     }
417                 },
418                 {
419                     "bVisible": exports_enabled ? true : false,
420                     "bSortable": false,
421                     "mDataProp": function ( oObj ) {
422                         var s = "<input type='checkbox' name='itemnumbers' value='" + oObj.itemnumber + "' style='visibility:hidden;' />";
423
424                         s += "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
425                         return s;
426                     }
427                 }
428             ],
429             "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
430                 var total_charge = 0;
431                 var total_fine  = 0;
432                 var total_price = 0;
433                 for ( var i=0; i < aaData.length; i++ ) {
434                     total_charge += aaData[i]['charge'] * 1;
435                     total_fine += aaData[i]['fine'] * 1;
436                     total_price  += aaData[i]['price'] * 1;
437                 }
438                 $("#totaldue").html(total_charge.toFixed(2));
439                 $("#totalfine").html(total_fine.toFixed(2));
440                 $("#totalprice").html(total_price.toFixed(2));
441             },
442             "bPaginate": false,
443             "bProcessing": true,
444             "bServerSide": false,
445             "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
446             "fnServerData": function ( sSource, aoData, fnCallback ) {
447                 aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
448
449                 $.getJSON( sSource, aoData, function (json) {
450                     fnCallback(json)
451                 } );
452             },
453             "fnInitComplete": function(oSettings) {
454                 // Disable rowGrouping plugin after first use
455                 // so any sorting on the table doesn't use it
456                 var oSettings = issuesTable.fnSettings();
457
458                 for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
459                     if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
460                         oSettings.aoDrawCallback.splice(f, 1);
461                         break;
462                     }
463                 }
464
465                 oSettings.aaSortingFixed = null;
466             },
467         }, columns_settings).rowGrouping(
468             {
469                 iGroupingColumnIndex: 1,
470                 iGroupingOrderByColumnIndex: 0,
471                 sGroupingColumnSortDirection: "asc"
472             }
473         );
474
475         if ( $("#issues-table").length ) {
476             $("#issues-table_processing").position({
477                 of: $( "#issues-table" ),
478                 collision: "none"
479             });
480         }
481     }
482
483     // Don't load relatives' issues table unless it is clicked on
484     var relativesIssuesTable;
485     $("#relatives-issues-tab").click( function() {
486         if ( ! relativesIssuesTable ) {
487             relativesIssuesTable = $("#relatives-issues-table").dataTable({
488                 "bAutoWidth": false,
489                 "sDom": "rt",
490                 "aaSorting": [],
491                 "aoColumns": [
492                     {
493                         "mDataProp": "date_due",
494                         "bVisible": false,
495                     },
496                     {
497                         "iDataSort": 1, // Sort on hidden unformatted date due column
498                         "mDataProp": function( oObj ) {
499                             var today = new Date();
500                             var due = new Date( oObj.date_due );
501                             if ( today > due ) {
502                                 return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
503                             } else {
504                                 return oObj.date_due_formatted;
505                             }
506                         }
507                     },
508                     {
509                         "mDataProp": function ( oObj ) {
510                             title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
511                                   + oObj.biblionumber
512                                   + "'>"
513                                   + oObj.title;
514
515                             $.each(oObj.subtitle, function( index, value ) {
516                                       title += " " + value.subfield;
517                             });
518
519                             if ( oObj.enumchron ) {
520                                 title += " (" + oObj.enumchron + ")";
521                             }
522
523                             title += "</a></span>";
524
525                             if ( oObj.author ) {
526                                 title += " " + BY.replace( "_AUTHOR_", " " + oObj.author );
527                             }
528
529                             if ( oObj.itemnotes ) {
530                                 var span_class = "";
531                                 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
532                                     span_class = "circ-hlt";
533                                 }
534                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
535                             }
536
537                             if ( oObj.itemnotes_nonpublic ) {
538                                 var span_class = "";
539                                 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
540                                     span_class = "circ-hlt";
541                                 }
542                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic + "</span>"
543                             }
544
545                             var onsite_checkout = '';
546                             if ( oObj.onsite_checkout == 1 ) {
547                                 onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
548                             }
549
550                             title += " "
551                                   + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
552                                   + oObj.biblionumber
553                                   + "&itemnumber="
554                                   + oObj.itemnumber
555                                   + "#"
556                                   + oObj.itemnumber
557                                   + "'>"
558                                   + oObj.barcode
559                                   + "</a>"
560                                   + onsite_checkout;
561
562                             return title;
563                         },
564                         "sType": "anti-the"
565                     },
566                     { "mDataProp": "itemtype" },
567                     { "mDataProp": "location" },
568                     { "mDataProp": "issuedate_formatted" },
569                     { "mDataProp": "branchname" },
570                     { "mDataProp": "itemcallnumber" },
571                     {
572                         "mDataProp": function ( oObj ) {
573                             if ( ! oObj.charge ) oObj.charge = 0;
574                             return parseFloat(oObj.charge).toFixed(2);
575                         }
576                     },
577                     {
578                         "mDataProp": function ( oObj ) {
579                             if ( ! oObj.fine ) oObj.fine = 0;
580                             return parseFloat(oObj.fine).toFixed(2);
581                         }
582                     },
583                     {
584                         "mDataProp": function ( oObj ) {
585                             if ( ! oObj.price ) oObj.price = 0;
586                             return parseFloat(oObj.price).toFixed(2);
587                         }
588                     },
589                     {
590                         "mDataProp": function( oObj ) {
591                             return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>"
592                                  + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")</a>"
593                         }
594                     },
595                 ],
596                 "bPaginate": false,
597                 "bProcessing": true,
598                 "bServerSide": false,
599                 "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
600                 "fnServerData": function ( sSource, aoData, fnCallback ) {
601                     $.each(relatives_borrowernumbers, function( index, value ) {
602                         aoData.push( { "name": "borrowernumber", "value": value } );
603                     });
604
605                     $.getJSON( sSource, aoData, function (json) {
606                         fnCallback(json)
607                     } );
608                 },
609             });
610         }
611     });
612
613     if ( $("#relatives-issues-table").length ) {
614         $("#relatives-issues-table_processing").position({
615             of: $( "#relatives-issues-table" ),
616             collision: "none"
617         });
618     }
619
620     if ( AllowRenewalLimitOverride ) {
621         $( '#override_limit' ).click( function () {
622             if ( this.checked ) {
623                 $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
624             } else {
625                 $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
626             }
627         } ).prop('checked', false);
628     }
629  });