]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/circ/util.js
replace parseInt with Number to prevent octal interpretation
[Evergreen.git] / Open-ILS / xul / staff_client / server / circ / util.js
1 dump('entering circ/util.js\n');
2
3 if (typeof circ == 'undefined') var circ = {};
4 circ.util = {};
5
6 circ.util.EXPORT_OK     = [ 
7         'offline_checkout_columns', 'offline_checkin_columns', 'offline_renew_columns', 'offline_inhouse_use_columns', 
8         'columns', 'hold_columns', 'checkin_via_barcode', 'std_map_row_to_column', 'hold_capture_via_copy_barcode',
9         'show_last_few_circs', 'abort_transits'
10 ];
11 circ.util.EXPORT_TAGS   = { ':all' : circ.util.EXPORT_OK };
12
13 circ.util.abort_transits = function(selection_list) {
14         var obj = {};
15         JSAN.use('util.error'); obj.error = new util.error();
16         JSAN.use('util.network'); obj.network = new util.network();
17         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
18         JSAN.use('util.functional');
19         var msg = 'Are you sure you would like to abort transits for copies:' + util.functional.map_list( selection_list, function(o){return o.copy_id;}).join(', ') + '?';
20         var r = obj.error.yns_alert(msg,'Aborting Transits','Yes','No',null,'Check here to confirm this action');
21         if (r == 0) {
22                 try {
23                         for (var i = 0; i < selection_list.length; i++) {
24                                 var copy_id = selection_list[i].copy_id;
25                                 var robj = obj.network.simple_request('FM_ATC_VOID',[ ses(), { 'copyid' : copy_id } ]);
26                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
27                         }
28                 } catch(E) {
29                         obj.error.standard_unexpected_error_alert('Transit not likely aborted.',E);
30                 }
31         }
32 }
33
34 circ.util.show_last_few_circs = function(selection_list,count) {
35         var obj = {};
36         JSAN.use('util.error'); obj.error = new util.error();
37         JSAN.use('util.window'); obj.win = new util.window();
38         JSAN.use('util.network'); obj.network = new util.network();
39         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
40
41         if (!count) count = 4;
42
43         for (var i = 0; i < selection_list.length; i++) {
44                 try {
45                         obj.data.fancy_prompt_data = null; obj.data.stash('fancy_prompt_data');
46                         var url = xulG.url_prefix( urls.XUL_CIRC_SUMMARY ) + '?copy_id=' + selection_list[i].copy_id + '&count=' + count;
47                         obj.win.open( url, 'show_last_few_circs', 'chrome,resizable,modal' );
48                         obj.data.stash_retrieve();
49
50                         if (! obj.data.fancy_prompt_data) continue;
51                         var patrons = JSON2js( obj.data.fancy_prompt_data );
52                         for (var j = 0; j < patrons.length; j++) {
53                                 if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
54                                         try {
55                                                 var url = urls.XUL_PATRON_DISPLAY + '?id=' + window.escape( patrons[j] );
56                                                 window.xulG.new_tab( url );
57                                         } catch(E) {
58                                                 obj.error.standard_unexpected_error_alert('Problem retrieving patron.',E);
59                                         }
60                                 }
61                         }
62
63                 } catch(E) {
64                         obj.error.standard_unexpected_error_alert('Problem retrieving circulations.',E);
65                 }
66         }
67 }
68
69 circ.util.offline_checkout_columns = function(modify,params) {
70         
71         var c = [
72                 { 
73                         'id' : 'timestamp', 
74                         'label' : 'Timestamp', 
75                         'flex' : 1, 'primary' : false, 'hidden' : true, 
76                         'render' : 'my.timestamp' 
77                 },
78                 { 
79                         'id' : 'checkout_time', 
80                         'label' : 'Check Out Time', 
81                         'flex' : 1, 'primary' : false, 'hidden' : true, 
82                         'render' : 'my.checkout_time' 
83                 },
84                 { 
85                         'id' : 'type', 
86                         'label' : 'Transaction Type', 
87                         'flex' : 1, 'primary' : false, 'hidden' : true, 
88                         'render' : 'my.type' 
89                 },
90                 {
91                         'id' : 'noncat',
92                         'label' : 'Non-Cataloged?',
93                         'flex' : 1, 'primary' : false, 'hidden' : true, 
94                         'render' : 'my.noncat'
95                 },
96                 {
97                         'id' : 'noncat_type',
98                         'label' : 'Non-Cat Type ID',
99                         'flex' : 1, 'primary' : false, 'hidden' : true,
100                         'render' : 'my.noncat_type'
101                 },
102                 {
103                         'id' : 'noncat_count',
104                         'label' : 'Count',
105                         'flex' : 1, 'primary' : false, 'hidden' : false,
106                         'render' : 'my.noncat_count'
107                 },
108                 { 
109                         'id' : 'patron_barcode', 
110                         'label' : 'Patron Barcode', 
111                         'flex' : 1, 'primary' : false, 'hidden' : true, 
112                         'render' : 'my.patron_barcode' 
113                 },
114                 { 
115                         'id' : 'barcode', 
116                         'label' : 'Item Barcode', 
117                         'flex' : 2, 'primary' : true, 'hidden' : false, 
118                         'render' : 'my.barcode' 
119                 },
120                 { 
121                         'id' : 'due_date', 
122                         'label' : 'Due Date', 
123                         'flex' : 1, 'primary' : false, 'hidden' : false, 
124                         'render' : 'my.due_date' 
125                 },
126         ];
127         if (modify) for (var i = 0; i < c.length; i++) {
128                 if (modify[ c[i].id ]) {
129                         for (var j in modify[ c[i].id ]) {
130                                 c[i][j] = modify[ c[i].id ][j];
131                         }
132                 }
133         }
134         if (params) {
135                 if (params.just_these) {
136                         JSAN.use('util.functional');
137                         var new_c = [];
138                         for (var i = 0; i < params.just_these.length; i++) {
139                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
140                                 new_c.push( function(y){ return y; }( x ) );
141                         }
142                         return new_c;
143                 }
144         }
145         return c;
146 }
147
148 circ.util.offline_checkin_columns = function(modify,params) {
149         
150         var c = [
151                 { 
152                         'id' : 'timestamp', 
153                         'label' : 'Timestamp', 
154                         'flex' : 1, 'primary' : false, 'hidden' : true, 
155                         'render' : 'my.timestamp' 
156                 },
157                 { 
158                         'id' : 'backdate', 
159                         'label' : 'Back Date', 
160                         'flex' : 1, 'primary' : false, 'hidden' : true, 
161                         'render' : 'my.backdate' 
162                 },
163                 { 
164                         'id' : 'type', 
165                         'label' : 'Transaction Type', 
166                         'flex' : 1, 'primary' : false, 'hidden' : true, 
167                         'render' : 'my.type' 
168                 },
169                 { 
170                         'id' : 'barcode', 
171                         'label' : 'Item Barcode', 
172                         'flex' : 2, 'primary' : true, 'hidden' : false, 
173                         'render' : 'my.barcode' 
174                 },
175         ];
176         if (modify) for (var i = 0; i < c.length; i++) {
177                 if (modify[ c[i].id ]) {
178                         for (var j in modify[ c[i].id ]) {
179                                 c[i][j] = modify[ c[i].id ][j];
180                         }
181                 }
182         }
183         if (params) {
184                 if (params.just_these) {
185                         JSAN.use('util.functional');
186                         var new_c = [];
187                         for (var i = 0; i < params.just_these.length; i++) {
188                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
189                                 new_c.push( function(y){ return y; }( x ) );
190                         }
191                         return new_c;
192                 }
193         }
194         return c;
195 }
196
197 circ.util.offline_renew_columns = function(modify,params) {
198         
199         var c = [
200                 { 
201                         'id' : 'timestamp', 
202                         'label' : 'Timestamp', 
203                         'flex' : 1, 'primary' : false, 'hidden' : true, 
204                         'render' : 'my.timestamp' 
205                 },
206                 { 
207                         'id' : 'checkout_time', 
208                         'label' : 'Check Out Time', 
209                         'flex' : 1, 'primary' : false, 'hidden' : true, 
210                         'render' : 'my.checkout_time' 
211                 },
212                 { 
213                         'id' : 'type', 
214                         'label' : 'Transaction Type', 
215                         'flex' : 1, 'primary' : false, 'hidden' : true, 
216                         'render' : 'my.type' 
217                 },
218                 { 
219                         'id' : 'patron_barcode', 
220                         'label' : 'Patron Barcode', 
221                         'flex' : 1, 'primary' : false, 'hidden' : true, 
222                         'render' : 'my.patron_barcode' 
223                 },
224                 { 
225                         'id' : 'barcode', 
226                         'label' : 'Item Barcode', 
227                         'flex' : 2, 'primary' : true, 'hidden' : false, 
228                         'render' : 'my.barcode' 
229                 },
230                 { 
231                         'id' : 'due_date', 
232                         'label' : 'Due Date', 
233                         'flex' : 1, 'primary' : false, 'hidden' : false, 
234                         'render' : 'my.due_date' 
235                 },
236         ];
237         if (modify) for (var i = 0; i < c.length; i++) {
238                 if (modify[ c[i].id ]) {
239                         for (var j in modify[ c[i].id ]) {
240                                 c[i][j] = modify[ c[i].id ][j];
241                         }
242                 }
243         }
244         if (params) {
245                 if (params.just_these) {
246                         JSAN.use('util.functional');
247                         var new_c = [];
248                         for (var i = 0; i < params.just_these.length; i++) {
249                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
250                                 new_c.push( function(y){ return y; }( x ) );
251                         }
252                         return new_c;
253                 }
254         }
255         return c;
256 }
257
258 circ.util.offline_inhouse_use_columns = function(modify,params) {
259         
260         var c = [
261                 { 
262                         'id' : 'timestamp', 
263                         'label' : 'Timestamp', 
264                         'flex' : 1, 'primary' : false, 'hidden' : true, 
265                         'render' : 'my.timestamp' 
266                 },
267                 { 
268                         'id' : 'use_time', 
269                         'label' : 'Use Time', 
270                         'flex' : 1, 'primary' : false, 'hidden' : true, 
271                         'render' : 'my.use_time' 
272                 },
273                 { 
274                         'id' : 'type', 
275                         'label' : 'Transaction Type', 
276                         'flex' : 1, 'primary' : false, 'hidden' : true, 
277                         'render' : 'my.type' 
278                 },
279                 {
280                         'id' : 'count',
281                         'label' : 'Count',
282                         'flex' : 1, 'primary' : false, 'hidden' : false,
283                         'render' : 'my.count'
284                 },
285                 { 
286                         'id' : 'barcode', 
287                         'label' : 'Item Barcode', 
288                         'flex' : 2, 'primary' : true, 'hidden' : false, 
289                         'render' : 'my.barcode' 
290                 },
291         ];
292         if (modify) for (var i = 0; i < c.length; i++) {
293                 if (modify[ c[i].id ]) {
294                         for (var j in modify[ c[i].id ]) {
295                                 c[i][j] = modify[ c[i].id ][j];
296                         }
297                 }
298         }
299         if (params) {
300                 if (params.just_these) {
301                         JSAN.use('util.functional');
302                         var new_c = [];
303                         for (var i = 0; i < params.just_these.length; i++) {
304                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
305                                 new_c.push( function(y){ return y; }( x ) );
306                         }
307                         return new_c;
308                 }
309         }
310         return c;
311 }
312
313
314
315 circ.util.columns = function(modify,params) {
316         
317         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
318
319         function getString(s) { return data.entities[s]; }
320
321         var c = [
322                 {
323                         'id' : 'acp_id', 'label' : getString('staff.acp_label_id'), 'flex' : 1,
324                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.id()', 'persist' : 'hidden width',
325                 },
326                 {
327                         'id' : 'circ_id', 'label' : getString('staff.circ_label_id'), 'flex' : 1,
328                         'primary' : false, 'hidden' : true, 'render' : 'my.circ.id()', 'persist' : 'hidden width',
329                 },
330                 {
331                         'id' : 'mvr_doc_id', 'label' : getString('staff.mvr_label_doc_id'), 'flex' : 1,
332                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.doc_id()', 'persist' : 'hidden width',
333                 },
334                 {
335                         'id' : 'barcode', 'label' : getString('staff.acp_label_barcode'), 'flex' : 1,
336                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.barcode()', 'persist' : 'hidden width',
337                 },
338                 {
339                         'id' : 'call_number', 'label' : getString('staff.acp_label_call_number'), 'flex' : 1,
340                         'primary' : false, 'hidden' : true, 'render' : ' if (my.acp && my.acp.call_number() == -1) { "Not Cataloged"; } else { if (!my.acn) { var x = obj.network.simple_request("FM_ACN_RETRIEVE",[ my.acp.call_number() ]); if (x.ilsevent) { "Not Cataloged"; } else { my.acn = x; x.label(); } } else { my.acn.label(); } } ' , 'persist' : 'hidden width',
341                 },
342                 {
343                         'id' : 'owning_lib', 'label' : 'Owning Lib', 'flex' : 1,
344                         'primary' : false, 'hidden' : true,
345                         'render' : 'if (Number(my.acn.owning_lib())>=0) obj.data.hash.aou[ my.acn.owning_lib() ].shortname(); else my.acn.owning_lib().shortname();', 'persist' : 'hidden width',
346                 },
347                 {
348                         'id' : 'copy_number', 'label' : getString('staff.acp_label_copy_number'), 'flex' : 1,
349                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.copy_number()', 'persist' : 'hidden width',
350                 },
351                 {
352                         'id' : 'location', 'label' : getString('staff.acp_label_location'), 'flex' : 1,
353                         'primary' : false, 'hidden' : true, 'render' : 'if (Number(my.acp.location())>=0) obj.data.lookup("acpl", my.acp.location() ).name(); else my.acp.location().name();', 'persist' : 'hidden width',
354                 },
355                 {
356                         'id' : 'loan_duration', 'label' : getString('staff.acp_label_loan_duration'), 'flex' : 1,
357                         'primary' : false, 'hidden' : true, 
358                         'render' : 'switch(my.acp.loan_duration()){ case 1: "Short"; break; case 2: "Normal"; break; case 3: "Long"; break; }', 'persist' : 'hidden width',
359                 },
360                 {
361                         'id' : 'circ_lib', 'label' : getString('staff.acp_label_circ_lib'), 'flex' : 1,
362                         'primary' : false, 'hidden' : true, 'render' : 'if (Number(my.acp.circ_lib())>=0) obj.data.hash.aou[ my.acp.circ_lib() ].shortname(); else my.acp.circ_lib().shortname();', 'persist' : 'hidden width',
363                 },
364                 {
365                         'id' : 'fine_level', 'label' : getString('staff.acp_label_fine_level'), 'flex' : 1,
366                         'primary' : false, 'hidden' : true,
367                         'render' : 'switch(my.acp.fine_level()){ case 1: "Low"; break; case 2: "Normal"; break; case 3: "High"; break; }', 'persist' : 'hidden width',
368                 },
369                 {
370                         'id' : 'circulate', 'label' : 'Circulate?', 'flex' : 1,
371                         'primary' : false, 'hidden' : true, 'render' : 'get_bool( my.acp.circulate() ) ? "Yes" : "No"', 'persist' : 'hidden width',
372                 },
373                 {
374                         'id' : 'holdable', 'label' : 'Holdable?', 'flex' : 1,
375                         'primary' : false, 'hidden' : true, 'render' : 'get_bool( my.acp.holdable() ) ? "Yes" : "No"', 'persist' : 'hidden width',
376                 },
377                 {
378                         'id' : 'opac_visible', 'label' : 'OPAC Visible?', 'flex' : 1,
379                         'primary' : false, 'hidden' : true, 'render' : 'get_bool( my.acp.opac_visible() ) ? "Yes" : "No"', 'persist' : 'hidden width',
380                 },
381                 {
382                         'persist' : 'hidden width', 'id' : 'ref', 'label' : 'Reference?', 'flex' : 1,
383                         'primary' : false, 'hidden' : true, 'render' : 'get_bool( my.acp.ref() ) ? "Yes" : "No"'
384                 },
385                 {
386                         'persist' : 'hidden width', 'id' : 'deposit', 'label' : 'Deposit?', 'flex' : 1,
387                         'primary' : false, 'hidden' : true, 'render' : 'get_bool( my.acp.deposit() ) ? "Yes" : "No"'
388                 },
389                 {
390                         'persist' : 'hidden width', 'id' : 'deposit_amount', 'label' : getString('staff.acp_label_deposit_amount'), 'flex' : 1,
391                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.deposit_amount()'
392                 },
393                 {
394                         'persist' : 'hidden width', 'id' : 'price', 'label' : getString('staff.acp_label_price'), 'flex' : 1,
395                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.price()'
396                 },
397                 {
398                         'persist' : 'hidden width', 'id' : 'circ_as_type', 'label' : getString('staff.acp_label_circ_as_type'), 'flex' : 1,
399                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.circ_as_type()'
400                 },
401                 {
402                         'persist' : 'hidden width', 'id' : 'circ_modifier', 'label' : getString('staff.acp_label_circ_modifier'), 'flex' : 1,
403                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.circ_modifier()'
404                 },
405                 {
406                         'persist' : 'hidden width', 'id' : 'xact_start', 'label' : getString('staff.circ_label_xact_start'), 'flex' : 1,
407                         'primary' : false, 'hidden' : true, 'render' : 'my.circ.xact_start()'
408                 },
409                 {
410                         'persist' : 'hidden width', 'id' : 'checkin_time', 'label' : 'Checkin Time', 'flex' : 1,
411                         'primary' : false, 'hidden' : true, 'render' : 'my.circ.checkin_time().substr(0,16)'
412                 },
413                 {
414                         'persist' : 'hidden width', 'id' : 'xact_finish', 'label' : 'Transaction Finished', 'flex' : 1,
415                         'primary' : false, 'hidden' : true, 'render' : 'my.circ.xact_finish()'
416                 },
417                 {
418                         'persist' : 'hidden width', 'id' : 'due_date', 'label' : getString('staff.circ_label_due_date'), 'flex' : 1,
419                         'primary' : false, 'hidden' : true, 'render' : 'my.circ.due_date().substr(0,10)'
420                 },
421                 {
422                         'persist' : 'hidden width', 'id' : 'title', 'label' : getString('staff.mvr_label_title'), 'flex' : 2,
423                         'primary' : false, 'hidden' : true, 'render' : 'try { my.mvr.title(); } catch(E) { my.acp.dummy_title(); }'
424                 },
425                 {
426                         'persist' : 'hidden width', 'id' : 'author', 'label' : getString('staff.mvr_label_author'), 'flex' : 1,
427                         'primary' : false, 'hidden' : true, 'render' : 'try { my.mvr.author(); } catch(E) { my.acp.dummy_author(); }'
428                 },
429                 {
430                         'persist' : 'hidden width', 'id' : 'edition', 'label' : 'Edition', 'flex' : 1,
431                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.edition();'
432                 },
433                 {
434                         'persist' : 'hidden width', 'id' : 'isbn', 'label' : 'ISBN', 'flex' : 1,
435                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.isbn();'
436                 },
437                 {
438                         'persist' : 'hidden width', 'id' : 'pubdate', 'label' : 'PubDate', 'flex' : 1,
439                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.pubdate();'
440                 },
441                 {
442                         'persist' : 'hidden width', 'id' : 'publisher', 'label' : 'Publisher', 'flex' : 1,
443                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.publisher();'
444                 },
445                 {
446                         'persist' : 'hidden width', 'id' : 'tcn', 'label' : 'TCN', 'flex' : 1,
447                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.tcn();'
448                 },
449                 {
450                         'persist' : 'hidden width', 'id' : 'renewal_remaining', 'label' : getString('staff.circ_label_renewal_remaining'), 'flex' : 0,
451                         'primary' : false, 'hidden' : true, 'render' : 'my.circ.renewal_remaining()'
452                 },
453                 {
454                         'persist' : 'hidden width', 'id' : 'stop_fines', 'label' : 'Fines Stopped', 'flex' : 0,
455                         'primary' : false, 'hidden' : true, 'render' : 'my.circ.stop_fines()'
456                 },
457                 {
458                         'persist' : 'hidden width', 'id' : 'status', 'label' : getString('staff.acp_label_status'), 'flex' : 1,
459                         'primary' : false, 'hidden' : true, 'render' : 'if (Number(my.acp.status())>=0) obj.data.hash.ccs[ my.acp.status() ].name(); else my.acp.status().name();'
460                 },
461                 {
462                         'persist' : 'hidden width', 'id' : 'route_to', 'label' : 'Route To', 'flex' : 1,
463                         'primary' : false, 'hidden' : true, 'render' : 'my.route_to.toString()'
464                 },
465                 {
466                         'persist' : 'hidden width', 'id' : 'message', 'label' : 'Message', 'flex' : 1,
467                         'primary' : false, 'hidden' : true, 'render' : 'my.message.toString()'
468                 },
469                 {
470                         'persist' : 'hidden width', 'id' : 'uses', 'label' : '# of Uses', 'flex' : 1,
471                         'primary' : false, 'hidden' : true, 'render' : 'my.uses'
472                 },
473                 {
474                         'persist' : 'hidden width', 'id' : 'alert_message', 'label' : 'Alert Message', 'flex' : 1,
475                         'primary' : false, 'hidden' : true, 'render' : 'my.acp.alert_message()'
476                 },
477         ];
478         for (var i = 0; i < c.length; i++) {
479                 if (modify[ c[i].id ]) {
480                         for (var j in modify[ c[i].id ]) {
481                                 c[i][j] = modify[ c[i].id ][j];
482                         }
483                 }
484         }
485         if (params) {
486                 if (params.just_these) {
487                         JSAN.use('util.functional');
488                         var new_c = [];
489                         for (var i = 0; i < params.just_these.length; i++) {
490                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
491                                 new_c.push( function(y){ return y; }( x ) );
492                         }
493                         return new_c;
494                 }
495         }
496         return c;
497 }
498
499 circ.util.hold_columns = function(modify,params) {
500         
501         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
502
503         function getString(s) { return data.entities[s]; }
504
505         var c = [
506                 {
507                         'persist' : 'hidden width', 'id' : 'request_time', 'label' : getString('staff.ahr_request_time_label'), 'flex' : 0,
508                         'primary' : false, 'hidden' : true,  
509                         'render' : 'my.ahr.request_time().toString().substr(0,10)'
510                 },
511                 {
512                         'persist' : 'hidden width', 'id' : 'capture_time', 'label' : getString('staff.ahr_capture_time_label'), 'flex' : 1,
513                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.capture_time()'
514                 },
515                 {
516                         'persist' : 'hidden width', 'id' : 'status', 'label' : getString('staff.ahr_status_label'), 'flex' : 1,
517                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.status()'
518                 },
519                 {
520                         'persist' : 'hidden width', 'id' : 'hold_type', 'label' : getString('staff.ahr_hold_type_label'), 'flex' : 0,
521                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.hold_type()'
522                 },
523                 {
524                         'persist' : 'hidden width', 'id' : 'pickup_lib', 'label' : getString('staff.ahr_pickup_lib_label'), 'flex' : 1,
525                         'primary' : false, 'hidden' : true,  
526                         'render' : 'if (Number(my.ahr.pickup_lib())>=0) obj.data.hash.aou[ my.ahr.pickup_lib() ].name(); else my.ahr.pickup_lib().name();'
527                 },
528                 {
529                         'persist' : 'hidden width', 'id' : 'pickup_lib_shortname', 'label' : getString('staff.ahr_pickup_lib_label'), 'flex' : 0,
530                         'primary' : false, 'hidden' : true,  
531                         'render' : 'if (Number(my.ahr.pickup_lib())>=0) obj.data.hash.aou[ my.ahr.pickup_lib() ].shortname(); else my.ahr.pickup_lib().shortname();'
532                 },
533                 {
534                         'persist' : 'hidden width', 'id' : 'current_copy', 'label' : getString('staff.ahr_current_copy_label'), 'flex' : 1,
535                         'primary' : false, 'hidden' : true,  'render' : 'my.acp ? my.acp.barcode() : "No Copy"'
536                 },
537                 {
538                         'persist' : 'hidden width', 'id' : 'email_notify', 'label' : getString('staff.ahr_email_notify_label'), 'flex' : 1,
539                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.email_notify() == 1 ? "Yes" : "No"'
540                 },
541                 {
542                         'persist' : 'hidden width', 'id' : 'expire_time', 'label' : getString('staff.ahr_expire_time_label'), 'flex' : 1,
543                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.expire_time()'
544                 },
545                 {
546                         'persist' : 'hidden width', 'id' : 'fulfillment_time', 'label' : getString('staff.ahr_fulfillment_time_label'), 'flex' : 1,
547                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.fulfillment_time()'
548                 },
549                 {
550                         'persist' : 'hidden width', 'id' : 'holdable_formats', 'label' : getString('staff.ahr_holdable_formats_label'), 'flex' : 1,
551                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.holdable_formats()'
552                 },
553                 {
554                         'persist' : 'hidden width', 'id' : 'id', 'label' : getString('staff.ahr_id_label'), 'flex' : 1,
555                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.id()'
556                 },
557                 {
558                         'persist' : 'hidden width', 'id' : 'phone_notify', 'label' : getString('staff.ahr_phone_notify_label'), 'flex' : 1,
559                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.phone_notify()'
560                 },
561                 {
562                         'persist' : 'hidden width', 'id' : 'prev_check_time', 'label' : getString('staff.ahr_prev_check_time_label'), 'flex' : 1,
563                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.prev_check_time()'
564                 },
565                 {
566                         'persist' : 'hidden width', 'id' : 'requestor', 'label' : getString('staff.ahr_requestor_label'), 'flex' : 1,
567                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.requestor()'
568                 },
569                 {
570                         'persist' : 'hidden width', 'id' : 'selection_depth', 'label' : getString('staff.ahr_selection_depth_label'), 'flex' : 1,
571                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.selection_depth()'
572                 },
573                 {
574                         'persist' : 'hidden width', 'id' : 'target', 'label' : getString('staff.ahr_target_label'), 'flex' : 1,
575                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.target()'
576                 },
577                 {
578                         'persist' : 'hidden width', 'id' : 'usr', 'label' : getString('staff.ahr_usr_label'), 'flex' : 1,
579                         'primary' : false, 'hidden' : true,  'render' : 'my.ahr.usr()'
580                 },
581                 {
582                         'persist' : 'hidden width', 'id' : 'title', 'label' : getString('staff.mvr_label_title'), 'flex' : 1,
583                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr ? my.mvr.title() : "No Title?"'
584                 },
585                 {
586                         'persist' : 'hidden width', 'id' : 'author', 'label' : getString('staff.mvr_label_author'), 'flex' : 1,
587                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr ? my.mvr.author() : "No Author?"'
588                 },
589                 {
590                         'persist' : 'hidden width', 'id' : 'edition', 'label' : 'Edition', 'flex' : 1,
591                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.edition();'
592                 },
593                 {
594                         'persist' : 'hidden width', 'id' : 'isbn', 'label' : 'ISBN', 'flex' : 1,
595                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.isbn();'
596                 },
597                 {
598                         'persist' : 'hidden width', 'id' : 'pubdate', 'label' : 'PubDate', 'flex' : 1,
599                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.pubdate();'
600                 },
601                 {
602                         'persist' : 'hidden width', 'id' : 'publisher', 'label' : 'Publisher', 'flex' : 1,
603                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.publisher();'
604                 },
605                 {
606                         'persist' : 'hidden width', 'id' : 'tcn', 'label' : 'TCN', 'flex' : 1,
607                         'primary' : false, 'hidden' : true, 'render' : 'my.mvr.tcn();'
608                 },
609
610
611         ];
612         for (var i = 0; i < c.length; i++) {
613                 if (modify[ c[i].id ]) {
614                         for (var j in modify[ c[i].id ]) {
615                                 c[i][j] = modify[ c[i].id ][j];
616                         }
617                 }
618         }
619         if (params) {
620                 if (params.just_these) {
621                         JSAN.use('util.functional');
622                         var new_c = [];
623                         for (var i = 0; i < params.just_these.length; i++) {
624                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
625                                 new_c.push( function(y){ return y; }( x ) );
626                         }
627                         return new_c;
628                 }
629         }
630         return c;
631 }
632
633 circ.util.std_map_row_to_column = function(error_value) {
634         return function(row,col) {
635                 // row contains { 'my' : { 'acp' : {}, 'circ' : {}, 'mvr' : {} } }
636                 // col contains one of the objects listed above in columns
637                 
638                 // mimicking some of the obj in circ.checkin and circ.checkout where map_row_to_column is usually defined
639                 var obj = {}; 
640                 JSAN.use('util.error'); obj.error = new util.error();
641                 JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
642                 JSAN.use('util.network'); obj.network = new util.network();
643
644                 var my = row.my;
645                 var value;
646                 try { 
647                         value = eval( col.render );
648                 } catch(E) {
649                         obj.error.sdump('D_WARN','map_row_to_column: ' + E);
650                         if (error_value) value = error_value; else value = '???';
651                 }
652                 return value;
653         }
654 }
655
656 circ.util.checkin_via_barcode = function(session,barcode,backdate,auto_print) {
657         try {
658                 JSAN.use('util.error'); var error = new util.error();
659                 JSAN.use('util.network'); var network = new util.network();
660                 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
661                 JSAN.use('util.date');
662                 if (backdate && (backdate == util.date.formatted_date(new Date(),'%Y-%m-%d')) ) backdate = null;
663
664                 var params = { 'barcode' : barcode };
665                 if (backdate) params.backdate = backdate;
666
667                 var check = network.request(
668                         api.CHECKIN_VIA_BARCODE.app,
669                         api.CHECKIN_VIA_BARCODE.method,
670                         [ session, params ],
671                         null,
672                         {
673                                 'title' : 'Override Checkin Failure?',
674                                 'overridable_events' : [ 
675                                         1203 /* COPY_BAD_STATUS */, 
676                                         7009 /* CIRC_CLAIMS_RETURNED */,
677                                         7010 /* COPY_ALERT_MESSAGE */, 
678                                         7011 /* COPY_STATUS_LOST */, 
679                                         7012 /* COPY_STATUS_MISSING */, 
680                                 ],
681                                 'text' : {
682                                         '1203' : function(r) {
683                                                 //return data.hash.ccs[ r.payload.status() ].name();
684                                                 return r.payload.status().name();
685                                         },
686                                         '7010' : function(r) {
687                                                 return r.payload;
688                                         },
689                                 }
690                         }
691                 );
692
693                 check.message = check.textcode;
694
695                 if (check.payload && check.payload.copy) check.copy = check.payload.copy;
696                 if (check.payload && check.payload.record) check.record = check.payload.record;
697                 if (check.payload && check.payload.circ) check.circ = check.payload.circ;
698
699                 if (!check.route_to) check.route_to = '???';
700
701                 /* SUCCESS  /  NO_CHANGE  /  ITEM_NOT_CATALOGED */
702                 if (check.ilsevent == 0 || check.ilsevent == 3 || check.ilsevent == 1202) {
703                         try { check.route_to = data.lookup('acpl', check.copy.location() ).name(); } catch(E) { msg += 'FIXME: ' + E + '\n'; }
704                         var msg = '';
705                         if (check.ilsevent == 3) msg = 'This item is already checked in.\n';
706                         if (check.ilsevent == 1202 && check.copy.status() != 11) {
707                                 msg = 'FIXME -- ITEM_NOT_CATALOGED event but copy status is '
708                                         + (data.hash.ccs[ check.copy.status() ] ? data.hash.ccs[ check.copy.status() ].name() : check.copy.status().name() ) + '\n';
709                         }
710                         switch(check.copy.status()) {
711                                 case 0: /* AVAILABLE */
712                                 case 7: /* RESHELVING */
713                                         if (msg) msg += 'This item needs to be routed to ' + check.route_to + '.';
714                                 break;
715                                 case 8: /* ON HOLDS SHELF */
716                                         check.route_to = 'HOLDS SHELF';
717                                         if (check.payload.hold) {
718                                                 if (check.payload.hold.pickup_lib() != data.list.au[0].ws_ou()) {
719                                                         msg += 'FIXME:  We should have received a ROUTE_ITEM\n';
720                                                 } else {
721                                                         msg += 'This item needs to be routed to ' + check.route_to + '.\n';
722                                                 }
723                                         } else { 
724                                                 msg += 'FIXME: status of Holds Shelf, but no hold in payload';
725                                         }
726                                         if (check.payload.hold) {
727                                                 JSAN.use('patron.util');
728                                                 msg += '\nBarcode: ' + check.payload.copy.barcode() + '\n';
729                                                 msg += 'Title: ' + (check.payload.record ? check.payload.record.title() : check.payload.copy.dummy_title() ) + '\n';
730                                                 var au_obj = patron.util.retrieve_fleshed_au_via_id( session, check.payload.hold.usr() );
731                                                 msg += '\nHold for patron ' + au_obj.family_name() + ', ' + au_obj.first_given_name() + '\n';
732                                                 msg += 'Barcode: ' + au_obj.card().barcode() + '\n';
733                                                 if (check.payload.hold.phone_notify()) msg += 'Notify by phone: ' + check.payload.hold.phone_notify() + '\n';
734                                                 if (check.payload.hold.email_notify()) msg += 'Notify by email: ' + au_obj.email() + '\n';
735                                         }
736                                         var rv = 0;
737                                         if (!auto_print) rv = error.yns_alert(
738                                                 msg,
739                                                 'Hold Slip',
740                                                 "Print",
741                                                 "Don't Print",
742                                                 null,
743                                                 "Check here to confirm this message"
744                                         );
745                                         if (rv == 0) {
746                                                 try {
747                                                         JSAN.use('util.print'); var print = new util.print();
748                                                         print.simple( msg, { 'no_prompt' : true, 'content_type' : 'text/plain' } );
749                                                 } catch(E) {
750                                                         dump('FIXME: ' + E + '\n');
751                                                         alert('FIXME: ' + E + '\n');
752                                                 }
753                                         }
754                                         msg = '';
755                                 break;
756                                 case 6: /* IN TRANSIT */
757                                         check.route_to = 'TRANSIT SHELF??';
758                                         msg += ("FIXME -- I didn't think we could get here.\n");
759                                 break;
760                                 case 11: /* CATALOGING */
761                                         check.route_to = 'CATALOGING';
762                                         msg += 'This item needs to be routed to ' + check.route_to + '.';
763                                 break;
764                                 default:
765                                         msg += ('FIXME -- this case "' + (data.hash.ccs[check.copy.status()] ? data.hash.ccs[check.copy.status()].name() : check.copy.status().name()) + '" is unhandled.\n');
766                                         msg += 'This item needs to be routed to ' + check.route_to + '.';
767                                 break;
768                         }
769                         if (msg) error.yns_alert(msg,'Alert',null,'OK',null,"Check here to confirm this message");
770                 }
771
772                 /* ROUTE_ITEM */
773                 if (check.ilsevent == 7000) {
774                         var lib = data.hash.aou[ check.org ];
775                         check.route_to = lib.shortname();
776                         var msg = 'This item is in transit to ' + check.route_to + '.\n';
777                         msg += '\n' + lib.name() + '\n';
778                         try {
779                                 if (lib.holds_address() ) {
780                                         var a = network.simple_request('FM_AOA_RETRIEVE',[ lib.holds_address() ]);
781                                         if (typeof a.ilsevent != 'undefined') throw(a);
782                                         if (a.street1()) msg += a.street1() + '\n';
783                                         if (a.street2()) msg += a.street2() + '\n';
784                                         msg += (a.city() ? a.city() + ', ' : '') + (a.state() ? a.state() + ' ' : '') + (a.post_code() ? a.post_code() : '') + '\n';
785                                 } else {
786                                         msg += "We do not have a holds address for this library.\n";
787                                 }
788                         } catch(E) {
789                                 msg += 'Unable to retrieve mailing address.\n';
790                                 error.standard_unexpected_error_alert('Unable to retrieve mailing address.',E);
791                         }
792                         msg += '\nBarcode: ' + check.payload.copy.barcode() + '\n';
793                         msg += 'Title: ' + (check.payload.record ? check.payload.record.title() : check.payload.copy.dummy_title() ) + '\n';
794                         msg += 'Author: ' + (check.payload.record ? check.payload.record.author() :check.payload.copy.dummy_author()  ) + '\n';
795                         if (check.payload.hold) {
796                                 JSAN.use('patron.util');
797                                 var au_obj = patron.util.retrieve_fleshed_au_via_id( session, check.payload.hold.usr() );
798                                 msg += '\nHold for patron ' + au_obj.family_name() + ', ' + au_obj.first_given_name() + '\n';
799                                 msg += 'Barcode: ' + au_obj.card().barcode() + '\n';
800                                 if (check.payload.hold.phone_notify()) msg += 'Notify by phone: ' + check.payload.hold.phone_notify() + '\n';
801                                 if (check.payload.hold.email_notify()) msg += 'Notify by email: ' + au_obj.email() + '\n';
802                         }
803                         var rv = 0;
804                         if (!auto_print) rv = error.yns_alert(
805                                 msg,
806                                 'Transit Slip',
807                                 "Print",
808                                 "Don't Print",
809                                 null,
810                                 "Check here to confirm this message"
811                         );
812                         if (rv == 0) {
813                                 try {
814                                         JSAN.use('util.print'); var print = new util.print();
815                                         print.simple( msg, { 'no_prompt' : true, 'content_type' : 'text/plain' } );
816                                 } catch(E) {
817                                         dump('FIXME: ' + E + '\n');
818                                         alert('FIXME: ' + E + '\n');
819                                 }
820                         }
821                 }
822
823                 /* ASSET_COPY_NOT_FOUND */
824                 if (check.ilsevent == 1502) {
825                         check.route_to = 'CATALOGING';
826                         error.yns_alert(
827                                 'The barcode was either mis-scanned or the item needs to be cataloged.',
828                                 'Alert',
829                                 null,
830                                 'OK',
831                                 null,
832                                 "Check here to confirm this message"
833                         );
834                 }
835
836                 /* NETWORK TIMEOUT */
837                 if (check.ilsevent == -1) {
838                         error.standard_network_error_alert('Check In Failed.  If you wish to use the offline interface, in the top menubar select Circulation -> Offline Interface');
839                 }
840
841 //                              case '2': case 2: /* LOST??? */
842 //                                      JSAN.use('patron.util');
843 //                                      var au_obj = patron.util.retrieve_au_via_id( session, check.circ.usr() );
844 //                                      var msg = check.text + '\r\n' + 'Barcode: ' + barcode + '  Title: ' + 
845 //                                                      check.record.title() + '  Author: ' + check.record.author() + '\r\n' +
846 //                                                      'Patron: ' + au_obj.card().barcode() + ' ' + au_obj.family_name() + ', ' +
847 //                                                      au_obj.first_given_name();
848 //                                      var pcheck = error.yns_alert(
849 //                                              msg,
850 //                                              'Lost Item',
851 //                                              'Edit Copy & Patron',
852 //                                              "Just Continue",
853 //                                              null,
854 //                                              "Check here to confirm this message"
855 //                                      ); 
856 //                                      if (pcheck == 0) {
857 //                                              //FIXME//Re-implement
858 //                                              /*
859 //                                              var w = mw.spawn_main();
860 //                                              setTimeout(
861 //                                                      function() {
862 //                                                              mw.spawn_patron_display(w.document,'new_tab','main_tabbox',{'patron':au_obj});
863 //                                                              mw.spawn_batch_copy_editor(w.document,'new_tab','main_tabbox',
864 //                                                                      {'copy_ids':[ check.copy.id() ]});
865 //                                                      }, 0
866 //                                              );
867 //                                              */
868 //                                      }
869 //                              break;
870                 return check;
871         } catch(E) {
872                 JSAN.use('util.error'); var error = new util.error();
873                 error.standard_unexpected_error_alert('Check In Failed (in circ.util.checkin): ',E);
874                 return null;
875         }
876 }
877
878 circ.util.hold_capture_via_copy_barcode = function ( session, barcode, retrieve_flag ) {
879         try {
880                 JSAN.use('util.network'); var network = new util.network();
881                 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
882                 var params = { barcode: barcode }
883                 if (retrieve_flag) { params.flesh_record = retrieve_flag; params.flesh_copy = retrieve_flag; }
884                 var robj = network.request(
885                         api.CAPTURE_COPY_FOR_HOLD_VIA_BARCODE.app,
886                         api.CAPTURE_COPY_FOR_HOLD_VIA_BARCODE.method,
887                         [ session, params ]
888                 );
889                 var check = robj.payload;
890                 if (!check) {
891                         check = {};
892                         check.status = robj.ilsevent;
893                         check.copy = new acp(); check.copy.barcode( barcode );
894                 }
895                 check.text = robj.textcode;
896                 check.route_to = robj.route_to;
897                 //check.text = 'Captured for Hold';
898                 if (Number(check.route_to)) check.route_to = data.hash.aou[ check.route_to ].shortname();
899                 return check;
900         } catch(E) {
901                 JSAN.use('util.error'); var error = new util.error();
902                 error.standard_unexpected_error_alert('Hold Capture Failed',E);
903                 return null;
904         }
905 }
906
907
908 dump('exiting circ/util.js\n');