]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/circ/patron/holds.js
LP2061136 - Stamping 1405 DB upgrade script
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / circ / patron / holds.js
1 /**
2  * List of patron holds
3  */
4
5 angular.module('egPatronApp').controller('PatronHoldsCtrl',
6
7        ['$scope','$q','$routeParams','egCore','egUser','patronSvc',
8         'egGridDataProvider','egHolds','$window','$location','egCirc','egHoldGridActions',
9 function($scope,  $q,  $routeParams,  egCore,  egUser,  patronSvc,  
10         egGridDataProvider , egHolds , $window , $location , egCirc, egHoldGridActions) {
11
12     $scope.initTab('holds', $routeParams.id);
13     $scope.holds_display = 'main';
14     $scope.detail_hold_id = $routeParams.hold_id;
15     $scope.gridControls = {};
16     $scope.grid_actions = egHoldGridActions;
17
18     function refresh_all() {
19         patronSvc.refreshPrimary();
20         patronSvc.holds = [];
21         patronSvc.hold_ids = [];
22         provider.refresh() 
23     }
24     $scope.grid_actions.refresh = refresh_all;
25
26     $scope.show_main_list = function() {
27         // don't need a full reset_page() to swap tabs
28         $scope.holds_display = 'main';
29         patronSvc.holds = [];
30         patronSvc.hold_ids = [];
31         provider.refresh();
32     }
33
34     $scope.show_alt_list = function() {
35         // don't need a full reset_page() to swap tabs
36         $scope.holds_display = 'alt';
37         patronSvc.holds = [];
38         patronSvc.hold_ids = [];
39         provider.refresh();
40     }
41
42     $scope.hide_cancel_hold = function(action) { 
43         return $scope.holds_display == 'alt';
44     }
45
46     $scope.hide_uncancel_hold = function(action) {
47         return !$scope.hide_cancel_hold();
48     }
49
50     var provider = egGridDataProvider.instance({});
51     $scope.gridDataProvider = provider;
52
53     function fetchHolds(offset, count) {
54         // TODO: LP#1697954 Fetch all holds on grid render to support
55         // client-side sorting.  Migrate to server-side sorting to avoid
56         // the need for fetching all items.
57
58         // we're going to just fetch all the holds up front
59         //var ids = patronSvc.hold_ids.slice(offset, offset + count); 
60         return egHolds.fetch_holds(patronSvc.hold_ids).then(null, null,
61             function(hold_data) { 
62                 console.log('fetchHolds, hold_data',hold_data);
63                 egCirc.flesh_copy_circ_library(hold_data.copy);
64                 patronSvc.holds.push(hold_data);
65                 return hold_data;
66             }
67         );
68     }
69
70     /*provider.get = function(offset, count) {
71
72         // see if we have the requested range cached
73         if (patronSvc.holds[offset]) {
74             return provider.arrayNotifier(patronSvc.holds, offset, count);
75         }
76
77         // see if we have the holds IDs for this range already loaded
78         if (patronSvc.hold_ids[offset]) {
79             return fetchHolds(offset, count);
80         }
81
82         var deferred = $q.defer();
83         patronSvc.hold_ids = [];
84
85         var method = 'open-ils.circ.holds.id_list.retrieve.authoritative';
86         if ($scope.holds_display == 'alt')
87             method = 'open-ils.circ.holds.canceled.id_list.retrieve.authoritative';
88
89         var current = 0;
90         egCore.net.request(
91             'open-ils.circ', method,
92             egCore.auth.token(), $scope.patron_id
93
94         ).then(function(hold_ids) {
95             
96             if (!hold_ids.length || hold_ids.length < offset + 1)
97             {
98                 deferred.resolve();
99                 return;
100             }
101
102             $scope.gridDataProvider.grid.totalCount = hold_ids.length;
103
104             patronSvc.hold_ids = hold_ids;
105             fetchHolds(offset, count)
106             .then(deferred.resolve, null, function (data) {
107                 if (data) {
108                     if (current >= offset && current < count) {
109                         deferred.notify(data);
110                     }
111                     current++;
112                 }
113             });
114         });
115
116         return deferred.promise;
117     }*/
118     provider.get = function(offset, count) {
119         console.log('get, this', this);
120         console.log('$scope', $scope);
121
122         // see if we have the requested range cached
123         if (patronSvc.holds[offset]) {
124             return provider.arrayNotifier(patronSvc.holds, offset, count);
125         }
126
127         hold_count = 0;
128         patronSvc.holds = [];
129         var restrictions = {
130                 cancel_time      : null,
131                 fulfillment_time  : null,
132                 'h.usr': $scope.patron_id
133         };
134         if ($scope.holds_display == 'alt') {
135             restrictions['cancel_time'] = { not : null };
136         }
137         console.log('restrictions',restrictions);
138
139         var order_by = [{ shelf_expire_time : null }];
140
141         // NOTE: Server sorting is currently disabled entirely by the 
142         // first clause in this 'if'.   This is perfectly fine because
143         // clientsort always runs inside the arrayNotifier implementation
144         // in the egGrid code.   However, in order to retain the memory
145         // of sorting constraints placed on us by the current server-side
146         // code, an initial "cannot sort these" array and test is added
147         // here.  An alternate implementation might be to map fields to
148         // query positions, thus allowing positional ORDER BY clauses.
149         // With as many fields as the wide hold object has, this is
150         // non-trivial at the moment.
151         if (false && provider.sort && provider.sort.length) {
152             // A list of fields we can't sort on the server side.  That's ok, because
153             // the grid is marked clientsort, so it always re-sorts in the browser.
154             var cannot_sort = [
155                 'relative_queue_position',
156                 'default_estimated_wait',
157                 'min_estimated_wait',
158                 'potentials',
159                 'other_holds',
160                 'total_wait_time',
161                 'notification_count',
162                 'last_notification_time',
163                 'is_staff_hold',
164                 'copy_location_order_position',
165                 'hold_status',
166                 'clear_me',
167                 'usr_alias_or_display_name',
168                 'usr_display_name',
169                 'usr_alias_or_first_given_name'
170             ];
171
172             order_by = [];
173             angular.forEach(provider.sort, function (c) {
174                 if (!angular.isObject(c)) {
175                     if (c.match(/^hold\./)) {
176                         var i = c.replace('hold.','');
177                         if (cannot_sort.includes(i)) return;
178                         var ob = {};
179                         ob[i] = null;
180                         order_by.push(ob);
181                     }
182                 } else {
183                     var i = Object.keys(c)[0];
184                     var direction = c[i];
185                     if (i.match(/^hold\./)) {
186                         i = i.replace('hold.','');
187                         if (cannot_sort.includes(i)) return;
188                         var ob = {}
189                         ob[i] = {dir:direction};
190                         order_by.push(ob);
191                     }
192                 }
193             });
194         }
195
196         // egProgressDialog.open({max : 1, value : 0});
197         var first = true;
198         return egHolds.fetch_wide_holds(
199             restrictions,
200             order_by
201         ).then(function () {
202                 return provider.arrayNotifier(patronSvc.holds, offset, count);
203             },
204             null,
205             function(hold_data) { 
206                 if (first) {
207                     hold_count = hold_data;
208                     first = false;
209                     // egProgressDialog.update({max:hold_count});
210                 } else {
211                     // egProgressDialog.increment();
212                     var new_item = { id : hold_data.id, hold : hold_data };
213                     new_item.status_string =
214                         egCore.strings['HOLD_STATUS_' + hold_data.hold_status]
215                         || hold_data.hold_status;
216
217                     patronSvc.holds.push(new_item);
218                 }
219             }
220         )/*.finally(egProgressDialog.close)*/;
221     }
222
223     $scope.print = function() {
224         var holds = [];
225         angular.forEach(patronSvc.holds, function(item) {
226             holds.push({
227                 hold : egCore.idl.toHash(item.hold),
228                 copy : egCore.idl.toHash(item.copy),
229                 volume : egCore.idl.toHash(item.volume),
230                 title : item.mvr.title(),
231                 author : item.mvr.author()
232             });
233         });
234
235         egCore.print.print({
236             context : 'receipt', 
237             template : 'holds_for_patron', 
238             scope : {patron : egCore.idl.toHash(patronSvc.current), holds : holds}
239         });
240     }
241
242     $scope.detail_view = function(action, user_data, items) {
243         if (h = items[0]) {
244             $location.path('/circ/patron/' + 
245                 $scope.patron_id + '/holds/' + h.id);
246         }
247     }
248
249     $scope.list_view = function(items) {
250         $location.path('/circ/patron/' + $scope.patron_id + '/holds');
251     }
252
253     $scope.place_hold = function() {
254
255         egCore.hatch.setLoginSessionItem(
256             'eg.circ.patron_hold_target', patronSvc.current.card().barcode());
257
258         $window.location.href = '/eg2/staff/catalog';
259     }
260
261     // when the detail hold is fetched (and updated), update the bib
262     // record summary display record id.
263     $scope.set_hold = function(hold_data) {
264         $scope.detail_hold_record_id = hold_data.bre_id;
265     }
266
267 }])
268
269
270 .controller('PatronHoldsCreateCtrl',
271        ['$scope','$routeParams','$location','egCore','egWorkLog','patronSvc','$cookies',
272 function($scope , $routeParams , $location , egCore , egWorkLog , patronSvc , $cookies) {
273
274     // set preferred and search library cookies
275     egCore.hatch.getItem('eg.search.pref_lib').then(function(lib) {
276         $cookies.put('eg_pref_lib', lib, {path: '/'});
277     });
278     egCore.hatch.getItem('eg.search.search_lib').then(function(lib) {
279         $cookies.put('eg_search_lib', lib, {path: '/'});
280     });
281
282     $scope.handlers = {
283         opac_hold_placed : function(hold) {
284             patronSvc.fetchUserStats(); // update hold counts
285             egWorkLog.record(
286                 egCore.strings.EG_WORK_LOG_REQUESTED_HOLD,{
287                     'action' : 'requested_hold',
288                     'patron_id' : patronSvc.current.id(),
289                     'hold_id' : hold
290                 }
291             );
292         }
293     }
294
295     $scope.initTab('holds', $routeParams.id).then(function(isAlert) {
296         if (isAlert) return;
297         // not guarenteed to have a barcode until init fetches the user
298         $scope.handlers.patron_barcode = patronSvc.current.card().barcode();
299     });
300
301     $scope.catalog_url = 
302         $location.absUrl().replace(/\/staff\/.*/, '/opac/advanced');
303
304     $scope.handle_page = function(url) {
305     }
306
307 }])
308