Bugzilla – Attachment 48107 Details for
Bug 15219
Server-side processing and pagination on checkouts tables
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 15219: Server-side processing and pagination on checkouts tables
Bug-15219-Server-side-processing-and-pagination-on.patch (text/plain), 58.24 KB, created by
Julian Maurice
on 2016-02-16 10:33:34 UTC
(
hide
)
Description:
Bug 15219: Server-side processing and pagination on checkouts tables
Filename:
MIME Type:
Creator:
Julian Maurice
Created:
2016-02-16 10:33:34 UTC
Size:
58.24 KB
patch
obsolete
>From 4ef962321bb8c20b9eadfd98af462b2c700023e8 Mon Sep 17 00:00:00 2001 >From: Julian Maurice <julian.maurice@biblibre.com> >Date: Wed, 18 Nov 2015 15:52:14 +0100 >Subject: [PATCH] Bug 15219: Server-side processing and pagination on checkouts > tables > >Some libraries have patrons with more than 1000 checkouts. Loading all >of them at once can be very long, and sometimes can cause timeout >errors. >This patch prevent that by enabling server-side processing and >pagination on checkouts tables. >This affects patron's checkouts and patron's relatives' checkouts tables >on pages circ/circulation.pl and members/moremember.pl. > >As server-side processing can be useless and cumbersome with small >sets of data, a new system preference is introduced to control this >behaviour (server-side processing is disabled by default). > >Additionally, this patch: >- adds a switch to turn off and on row grouping (today's checkouts vs > previous checkouts) (on by default) >- adds "column settings" for relatives' checkouts tables >- factorize some code that was duplicated across the two DataTables > configurations (mDataProp) > >Test plan: >1. Find (or create) a patron that have at least 10 checkouts and where > the relatives checkouts table contain at least 10 checkouts. >2. Go to the patron's detail page and check everything works fine > in both tables (sorting, pagination, the data itself, ...) >3. Do the same on circulation page (circulation.pl) >4. Enable system preference ServerSideCheckoutsTable >5. Repeat steps 2 and 3 >--- > admin/columns_settings.yml | 60 +- > installer/data/mysql/atomicupdate/bug_15219.sql | 2 + > installer/data/mysql/sysprefs.sql | 1 + > .../plugins/jquery.dataTables.rowGrouping.js | 10 +- > .../prog/en/includes/checkouts-table-footer.inc | 2 +- > .../prog/en/includes/checkouts-table.inc | 1 - > .../prog/en/includes/checkouts.js.inc | 24 + > .../prog/en/includes/columns_settings.inc | 2 +- > .../intranet-tmpl/prog/en/includes/datatables.inc | 20 +- > .../intranet-tmpl/prog/en/includes/strings.inc | 1 + > koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js | 689 +++++++++++---------- > .../en/modules/admin/preferences/circulation.pref | 6 + > .../prog/en/modules/circ/circulation.tt | 13 +- > .../prog/en/modules/members/moremember.tt | 12 +- > svc/checkouts | 108 ++-- > 15 files changed, 495 insertions(+), 456 deletions(-) > create mode 100644 installer/data/mysql/atomicupdate/bug_15219.sql > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/checkouts.js.inc > >diff --git a/admin/columns_settings.yml b/admin/columns_settings.yml >index a412986..236804b 100644 >--- a/admin/columns_settings.yml >+++ b/admin/columns_settings.yml >@@ -187,7 +187,7 @@ modules: > moremember: > issues-table: > - >- columnname: sort_order >+ columnname: group_order > cannot_be_toggled: 1 > cannot_be_modified: 1 > is_hidden: 1 >@@ -197,11 +197,6 @@ modules: > cannot_be_modified: 1 > is_hidden: 1 > - >- columnname: due_date_unformatted >- cannot_be_toggled: 1 >- cannot_be_modified: 1 >- is_hidden: 1 >- - > columnname: due_date > - > columnname: title >@@ -233,6 +228,29 @@ modules: > columnname: export > cannot_be_toggled: 1 > cannot_be_modified: 1 >+ relatives-issues-table: >+ - >+ columnname: due_date >+ - >+ columnname: title >+ - >+ columnname: item_type >+ - >+ columnname: location >+ - >+ columnname: checkout_on >+ - >+ columnname: checkout_from >+ - >+ columnname: callno >+ - >+ columnname: charge >+ - >+ columnname: fine >+ - >+ columnname: price >+ - >+ columnname: patron > > reports: > lostitems: >@@ -270,7 +288,7 @@ modules: > circulation: > issues-table: > - >- columnname: sort_order >+ columnname: group_order > cannot_be_toggled: 1 > cannot_be_modified: 1 > is_hidden: 1 >@@ -280,11 +298,6 @@ modules: > cannot_be_modified: 1 > is_hidden: 1 > - >- columnname: due_date_unformatted >- cannot_be_toggled: 1 >- cannot_be_modified: 1 >- is_hidden: 1 >- - > columnname: due_date > - > columnname: title >@@ -316,3 +329,26 @@ modules: > columnname: export > cannot_be_toggled: 1 > cannot_be_modified: 1 >+ relatives-issues-table: >+ - >+ columnname: due_date >+ - >+ columnname: title >+ - >+ columnname: item_type >+ - >+ columnname: location >+ - >+ columnname: checkout_on >+ - >+ columnname: checkout_from >+ - >+ columnname: callno >+ - >+ columnname: charge >+ - >+ columnname: fine >+ - >+ columnname: price >+ - >+ columnname: patron >diff --git a/installer/data/mysql/atomicupdate/bug_15219.sql b/installer/data/mysql/atomicupdate/bug_15219.sql >new file mode 100644 >index 0000000..a186d45 >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_15219.sql >@@ -0,0 +1,2 @@ >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) >+VALUES ('ServerSideCheckoutsTables','0',NULL,'If enabled, use the "server-side processing" feature for checkouts tables. Can improve performance when there is a big number of checkouts to display.','YesNo'); >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index 96ea9ad..a1d6e4e 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -413,6 +413,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` > ('SelfCheckTimeout','120','','Define the number of seconds before the Web-based Self Checkout times out a patron','Integer'), > ('SeparateHoldings','0',NULL,'Separate current branch holdings from other holdings','YesNo'), > ('SeparateHoldingsBranch','homebranch','homebranch|holdingbranch','Branch used to separate holdings','Choice'), >+('ServerSideCheckoutsTables','0',NULL,'If enabled, use the "server-side processing" feature for checkouts tables. Can improve performance when there is a big number of checkouts per patron.','YesNo'), > ('SessionRestrictionByIP','1','Check for change in remote IP address for session security. Disable only when remote IP address changes frequently.','','YesNo'), > ('SessionStorage','mysql','mysql|Pg|tmp','Use database or a temporary file for storing session data','Choice'), > ('ShelfBrowserUsesCcode','1','0','Use the item collection code when finding items for the shelf browser.','YesNo'), >diff --git a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js >index 126ff63..12a88e4 100644 >--- a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js >+++ b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js >@@ -608,15 +608,15 @@ > > } > >- oTable.fnSetColumnVis(properties.iGroupingColumnIndex, !properties.bHideGroupingColumn); >+ oTable.fnSetColumnVis(properties.iGroupingColumnIndex, !properties.bHideGroupingColumn, false); > if (properties.bCustomColumnOrdering) { >- oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex, !properties.bHideGroupingOrderByColumn); >+ oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex, !properties.bHideGroupingOrderByColumn, false); > } > if (properties.iGroupingColumnIndex2 != -1) { >- oTable.fnSetColumnVis(properties.iGroupingColumnIndex2, !properties.bHideGroupingColumn2); >+ oTable.fnSetColumnVis(properties.iGroupingColumnIndex2, !properties.bHideGroupingColumn2, false); > } > if (properties.bCustomColumnOrdering2) { >- oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex2, !properties.bHideGroupingOrderByColumn2); >+ oTable.fnSetColumnVis(properties.iGroupingOrderByColumnIndex2, !properties.bHideGroupingOrderByColumn2, false); > } > oTable.fnSettings().aoDrawCallback.push({ > "fn": _fnDrawCallBackWithGrouping, >@@ -687,4 +687,4 @@ > > }); > }; >-})(jQuery); >\ No newline at end of file >+})(jQuery); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc >index 0039c8e..b23aa24 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc >@@ -1,6 +1,6 @@ > <tfoot> > <tr> >- <td colspan="10" style="text-align: right; font-weight:bold;">Totals:</td> >+ <td colspan="9" style="text-align: right; font-weight:bold;">Totals:</td> > <td id="totaldue" style="text-align: right;">[% totaldue %]</td> > <td id="totalfine" style="text-align: right;">[% finetotal %]</td> > <td id="totalprice" style="text-align: right;">[% totalprice %]</td> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >index 88d4e5c..5f53d1d 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >@@ -12,7 +12,6 @@ > <th scope="col"> </th> > <th scope="col"> </th> > <th scope="col">Due date</th> >- <th scope="col">Due date</th> > <th scope="col">Title</th> > <th scope="col">Item type</th> > <th scope="col">Location</th> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts.js.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts.js.inc >new file mode 100644 >index 0000000..97ec3be >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts.js.inc >@@ -0,0 +1,24 @@ >+[% USE Koha %] >+ >+<script> >+ [% IF Koha.Preference('ServerSideCheckoutsTables') %] >+ var ServerSideCheckoutsTables = true; >+ [% ELSE %] >+ var ServerSideCheckoutsTables = false; >+ [% END %] >+ var AllowCirculate = [% (CAN_user_circulate_circulate_remaining_permissions)? 1 : 0 %]; >+ var AllowRenewalLimitOverride = [% (CAN_user_circulate_override_renewals && AllowRenewalLimitOverride)? 1 : 0 %]; >+ >+ var MSG_DT_LOADING_RECORDS = _("Loading... you may continue scanning."); >+ >+ var borrowernumber = "[% borrowernumber %]"; >+ var relatives_borrowernumbers = new Array(); >+ [% FOREACH b IN relatives_borrowernumbers %] >+ relatives_borrowernumbers.push("[% b %]"); >+ [% END %] >+ >+ var columns_settings = [% ColumnsSettings.GetColumns( 'circ', 'circulation', 'issues-table', 'json' ) %]; >+ var relatives_columns_settings = [% ColumnsSettings.GetColumns( 'circ', 'circulation', 'relatives-issues-table', 'json' ) %]; >+</script> >+ >+<script type="text/javascript" src="[% themelang %]/js/checkouts.js"></script> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc >index ec86690..394ded4 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc >@@ -25,7 +25,7 @@ function KohaTable(selector, dt_parameters, columns_settings) { > var table = $(selector).dataTable($.extend(true, {}, dataTablesDefaults, dt_parameters)); > > $(hidden_ids).each(function(index, value) { >- table.fnSetColumnVis( value, false ); >+ table.fnSetColumnVis( value, false, false ); > }); > > return table; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/datatables.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/datatables.inc >index 4381b01..8760f54 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/datatables.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/datatables.inc >@@ -1,22 +1,4 @@ > [% INCLUDE 'format_price.inc' %] > <script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.dataTables.min.js"></script> >-<script type="text/javascript"> >-//<![CDATA[ >- var MSG_DT_FIRST = _("First"); >- var MSG_DT_LAST = _("Last"); >- var MSG_DT_NEXT = _("Next"); >- var MSG_DT_PREVIOUS = _("Previous"); >- var MSG_DT_EMPTY_TABLE = _("No data available in table"); >- var MSG_DT_INFO = _("Showing _START_ to _END_ of _TOTAL_"); >- var MSG_DT_INFO_EMPTY = _("No entries to show"); >- var MSG_DT_INFO_FILTERED = _("(filtered from _MAX_ total entries)"); >- var MSG_DT_LENGTH_MENU = _("Show _MENU_ entries"); >- var MSG_DT_LOADING_RECORDS = _("Loading..."); >- var MSG_DT_PROCESSING = _("Processing..."); >- var MSG_DT_SEARCH = _("Search:"); >- var MSG_DT_ZERO_RECORDS = _("No matching records found"); >- var MSG_DT_ALL = _("All"); >- var CONFIG_EXCLUDE_ARTICLES_FROM_SORT = _("a an the"); >-//]]> >-</script> >+[% INCLUDE 'datatables-strings.inc' %] > <script type="text/javascript" src="[% themelang %]/js/datatables.js"></script> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >index 62af2a3..222e888 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >@@ -38,5 +38,6 @@ > var SUSPEND_HOLD_ERROR_DATE = _("Unable to suspend hold, invalid date"); > var SUSPEND_HOLD_ERROR_NOT_FOUND = _("Unable to suspend hold, hold not found"); > var RESUME_HOLD_ERROR_NOT_FOUND = _("Unable to resume, hold not found"); >+ var GROUP_TODAYS_CHECKOUTS = _("Group today's checkouts"); > //]]> > </script> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js b/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js >index 3c07960..e6f9b53 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js >+++ b/koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js >@@ -1,3 +1,242 @@ >+(function($) { >+ >+var ymd = $.datepicker.formatDate('yy-mm-dd', new Date()); >+ >+function enableGrouping(datatable) { >+ datatable.rowGrouping({ >+ iGroupingColumnIndex: 1, >+ iGroupingOrderByColumnIndex: 0, >+ sGroupingColumnSortDirection: "desc" >+ }); >+} >+ >+function disableGrouping(datatable) { >+ var oSettings = datatable.fnSettings(); >+ for (f = 0; f < oSettings.aoDrawCallback.length; f++) { >+ if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') { >+ oSettings.aoDrawCallback.splice(f, 1); >+ oSettings.aaSortingFixed = null; >+ datatable.fnDraw(); >+ break; >+ } >+ } >+} >+ >+var mRenders = { >+ groupOrder: function (oData, sType, oObj) { >+ if ( oObj.issued_today ) { >+ return "1"; >+ } else { >+ return "0"; >+ } >+ }, >+ groupName: function (oData, sType, oObj) { >+ if (oObj.issued_today) { >+ return "<strong>" + TODAYS_CHECKOUTS + "</strong>"; >+ } else { >+ return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>"; >+ } >+ }, >+ dateDueFormatted: function (oData, sType, oObj) { >+ var due = oObj.date_due_formatted; >+ >+ if (oObj.date_due_overdue) { >+ due = "<span class='overdue'>" + due + "</span>"; >+ } >+ >+ if (oObj.lost) { >+ due += "<span class='lost'>" + oObj.lost + "</span>"; >+ } >+ >+ if (oObj.damaged) { >+ due += "<span class='dmg'>" + oObj.damaged + "</span>"; >+ } >+ >+ due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>"; >+ >+ return due; >+ }, >+ title: function (oData, sType, oObj) { >+ var title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber=" >+ + oObj.biblionumber >+ + "'>" >+ + oObj.title; >+ >+ $.each(oObj.subtitle, function (index, value) { >+ title += " " + value.subfield; >+ }); >+ >+ title += "</a></span>"; >+ >+ if (oObj.author) { >+ title += " " + BY.replace("_AUTHOR_", " " + oObj.author); >+ } >+ >+ if (oObj.itemnotes) { >+ var span_class = ""; >+ if ($.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate)) == ymd) { >+ span_class = "circ-hlt"; >+ } >+ title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>" >+ } >+ >+ if ( oObj.itemnotes_nonpublic ) { >+ var span_class = ""; >+ if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >+ span_class = "circ-hlt"; >+ } >+ title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic + "</span>" >+ } >+ >+ var onsite_checkout = ''; >+ if (oObj.onsite_checkout == 1) { >+ onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>"; >+ } >+ >+ title += " " >+ + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=" >+ + oObj.biblionumber >+ + "&itemnumber=" >+ + oObj.itemnumber >+ + "#" >+ + oObj.itemnumber >+ + "'>" >+ + oObj.barcode >+ + "</a>" >+ + onsite_checkout; >+ >+ return title; >+ }, >+ itemtype: function (oData, sType, oObj) { >+ return oObj.itemtype_description; >+ }, >+ issuedate: function (oData, sType, oObj) { >+ return oObj.issuedate_formatted; >+ }, >+ branch: function (oData, sType, oObj) { >+ return oObj.branchname; >+ }, >+ charge: function (oData, sType, oObj) { >+ if (!oObj.charge) oObj.charge = 0; >+ return '<span style="text-align: right; display: block;">' + parseFloat(oObj.charge).toFixed(2) + '<span>'; >+ }, >+ fine: function (oData, sType, oObj) { >+ if (!oObj.fine) oObj.fine = 0; >+ return '<span style="text-align: right; display: block;">' + parseFloat(oObj.fine).toFixed(2) + '<span>'; >+ }, >+ price: function (oData, sType, oObj) { >+ if (!oObj.price) oObj.price = 0; >+ return parseFloat(oObj.price).toFixed(2); >+ }, >+ renew: function (oData, sType, oObj) { >+ var content = ""; >+ var span_style = ""; >+ var span_class = ""; >+ >+ content += "<span>"; >+ content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>"; >+ >+ if (oObj.can_renew) { >+ // Do nothing >+ } else if (oObj.can_renew_error == "on_reserve") { >+ content += "<span class='renewals-disabled-no-override'>" >+ + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>" >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if (oObj.can_renew_error == "too_many") { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if (oObj.can_renew_error == "restriction") { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_RESTRICTION >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if (oObj.can_renew_error == "overdue") { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_OVERDUE >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if (oObj.can_renew_error == "too_soon") { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date ) >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if (oObj.can_renew_error == "auto_too_soon") { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_AUTO_TOO_SOON >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if (oObj.can_renew_error == "auto_renew") { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_AUTO_RENEW >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if (oObj.can_renew_error == "onsite_checkout") { >+ // Don't display something if it's an onsite checkout >+ } else { >+ content += "<span class='renewals-disabled'>" >+ + oObj.can_renew_error >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } >+ >+ var can_force_renew = (oObj.onsite_checkout == 0) && (oObj.can_renew_error != "on_reserve"); >+ var can_renew = (oObj.renewals_remaining > 0 && !oObj.can_renew_error); >+ if (can_renew || can_force_renew) { >+ content += "<span class='" + span_class + "' style='" + span_style + "'>" >+ + "<input type='checkbox' "; >+ if (oObj.date_due_overdue && can_renew) { >+ content += "checked='checked' "; >+ } >+ content += "class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>" >+ + "</span>"; >+ >+ content += "<span class='renewals'>(" >+ + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed ) >+ + ")</span>"; >+ } >+ >+ content += "</span>"; >+ >+ return content; >+ }, >+ checkin: function (oData, sType, oObj) { >+ if (oObj.can_renew_error == "on_reserve") { >+ return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"; >+ } else { >+ return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>"; >+ } >+ }, >+ export: function (oData, sType, oObj) { >+ var s = "<input type='checkbox' name='itemnumbers' value='" + oObj.itemnumber + "' style='visibility:hidden;' />"; >+ >+ s += "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />"; >+ return s; >+ }, >+ patron: function (oData, sType, oObj) { >+ return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>" >+ + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")</a>" >+ } >+}; >+ > $(document).ready(function() { > $.ajaxSetup ({ cache: false }); > >@@ -139,8 +378,6 @@ $(document).ready(function() { > return false; > }); > >- var ymd = $.datepicker.formatDate('yy-mm-dd', new Date()); >- > $('#issues-table').hide(); > $('#issues-table-actions').hide(); > $('#issues-table-load-immediately').change(function(){ >@@ -174,16 +411,24 @@ $(document).ready(function() { > "sProcessing": MSG_DT_LOADING_RECORDS, > }, > "bAutoWidth": false, >- "sDom": 'C<"clearfix">rt', >+ "bProcessing": true, >+ "bServerSide": ServerSideCheckoutsTables, >+ "sAjaxSource": "/cgi-bin/koha/svc/checkouts", >+ "fnServerParams": function (aoData) { >+ aoData.push({ "name": "borrowernumber", "value": borrowernumber }); >+ }, >+ "bPaginate": true, >+ "sPaginationType": "four_button", >+ "sDom": 'C<"top pager"ilp>rt', >+ "aaSorting": [], > "aoColumns": [ > { >- "mDataProp": function( oObj ) { >- return oObj.sort_order; >- } >+ "mData": "issued_today", >+ "mRender": mRenders.groupOrder > }, > { >- "mDataProp": function( oObj ) { >- if ( oObj.issued_today ) { >+ "mData": function (oObj) { >+ if (oObj.issued_today) { > return "<strong>" + TODAYS_CHECKOUTS + "</strong>"; > } else { > return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>"; >@@ -191,222 +436,56 @@ $(document).ready(function() { > } > }, > { >- "mDataProp": "date_due", >- "bVisible": false, >+ "mData": "date_due", >+ "mRender": mRenders.dateDueFormatted > }, > { >- "iDataSort": 2, // Sort on hidden unformatted date due column >- "mDataProp": function( oObj ) { >- var due = oObj.date_due_formatted; >- >- if ( oObj.date_due_overdue ) { >- due = "<span class='overdue'>" + due + "</span>"; >- } >- >- if ( oObj.lost ) { >- due += "<span class='lost'>" + oObj.lost + "</span>"; >- } >- >- if ( oObj.damaged ) { >- due += "<span class='dmg'>" + oObj.damaged + "</span>"; >- } >- >- due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>"; >- >- return due; >- } >+ "mData": "title", >+ "mRender": mRenders.title > }, > { >- "mDataProp": function ( oObj ) { >- title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber=" >- + oObj.biblionumber >- + "'>" >- + oObj.title; >- >- $.each(oObj.subtitle, function( index, value ) { >- title += " " + value.subfield; >- }); >- >- title += "</a></span>"; >- >- if ( oObj.author ) { >- title += " " + BY.replace( "_AUTHOR_", " " + oObj.author ); >- } >- >- if ( oObj.itemnotes ) { >- var span_class = ""; >- if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >- span_class = "circ-hlt"; >- } >- title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>" >- } >- >- if ( oObj.itemnotes_nonpublic ) { >- var span_class = ""; >- if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >- span_class = "circ-hlt"; >- } >- title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic + "</span>" >- } >- >- var onsite_checkout = ''; >- if ( oObj.onsite_checkout == 1 ) { >- onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>"; >- } >- >- title += " " >- + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=" >- + oObj.biblionumber >- + "&itemnumber=" >- + oObj.itemnumber >- + "#" >- + oObj.itemnumber >- + "'>" >- + oObj.barcode >- + "</a>" >- + onsite_checkout; >- >- return title; >- }, >- "sType": "anti-the" >+ "mData": "itemtype", >+ "mRender": mRenders.itemtype > }, >- { "mDataProp": "itemtype_description" }, >- { "mDataProp": "location" }, >- { "mDataProp": "issuedate_formatted" }, >- { "mDataProp": "branchname" }, >- { "mDataProp": "itemcallnumber" }, >+ { "mData": "location" }, > { >- "mDataProp": function ( oObj ) { >- if ( ! oObj.charge ) oObj.charge = 0; >- return '<span style="text-align: right; display: block;">' + parseFloat(oObj.charge).toFixed(2) + '<span>'; >- } >+ "mData": "issuedate", >+ "mRender": mRenders.issuedate > }, > { >- "mDataProp": function ( oObj ) { >- if ( ! oObj.fine ) oObj.fine = 0; >- return '<span style="text-align: right; display: block;">' + parseFloat(oObj.fine).toFixed(2) + '<span>'; >- } >+ "mData": "branchcode", >+ "mRender": mRenders.branch > }, >+ { "mData": "itemcallnumber" }, > { >- "mDataProp": function ( oObj ) { >- if ( ! oObj.price ) oObj.price = 0; >- return '<span style="text-align: right; display: block;">' + parseFloat(oObj.price).toFixed(2) + '<span>'; >- } >+ "mData": "charge", >+ "mRender": mRenders.charge, >+ "bSortable": ServerSideCheckoutsTables ? false : true >+ }, >+ { >+ "mData": "fine", >+ "mRender": mRenders.fine, >+ "bSortable": ServerSideCheckoutsTables ? false : true >+ }, >+ { >+ "mData": "replacementprice", >+ "mRender": mRenders.price, >+ "bSortable": ServerSideCheckoutsTables ? false : true > }, > { >- "bSortable": false, > "bVisible": AllowCirculate ? true : false, >- "mDataProp": function ( oObj ) { >- var content = ""; >- var span_style = ""; >- var span_class = ""; >- >- content += "<span>"; >- content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>"; >- >- if ( oObj.can_renew ) { >- // Do nothing >- } else if ( oObj.can_renew_error == "on_reserve" ) { >- content += "<span class='renewals-disabled-no-override'>" >- + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>" >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "too_many" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "restriction" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_RESTRICTION >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "overdue" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_OVERDUE >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "too_soon" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date ) >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "auto_too_soon" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_AUTO_TOO_SOON >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "auto_renew" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_AUTO_RENEW >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "onsite_checkout" ) { >- // Don't display something if it's an onsite checkout >- } else { >- content += "<span class='renewals-disabled'>" >- + oObj.can_renew_error >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } >- >- var can_force_renew = ( oObj.onsite_checkout == 0 ) && ( oObj.can_renew_error != "on_reserve" ); >- var can_renew = ( oObj.renewals_remaining > 0 && !oObj.can_renew_error ); >- if ( can_renew || can_force_renew ) { >- content += "<span class='" + span_class + "' style='" + span_style + "'>" >- + "<input type='checkbox' "; >- if ( oObj.date_due_overdue && can_renew ) { >- content += "checked='checked' "; >- } >- content += "class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>" >- + "</span>"; >- >- content += "<span class='renewals'>(" >- + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed ) >- + ")</span>"; >- } >- >- content += "</span>"; >- >- return content; >- } >+ "mRender": mRenders.renew, >+ "bSortable": false > }, > { >- "bSortable": false, > "bVisible": AllowCirculate ? true : false, >- "mDataProp": function ( oObj ) { >- if ( oObj.can_renew_error == "on_reserve" ) { >- return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"; >- } else { >- return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>"; >- } >- } >+ "mRender": mRenders.checkin, >+ "bSortable": false > }, > { > "bVisible": exports_enabled ? true : false, > "bSortable": false, >- "mDataProp": function ( oObj ) { >- var s = "<input type='checkbox' name='itemnumbers' value='" + oObj.itemnumber + "' style='visibility:hidden;' />"; >- >- s += "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />"; >- return s; >- } >+ "mRender": mRenders.export > } > ], > "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) { >@@ -421,39 +500,30 @@ $(document).ready(function() { > $("#totaldue").html(total_charge.toFixed(2)); > $("#totalfine").html(total_fine.toFixed(2)); > $("#totalprice").html(total_price.toFixed(2)); >- }, >- "bPaginate": false, >- "bProcessing": true, >- "bServerSide": false, >- "sAjaxSource": '/cgi-bin/koha/svc/checkouts', >- "fnServerData": function ( sSource, aoData, fnCallback ) { >- aoData.push( { "name": "borrowernumber", "value": borrowernumber } ); >- >- $.getJSON( sSource, aoData, function (json) { >- fnCallback(json) >- } ); >- }, >- "fnInitComplete": function(oSettings) { >- // Disable rowGrouping plugin after first use >- // so any sorting on the table doesn't use it >- var oSettings = issuesTable.fnSettings(); >- >- for (f = 0; f < oSettings.aoDrawCallback.length; f++) { >- if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') { >- oSettings.aoDrawCallback.splice(f, 1); >- break; >- } >- } >- >- oSettings.aaSortingFixed = null; >- }, >- }, columns_settings).rowGrouping( >- { >- iGroupingColumnIndex: 1, >- iGroupingOrderByColumnIndex: 0, >- sGroupingColumnSortDirection: "asc" > } >- ); >+ }, columns_settings); >+ >+ enableGrouping(issuesTable); >+ >+ var groupingSwitch = $('<input type="checkbox">') >+ .attr('id', 'issues-table-row-grouping-switch') >+ .attr('checked', 'checked') >+ .css('vertical-align', 'middle') >+ .change(function() { >+ if ($(this).is(':checked')) { >+ enableGrouping(issuesTable); >+ } else { >+ disableGrouping(issuesTable); >+ } >+ }); >+ $('<div></div>') >+ .css('float', 'left') >+ .css('padding', '0.3em 0.5em') >+ .css('line-height', '1.9em') >+ .append(groupingSwitch) >+ .append(' ') >+ .append('<label for="issues-table-row-grouping-switch">' + GROUP_TODAYS_CHECKOUTS + '</label>') >+ .appendTo('#issues-table_wrapper .top.pager'); > > if ( $("#issues-table").length ) { > $("#issues-table_processing").position({ >@@ -467,125 +537,60 @@ $(document).ready(function() { > var relativesIssuesTable; > $("#relatives-issues-tab").click( function() { > if ( ! relativesIssuesTable ) { >- relativesIssuesTable = $("#relatives-issues-table").dataTable({ >+ relativesIssuesTable = KohaTable("#relatives-issues-table", { > "bAutoWidth": false, >- "sDom": "rt", >- "aaSorting": [], >+ "sDom": 'C<"top pager"ilp>rt', >+ "aaSorting": [[4, "desc"]], >+ "bProcessing": true, >+ "bServerSide": ServerSideCheckoutsTables, >+ "sAjaxSource": "/cgi-bin/koha/svc/checkouts", >+ "fnServerParams": function (aoData) { >+ for (i in relatives_borrowernumbers) { >+ var borrowernumber = relatives_borrowernumbers[i]; >+ aoData.push({ "name": "borrowernumber", "value": borrowernumber }); >+ } >+ }, >+ "bPaginate": true, >+ "sPaginationType": "four_button", > "aoColumns": [ > { >- "mDataProp": "date_due", >- "bVisible": false, >+ "mData": "date_due", >+ "mRender": mRenders.dateDueFormatted > }, > { >- "iDataSort": 1, // Sort on hidden unformatted date due column >- "mDataProp": function( oObj ) { >- var today = new Date(); >- var due = new Date( oObj.date_due ); >- if ( today > due ) { >- return "<span class='overdue'>" + oObj.date_due_formatted + "</span>"; >- } else { >- return oObj.date_due_formatted; >- } >- } >+ "mData": "title", >+ "mRender": mRenders.title, > }, >+ { "mData": "itemtype" }, >+ { "mData": "location" }, > { >- "mDataProp": function ( oObj ) { >- title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber=" >- + oObj.biblionumber >- + "'>" >- + oObj.title; >- >- $.each(oObj.subtitle, function( index, value ) { >- title += " " + value.subfield; >- }); >- >- title += "</a></span>"; >- >- if ( oObj.author ) { >- title += " " + BY.replace( "_AUTHOR_", " " + oObj.author ); >- } >- >- if ( oObj.itemnotes ) { >- var span_class = ""; >- if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >- span_class = "circ-hlt"; >- } >- title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>" >- } >- >- if ( oObj.itemnotes_nonpublic ) { >- var span_class = ""; >- if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >- span_class = "circ-hlt"; >- } >- title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic + "</span>" >- } >- >- var onsite_checkout = ''; >- if ( oObj.onsite_checkout == 1 ) { >- onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>"; >- } >- >- title += " " >- + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=" >- + oObj.biblionumber >- + "&itemnumber=" >- + oObj.itemnumber >- + "#" >- + oObj.itemnumber >- + "'>" >- + oObj.barcode >- + "</a>" >- + onsite_checkout; >- >- return title; >- }, >- "sType": "anti-the" >+ "mData": "issuedate", >+ "mRender": mRenders.issuedate > }, >- { "mDataProp": "itemtype" }, >- { "mDataProp": "location" }, >- { "mDataProp": "issuedate_formatted" }, >- { "mDataProp": "branchname" }, >- { "mDataProp": "itemcallnumber" }, >+ { "mData": "branchname" }, >+ { "mData": "itemcallnumber" }, > { >- "mDataProp": function ( oObj ) { >- if ( ! oObj.charge ) oObj.charge = 0; >- return parseFloat(oObj.charge).toFixed(2); >- } >+ "mData": "charge", >+ "mRender": mRenders.charge, >+ "bSortable": ServerSideCheckoutsTables ? false : true > }, > { >- "mDataProp": function ( oObj ) { >- if ( ! oObj.fine ) oObj.fine = 0; >- return parseFloat(oObj.fine).toFixed(2); >- } >+ "mData": "fine", >+ "mRender": mRenders.fine, >+ "bSortable": ServerSideCheckoutsTables ? false : true > }, > { >- "mDataProp": function ( oObj ) { >- if ( ! oObj.price ) oObj.price = 0; >- return parseFloat(oObj.price).toFixed(2); >- } >+ "mData": "replacementprice", >+ "mRender": mRenders.price, >+ "bSortable": ServerSideCheckoutsTables ? false : true > }, > { >- "mDataProp": function( oObj ) { >- return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>" >- + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")</a>" >- } >- }, >- ], >- "bPaginate": false, >- "bProcessing": true, >- "bServerSide": false, >- "sAjaxSource": '/cgi-bin/koha/svc/checkouts', >- "fnServerData": function ( sSource, aoData, fnCallback ) { >- $.each(relatives_borrowernumbers, function( index, value ) { >- aoData.push( { "name": "borrowernumber", "value": value } ); >- }); >- >- $.getJSON( sSource, aoData, function (json) { >- fnCallback(json) >- } ); >- }, >- }); >+ "mData": "borrowernumber", >+ "mRender": mRenders.patron, >+ "bSortable": ServerSideCheckoutsTables ? false : true >+ } >+ ] >+ }, relatives_columns_settings); > } > }); > >@@ -605,4 +610,6 @@ $(document).ready(function() { > } > } ).attr( 'checked', false ); > } >- }); >+}); >+ >+})(jQuery); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >index d9c7e25..459cc41 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref >@@ -40,6 +40,12 @@ Circulation: > desc: latest to earliest > - due date. > - >+ - pref: ServerSideCheckoutsTables >+ choices: >+ yes: Enable >+ no: Do not enable >+ - server-side processing on checkouts tables. It can improve performance when there is a big number of checkouts to display. >+ - > - pref: SpecifyDueDate > choices: > yes: Allow >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >index 6fd722c..eac5301 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >@@ -26,30 +26,20 @@ > [% INCLUDE 'timepicker.inc' %] > <script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.dataTables.rowGrouping.js"></script> > <script type="text/javascript" src="[% themelang %]/js/pages/circulation.js"></script> >-<script type="text/javascript" src="[% themelang %]/js/checkouts.js"></script> >+[% INCLUDE 'checkouts.js.inc' %] > <script type="text/javascript" src="[% themelang %]/js/holds.js"></script> > <script type="text/javascript"> > //<![CDATA[ > /* Set some variable needed in circulation.js */ >-var MSG_DT_LOADING_RECORDS = _("Loading... you may continue scanning."); > var interface = "[% interface %]"; > var theme = "[% theme %]"; >-var borrowernumber = "[% borrowernumber %]"; > var branchcode = "[% branch %]"; > var exports_enabled = "[% exports_enabled %]"; >-var AllowRenewalLimitOverride = [% (CAN_user_circulate_override_renewals && AllowRenewalLimitOverride)? 1: 0 %]; >-var AllowCirculate = [% (CAN_user_circulate_circulate_remaining_permissions)? 1 : 0 %]; > var script = "circulation"; >-var relatives_borrowernumbers = new Array(); >-[% FOREACH b IN relatives_borrowernumbers %] >- relatives_borrowernumbers.push("[% b %]"); >-[% END %] > > var MSG_ADD_MESSAGE = _("Add a new message"); > var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); > >-columns_settings = [% ColumnsSettings.GetColumns( 'circ', 'circulation', 'issues-table', 'json' ) %] >- > [% IF ( borrowernumber ) %] > if($.cookie("holdfor") != [% borrowernumber %]){ > $.removeCookie("holdfor", { path: '/' }); >@@ -907,7 +897,6 @@ No patron matched <span class="ex">[% message %]</span> > <table id="relatives-issues-table"> > <thead> > <tr> >- <th scope="col">Due date (unformatted, hidden)</th> > <th scope="col">Due date</th> > <th scope="col">Title</th> > <th scope="col">Item type</th> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >index 30cda46..a121310 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -24,29 +24,20 @@ > [% INCLUDE 'timepicker.inc' %] > <script type="text/javascript" src="[% interface %]/lib/jquery/plugins/jquery.dataTables.rowGrouping.js"></script> > <script type="text/javascript" src="[% themelang %]/js/pages/circulation.js"></script> >-<script type="text/javascript" src="[% themelang %]/js/checkouts.js"></script> >+[% INCLUDE 'checkouts.js.inc' %] > <script type="text/javascript" src="[% themelang %]/js/holds.js"></script> > <script type="text/JavaScript"> > //<![CDATA[ > /* Set some variable needed in circulation.js */ > var interface = "[% interface %]"; > var theme = "[% theme %]"; >-var borrowernumber = "[% borrowernumber %]"; > var branchcode = "[% branch %]"; > var exports_enabled = "[% exports_enabled %]"; >-var AllowCirculate = [% (CAN_user_circulate_circulate_remaining_permissions)? 1 : 0 %] >-var AllowRenewalLimitOverride = [% (CAN_user_circulate_override_renewals && AllowRenewalLimitOverride)? 1: 0 %]; > var script = "moremember"; >-var relatives_borrowernumbers = new Array(); >-[% FOREACH b IN relatives_borrowernumbers %] >- relatives_borrowernumbers.push("[% b %]"); >-[% END %] > > var MSG_ADD_MESSAGE = _("Add a new message"); > var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); > >-columns_settings = [% ColumnsSettings.GetColumns( 'members', 'moremember', 'issues-table', 'json' ) %] >- > $(document).ready(function() { > $('#finesholdsissues').tabs({ > // Correct table sizing for tables hidden in tabs >@@ -452,7 +443,6 @@ function validate1(date) { > <table id="relatives-issues-table" style="width: 100% !Important;"> > <thead> > <tr> >- <th scope="col">Due date hidden not formatted</th> > <th scope="col">Due date</th> > <th scope="col">Title</th> > <th scope="col">Item type</th> >diff --git a/svc/checkouts b/svc/checkouts >index 93a1c95..bae51e4 100755 >--- a/svc/checkouts >+++ b/svc/checkouts >@@ -17,8 +17,7 @@ > # with Koha; if not, write to the Free Software Foundation, Inc., > # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > >-use strict; >-use warnings; >+use Modern::Perl; > > use CGI; > use JSON qw(to_json); >@@ -29,6 +28,7 @@ use C4::Circulation qw(GetIssuingCharges CanBookBeRenewed GetRenewCount GetSoone > use C4::Koha qw(GetAuthorisedValueByCode); > use C4::Overdues qw(GetFine); > use C4::Context; >+use C4::Utils::DataTables; > > use Koha::DateUtils; > >@@ -45,26 +45,33 @@ unless (haspermission($userid, { circulate => 'circulate_remaining_permissions' > exit 0; > } > >-my @sort_columns = qw/date_due title itype issuedate branchcode itemcallnumber/; >- > my @borrowernumber = $input->param('borrowernumber'); >-my $offset = $input->param('iDisplayStart'); >-my $results_per_page = $input->param('iDisplayLength') || -1; >- >-my $sorting_column = $input->param('iSortCol_0') || q{}; >-$sorting_column = ( $sorting_column && $sort_columns[$sorting_column] ) ? $sort_columns[$sorting_column] : 'issuedate'; >- >-my $sorting_direction = $input->param('sSortDir_0') || q{}; >-$sorting_direction = $sorting_direction eq 'asc' ? 'asc' : 'desc'; >- >-$results_per_page = undef if ( $results_per_page == -1 ); >- >-binmode STDOUT, ":encoding(UTF-8)"; >-print $input->header( -type => 'text/plain', -charset => 'UTF-8' ); >+my $offset = $input->param('iDisplayStart'); >+my $count = $input->param('iDisplayLength'); >+ >+my %params = dt_get_params($input); >+my $orderby = dt_build_orderby(\%params); >+ >+my $todaysIssuesDefaultSortOrder = >+ C4::Context->preference('todaysIssuesDefaultSortOrder'); >+my $previousIssuesDefaultSortOrder = >+ C4::Context->preference('previousIssuesDefaultSortOrder'); >+ >+# Default sort when user hasn't clicked on a column header yet. >+# When row grouping is enabled, DataTables ask to sort on issued_today column, >+# so we need to treat this case the same as the "no sorting" case >+if (!$orderby || $orderby =~ m/ORDER BY issued_today desc\s*$/) { >+ $orderby = qq{ >+ ORDER BY >+ issued_today DESC, >+ CASE WHEN issued_today = 0 THEN date_due END $previousIssuesDefaultSortOrder, >+ CASE WHEN issued_today != 0 THEN date_due END $todaysIssuesDefaultSortOrder >+ }; >+} > > my @parameters; > my $sql = ' >- SELECT >+ SELECT SQL_CALC_FOUND_ROWS > issuedate, > date_due, > date_due < now() as date_due_overdue, >@@ -98,34 +105,40 @@ my $sql = ' > damaged, > location, > >- DATEDIFF( issuedate, CURRENT_DATE() ) AS not_issued_today >+ DATEDIFF( issuedate, CURRENT_DATE() ) = 0 AS issued_today > FROM issues > LEFT JOIN items USING ( itemnumber ) > LEFT JOIN biblio USING ( biblionumber ) > LEFT JOIN biblioitems USING ( biblionumber ) > LEFT JOIN borrowers USING ( borrowernumber ) > LEFT JOIN branches ON ( issues.branchcode = branches.branchcode ) >- WHERE borrowernumber >+ WHERE > '; > >+my $borrowernumber_sql = 'borrowernumber'; > if ( @borrowernumber == 1 ) { >- $sql .= '= ?'; >-} >-else { >- $sql .= ' IN (' . join( ',', ('?') x @borrowernumber ) . ') '; >+ $borrowernumber_sql .= ' = ?'; >+} else { >+ $borrowernumber_sql .= ' IN (' . join( ',', ('?') x @borrowernumber ) . ') '; > } >+$sql .= $borrowernumber_sql; > push( @parameters, @borrowernumber ); > >-$sql .= " ORDER BY $sorting_column $sorting_direction "; >+$sql .= " $orderby"; >+ >+if ($count && $count > 0) { >+ $sql .= " LIMIT ?,?"; >+ push @parameters, $offset, $count; >+} > > my $dbh = C4::Context->dbh(); > my $sth = $dbh->prepare($sql); > $sth->execute(@parameters); >+my ($iTotalDisplayRecords) = $dbh->selectrow_array('SELECT FOUND_ROWS()'); > > my $item_level_itypes = C4::Context->preference('item-level_itypes'); > >-my @checkouts_today; >-my @checkouts_previous; >+my @checkouts; > while ( my $c = $sth->fetchrow_hashref() ) { > my ($charge) = GetIssuingCharges( $c->{itemnumber}, $c->{borrowernumber} ); > my $fine = GetFine( $c->{itemnumber}, $c->{borrowernumber} ); >@@ -197,36 +210,25 @@ while ( my $c = $sth->fetchrow_hashref() ) { > firstname => $c->{firstname}, > cardnumber => $c->{cardnumber}, > }, >- issued_today => !$c->{not_issued_today}, >+ issued_today => $c->{issued_today} ? JSON::true : JSON::false, > }; > >- if ( $c->{not_issued_today} ) { >- push( @checkouts_previous, $checkout ); >- } >- else { >- push( @checkouts_today, $checkout ); >- } >+ push @checkouts, $checkout; > } > >+binmode STDOUT, ":encoding(UTF-8)"; >+print $input->header( -type => 'application/json', -charset => 'UTF-8' ); > >-@checkouts_today = sort { $a->{timestamp} cmp $b->{timestamp} } @checkouts_today; >-@checkouts_today = reverse(@checkouts_today) >- unless ( C4::Context->preference('todaysIssuesDefaultSortOrder') eq 'desc' ); >- >-@checkouts_previous = sort { $a->{date_due} cmp $b->{date_due} } @checkouts_previous; >-@checkouts_previous = reverse(@checkouts_previous) >- if ( C4::Context->preference('previousIssuesDefaultSortOrder') eq 'desc' ); >- >-my @checkouts = ( @checkouts_today, @checkouts_previous ); >- >-my $i = 1; >-map { $_->{sort_order} = $i++ } @checkouts; >- >+my $sEcho = $input->param('sEcho'); >+my ($iTotalRecords) = $dbh->selectrow_array( >+ "SELECT COUNT(*) FROM issues WHERE $borrowernumber_sql", undef, >+ @borrowernumber); > >-my $data; >-$data->{'iTotalRecords'} = scalar @checkouts; >-$data->{'iTotalDisplayRecords'} = scalar @checkouts; >-$data->{'sEcho'} = $input->param('sEcho') || undef; >-$data->{'aaData'} = \@checkouts; >+my $response = { >+ iTotalRecords => $iTotalRecords, >+ iTotalDisplayRecords => $iTotalDisplayRecords, >+ sEcho => $sEcho, >+ aaData => \@checkouts, >+}; > >-print to_json($data); >+print to_json($response); >-- >1.9.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 15219
:
45018
|
45036
|
45054
|
48107
|
50075
|
60071
|
60642
|
61158
|
61159
|
61545
|
61546
|
72905
|
72906
|
74224
|
74225
|
75911
|
75912
|
75913
|
78555
|
78556
|
78557
|
78558
|
78559
|
79195
|
79196
|
79197
|
79198
|
79199
|
92776
|
92777
|
92778
|
92779
|
92780
|
92781
|
93921