]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/circ/util.js
Merge branch 'master' of git+ssh://yeti.esilibrary.com/home/evergreen/evergreen-equin...
[Evergreen.git] / Open-ILS / xul / staff_client / server / circ / util.js
1 dump('entering circ/util.js\n');
2 // vim:noet:sw=4:ts=4:
3
4 if (typeof circ == 'undefined') { var circ = {}; }
5 circ.util = {};
6
7 circ.util.EXPORT_OK    = [
8     'offline_checkout_columns', 'offline_checkin_columns', 'offline_renew_columns', 'offline_inhouse_use_columns',
9     'columns', 'hold_columns', 'checkin_via_barcode', 'std_map_row_to_columns',
10     'show_last_few_circs', 'abort_transits', 'transit_columns', 'work_log_columns', 'renew_via_barcode', 'backdate_post_checkin', 'batch_hold_update'
11 ];
12 circ.util.EXPORT_TAGS    = { ':all' : circ.util.EXPORT_OK };
13
14 circ.util.abort_transits = function(selection_list) {
15     var obj = {};
16     JSAN.use('util.error'); obj.error = new util.error();
17     JSAN.use('util.network'); obj.network = new util.network();
18     JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
19     JSAN.use('util.functional');
20     var copies = util.functional.map_list( selection_list, function(o){return o.copy_id;}).join(', ');
21     var msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.abort_transits.confirm', [copies]);
22     var r = obj.error.yns_alert(
23         msg,
24         document.getElementById('circStrings').getString('staff.circ.utils.abort_transits.title'),
25         document.getElementById('circStrings').getString('staff.circ.utils.yes'),
26         document.getElementById('circStrings').getString('staff.circ.utils.no'),
27         null,
28         document.getElementById('circStrings').getString('staff.circ.confirm')
29     );
30     if (r == 0) {
31         try {
32             for (var i = 0; i < selection_list.length; i++) {
33                 var copy_id = selection_list[i].copy_id;
34                 var robj = obj.network.simple_request('FM_ATC_VOID',[ ses(), { 'copyid' : copy_id } ]);
35                 if (typeof robj.ilsevent != 'undefined') {
36                     switch(Number(robj.ilsevent)) {
37                         case 1225 /* TRANSIT_ABORT_NOT_ALLOWED */ :
38                             alert(document.getElementById('circString').getFormattedString('staff.circ.utils.abort_transits.not_allowed', [copy_id]) + '\n' + robj.desc);
39                         break;
40                         case 1504 /* ACTION_TRANSIT_COPY_NOT_FOUND */ :
41                             alert(document.getElementById('circString').getString('staff.circ.utils.abort_transits.not_found'));
42                         break;
43                         case 5000 /* PERM_FAILURE */ :
44                         break;
45                         default:
46                             throw(robj);
47                         break;
48                     }
49                 }
50             }
51         } catch(E) {
52             obj.error.standard_unexpected_error_alert(document.getElementById('circString').getString('staff.circ.utils.abort_transits.unexpected_error'),E);
53         }
54     }
55 };
56
57 circ.util.show_copy_details = function(copy_id) {
58     var obj = {};
59     JSAN.use('util.error'); obj.error = new util.error();
60     JSAN.use('util.window'); obj.win = new util.window();
61     JSAN.use('util.network'); obj.network = new util.network();
62     JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
63
64     if (typeof copy_id == 'object' && copy_id != null) copy_id = copy_id.id();
65
66     try {
67         var url = xulG.url_prefix( urls.XUL_COPY_DETAILS ); // + '?copy_id=' + copy_id;
68         var my_xulG = obj.win.open( url, 'show_copy_details', 'chrome,resizable,modal', { 'copy_id' : copy_id, 'new_tab' : xulG.new_tab, 'url_prefix' : xulG.url_prefix } );
69
70         if (typeof my_xulG.retrieve_these_patrons == 'undefined') return;
71         var patrons = my_xulG.retrieve_these_patrons;
72         for (var j = 0; j < patrons.length; j++) {
73             if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
74                 try {
75                     window.xulG.new_patron_tab( {}, { 'id' : patrons[j] } );
76                 } catch(E) {
77                     obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.utils.retrieve_patron.failure'), E);
78                 }
79             }
80         }
81
82     } catch(E) {
83         obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.utils.retrieve_copy.failure'),E);
84     }
85 };
86
87 circ.util.item_details_new = function(barcodes) {
88     try {
89         var content_params = {
90             'from_item_details_new': true,
91             'barcodes': barcodes
92         };
93         xulG.new_tab(urls.XUL_COPY_STATUS, {}, content_params);
94     } catch(E) {
95         JSAN.use('util.error');
96         (new util.error()).standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.utils.retrieve_copy.failure'),E);
97     }
98 };
99
100 circ.util.backdate_post_checkin = function(circ_ids) {
101     var obj = {};
102     JSAN.use('util.error'); obj.error = new util.error();
103     JSAN.use('util.window'); obj.win = new util.window();
104     JSAN.use('util.network'); obj.network = new util.network();
105     JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
106     JSAN.use('util.sound'); obj.sound = new util.sound();
107
108     var circStrings = document.getElementById('circStrings');
109
110     dojo.forEach(
111         circ_ids,
112         function(element,idx,list) {
113             if (typeof element == 'object' && element != null) list[idx] = element.id();
114         }
115     );
116
117     try {
118         var url = xulG.url_prefix( urls.XUL_BACKDATE );
119         var my_xulG = obj.win.open( url, 'backdate_post_checkin', 'chrome,resizable,modal', { 'circ_ids' : circ_ids } );
120
121         return my_xulG;
122
123     } catch(E) {
124         obj.error.standard_unexpected_error_alert(circStrings.getString('staff.circ.utils.retrieve_copy.failure'),E);
125     }
126 };
127
128
129 circ.util.show_last_few_circs = function(selection_list) {
130     var obj = {};
131     JSAN.use('util.error'); obj.error = new util.error();
132     JSAN.use('util.window'); obj.win = new util.window();
133     JSAN.use('util.network'); obj.network = new util.network();
134     JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
135
136     for (var i = 0; i < selection_list.length; i++) {
137         try {
138             if (typeof selection_list[i].copy_id == 'undefined' || selection_list[i].copy_id == null) continue;
139             var url = xulG.url_prefix( urls.XUL_CIRC_SUMMARY ); // + '?copy_id=' + selection_list[i].copy_id + '&count=' + count;
140             var my_xulG = obj.win.open( url, 'show_last_few_circs', 'chrome,resizable,modal', { 'copy_id' : selection_list[i].copy_id, 'new_tab' : xulG.new_tab, 'url_prefix': xulG.url_prefix } );
141
142             if (typeof my_xulG.retrieve_these_patrons == 'undefined') continue;
143             var patrons = my_xulG.retrieve_these_patrons;
144             for (var j = 0; j < patrons.length; j++) {
145                 if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
146                     try {
147                         window.xulG.new_patron_tab( {}, { 'id' : patrons[j] } );
148                     } catch(E) {
149                         obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.utils.retrieve_patron.failure') ,E);
150                     }
151                 }
152             }
153
154         } catch(E) {
155             obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.utils.retrieve_circs.failure') ,E);
156         }
157     }
158 };
159
160 circ.util.offline_checkout_columns = function(modify,params) {
161
162     var c = [
163         {
164             'id' : 'timestamp',
165             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.timestamp'),
166             'flex' : 1,
167             'primary' : false,
168             'hidden' : true,
169             'editable' : false, 'render' : function(my) { return my.timestamp; }
170         },
171         {
172             'id' : 'checkout_time',
173             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.checkout_time'),
174             'flex' : 1,
175             'primary' : false,
176             'hidden' : true,
177             'editable' : false, 'render' : function(my) { return my.checkout_time; }
178         },
179         {
180             'id' : 'type',
181             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.type'),
182             'flex' : 1,
183             'primary' : false,
184             'hidden' : true,
185             'editable' : false, 'render' : function(my) { return my.type; }
186         },
187         {
188             'id' : 'noncat',
189             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.noncat'),
190             'flex' : 1,
191             'primary' : false,
192             'hidden' : true,
193             'editable' : false, 'render' : function(my) { return my.noncat; }
194         },
195         {
196             'id' : 'noncat_type',
197             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.noncat_type'),
198             'flex' : 1,
199             'primary' : false,
200             'hidden' : true,
201             'editable' : false, 'render' : function(my) { return my.noncat_type; }
202         },
203         {
204             'id' : 'noncat_count',
205             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.count'),
206             'sort_type' : 'number',
207             'flex' : 1,
208             'primary' : false,
209             'hidden' : false,
210             'editable' : false, 'render' : function(my) { return my.noncat_count; }
211         },
212         {
213             'id' : 'patron_barcode',
214             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.patron_barcode'),
215             'flex' : 1,
216             'primary' : false,
217             'hidden' : true,
218             'editable' : false, 'render' : function(my) { return my.patron_barcode; }
219         },
220         {
221             'id' : 'barcode',
222             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.item_barcode'),
223             'flex' : 2,
224             'primary' : true,
225             'hidden' : false,
226             'editable' : false, 'render' : function(my) { return my.barcode; }
227         },
228         {
229             'id' : 'due_date',
230             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.due_date'),
231             'flex' : 1,
232             'primary' : false,
233             'hidden' : false,
234             'editable' : false, 'render' : function(my) { return my.due_date; }
235         },
236         {
237             'id' : 'due_time',
238             'label' : document.getElementById('commonStrings').getString('staff.circ_label_due_time'),
239             'flex' : 1,
240             'primary' : false,
241             'hidden' : false,
242             'editable' : false, 'render' : function(my) { return my.due_time; }
243         }
244
245     ];
246     if (modify) for (var i = 0; i < c.length; i++) {
247         if (modify[ c[i].id ]) {
248             for (var j in modify[ c[i].id ]) {
249                 c[i][j] = modify[ c[i].id ][j];
250             }
251         }
252     }
253     if (params) {
254         if (params.just_these) {
255             JSAN.use('util.functional');
256             var new_c = [];
257             for (var i = 0; i < params.just_these.length; i++) {
258                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
259                 new_c.push( function(y){ return y; }( x ) );
260             }
261             c = new_c;
262         }
263         if (params.except_these) {
264             JSAN.use('util.functional');
265             var new_c = [];
266             for (var i = 0; i < c.length; i++) {
267                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
268                 if (!x) new_c.push(c[i]);
269             }
270             c = new_c;
271         }
272
273     }
274     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
275 };
276
277 circ.util.offline_checkin_columns = function(modify,params) {
278
279     var c = [
280         {
281             'id' : 'timestamp',
282             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.timestamp'),
283             'flex' : 1,
284             'primary' : false,
285             'hidden' : true,
286             'editable' : false, 'render' : function(my) { return my.timestamp; }
287         },
288         {
289             'id' : 'backdate',
290             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.backdate'),
291             'flex' : 1,
292             'primary' : false,
293             'hidden' : true,
294             'editable' : false, 'render' : function(my) { return my.backdate; }
295         },
296         {
297             'id' : 'type',
298             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.type'),
299             'flex' : 1,
300             'primary' : false,
301             'hidden' : true,
302             'editable' : false, 'render' : function(my) { return my.type; }
303         },
304         {
305             'id' : 'barcode',
306             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.item_barcode'),
307             'flex' : 2,
308             'primary' : true,
309             'hidden' : false,
310             'editable' : false, 'render' : function(my) { return my.barcode; }
311         }
312     ];
313     if (modify) for (var i = 0; i < c.length; i++) {
314         if (modify[ c[i].id ]) {
315             for (var j in modify[ c[i].id ]) {
316                 c[i][j] = modify[ c[i].id ][j];
317             }
318         }
319     }
320     if (params) {
321         if (params.just_these) {
322             JSAN.use('util.functional');
323             var new_c = [];
324             for (var i = 0; i < params.just_these.length; i++) {
325                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
326                 new_c.push( function(y){ return y; }( x ) );
327             }
328             c = new_c;
329         }
330         if (params.except_these) {
331             JSAN.use('util.functional');
332             var new_c = [];
333             for (var i = 0; i < c.length; i++) {
334                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
335                 if (!x) new_c.push(c[i]);
336             }
337             c = new_c;
338         }
339
340     }
341     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
342 };
343
344 circ.util.offline_renew_columns = function(modify,params) {
345
346     var c = [
347         {
348             'id' : 'timestamp',
349             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.timestamp'),
350             'flex' : 1,
351             'primary' : false,
352             'hidden' : true,
353             'editable' : false, 'render' : function(my) { return my.timestamp; }
354         },
355         {
356             'id' : 'checkout_time',
357             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.checkout_time'),
358             'flex' : 1,
359             'primary' : false,
360             'hidden' : true,
361             'editable' : false, 'render' : function(my) { return my.checkout_time; }
362         },
363         {
364             'id' : 'type',
365             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.type'),
366             'flex' : 1,
367             'primary' : false,
368             'hidden' : true,
369             'editable' : false, 'render' : function(my) { return my.type; }
370         },
371         {
372             'id' : 'patron_barcode',
373             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.patron_barcode'),
374             'flex' : 1,
375             'primary' : false,
376             'hidden' : true,
377             'editable' : false, 'render' : function(my) { return my.patron_barcode; }
378         },
379         {
380             'id' : 'barcode',
381             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.item_barcode'),
382             'flex' : 2,
383             'primary' : true,
384             'hidden' : false,
385             'editable' : false, 'render' : function(my) { return my.barcode; }
386         },
387         {
388             'id' : 'due_date',
389             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.due_date'),
390             'flex' : 1,
391             'primary' : false,
392             'hidden' : false,
393             'editable' : false, 'render' : function(my) { return my.due_date; }
394         },
395         {
396             'id' : 'due_time',
397             'label' : document.getElementById('commonStrings').getString('staff.circ_label_due_time'),
398             'flex' : 1,
399             'primary' : false,
400             'hidden' : false,
401             'editable' : false, 'render' : function(my) { return my.due_time; }
402         }
403     ];
404     if (modify) for (var i = 0; i < c.length; i++) {
405         if (modify[ c[i].id ]) {
406             for (var j in modify[ c[i].id ]) {
407                 c[i][j] = modify[ c[i].id ][j];
408             }
409         }
410     }
411     if (params) {
412         if (params.just_these) {
413             JSAN.use('util.functional');
414             var new_c = [];
415             for (var i = 0; i < params.just_these.length; i++) {
416                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
417                 new_c.push( function(y){ return y; }( x ) );
418             }
419             c = new_c;
420         }
421         if (params.except_these) {
422             JSAN.use('util.functional');
423             var new_c = [];
424             for (var i = 0; i < c.length; i++) {
425                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
426                 if (!x) new_c.push(c[i]);
427             }
428             c = new_c;
429         }
430
431     }
432     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
433 };
434
435 circ.util.offline_inhouse_use_columns = function(modify,params) {
436
437     var c = [
438         {
439             'id' : 'timestamp',
440             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.timestamp'),
441             'flex' : 1,
442             'primary' : false,
443             'hidden' : true,
444             'editable' : false, 'render' : function(my) { return my.timestamp; }
445         },
446         {
447             'id' : 'use_time',
448             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.use_time'),
449             'flex' : 1,
450             'primary' : false,
451             'hidden' : true,
452             'editable' : false, 'render' : function(my) { return my.use_time; }
453         },
454         {
455             'id' : 'type',
456             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.type'),
457             'flex' : 1,
458             'primary' : false,
459             'hidden' : true,
460             'editable' : false, 'render' : function(my) { return my.type; }
461         },
462         {
463             'id' : 'count',
464             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.count'),
465             'sort_type' : 'number',
466             'flex' : 1,
467             'primary' : false,
468             'hidden' : false,
469             'editable' : false, 'render' : function(my) { return my.count; }
470         },
471         {
472             'id' : 'barcode',
473             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.item_barcode'),
474             'flex' : 2,
475             'primary' : true,
476             'hidden' : false,
477             'editable' : false, 'render' : function(my) { return my.barcode; }
478         }
479     ];
480     if (modify) for (var i = 0; i < c.length; i++) {
481         if (modify[ c[i].id ]) {
482             for (var j in modify[ c[i].id ]) {
483                 c[i][j] = modify[ c[i].id ][j];
484             }
485         }
486     }
487     if (params) {
488         if (params.just_these) {
489             JSAN.use('util.functional');
490             var new_c = [];
491             for (var i = 0; i < params.just_these.length; i++) {
492                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
493                 new_c.push( function(y){ return y; }( x ) );
494             }
495             c = new_c;
496         }
497         if (params.except_these) {
498             JSAN.use('util.functional');
499             var new_c = [];
500             for (var i = 0; i < c.length; i++) {
501                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
502                 if (!x) new_c.push(c[i]);
503             }
504             c = new_c;
505         }
506
507     }
508     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
509 };
510
511 circ.util.columns = function(modify,params) {
512
513     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
514     JSAN.use('util.network'); var network = new util.network();
515     JSAN.use('util.money');
516
517     var c = [
518         {
519             'id' : 'acp_id',
520             'fm_class' : 'acp',
521             'label' : document.getElementById('commonStrings').getString('staff.acp_label_id'),
522             'flex' : 1,
523             'primary' : false,
524             'hidden' : true,
525             'editable' : false, 'render' : function(my) { return my.acp.id(); },
526             'persist' : 'hidden width ordinal'
527         },
528         {
529             'id' : 'circ_id',
530             'fm_class' : 'circ',
531             'label' : document.getElementById('commonStrings').getString('staff.circ_label_id'),
532             'flex' : 1,
533             'primary' : false,
534             'hidden' : true,
535             'editable' : false, 'render' : function(my) { return my.circ ? my.circ.id() : ""; },
536             'persist' : 'hidden width ordinal'
537         },
538         {
539             'id' : 'mvr_doc_id',
540             'fm_class' : 'mvr',
541             'label' : document.getElementById('commonStrings').getString('staff.mvr_label_doc_id'),
542             'flex' : 1,
543             'primary' : false,
544             'hidden' : true,
545             'editable' : false, 'render' : function(my) { return my.mvr.doc_id(); },
546             'persist' : 'hidden width ordinal'
547         },
548         {
549             'persist' : 'hidden width ordinal',
550             'id' : 'service',
551             'label' : 'Service',
552             'flex' : 1,
553             'primary' : false,
554             'hidden' : true,
555             'editable' : false, 'render' : function(my) { return my.service; }
556         },
557         {
558             'id' : 'barcode',
559             'fm_class' : 'acp',
560             'label' : document.getElementById('commonStrings').getString('staff.acp_label_barcode'),
561             'flex' : 1,
562             'primary' : false,
563             'hidden' : true,
564             'editable' : false, 'render' : function(my) { return my.acp.barcode(); },
565             'persist' : 'hidden width ordinal'
566         },
567         {
568             'id' : 'call_number',
569             'fm_class' : 'acp',
570             'label' : document.getElementById('commonStrings').getString('staff.acp_label_call_number'),
571             'flex' : 1,
572             'primary' : false,
573             'hidden' : true,
574             'editable' : false, 'render' : function(my,scratch_data) {
575                 var acn_id;
576                 if (my.acn) {
577                     if (typeof my.acn == 'object') {
578                         acn_id = my.acn.id();
579                     } else {
580                         acn_id = my.acn;
581                     }
582                 } else if (my.acp) {
583                     if (typeof my.acp.call_number() == 'object') {
584                         acn_id = my.acp.call_number().id();
585                     } else {
586                         acn_id = my.acp.call_number();
587                     }
588                 }
589                 if (!acn_id && acn_id != 0) {
590                     return '';
591                 } else if (acn_id == -1) {
592                     return document.getElementById('circStrings').getString('staff.circ.utils.not_cataloged');
593                 } else if (acn_id == -2) {
594                     return document.getElementById('circStrings').getString('staff.circ.utils.retrieving');
595                 } else {
596                     if (!my.acn) {
597                         if (typeof scratch_data['acn_map'] == 'undefined') {
598                             scratch_data['acn_map'] = {};
599                         }
600                         if (typeof scratch_data['acn_map'][ acn_id ] == 'undefined') {
601                             var x = network.simple_request("FM_ACN_RETRIEVE.authoritative",[ acn_id ]);
602                             if (x.ilsevent) {
603                                 return document.getElementById('circStrings').getString('staff.circ.utils.not_cataloged');
604                             } else {
605                                 my.acn = x;
606                                 scratch_data['acn_map'][ acn_id ] = my.acn;
607                             }
608                         } else {
609                             my.acn = scratch_data['acn_map'][ acn_id ];
610                         }
611                     }
612                     return my.acn.label();
613                 }
614             },
615             'persist' : 'hidden width ordinal'
616         },
617         {
618             'id' : 'owning_lib',
619             'fm_class' : 'acn',
620             'label' : document.getElementById('circStrings').getString('staff.circ.utils.owning_lib'),
621             'flex' : 1,
622             'primary' : false,
623             'hidden' : true,
624             'editable' : false, 'render' : function(my) {
625                 if (Number(my.acn.owning_lib())>=0) {
626                     return data.hash.aou[ my.acn.owning_lib() ].shortname();
627                 } else {
628                     return my.acn.owning_lib().shortname();
629                 }
630             },
631             'persist' : 'hidden width ordinal'
632         },
633         {
634             'id' : 'prefix',
635             'fm_class' : 'acn',
636             'label' : document.getElementById('circStrings').getString('staff.circ.utils.prefix'),
637             'flex' : 1,
638             'primary' : false,
639             'hidden' : true,
640             'editable' : false, 'render' : function(my) {
641                 if (typeof my.acn == 'undefined') return '';
642                 return (typeof my.acn.prefix() == 'object') ? my.acn.prefix().label() : my.acn.prefix();
643             },
644             'persist' : 'hidden width ordinal'
645         },
646         {
647             'id' : 'suffix',
648             'fm_class' : 'acn',
649             'label' : document.getElementById('circStrings').getString('staff.circ.utils.suffix'),
650             'flex' : 1,
651             'primary' : false,
652             'hidden' : true,
653             'editable' : false, 'render' : function(my) {
654                 if (typeof my.acn == 'undefined') return '';
655                 return (typeof my.acn.suffix() == 'object') ? my.acn.suffix().label() : my.acn.suffix();
656             },
657             'persist' : 'hidden width ordinal'
658         },
659         {
660             'id' : 'label_class',
661             'fm_class' : 'acn',
662             'label' : document.getElementById('circStrings').getString('staff.circ.utils.label_class'),
663             'flex' : 1,
664             'primary' : false,
665             'hidden' : true,
666             'editable' : false, 'render' : function(my) {
667                 if (typeof my.acn == 'undefined') return '';
668                 return (typeof my.acn.label_class() == 'object') ? my.acn.label_class().name() : my.acn.label_class();
669             },
670             'persist' : 'hidden width ordinal'
671         },
672         {
673             'id' : 'parts',
674             'fm_class' : 'acp',
675             'label' : document.getElementById('commonStrings').getString('staff.acp_label_parts'),
676             'flex' : 1,
677             'sort_type' : 'number',
678             'primary' : false,
679             'hidden' : true,
680             'editable' : false, 'render' : function(my) {
681                 if (! my.acp.parts()) return '';
682                 var parts = my.acp.parts();
683                 var display_string = '';
684                 for (var i = 0; i < parts.length; i++) {
685                     if (my.doc_id) {
686                         if (my.doc_id == parts[i].record()) {
687                             return parts[i].label();
688                         }
689                     } else {
690                         if (i != 0) display_string += ' : ';
691                         display_string += parts[i].label();
692                     }
693                 }
694                 return display_string;
695             },
696             'persist' : 'hidden width ordinal'
697         },
698         {
699             'id' : 'copy_number',
700             'fm_class' : 'acp',
701             'label' : document.getElementById('commonStrings').getString('staff.acp_label_copy_number'),
702             'flex' : 1,
703             'sort_type' : 'number',
704             'primary' : false,
705             'hidden' : true,
706             'editable' : false, 'render' : function(my) { return my.acp.copy_number(); },
707             'persist' : 'hidden width ordinal'
708         },
709         {
710             'id' : 'location',
711             'fm_class' : 'acp',
712             'label' : document.getElementById('commonStrings').getString('staff.acp_label_location'),
713             'flex' : 1,
714             'primary' : false,
715             'hidden' : true,
716             'editable' : false, 'render' : function(my) {
717                 if (Number(my.acp.location())>=0) {
718                     return data.lookup("acpl", my.acp.location() ).name();
719                 } else {
720                     return my.acp.location().name();
721                 }
722             },
723             'persist' : 'hidden width ordinal'
724         },
725         {
726             'id' : 'loan_duration',
727             'fm_class' : 'acp',
728             'label' : document.getElementById('commonStrings').getString('staff.acp_label_loan_duration'),
729             'flex' : 1,
730             'primary' : false,
731             'hidden' : true,
732             'editable' : false, 'render' : function(my) {
733                 switch(Number(my.acp.loan_duration())) {
734                     case 1:
735                         return document.getElementById('circStrings').getString('staff.circ.utils.loan_duration.short');
736                         break;
737                     case 2:
738                         return document.getElementById('circStrings').getString('staff.circ.utils.loan_duration.normal');
739                         break;
740                     case 3:
741                         return document.getElementById('circStrings').getString('staff.circ.utils.loan_duration.long');
742                         break;
743                 };
744             },
745             'persist' : 'hidden width ordinal'
746         },
747         {
748             'id' : 'circ_lib',
749             'fm_class' : 'acp',
750             'label' : document.getElementById('commonStrings').getString('staff.acp_label_circ_lib'),
751             'flex' : 1,
752             'primary' : false,
753             'hidden' : true,
754             'editable' : false, 'render' : function(my) {
755                 if (Number(my.acp.circ_lib())>=0) {
756                     return data.hash.aou[ my.acp.circ_lib() ].shortname();
757                 } else {
758                     return my.acp.circ_lib().shortname();
759                 }
760             },
761             'persist' : 'hidden width ordinal'
762         },
763         {
764             'id' : 'fine_level',
765             'fm_class' : 'acp',
766             'label' : document.getElementById('commonStrings').getString('staff.acp_label_fine_level'),
767             'flex' : 1,
768             'primary' : false,
769             'hidden' : true,
770             'editable' : false, 'render' : function(my) {
771                 switch(Number(my.acp.fine_level())) {
772                     case 1:
773                         return document.getElementById('circStrings').getString('staff.circ.utils.fine_level.low');
774                         break;
775                     case 2:
776                         return document.getElementById('circStrings').getString('staff.circ.utils.fine_level.normal');
777                         break;
778                     case 3:
779                         return document.getElementById('circStrings').getString('staff.circ.utils.fine_level.high');
780                         break;
781                 };
782             },
783             'persist' : 'hidden width ordinal'
784         },
785         {
786             'id' : 'circulate',
787             'fm_class' : 'acp',
788             'label' : document.getElementById('circStrings').getString('staff.circ.utils.circulate'),
789             'flex' : 1,
790             'primary' : false,
791             'hidden' : true,
792             'editable' : false, 'render' : function(my) {
793                 if (get_bool( my.acp.circulate() )) {
794                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
795                 } else {
796                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
797                 }
798             },
799             'persist' : 'hidden width ordinal'
800         },
801         {
802             'id' : 'deleted',
803             'fm_class' : 'acp',
804             'label' : document.getElementById('circStrings').getString('staff.circ.utils.deleted'),
805             'flex' : 1,
806             'primary' : false,
807             'hidden' : true,
808             'editable' : false, 'render' : function(my) {
809                 if (get_bool( my.acp.deleted() )) {
810                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
811                 } else {
812                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
813                 }
814             },
815             'persist' : 'hidden width ordinal'
816         },
817         {
818             'id' : 'holdable',
819             'fm_class' : 'acp',
820             'label' : document.getElementById('circStrings').getString('staff.circ.utils.holdable'),
821             'flex' : 1,
822             'primary' : false,
823             'hidden' : true,
824             'editable' : false, 'render' : function(my) {
825                 if (get_bool( my.acp.holdable() )) {
826                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
827                 } else {
828                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
829                 }
830             },
831             'persist' : 'hidden width ordinal'
832         },
833         {
834             'id' : 'floating',
835             'fm_class' : 'acp',
836             'label' : document.getElementById('circStrings').getString('staff.circ.utils.floating'),
837             'flex' : 1,
838             'primary' : false,
839             'hidden' : true,
840             'editable' : false, 'render' : function(my) {
841                 if (get_bool( my.acp.floating() )) {
842                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
843                 } else {
844                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
845                 }
846             },
847             'persist' : 'hidden width ordinal'
848         },
849
850         {
851             'id' : 'opac_visible',
852             'fm_class' : 'acp',
853             'label' : document.getElementById('circStrings').getString('staff.circ.utils.opac_visible'),
854             'flex' : 1,
855             'primary' : false,
856             'hidden' : true,
857             'editable' : false, 'render' : function(my) {
858                 if (get_bool( my.acp.opac_visible() )) {
859                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
860                 } else {
861                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
862                 }
863             },
864             'persist' : 'hidden width ordinal'
865         },
866         {
867             'persist' : 'hidden width ordinal',
868             'id' : 'acp_mint_condition',
869             'fm_class' : 'acp',
870             'label' : document.getElementById('circStrings').getString('staff.circ.utils.acp_mint_condition'),
871             'flex' : 0,
872             'primary' : false,
873             'hidden' : true,
874             'editable' : false, 'render' : function(my) {
875                 if (get_bool( my.acp.mint_condition() )) {
876                     return document.getElementById('circStrings').getString('staff.circ.utils.acp_mint_condition.true');
877                 } else {
878                     return document.getElementById('circStrings').getString('staff.circ.utils.acp_mint_condition.false');
879                 }
880             }
881         },
882         {
883             'persist' : 'hidden width ordinal',
884             'fm_class' : 'acp',
885             'id' : 'ref',
886             'label' : document.getElementById('circStrings').getString('staff.circ.utils.reference'),
887             'flex' : 1,
888             'primary' : false,
889             'hidden' : true,
890             'editable' : false, 'render' : function(my) {
891                 if (get_bool( my.acp.ref() )) {
892                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
893                 } else {
894                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
895                 }
896             }
897         },
898         {
899             'persist' : 'hidden width ordinal',
900             'fm_class' : 'acp',
901             'id' : 'deposit',
902             'label' : document.getElementById('circStrings').getString('staff.circ.utils.deposit'),
903             'flex' : 1,
904             'primary' : false,
905             'hidden' : true,
906             'editable' : false, 'render' : function(my) {
907                 if (get_bool( my.acp.deposit() )) {
908                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
909                 } else {
910                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
911                 }
912             }
913         },
914         {
915             'persist' : 'hidden width ordinal',
916             'fm_class' : 'acp',
917             'id' : 'deposit_amount',
918             'label' : document.getElementById('commonStrings').getString('staff.acp_label_deposit_amount'),
919             'flex' : 1,
920             'primary' : false,
921             'hidden' : true,
922             'editable' : false, 'render' : function(my) {
923                 if (my.acp.price() == null) {
924                     return document.getElementById('circStrings').getString('staff.circ.utils.unset');
925                 } else {
926                     return util.money.sanitize(my.acp.deposit_amount());
927                 }
928             },
929             'sort_type' : 'money'
930         },
931         {
932             'persist' : 'hidden width ordinal',
933             'fm_class' : 'acp',
934             'id' : 'price',
935             'label' : document.getElementById('commonStrings').getString('staff.acp_label_price'),
936             'flex' : 1,
937             'primary' : false,
938             'hidden' : true,
939             'editable' : false, 'render' : function(my) {
940                 if (my.acp.price() == null) {
941                     return document.getElementById('circStrings').getString('staff.circ.utils.unset');
942                 } else {
943                     return util.money.sanitize(my.acp.price());
944                 }
945             },
946             'sort_type' : 'money'
947         },
948         {
949             'persist' : 'hidden width ordinal',
950             'fm_class' : 'acp',
951             'id' : 'circ_as_type',
952             'label' : document.getElementById('commonStrings').getString('staff.acp_label_circ_as_type'),
953             'flex' : 1,
954             'primary' : false,
955             'hidden' : true,
956             'editable' : false, 'render' : function(my) { return my.acp.circ_as_type(); }
957         },
958         {
959             'persist' : 'hidden width ordinal',
960             'fm_class' : 'acp',
961             'id' : 'circ_modifier',
962             'label' : document.getElementById('commonStrings').getString('staff.acp_label_circ_modifier'),
963             'flex' : 1,
964             'primary' : false,
965             'hidden' : true,
966             'editable' : false, 'render' : function(my) { var cm = my.acp.circ_modifier(); return document.getElementById('commonStrings').getFormattedString('staff.circ_modifier.display',[cm,data.hash.ccm[cm].name(),data.hash.ccm[cm].description()]); }
967         },
968         {
969             'id' : 'status_changed_time',
970             'fm_class' : 'acp',
971             'label' : document.getElementById('circStrings').getString('staff.circ.utils.status_changed_time'),
972             'flex' : 1,
973             'sort_type' : 'date',
974             'primary' : false,
975             'hidden' : true,
976             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.acp.status_changed_time(), '%{localized}' ); },
977             'persist' : 'hidden width ordinal'
978         },
979         {
980             'persist' : 'hidden width ordinal',
981             'fm_class' : 'circ',
982             'id' : 'checkout_lib',
983             'label' : document.getElementById('circStrings').getString('staff.circ.utils.checkout_lib'),
984             'flex' : 1,
985             'primary' : false,
986             'hidden' : true,
987             'editable' : false, 'render' : function(my) {
988                 if (my.circ) {
989                     return data.hash.aou[ my.circ.circ_lib() ].shortname();
990                 } else {
991                     return "";
992                 }
993             }
994         },
995         {
996             'persist' : 'hidden width ordinal',
997             'fm_class' : 'circ',
998             'id' : 'xact_start',
999             'label' : document.getElementById('circStrings').getString('staff.circ.utils.xact_start'),
1000             'flex' : 1,
1001             'sort_type' : 'date',
1002             'primary' : false,
1003             'hidden' : true,
1004             'editable' : false, 'render' : function(my) {
1005                 if (my.circ) {
1006                     return util.date.formatted_date( my.circ.xact_start(), '%{localized}' );
1007                 } else {
1008                     return "";
1009                 }
1010             }
1011         },
1012         {
1013             'persist' : 'hidden width ordinal',
1014             'fm_class' : 'circ',
1015             'id' : 'checkin_time',
1016             'label' : document.getElementById('circStrings').getString('staff.circ.utils.checkin_time'),
1017             'flex' : 1,
1018             'sort_type' : 'date',
1019             'primary' : false,
1020             'hidden' : true,
1021             'editable' : false, 'render' : function(my) {
1022                 if (my.circ) {
1023                     return util.date.formatted_date( my.circ.checkin_time(), '%{localized}' );
1024                 } else {
1025                     return "";
1026                 }
1027             }
1028         },
1029         {
1030             'persist' : 'hidden width ordinal',
1031             'fm_class' : 'circ',
1032             'id' : 'xact_finish',
1033             'label' : document.getElementById('circStrings').getString('staff.circ.utils.xact_finish'),
1034             'flex' : 1,
1035             'sort_type' : 'date',
1036             'primary' : false,
1037             'hidden' : true,
1038             'editable' : false, 'render' : function(my) { return my.circ ? util.date.formatted_date( my.circ.xact_finish(), '%{localized}' ) : ""; },
1039         },
1040         {
1041             'persist' : 'hidden width ordinal',
1042             'fm_class' : 'circ',
1043             'id' : 'due_date',
1044             'label' : document.getElementById('commonStrings').getString('staff.circ_label_due_date'),
1045             'flex' : 1,
1046             'sort_type' : 'date',
1047             'primary' : false,
1048             'hidden' : true,
1049             'editable' : false, 'render' : function(my) {
1050                 if (my.circ) {
1051                     return util.date.formatted_date( my.circ.due_date(), '%{localized}' );
1052                 } else {
1053                     return "";
1054                 }
1055             }
1056         },
1057         {
1058             'persist' : 'hidden width ordinal',
1059             'fm_class' : 'acp',
1060             'id' : 'acp_create_date',
1061             'label' : document.getElementById('circStrings').getString('staff.circ.utils.create_date'),
1062             'flex' : 1,
1063             'sort_type' : 'date',
1064             'primary' : false,
1065             'hidden' : true,
1066             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.acp.create_date(), '%{localized}' ); }
1067         },
1068         {
1069             'persist' : 'hidden width ordinal',
1070             'fm_class' : 'acp',
1071             'id' : 'acp_edit_date',
1072             'label' : document.getElementById('circStrings').getString('staff.circ.utils.edit_date'),
1073             'flex' : 1,
1074             'sort_type' : 'date',
1075             'primary' : false,
1076             'hidden' : true,
1077             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.acp.edit_date(), '%{localized}' ); }
1078         },
1079         {
1080             'persist' : 'hidden width ordinal',
1081             'fm_class' : 'mvr',
1082             'id' : 'title',
1083             'label' : document.getElementById('commonStrings').getString('staff.mvr_label_title'),
1084             'flex' : 2,
1085             'sort_type' : 'title',
1086             'primary' : false,
1087             'hidden' : true,
1088             'editable' : false, 'render' : function(my) {
1089                 if (my.mvr) {
1090                     if (my.mvr.doc_id() == -1) {
1091                         return my.acp.dummy_title();
1092                     } else {
1093                         return my.mvr.title();
1094                     }
1095                 } else {
1096                     return my.acp.dummy_title();
1097                 }
1098             }
1099         },
1100         {
1101             'persist' : 'hidden width ordinal',
1102             'fm_class' : 'mvr',
1103             'id' : 'author',
1104             'label' : document.getElementById('commonStrings').getString('staff.mvr_label_author'),
1105             'flex' : 1,
1106             'primary' : false,
1107             'hidden' : true,
1108             'editable' : false, 'render' : function(my) {
1109                 if (my.mvr) {
1110                     if (my.mvr.doc_id() == -1) {
1111                         return my.acp.dummy_author();
1112                     } else {
1113                         return my.mvr.author();
1114                     }
1115                 } else {
1116                     return my.acp.dummy_author();
1117                 }
1118             }
1119         },
1120         {
1121             'persist' : 'hidden width ordinal',
1122             'fm_class' : 'mvr',
1123             'id' : 'edition',
1124             'label' : document.getElementById('circStrings').getString('staff.circ.utils.edition'),
1125             'flex' : 1,
1126             'primary' : false,
1127             'hidden' : true,
1128             'editable' : false, 'render' : function(my) { return my.mvr.edition(); }
1129         },
1130         {
1131             'persist' : 'hidden width ordinal',
1132             'fm_class' : 'mvr',
1133             'id' : 'isbn',
1134             'label' : document.getElementById('circStrings').getString('staff.circ.utils.isbn'),
1135             'flex' : 1,
1136             'primary' : false,
1137             'hidden' : true,
1138             'editable' : false, 'render' : function(my) { 
1139                 if (my.mvr) {
1140                     if (my.mvr.doc_id() == -1) {
1141                         return my.acp.dummy_isbn();
1142                     } else {
1143                         return my.mvr.isbn();
1144                     }
1145                 } else {
1146                     return my.acp.dummy_isbn();
1147                 }
1148             }
1149         },
1150         {
1151             'persist' : 'hidden width ordinal',
1152             'fm_class' : 'mvr',
1153             'id' : 'pubdate',
1154             'label' : document.getElementById('circStrings').getString('staff.circ.utils.pubdate'),
1155             'flex' : 1,
1156             'primary' : false,
1157             'hidden' : true,
1158             'editable' : false, 'render' : function(my) { return my.mvr.pubdate(); }
1159         },
1160         {
1161             'persist' : 'hidden width ordinal',
1162             'fm_class' : 'mvr',
1163             'id' : 'publisher',
1164             'label' : document.getElementById('circStrings').getString('staff.circ.utils.publisher'),
1165             'flex' : 1,
1166             'primary' : false,
1167             'hidden' : true,
1168             'editable' : false, 'render' : function(my) { return my.mvr.publisher(); }
1169         },
1170         {
1171             'persist' : 'hidden width ordinal',
1172             'fm_class' : 'mvr',
1173             'id' : 'tcn',
1174             'label' : document.getElementById('circStrings').getString('staff.circ.utils.tcn'),
1175             'flex' : 1,
1176             'primary' : false,
1177             'hidden' : true,
1178             'editable' : false, 'render' : function(my) { return my.mvr.tcn(); }
1179         },
1180         {
1181             'persist' : 'hidden width ordinal',
1182             'fm_class' : 'circ',
1183             'id' : 'renewal_remaining',
1184             'label' : document.getElementById('commonStrings').getString('staff.circ_label_renewal_remaining'),
1185             'flex' : 0,
1186             'primary' : false,
1187             'hidden' : true,
1188             'editable' : false, 'render' : function(my) {
1189                 if (my.circ) {
1190                     return my.circ.renewal_remaining();
1191                 } else {
1192                     return "";
1193                 }
1194             },
1195             'sort_type' : 'number'
1196         },
1197         {
1198             'persist' : 'hidden width ordinal',
1199             'fm_class' : 'circ',
1200             'id' : 'stop_fines',
1201             'label' : document.getElementById('circStrings').getString('staff.circ.utils.stop_fines'),
1202             'flex' : 0,
1203             'primary' : false,
1204             'hidden' : true,
1205             'editable' : false, 'render' : function(my) {
1206                 if (my.circ) {
1207                     return my.circ.stop_fines();
1208                 } else {
1209                     return "";
1210                 }
1211             }
1212         },
1213         {
1214             'persist' : 'hidden width ordinal',
1215             'fm_class' : 'circ',
1216             'id' : 'stop_fines_time',
1217             'label' : document.getElementById('circStrings').getString('staff.circ.utils.stop_fines_time'),
1218             'flex' : 0,
1219             'sort_type' : 'date',
1220             'primary' : false,
1221             'hidden' : true,
1222             'editable' : false, 'render' : function(my) {
1223                 if (my.circ) {
1224                     return util.date.formatted_date( my.circ.stop_fines_time(), '%{localized}' );
1225                 } else {
1226                     return "";
1227                 }
1228             }
1229         },
1230         {
1231             'persist' : 'hidden width ordinal',
1232             'fm_class' : 'acp',
1233             'id' : 'acp_status',
1234             'label' : document.getElementById('commonStrings').getString('staff.acp_label_status'),
1235             'flex' : 1,
1236             'primary' : false,
1237             'hidden' : true,
1238             'editable' : false, 'render' : function(my) {
1239                 if (Number(my.acp.status())>=0) {
1240                     return data.hash.ccs[ my.acp.status() ].name();
1241                 } else {
1242                     return my.acp.status().name();
1243                 }
1244             }
1245         },
1246         {
1247             'persist' : 'hidden width ordinal',
1248             'id' : 'route_to',
1249             'label' : document.getElementById('circStrings').getString('staff.circ.utils.route_to'),
1250             'flex' : 1,
1251             'primary' : false,
1252             'hidden' : true,
1253             'editable' : false, 'render' : function(my) { return my.route_to.toString(); }
1254         },
1255         {
1256             'persist' : 'hidden width ordinal',
1257             'id' : 'message',
1258             'label' : document.getElementById('circStrings').getString('staff.circ.utils.message'),
1259             'flex' : 1,
1260             'primary' : false,
1261             'hidden' : true,
1262             'editable' : false, 'render' : function(my) { return my.message.toString(); }
1263         },
1264         {
1265             'persist' : 'hidden width ordinal',
1266             'id' : 'uses',
1267             'label' : document.getElementById('circStrings').getString('staff.circ.utils.uses'),
1268             'flex' : 1,
1269             'primary' : false,
1270             'hidden' : true,
1271             'editable' : false, 'render' : function(my) { return my.uses; },
1272             'sort_type' : 'number'
1273         },
1274         {
1275             'persist' : 'hidden width ordinal',
1276             'fm_class' : 'acp',
1277             'id' : 'alert_message',
1278             'label' : document.getElementById('circStrings').getString('staff.circ.utils.alert_message'),
1279             'flex' : 1,
1280             'primary' : false,
1281             'hidden' : true,
1282             'editable' : false, 'render' : function(my) { return my.acp.alert_message(); }
1283         },
1284         {
1285             'persist' : 'hidden width ordinal',
1286             'fm_class' : 'circ',
1287             'id' : 'checkin_workstation',
1288             'label' : document.getElementById('circStrings').getString('staff.circ.utils.checkin_workstation'),
1289             'flex' : 1,
1290             'primary' : false,
1291             'hidden' : true,
1292             'editable' : false, 'render' : function(my) { return my.circ ? ( typeof my.circ.checkin_workstation() == 'object' ? my.circ.checkin_workstation().name() : my.circ.checkin_workstation() ) : ""; },
1293         },
1294         {
1295             'persist' : 'hidden width ordinal',
1296             'fm_class' : 'circ',
1297             'id' : 'checkout_workstation',
1298             'label' : document.getElementById('circStrings').getString('staff.circ.utils.checkout_workstation'),
1299             'flex' : 1,
1300             'primary' : false,
1301             'hidden' : true,
1302             'editable' : false, 'render' : function(my) { return my.circ ? ( typeof my.circ.workstation() == 'object' ? my.circ.workstation().name() : my.circ.workstation() ) : ""; },
1303         },
1304         {
1305             'persist' : 'hidden width ordinal',
1306             'fm_class' : 'circ',
1307             'id' : 'checkout_workstation_top_of_chain',
1308             'label' : document.getElementById('circStrings').getString('staff.circ.utils.checkout_workstation_top_of_chain'),
1309             'flex' : 1,
1310             'primary' : false,
1311             'hidden' : true,
1312             'editable' : false, 'render' : function(my) { if (my.circ&&!my.original_circ) { if(!get_bool(my.circ.desk_renewal())&&!get_bool(my.circ.opac_renewal())&&!get_bool(my.circ.phone_renewal())){my.original_circ = my.circ;}}; return my.original_circ ? ( typeof my.original_circ.workstation() == 'object' ? my.original_circ.workstation().name() : my.original_circ.workstation() ) : ""; },
1313         },
1314         {
1315             'persist' : 'hidden width ordinal',
1316             'fm_class' : 'circ',
1317             'id' : 'checkin_scan_time',
1318             'label' : document.getElementById('circStrings').getString('staff.circ.utils.checkin_scan_time'),
1319             'flex' : 1,
1320             'sort_type' : 'date',
1321             'primary' : false,
1322             'hidden' : true,
1323             'editable' : false, 'render' : function(my) { return my.circ ? util.date.formatted_date( my.circ.checkin_scan_time(), '%{localized}' ) : ""; },
1324         },
1325         {
1326             'persist' : 'hidden width ordinal',
1327             'fm_class' : 'bre',
1328             'id' : 'owner',
1329             'label' : document.getElementById('circStrings').getString('staff.circ.utils.owner'),
1330             'flex' : 1,
1331             'primary' : false,
1332             'hidden' : true,
1333             'editable' : false, 'render' : function(my) { return my.bre ? (typeof my.bre.owner() == 'object' ? my.bre.owner().shortname() : data.hash.aou[my.bre.owner()].shortname() ) : ''; }
1334         },
1335         {
1336             'persist' : 'hidden width ordinal',
1337             'fm_class' : 'bre',
1338             'id' : 'creator',
1339             'label' : document.getElementById('circStrings').getString('staff.circ.utils.creator'),
1340             'flex' : 1,
1341             'primary' : false,
1342             'hidden' : true,
1343             'editable' : false, 'render' : function(my) { return my.bre ? (typeof my.bre.creator() == 'object' ? my.bre.creator().usrname() : '#' + my.bre.creator() ) : ''; }
1344         },
1345         {
1346             'persist' : 'hidden width ordinal',
1347             'fm_class' : 'bre',
1348             'id' : 'editor',
1349             'label' : document.getElementById('circStrings').getString('staff.circ.utils.editor'),
1350             'flex' : 1,
1351             'primary' : false,
1352             'hidden' : true,
1353             'editable' : false, 'render' : function(my) { return my.bre ? (typeof my.bre.editor() == 'object' ? my.bre.editor().usrname() : '#' + my.bre.editor() ) : ''; }
1354         },
1355         {
1356             'persist' : 'hidden width ordinal',
1357             'fm_class' : 'bre',
1358             'id' : 'create_date',
1359             'label' : document.getElementById('circStrings').getString('staff.circ.utils.bre.create_date'),
1360             'flex' : 1,
1361             'sort_type' : 'date',
1362             'primary' : false,
1363             'hidden' : true,
1364             'editable' : false, 'render' : function(my) { return my.bre ? util.date.formatted_date( my.bre.create_date(), '%{localized}' ) : ''; }
1365         },
1366         {
1367             'persist' : 'hidden width ordinal',
1368             'fm_class' : 'bre',
1369             'id' : 'edit_date',
1370             'label' : document.getElementById('circStrings').getString('staff.circ.utils.bre.edit_date'),
1371             'flex' : 1,
1372             'sort_type' : 'date',
1373             'primary' : false,
1374             'hidden' : true,
1375             'editable' : false, 'render' : function(my) { return my.bre ? util.date.formatted_date( my.bre.edit_date(), '%{localized}' ) : ''; }
1376         },
1377         {
1378             'persist' : 'hidden width ordinal',
1379             'fm_class' : 'bre',
1380             'id' : 'tcn_value',
1381             'label' : document.getElementById('circStrings').getString('staff.circ.utils.tcn'),
1382             'flex' : 1,
1383             'primary' : false,
1384             'hidden' : true,
1385             'editable' : false, 'render' : function(my) { return my.bre ? my.bre.tcn_value() : ''; }
1386         },
1387         {
1388             'persist' : 'hidden width ordinal',
1389             'fm_class' : 'bre',
1390             'id' : 'tcn_source',
1391             'label' : document.getElementById('circStrings').getString('staff.circ.utils.tcn_source'),
1392             'flex' : 1,
1393             'primary' : false,
1394             'hidden' : true,
1395             'editable' : false, 'render' : function(my) { return my.bre ? my.bre.tcn_source() : ''; }
1396         }
1397
1398     ];
1399     for (var i = 0; i < c.length; i++) {
1400         if (modify[ c[i].id ]) {
1401             for (var j in modify[ c[i].id ]) {
1402                 c[i][j] = modify[ c[i].id ][j];
1403             }
1404         }
1405     }
1406     if (params) {
1407         if (params.just_these) {
1408             JSAN.use('util.functional');
1409             var new_c = [];
1410             for (var i = 0; i < params.just_these.length; i++) {
1411                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
1412                 new_c.push( function(y){ return y; }( x ) );
1413             }
1414             c = new_c;
1415         }
1416         if (params.except_these) {
1417             JSAN.use('util.functional');
1418             var new_c = [];
1419             for (var i = 0; i < c.length; i++) {
1420                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
1421                 if (!x) new_c.push(c[i]);
1422             }
1423             c = new_c;
1424         }
1425     }
1426     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
1427 };
1428
1429 circ.util.work_log_columns = function(modify,params) {
1430
1431     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
1432
1433     var c = [
1434         {
1435             'persist' : 'hidden width ordinal',
1436             'id' : 'message',
1437             'label' : document.getElementById('circStrings').getString('staff.circ.work_log_column.message'),
1438             'flex' : 3,
1439             'primary' : true,
1440             'hidden' : false,
1441             'editable' : false, 'render' : function(my) { return my.message; }
1442         },
1443         {
1444             'persist' : 'hidden width ordinal',
1445             'id' : 'when',
1446             'label' : document.getElementById('circStrings').getString('staff.circ.work_log_column.when'),
1447             'flex' : 1,
1448             'primary' : false,
1449             'hidden' : false,
1450             'editable' : false, 'render' : function(my) { return String( my.when ); }
1451         }
1452
1453     ];
1454     for (var i = 0; i < c.length; i++) {
1455         if (modify[ c[i].id ]) {
1456             for (var j in modify[ c[i].id ]) {
1457                 c[i][j] = modify[ c[i].id ][j];
1458             }
1459         }
1460     }
1461     if (params) {
1462         if (params.just_these) {
1463             JSAN.use('util.functional');
1464             var new_c = [];
1465             for (var i = 0; i < params.just_these.length; i++) {
1466                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
1467                 new_c.push( function(y){ return y; }( x ) );
1468             }
1469             c = new_c;
1470         }
1471         if (params.except_these) {
1472             JSAN.use('util.functional');
1473             var new_c = [];
1474             for (var i = 0; i < c.length; i++) {
1475                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
1476                 if (!x) new_c.push(c[i]);
1477             }
1478             c = new_c;
1479         }
1480
1481     }
1482     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
1483 };
1484
1485 circ.util.transit_columns = function(modify,params) {
1486
1487     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
1488
1489     var c = [
1490         {
1491             'persist' : 'hidden width ordinal',
1492             'id' : 'transit_item_barcode',
1493             'label' : document.getElementById('circStrings').getString('staff.circ.utils.barcode'),
1494             'flex' : 1,
1495             'primary' : false,
1496             'hidden' : true,
1497             'editable' : false, 'render' : function(my) { return my.acp.barcode(); }
1498         },
1499         {
1500             'persist' : 'hidden width ordinal',
1501             'id' : 'transit_item_title',
1502             'label' : document.getElementById('circStrings').getString('staff.circ.utils.title'),
1503             'flex' : 1,
1504             'primary' : false,
1505             'hidden' : true,
1506             'editable' : false, 'render' : function(my) {
1507                 try { return my.mvr.title(); }
1508                 catch(E) { return my.acp.dummy_title(); }
1509             }
1510         },
1511         {
1512             'persist' : 'hidden width ordinal',
1513             'id' : 'transit_item_author',
1514             'label' : document.getElementById('circStrings').getString('staff.circ.utils.author'),
1515             'flex' : 1,
1516             'primary' : false,
1517             'hidden' : true,
1518             'editable' : false, 'render' : function(my) {
1519                 try { return my.mvr.author(); }
1520                 catch(E) { return my.acp.dummy_author(); }
1521             }
1522         },
1523         {
1524             'persist' : 'hidden width ordinal',
1525             'id' : 'transit_item_callnumber',
1526             'label' : document.getElementById('circStrings').getString('staff.circ.utils.callnumber'),
1527             'flex' : 1,
1528             'primary' : false,
1529             'hidden' : true,
1530             'editable' : false, 'render' : function(my) { return my.acn.label(); }
1531         },
1532         {
1533             'persist' : 'hidden width ordinal',
1534             'id' : 'transit_id',
1535             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_id'),
1536             'flex' : 1,
1537             'primary' : false,
1538             'hidden' : true,
1539             'editable' : false, 'render' : function(my) { return my.atc.id(); }
1540         },
1541         {
1542             'persist' : 'hidden width ordinal',
1543             'id' : 'transit_source',
1544             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_source'),
1545             'flex' : 1,
1546             'primary' : false,
1547             'hidden' : false,
1548             'editable' : false, 'render' : function(my) {
1549                 if (typeof my.atc.source() == "object") {
1550                     return my.atc.source().shortname();
1551                 } else {
1552                     return data.hash.aou[ my.atc.source() ].shortname();
1553                 }
1554             }
1555         },
1556         {
1557             'persist' : 'hidden width ordinal',
1558             'id' : 'transit_source_send_time',
1559             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_source_send_time'),
1560             'flex' : 1,
1561             'sort_type' : 'date',
1562             'primary' : false,
1563             'hidden' : false,
1564             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.atc.source_send_time(), '%{localized}' ); }
1565         },
1566         {
1567             'persist' : 'hidden width ordinal',
1568             'id' : 'transit_dest_lib',
1569             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_dest'),
1570             'flex' : 1,
1571             'primary' : false,
1572             'hidden' : false,
1573             'editable' : false, 'render' : function(my) {
1574                 if (typeof my.atc.dest() == "object") {
1575                     return my.atc.dest().shortname();
1576                 } else {
1577                     return data.hash.aou[ my.atc.dest() ].shortname();
1578                 }
1579             }
1580         },
1581         {
1582             'persist' : 'hidden width ordinal',
1583             'id' : 'transit_dest_recv_time',
1584             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_dest_recv_time'),
1585             'flex' : 1,
1586             'sort_type' : 'date',
1587             'primary' : false,
1588             'hidden' : false,
1589             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.atc.dest_recv_time(), '%{localized}' ); }
1590         },
1591         {
1592             'persist' : 'hidden width ordinal',
1593             'id' : 'transit_target_copy',
1594             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_target_copy'),
1595             'flex' : 1,
1596             'primary' : false,
1597             'hidden' : true,
1598             'editable' : false, 'render' : function(my) { return my.atc.target_copy(); }
1599         },
1600     ];
1601     for (var i = 0; i < c.length; i++) {
1602         if (modify[ c[i].id ]) {
1603             for (var j in modify[ c[i].id ]) {
1604                 c[i][j] = modify[ c[i].id ][j];
1605             }
1606         }
1607     }
1608     if (params) {
1609         if (params.just_these) {
1610             JSAN.use('util.functional');
1611             var new_c = [];
1612             for (var i = 0; i < params.just_these.length; i++) {
1613                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
1614                 new_c.push( function(y){ return y; }( x ) );
1615             }
1616             c = new_c;
1617         }
1618         if (params.except_these) {
1619             JSAN.use('util.functional');
1620             var new_c = [];
1621             for (var i = 0; i < c.length; i++) {
1622                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
1623                 if (!x) new_c.push(c[i]);
1624             }
1625             c = new_c;
1626         }
1627
1628     }
1629     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
1630 };
1631
1632 circ.util.hold_columns = function(modify,params) {
1633
1634     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
1635
1636     var c = [
1637         {
1638             'id' : 'post_clear_shelf_action',
1639             'flex' : 1, 'primary' : false, 'hidden' : true, 'editable' : false, 
1640             'label' : document.getElementById('circStrings').getString('staff.circ.utils.hold_post_clear_shelf_action.label'),
1641             'render' : function(my) { 
1642                 return my.post_clear_shelf_action ? document.getElementById('circStrings').getString('staff.circ.utils.hold_post_clear_shelf_action.' + my.post_clear_shelf_action) : '';
1643             }
1644         },
1645         {
1646             'persist' : 'hidden width ordinal',
1647             'id' : 'cancel_time',
1648             'label' : document.getElementById('circStrings').getString('staff.circ.utils.hold_cancel_time'),
1649             'flex' : 1,
1650             'sort_type' : 'date',
1651             'primary' : false,
1652             'hidden' : true,
1653             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.ahr.cancel_time(), '%{localized}' ); }
1654         },
1655         {
1656             'persist' : 'hidden width ordinal',
1657             'id' : 'cancel_cause',
1658             'label' : document.getElementById('circStrings').getString('staff.circ.utils.hold_cancel_cause'),
1659             'flex' : 1,
1660             'primary' : false,
1661             'hidden' : true,
1662             'editable' : false, 'render' : function(my) { return typeof my.ahr.cancel_cause == 'object' ? my.ahr.cancel_cause().label() : data.hash.ahrcc[ my.ahr.cancel_cause() ].label(); }
1663         },
1664         {
1665             'persist' : 'hidden width ordinal',
1666             'id' : 'cancel_note',
1667             'label' : document.getElementById('circStrings').getString('staff.circ.utils.hold_cancel_note'),
1668             'flex' : 1,
1669             'primary' : false,
1670             'hidden' : true,
1671             'editable' : false, 'render' : function(my) { return my.ahr.cancel_note(); }
1672         },
1673         {
1674             'persist' : 'hidden width ordinal',
1675             'id' : 'request_lib',
1676             'label' : document.getElementById('circStrings').getString('staff.circ.utils.request_lib'),
1677             'flex' : 1,
1678             'primary' : false,
1679             'hidden' : true,
1680             'editable' : false, 'render' : function(my) {
1681                 if (Number(my.ahr.request_lib())>=0) {
1682                     return data.hash.aou[ my.ahr.request_lib() ].name();
1683                 } else {
1684                     return my.ahr.request_lib().name();
1685                 }
1686             }
1687         },
1688         {
1689             'persist' : 'hidden width ordinal',
1690             'id' : 'request_lib_shortname',
1691             'label' : document.getElementById('circStrings').getString('staff.circ.utils.request_lib_shortname'),
1692             'flex' : 0,
1693             'primary' : false,
1694             'hidden' : true,
1695             'editable' : false, 'render' : function(my) {
1696                 if (Number(my.ahr.request_lib())>=0) {
1697                     return data.hash.aou[ my.ahr.request_lib() ].shortname();
1698                 } else {
1699                     return my.ahr.request_lib().shortname();
1700                 }
1701             }
1702         },
1703         {
1704             'persist' : 'hidden width ordinal',
1705             'id' : 'request_time',
1706             'label' : document.getElementById('circStrings').getString('staff.circ.utils.request_time'),
1707             'flex' : 0,
1708             'sort_type' : 'date',
1709             'primary' : false,
1710             'hidden' : true,
1711             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.ahr.request_time(), '%{localized}' ); }
1712         },
1713         {
1714             'persist' : 'hidden width ordinal',
1715             'id' : 'shelf_time',
1716             'label' : document.getElementById('circStrings').getString('staff.circ.utils.holds.shelf_time'),
1717             'flex' : 0,
1718             'sort_type' : 'date',
1719             'primary' : false,
1720             'hidden' : true,
1721             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.ahr.shelf_time(), '%{localized}' ); }
1722         },
1723         {
1724             'persist' : 'hidden width ordinal',
1725             'id' : 'shelf_expire_time',
1726             'label' : document.getElementById('circStrings').getString('staff.circ.utils.holds.shelf_expire_time'),
1727             'flex' : 0,
1728             'sort_type' : 'date',
1729             'primary' : false,
1730             'hidden' : true,
1731             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.ahr.shelf_expire_time(), '%{localized}' ); }
1732         },
1733         {
1734             'persist' : 'hidden width ordinal',
1735             'id' : 'available_time',
1736             'label' : document.getElementById('circStrings').getString('staff.circ.utils.available_time'),
1737             'flex' : 1,
1738             'sort_type' : 'date',
1739             'primary' : false,
1740             'hidden' : false,
1741             'editable' : false, 'render' : function(my) {
1742                 if (my.ahr.transit() && my.ahr.transit().dest_recv_time()) {
1743                     return util.date.formatted_date( my.ahr.transit().dest_recv_time(), '%{localized}' );
1744                 }
1745                 if (!my.ahr.transit() && my.ahr.capture_time()) {
1746                     return util.date.formatted_date( my.ahr.capture_time(), '%{localized}' );
1747                 }
1748                 return "";
1749             }
1750         },
1751         {
1752             'persist' : 'hidden width ordinal',
1753             'id' : 'capture_time',
1754             'label' : document.getElementById('circStrings').getString('staff.circ.utils.capture_time'),
1755             'flex' : 1,
1756             'sort_type' : 'date',
1757             'primary' : false,
1758             'hidden' : true,
1759             'editable' : false, 'render' : function(my) { return my.ahr.capture_time() ? util.date.formatted_date( my.ahr.capture_time(), '%{localized}' ) : ""; }
1760         },
1761         {
1762             'persist' : 'hidden width ordinal',
1763             'id' : 'ahr_status',
1764             'label' : document.getElementById('commonStrings').getString('staff.ahr_status_label'),
1765             'flex' : 1,
1766             'primary' : false,
1767             'hidden' : false,
1768             'editable' : false, 'render' : function(my) {
1769                 switch (Number(my.status)) {
1770                     case 1:
1771                         return document.getElementById('circStrings').getString('staff.circ.utils.hold_status.1');
1772                         break;
1773                     case 2:
1774                         return document.getElementById('circStrings').getString('staff.circ.utils.hold_status.2');
1775                         break;
1776                     case 3:
1777                         return document.getElementById('circStrings').getString('staff.circ.utils.hold_status.3');
1778                         break;
1779                     case 4:
1780                         return document.getElementById('circStrings').getString('staff.circ.utils.hold_status.4');
1781                         break;
1782                     case 5:
1783                         return document.getElementById('circStrings').getString('staff.circ.utils.hold_status.5');
1784                         break;
1785                     case 6:
1786                         return document.getElementById('circStrings').getString('staff.circ.utils.hold_status.6');
1787                         break;
1788                     default:
1789                         return my.status;
1790                         break;
1791                 };
1792             }
1793         },
1794         {
1795             'persist' : 'hidden width ordinal',
1796             'id' : 'hold_type',
1797             'label' : document.getElementById('commonStrings').getString('staff.ahr_hold_type_label'),
1798             'flex' : 0,
1799             'primary' : false,
1800             'hidden' : true,
1801             'editable' : false, 'render' : function(my) { return my.ahr.hold_type(); }
1802         },
1803         {
1804             'persist' : 'hidden width ordinal',
1805             'id' : 'ahr_mint_condition',
1806             'label' : document.getElementById('circStrings').getString('staff.circ.utils.ahr_mint_condition'),
1807             'flex' : 0,
1808             'primary' : false,
1809             'hidden' : true,
1810             'editable' : false, 'render' : function(my) {
1811                 if (get_bool( my.ahr.mint_condition() )) {
1812                     return document.getElementById('circStrings').getString('staff.circ.utils.ahr_mint_condition.true');
1813                 } else {
1814                     return document.getElementById('circStrings').getString('staff.circ.utils.ahr_mint_condition.false');
1815                 }
1816             }
1817         },
1818         {
1819             'persist' : 'hidden width ordinal',
1820             'id' : 'frozen',
1821             'label' : document.getElementById('circStrings').getString('staff.circ.utils.active'),
1822             'flex' : 0,
1823             'primary' : false,
1824             'hidden' : true,
1825             'editable' : false, 'render' : function(my) {
1826                 if (!get_bool( my.ahr.frozen() )) {
1827                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
1828                 } else {
1829                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
1830                 }
1831             }
1832         },
1833         {
1834             'persist' : 'hidden width ordinal',
1835             'id' : 'thaw_date',
1836             'label' : document.getElementById('circStrings').getString('staff.circ.utils.thaw_date'),
1837             'flex' : 0,
1838             'sort_type' : 'date',
1839             'primary' : false,
1840             'hidden' : true,
1841             'editable' : false, 'render' : function(my) {
1842                 if (my.ahr.thaw_date() == null) {
1843                     return document.getElementById('circStrings').getString('staff.circ.utils.thaw_date.none');
1844                 } else {
1845                     return util.date.formatted_date( my.ahr.thaw_date(), '%{localized}' );
1846                 }
1847             }
1848         },
1849         {
1850             'persist' : 'hidden width ordinal',
1851             'id' : 'pickup_lib',
1852             'label' : document.getElementById('circStrings').getString('staff.circ.utils.pickup_lib'),
1853             'flex' : 1,
1854             'primary' : false,
1855             'hidden' : true,
1856             'editable' : false, 'render' : function(my) {
1857                 if (Number(my.ahr.pickup_lib())>=0) {
1858                     return data.hash.aou[ my.ahr.pickup_lib() ].name();
1859                 } else {
1860                     return my.ahr.pickup_lib().name();
1861                 }
1862             }
1863         },
1864         {
1865             'persist' : 'hidden width ordinal',
1866             'id' : 'pickup_lib_shortname',
1867             'label' : document.getElementById('commonStrings').getString('staff.ahr_pickup_lib_label'),
1868             'flex' : 0,
1869             'primary' : false,
1870             'hidden' : true,
1871             'editable' : false, 'render' : function(my) {
1872                 if (Number(my.ahr.pickup_lib())>=0) {
1873                     return data.hash.aou[ my.ahr.pickup_lib() ].shortname();
1874                 } else {
1875                     return my.ahr.pickup_lib().shortname();
1876                 }
1877             }
1878         },
1879         {
1880             'persist' : 'hidden width ordinal',
1881             'id' : 'current_copy',
1882             'label' : document.getElementById('commonStrings').getString('staff.ahr_current_copy_label'),
1883             'flex' : 1,
1884             'primary' : false,
1885             'hidden' : true,
1886             'editable' : false, 'render' : function(my) {
1887                 if (my.acp) {
1888                     return my.acp.barcode();
1889                 } else {
1890                     return document.getElementById('circStrings').getString('staff.circ.utils.current_copy.none');
1891                 }
1892             }
1893         },
1894         {
1895             'persist' : 'hidden width ordinal',
1896             'id' : 'current_copy_location',
1897             'label' : document.getElementById('commonStrings').getString('staff.ahr_current_copy_location_label'),
1898             'flex' : 1,
1899             'primary' : false,
1900             'hidden' : true,
1901             'editable' : false, 'render' : function(my) {
1902                 if (!my.acp) { return ""; } else { if (Number(my.acp.location())>=0) return data.lookup("acpl", my.acp.location() ).name(); else return my.acp.location().name(); }
1903             }
1904         },
1905         {
1906             'persist' : 'hidden width ordinal',
1907             'id' : 'email_notify',
1908             'label' : document.getElementById('commonStrings').getString('staff.ahr_email_notify_label'),
1909             'flex' : 1,
1910             'primary' : false,
1911             'hidden' : true,
1912             'editable' : false, 'render' : function(my) {
1913                 if (get_bool(my.ahr.email_notify())) {
1914                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
1915                 } else {
1916                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
1917                 }
1918             }
1919         },
1920         {
1921             'persist' : 'hidden width ordinal',
1922             'id' : 'expire_date',
1923             'label' : document.getElementById('commonStrings').getString('staff.ahr_expire_date_label'),
1924             'flex' : 1,
1925             'sort_type' : 'date',
1926             'primary' : false,
1927             'hidden' : true,
1928             'editable' : false, 'render' : function(my) { return my.ahr.expire_time() ? util.date.formatted_date( my.ahr.expire_time(), '%{localized}' ) : ''; }
1929         },
1930         {
1931             'persist' : 'hidden width ordinal',
1932             'id' : 'fulfillment_time',
1933             'label' : document.getElementById('commonStrings').getString('staff.ahr_fulfillment_time_label'),
1934             'flex' : 1,
1935             'sort_type' : 'date',
1936             'primary' : false,
1937             'hidden' : true,
1938             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.ahr.fulfillment_time(), '%{localized}' ); }
1939         },
1940         {
1941             'persist' : 'hidden width ordinal',
1942             'id' : 'holdable_formats',
1943             'label' : document.getElementById('commonStrings').getString('staff.ahr_holdable_formats_label'),
1944             'flex' : 1,
1945             'primary' : false,
1946             'hidden' : true,
1947             'editable' : false, 'render' : function(my) { return my.ahr.holdable_formats(); }
1948         },
1949         {
1950             'persist' : 'hidden width ordinal',
1951             'id' : 'holdable_part',
1952             'label' : document.getElementById('commonStrings').getString('staff.ahr_holdable_part_label'),
1953             'flex' : 1,
1954             'primary' : false,
1955             'hidden' : true,
1956             'editable' : false, 'render' : function(my) { return my.part.label(); }
1957         },
1958         {
1959             'persist' : 'hidden width ordinal',
1960             'id' : 'issuance_label',
1961             'label' : document.getElementById('commonStrings').getString('staff.ahr_issuance_label_label'),
1962             'flex' : 1,
1963             'primary' : false,
1964             'hidden' : true,
1965             'editable' : false, 'render' : function(my) { return my.issuance.label(); }
1966         },
1967         {
1968             'persist' : 'hidden width ordinal',
1969             'id' : 'ahr_id',
1970             'label' : document.getElementById('commonStrings').getString('staff.ahr_id_label'),
1971             'flex' : 1,
1972             'primary' : false,
1973             'hidden' : true,
1974             'editable' : false, 'render' : function(my) { return my.ahr.id(); }
1975         },
1976         {
1977             'persist' : 'hidden width ordinal',
1978             'id' : 'phone_notify',
1979             'label' : document.getElementById('commonStrings').getString('staff.ahr_phone_notify_label'),
1980             'flex' : 1,
1981             'primary' : false,
1982             'hidden' : true,
1983             'editable' : false, 'render' : function(my) { return my.ahr.phone_notify(); }
1984         },
1985         {
1986             'persist' : 'hidden width ordinal',
1987             'id' : 'prev_check_time',
1988             'label' : document.getElementById('commonStrings').getString('staff.ahr_prev_check_time_label'),
1989             'flex' : 1,
1990             'sort_type' : 'date',
1991             'primary' : false,
1992             'hidden' : true,
1993             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.ahr.prev_check_time(), '%{localized}' ); }
1994         },
1995         {
1996             'persist' : 'hidden width ordinal',
1997             'id' : 'requestor',
1998             'label' : document.getElementById('commonStrings').getString('staff.ahr_requestor_label'),
1999             'flex' : 1,
2000             'primary' : false,
2001             'hidden' : true,
2002             'editable' : false, 'render' : function(my) { return my.ahr.requestor(); }
2003         },
2004         {
2005             'persist' : 'hidden width ordinal',
2006             'id' : 'selection_depth',
2007             'label' : document.getElementById('commonStrings').getString('staff.ahr_selection_depth_label'),
2008             'flex' : 1,
2009             'primary' : false,
2010             'hidden' : true,
2011             'editable' : false, 'render' : function(my) { return my.ahr.selection_depth(); }
2012         },
2013         {
2014             'persist' : 'hidden width ordinal',
2015             'id' : 'top_of_queue',
2016             'label' : document.getElementById('commonStrings').getString('staff.ahr_top_of_queue_label'),
2017             'flex' : 1,
2018             'primary' : false,
2019             'hidden' : true,
2020             'editable' : false, 'render' : function(my) { return get_bool( my.ahr.cut_in_line() ) ? document.getElementById('commonStrings').getString('common.yes') : document.getElementById('commonStrings').getString('common.no') ; }
2021         },
2022         {
2023             'persist' : 'hidden width ordinal',
2024             'id' : 'target',
2025             'label' : document.getElementById('commonStrings').getString('staff.ahr_target_label'),
2026             'flex' : 1,
2027             'primary' : false,
2028             'hidden' : true,
2029             'editable' : false, 'render' : function(my) { return my.ahr.target(); }
2030         },
2031         {
2032             'persist' : 'hidden width ordinal',
2033             'id' : 'usr',
2034             'label' : document.getElementById('commonStrings').getString('staff.ahr_usr_label'),
2035             'flex' : 1,
2036             'primary' : false,
2037             'hidden' : true,
2038             'editable' : false, 'render' : function(my) { return my.ahr.usr(); }
2039         },
2040         {
2041             'persist' : 'hidden width ordinal',
2042             'id' : 'title',
2043             'label' : document.getElementById('commonStrings').getString('staff.mvr_label_title'),
2044             'flex' : 1,
2045             'sort_type' : 'title',
2046             'primary' : false,
2047             'hidden' : true,
2048             'editable' : false, 'render' : function(my) {
2049                 if (my.mvr) {
2050                     return my.mvr.title();
2051                 } else {
2052                     return document.getElementById('circStrings').getString('staff.circ.utils.title.none');
2053                 }
2054             }
2055         },
2056         {
2057             'persist' : 'hidden width ordinal',
2058             'id' : 'author',
2059             'label' : document.getElementById('commonStrings').getString('staff.mvr_label_author'),
2060             'flex' : 1,
2061             'primary' : false,
2062             'hidden' : true,
2063             'editable' : false, 'render' : function(my) {
2064                 if (my.mvr) {
2065                     return my.mvr.author();
2066                 } else {
2067                     return document.getElementById('circStrings').getString('staff.circ.utils.author.none');
2068                 }
2069             }
2070         },
2071         {
2072             'persist' : 'hidden width ordinal',
2073             'id' : 'edition',
2074             'label' : document.getElementById('circStrings').getString('staff.circ.utils.edition'),
2075             'flex' : 1,
2076             'primary' : false,
2077             'hidden' : true,
2078             'editable' : false, 'render' : function(my) { return my.mvr.edition(); }
2079         },
2080         {
2081             'persist' : 'hidden width ordinal',
2082             'id' : 'isbn',
2083             'label' : document.getElementById('circStrings').getString('staff.circ.utils.isbn'),
2084             'flex' : 1,
2085             'primary' : false,
2086             'hidden' : true,
2087             'editable' : false, 'render' : function(my) { return my.mvr.isbn(); }
2088         },
2089         {
2090             'persist' : 'hidden width ordinal',
2091             'id' : 'pubdate',
2092             'label' : document.getElementById('circStrings').getString('staff.circ.utils.pubdate'),
2093             'flex' : 1,
2094             'primary' : false,
2095             'hidden' : true,
2096             'editable' : false, 'render' : function(my) { return my.mvr.pubdate(); }
2097         },
2098         {
2099             'persist' : 'hidden width ordinal',
2100             'id' : 'publisher',
2101             'label' : document.getElementById('circStrings').getString('staff.circ.utils.publisher'),
2102             'flex' : 1,
2103             'primary' : false,
2104             'hidden' : true,
2105             'editable' : false, 'render' : function(my) { return my.mvr.publisher(); }
2106         },
2107         {
2108             'persist' : 'hidden width ordinal',
2109             'id' : 'tcn',
2110             'label' : document.getElementById('circStrings').getString('staff.circ.utils.tcn'),
2111             'flex' : 1,
2112             'primary' : false,
2113             'hidden' : true,
2114             'editable' : false, 'render' : function(my) { return my.mvr.tcn(); }
2115         },
2116         {
2117             'persist' : 'hidden width ordinal',
2118             'id' : 'notify_time',
2119             'label' : document.getElementById('circStrings').getString('staff.circ.utils.notify_time'),
2120             'flex' : 1,
2121             'sort_type' : 'date',
2122             'primary' : false,
2123             'hidden' : true,
2124             'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.ahr.notify_time(), '%{localized}' ); }
2125         },
2126         {
2127             'persist' : 'hidden width ordinal',
2128             'id' : 'notify_count',
2129             'label' : document.getElementById('circStrings').getString('staff.circ.utils.notify_count'),
2130             'flex' : 1,
2131             'primary' : false,
2132             'hidden' : true,
2133             'editable' : false, 'render' : function(my) { return my.ahr.notify_count(); }
2134         },
2135         {
2136             'persist' : 'hidden width ordinal',
2137             'id' : 'transit_source',
2138             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_source'),
2139             'flex' : 1,
2140             'primary' : false,
2141             'hidden' : true,
2142             'editable' : false, 'render' : function(my) {
2143                 if (my.ahr.transit()) {
2144                     return data.hash.aou[ my.ahr.transit().source() ].shortname();
2145                 } else {
2146                     return "";
2147                 }
2148             }
2149         },
2150         {
2151             'persist' : 'hidden width ordinal',
2152             'id' : 'transit_source_send_time',
2153             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_source_send_time'),
2154             'flex' : 1,
2155             'sort_type' : 'date',
2156             'primary' : false,
2157             'hidden' : true,
2158             'editable' : false, 'render' : function(my) { return my.ahr.transit() ?  util.date.formatted_date( my.ahr.transit().source_send_time(), '%{localized}' ) : ""; }
2159         },
2160         {
2161             'persist' : 'hidden width ordinal',
2162             'id' : 'transit_dest_lib',
2163             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_dest'),
2164             'flex' : 1,
2165             'primary' : false,
2166             'hidden' : true,
2167             'editable' : false, 'render' : function(my) { return my.ahr.transit() ?  data.hash.aou[ my.ahr.transit().dest() ].shortname() : ""; }
2168         },
2169         {
2170             'persist' : 'hidden width ordinal',
2171             'id' : 'transit_dest_recv_time',
2172             'label' : document.getElementById('circStrings').getString('staff.circ.utils.transit_dest_recv_time'),
2173             'flex' : 1,
2174             'sort_type' : 'date',
2175             'primary' : false,
2176             'hidden' : true,
2177             'editable' : false, 'render' : function(my) { return my.ahr.transit() ?  util.date.formatted_date( my.ahr.transit().dest_recv_time(), '%{localized}' ) : ""; }
2178         },
2179         {
2180             'persist' : 'hidden width ordinal',
2181             'id' : 'patron_barcode',
2182             'label' : document.getElementById('circStrings').getString('staff.circ.utils.offline.patron_barcode'),
2183             'flex' : 1,
2184             'primary' : false,
2185             'hidden' : true,
2186             'editable' : false, 'render' : function(my) { return my.patron_barcode ? my.patron_barcode : ""; }
2187         },
2188         {
2189             'persist' : 'hidden width ordinal',
2190             'id' : 'patron_family_name',
2191             'label' : document.getElementById('circStrings').getString('staff.circ.utils.patron_family_name'),
2192             'flex' : 1,
2193             'primary' : false,
2194             'hidden' : true,
2195             'editable' : false, 'render' : function(my) { return my.patron_family_name ? my.patron_family_name : ""; }
2196         },
2197         {
2198             "persist": "hidden width ordinal",
2199             "id": "patron_alias",
2200             'label' : document.getElementById('circStrings').getString('staff.circ.utils.patron_alias'),
2201             'flex' : 1,
2202             'primary' : false,
2203             'hidden' : true,
2204             'editable' : false, 'render' : function(my) { return my.patron_alias ? my.patron_alias : ""; }
2205         },
2206         {
2207             'persist' : 'hidden width ordinal',
2208             'id' : 'patron_first_given_name',
2209             'label' : document.getElementById('circStrings').getString('staff.circ.utils.patron_first_given_name'),
2210             'flex' : 1,
2211             'primary' : false,
2212             'hidden' : true,
2213             'editable' : false, 'render' : function(my) { return my.patron_first_given_name ? my.patron_first_given_name : ""; }
2214         },
2215         {
2216             'persist' : 'hidden width ordinal',
2217             'id' : 'callnumber',
2218             'label' : document.getElementById('circStrings').getString('staff.circ.utils.callnumber'),
2219             'flex' : 1,
2220             'primary' : false,
2221             'hidden' : true,
2222             'editable' : false, 'render' : function(my) { return my.acn.label(); }
2223         },
2224                 {
2225             'persist' : 'hidden width ordinal',
2226             'id' : 'total_holds',
2227             'label' : document.getElementById('circStrings').getString('staff.circ.utils.total_holds'),
2228             'flex' : 1,
2229             'primary' : false,
2230             'hidden' : true,
2231             'editable' : false, 'render' : function(my) { return my.total_holds; }
2232         },
2233                 {
2234             'persist' : 'hidden width ordinal',
2235             'id' : 'queue_position',
2236             'label' : document.getElementById('circStrings').getString('staff.circ.utils.queue_position'),
2237             'flex' : 1,
2238             'primary' : false,
2239             'hidden' : true,
2240             'editable' : false, 'render' : function(my) { return my.queue_position; }
2241         },
2242                 {
2243             'persist' : 'hidden width ordinal',
2244             'id' : 'potential_copies',
2245             'label' : document.getElementById('circStrings').getString('staff.circ.utils.potential_copies'),
2246             'flex' : 1,
2247             'primary' : false,
2248             'hidden' : true,
2249             'editable' : false, 'render' : function(my) { return my.potential_copies; }
2250         },
2251                 {
2252             'persist' : 'hidden width ordinal',
2253             'id' : 'estimated_wait',
2254             'label' : document.getElementById('circStrings').getString('staff.circ.utils.estimated_wait'),
2255             'flex' : 1,
2256             'primary' : false,
2257             'hidden' : true,
2258             'editable' : false, 'render' : function(my) { return my.estimated_wait; }
2259         },
2260         {
2261             'persist' : 'hidden width ordinal',
2262             'id' : 'hold_note',
2263             'label' : document.getElementById('circStrings').getString('staff.circ.utils.hold_note'),
2264             'flex' : 1,
2265             'primary' : false,
2266             'hidden' : true,
2267             'editable' : false, 'render' : function(my) { return my.ahrn_count; }
2268         },
2269         {
2270             'persist' : 'hidden width ordinal',
2271             'id' : 'staff_hold',
2272             'label' : document.getElementById('circStrings').getString('staff.circ.utils.staff_hold'),
2273             'flex' : 1,
2274             'primary' : false,
2275             'hidden' : true,
2276             'editable' : false, 
2277             'render' : function(my) {
2278                 if (my.ahr.usr() != my.ahr.requestor()){
2279                     return document.getElementById('circStrings').getString('staff.circ.utils.yes');
2280                 } else {
2281                     return document.getElementById('circStrings').getString('staff.circ.utils.no');
2282                 }
2283             }
2284         }
2285     ];
2286     for (var i = 0; i < c.length; i++) {
2287         if (modify[ c[i].id ]) {
2288             for (var j in modify[ c[i].id ]) {
2289                 c[i][j] = modify[ c[i].id ][j];
2290             }
2291         }
2292     }
2293     if (params) {
2294         if (params.just_these) {
2295             JSAN.use('util.functional');
2296             var new_c = [];
2297             for (var i = 0; i < params.just_these.length; i++) {
2298                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
2299                 new_c.push( function(y){ return y; }( x ) );
2300             }
2301             c = new_c;
2302         }
2303         if (params.except_these) {
2304             JSAN.use('util.functional');
2305             var new_c = [];
2306             for (var i = 0; i < c.length; i++) {
2307                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
2308                 if (!x) new_c.push(c[i]);
2309             }
2310             c = new_c;
2311         }
2312
2313     }
2314     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
2315 };
2316 /*
2317 circ.util.std_map_row_to_column = function(error_value) {
2318     return function(row,col) {
2319         // row contains { 'my' : { 'acp' : {}, 'circ' : {}, 'mvr' : {} } }
2320         // col contains one of the objects listed above in columns
2321
2322         // mimicking some of the obj in circ.checkin and circ.checkout where map_row_to_column is usually defined
2323         var obj = {};
2324         JSAN.use('util.error'); obj.error = new util.error();
2325         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
2326         JSAN.use('util.network'); obj.network = new util.network();
2327         JSAN.use('util.money');
2328
2329         var my = row.my;
2330         var value;
2331         try {
2332             value = eval( col.render );
2333         } catch(E) {
2334             obj.error.sdump('D_WARN','map_row_to_column: ' + E);
2335             if (error_value) value = error_value; else value = '   ';
2336         }
2337         return value;
2338     }
2339 };
2340 */
2341 circ.util.std_map_row_to_columns = function(error_value) {
2342     return function(row,cols,scratch) {
2343         // row contains { 'my' : { 'acp' : {}, 'circ' : {}, 'mvr' : {} } }
2344         // cols contains all of the objects listed above in columns
2345         // scratch is a temporary space shared by all cells/rows (or just per row if not explicitly passed in)
2346         if (!scratch) { scratch = {}; }
2347
2348         var obj = {};
2349         JSAN.use('util.error'); obj.error = new util.error();
2350         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
2351         JSAN.use('util.network'); obj.network = new util.network();
2352         JSAN.use('util.money');
2353
2354         var my = row.my;
2355         var values = [];
2356         var cmd = '';
2357         try {
2358             for (var i = 0; i < cols.length; i++) {
2359                 switch (typeof cols[i].render) {
2360                     case 'function': try { values[i] = cols[i].render(my,scratch); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
2361                     case 'string' : cmd += 'try { ' + cols[i].render + '; values['+i+'] = v; } catch(E) { values['+i+'] = error_value; }'; break;
2362                     default: cmd += 'values['+i+'] = "??? '+(typeof cols[i].render)+'"; ';
2363                 }
2364             }
2365             if (cmd) eval( cmd );
2366         } catch(E) {
2367             obj.error.sdump('D_WARN','map_row_to_column: ' + E);
2368             if (error_value) { value = error_value; } else { value = '   ' };
2369         }
2370         return values;
2371     }
2372 };
2373
2374 circ.util.checkin_via_barcode = function(session,params,backdate,auto_print,async) {
2375     try {
2376         JSAN.use('util.error'); var error = new util.error();
2377         JSAN.use('util.network'); var network = new util.network();
2378         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
2379         JSAN.use('util.date'); JSAN.use('util.functional');
2380
2381         if (backdate && (backdate == util.date.formatted_date(new Date(),'%Y-%m-%d')) ) backdate = null;
2382
2383         //var params = { 'barcode' : barcode };
2384         if (backdate) params.backdate = util.date.formatted_date(backdate,'%{iso8601}');
2385
2386         if (typeof params.disable_textbox == 'function') {
2387             try { params.disable_textbox(); }
2388             catch(E) { error.sdump('D_ERROR','params.disable_textbox() = ' + E); };
2389         }
2390
2391         function checkin_callback(req) {
2392             JSAN.use('util.error'); var error = new util.error();
2393             try {
2394                 var check = req.getResultObject();
2395                 var r = circ.util.checkin_via_barcode2(session,params,backdate,auto_print,check);
2396                 try {
2397                     error.work_log(
2398                         document.getElementById('circStrings').getFormattedString(
2399                             'staff.circ.work_log_checkin_attempt.' + r.what_happened + '.message',
2400                             [
2401                                 ses('staff_usrname'),
2402                                 r.payload.patron ? r.payload.patron.family_name() : '',
2403                                 r.payload.patron ? r.payload.patron.card().barcode() : '',
2404                                 r.payload.copy ? r.payload.copy.barcode() : '',
2405                                 r.route_to ? r.route_to : ''
2406                             ]
2407                         ), {
2408                             'au_id' : r.payload.patron ? r.payload.patron.id() : '',
2409                             'au_family_name' : r.payload.patron ? r.payload.patron.family_name() : '',
2410                             'au_barcode' : r.payload.patron ? r.payload.patron.card().barcode() : '',
2411                             'acp_barcode' : r.payload.copy ? r.payload.copy.barcode() : ''
2412                         }
2413                     );
2414                 } catch(E) {
2415                     error.sdump('D_ERROR','Error with work_logging in server/circ/checkout.js, _checkout:' + E);
2416                 }
2417
2418                 if (typeof params.checkin_result == 'function') {
2419                     try { params.checkin_result(r); } catch(E) { error.sdump('D_ERROR','params.checkin_result() = ' + E); };
2420                 }
2421                 if (typeof async == 'function') async(check);
2422                 return check;
2423             } catch(E) {
2424                 error.standard_unexpected_error_alert(document.getElementById('circStrings').getFormattedString('staff.circ.checkin.error', ['1']), E);
2425                 if (typeof params.enable_textbox == 'function') {
2426                     try { params.enable_textbox(); }
2427                     catch(E) { error.sdump('D_ERROR','params.disable_textbox() = ' + E); };
2428                 }
2429                 return null;
2430             }
2431         }
2432
2433         var suppress_popups = data.hash.aous['ui.circ.suppress_checkin_popups'];
2434
2435         var check = network.request(
2436             api.CHECKIN_VIA_BARCODE.app,
2437             api.CHECKIN_VIA_BARCODE.method,
2438             [ session, util.functional.filter_object( params, function(i,o) { return typeof o != 'function'; } ) ],
2439             async ? checkin_callback : null,
2440             {
2441                 'title' : document.getElementById('circStrings').getString('staff.circ.utils.checkin.override'),
2442                 'auto_override_these_events' : suppress_popups ? [
2443                     null /* custom event */,
2444                     1203 /* COPY_BAD_STATUS */,
2445                     1213 /* PATRON_BARRED */,
2446                     1217 /* PATRON_INACTIVE */,
2447                     1224 /* PATRON_ACCOUNT_EXPIRED */,
2448                     1234 /* ITEM_DEPOSIT_PAID */,
2449                     7009 /* CIRC_CLAIMS_RETURNED */,
2450                     7010 /* COPY_ALERT_MESSAGE */,
2451                     7011 /* COPY_STATUS_LOST */,
2452                     7012 /* COPY_STATUS_MISSING */,
2453                     7013 /* PATRON_EXCEEDS_FINES */
2454                 ] : [],
2455                 'overridable_events' : [
2456                     null /* custom event */,
2457                     1203 /* COPY_BAD_STATUS */,
2458                     1213 /* PATRON_BARRED */,
2459                     1217 /* PATRON_INACTIVE */,
2460                     1224 /* PATRON_ACCOUNT_EXPIRED */,
2461                     1234 /* ITEM_DEPOSIT_PAID */,
2462                     7009 /* CIRC_CLAIMS_RETURNED */,
2463                     7010 /* COPY_ALERT_MESSAGE */,
2464                     7011 /* COPY_STATUS_LOST */,
2465                     7012 /* COPY_STATUS_MISSING */,
2466                     7013 /* PATRON_EXCEEDS_FINES */
2467                 ],
2468                 'text' : {
2469                     '1203' : function(r) {
2470                         return typeof r.payload.status() == 'object' ? r.payload.status().name() : data.hash.ccs[ r.payload.status() ].name();
2471                     },
2472                     '1234' : function(r) {
2473                         return document.getElementById('circStrings').getString('staff.circ.utils.checkin.override.item_deposit_paid.warning');
2474                     },
2475                     '7010' : function(r) {
2476                         return r.payload;
2477                     }
2478                 }
2479             }
2480         );
2481         if (! async ) {
2482             return checkin_callback( { 'getResultObject' : function() { return check; } } );
2483         }
2484
2485
2486     } catch(E) {
2487         JSAN.use('util.error'); var error = new util.error();
2488         error.standard_unexpected_error_alert(document.getElementById('circStrings').getFormattedString('staff.circ.checkin.error', ['2']), E);
2489         if (typeof params.enable_textbox == 'function') {
2490             try { params.enable_textbox(); } catch(E) { error.sdump('D_ERROR','params.disable_textbox() = ' + E); };
2491         }
2492         return null;
2493     }
2494 };
2495
2496 circ.util.checkin_via_barcode2 = function(session,params,backdate,auto_print,check) {
2497     try {
2498         JSAN.use('util.error'); var error = new util.error();
2499         JSAN.use('util.network'); var network = new util.network();
2500         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
2501         JSAN.use('util.date');
2502         JSAN.use('util.sound'); var sound = new util.sound();
2503
2504         error.sdump('D_DEBUG','check = ' + error.pretty_print( js2JSON( check ) ) );
2505
2506         check.message = check.textcode;
2507
2508         if (check.payload && check.payload.copy) { check.copy = check.payload.copy; }
2509         if (check.payload && check.payload.record) { check.record = check.payload.record; }
2510         if (check.payload && check.payload.circ) { check.circ = check.payload.circ; }
2511         if (check.payload && check.payload.patron) { check.patron = check.payload.patron; }
2512
2513         if (!check.route_to) { check.route_to = '   '; }
2514
2515         var no_change_label = document.getElementById('no_change_label');
2516
2517         if (no_change_label) {
2518             no_change_label.setAttribute('value','');
2519             no_change_label.setAttribute('hidden','true');
2520             no_change_label.setAttribute('onclick','');
2521             removeCSSClass(no_change_label,'click_link');
2522             no_change_label.setAttribute('unique_row_counter','');
2523         }
2524
2525         var msg = '';
2526         var print_list = [];
2527         var print_data = { 
2528             'error' : '',
2529             'error_msg' : '',
2530             'cancelled' : '',
2531             'route_to' : '',
2532             'route_to_msg' : '',
2533             'route_to_org_fullname' : '',
2534             'destination_shelf' : '',
2535             'destination_shelf_msg' : '',
2536             'courier_code' : '',
2537             'street1' : '',
2538             'street2' : '',
2539             'city_state_zip' : '',
2540             'city' : '',
2541             'state' : '',
2542             'county' : '',
2543             'country' : '',
2544             'post_code' : '',
2545             'item_barcode' : '',
2546             'item_barcode_msg' : '',
2547             'item_title' : '',
2548             'item_title_msg' : '',
2549             'item_author' : '',
2550             'item_author_msg' : '',
2551             'hold_for_msg' : '',
2552             'hold_for_alias' : '',
2553             'hold_for_family_name' : '',
2554             'hold_for_first_given_name' : '',
2555             'hold_for_second_given_name' : '',
2556             'user_barcode' : '',
2557             'user_barcode_msg' : '',
2558             'notify_by_phone' : '',
2559             'notify_by_phone_msg' : '',
2560             'notify_by_email' : '',
2561             'notify_by_email_msg' : '',
2562             'request_date' : '',
2563             'request_date_msg' : '',
2564             'slip_date' : '',
2565             'slip_date_msg' : '',
2566             'user' : '',
2567             'user_stat_cat_entries' : ''
2568         };
2569
2570         if (check.payload && check.payload.cancelled_hold_transit) {
2571             print_data.cancelled = document.getElementById('circStrings').getString('staff.circ.utils.transit_hold_cancelled');
2572             msg += print_data.cancelled;
2573             msg += '\n\n';
2574         }
2575
2576         /* SUCCESS  /  NO_CHANGE  /  ITEM_NOT_CATALOGED */
2577         if (check.ilsevent == 0 || check.ilsevent == 3 || check.ilsevent == 1202) {
2578             try { check.route_to = data.lookup('acpl', check.copy.location() ).name(); }
2579             catch(E) {
2580                 print_data.error_msg = document.getElementById('commonStrings').getString('common.error');
2581                 print_data.error_msg += '\nFIXME: ' + E + '\n';
2582                 msg += print_data.error_msg;
2583             }
2584             if (check.ilsevent == 3 /* NO_CHANGE */) {
2585                 //msg = 'This item is already checked in.\n';
2586                 check.what_happened = 'no_change';
2587                 if (no_change_label) {
2588                     var m = no_change_label.getAttribute('value');
2589                     var text = document.getElementById('circStrings').getFormattedString('staff.circ.utils.item_checked_in', [params.barcode]);
2590                     no_change_label.setAttribute('value', m + text + '  ');
2591                     no_change_label.setAttribute('hidden','false');
2592                     no_change_label.setAttribute('onclick','');
2593                     removeCSSClass(no_change_label,'click_link');
2594                     no_change_label.setAttribute('unique_row_counter','');
2595                     if (typeof params.info_blurb == 'function') {
2596                         params.info_blurb( text );
2597                     }
2598                 }
2599             }
2600             if (check.ilsevent == 1202 /* ITEM_NOT_CATALOGED */ && check.copy.status() != 11) {
2601                 check.what_happened = 'error';
2602                 var copy_status = (data.hash.ccs[ check.copy.status() ] ? data.hash.ccs[ check.copy.status() ].name() : check.copy.status().name() );
2603                 var err_msg = document.getElementById('commonStrings').getString('common.error');
2604                 err_msg += '\nFIXME --';
2605                 err_msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.item_not_cataloged', [copy_status]);
2606                 err_msg += '\n';
2607                 msg += err_msg;
2608                 print_data.error_msg += err_msg;
2609             }
2610             switch(Number(check.copy.status())) {
2611                 case 0: /* AVAILABLE */
2612                 case 7: /* RESHELVING */
2613                     check.what_happened = 'success';
2614                     if (msg) {
2615                         print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2616                         print_data.route_to = check.route_to;
2617                         msg += print_data.route_to_msg;
2618                         msg += '\n';
2619                     }
2620                 break;
2621                 case 8: /* ON HOLDS SHELF */
2622                     check.what_happened = 'hold_shelf';
2623                     check.route_to = document.getElementById('circStrings').getString('staff.circ.route_to.hold_shelf');
2624                     if (check.payload.hold) {
2625                         if (check.payload.hold.pickup_lib() != data.list.au[0].ws_ou()) {
2626                             check.what_happened = 'error';
2627                             var err_msg = document.getElementById('commonStrings').getString('common.error');
2628                             err_msg += '\nFIXME: ';
2629                             err_msg += document.getElementById('circStrings').getString('staff.circ.utils.route_item_error');
2630                             err_msg += '\n';
2631                             msg += err_msg;
2632                             print_data.error_msg += err_msg;
2633                         } else {
2634                             print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2635                             print_data.route_to = check.route_to;
2636                             var behind_the_desk_support = String( data.hash.aous['circ.holds.behind_desk_pickup_supported'] ) == 'true';
2637                             if (behind_the_desk_support) {
2638                                var usr_settings = network.simple_request('FM_AUS_RETRIEVE',[ses(),check.payload.hold.usr()]); 
2639                                 if (typeof usr_settings['circ.holds_behind_desk'] != 'undefined') {
2640                                     if (usr_settings['circ.holds_behind_desk']) {
2641                                         print_data.prefer_behind_holds_desk = true;
2642                                         check.route_to = document.getElementById('circStrings').getString('staff.circ.route_to.private_hold_shelf');
2643                                         print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2644                                         print_data.route_to = check.route_to;
2645                                     } else {
2646                                         check.route_to = document.getElementById('circStrings').getString('staff.circ.route_to.public_hold_shelf');
2647                                         print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2648                                         print_data.route_to = check.route_to;
2649                                     }
2650                                 } else {
2651                                     check.route_to = document.getElementById('circStrings').getString('staff.circ.route_to.public_hold_shelf');
2652                                     print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2653                                     print_data.route_to = check.route_to;
2654                                 }
2655                             }
2656                             print_data.destination_shelf_msg = print_data.route_to_msg;
2657                             print_data.destination_shelf = print_data.route_to;
2658                             msg += print_data.route_to_msg;
2659                             msg += '\n';
2660                         }
2661                     } else {
2662                         check.what_happened = 'error';
2663                         var err_msg = document.getElementById('commonStrings').getString('common.error');
2664                         err_msg += '\nFIXME: ';
2665                         err_msg += document.getElementById('circStrings').getString('staff.circ.utils.route_item_status_error');
2666                         err_msg += '\n';
2667                         msg += err_msg;
2668                         print_data.error_msg += err_msg;
2669                     }
2670                     JSAN.use('util.date');
2671                     if (check.payload.hold) {
2672                         JSAN.use('patron.util');
2673                         msg += '\n';
2674                         print_data.item_barcode_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.barcode', [check.payload.copy.barcode()]);
2675                         print_data.item_barcode = check.payload.copy.barcode();
2676                         msg += print_data.item_barcode_msg;
2677                         msg += '\n';
2678                         var payload_title  = (check.payload.record ? check.payload.record.title() : check.payload.copy.dummy_title() );
2679                         print_data.item_title_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.title', [payload_title]);
2680                         print_data.item_title = payload_title;
2681                         msg += print_data.item_title_msg;
2682                         msg += '\n';
2683                         var au_obj = patron.util.retrieve_fleshed_au_via_id( session, check.payload.hold.usr() );
2684                         print_data.user = au_obj;
2685                         print_data.user_stat_cat_entries = [];
2686                         var entries = au_obj.stat_cat_entries();
2687                         for (var i = 0; i < entries.length; i++) {
2688                             var stat_cat = data.hash.my_actsc[ entries[i].stat_cat() ];
2689                             if (!stat_cat) {
2690                                 stat_cat = data.lookup('actsc', entries[i].stat_cat());
2691                             }
2692                             print_data.user_stat_cat_entries.push( { 
2693                                 'id' : entries[i].id(),
2694                                 'stat_cat' : {
2695                                     'id' : stat_cat.id(),
2696                                     'name' : stat_cat.name(),
2697                                     'opac_visible' : stat_cat.opac_visible(),
2698                                     'owner' : stat_cat.owner(),
2699                                     'usr_summary' : stat_cat.usr_summary()
2700                                 },
2701                                 'stat_cat_entry' : entries[i].stat_cat_entry(),
2702                                 'target_usr' : entries[i].target_usr() 
2703                             } );
2704                         }
2705                         msg += '\n';
2706                         if (au_obj.alias()) {
2707                             print_data.hold_for_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.patron_alias',  [au_obj.alias()]);
2708                             print_data.hold_for_alias = au_obj.alias();
2709                             msg += print_data.hold_for_msg;
2710                         } else {
2711                             print_data.hold_for_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.patron',  [au_obj.family_name() ? au_obj.family_name() : '', au_obj.first_given_name() ? au_obj.first_given_name() : '', au_obj.second_given_name() ? au_obj.second_given_name() : '']);
2712                             msg += print_data.hold_for_msg;
2713                             print_data.hold_for_family_name = au_obj.family_name() ? au_obj.family_name() : '';
2714                             print_data.hold_for_first_given_name = au_obj.first_given_name() ? au_obj.first_given_name() : '';
2715                             print_data.hold_for_second_given_name = au_obj.second_given_name() ? au_obj.second_given_name() : '';
2716                         }
2717                         msg += '\n';
2718                         print_data.user_barcode_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.barcode', [au_obj.card().barcode()]);
2719                         print_data.user_barcode = au_obj.card().barcode();
2720                         msg += print_data.user_barcode_msg;
2721                         msg += '\n';
2722                         if (check.payload.hold.phone_notify()) {
2723                             print_data.notify_by_phone_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.phone_notify', [check.payload.hold.phone_notify()]);
2724                             print_data.notify_by_phone = check.payload.hold.phone_notify();
2725                             msg += print_data.notify_by_phone_msg;
2726                             msg += '\n';
2727                         }
2728                         if (get_bool(check.payload.hold.email_notify())) {
2729                             var payload_email = au_obj.email() ? au_obj.email() : '';
2730                             print_data.notify_by_email_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.email_notify', [payload_email]);
2731                             print_data.notify_by_email = payload_email;
2732                             msg += print_data.notify_by_email_msg;
2733                             msg += '\n';
2734                         }
2735                         msg += '\n';
2736                         var notes = check.payload.hold.notes();
2737                         print_data.notes_raw = notes;
2738                         for (var i = 0; i < notes.length; i++) {
2739                             if ( get_bool( notes[i].slip() ) ) {
2740                                 var temp_msg;
2741                                 if ( get_bool( notes[i].staff() ) ) {
2742                                     temp_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.notes.staff_note', [ notes[i].title(), notes[i].body() ]);
2743                                 } else {
2744                                     temp_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.notes.patron_note', [ notes[i].title(), notes[i].body() ]);
2745                                 }
2746                                 msg += temp_msg + '\n';
2747                                 print_list.push(
2748                                     {
2749                                         'formatted_note' : temp_msg,
2750                                         'note_title' : notes[i].title(),
2751                                         'note_body' : notes[i].body(),
2752                                         'note_public' : notes[i].pub(),
2753                                         'note_by_staff' : notes[i].staff()
2754                                     }
2755                                 );
2756                             }
2757                         }
2758                         msg += '\n';
2759                         msg += '\n';
2760                         print_data.request_date = util.date.formatted_date(check.payload.hold.request_time(),'%F');
2761                         print_data.request_date_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.request_date', [print_data.request_date]);
2762                         msg += print_data.request_date_msg;
2763                         msg += '\n';
2764                     }
2765                     var rv = 0;
2766                     var suppress_popups = data.hash.aous['ui.circ.suppress_checkin_popups'];
2767                     if (suppress_popups) {
2768                         rv = auto_print ? 0 : -1; auto_print = true; // skip dialog and PRINT or DO NOT PRINT based on Auto-Print checkbox
2769                     }
2770                     var x = data.hash.aous['circ.staff_client.do_not_auto_attempt_print'];
2771                     var no_print_prompting = x ? ( x.indexOf( "Hold Slip" ) > -1) : false;
2772                     if (no_print_prompting) {
2773                         rv = -1; auto_print = true; // DO NOT PRINT and skip dialog
2774                     }
2775                     print_data.slip_date = util.date.formatted_date(new Date(),'%F');
2776                     print_data.slip_date_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.slip_date', [print_data.slip_date]);
2777                     msg += print_data.slip_date_msg;
2778                     msg += '\n';
2779                     print_data.payload = check.payload;
2780
2781                     if (!auto_print) {
2782                         rv = error.yns_alert_formatted(
2783                             msg,
2784                             document.getElementById('circStrings').getString('staff.circ.utils.hold_slip'),
2785                             document.getElementById('circStrings').getString('staff.circ.utils.hold_slip.print.yes'),
2786                             document.getElementById('circStrings').getString('staff.circ.utils.hold_slip.print.no'),
2787                             null,
2788                             document.getElementById('circStrings').getString('staff.circ.confirm.msg'),
2789                             '/xul/server/skin/media/images/turtle.gif'
2790                         );
2791                     } else {
2792                         if (suppress_popups && !no_print_prompting) {
2793                             // FIXME: Add SFX and/or GFX
2794                             sound.circ_bad();
2795                         }
2796                     }
2797                     if (rv == 0) {
2798                         try {
2799                             JSAN.use('util.print'); var print = new util.print();
2800                             var old_template = String( data.hash.aous['ui.circ.old_harcoded_slip_template'] ) == 'true';
2801                             if (old_template) {
2802                                 msg = msg.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g,'<br/>');
2803                                 print.simple( msg , { 'no_prompt' : true, 'content_type' : 'text/html' } );
2804                             } else {
2805                                 var template = 'hold_slip';
2806                                 var params = {
2807                                     'patron' : print_data.user,
2808                                     'lib' : data.hash.aou[ check.payload.hold.pickup_lib() ],
2809                                     'staff' : data.list.au[0],
2810                                     'header' : data.print_list_templates[ template ].header,
2811                                     'line_item' : data.print_list_templates[ template ].line_item,
2812                                     'footer' : data.print_list_templates[ template ].footer,
2813                                     'type' : data.print_list_templates[ template ].type,
2814                                     'list' : print_list,
2815                                     'data' : print_data
2816                                 };
2817                                 print.tree_list( params );
2818                             }
2819                         } catch(E) {
2820                             var err_msg = document.getElementById('commonStrings').getString('common.error');
2821                             err_msg += '\nFIXME: ' + E + '\n';
2822                             dump(err_msg);
2823                             alert(err_msg);
2824                         }
2825                     }
2826                     msg = '';
2827                     if (no_change_label) {
2828                         var m = no_change_label.getAttribute('value');
2829                         var text = document.getElementById('circStrings').getFormattedString('staff.circ.utils.capture', [params.barcode]);
2830                         m += text + '  ';
2831                         no_change_label.setAttribute('value', m);
2832                         no_change_label.setAttribute('hidden','false');
2833                         no_change_label.setAttribute('onclick','');
2834                         removeCSSClass(no_change_label,'click_link');
2835                         no_change_label.setAttribute('unique_row_counter','');
2836                         if (typeof params.info_blurb == 'function') {
2837                             params.info_blurb( text );
2838                         }
2839                     }
2840                 break;
2841                 case 6: /* IN TRANSIT */
2842                     check.what_happened = 'error';
2843                     check.route_to = 'TRANSIT SHELF??';
2844                     print_data.route_to;
2845                     var err_msg = document.getElementById('commonStrings').getString('common.error');
2846                     err_msg += "\nFIXME -- I didn't think we could get here.\n";
2847                     print_data.error_msg += err_msg;
2848                     msg += err_msg;
2849                 break;
2850                 case 11: /* CATALOGING */
2851                     check.what_happened = 'cataloging';
2852                     check.route_to = 'CATALOGING';
2853                     print_data.route_to;
2854                     var suppress_popups = data.hash.aous['ui.circ.suppress_checkin_popups'];
2855                     var x = document.getElementById('do_not_alert_on_precat');
2856                     var do_not_alert_on_precats = x ? ( x.getAttribute('checked') == 'true' ) : false;
2857                     if ( !suppress_popups && !do_not_alert_on_precats ) {
2858                         print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2859                         msg += print_data.route_to_msg;
2860                     } else {
2861                         if (suppress_popups && !do_not_alert_on_precats) {
2862                             // FIXME: add SFX and/or GFX
2863                             sound.circ_bad();
2864                         }
2865                     }
2866                     if (no_change_label) {
2867                         var m = no_change_label.getAttribute('value');
2868                         var needs_cat = document.getElementById('circStrings').getFormattedString('staff.circ.utils.needs_cataloging', [params.barcode]);
2869                         no_change_label.setAttribute('value', m + needs_cat + '  ');
2870                         no_change_label.setAttribute('hidden','false');
2871                         no_change_label.setAttribute('onclick','');
2872                         removeCSSClass(no_change_label,'click_link');
2873                         no_change_label.setAttribute('unique_row_counter','');
2874                         if (typeof params.info_blurb == 'function') {
2875                             params.info_blurb( needs_cat );
2876                         }
2877                     }
2878                 break;
2879                 case 15: // ON_RESERVATION_SHELF
2880                     check.route_to = 'RESERVATION SHELF';
2881                     check.what_happened = "reservation_shelf";
2882                     if (check.payload.reservation) {
2883                         if (check.payload.reservation.pickup_lib() != data.list.au[0].ws_ou()) {
2884                             msg += document.getElementById('commonStrings').getString('common.error');
2885                             msg += '\nFIXME: ';
2886                             msg += document.getElementById('circStrings').getString('staff.circ.utils.route_item_error');
2887                             msg += '\n';
2888                         } else {
2889                             msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2890                             msg += '.\n';
2891                         }
2892                     } else {
2893                         msg += document.getElementById('commonStrings').getString('common.error');
2894                         msg += '\nFIXME: ';
2895                         msg += document.getElementById('circStrings').getString('staff.circ.utils.reservation_status_error');
2896                         msg += '\n';
2897                     }
2898                     JSAN.use('util.date');
2899                     if (check.payload.reservation) {
2900                         JSAN.use('patron.util');
2901                         msg += '\n';
2902                         msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.barcode', [check.payload.copy.barcode()]);
2903                         msg += '\n';
2904                         var payload_title  = (check.payload.record ? check.payload.record.title() : check.payload.copy.dummy_title() );
2905                         msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.title', [payload_title]);
2906                         msg += '\n';
2907                         var au_obj =
2908                             typeof(check.payload.reservation.usr().card) == "function" ?
2909                                 check.payload.reservation.usr() :
2910                                 patron.util.retrieve_fleshed_au_via_id(session, check.payload.reservation.usr());
2911                         msg += '\n';
2912                         if (au_obj.alias()) {
2913                             msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.patron_alias',  [au_obj.alias()]);
2914                         } else {
2915                             msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.patron',  [au_obj.family_name() || "", au_obj.first_given_name() || "", au_obj.second_given_name() || ""]);
2916                         }
2917                         msg += '\n';
2918                         msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.barcode', [au_obj.card().barcode()]);
2919                         msg += '\n';
2920                         msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.request_date', [util.date.formatted_date(check.payload.reservation.request_time(),'%F %H:%M')]);
2921                         msg += '\n';
2922
2923                         msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.start_date', [util.date.formatted_date(check.payload.reservation.start_time(),'%F %H:%M')]);
2924                         msg += '\n';
2925                     }
2926                     var rv = 0;
2927                     msg += document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.reservation.slip_date', [util.date.formatted_date(new Date(),'%F')]);
2928                     msg += '\n';
2929                     if (!auto_print) {
2930                         rv = error.yns_alert_formatted(
2931                             msg,
2932                             document.getElementById('circStrings').getString('staff.circ.utils.reservation_slip'),
2933                             document.getElementById('circStrings').getString('staff.circ.utils.reservation_slip.print.yes'),
2934                             document.getElementById('circStrings').getString('staff.circ.utils.reservation_slip.print.no'),
2935                             null,
2936                             document.getElementById('circStrings').getString('staff.circ.confirm.msg'),
2937                             '/xul/server/skin/media/images/turtle.gif'
2938                         );
2939                     }
2940                     if (rv == 0) {
2941                         try {
2942                             JSAN.use('util.print'); var print = new util.print();
2943                             msg = msg.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g,'<br/>');
2944                             print.simple( msg , { 'no_prompt' : true, 'content_type' : 'text/html' } );
2945                         } catch(E) {
2946                             var err_msg = document.getElementById('commonStrings').getString('common.error');
2947                             err_msg += '\nFIXME: ' + E + '\n';
2948                             dump(err_msg);
2949                             alert(err_msg);
2950                         }
2951                     }
2952                     msg = '';
2953                     if (no_change_label) {
2954                         var m = no_change_label.getAttribute('value');
2955                         var text = document.getElementById('circStrings').getFormattedString('staff.circ.utils.reservation_capture', [params.barcode]);
2956                         m += text + '  ';
2957                         no_change_label.setAttribute('value', m);
2958                         no_change_label.setAttribute('hidden','false');
2959                         no_change_label.setAttribute('onclick','');
2960                         removeCSSClass(no_change_label,'click_link');
2961                         no_change_label.setAttribute('unique_row_counter','');
2962                         if (typeof params.info_blurb == 'function') {
2963                             params.info_blurb( text );
2964                         }
2965                     }
2966                 break;
2967                 default:
2968                     check.what_happened = 'error';
2969                     msg += document.getElementById('commonStrings').getString('common.error');
2970                     var copy_status = data.hash.ccs[check.copy.status()] ? data.hash.ccs[check.copy.status()].name() : check.copy.status().name();
2971                     msg += '\n';
2972                     var error_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.copy_status.error', [copy_status]);
2973                     print_data.error_msg += error_msg;
2974                     msg += error_msg;
2975                     msg += '\n';
2976                     print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [check.route_to]);
2977                     msg += print_data.route_to_msg;
2978                 break;
2979             }
2980             if (msg) {
2981                 error.yns_alert(
2982                     msg,
2983                     document.getElementById('circStrings').getString('staff.circ.alert'),
2984                     null,
2985                     document.getElementById('circStrings').getString('staff.circ.utils.msg.ok'),
2986                     null,
2987                     document.getElementById('circStrings').getString('staff.circ.confirm.msg')
2988                 );
2989             }
2990         } else /* ROUTE_ITEM */ if (check.ilsevent == 7000) {
2991
2992             check.what_happened = 'transit';
2993             var lib = data.hash.aou[ check.org ];
2994             check.route_to = lib.shortname();
2995             print_data.route_to = check.route_to;
2996             print_data.route_to_org = lib;
2997             print_data.route_to_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.destination', [check.route_to]);
2998             print_data.route_to_org_fullname = lib.name();
2999             var aous_req = network.simple_request('FM_AOUS_SPECIFIC_RETRIEVE',[ lib.id(), 'lib.courier_code' ]);
3000             if (aous_req) {
3001                 print_data.courier_code = aous_req.value || '';
3002             }
3003             msg += print_data.route_to_msg;
3004             msg += '\n\n';
3005             msg += lib.name();
3006             msg += '\n';
3007             try {
3008                 if (lib.holds_address() ) {
3009                     var a = network.simple_request('FM_AOA_RETRIEVE',[ lib.holds_address() ]);
3010                     if (typeof a.ilsevent != 'undefined') throw(a);
3011                     if (a.street1()) { msg += a.street1() + '\n'; print_data.street1 = a.street1(); }
3012                     if (a.street2()) { msg += a.street2() + '\n'; print_data.street2 = a.street2(); }
3013                     print_data.city_state_zip = (a.city() ? a.city() + ', ' : '') + (a.state() ? a.state() + ' ' : '') + (a.post_code() ? a.post_code() : '');
3014                     print_data.city = a.city();
3015                     print_data.state = a.state();
3016                     print_data.county = a.county();
3017                     print_data.country = a.country();
3018                     print_data.post_code = a.post_code();
3019                     msg += print_data.city_state_zip + '\n';
3020                 } else {
3021                     print_data.street1 = document.getElementById('circStrings').getString('staff.circ.utils.route_to.no_address');
3022                     print_data.no_address = true;
3023                     msg += print_data.street1;
3024                     msg += '\n';
3025                 }
3026             } catch(E) {
3027                 var err_msg = document.getElementById('circStrings').getString('staff.circ.utils.route_to.no_address.error');
3028                 print_data.error_msg += err_msg + '\n';
3029                 msg += err_msg + '\n';
3030                 error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.utils.route_to.no_address.error'), E);
3031             }
3032             msg += '\n';
3033             print_data.item_barcode_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.barcode', [check.payload.copy.barcode()]);
3034             print_data.item_barcode = check.payload.copy.barcode();
3035             msg += print_data.item_barcode_msg;
3036             msg += '\n';
3037             var payload_title  = (check.payload.record ? check.payload.record.title() : check.payload.copy.dummy_title() );
3038             print_data.item_title_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.title', [payload_title]);
3039             print_data.item_title = payload_title;
3040             msg += print_data.item_title_msg;
3041             msg += '\n';
3042             var payload_author = (check.payload.record ? check.payload.record.author() :check.payload.copy.dummy_author());
3043             print_data.item_author_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.author', [payload_author]);
3044             print_data.item_author = payload_author;
3045             msg += print_data.item_author_msg;
3046             msg += '\n';
3047             JSAN.use('util.date');
3048             if (check.payload.hold) {
3049                 check.what_happened = 'transit_for_hold';
3050                 JSAN.use('patron.util');
3051                 var au_obj = patron.util.retrieve_fleshed_au_via_id( session, check.payload.hold.usr() );
3052                 print_data.user = au_obj;
3053                 print_data.user_stat_cat_entries = [];
3054                 var entries = au_obj.stat_cat_entries();
3055                 for (var i = 0; i < entries.length; i++) {
3056                     var stat_cat = data.hash.my_actsc[ entries[i].stat_cat() ];
3057                     if (!stat_cat) {
3058                         stat_cat = data.lookup('actsc', entries[i].stat_cat());
3059                     }
3060                     print_data.user_stat_cat_entries.push( { 
3061                         'id' : entries[i].id(),
3062                         'stat_cat' : {
3063                             'id' : stat_cat.id(),
3064                             'name' : stat_cat.name(),
3065                             'opac_visible' : stat_cat.opac_visible(),
3066                             'owner' : stat_cat.owner(),
3067                             'usr_summary' : stat_cat.usr_summary()
3068                         },
3069                         'stat_cat_entry' : entries[i].stat_cat_entry(),
3070                         'target_usr' : entries[i].target_usr() 
3071                     } );
3072                 }
3073                 msg += '\n';
3074                 if (au_obj.alias()) {
3075                     print_data.hold_for_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.patron_alias',  [au_obj.alias()]);
3076                     print_data.hold_for_alias = au_obj.alias();
3077                     msg += print_data.hold_for_msg;
3078                 } else {
3079                     print_data.hold_for_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.patron',  [au_obj.family_name() ? au_obj.family_name() : '', au_obj.first_given_name() ? au_obj.first_given_name() : '', au_obj.second_given_name() ? au_obj.second_given_name() : '']);
3080                     msg += print_data.hold_for_msg;
3081                     print_data.hold_for_family_name = au_obj.family_name() ? au_obj.family_name() : '';
3082                     print_data.hold_for_first_given_name = au_obj.first_given_name() ? au_obj.first_given_name() : '';
3083                     print_data.hold_for_second_given_name = au_obj.second_given_name() ? au_obj.second_given_name() : '';
3084                 }
3085                 msg += '\n';
3086                 print_data.user_barcode_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.barcode', [au_obj.card().barcode()]);
3087                 print_data.user_barcode = au_obj.card().barcode();
3088                 msg += print_data.user_barcode_msg;
3089                 msg += '\n';
3090                 if (check.payload.hold.phone_notify()) {
3091                     print_data.notify_by_phone_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.phone_notify', [check.payload.hold.phone_notify()]);
3092                     print_data.notify_by_phone = check.payload.hold.phone_notify();
3093                     msg += print_data.notify_by_phone_msg;
3094                     msg += '\n';
3095                 }
3096                 if (get_bool(check.payload.hold.email_notify())) {
3097                     var payload_email = au_obj.email() ? au_obj.email() : '';
3098                     print_data.notify_by_email_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.email_notify', [payload_email]);
3099                     print_data.notify_by_email = payload_email;
3100                     msg += print_data.notify_by_email_msg;
3101                     msg += '\n';
3102                 }
3103                 msg += '\n';
3104                 var notes = check.payload.hold.notes();
3105                 print_data.notes_raw = notes;
3106                 for (var i = 0; i < notes.length; i++) {
3107                     if ( get_bool( notes[i].slip() ) ) {
3108                         var temp_msg;
3109                         if ( get_bool( notes[i].staff() ) ) {
3110                             temp_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.notes.staff_note', [ notes[i].title(), notes[i].body() ]);
3111                         } else {
3112                             temp_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.notes.patron_note', [ notes[i].title(), notes[i].body() ]);
3113                         }
3114                         msg += temp_msg + '\n';
3115                         print_list.push(
3116                             {
3117                                 'formatted_note' : temp_msg,
3118                                 'note_title' : notes[i].title(),
3119                                 'note_body' : notes[i].body(),
3120                                 'note_public' : notes[i].pub(),
3121                                 'note_by_staff' : notes[i].staff()
3122                             }
3123                         );
3124                     }
3125                 }
3126                 msg += '\n';
3127                 msg += '\n';
3128                 print_data.request_date = util.date.formatted_date(check.payload.hold.request_time(),'%F');
3129                 print_data.request_date_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.request_date', [print_data.request_date]);
3130                 msg += print_data.request_date_msg;
3131                 msg += '\n';
3132                 var destination_shelf = document.getElementById('circStrings').getString('staff.circ.route_to.hold_shelf');
3133                 print_data.destination_shelf_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [destination_shelf]);
3134                 print_data.destination_shelf = destination_shelf;
3135                 var behind_the_desk_support = String( data.hash.aous['circ.holds.behind_desk_pickup_supported'] ) == 'true';
3136                 if (behind_the_desk_support) {
3137                    var usr_settings = network.simple_request('FM_AUS_RETRIEVE',[ses(),check.payload.hold.usr()]); 
3138                     if (typeof usr_settings['circ.holds_behind_desk'] != 'undefined') {
3139                         if (usr_settings['circ.holds_behind_desk']) {
3140                             print_data.prefer_behind_holds_desk = true;
3141                             destination_shelf = document.getElementById('circStrings').getString('staff.circ.route_to.private_hold_shelf');
3142                             print_data.destination_shelf_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [destination_shelf]);
3143                             print_data.destination_shelf = destination_shelf;
3144                         } else {
3145                             destination_shelf = document.getElementById('circStrings').getString('staff.circ.route_to.public_hold_shelf');
3146                             print_data.destination_shelf_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [destination_shelf]);
3147                             print_data.destination_shelf = destination_shelf;
3148                         }
3149                     } else {
3150                         destination_shelf = document.getElementById('circStrings').getString('staff.circ.route_to.public_hold_shelf');
3151                         print_data.destination_shelf_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.route_to.msg', [destination_shelf]);
3152                         print_data.destination_shelf = destination_shelf;
3153                     }
3154                 }
3155             }
3156             var rv = 0;
3157             var suppress_popups = data.hash.aous['ui.circ.suppress_checkin_popups'];
3158             if (suppress_popups) {
3159                 rv = auto_print ? 0 : -1; auto_print = true; // skip dialog and PRINT or DO NOT PRINT based on Auto-Print checkbox
3160             }
3161             var x = data.hash.aous['circ.staff_client.do_not_auto_attempt_print'];
3162             var no_print_prompting = x ? (x.indexOf( check.payload.hold ? "Hold/Transit Slip" : "Transit Slip" ) > -1) : false;
3163             if (no_print_prompting) {
3164                 rv = -1; auto_print = true; // DO NOT PRINT and skip dialog
3165             }
3166             print_data.slip_date = util.date.formatted_date(new Date(),'%F');
3167             print_data.slip_date_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.hold.slip_date', [print_data.slip_date]);
3168             msg += print_data.slip_date_msg;
3169             print_data.payload = check.payload;
3170
3171             if (!auto_print) {
3172                 rv = error.yns_alert_formatted(
3173                     msg,
3174                     document.getElementById('circStrings').getString('staff.circ.utils.transit_slip'),
3175                     document.getElementById('circStrings').getString('staff.circ.utils.transit_slip.print.yes'),
3176                     document.getElementById('circStrings').getString('staff.circ.utils.transit_slip.print.no'),
3177                     null,
3178                     document.getElementById('circStrings').getString('staff.circ.confirm.msg'),
3179                     '/xul/server/skin/media/images/turtle.gif'
3180                 );
3181             } else {
3182                 if (suppress_popups && !no_print_prompting) {
3183                     // FIXME: add SFX and/or GFX
3184                     sound.circ_bad();
3185                 }
3186             }
3187             if (rv == 0) {
3188                 try {
3189                     JSAN.use('util.print'); var print = new util.print();
3190                     var old_template = String( data.hash.aous['ui.circ.old_harcoded_slip_template'] ) == 'true';
3191                     if (old_template) {
3192                         msg = msg.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g,'<br/>');
3193                         print.simple( msg , { 'no_prompt' : true, 'content_type' : 'text/html' } );
3194                     } else {
3195                         var template = check.payload.hold ? 'hold_transit_slip' : 'transit_slip';
3196                         var params = {
3197                             'patron' : print_data.user,
3198                             'lib' : data.hash.aou[ data.list.au[0].ws_ou() ],
3199                             'staff' : data.list.au[0],
3200                             'header' : data.print_list_templates[ template ].header,
3201                             'line_item' : data.print_list_templates[ template ].line_item,
3202                             'footer' : data.print_list_templates[ template ].footer,
3203                             'type' : data.print_list_templates[ template ].type,
3204                             'list' : print_list,
3205                             'data' : print_data 
3206                         };
3207                         print.tree_list( params );
3208                     }
3209                 } catch(E) {
3210                     var err_msg = document.getElementById('commonStrings').getString('common.error');
3211                     err_msg += '\nFIXME: ' + E + '\n';
3212                     dump(err_msg);
3213                     alert(err_msg);
3214                 }
3215             }
3216             if (no_change_label) {
3217                 var m = no_change_label.getAttribute('value');
3218                 var trans_msg = document.getElementById('circStrings').getFormattedString('staff.circ.utils.payload.in_transit', [params.barcode]);
3219                 no_change_label.setAttribute('value', m + trans_msg + '  ');
3220                 no_change_label.setAttribute('hidden','false');
3221                 no_change_label.setAttribute('onclick','');
3222                 removeCSSClass(no_change_label,'click_link');
3223                 no_change_label.setAttribute('unique_row_counter','');
3224                 if (typeof params.info_blurb == 'function') {
3225                     params.info_blurb( trans_msg );
3226                 }
3227             }
3228
3229         } else /* ASSET_COPY_NOT_FOUND */ if (check.ilsevent == 1502) {
3230
3231             check.what_happened = 'not_found';
3232             check.route_to = 'CATALOGING';
3233             var mis_scan_msg = document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.status.copy_not_found', [params.barcode]);
3234             var suppress_popups = data.hash.aous['ui.circ.suppress_checkin_popups'];
3235             if (!suppress_popups) {
3236                 error.yns_alert(
3237                     mis_scan_msg,
3238                     document.getElementById('circStrings').getString('staff.circ.alert'),
3239                     null,
3240                     document.getElementById('circStrings').getString('staff.circ.utils.msg.ok'),
3241                     null,
3242                     document.getElementById('circStrings').getString('staff.circ.confirm.msg')
3243                 );
3244             } else {
3245                 // FIXME: add SFX and/or GFX
3246                 sound.circ_bad();
3247             }
3248             if (no_change_label) {
3249                 var m = no_change_label.getAttribute('value');
3250                 no_change_label.setAttribute('value',m + mis_scan_msg + '  ');
3251                 no_change_label.setAttribute('hidden','false');
3252                 no_change_label.setAttribute('onclick','');
3253                 removeCSSClass(no_change_label,'click_link');
3254                 no_change_label.setAttribute('unique_row_counter','');
3255                 if (typeof params.info_blurb == 'function') {
3256                     params.info_blurb( mis_scan_msg );
3257                 }
3258             }
3259
3260         } else /* HOLD_CAPTURE_DELAYED */ if (check.ilsevent == 7019) {
3261
3262             check.what_happened = 'hold_capture_delayed';
3263             var rv = 0;
3264             msg += document.getElementById('circStrings').getString('staff.circ.utils.hold_capture_delayed.description');
3265             var suppress_popups = data.hash.aous['ui.circ.suppress_checkin_popupst'];
3266             if (!suppress_popups) {
3267                 rv = error.yns_alert_formatted(
3268                     msg,
3269                     document.getElementById('circStrings').getString('staff.circ.utils.hold_capture_delayed.titlebar'),
3270                     document.getElementById('circStrings').getString('staff.circ.utils.hold_capture_delayed.prompt_for_nocapture'),
3271                     document.getElementById('circStrings').getString('staff.circ.utils.hold_capture_delayed.prompt_for_capture'),
3272                     null,
3273                     document.getElementById('circStrings').getString('staff.circ.confirm.msg'),
3274                     '/xul/server/skin/media/images/stop_sign.png'
3275                 );
3276             } else {
3277                 // FIXME: add SFX and/or GFX
3278                 sound.circ_bad();
3279             }
3280             params.capture = rv == 0 ? 'nocapture' : 'capture';
3281
3282             return circ.util.checkin_via_barcode(session,params,backdate,auto_print,false);
3283
3284         } else /* NETWORK TIMEOUT */ if (check.ilsevent == -1) {
3285             check.what_happened = 'error';
3286             error.standard_network_error_alert(document.getElementById('circStrings').getString('staff.circ.checkin.suggest_offline'));
3287         } else {
3288
3289             if (check.ilsevent == null) { return null; /* handled */ }
3290             switch (Number(check.ilsevent)) {
3291                 case 1203 /* COPY_BAD_STATUS */ :
3292                 case 1213 /* PATRON_BARRED */ :
3293                 case 1217 /* PATRON_INACTIVE */ :
3294                 case 1224 /* PATRON_ACCOUNT_EXPIRED */ :
3295                 case 1234 /* ITEM_DEPOSIT_PAID */ :
3296                 case 7009 /* CIRC_CLAIMS_RETURNED */ :
3297                 case 7010 /* COPY_ALERT_MESSAGE */ :
3298                 case 7011 /* COPY_STATUS_LOST */ :
3299                 case 7012 /* COPY_STATUS_MISSING */ :
3300                 case 7013 /* PATRON_EXCEEDS_FINES */ :
3301                     return null; /* handled */
3302                 break;
3303             }
3304
3305             throw(check);
3306
3307         }
3308
3309         return check;
3310     } catch(E) {
3311         JSAN.use('util.error'); var error = new util.error();
3312         error.standard_unexpected_error_alert(document.getElementById('circStrings').getFormattedString('staff.circ.checkin.error', ['3']), E);
3313         return null;
3314     }
3315 };
3316
3317 circ.util.renew_via_barcode = function ( params, async ) {
3318     try {
3319         var obj = {};
3320         JSAN.use('util.network'); obj.network = new util.network();
3321         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.stash_retrieve();
3322
3323         function renew_callback(req) {
3324             try {
3325                 JSAN.use('util.error'); var error = new util.error();
3326                 var renew = req.getResultObject();
3327                 if (typeof renew.ilsevent != 'undefined') renew = [ renew ];
3328                 for (var j = 0; j < renew.length; j++) {
3329                     switch(renew[j].ilsevent == null ? null : Number(renew[j].ilsevent)) {
3330                         case 0 /* SUCCESS */ : break;
3331                         case null /* custom event */ : break;
3332                         case 5000 /* PERM_FAILURE */: break;
3333                         case 1212 /* PATRON_EXCEEDS_OVERDUE_COUNT */ : break;
3334                         case 1213 /* PATRON_BARRED */ : break;
3335                         case 1215 /* CIRC_EXCEEDS_COPY_RANGE */ : break;
3336                         case 1224 /* PATRON_ACCOUNT_EXPIRED */ : break;
3337                         case 1232 /* ITEM_DEPOSIT_REQUIRED */ : break;
3338                         case 1233 /* ITEM_RENTAL_FEE_REQUIRED */ : break;
3339                         case 1234 /* ITEM_DEPOSIT_PAID */ : break;
3340                         case 1500 /* ACTION_CIRCULATION_NOT_FOUND */ : break;
3341                         case 1502 /* ASSET_COPY_NOT_FOUND */ : 
3342                             var mis_scan_msg = document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.status.copy_not_found', [params.barcode]);
3343                             error.yns_alert(
3344                                 mis_scan_msg,
3345                                 document.getElementById('circStrings').getString('staff.circ.alert'),
3346                                 null,
3347                                 document.getElementById('circStrings').getString('staff.circ.utils.msg.ok'),
3348                                 null,
3349                                 document.getElementById('circStrings').getString('staff.circ.confirm.msg')
3350                             );
3351                             if (no_change_label) {
3352                                 var m = no_change_label.getAttribute('value');
3353                                 no_change_label.setAttribute('value',m + mis_scan_msg + '  ');
3354                                 no_change_label.setAttribute('hidden','false');
3355                                 no_change_label.setAttribute('onclick','');
3356                                 removeCSSClass(no_change_label,'click_link');
3357                                 no_change_label.setAttribute('unique_row_counter','');
3358                                 if (typeof params.info_blurb == 'function') {
3359                                     params.info_blurb( mis_scan_msg );
3360                                 }
3361                             }
3362                         break;
3363                         case 7002 /* PATRON_EXCEEDS_CHECKOUT_COUNT */ : break;
3364                         case 7003 /* COPY_CIRC_NOT_ALLOWED */ : break;
3365                         case 7004 /* COPY_NOT_AVAILABLE */ : break;
3366                         case 7006 /* COPY_IS_REFERENCE */ : break;
3367                         case 7007 /* COPY_NEEDED_FOR_HOLD */ : break;
3368                         case 7008 /* MAX_RENEWALS_REACHED */ : break;
3369                         case 7009 /* CIRC_CLAIMS_RETURNED */ : break;
3370                         case 7010 /* COPY_ALERT_MESSAGE */ : break;
3371                         case 7013 /* PATRON_EXCEEDS_FINES */ : break;
3372                         default:
3373                             throw(renew);
3374                         break;
3375                     }
3376                 }
3377                 try {
3378                     var ibarcode = renew[0].payload.copy ? renew[0].payload.copy.barcode() : params.barcode;
3379                     var p_id = renew[0].payload.patron ? renew[0].payload.patron.id() : renew[0].payload.circ.usr();
3380                     var pname; var pbarcode; 
3381                     if (renew[0].patron) {
3382                         pname = renew[0].payload.patron.family_name();
3383                         pbarcode = typeof renew[0].payload.patron.card() == 'object' ? renew[0].payload.patron.card().barcode() : null;
3384                     } else {
3385                         if (circ.util.renew_via_barcode.last_usr_id == p_id) {
3386                             pname = circ.util.renew_via_barcode.last_pname;
3387                             pbarcode = circ.util.renew_via_barcode.last_pbarcode;
3388                         } else {
3389                             JSAN.use('patron.util'); var p = patron.util.retrieve_fleshed_au_via_id(ses(),p_id);
3390                             pname = p.family_name();
3391                             pbarcode = typeof p.card() == 'object' ? p.card().barcode() : null;
3392                             if (pname) {
3393                                 circ.util.renew_via_barcode.last_usr_id = p_id;
3394                                 circ.util.renew_via_barcode.last_pname = pname;
3395                                 circ.util.renew_via_barcode.last_pbarcode = pbarcode;
3396                             }
3397                         } 
3398                     }
3399                     error.work_log(
3400                         document.getElementById('circStrings').getFormattedString(
3401                             'staff.circ.work_log_renew.message',
3402                             [
3403                                 ses('staff_usrname'),
3404                                 pname ? pname : '???',
3405                                 pbarcode ? pbarcode : '???',
3406                                 ibarcode ? ibarcode : '???'
3407                             ]
3408                         ), {
3409                             'au_id' : p_id,
3410                             'au_family_name' : pname,
3411                             'au_barcode' : pbarcode,
3412                             'acp_barcode' : ibarcode
3413                         }
3414                     );
3415                 } catch(E) {
3416                     error.sdump('D_ERROR','Error with work_logging in server/circ/util.js, renew_via_barcode():' + E);
3417                 }
3418                 if (typeof async == 'function') async(renew);
3419                 return renew;
3420             } catch(E) {
3421                 JSAN.use('util.error'); var error = new util.error();
3422                 error.standard_unexpected_error_alert(document.getElementById('circStrings').getFormattedString('staff.circ.checkin.renew_failed.error', [params.barcode]), E);
3423                 return null;
3424             }
3425         }
3426
3427         var renew = obj.network.simple_request(
3428             'CHECKOUT_RENEW',
3429             [ ses(), params ],
3430             async ? renew_callback : null,
3431             {
3432                 'title' : document.getElementById('circStrings').getString('staff.circ.checkin.renew_failed.override'),
3433                 'overridable_events' : [
3434                     null /* custom event */,
3435                     1212 /* PATRON_EXCEEDS_OVERDUE_COUNT */,
3436                     1213 /* PATRON_BARRED */,
3437                     1215 /* CIRC_EXCEEDS_COPY_RANGE */,
3438                     1232 /* ITEM_DEPOSIT_REQUIRED */,
3439                     1233 /* ITEM_RENTAL_FEE_REQUIRED */,
3440                     1234 /* ITEM_DEPOSIT_PAID */,
3441                     7002 /* PATRON_EXCEEDS_CHECKOUT_COUNT */,
3442                     7003 /* COPY_CIRC_NOT_ALLOWED */,
3443                     7004 /* COPY_NOT_AVAILABLE */,
3444                     7006 /* COPY_IS_REFERENCE */,
3445                     7007 /* COPY_NEEDED_FOR_HOLD */,
3446                     7008 /* MAX_RENEWALS_REACHED */,
3447                     7009 /* CIRC_CLAIMS_RETURNED */,
3448                     7010 /* COPY_ALERT_MESSAGE */,
3449                     7013 /* PATRON_EXCEEDS_FINES */,
3450                 ],
3451                 'text' : {
3452                     '1212' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3453                     '1213' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3454                     '1215' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3455                     '1232' : function(r) {
3456                         return document.getElementById('circStrings').getFormattedString('staff.circ.renew.override.item_deposit_required.warning.barcode', [params.barcode]);
3457                     },
3458                     '1233' : function(r) {
3459                         return document.getElementById('circStrings').getFormattedString('staff.circ.renew.override.item_rental_fee_required.warning.barcode', [params.barcode]);
3460                     },
3461                     '1234' : function(r) {
3462                         return document.getElementById('circStrings').getFormattedString('staff.circ.utils.checkin.override.item_deposit_paid.warning');
3463                     },
3464                     '7002' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3465                     '7003' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3466                     '7004' : function(r) {
3467                         return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode.status', [params.barcode, typeof r.payload.status() == 'object' ? r.payload.status().name() : obj.data.hash.ccs[ r.payload.status() ].name()]);
3468                     },
3469                     '7006' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3470                     '7007' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3471                     '7008' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3472                     '7009' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); },
3473                     '7010' : function(r) {
3474                         return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode.msg', [params.barcode, r.payload]);
3475                     },
3476                     '7013' : function(r) { return document.getElementById('circStrings').getFormattedString('staff.circ.renew.barcode', [params.barcode]); }
3477                 }
3478             }
3479         );
3480         if (! async ) {
3481             return renew_callback( { 'getResultObject' : function() { return renew; } } );
3482         }
3483
3484     } catch(E) {
3485         JSAN.use('util.error'); var error = new util.error();
3486         error.standard_unexpected_error_alert(document.getElementById('circStrings').getFormattedString('staff.circ.checkin.renew_failed.error', [params.barcode]), E);
3487         return null;
3488     }
3489 };
3490
3491 circ.util.batch_hold_update = function ( hold_ids, field_changes, params ) {
3492     try {
3493         JSAN.use('util.sound'); var sound = new util.sound();
3494         var change_list = []; var idx = -1; var bad_holds = [];
3495         dojo.forEach(
3496             hold_ids,
3497             function(el) {
3498                 change_list.push( function(id,fc){ var clone = JSON2js(js2JSON(fc)); clone.id = id; return clone; }(el,field_changes) ); // Is there a better way to do this?
3499             }
3500         );
3501         if (params.progressmeter) { params.progressmeter.value = 0; params.progressmeter.hidden = false; }
3502         fieldmapper.standardRequest(
3503             [ api.FM_AHR_UPDATE_BATCH.app, api.FM_AHR_UPDATE_BATCH.method ],
3504             {   async: true,
3505                 params: [ses(), null, change_list],
3506                 onresponse: function(r) {
3507                     idx++; 
3508                     if (params.progressmeter) { params.progressmeter.value = Number( params.progressmeter.value ) + 100/hold_ids.length; }
3509                     var result = r.recv().content();
3510                     if (result != hold_ids[ idx ]) {
3511                         bad_holds.push( { 'hold_id' : hold_ids[ idx ], 'result' : result } );
3512                     }
3513                 },
3514                 oncomplete: function() {
3515                     if (bad_holds.length > 0) {
3516                         sound.circ_bad();
3517                         alert( $('circStrings').getFormattedString('staff.circ.hold_update.hold_ids.failed',[ bad_holds.length ]) );
3518                     } else {
3519                         sound.circ_good();
3520                     }
3521                     if (typeof params.oncomplete == 'function') {
3522                         params.oncomplete( bad_holds );
3523                     }
3524                     if (params.progressmeter) { params.progressmeter.value = 0; params.progressmeter.hidden = true; }
3525                 },
3526                 onerror: function(r) {
3527                     alert('Error in circ/util.js, batch_hold_update(), onerror: ' + r);
3528                 }
3529             }
3530         );
3531     } catch(E) {
3532         alert('Error in circ.util.js, circ.util.batch_hold_update(): ' + E);
3533     }
3534 };
3535
3536 circ.util.find_acq_po = function(session, copy_id) {
3537     dojo.require("openils.Util");
3538     fieldmapper.standardRequest(
3539         ["open-ils.acq", "open-ils.acq.lineitem.retrieve.by_copy_id.authoritative"], {
3540             "params": [session, copy_id, {"clear_marc": true}],
3541             "onresponse": function(r) {
3542                 if (r = openils.Util.readResponse(r)) {
3543                     if (r.purchase_order()) {
3544                         var url = urls.XUL_BROWSER + "?url=" +
3545                             xulG.url_prefix(
3546                                 escape(urls.EG_ACQ_PO_VIEW +
3547                                     "/" + r.purchase_order() + "/" + r.id())
3548                             );
3549                         window.xulG.new_tab(
3550                             url, {"browser": true}, {
3551                                 "no_xulG": false,
3552                                 "show_print_button": false,
3553                                 "show_nav_buttons": true
3554                             }
3555                         );
3556                     } else {
3557                         /* unlikely: got an LI with no PO */
3558                         alert(dojo.byId("circStrings").getFormattedString(
3559                             "staff.circ.utils.find_acq_po.no_po", [r.id()]
3560                         ));
3561                     }
3562                 }
3563             }
3564         }
3565     );
3566 };
3567
3568 dump('exiting circ/util.js\n');