Bug 13020 - Checkouts table default ordering is incorrect
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / js / checkouts.js
1 $(document).ready(function() {
2     $.ajaxSetup ({ cache: false });
3
4     // Handle the select all/none links for checkouts table columns
5     $("#CheckAllRenewals").on("click",function(){
6         $("#UncheckAllCheckins").click();
7         $(".renew:visible").attr("checked", "checked" );
8         return false;
9     });
10     $("#UncheckAllRenewals").on("click",function(){
11         $(".renew:visible").removeAttr("checked");
12         return false;
13     });
14
15     $("#CheckAllCheckins").on("click",function(){
16         $("#UncheckAllRenewals").click();
17         $(".checkin:visible").attr("checked", "checked" );
18         return false;
19     });
20     $("#UncheckAllCheckins").on("click",function(){
21         $(".checkin:visible").removeAttr("checked");
22         return false;
23     });
24
25     // Don't allow both return and renew checkboxes to be checked
26     $(document).on("change", '.renew', function(){
27         if ( $(this).is(":checked") ) {
28             $( "#checkin_" + $(this).val() ).removeAttr("checked");
29         }
30     });
31     $(document).on("change", '.checkin', function(){
32         if ( $(this).is(":checked") ) {
33             $( "#renew_" + $(this).val() ).removeAttr("checked");
34         }
35     });
36
37     // Clicking the table cell checks the checkbox inside it
38     $(document).on("click", 'td', function(e){
39         if(e.target.tagName.toLowerCase() == 'td'){
40           $(this).find("input:checkbox:visible").each( function() {
41             $(this).click();
42           });
43         }
44     });
45
46     // Handle renewals and returns
47     $("#RenewCheckinChecked").on("click",function(){
48         $(".checkin:checked:visible").each(function() {
49             itemnumber = $(this).val();
50
51             $(this).replaceWith("<img id='checkin_" + itemnumber + "' src='" + interface + "/" + theme + "/img/loading-small.gif' />");
52
53             params = {
54                 itemnumber:     itemnumber,
55                 borrowernumber: borrowernumber,
56                 branchcode:     branchcode,
57                 exempt_fine:    $("#exemptfine").is(':checked')
58             };
59
60             $.post( "/cgi-bin/koha/svc/checkin", params, function( data ) {
61                 id = "#checkin_" + data.itemnumber;
62
63                 content = "";
64                 if ( data.returned ) {
65                     content = CIRCULATION_RETURNED;
66                 } else {
67                     content = CIRCULATION_NOT_RETURNED;
68                 }
69
70                 $(id).replaceWith( content );
71             }, "json")
72         });
73
74         $(".renew:checked:visible").each(function() {
75             var override_limit = $("#override_limit").is(':checked') ? 1 : 0;
76
77             var itemnumber = $(this).val();
78
79             $(this).parent().parent().replaceWith("<img id='renew_" + itemnumber + "' src='" + interface + "/" + theme + "/img/loading-small.gif' />");
80
81             var params = {
82                 itemnumber:     itemnumber,
83                 borrowernumber: borrowernumber,
84                 branchcode:     branchcode,
85                 override_limit: override_limit,
86                 date_due:       $("#newduedate").val()
87             };
88
89             $.post( "/cgi-bin/koha/svc/renew", params, function( data ) {
90                 var id = "#renew_" + data.itemnumber;
91
92                 var content = "";
93                 if ( data.renew_okay ) {
94                     content = CIRCULATION_RENEWED_DUE + " " + data.date_due;
95                 } else {
96                     content = CIRCULATION_RENEW_FAILED + " ";
97                     if ( data.error == "no_checkout" ) {
98                         content += NOT_CHECKED_OUT;
99                     } else if ( data.error == "too_many" ) {
100                         content += TOO_MANY_RENEWALS;
101                     } else if ( data.error == "on_reserve" ) {
102                         content += ON_RESERVE;
103                     } else if ( data.error ) {
104                         content += data.error;
105                     } else {
106                         content += REASON_UNKNOWN;
107                     }
108                 }
109
110                 $(id).replaceWith( content );
111             }, "json")
112         });
113
114         // Prevent form submit
115         return false;
116     });
117
118     $("#RenewAll").on("click",function(){
119         $("#CheckAllRenewals").click();
120         $("#UncheckAllCheckins").click();
121         $("#RenewCheckinChecked").click();
122
123         // Prevent form submit
124         return false;
125     });
126
127     var ymd = $.datepicker.formatDate('yy-mm-dd', new Date());
128
129     $('#issues-table').hide();
130     $('#issues-table-actions').hide();
131     $('#issues-table-load-immediately').change(function(){
132         if ( this.checked && typeof issuesTable === 'undefined') {
133             $('#issues-table-load-now-button').click();
134         }
135     });
136     $('#issues-table-load-now-button').click(function(){
137         LoadIssuesTable();
138         return false;
139     });
140
141     if ( $.cookie("issues-table-load-immediately-" + script) == "true" ) {
142         LoadIssuesTable();
143         $('#issues-table-load-immediately').prop('checked', true);
144     }
145     $('#issues-table-load-immediately').on( "change", function(){
146         $.cookie("issues-table-load-immediately-" + script, $(this).is(':checked'));
147     });
148
149     function LoadIssuesTable() {
150         $('#issues-table-loading-message').hide();
151         $('#issues-table').show();
152         $('#issues-table-actions').show();
153
154         issuesTable = $("#issues-table").dataTable({
155             "oLanguage": {
156                 "sEmptyTable" : MSG_DT_LOADING_RECORDS,
157             },
158             "bAutoWidth": false,
159             "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t",
160             "aoColumns": [
161                 {
162                     "mDataProp": function( oObj ) {
163                         if ( oObj.issued_today ) {
164                             return "1" + oObj.timestamp;
165                         } else {
166                             return "0" + oObj.date_due;
167                         }
168                     }
169                 },
170                 {
171                     "mDataProp": function( oObj ) {
172                         if ( oObj.issued_today ) {
173                             return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
174                         } else {
175                             return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
176                         }
177                     }
178                 },
179                 {
180                     "mDataProp": "date_due",
181                     "bVisible": false,
182                 },
183                 {
184                     "iDataSort": 1, // Sort on hidden unformatted date due column
185                     "mDataProp": function( oObj ) {
186                         if ( oObj.date_due_overdue ) {
187                             return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
188                         } else {
189                             return oObj.date_due_formatted;
190                         }
191                     }
192                 },
193                 {
194                     "mDataProp": function ( oObj ) {
195                         title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
196                               + oObj.biblionumber
197                               + "'>"
198                               + oObj.title;
199
200                         $.each(oObj.subtitle, function( index, value ) {
201                                   title += " " + value.subfield;
202                         });
203
204                         title += "</a></span>";
205
206                         if ( oObj.author ) {
207                             title += " " + BY.replace( "_AUTHOR_",  " " + oObj.author );
208                         }
209
210                         if ( oObj.itemnotes ) {
211                             var span_class = "";
212                             if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
213                                 span_class = "circ-hlt";
214                             }
215                             title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
216                         }
217
218                         title += " "
219                               + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
220                               + oObj.biblionumber
221                               + "&itemnumber="
222                               + oObj.itemnumber
223                               + "#"
224                               + oObj.itemnumber
225                               + "'>"
226                               + oObj.barcode
227                               + "</a>";
228
229                         return title;
230                     }
231                 },
232                 { "mDataProp": "itemtype" },
233                 { "mDataProp": "issuedate_formatted" },
234                 { "mDataProp": "branchname" },
235                 { "mDataProp": "itemcallnumber" },
236                 {
237                     "mDataProp": function ( oObj ) {
238                         if ( ! oObj.charge ) oObj.charge = 0;
239                         return parseFloat(oObj.charge).toFixed(2);
240                     }
241                 },
242                 {
243                     "mDataProp": function ( oObj ) {
244                         if ( ! oObj.price ) oObj.price = 0;
245                         return parseFloat(oObj.price).toFixed(2);
246                     }
247                 },
248                 {
249                     "bSortable": false,
250                     "mDataProp": function ( oObj ) {
251                         var content = "";
252                         var span_style = "";
253                         var span_class = "";
254
255                         content += "<span>";
256                         content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
257
258                         if ( oObj.can_renew ) {
259                             // Do nothing
260                         } else if ( oObj.can_renew_error == "on_reserve" ) {
261                             content += "<span class='renewals-disabled'>"
262                                     + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
263                                     + "</span>";
264
265                             span_style = "display: none";
266                             span_class = "renewals-allowed";
267                         } else if ( oObj.can_renew_error == "too_many" ) {
268                             content += "<span class='renewals-disabled'>"
269                                     + NOT_RENEWABLE
270                                     + "</span>";
271
272                             span_style = "display: none";
273                             span_class = "renewals-allowed";
274                         } else if ( oObj.can_renew_error == "too_soon" ) {
275                             content += "<span class='renewals-disabled'>"
276                                     + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
277                                     + "</span>";
278
279                             span_style = "display: none";
280                             span_class = "renewals-allowed";
281                         } else if ( oObj.can_renew_error == "auto_too_soon" ) {
282                             content += "<span class='renewals-disabled'>"
283                                     + NOT_RENEWABLE_AUTO_TOO_SOON
284                                     + "</span>";
285
286                             span_style = "display: none";
287                             span_class = "renewals-allowed";
288                         } else if ( oObj.can_renew_error == "auto_renew" ) {
289                             content += "<span class='renewals-disabled'>"
290                                     + NOT_RENEWABLE_AUTO_RENEW
291                                     + "</span>";
292
293                             span_style = "display: none";
294                             span_class = "renewals-allowed";
295                         } else {
296                             content += "<span class='renewals-disabled'>"
297                                     + oObj.can_renew_error
298                                     + "</span>";
299
300                             span_style = "display: none";
301                             span_class = "renewals-allowed";
302                         }
303
304                         content += "<span class='" + span_class + "' style='" + span_style + "'>"
305                                 +  "<input type='checkbox' class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
306                                 +  "</span>";
307
308                         if ( oObj.renewals_remaining ) {
309                             content += "<span class='renewals'>("
310                                     + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
311                                     + ")</span>";
312                         }
313
314                         content += "</span>";
315
316
317                         return content;
318                     }
319                 },
320                 {
321                     "bSortable": false,
322                     "mDataProp": function ( oObj ) {
323                         if ( oObj.can_renew_error == "on_reserve" ) {
324                             return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
325                         } else {
326                             return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
327                         }
328                     }
329                 },
330                 {
331                     "bVisible": exports_enabled ? true : false,
332                     "bSortable": false,
333                     "mDataProp": function ( oObj ) {
334                         return "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
335                     }
336                 }
337             ],
338             "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
339                 var total_charge = 0;
340                 var total_price = 0;
341                 for ( var i=0; i < aaData.length; i++ ) {
342                     total_charge += aaData[i]['charge'] * 1;
343                     total_price  += aaData[i]['price'] * 1;
344                 }
345                 var nCells = nRow.getElementsByTagName('td');
346                 nCells[1].innerHTML = total_charge.toFixed(2);
347                 nCells[2].innerHTML = total_price.toFixed(2);
348             },
349             "bPaginate": false,
350             "bProcessing": true,
351             "bServerSide": false,
352             "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
353             "fnServerData": function ( sSource, aoData, fnCallback ) {
354                 aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
355
356                 $.getJSON( sSource, aoData, function (json) {
357                     fnCallback(json)
358                 } );
359             },
360             "fnInitComplete": function(oSettings) {
361                 // Disable rowGrouping plugin after first use
362                 // so any sorting on the table doesn't use it
363                 var oSettings = issuesTable.fnSettings();
364
365                 for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
366                     if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
367                         oSettings.aoDrawCallback.splice(f, 1);
368                         break;
369                     }
370                 }
371
372                 oSettings.aaSortingFixed = null;
373             },
374         }).rowGrouping(
375             {
376                 iGroupingColumnIndex: 1,
377                 iGroupingOrderByColumnIndex: 0,
378                 sGroupingColumnSortDirection: "desc"
379             }
380         );
381
382         if ( $("#issues-table").length ) {
383             $("#issues-table_processing").position({
384                 of: $( "#issues-table" ),
385                 collision: "none"
386             });
387         }
388     }
389
390     // Don't load relatives' issues table unless it is clicked on
391     var relativesIssuesTable;
392     $("#relatives-issues-tab").click( function() {
393         if ( ! relativesIssuesTable ) {
394             relativesIssuesTable = $("#relatives-issues-table").dataTable({
395                 "bAutoWidth": false,
396                 "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t",
397                 "aaSorting": [],
398                 "aoColumns": [
399                     {
400                         "mDataProp": "date_due",
401                         "bVisible": false,
402                     },
403                     {
404                         "iDataSort": 1, // Sort on hidden unformatted date due column
405                         "mDataProp": function( oObj ) {
406                             var today = new Date();
407                             var due = new Date( oObj.date_due );
408                             if ( today > due ) {
409                                 return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
410                             } else {
411                                 return oObj.date_due_formatted;
412                             }
413                         }
414                     },
415                     {
416                         "mDataProp": function ( oObj ) {
417                             title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
418                                   + oObj.biblionumber
419                                   + "'>"
420                                   + oObj.title;
421
422                             $.each(oObj.subtitle, function( index, value ) {
423                                       title += " " + value.subfield;
424                             });
425
426                             title += "</a></span>";
427
428                             if ( oObj.author ) {
429                                 title += " " + BY + " " + oObj.author;
430                             }
431
432                             if ( oObj.itemnotes ) {
433                                 var span_class = "";
434                                 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
435                                     span_class = "circ-hlt";
436                                 }
437                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
438                             }
439
440                             title += " "
441                                   + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
442                                   + oObj.biblionumber
443                                   + "&itemnumber="
444                                   + oObj.itemnumber
445                                   + "#"
446                                   + oObj.itemnumber
447                                   + "'>"
448                                   + oObj.barcode
449                                   + "</a>";
450
451                             return title;
452                         }
453                     },
454                     { "mDataProp": "itemtype" },
455                     { "mDataProp": "issuedate_formatted" },
456                     { "mDataProp": "branchname" },
457                     { "mDataProp": "itemcallnumber" },
458                     {
459                         "mDataProp": function ( oObj ) {
460                             if ( ! oObj.charge ) oObj.charge = 0;
461                             return parseFloat(oObj.charge).toFixed(2);
462                         }
463                     },
464                     {
465                         "mDataProp": function ( oObj ) {
466                             if ( ! oObj.price ) oObj.price = 0;
467                             return parseFloat(oObj.price).toFixed(2);
468                         }
469                     },
470                     {
471                         "mDataProp": function( oObj ) {
472                             return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>"
473                                  + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")</a>"
474                         }
475                     },
476                 ],
477                 "bPaginate": false,
478                 "bProcessing": true,
479                 "bServerSide": false,
480                 "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
481                 "fnServerData": function ( sSource, aoData, fnCallback ) {
482                     $.each(relatives_borrowernumbers, function( index, value ) {
483                         aoData.push( { "name": "borrowernumber", "value": value } );
484                     });
485
486                     $.getJSON( sSource, aoData, function (json) {
487                         fnCallback(json)
488                     } );
489                 },
490             });
491         }
492     });
493
494     if ( $("#relatives-issues-table").length ) {
495         $("#relatives-issues-table_processing").position({
496             of: $( "#relatives-issues-table" ),
497             collision: "none"
498         });
499     }
500
501     if ( AllowRenewalLimitOverride ) {
502         $( '#override_limit' ).click( function () {
503             if ( this.checked ) {
504                 $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
505             } else {
506                 $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
507             }
508         } ).attr( 'checked', false );
509     }
510  });