<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/org.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/startup.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/hatch.js"></script>
+<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/print.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/coresvc.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/navbar.js"></script>
<script src="[% ctx.media_prefix %]/js/ui/default/staff/services/statusbar.js"></script>
<div class="flex-row pad-vert">
<div class="flex-cell"></div>
- <div class="pad-horiz">
- <input ng-model="auto_print" type="checkbox"/>
- [% l('Auto-Print') %]
+ <div class="pad-horiz checkbox">
+ <label>
+ <input ng-model="show_print_dialog" type="checkbox"/>
+ [% l('Show Print Dialog') %]
+ </label>
</div>
- <div>
+ <div class="pad-horiz">
<button class="btn btn-default"
ng-click="print_receipt()">[% l('Print Receipt') %]</button>
</div>
+ <div>
+ <button class="btn btn-default" ng-click="done()">[% l('Done') %]</button>
+ </div>
</div>
'services/org.js',
'services/startup.js',
'services/hatch.js',
+ 'services/print.js',
'services/coresvc.js',
'services/navbar.js',
'services/statusbar.js',
$scope.testPrint = function(withDialog) {
if ($scope.contentType == 'text/plain') {
- egCore.hatch.print(
- $scope.context,
- $scope.contentType,
- $scope.textPrintContent,
- null,
- withDialog
- );
+ egCore.print.print({
+ context : $scope.context,
+ content_type : $scope.contentType,
+ content : $scope.textPrintContent,
+ show_dialog : withDialog
+ });
} else {
- egCore.hatch.print(
- $scope.context,
- $scope.contentType,
- $scope.htmlPrintContent,
- {
+ egCore.print.print({
+ context : $scope.context,
+ content_type : $scope.contentType,
+ content : $scope.htmlPrintContent,
+ scope : {
value1 : 'Value One',
value2 : 'Value Two',
date_value : '2015-02-04T14:04:34-0400'
},
- withDialog
- );
+ show_dialog : withDialog
+ });
}
}
}
$scope.preview_scope = {
- current_location : egCore.idl.toHash(
- egCore.org.get(egCore.auth.user().ws_ou())),
- today : new Date(),
-
//bills
transactions : [
{
},
title : seed_record.title,
author : seed_record.author,
- staff : egCore.idl.toHash(egCore.auth.user()),
patron : egCore.idl.toHash(egCore.auth.user()),
address : seed_addr
}
$scope.preview_scope.payments[1].xact.title = seed_record.title;
$scope.preview_scope.payments[1].xact.copy_barcode = seed_copy.barcode;
+ // today, staff, current_location, etc.
+ egCore.print.fleshPrintScope($scope);
+
$scope.template_changed = function() {
$scope.print.load_failed = false;
- egCore.hatch.getPrintTemplate($scope.print.template_name)
+ egCore.print.getPrintTemplate($scope.print.template_name)
.then(
function(html) {
$scope.print.template_content = html;
$scope.summary_stat_cats = function() { return patronSvc.summary_stat_cats }
$scope.print_address = function(addr) {
- egCore.hatch.printFromTemplate('default', 'patron_address', {
- patron : egCore.idl.toHash(patronSvc.current),
- address : egCore.idl.toHash(addr)
+ egCore.print.print({
+ context : 'default',
+ template : 'patron_address',
+ scope : {
+ patron : egCore.idl.toHash(patronSvc.current),
+ address : egCore.idl.toHash(addr)
+ }
});
}
}])
$scope.printNote = function(note) {
var hash = egCore.idl.toHash(note);
hash.usr = egCore.idl.toHash($scope.patron());
- egCore.hatch.printFromTemplate(
- 'default', 'patron_note', {note : hash});
+ egCore.print.print({
+ context : 'default',
+ template : 'patron_note',
+ scope : {note : hash}
+ });
}
// perform the initial note fetch
print_data.payment_applied * 100) / 100;
for (var i = 0; i < $scope.receipt_count; i++) {
- egCore.hatch.printFromTemplate(
- 'receipt', 'bill_payment', print_data);
+ egCore.print.print({
+ context : 'receipt',
+ template : 'bill_payment',
+ scope : print_data
+ });
}
}
{authoritative : true}
).then(
function() {
- egCore.hatch.printFromTemplate(
- 'receipt', 'bills_current',
- { transactions : xacts,
+ egCore.print.print({
+ context : 'receipt',
+ template : 'bills_current',
+ scope : {
+ transactions : xacts,
current_location : egCore.idl.toHash(
egCore.org.get(egCore.auth.user().ws_ou()))
}
- );
+ });
},
null,
function(xact) {
angular.module('egPatronApp').controller('PatronCheckoutCtrl',
['$scope','$q','$modal','$routeParams','egCore','egUser','patronSvc',
- 'egGridDataProvider','$location','egCirc',
+ 'egGridDataProvider','$location','$timeout','egCirc',
function($scope , $q , $modal , $routeParams , egCore , egUser , patronSvc ,
- egGridDataProvider , $location , egCirc) {
+ egGridDataProvider , $location , $timeout , egCirc) {
$scope.initTab('checkout', $routeParams.id);
$scope.focusMe = true;
}
});
- egCirc.get_circ_mods().then(function(list) {
- $scope.circModifiers = list;
+ var printOnComplete = true;
+ egCore.org.settings([
+ 'circ.staff_client.do_not_auto_attempt_print'
+ ]).then(function(settings) {
+ printOnComplete = !Boolean(
+ settings['circ.staff_client.do_not_auto_attempt_print']);
});
egCirc.get_noncat_types().then(function(list) {
}
}
+ // TODO: show print dialog
$scope.print_receipt = function() {
- var print_data = {
- circulations : [],
- staff : egCore.idl.toHash(egCore.auth.user()),
- current_location : egCore.idl.toHash(
- egCore.org.get(egCore.auth.user().ws_ou()))
- }
+ var print_data = {circulations : []}
+
+ if ($scope.checkouts.length == 0) return $q.when();
+
angular.forEach($scope.checkouts, function(co) {
var circ = egCore.idl.toHash(co.payload.circ);
circ.title = co.payload.record.title;
print_data.circulations.push(circ);
});
- egCore.hatch.printFromTemplate('default', 'checkout', print_data);
+ return egCore.print.print({
+ context : 'default',
+ template : 'checkout',
+ scope : print_data
+ });
+ }
+
+ // 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');
+ });
+
+ } else {
+ $location.path('/circ/patron/bcsearch');
+ }
}
}])
transit : egCore.idl.toHash(transit),
title : evt.payload.record.title(),
author : evt.payload.record.author(),
- staff : egCore.idl.toHash(egCore.auth.user()),
copy : egCore.idl.toHash(evt.payload.copy),
dest_location :
egCore.idl.toHash(egCore.org.get(transit.dest())),
dest_address : egCore.idl.toHash(destAddr),
- current_location : egCore.idl.toHash(
- egCore.org.get(egCore.auth.user().ws_ou()))
}
var template = 'transit_slip';
print_context.patron = egCore.idl.toHash(holdUser);
}
- egCore.hatch.printFromTemplate(
- 'default', template, print_context);
+ egCore.print.print({
+ context : 'default',
+ template : template,
+ scope : print_context
+ });
}
}],
resolve : {
.factory('egCore',
['egIDL','egNet','egEnv','egOrg','egPCRUD','egEvent','egAuth',
- 'egPerm','egHatch','egStartup','egStrings',
+ 'egPerm','egHatch','egPrint','egStartup','egStrings',
function(egIDL , egNet , egEnv , egOrg , egPCRUD , egEvent , egAuth ,
- egPerm , egHatch , egStartup , egStrings) {
+ egPerm , egHatch , egPrint , egStartup , egStrings) {
return {
idl : egIDL,
auth : egAuth,
perm : egPerm,
hatch : egHatch,
+ print : egPrint,
startup : egStartup,
strings : egStrings
};
* Most handlers also provide direct remote and local variants to the
* application can decide to which to use as needed.
*
- * Printing is handled locally with an egPrintContainer whose contents
- * are made visible during printing using CSS print media.
- *
* Local storage requests are handled by $window.localStorage.
*
* Note that all top-level and remote requests return promises. All
angular.module('egCoreMod')
.factory('egHatch',
- ['$q','$window','$timeout','$interpolate','$rootScope','$http',
- function($q , $window , $timeout , $interpolate , $rootScope , $http) {
+ ['$q','$window','$timeout','$interpolate','$http',
+ function($q , $window , $timeout , $interpolate , $http) {
var service = {};
service.msgId = 0;
service.defaultHatchURL = 'wss://localhost:8443/hatch';
service.hatchRequired = false;
- service.printTemplateBase = 'share/print_templates/t_';
-
// write a message to the Hatch websocket
service.sendToHatch = function(msg) {
var msg2 = {};
}
}
- service.printFromTemplate = function(context, templateName, printScope) {
+ service.getPrintConfig = function() {
+ if (service.printConfig)
+ return $q.when(service.printConfig);
- // populate some common print scope values...
- printScope.today = new Date();
- return service.getPrintTemplate(templateName)
- .then(function(template) {
- service.print(context, 'text/html', template, printScope);
+ return service.getRemoteItem('eg.print.config')
+ .then(function(conf) {
+ return (service.printConfig = conf || {})
});
}
- service.print = function(
- context, contentType, content, printScope, withDialog) {
-
- var promise;
- if (contentType == 'text/html') {
- // all HTML content is assumed to require compilation, regardless
- // of the print destination
- promise = service.ingestPrintContent(
- contentType, content, printScope);
- } else {
- // text content does not require compilation for remote printing
- promise = $q.when(content);
- }
-
- return promise.then(function(html) {
- return service.remotePrint(
- context, contentType, html, withDialog)['catch'](
-
- function(msg) {
- // remote print not available;
- if (contentType != 'text/html') {
- // text content does require compilation
- // (absorption) for browser printing
- service.ingestPrintContent(contentType, content, {})
- .then(function() { $window.print() });
- } else {
- // HTML content is already ingested and accessible
- // within the page to the printer.
- $window.print();
- }
- }
- );
- });
+ service.setPrintConfig = function(conf) {
+ service.printConfig = conf;
+ return service.setRemoteItem('eg.print.config', conf);
}
+
service.remotePrint = function(
context, contentType, content, withDialog) {
);
}
- // -------------
- // print configuration is always stored as remote items,
- // since there is no concept of a local printer
- service.getPrintConfig = function() {
- if (service.printConfig)
- return $q.when(service.printConfig);
-
- return service.getRemoteItem('eg.print.config')
- .then(function(conf) {
- return (service.printConfig = conf || {})
- });
- }
- service.setPrintConfig = function(conf) {
- service.printConfig = conf;
- return service.setRemoteItem('eg.print.config', conf);
- }
- // -----------
-
// launch the print dialog then attach the resulting configuration
// to the requested context, then store the final values.
service.configurePrinter = function(context, printer) {
return keys;
}
- // loads an HTML print template by name from the server
- // If no template is available in local/hatch storage,
- // fetch the template as an HTML file from the server.
- service.getPrintTemplate = function(name) {
- var deferred = $q.defer();
-
- service.getItem('eg.print.template.' + name)
- .then(function(html) {
-
- if (html) {
- // we have a locally stored template
- deferred.resolve(html);
- return;
- }
-
- var path = service.printTemplateBase + name;
- console.debug('fetching template ' + path);
-
- $http.get(path)
- .success(function(data) { deferred.resolve(data) })
- .error(function() {
- console.error('unable to locate print template: ' + name);
- deferred.reject();
- });
- });
-
- return deferred.promise;
- }
-
- service.storePrintTemplate = function(name, html) {
- return service.setItem('eg.print.template.' + name, html);
- }
-
return service;
}])
-/**
- * Container for inserting print data into the browser page.
- * On insert, $window.print() is called to print the data.
- * The div housing eg-print-container must apply the correct
- * print media CSS to ensure this content (and not the rest
- * of the page) is printed.
- */
-
-// FIXME: only apply print CSS when print commands are issued via the
-// print container, otherwise using the browser's native print page
-// option will always result in empty pages. Move the print CSS
-// out of the standalone CSS file and put it into a template file
-// for this directive.
-.directive('egPrintContainer', ['$compile', function($compile) {
- return {
- restrict : 'AE',
- scope : {}, // isolate our scope
- link : function(scope, element, attrs) {
- scope.elm = element;
- },
- controller :
- ['$scope','$q','$window','$timeout','egHatch',
- function($scope , $q , $window , $timeout , egHatch) {
-
- egHatch.ingestPrintContent = function(type, content, printScope) {
-
- if (type == 'text/csv' || type == 'text/plain') {
- // preserve newlines, spaces, etc.
- content = '<pre>' + content + '</pre>';
- }
-
- $scope.elm.html(content);
-
- var sub_scope = $scope.$new(true);
- angular.forEach(printScope, function(val, key) {
- sub_scope[key] = val;
- })
-
- var resp = $compile($scope.elm.contents())(sub_scope);
-
- var deferred = $q.defer();
- $timeout(function(){
- // give the $digest a chance to complete then
- // resolve with the compiled HTML from our
- // print container
-
- deferred.resolve(
- resp.contents()[0].parentNode.innerHTML
- );
- });
-
- return deferred.promise;
- }
- }
- ]
- }
-}])
-
--- /dev/null
+/**
+ */
+angular.module('egCoreMod')
+
+.factory('egPrint',
+ ['$q','$window','$timeout','$http','egHatch','egAuth','egIDL','egOrg',
+function($q , $window , $timeout , $http , egHatch , egAuth , egIDL , egOrg) {
+
+ var service = {};
+
+ service.template_base_path = 'share/print_templates/t_';
+
+ /*
+ * context : 'default', 'receipt','label', etc.
+ * scope : data loaded into the template environment
+ * template : template name (e.g. 'checkout', 'transit_slip'
+ * content : content to print. If 'template' is set, content is
+ * derived from the template.
+ * content_type : 'text/html', 'text/plain', 'text/csv'
+ * show_dialog : boolean, if true, print dialog is shown. This setting
+ * only affects remote printers, since browser printers
+ * do not allow such control
+ */
+ service.print = function(args) {
+ if (!args) return $q.when();
+
+ if (args.template) {
+ // fetch the template, then proceed to printing
+
+ return service.getPrintTemplate(args.template)
+ .then(function(content) {
+ args.content = content;
+ if (!args.content_type) args.content_type = 'html';
+ return service.print_content(args);
+ });
+
+ }
+
+ return service.print_content(args);
+ }
+
+ // add commonly used attributes to the print scope
+ service.fleshPrintScope = function(scope) {
+ if (!scope) scope = {};
+ scope.today = new Date();
+ scope.staff = egIDL.toHash(egAuth.user());
+ scope.current_location =
+ egIDL.toHash(egOrg.get(egAuth.user().ws_ou()));
+ }
+
+ // Template has been fetched (or no template needed)
+ // Process the template and send the result off to the printer.
+ service.print_content = function(args) {
+ service.fleshPrintScope(args.scope);
+
+ var promise;
+ if (args.content_type == 'text/html') {
+
+ // all HTML content is assumed to require compilation,
+ // regardless of the print destination
+ promise = service.ingest_print_content(
+ args.content_type, args.content, args.scope);
+
+ } else {
+ // text content does not require compilation for remote printing
+ promise = $q.when();
+ }
+
+ return promise.then(function(html) {
+
+ return egHatch.remotePrint(args.context,
+ args.content_type, html, args.show_dialog)['catch'](
+
+ function(msg) {
+ // remote print not available;
+
+ if (args.content_type != 'text/html') {
+ // text content does require compilation
+ // (absorption) for browser printing
+ return service.ingest_print_content(
+ args.content_type, args.content, args.scope
+ ).then(function() { $window.print() });
+ } else {
+ // HTML content is already ingested and accessible
+ // within the page to the printer.
+ $window.print();
+ }
+ }
+ );
+ });
+ }
+
+ // loads an HTML print template by name from the server
+ // If no template is available in local/hatch storage,
+ // fetch the template as an HTML file from the server.
+ service.getPrintTemplate = function(name) {
+ var deferred = $q.defer();
+
+ egHatch.getItem('eg.print.template.' + name)
+ .then(function(html) {
+
+ if (html) {
+ // we have a locally stored template
+ deferred.resolve(html);
+ return;
+ }
+
+ var path = service.template_base_path + name;
+ console.debug('fetching template ' + path);
+
+ $http.get(path)
+ .success(function(data) { deferred.resolve(data) })
+ .error(function() {
+ console.error('unable to locate print template: ' + name);
+ deferred.reject();
+ });
+ });
+
+ return deferred.promise;
+ }
+
+ service.storePrintTemplate = function(name, html) {
+ return egHatch.setItem('eg.print.template.' + name, html);
+ }
+
+ return service;
+}])
+
+
+/**
+ * Container for inserting print data into the browser page.
+ * On insert, $window.print() is called to print the data.
+ * The div housing eg-print-container must apply the correct
+ * print media CSS to ensure this content (and not the rest
+ * of the page) is printed.
+ */
+
+// FIXME: only apply print CSS when print commands are issued via the
+// print container, otherwise using the browser's native print page
+// option will always result in empty pages. Move the print CSS
+// out of the standalone CSS file and put it into a template file
+// for this directive.
+.directive('egPrintContainer', ['$compile', function($compile) {
+ return {
+ restrict : 'AE',
+ scope : {}, // isolate our scope
+ link : function(scope, element, attrs) {
+ scope.elm = element;
+ },
+ controller :
+ ['$scope','$q','$window','$timeout','egHatch','egPrint',
+ function($scope , $q , $window , $timeout , egHatch , egPrint) {
+
+ egPrint.ingest_print_content = function(type, content, printScope) {
+
+ if (type == 'text/csv' || type == 'text/plain') {
+ // preserve newlines, spaces, etc.
+ content = '<pre>' + content + '</pre>';
+ }
+
+ $scope.elm.html(content);
+
+ var sub_scope = $scope.$new(true);
+ angular.forEach(printScope, function(val, key) {
+ sub_scope[key] = val;
+ })
+
+ var resp = $compile($scope.elm.contents())(sub_scope);
+
+ var deferred = $q.defer();
+ $timeout(function(){
+ // give the $digest a chance to complete then
+ // resolve with the compiled HTML from our
+ // print container
+
+ deferred.resolve(
+ resp.contents()[0].parentNode.innerHTML
+ );
+ });
+
+ return deferred.promise;
+ }
+ }
+ ]
+ }
+}])
+
'services/env.js',
'services/org.js',
'services/hatch.js',
+ 'services/print.js',
'services/coresvc.js',
'services/user.js',
'services/startup.js',