]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/staff/circ/renew/app.js
LP2045292 Color contrast for AngularJS patron bills
[working/Evergreen.git] / Open-ILS / web / js / ui / default / staff / circ / renew / app.js
1 /**
2  * Renewal
3  */
4
5 angular.module('egRenewApp', 
6     ['ngRoute', 'ui.bootstrap', 'egCoreMod', 'egUiMod', 'egGridMod'])
7
8 .config(function($routeProvider, $locationProvider, $compileProvider) {
9     $locationProvider.html5Mode(true);
10     $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|mailto|blob):/); // grid export    
11         
12         var resolver = {delay : function(egStartup) {return egStartup.go()}};
13
14     $routeProvider.when('/circ/renew/renew', {
15         templateUrl: './circ/renew/t_renew',
16         controller: 'RenewCtrl',
17         resolve : resolver
18     });
19
20     $routeProvider.when('/circ/renew/renew', {
21         templateUrl: './circ/renew/t_renew',
22         controller: 'RenewCtrl',
23         resolve : resolver
24     });
25     
26     $routeProvider.otherwise({redirectTo : '/circ/renew/renew'});
27 })
28
29
30
31
32 .controller('RenewCtrl',
33        ['$scope','$window','$location','egCore','egGridDataProvider','egCirc',
34 function($scope , $window , $location , egCore , egGridDataProvider , egCirc) {
35     var now = new Date();
36
37     egCore.hatch.getItem('circ.renew.strict_barcode')
38         .then(function(sb){ $scope.strict_barcode = sb });
39     $scope.focusBarcode = true;
40     $scope.outOfRange = false;
41     $scope.minDate = new Date(now);
42     $scope.renewals = [];
43
44     $scope.renewalArgs = {due_date : new Date(now)};
45
46     $scope.sort_money = function (a,b) {
47         var ma = parseFloat(a);
48         var mb = parseFloat(b);
49         if (ma < mb) return -1;
50         if (ma > mb) return 1;
51         return 0
52     }
53
54     $scope.gridDataProvider = egGridDataProvider.instance({
55         get : function(offset, count) {
56             return this.arrayNotifier($scope.renewals, offset, count);
57         }
58     });
59
60     // avoid multiple, in-flight attempts on the same barcode
61     var pending_barcodes = {};
62
63     $scope.renew = function(args) {
64         var params = angular.copy(args);
65
66         if (args.sticky_date) {
67             params.due_date = args.due_date.toISOString();
68         } else {
69             delete params.due_date;
70         }
71         delete params.sticky_date;
72          if (!args.copy_barcode) return;
73
74         args.copy_barcode = ''; // reset UI input
75
76         if (pending_barcodes[params.copy_barcode]) {
77             console.log(
78                 "Skipping renewals of redundant barcode " 
79                 + params.copy_barcode
80             );
81             return;
82         }
83
84         pending_barcodes[params.copy_barcode] = true;
85         send_renewal(params);
86
87         $scope.focusBarcode = true; // return focus to barcode input
88     }
89
90     function send_renewal(params) {
91
92         params.noncat_type = params.noncat ? params.noncat_type : '';
93
94         // populate the grid row before we send the request so that the
95         // order of actions is maintained and so the user gets an 
96         // immediate reaction to their barcode input action.
97         var row_item = {
98             index : $scope.renewals.length,
99             input_barcode : params.copy_barcode,
100             noncat_type : params.noncat_type
101         };
102
103         $scope.renewals.unshift(row_item);
104         $scope.gridDataProvider.refresh();
105
106         var options = {check_barcode : $scope.strict_barcode};
107
108         egCirc.renew(params, options).then(
109             function(final_resp) {
110
111                 row_item.evt = final_resp.evt;
112                 angular.forEach(final_resp.data, function(val, key) {
113                     row_item[key] = val;
114                 });
115
116                 row_item['copy_barcode'] = row_item.acp.barcode();
117
118                 if (row_item.mbts) {
119                     var amt = Number(row_item.mbts.balance_owed());
120                     if (amt != 0) {
121                         $scope.billable_barcode = row_item.copy_barcode;
122                         $scope.billable_amount = amt;
123                         $scope.fine_total = 
124                             ($scope.fine_total * 100 + amt * 100) / 100;
125                     }
126                 }
127
128                 if ($scope.trim_list && checkinSvc.checkins.length > 20)
129                     checkinSvc.checkins = checkinSvc.checkins.splice(0, 20);
130
131             },
132             function() {
133                 // Circ was rejected somewhere along the way.
134                 // Remove the copy from the grid since there was no action.
135                 // note: since renewals are unshifted onto the array, the
136                 // index value does not (generally) match the array position.
137                 var pos = -1;
138                 angular.forEach($scope.renewals, function(co, idx) {
139                     if (co.index == row_item.index) pos = idx;
140                 });
141                 $scope.renewals.splice(pos, 1);
142                 $scope.gridDataProvider.refresh();
143             }
144
145         )['finally'](function() {
146
147             // regardless of the outcome of the circ, remove the 
148             // barcode from the pending list.
149             if (params.copy_barcode)
150                 delete pending_barcodes[params.copy_barcode];
151         });
152     }
153
154     $scope.fetchLastCircPatron = function(items) {
155         var renewal = items[0];
156         if (!renewal || !renewal.acp) return;
157
158         egCirc.last_copy_circ(renewal.acp.id())
159         .then(function(circ) {
160
161             if (circ) {
162                 // jump to the patron UI (separate app)
163                 $window.location.href = $location
164                     .path('/circ/patron/' + circ.usr() + '/checkout')
165                     .absUrl();
166                 return;
167             }
168
169             $scope.alert = {item_never_circed : renewal.acp.barcode()};
170         });
171     }
172
173     $scope.showMarkDamaged = function(items) {
174         var copy_ids = [];
175         angular.forEach(items, function(item) {
176             if (item.acp) copy_ids.push(item.acp.id());
177         });
178
179         if (copy_ids.length) {
180             egCirc.mark_damaged(copy_ids).then(function() {
181                 // update grid items?
182             });
183         }
184     }
185
186     $scope.showMarkDiscard = function(items) {
187         var copies = [];
188         angular.forEach(items, function(item) {
189             if (item.acp) copies.push(egCore.idl.toHash(item.acp));
190         });
191
192         if (copies.length) {
193             egCirc.mark_discard(copies).then(function() {
194                 // update grid items?
195             });
196         }
197     }
198
199     $scope.showLastFewCircs = function(items) {
200         if (items.length && (copy = items[0].acp)) {
201             var url = $location.path(
202                 '/cat/item/' + copy.id() + '/circ_list').absUrl();
203             $window.open(url, '_blank').focus();
204         }
205     }
206
207     $scope.abortTransit = function(items) {
208         var transit_ids = [];
209         angular.forEach(items, function(item) {
210             if (item.transit) transit_ids.push(item.transit.id());
211         });
212
213         egCirc.abort_transits(transit_ids).then(function() {
214             // update grid items?
215         });
216     }
217
218     $scope.addCopyAlerts = function(items) {
219         var copy_ids = [];
220         angular.forEach(items, function(item) {
221             if (item.acp) copy_ids.push(item.acp.id());
222         });
223         egCirc.add_copy_alerts(copy_ids).then(function() {
224             // update grid items?
225         });
226     }
227
228     $scope.manageCopyAlerts = function(items) {
229         var copy_ids = [];
230         angular.forEach(items, function(item) {
231             if (item.acp) copy_ids.push(item.acp.id());
232         });
233         egCirc.manage_copy_alerts(copy_ids).then(function() {
234             // update grid items?
235         });
236     }
237
238     $scope.onStrictBarcodeChange = function() {
239         egCore.hatch.setItem(
240             'circ.renew.strict_barcode',
241             $scope.strict_barcode
242         );
243     };
244
245     $scope.print_receipt = function() {
246         var print_data = {circulations : []}
247
248         if ($scope.renewals.length == 0) return $q.when();
249
250         angular.forEach($scope.renewals, function(renewal) {
251             if (renewal.circ) {
252                 print_data.circulations.push({
253                     circ : egCore.idl.toHash(renewal.circ),
254                     copy : egCore.idl.toHash(renewal.acp),
255                     title : egCore.idl.toHash(renewal.title),
256                     author : egCore.idl.toHash(renewal.author)
257                 });
258                 // Flesh selected fields of this circulation 
259                 print_data.circulations[0].copy.call_number =
260                     egCore.idl.toHash(renewal.acn);
261                 print_data.circulations[0].copy.owning_lib =
262                     egCore.idl.toHash(renewal.aou);
263             }
264         });
265
266         return egCore.print.print({
267             context : 'default', 
268             template : 'renew', 
269             scope : print_data,
270         });
271     }
272 }])
273