]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/circ/holds/app.js
holds shelf. actions / clear shelf
[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.otherwise({redirectTo : '/circ/holds/shelf'});
24 })
25
26 .controller('HoldsShelfCtrl',
27        ['$scope','$q','$routeParams','$window','$location','egCore','egHolds','egCirc','egGridDataProvider',
28 function($scope , $q , $routeParams , $window , $location , egCore , egHolds , egCirc , egGridDataProvider)  {
29     $scope.detail_hold_id = $routeParams.hold_id;
30
31     var hold_ids = [];
32     var holds = [];
33     var clear_mode = false;
34     $scope.gridControls = {};
35
36     function fetch_holds(offset, count) {
37         var ids = hold_ids.slice(offset, offset + count);
38         return egHolds.fetch_holds(ids).then(null, null,
39             function(hold_data) { 
40                 holds.push(hold_data);
41                 return hold_data; // to the grid
42             }
43         );
44     }
45
46     var provider = egGridDataProvider.instance({});
47     $scope.gridDataProvider = provider;
48
49     provider.get = function(offset, count) {
50
51         // see if we have the requested range cached
52         if (holds[offset]) {
53             return provider.arrayNotifier(patronSvc.holds, offset, count);
54         }
55
56         // see if we have the holds IDs for this range already loaded
57         if (hold_ids[offset]) {
58             return fetch_holds(offset, count);
59         }
60
61         var deferred = $q.defer();
62         hold_ids = [];
63         holds = [];
64
65         var method = 'open-ils.circ.captured_holds.id_list.on_shelf.retrieve.authoritative.atomic';
66         if (clear_mode) 
67             method = 'open-ils.circ.captured_holds.id_list.expired_on_shelf_or_wrong_shelf.retrieve.atomic';
68
69         egCore.net.request(
70             'open-ils.circ', method,
71             egCore.auth.token(), $scope.pickup_ou.id()
72
73         ).then(function(ids) {
74             if (!ids.length) { 
75                 deferred.resolve(); 
76                 return; 
77             }
78
79             hold_ids = ids;
80             fetch_holds(offset, count)
81             .then(deferred.resolve, null, deferred.notify);
82         });
83
84         return deferred.promise;
85     }
86
87     function refresh_page() {
88         holds = [];
89         hold_ids = [];
90         provider.refresh();
91     }
92
93
94     // re-draw the grid when user changes the org selector
95     $scope.pickup_ou = egCore.org.get(egCore.auth.user().ws_ou());
96     $scope.$watch('pickup_ou', function(newVal, oldVal) {
97         if (newVal && newVal != oldVal) 
98             refresh_page();
99     });
100
101     $scope.detail_view = function(action, user_data, items) {
102         if (h = items[0]) {
103             $location.path('/circ/holds/shelf/' + h.hold.id());
104         }
105     }
106
107     $scope.list_view = function(items) {
108         $location.path('/circ/holds/shelf');
109     }
110
111     // when the detail hold is fetched (and updated), update the bib
112     // record summary display record id.
113     $scope.set_hold = function(hold_data) {
114         $scope.detail_hold_record_id = hold_data.mvr.doc_id();
115     }
116
117     // manage active vs. clearable holds display
118     var clearing = false; // true if actively clearing holds (below)
119     $scope.is_clearing = function() { return clearing };
120     $scope.active_mode = function() {return !clear_mode}
121     $scope.clear_mode = function() {return clear_mode}
122     $scope.show_clearable = function() { clear_mode = true; refresh_page() }
123     $scope.show_active = function() { clear_mode = false; refresh_page() }
124     $scope.disable_clear = function() { return clearing || !clear_mode }
125
126     // action handlers
127     // TODO: These are copied directly from patron/holds.js.  
128     // Consider refactoring / consolidating.
129     $scope.cancel_hold = function(items) {
130         var hold_ids = items.filter(function(item) {
131             return !item.hold.cancel_time();
132         }).map(function(item) {return item.hold.id()});
133
134         return egHolds.cancel_holds(hold_ids).then(refresh_page);
135     }
136
137     // jump to circ list for either 1) the targeted copy or
138     // 2) the hold target copy for copy-level holds
139     $scope.show_recent_circs = function(items) {
140         if (items.length && (copy = items[0].copy)) {
141             var url = $location.path(
142                 '/cat/item/' + copy.id() + '/circ_list').absUrl();
143             $window.open(url, '_blank').focus();
144         }
145     }
146
147     function generic_update(items, action) {
148         if (!items.length) return $q.when();
149         var hold_ids = items.map(function(item) {return item.hold.id()});
150         return egHolds[action](hold_ids).then(refresh_page);
151     }
152
153     $scope.set_copy_quality = function(items) {
154         generic_update(items, 'set_copy_quality'); }
155     $scope.edit_pickup_lib = function(items) {
156         generic_update(items, 'edit_pickup_lib'); }
157     $scope.edit_notify_prefs = function(items) {
158         generic_update(items, 'edit_notify_prefs'); }
159     $scope.edit_dates = function(items) {
160         generic_update(items, 'edit_dates'); }
161     $scope.suspend = function(items) {
162         generic_update(items, 'suspend_holds'); }
163     $scope.activate = function(items) {
164         generic_update(items, 'activate_holds'); }
165     $scope.set_top_of_queue = function(items) {
166         generic_update(items, 'set_top_of_queue'); }
167     $scope.clear_top_of_queue = function(items) {
168         generic_update(items, 'clear_top_of_queue'); }
169     $scope.transfer_to_marked_title = function(items) {
170         generic_update(items, 'transfer_to_marked_title'); }
171
172     $scope.mark_damaged = function(items) {
173         var copy_ids = items
174             .filter(function(item) { return Boolean(item.copy) })
175             .map(function(item) { return item.copy.id() });
176         if (copy_ids.length) 
177             egCirc.mark_damaged(copy_ids).then(refresh_page);
178     }
179
180     $scope.mark_missing = function(items) {
181         var copy_ids = items
182             .filter(function(item) { return Boolean(item.copy) })
183             .map(function(item) { return item.copy.id() });
184         if (copy_ids.length) 
185             egCirc.mark_missing(copy_ids).then(refresh_page);
186     }
187
188     $scope.retarget = function(items) {
189         var hold_ids = items.map(function(item) { return item.hold.id() });
190         egHolds.retarget(hold_ids).then(refresh_page);
191     }
192
193     $scope.clear_holds = function() {
194         clearing = true;
195         $scope.clear_progress = { max : 0, value : 0 };
196
197         // we want to see all processed holds, so (effectively) remove
198         // the grid limit.
199         $scope.gridControls.setLimit(1000); 
200
201         // initiate clear shelf and grab cache key
202         egCore.net.request(
203             'open-ils.circ',
204             'open-ils.circ.hold.clear_shelf.process',
205             egCore.auth.token(), $scope.pickup_ou.id()
206
207         // request responses from the clear shelf cache
208         ).then(function(resp) {
209             console.debug('clear holds cache key is ' + resp.cache_key);
210             return egCore.net.request(
211                 'open-ils.circ',
212                 'open-ils.circ.hold.clear_shelf.get_cache',
213                 egCore.auth.token(), resp.cache_key
214             )
215
216         // with each clear-shelf response, update the progress meter,
217         // hide it when done.
218         }).then(
219             function() { 
220                 clearing = false;
221             },
222             null,
223             function(resp) {
224                 console.debug('clear shelf said: ' + js2JSON(resp));
225                 if (!angular.isArray(resp)) resp = [resp];
226                 angular.forEach(resp, function(info) {
227                     if (info.maximum) 
228                         $scope.clear_progress.max = info.maximum;
229                     if (info.progress)
230                         $scope.clear_progress.value = info.progress;
231
232                     if (info.action) {
233                         var grid_item = holds.filter(function(item) {
234                             return item.hold.id() == info.hold_details.id
235                         })[0];
236
237                         // there will be no grid item if the hold is off-page
238                         if (grid_item) {
239                             grid_item.post_clear = 
240                                 egCore.strings['CLEAR_SHELF_ACTION_' + info.action];
241                         }
242                     }
243                 });
244             }
245         );
246     }
247
248
249     refresh_page();
250
251 }]);
252