From f8422d9abd41f9b10b1b1cc4cc824e0eaef5b84e Mon Sep 17 00:00:00 2001 From: Mike Rylander Date: Wed, 3 Aug 2016 16:51:54 -0400 Subject: [PATCH] LP#1356477: add quick receipt button This patch adds a new button to the webstaff checkout page called Quick Receipt. If the button itself is pushed, a receipt containing the current checkouts is either printed or emailed, depending on the user's preference. If the drop-down portion of the button is used, staff members can override the user's default preference to print or email the receipt. The Quick Receipt button is enabled only if at least one checkout has been made during the current session. Note that email receipts is an option only when the patron has an email address supplied. An icon next to the Quick Receipt button will be either a printer or an envelope depending on the user's preferred receipt setting. This patch also modifies the "Done" button. If pressed, the session is ended and the receipt is generated according to the user's preferences, but the drop-down portion can be used to end the session while letting the staff member choose how the receipt is emitted. If a receipt is emailed, a toast is displayed saying so. Signed-off-by: Mike Rylander Signed-off-by: Galen Charlton --- .../perlmods/lib/OpenILS/Application/Actor.pm | 2 + .../staff/circ/patron/t_checkout.tt2 | 29 +++++- .../staff/circ/share/circ_strings.tt2 | 2 + .../js/ui/default/staff/circ/patron/app.js | 9 +- .../ui/default/staff/circ/patron/checkout.js | 93 +++++++++++++++++-- .../web/js/ui/default/staff/services/user.js | 1 + .../js/ui/default/staff/test/karma.conf.js | 2 + 7 files changed, 123 insertions(+), 15 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm index 309dd3d9e0..0e936cfbd8 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm @@ -534,6 +534,7 @@ sub flesh_user { "cards", "card", "standing_penalties", + "settings", "addresses", "billing_address", "mailing_address", @@ -3008,6 +3009,7 @@ sub user_retrieve_fleshed_by_id { "card", "groups", "standing_penalties", + "settings", "addresses", "billing_address", "mailing_address", diff --git a/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2 b/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2 index 29974aa5c6..861841988e 100644 --- a/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2 +++ b/Open-ILS/src/templates/staff/circ/patron/t_checkout.tt2 @@ -131,12 +131,33 @@
- + + +
+ + + +
-
+
+ id="done-button" type="button" + ng-click="done_auto_receipt()">[% l('Done') %] + +
diff --git a/Open-ILS/src/templates/staff/circ/share/circ_strings.tt2 b/Open-ILS/src/templates/staff/circ/share/circ_strings.tt2 index 316e64a8f3..4f9c917ada 100644 --- a/Open-ILS/src/templates/staff/circ/share/circ_strings.tt2 +++ b/Open-ILS/src/templates/staff/circ/share/circ_strings.tt2 @@ -12,6 +12,8 @@ s.CIRC_CLAIMS_RETURNED = '[% l('Item "[_1]" is marked as Claims Returned', '{{barcode}}') %]'; s.CHECKOUT_FAILED_GENERIC = '[% l('Unable to checkout copy "[_1]" : [_2]', '{{barcode}}', '{{textcode}}') %]'; +s.EMAILED_CHECKOUT_RECEIPT = + "[% l('Emailed checkout receipt') %]"; s.COPY_ALERT_MSG_DIALOG_TITLE = '[% l('Copy Alert Message for "[_1]"', '{{copy_barcode}}') %]'; s.UNCAT_ALERT_DIALOG = diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js index fe139396aa..687dd3c1a8 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/patron/app.js +++ b/Open-ILS/web/js/ui/default/staff/circ/patron/app.js @@ -5,7 +5,14 @@ */ angular.module('egPatronApp', ['ngRoute', 'ui.bootstrap', - 'egCoreMod', 'egUiMod', 'egGridMod', 'egUserMod']) + 'egCoreMod', 'egUiMod', 'egGridMod', 'egUserMod', 'ngToast']) + +.config(['ngToastProvider', function(ngToastProvider) { + ngToastProvider.configure({ + verticalPosition: 'bottom', + animation: 'fade' + }); +}]) .config(function($routeProvider, $locationProvider, $compileProvider) { $locationProvider.html5Mode(true); diff --git a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js index 3d6e9c6f74..3f82de710f 100644 --- a/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js +++ b/Open-ILS/web/js/ui/default/staff/circ/patron/checkout.js @@ -5,10 +5,10 @@ angular.module('egPatronApp').controller('PatronCheckoutCtrl', ['$scope','$q','$routeParams','egCore','egUser','patronSvc', - 'egGridDataProvider','$location','$timeout','egCirc', + 'egGridDataProvider','$location','$timeout','egCirc','ngToast', function($scope , $q , $routeParams , egCore , egUser , patronSvc , - egGridDataProvider , $location , $timeout , egCirc) { + egGridDataProvider , $location , $timeout , egCirc , ngToast) { $scope.initTab('checkout', $routeParams.id).finally(function(){ $scope.focusMe = true; @@ -34,6 +34,34 @@ function($scope , $q , $routeParams , egCore , egUser , patronSvc , ); } + function setting_value (user, setting) { + if (user) { + var list = user.settings().filter(function(s){ + return s.name() == setting; + }); + + if (list.length) return list[0].value(); + } + } + + $scope.has_email_address = function() { + return ( + patronSvc.current && + patronSvc.current.email() && + patronSvc.current.email().match(/.*@.*/).length + ); + } + + $scope.may_email_receipt = function() { + return ( + $scope.has_email_address() && + setting_value( + patronSvc.current, + 'circ.send_email_checkout_receipts' + ) == 'true' + ); + } + $scope.using_hatch = egCore.hatch.usingHatch(); egCore.hatch.getItem('circ.checkout.strict_barcode') @@ -191,18 +219,63 @@ function($scope , $q , $routeParams , egCore , egUser , patronSvc , }); } - // Redirect the user to the barcode entry page to load a new patron. - // If configured to do so, print the receipt first - $scope.done = function() { - if (printOnComplete) { - - $scope.print_receipt().then(function() { - $location.path('/circ/patron/bcsearch'); + $scope.email_receipt = function() { + if ($scope.has_email_address() && $scope.checkouts.length) { + return egCore.net.request( + 'open-ils.circ', + 'open-ils.circ.checkout.batch_notify.session.atomic', + egCore.auth.token(), + patronSvc.current.id(), + $scope.checkouts.map(function (c) { return c.circ.id() }) + ).then(function() { + ngToast.create(egCore.strings.EMAILED_CHECKOUT_RECEIPT); + return $q.when(); }); + } + return $q.when(); + } + + $scope.print_or_email_receipt = function() { + if ($scope.may_email_receipt()) return $scope.email_receipt(); + $scope.print_receipt(); + } + // set of functions to issue a receipt (if desired), then + // redirect + $scope.done_auto_receipt = function() { + if ($scope.may_email_receipt()) { + $scope.email_receipt().then(function() { + $scope.done_redirect(); + }); } else { - $location.path('/circ/patron/bcsearch'); + if (printOnComplete) { + + $scope.print_receipt().then(function() { + $scope.done_redirect(); + }); + + } else { + $scope.done_redirect(); + } } } + $scope.done_print_receipt = function() { + $scope.print_receipt().then( function () { + $scope.done_redirect(); + }); + } + $scope.done_email_receipt = function() { + $scope.email_receipt().then( function () { + $scope.done_redirect(); + }); + } + $scope.done_no_receipt = function() { + $scope.done_redirect(); + } + + // Redirect the user to the barcode entry page to load a new patron. + $scope.done_redirect = function() { + $location.path('/circ/patron/bcsearch'); + } }]) diff --git a/Open-ILS/web/js/ui/default/staff/services/user.js b/Open-ILS/web/js/ui/default/staff/services/user.js index f2a70c17dd..9fd32a8b5e 100644 --- a/Open-ILS/web/js/ui/default/staff/services/user.js +++ b/Open-ILS/web/js/ui/default/staff/services/user.js @@ -11,6 +11,7 @@ function($q, $timeout, egNet, egAuth, egOrg) { var service = { defaultFleshFields : [ 'card', + 'settings', 'standing_penalties', 'addresses', 'billing_address', diff --git a/Open-ILS/web/js/ui/default/staff/test/karma.conf.js b/Open-ILS/web/js/ui/default/staff/test/karma.conf.js index b8c1259f94..b0cef3fb7b 100644 --- a/Open-ILS/web/js/ui/default/staff/test/karma.conf.js +++ b/Open-ILS/web/js/ui/default/staff/test/karma.conf.js @@ -10,6 +10,8 @@ module.exports = function(config){ 'build/js/angular-route.min.js', 'bower_components/angular-mocks/angular-mocks.js', // testing only 'bower_components/angular-file-saver/dist/angular-file-saver.bundle.min.js', + 'bower_components/ngtoast/dist/ngToast.min.js', + 'bower_components/angular-sanitize/angular-sanitize.min.js', 'build/js/ui-bootstrap.min.js', 'build/js/hotkeys.min.js', 'build/js/angular-cookies.min.js', -- 2.43.2