@@ -, +, @@
tables
- 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)
the relatives checkouts table contain at least 10 checkouts.
in both tables (sorting, pagination, the data itself, ...)
---
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/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, 519 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
--- a/admin/columns_settings.yml
+++ a/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:
@@ -321,7 +339,7 @@ modules:
circulation:
issues-table:
-
- columnname: sort_order
+ columnname: group_order
cannot_be_toggled: 1
cannot_be_modified: 1
is_hidden: 1
@@ -330,11 +348,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
-
@@ -367,6 +380,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:
--- a/installer/data/mysql/atomicupdate/bug_15219.sql
+++ a/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');
--- a/installer/data/mysql/sysprefs.sql
+++ a/installer/data/mysql/sysprefs.sql
@@ -488,6 +488,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'),
--- a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/jquery.dataTables.rowGrouping.js
+++ a/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);
+})(jQuery);
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table-footer.inc
@@ -1,6 +1,6 @@
- Totals: |
+ Totals: |
[% totaldue %] |
[% finetotal %] |
[% totalprice %] |
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc
@@ -13,7 +13,6 @@
|
|
Due date |
- Due date |
Title |
Item type |
Location |
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts.js.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts.js.inc
@@ -0,0 +1,24 @@
+[% USE Koha %]
+
+
+
+
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/columns_settings.inc
+++ a/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 ) {
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/strings.inc
+++ a/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");
//]]>
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref
+++ a/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:
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
@@ -847,7 +847,6 @@ No patron matched [% message | html %]
- Due date (unformatted, hidden) |
Due date |
Title |
Item type |
@@ -981,24 +980,16 @@ No patron matched [% message | html %]
[% INCLUDE 'timepicker.inc' %]
-
+ [% INCLUDE 'checkouts.js.inc' %]
-
+ [% INCLUDE 'checkouts.js.inc' %]
@@ -559,22 +558,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() {
--- a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js
+++ a/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 "" + TODAYS_CHECKOUTS + "";
+ } else {
+ return "" + PREVIOUS_CHECKOUTS + "";
+ }
+ },
+ dateDueFormatted: function (oData, sType, oObj) {
+ var due = oObj.date_due_formatted;
+
+ if ( oObj.date_due_overdue ) {
+ due = "" + due + "";
+ }
+
+ due = "" + due + "";
+
+ if ( oObj.lost ) {
+ due += "" + oObj.lost + "";
+ }
+
+ if ( oObj.damaged ) {
+ due += "" + oObj.damaged + "";
+ }
+
+ return due;
+ },
+ title: function (oData, sType, oObj) {
+ var title = ""
+ + oObj.title;
+
+ $.each(oObj.subtitle, function( index, value ) {
+ title += " " + value.subfield;
+ });
+
+ if ( oObj.enumchron ) {
+ title += " (" + oObj.enumchron + ")";
+ }
+
+ title += "";
+
+ 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 += " - " + oObj.itemnotes + "";
+ }
+
+ 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 += " - " + oObj.itemnotes_nonpublic + "";
+ }
+
+ var onsite_checkout = '';
+ if ( oObj.onsite_checkout == 1 ) {
+ onsite_checkout += " (" + INHOUSE_USE + ")";
+ }
+
+ title += " "
+ + ""
+ + oObj.barcode
+ + ""
+ + 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 '' + parseFloat(oObj.charge).toFixed(2) + '';
+ },
+ fine: function (oData, sType, oObj) {
+ if (!oObj.fine) oObj.fine = 0;
+ return '' + parseFloat(oObj.fine).toFixed(2) + '';
+ },
+ 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 += "";
+ content += "" + oObj.renewals_count + "";
+
+ if ( oObj.can_renew ) {
+ // Do nothing
+ } else if ( oObj.can_renew_error == "on_reserve" ) {
+ content += ""
+ + "" + ON_HOLD + ""
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "too_many" ) {
+ content += ""
+ + NOT_RENEWABLE
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "restriction" ) {
+ content += ""
+ + NOT_RENEWABLE_RESTRICTION
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "overdue" ) {
+ content += ""
+ + NOT_RENEWABLE_OVERDUE
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "too_soon" ) {
+ content += ""
+ + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "auto_too_soon" ) {
+ content += ""
+ + NOT_RENEWABLE_AUTO_TOO_SOON
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "auto_too_late" ) {
+ content += ""
+ + NOT_RENEWABLE_AUTO_TOO_LATE
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "auto_too_much_oweing" ) {
+ content += ""
+ + NOT_RENEWABLE_AUTO_TOO_MUCH_OWEING
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "auto_account_expired" ) {
+ content += ""
+ + NOT_RENEWABLE_AUTO_ACCOUNT_EXPIRED
+ + "";
+
+ span_style = "display: none";
+ span_class = "renewals-allowed";
+ } else if ( oObj.can_renew_error == "auto_renew" ) {
+ content += ""
+ + NOT_RENEWABLE_AUTO_RENEW
+ + "";
+
+ 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 += ""
+ + oObj.can_renew_error
+ + "";
+
+ 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 += ""
+ + ""
+ + "";
+
+ content += "("
+ + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
+ + ")";
+ }
+
+ content += "";
+
+ return content;
+ },
+ checkin: function (oData, sType, oObj) {
+ if (oObj.can_renew_error == "on_reserve") {
+ return "" + ON_HOLD + "";
+ } else {
+ return "";
+ }
+ },
+ export: function (oData, sType, oObj) {
+ var s = "";
+
+ s += "";
+ return s;
+ },
+ patron: function (oData, sType, oObj) {
+ return ""
+ + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")"
+ }
+};
+
$(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 "" + TODAYS_CHECKOUTS + "";
} else {
return "" + PREVIOUS_CHECKOUTS + "";
@@ -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 = "" + due + "";
- }
-
- due = "" + due + "";
-
- if ( oObj.lost ) {
- due += "" + oObj.lost + "";
- }
-
- if ( oObj.damaged ) {
- due += "" + oObj.damaged + "";
- }
-
- var patron_note = " ";
- due +="
" + patron_note;
-
- return due;
- }
+ "mData": "title",
+ "mRender": mRenders.title
},
{
- "mDataProp": function ( oObj ) {
- title = ""
- + oObj.title;
-
- $.each(oObj.subtitle, function( index, value ) {
- title += " " + value.subfield;
- });
-
- if ( oObj.enumchron ) {
- title += " (" + oObj.enumchron + ")";
- }
-
- title += "";
-
- 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 += " - " + oObj.itemnotes + "";
- }
-
- 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 += " - " + oObj.itemnotes_nonpublic + "";
- }
-
- var onsite_checkout = '';
- if ( oObj.onsite_checkout == 1 ) {
- onsite_checkout += " (" + INHOUSE_USE + ")";
- }
-
- title += " "
- + ""
- + oObj.barcode
- + ""
- + 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 '' + parseFloat(oObj.charge).toFixed(2) + '';
- }
+ "mData": "issuedate",
+ "mRender": mRenders.issuedate
},
{
- "mDataProp": function ( oObj ) {
- if ( ! oObj.fine ) oObj.fine = 0;
- return '' + parseFloat(oObj.fine).toFixed(2) + '';
- }
+ "mData": "branchcode",
+ "mRender": mRenders.branch
},
+ { "mData": "itemcallnumber" },
{
- "mDataProp": function ( oObj ) {
- if ( ! oObj.price ) oObj.price = 0;
- return '' + parseFloat(oObj.price).toFixed(2) + '';
- }
+ "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 += "";
- content += "" + oObj.renewals_count + "";
-
- if ( oObj.can_renew ) {
- // Do nothing
- } else if ( oObj.can_renew_error == "on_reserve" ) {
- content += ""
- + "" + ON_HOLD + ""
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "too_many" ) {
- content += ""
- + NOT_RENEWABLE
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "restriction" ) {
- content += ""
- + NOT_RENEWABLE_RESTRICTION
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "overdue" ) {
- content += ""
- + NOT_RENEWABLE_OVERDUE
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "too_soon" ) {
- content += ""
- + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "auto_too_soon" ) {
- content += ""
- + NOT_RENEWABLE_AUTO_TOO_SOON
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "auto_too_late" ) {
- content += ""
- + NOT_RENEWABLE_AUTO_TOO_LATE
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "auto_too_much_oweing" ) {
- content += ""
- + NOT_RENEWABLE_AUTO_TOO_MUCH_OWEING
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "auto_account_expired" ) {
- content += ""
- + NOT_RENEWABLE_AUTO_ACCOUNT_EXPIRED
- + "";
-
- span_style = "display: none";
- span_class = "renewals-allowed";
- } else if ( oObj.can_renew_error == "auto_renew" ) {
- content += ""
- + NOT_RENEWABLE_AUTO_RENEW
- + "";
-
- 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 += ""
- + oObj.can_renew_error
- + "";
-
- 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 += ""
- + ""
- + "";
-
- content += "("
- + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
- + ")";
- }
-
- content += "";
-
- return content;
- }
+ "mRender": mRenders.renew,
+ "bSortable": false
},
{
- "bSortable": false,
"bVisible": AllowCirculate ? true : false,
- "mDataProp": function ( oObj ) {
- if ( oObj.can_renew_error == "on_reserve" ) {
- return "" + ON_HOLD + "";
- } else {
- return "";
- }
- }
+ "mRender": mRenders.checkin,
+ "bSortable": false
},
{
"bVisible": exports_enabled == 1 ? true : false,
"bSortable": false,
- "mDataProp": function ( oObj ) {
- var s = "";
-
- s += "";
- 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 = $('')
+ .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);
+ }
+ });
+ $('')
+ .css('float', 'left')
+ .css('padding', '0.3em 0.5em')
+ .css('line-height', '1.9em')
+ .append(groupingSwitch)
+ .append(' ')
+ .append('')
+ .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 "" + oObj.date_due_formatted + "";
- } else {
- return oObj.date_due_formatted;
- }
- }
+ "mData": "title",
+ "mRender": mRenders.title,
},
+ { "mData": "itemtype" },
+ { "mData": "location" },
{
- "mDataProp": function ( oObj ) {
- title = ""
- + oObj.title;
-
- $.each(oObj.subtitle, function( index, value ) {
- title += " " + value.subfield;
- });
-
- if ( oObj.enumchron ) {
- title += " (" + oObj.enumchron + ")";
- }
-
- title += "";
-
- 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 += " - " + oObj.itemnotes + ""
- }
-
- if ( oObj.itemnotes_nonpublic ) {
- var span_class = "";
- if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
- span_class = "circ-hlt";
- }
- title += " - " + oObj.itemnotes_nonpublic + ""
- }
-
- var onsite_checkout = '';
- if ( oObj.onsite_checkout == 1 ) {
- onsite_checkout += " (" + INHOUSE_USE + ")";
- }
-
- title += " "
- + ""
- + oObj.barcode
- + ""
- + 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 ""
- + oObj.borrower.firstname + " " + oObj.borrower.surname + " (" + oObj.borrower.cardnumber + ")"
- }
- },
- ],
- "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);
--- a/svc/checkouts
+++ a/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);
--