Bugzilla – Attachment 74224 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), 60.51 KB, created by
Julian Maurice
on 2018-04-16 09:10:38 UTC
(
hide
)
Description:
Bug 15219: Server-side processing and pagination on checkouts tables
Filename:
MIME Type:
Creator:
Julian Maurice
Created:
2018-04-16 09:10:38 UTC
Size:
60.51 KB
patch
obsolete
>From 6485f2a8d5ddd1e41810640cabedfdd72041d9cd 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 > >Signed-off-by: Eric Gosselin <eric.gosselin@inlibro.com> >--- > 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 | 25 + > .../prog/en/includes/columns_settings.inc | 2 +- > .../intranet-tmpl/prog/en/includes/strings.inc | 1 + > .../en/modules/admin/preferences/circulation.pref | 6 + > .../prog/en/modules/circ/circulation.tt | 13 +- > .../prog/en/modules/members/moremember.tt | 12 +- > koha-tmpl/intranet-tmpl/prog/js/checkouts.js | 748 ++++++++++----------- > svc/checkouts | 105 +-- > 14 files changed, 520 insertions(+), 468 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 23903646b0..9dec2a7c74 100644 >--- a/admin/columns_settings.yml >+++ b/admin/columns_settings.yml >@@ -209,7 +209,7 @@ modules: > moremember: > issues-table: > - >- columnname: sort_order >+ columnname: group_order > cannot_be_toggled: 1 > cannot_be_modified: 1 > is_hidden: 1 >@@ -218,11 +218,6 @@ modules: > cannot_be_toggled: 1 > 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 > - >@@ -255,6 +250,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 > > holdshistory: > holdshistory-table: >@@ -364,7 +382,7 @@ modules: > circulation: > issues-table: > - >- columnname: sort_order >+ columnname: group_order > cannot_be_toggled: 1 > cannot_be_modified: 1 > is_hidden: 1 >@@ -373,11 +391,6 @@ modules: > cannot_be_toggled: 1 > 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 > - >@@ -410,6 +423,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 > > returns: > checkedintable: >diff --git a/installer/data/mysql/atomicupdate/bug_15219.sql b/installer/data/mysql/atomicupdate/bug_15219.sql >new file mode 100644 >index 0000000000..a186d45abe >--- /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 d498841e83..296a44df07 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -494,6 +494,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 126ff63357..12a88e4dba 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 3adbfa326a..a8b906b7c2 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="11" style="text-align: right; font-weight:bold;">Totals:</td> >+ <td colspan="10" 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 b34089d3c7..b723d62a66 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >@@ -13,7 +13,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 0000000000..1f846b33f2 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts.js.inc >@@ -0,0 +1,25 @@ >+[% USE Asset %] >+[% 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 && Koha.Preference('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> >+ >+[% Asset.js('js/checkouts.js') %] >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 1ee31b0739..1d53b51c5d 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc >@@ -40,7 +40,7 @@ function KohaTable(id_selector, dt_parameters, columns_settings, add_filters) { > table.dataTable($.extend(true, {}, dataTablesDefaults, dt_parameters)); > > $(hidden_ids).each(function(index, value) { >- table.fnSetColumnVis( value, false ); >+ table.fnSetColumnVis( value, false, false ); > }); > > if ( add_filters ) { >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >index e116204cdc..ff87e4b0ad 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc >@@ -43,5 +43,6 @@ > 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 CURRENT = _(" (current) "); >+ var GROUP_TODAYS_CHECKOUTS = _("Group today's checkouts"); > //]]> > </script> >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 8ec6a6b5b6..549f6794db 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 >@@ -52,6 +52,12 @@ Circulation: > asc: earliest to latest > 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: >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 b2c883432c..7788716c21 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >@@ -847,7 +847,6 @@ No patron matched <span class="ex">[% message | html %]</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> >@@ -981,24 +980,16 @@ No patron matched <span class="ex">[% message | html %]</span> > [% INCLUDE 'timepicker.inc' %] > [% Asset.js("lib/jquery/plugins/jquery.dataTables.rowGrouping.js") %] > [% Asset.js("js/pages/circulation.js") %] >- [% Asset.js("js/checkouts.js") %] >+ [% INCLUDE 'checkouts.js.inc' %] > [% Asset.js("js/holds.js") %] > [% Asset.js("js/circ-patron-search-results.js") %] > <script type="text/javascript"> > /* 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 = "[% patron.borrowernumber %]"; > var branchcode = "[% branch %]"; > var exports_enabled = "[% Koha.Preference('ExportCircHistory') %]"; >- var AllowRenewalLimitOverride = [% (CAN_user_circulate_override_renewals && Koha.Preference('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_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); > var MSG_CONFIRM_DELETE_MESSAGE = _("Are you sure you want to delete this message? This cannot be undone."); >@@ -1012,8 +1003,6 @@ No patron matched <span class="ex">[% message | html %]</span> > var destination = "[% destination %]"; > var CAN_user_borrowers_edit_borrowers = "[% CAN_user_borrowers_edit_borrowers %]"; > >- columns_settings = [% ColumnsSettings.GetColumns( 'circ', 'circulation', 'issues-table', 'json' ) %] >- > [% IF borrowernumber and patron %] > if($.cookie("holdfor") != [% patron.borrowernumber %]){ > $.removeCookie("holdfor", { path: '/' }); >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 edfee7e45c..5c35aa094f 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -444,7 +444,6 @@ > <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> >@@ -555,7 +554,7 @@ > [% INCLUDE 'timepicker.inc' %] > [% Asset.js("lib/jquery/plugins/jquery.dataTables.rowGrouping.js") %] > [% Asset.js("js/pages/circulation.js") %] >- [% Asset.js("js/checkouts.js") %] >+ [% INCLUDE 'checkouts.js.inc' %] > [% Asset.js("js/holds.js") %] > [% Asset.js("js/members-menu.js") %] > [% Asset.js("js/messaging-preference-form.js") %] >@@ -563,22 +562,13 @@ > /* Set some variable needed in circulation.js */ > var interface = "[% interface %]"; > var theme = "[% theme %]"; >- var borrowernumber = "[% patron.borrowernumber %]"; > var branchcode = "[% Branches.GetLoggedInBranchcode() %]"; > var exports_enabled = "[% Koha.Preference('ExportCircHistory') %]"; >- var AllowCirculate = [% (CAN_user_circulate_circulate_remaining_permissions)? 1 : 0 %] >- var AllowRenewalLimitOverride = [% (CAN_user_circulate_override_renewals && Koha.Preference('AllowRenewalLimitOverride') )? 1: 0 %]; > var script = "moremember"; >- var relatives_borrowernumbers = new Array(); >- [% FOREACH b IN relatives_borrowernumbers %] >- relatives_borrowernumbers.push("[% b %]"); >- [% END %] > > var MSG_EXPORT_SELECT_CHECKOUTS = _("You must select checkout(s) to export"); > var MSG_CONFIRM_DELETE_MESSAGE = _("Are you sure you want to delete this message? This cannot be undone."); > >- columns_settings = [% ColumnsSettings.GetColumns( 'members', 'moremember', 'issues-table', 'json' ) %] >- > $(document).ready(function() { > if ( $('#clubs-tab').length ) { > $('#clubs-tab-link').on('click', function() { >diff --git a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >index 5167ee12ae..a8e94e0625 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >@@ -1,3 +1,267 @@ >+(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>"; >+ } >+ >+ due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>"; >+ >+ if ( oObj.lost ) { >+ due += "<span class='lost'>" + oObj.lost + "</span>"; >+ } >+ >+ if ( oObj.damaged ) { >+ due += "<span class='dmg'>" + oObj.damaged + "</span>"; >+ } >+ >+ return due; >+ }, >+ title: function (oData, sType, oObj) { >+ var title = "<span id='title_" + oObj.itemnumber + "' class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber=" >+ + oObj.biblionumber >+ + "'>" >+ + oObj.title; >+ >+ $.each(oObj.subtitle, function( index, value ) { >+ title += " " + value.subfield; >+ }); >+ >+ if ( oObj.enumchron ) { >+ title += " (" + oObj.enumchron + ")"; >+ } >+ >+ title += "</a></span>"; >+ >+ if ( oObj.author ) { >+ title += " " + BY.replace( "_AUTHOR_", " " + oObj.author ); >+ } >+ >+ if ( oObj.itemnotes ) { >+ var span_class = "text-muted"; >+ if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >+ span_class = "circ-hlt"; >+ } >+ title += " - <span class='" + span_class + " item-note-public'>" + oObj.itemnotes + "</span>"; >+ } >+ >+ if ( oObj.itemnotes_nonpublic ) { >+ var span_class = "text-danger"; >+ if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >+ span_class = "circ-hlt"; >+ } >+ title += " - <span class='" + span_class + " item-note-nonpublic'>" + 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_too_late" ) { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_AUTO_TOO_LATE >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if ( oObj.can_renew_error == "auto_too_much_oweing" ) { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_AUTO_TOO_MUCH_OWEING >+ + "</span>"; >+ >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if ( oObj.can_renew_error == "auto_account_expired" ) { >+ content += "<span class='renewals-disabled'>" >+ + NOT_RENEWABLE_AUTO_ACCOUNT_EXPIRED >+ + "</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 }); > >@@ -152,8 +416,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(){ >@@ -187,16 +449,24 @@ $(document).ready(function() { > "sProcessing": MSG_DT_LOADING_RECORDS, > }, > "bAutoWidth": false, >- "dom": 'B<"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", >+ "dom": 'B<"clearfix"><"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>"; >@@ -204,251 +474,57 @@ $(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>"; >- } >- >- due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>"; >- >- if ( oObj.lost ) { >- due += "<span class='lost'>" + oObj.lost + "</span>"; >- } >- >- if ( oObj.damaged ) { >- due += "<span class='dmg'>" + oObj.damaged + "</span>"; >- } >- >- var patron_note = " <span class='patron_note_" + oObj.itemnumber + "'></span>"; >- due +="<br>" + patron_note; >- >- return due; >- } >+ "mData": "title", >+ "mRender": mRenders.title > }, > { >- "mDataProp": function ( oObj ) { >- title = "<span id='title_" + oObj.itemnumber + "' class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber=" >- + oObj.biblionumber >- + "'>" >- + oObj.title; >- >- $.each(oObj.subtitle, function( index, value ) { >- title += " " + value.subfield; >- }); >- >- if ( oObj.enumchron ) { >- title += " (" + oObj.enumchron + ")"; >- } >- >- title += "</a></span>"; >- >- if ( oObj.author ) { >- title += " " + BY.replace( "_AUTHOR_", " " + oObj.author ); >- } >- >- if ( oObj.itemnotes ) { >- var span_class = "text-muted"; >- if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >- span_class = "circ-hlt"; >- } >- title += " - <span class='" + span_class + " item-note-public'>" + oObj.itemnotes + "</span>"; >- } >- >- if ( oObj.itemnotes_nonpublic ) { >- var span_class = "text-danger"; >- if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) { >- span_class = "circ-hlt"; >- } >- title += " - <span class='" + span_class + " item-note-nonpublic'>" + 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": "homebranch" }, >- { "mDataProp": "issuedate_formatted" }, >- { "mDataProp": "branchname" }, >- { "mDataProp": "itemcallnumber" }, >+ { "mData": "location" }, >+ { "mData": "homebranch" }, > { >- "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_too_late" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_AUTO_TOO_LATE >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "auto_too_much_oweing" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_AUTO_TOO_MUCH_OWEING >- + "</span>"; >- >- span_style = "display: none"; >- span_class = "renewals-allowed"; >- } else if ( oObj.can_renew_error == "auto_account_expired" ) { >- content += "<span class='renewals-disabled'>" >- + NOT_RENEWABLE_AUTO_ACCOUNT_EXPIRED >- + "</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 == 1 ? 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 ) { >@@ -463,39 +539,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({ >@@ -509,129 +576,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; >- }); >- >- if ( oObj.enumchron ) { >- title += " (" + oObj.enumchron + ")"; >- } >- >- 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); > } > }); > >@@ -651,4 +649,6 @@ $(document).ready(function() { > } > } ).prop('checked', false); > } >- }); >+}); >+ >+})(jQuery); >diff --git a/svc/checkouts b/svc/checkouts >index fefadeeeea..34a8562e6c 100755 >--- a/svc/checkouts >+++ b/svc/checkouts >@@ -27,6 +27,7 @@ use C4::Biblio qw(GetMarcBiblio GetFrameworkCode GetRecordValue ); > use C4::Circulation qw(GetIssuingCharges CanBookBeRenewed GetRenewCount GetSoonestRenewDate); > use C4::Overdues qw(GetFine); > use C4::Context; >+use C4::Utils::DataTables; > > use Koha::AuthorisedValues; > use Koha::DateUtils; >@@ -45,26 +46,33 @@ unless (haspermission($userid, { circulate => 'circulate_remaining_permissions' > exit 0; > } > >-my @sort_columns = qw/date_due title itype issuedate branchcode itemcallnumber/; >- > my @borrowernumber = $input->multi_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, >@@ -100,7 +108,7 @@ my $sql = ' > location, > items.enumchron, > >- 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 ) >@@ -108,27 +116,33 @@ my $sql = ' > LEFT JOIN borrowers USING ( borrowernumber ) > LEFT JOIN branches ON ( issues.branchcode = branches.branchcode ) > LEFT JOIN branches branches2 ON ( items.homebranch = branches2.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} ); >@@ -219,36 +233,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); >-- >2.14.2
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