]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/services/print.js
LP#1402797 webby: repair Hatch type=text printing
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / services / print.js
1 /**
2  * egPrint : manage print templates, process templates, print content
3  *
4  * TODO: create configurable links between print template and context.
5  */
6 angular.module('egCoreMod')
7
8 .factory('egPrint',
9        ['$q','$window','$timeout','$http','egHatch','egAuth','egIDL','egOrg',
10 function($q , $window , $timeout , $http , egHatch , egAuth , egIDL , egOrg) {
11
12     var service = {};
13
14     service.template_base_path = 'share/print_templates/t_';
15
16     /*
17      * context  : 'default', 'receipt','label', etc. 
18      * scope    : data loaded into the template environment
19      * template : template name (e.g. 'checkout', 'transit_slip'
20      * content  : content to print.  If 'template' is set, content is
21      *            derived from the template.
22      * content_type : 'text/html', 'text/plain', 'text/csv'
23      * show_dialog  : boolean, if true, print dialog is shown.  This setting
24      *                only affects remote printers, since browser printers
25      *                do not allow such control
26      */
27     service.print = function(args) {
28         if (!args) return $q.when();
29
30         if (args.template) {
31             // fetch the template, then proceed to printing
32
33             return service.getPrintTemplate(args.template)
34             .then(function(content) {
35                 args.content = content;
36                 if (!args.content_type) args.content_type = 'html';
37                 return service.print_content(args);
38             });
39
40         } 
41
42         return service.print_content(args);
43     }
44
45     // add commonly used attributes to the print scope
46     service.fleshPrintScope = function(scope) {
47         if (!scope) scope = {};
48         scope.today = new Date().toISOString();
49         scope.staff = egIDL.toHash(egAuth.user());
50         scope.current_location = 
51             egIDL.toHash(egOrg.get(egAuth.user().ws_ou()));
52     }
53
54     // Template has been fetched (or no template needed) 
55     // Process the template and send the result off to the printer.
56     service.print_content = function(args) {
57         service.fleshPrintScope(args.scope);
58
59         var promise;
60         if (args.content_type == 'text/html') {
61
62             // all HTML content is assumed to require compilation, 
63             // regardless of the print destination
64             promise = service.ingest_print_content(
65                 args.content_type, args.content, args.scope);
66
67         } else {
68             // text content does not require compilation for remote printing
69             promise = $q.when(args.content);
70         }
71
72         // TODO: link print context to template type
73         var context = args.context || 'default';
74
75         return promise.then(function(html) {
76
77             return egHatch.remotePrint(context,
78                 args.content_type, html, args.show_dialog)['catch'](
79
80                 function(msg) {
81                     // remote print not available; 
82
83                     if (egHatch.hatchRequired()) {
84                         console.error("Unable to print data; "
85                          + "hatchRequired=true, but hatch is not connected");
86                          return $q.reject();
87                     }
88
89                     if (args.content_type != 'text/html') {
90                         // text content does require compilation 
91                         // (absorption) for browser printing
92                         return service.ingest_print_content(
93                             args.content_type, args.content, args.scope
94                         ).then(function() { $window.print() });
95                     } else {
96                         // HTML content is already ingested and accessible
97                         // within the page to the printer.  
98                         $window.print();
99                     }
100                 }
101             );
102         });
103     }
104
105     // loads an HTML print template by name from the server
106     // If no template is available in local/hatch storage, 
107     // fetch the template as an HTML file from the server.
108     service.getPrintTemplate = function(name) {
109         var deferred = $q.defer();
110
111         egHatch.getItem('eg.print.template.' + name)
112         .then(function(html) {
113
114             if (html) {
115                 // we have a locally stored template
116                 deferred.resolve(html);
117                 return;
118             }
119
120             var path = service.template_base_path + name;
121             console.debug('fetching template ' + path);
122
123             $http.get(path)
124             .success(function(data) { deferred.resolve(data) })
125             .error(function() {
126                 console.error('unable to locate print template: ' + name);
127                 deferred.reject();
128             });
129         });
130
131         return deferred.promise;
132     }
133
134     service.storePrintTemplate = function(name, html) {
135         return egHatch.setItem('eg.print.template.' + name, html);
136     }
137
138     return service;
139 }])
140
141
142 /**
143  * Container for inserting print data into the browser page.
144  * On insert, $window.print() is called to print the data.
145  * The div housing eg-print-container must apply the correct
146  * print media CSS to ensure this content (and not the rest
147  * of the page) is printed.
148  */
149
150 // FIXME: only apply print CSS when print commands are issued via the 
151 // print container, otherwise using the browser's native print page 
152 // option will always result in empty pages.  Move the print CSS
153 // out of the standalone CSS file and put it into a template file
154 // for this directive.
155 .directive('egPrintContainer', ['$compile', function($compile) {
156     return {
157         restrict : 'AE',
158         scope : {}, // isolate our scope
159         link : function(scope, element, attrs) {
160             scope.elm = element;
161         },
162         controller : 
163                    ['$scope','$q','$window','$timeout','egHatch','egPrint',
164             function($scope , $q , $window , $timeout , egHatch , egPrint) {
165
166                 egPrint.ingest_print_content = function(type, content, printScope) {
167
168                     if (type == 'text/csv' || type == 'text/plain') {
169                         // preserve newlines, spaces, etc.
170                         content = '<pre>' + content + '</pre>';
171                     }
172
173                     $scope.elm.html(content);
174
175                     var sub_scope = $scope.$new(true);
176                     angular.forEach(printScope, function(val, key) {
177                         sub_scope[key] = val;
178                     })
179
180                     var resp = $compile($scope.elm.contents())(sub_scope);
181
182                     var deferred = $q.defer();
183                     $timeout(function(){
184                         // give the $digest a chance to complete then
185                         // resolve with the compiled HTML from our
186                         // print container
187
188                         deferred.resolve(
189                             resp.contents()[0].parentNode.innerHTML
190                         );
191                     });
192
193                     return deferred.promise;
194                 }
195             }
196         ]
197     }
198 }])
199