]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/circ/holds/app.js
webstaff: give the Holds Shelf a template and print button
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / circ / holds / app.js
1 angular.module('egHoldsApp', 
2     ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod'])
3
4 .config(function($routeProvider, $locationProvider, $compileProvider) {
5     $locationProvider.html5Mode(true);
6     $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|blob):/); // grid export
7
8     var resolver = {delay : 
9         ['egStartup', function(egStartup) {return egStartup.go()}]}
10
11     $routeProvider.when('/circ/holds/shelf', {
12         templateUrl: './circ/holds/t_shelf',
13         controller: 'HoldsShelfCtrl',
14         resolve : resolver
15     });
16
17     $routeProvider.when('/circ/holds/shelf/:hold_id', {
18         templateUrl: './circ/holds/t_shelf',
19         controller: 'HoldsShelfCtrl',
20         resolve : resolver
21     });
22
23     $routeProvider.when('/circ/holds/pull', {
24         templateUrl: './circ/holds/t_pull',
25         controller: 'HoldsPullListCtrl',
26         resolve : resolver
27     });
28
29     $routeProvider.when('/circ/holds/pull/:hold_id', {
30         templateUrl: './circ/holds/t_pull',
31         controller: 'HoldsPullListCtrl',
32         resolve : resolver
33     });
34
35     $routeProvider.otherwise({redirectTo : '/circ/holds/shelf'});
36 })
37
38 .factory('holdUiSvc', function() {
39     return {
40         holds : [] // cache
41     }
42 })
43
44 .controller('HoldsShelfCtrl',
45        ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egHoldGridActions','egCirc','egGridDataProvider',
46 function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egHoldGridActions , egCirc , egGridDataProvider)  {
47     $scope.detail_hold_id = $routeParams.hold_id;
48
49     var hold_ids = [];
50     var holds = [];
51     var clear_mode = false;
52     $scope.gridControls = {};
53     $scope.grid_actions = egHoldGridActions;
54
55     function fetch_holds(offset, count) {
56         var ids = hold_ids.slice(offset, offset + count);
57         return egHolds.fetch_holds(ids).then(null, null,
58             function(hold_data) { 
59                 holds.push(hold_data);
60                 return hold_data; // to the grid
61             }
62         );
63     }
64
65     var provider = egGridDataProvider.instance({});
66     $scope.gridDataProvider = provider;
67
68     function refresh_page() {
69         holds = [];
70         hold_ids = [];
71         provider.refresh();
72     }
73     // called after any egHoldGridActions action occurs
74     $scope.grid_actions.refresh = refresh_page;
75
76     provider.get = function(offset, count) {
77
78         // see if we have the requested range cached
79         if (holds[offset]) {
80             return provider.arrayNotifier(holds, offset, count);
81         }
82
83         // see if we have the holds IDs for this range already loaded
84         if (hold_ids[offset]) {
85             return fetch_holds(offset, count);
86         }
87
88         var deferred = $q.defer();
89         hold_ids = [];
90         holds = [];
91
92         var method = 'open-ils.circ.captured_holds.id_list.on_shelf.retrieve.authoritative.atomic';
93         if (clear_mode) 
94             method = 'open-ils.circ.captured_holds.id_list.expired_on_shelf_or_wrong_shelf.retrieve.atomic';
95
96         egCore.net.request(
97             'open-ils.circ', method,
98             egCore.auth.token(), $scope.pickup_ou.id()
99
100         ).then(function(ids) {
101             if (!ids.length) { 
102                 deferred.resolve(); 
103                 return; 
104             }
105
106             hold_ids = ids;
107             fetch_holds(offset, count)
108             .then(deferred.resolve, null, deferred.notify);
109         });
110
111         return deferred.promise;
112     }
113
114     // re-draw the grid when user changes the org selector
115     $scope.pickup_ou = egCore.org.get(egCore.auth.user().ws_ou());
116     $scope.$watch('pickup_ou', function(newVal, oldVal) {
117         if (newVal && newVal != oldVal) 
118             refresh_page();
119     });
120
121     $scope.detail_view = function(action, user_data, items) {
122         if (h = items[0]) {
123             $location.path('/circ/holds/shelf/' + h.hold.id());
124         }
125     }
126
127     $scope.list_view = function(items) {
128         $location.path('/circ/holds/shelf');
129     }
130
131     // when the detail hold is fetched (and updated), update the bib
132     // record summary display record id.
133     $scope.set_hold = function(hold_data) {
134         $scope.detail_hold_record_id = hold_data.mvr.doc_id();
135     }
136
137     // manage active vs. clearable holds display
138     var clearing = false; // true if actively clearing holds (below)
139     $scope.is_clearing = function() { return clearing };
140     $scope.active_mode = function() {return !clear_mode}
141     $scope.clear_mode = function() {return clear_mode}
142     $scope.show_clearable = function() { clear_mode = true; refresh_page() }
143     $scope.show_active = function() { clear_mode = false; refresh_page() }
144     $scope.disable_clear = function() { return clearing || !clear_mode }
145
146     // udpate the in-grid hold with the clear-shelf cached response info.
147     function handle_clear_cache_resp(resp) {
148         if (!angular.isArray(resp)) resp = [resp];
149         angular.forEach(resp, function(info) {
150             if (info.action) {
151                 var grid_item = holds.filter(function(item) {
152                     return item.hold.id() == info.hold_details.id
153                 })[0];
154
155                 // there will be no grid item if the hold is off-page
156                 if (grid_item) {
157                     grid_item.post_clear = 
158                         egCore.strings['CLEAR_SHELF_ACTION_' + info.action];
159                 }
160             }
161         });
162     }
163
164     $scope.clear_holds = function() {
165         clearing = true;
166         $scope.clear_progress = {max : 0, value : 0};
167
168         // we want to see all processed holds, so (effectively) remove
169         // the grid limit.
170         $scope.gridControls.setLimit(1000, true); 
171
172         // initiate clear shelf and grab cache key
173         egCore.net.request(
174             'open-ils.circ',
175             'open-ils.circ.hold.clear_shelf.process',
176             egCore.auth.token(), $scope.pickup_ou.id(),
177             null, 1
178
179         // request responses from the clear shelf cache
180         ).then(
181             
182             // clear shelf done; fetch the cached results.
183             function(resp) {
184                 clearing = false;
185                 egCore.net.request(
186                     'open-ils.circ',
187                     'open-ils.circ.hold.clear_shelf.get_cache',
188                     egCore.auth.token(), resp.cache_key, 1
189                 ).then(null, null, handle_clear_cache_resp);
190             }, 
191
192             null,
193
194             // handle streamed clear_shelf progress updates
195             function(resp) {
196                 if (resp.maximum) 
197                     $scope.clear_progress.max = resp.maximum;
198                 if (resp.progress)
199                     $scope.clear_progress.value = resp.progress;
200             }
201
202         );
203     }
204
205     $scope.print_list_progress = null;
206     $scope.print_shelf_list = function() {
207         var print_holds = [];
208         $scope.print_list_loading = true;
209         $scope.print_list_progress = 0;
210
211         // collect the full list of holds
212         egCore.net.request(
213             'open-ils.circ',
214             'open-ils.circ.captured_holds.id_list.on_shelf.retrieve.authoritative.atomic',
215             egCore.auth.token(), $scope.pickup_ou.id()
216         ).then( function(idlist) {
217
218             egHolds.fetch_holds(idlist).then(
219                 function () {
220                     console.debug('printing ' + print_holds.length + ' holds');
221                     // holds fetched, send to print
222                     egCore.print.print({
223                         context : 'default', 
224                         template : 'hold_shelf_list', 
225                         scope : {holds : print_holds}
226                     })
227                 },
228                 null,
229                 function(hold_data) {
230                     $scope.print_list_progress++;
231                     egHolds.local_flesh(hold_data);
232                     print_holds.push(hold_data);
233                     hold_data.title = hold_data.mvr.title();
234                     hold_data.author = hold_data.mvr.author();
235                     hold_data.hold = egCore.idl.toHash(hold_data.hold);
236                     hold_data.copy = egCore.idl.toHash(hold_data.copy);
237                     hold_data.volume = egCore.idl.toHash(hold_data.volume);
238                     hold_data.part = egCore.idl.toHash(hold_data.part);
239                 }
240             )
241         }).finally(function() {
242             $scope.print_list_loading = false;
243             $scope.print_list_progress = null;
244         });
245     }
246
247     refresh_page();
248
249 }])
250
251 .controller('HoldsPullListCtrl',
252        ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egCirc','egGridDataProvider','egHoldGridActions','holdUiSvc',
253 function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egCirc , egGridDataProvider , egHoldGridActions , holdUiSvc)  {
254     $scope.detail_hold_id = $routeParams.hold_id;
255
256     var provider = egGridDataProvider.instance({});
257     $scope.gridDataProvider = provider;
258
259     $scope.grid_actions = egHoldGridActions;
260     $scope.grid_actions.refresh = function() {
261         holdUiSvc.holds = [];
262         provider.refresh();
263     }
264
265     provider.get = function(offset, count) {
266
267         if (holdUiSvc.holds[offset]) {
268             return provider.arrayNotifier(holdUiSvc.holds, offset, count);
269         }
270
271         var deferred = $q.defer();
272         var recv_index = 0;
273
274         // fetch the IDs
275         egCore.net.request(
276             'open-ils.circ',
277             'open-ils.circ.hold_pull_list.fleshed.stream',
278             egCore.auth.token(), count, offset
279         ).then(
280             deferred.resolve, null, 
281             function(hold_data) {
282                 egHolds.local_flesh(hold_data);
283                 holdUiSvc.holds[offset + recv_index++] = hold_data;
284                 deferred.notify(hold_data);
285             }
286         );
287
288         return deferred.promise;
289     }
290
291     $scope.detail_view = function(action, user_data, items) {
292         if (h = items[0]) {
293             $location.path('/circ/holds/pull/' + h.hold.id());
294         }
295     }
296
297     $scope.list_view = function(items) {
298         $location.path('/circ/holds/pull');
299     }
300
301     // when the detail hold is fetched (and updated), update the bib
302     // record summary display record id.
303     $scope.set_hold = function(hold_data) {
304         $scope.detail_hold_record_id = hold_data.mvr.doc_id();
305     }
306
307     // By default, this action is hidded from the UI, but leaving it
308     // here in case it's needed in the future
309     $scope.print_list_alt = function() {
310         var url = '/opac/extras/circ/alt_holds_print.html';
311         var win = $window.open(url, '_blank');
312         win.ses = function() {return egCore.auth.token()};
313         win.open();
314         win.focus();
315     }
316
317     $scope.print_list_progress = null;
318     $scope.print_full_list = function() {
319         var print_holds = [];
320         $scope.print_list_loading = true;
321         $scope.print_list_progress = 0;
322
323         // collect the full list of holds
324         egCore.net.request(
325             'open-ils.circ',
326             'open-ils.circ.hold_pull_list.fleshed.stream',
327             egCore.auth.token(), 10000, 0
328         ).then(
329             function() {
330                 console.debug('printing ' + print_holds.length + ' holds');
331
332                 // holds fetched, send to print
333                 egCore.print.print({
334                     context : 'default', 
335                     template : 'hold_pull_list', 
336                     scope : {holds : print_holds}
337                 });
338             },
339             null, 
340             function(hold_data) {
341                 $scope.print_list_progress++;
342                 egHolds.local_flesh(hold_data);
343                 print_holds.push(hold_data);
344                 hold_data.title = hold_data.mvr.title();
345                 hold_data.author = hold_data.mvr.author();
346                 hold_data.hold = egCore.idl.toHash(hold_data.hold);
347                 hold_data.copy = egCore.idl.toHash(hold_data.copy);
348                 hold_data.volume = egCore.idl.toHash(hold_data.volume);
349                 hold_data.part = egCore.idl.toHash(hold_data.part);
350             }
351         ).finally(function() {
352             $scope.print_list_loading = false;
353             $scope.print_list_progress = null;
354         });
355     }
356
357 }])
358