]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/circ/util.js
input filter for money fields in copy editor, and convert empty strings to nulls...
[Evergreen.git] / Open-ILS / xul / staff_client / server / circ / util.js
1 dump('entering circ/util.js\n');
2
3 if (typeof circ == 'undefined') var circ = {};
4 circ.util = {};
5
6 circ.util.EXPORT_OK     = [ 
7         'offline_checkout_columns', 'offline_checkin_columns', 'offline_renew_columns', 'offline_inhouse_use_columns', 
8         'columns', 'hold_columns', 'checkin_via_barcode', 'std_map_row_to_columns', 
9         'show_last_few_circs', 'abort_transits', 'transit_columns', 'renew_via_barcode',
10 ];
11 circ.util.EXPORT_TAGS   = { ':all' : circ.util.EXPORT_OK };
12
13 circ.util.abort_transits = function(selection_list) {
14         var obj = {};
15         JSAN.use('util.error'); obj.error = new util.error();
16         JSAN.use('util.network'); obj.network = new util.network();
17         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
18         JSAN.use('util.functional');
19         var msg = 'Are you sure you would like to abort transits for copies:' + util.functional.map_list( selection_list, function(o){return o.copy_id;}).join(', ') + '?';
20         var r = obj.error.yns_alert(msg,'Aborting Transits','Yes','No',null,'Check here to confirm this action');
21         if (r == 0) {
22                 try {
23                         for (var i = 0; i < selection_list.length; i++) {
24                                 var copy_id = selection_list[i].copy_id;
25                                 var robj = obj.network.simple_request('FM_ATC_VOID',[ ses(), { 'copyid' : copy_id } ]);
26                                 if (typeof robj.ilsevent != 'undefined') {
27                                         switch(robj.ilsevent) {
28                                                 case 1225 /* TRANSIT_ABORT_NOT_ALLOWED */ :
29                                                         alert('Copy Id = ' + copy_id + '\n' + robj.desc);
30                                                 break;
31                                                 case 1504 /* ACTION_TRANSIT_COPY_NOT_FOUND */ :
32                                                         alert('This item was no longer in transit at the time of the abort.  Perhaps this happened from a stale display?');
33                                                 break;
34                                                 case 5000 /* PERM_FAILURE */ :
35                                                 break;
36                                                 default:
37                                                         throw(robj);
38                                                 break;
39                                         }
40                                 }
41                         }
42                 } catch(E) {
43                         obj.error.standard_unexpected_error_alert('Transit not likely aborted.',E);
44                 }
45         }
46 }
47
48 circ.util.show_copy_details = function(copy_id) {
49         var obj = {};
50         JSAN.use('util.error'); obj.error = new util.error();
51         JSAN.use('util.window'); obj.win = new util.window();
52         JSAN.use('util.network'); obj.network = new util.network();
53         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
54
55         if (typeof copy_id == 'object' && copy_id != null) copy_id = copy_id.id();
56
57         try {
58                 obj.data.fancy_prompt_data = null; obj.data.stash('fancy_prompt_data');
59                 var url = xulG.url_prefix( urls.XUL_COPY_DETAILS ) + '?copy_id=' + copy_id;
60                 obj.win.open( url, 'show_copy_details', 'chrome,resizable,modal' );
61                 obj.data.stash_retrieve();
62
63                 if (! obj.data.fancy_prompt_data) return;
64                 var patrons = JSON2js( obj.data.fancy_prompt_data );
65                 for (var j = 0; j < patrons.length; j++) {
66                         if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
67                                 try {
68                                         var url = urls.XUL_PATRON_DISPLAY + '?id=' + window.escape( patrons[j] );
69                                         window.xulG.new_tab( url );
70                                 } catch(E) {
71                                         obj.error.standard_unexpected_error_alert('Problem retrieving patron.',E);
72                                 }
73                         }
74                 }
75
76         } catch(E) {
77                 obj.error.standard_unexpected_error_alert('Problem retrieving copy details.',E);
78         }
79 }
80
81
82 circ.util.show_last_few_circs = function(selection_list,count) {
83         var obj = {};
84         JSAN.use('util.error'); obj.error = new util.error();
85         JSAN.use('util.window'); obj.win = new util.window();
86         JSAN.use('util.network'); obj.network = new util.network();
87         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
88
89         if (!count) count = 4;
90
91         for (var i = 0; i < selection_list.length; i++) {
92                 try {
93                         if (typeof selection_list[i].copy_id == 'undefined' || selection_list[i].copy_id == null) continue;
94                         obj.data.fancy_prompt_data = null; obj.data.stash('fancy_prompt_data');
95                         var url = xulG.url_prefix( urls.XUL_CIRC_SUMMARY ) + '?copy_id=' + selection_list[i].copy_id + '&count=' + count;
96                         obj.win.open( url, 'show_last_few_circs', 'chrome,resizable,modal' );
97                         obj.data.stash_retrieve();
98
99                         if (! obj.data.fancy_prompt_data) continue;
100                         var patrons = JSON2js( obj.data.fancy_prompt_data );
101                         for (var j = 0; j < patrons.length; j++) {
102                                 if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
103                                         try {
104                                                 var url = urls.XUL_PATRON_DISPLAY + '?id=' + window.escape( patrons[j] );
105                                                 window.xulG.new_tab( url );
106                                         } catch(E) {
107                                                 obj.error.standard_unexpected_error_alert('Problem retrieving patron.',E);
108                                         }
109                                 }
110                         }
111
112                 } catch(E) {
113                         obj.error.standard_unexpected_error_alert('Problem retrieving circulations.',E);
114                 }
115         }
116 }
117
118 circ.util.offline_checkout_columns = function(modify,params) {
119         
120         var c = [
121                 { 
122                         'id' : 'timestamp', 
123                         'label' : 'Timestamp', 
124                         'flex' : 1, 'primary' : false, 'hidden' : true, 
125                         'render' : function(my) { return my.timestamp; },
126                 },
127                 { 
128                         'id' : 'checkout_time', 
129                         'label' : 'Check Out Time', 
130                         'flex' : 1, 'primary' : false, 'hidden' : true, 
131                         'render' : function(my) { return my.checkout_time; },
132                 },
133                 { 
134                         'id' : 'type', 
135                         'label' : 'Transaction Type', 
136                         'flex' : 1, 'primary' : false, 'hidden' : true, 
137                         'render' : function(my) { return my.type; }, 
138                 },
139                 {
140                         'id' : 'noncat',
141                         'label' : 'Non-Cataloged?',
142                         'flex' : 1, 'primary' : false, 'hidden' : true, 
143                         'render' : function(my) { return my.noncat; },
144                 },
145                 {
146                         'id' : 'noncat_type',
147                         'label' : 'Non-Cat Type ID',
148                         'flex' : 1, 'primary' : false, 'hidden' : true,
149                         'render' : function(my) { return my.noncat_type; },
150                 },
151                 {
152                         'id' : 'noncat_count',
153                         'label' : 'Count', 'sort_type' : 'number',
154                         'flex' : 1, 'primary' : false, 'hidden' : false,
155                         'render' : function(my) { return my.noncat_count; },
156                 },
157                 { 
158                         'id' : 'patron_barcode', 
159                         'label' : 'Patron Barcode', 
160                         'flex' : 1, 'primary' : false, 'hidden' : true, 
161                         'render' : function(my) { return my.patron_barcode; },
162                 },
163                 { 
164                         'id' : 'barcode', 
165                         'label' : 'Item Barcode', 
166                         'flex' : 2, 'primary' : true, 'hidden' : false, 
167                         'render' : function(my) { return my.barcode; },
168                 },
169                 { 
170                         'id' : 'due_date', 
171                         'label' : 'Due Date', 
172                         'flex' : 1, 'primary' : false, 'hidden' : false, 
173                         'render' : function(my) { return my.due_date; },
174                 },
175         ];
176         if (modify) for (var i = 0; i < c.length; i++) {
177                 if (modify[ c[i].id ]) {
178                         for (var j in modify[ c[i].id ]) {
179                                 c[i][j] = modify[ c[i].id ][j];
180                         }
181                 }
182         }
183         if (params) {
184                 if (params.just_these) {
185                         JSAN.use('util.functional');
186                         var new_c = [];
187                         for (var i = 0; i < params.just_these.length; i++) {
188                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
189                                 new_c.push( function(y){ return y; }( x ) );
190                         }
191                         c = new_c;
192                 }
193                 if (params.except_these) {
194                         JSAN.use('util.functional');
195                         var new_c = [];
196                         for (var i = 0; i < c.length; i++) {
197                                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
198                                 if (!x) new_c.push(c[i]);
199                         }
200                         c = new_c;
201                 }
202
203         }
204         return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
205 }
206
207 circ.util.offline_checkin_columns = function(modify,params) {
208         
209         var c = [
210                 { 
211                         'id' : 'timestamp', 
212                         'label' : 'Timestamp', 
213                         'flex' : 1, 'primary' : false, 'hidden' : true, 
214                         'render' : function(my) { return my.timestamp; },
215                 },
216                 { 
217                         'id' : 'backdate', 
218                         'label' : 'Back Date', 
219                         'flex' : 1, 'primary' : false, 'hidden' : true, 
220                         'render' : function(my) { return my.backdate; },
221                 },
222                 { 
223                         'id' : 'type', 
224                         'label' : 'Transaction Type', 
225                         'flex' : 1, 'primary' : false, 'hidden' : true, 
226                         'render' : function(my) { return my.type; },
227                 },
228                 { 
229                         'id' : 'barcode', 
230                         'label' : 'Item Barcode', 
231                         'flex' : 2, 'primary' : true, 'hidden' : false, 
232                         'render' : function(my) { return my.barcode; },
233                 },
234         ];
235         if (modify) for (var i = 0; i < c.length; i++) {
236                 if (modify[ c[i].id ]) {
237                         for (var j in modify[ c[i].id ]) {
238                                 c[i][j] = modify[ c[i].id ][j];
239                         }
240                 }
241         }
242         if (params) {
243                 if (params.just_these) {
244                         JSAN.use('util.functional');
245                         var new_c = [];
246                         for (var i = 0; i < params.just_these.length; i++) {
247                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
248                                 new_c.push( function(y){ return y; }( x ) );
249                         }
250                         c = new_c;
251                 }
252                 if (params.except_these) {
253                         JSAN.use('util.functional');
254                         var new_c = [];
255                         for (var i = 0; i < c.length; i++) {
256                                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
257                                 if (!x) new_c.push(c[i]);
258                         }
259                         c = new_c;
260                 }
261
262         }
263         return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
264 }
265
266 circ.util.offline_renew_columns = function(modify,params) {
267         
268         var c = [
269                 { 
270                         'id' : 'timestamp', 
271                         'label' : 'Timestamp', 
272                         'flex' : 1, 'primary' : false, 'hidden' : true, 
273                         'render' : function(my) { return my.timestamp; },
274                 },
275                 { 
276                         'id' : 'checkout_time', 
277                         'label' : 'Check Out Time', 
278                         'flex' : 1, 'primary' : false, 'hidden' : true, 
279                         'render' : function(my) { return my.checkout_time; },
280                 },
281                 { 
282                         'id' : 'type', 
283                         'label' : 'Transaction Type', 
284                         'flex' : 1, 'primary' : false, 'hidden' : true, 
285                         'render' : function(my) { return my.type; },
286                 },
287                 { 
288                         'id' : 'patron_barcode', 
289                         'label' : 'Patron Barcode', 
290                         'flex' : 1, 'primary' : false, 'hidden' : true, 
291                         'render' : function(my) { return my.patron_barcode; },
292                 },
293                 { 
294                         'id' : 'barcode', 
295                         'label' : 'Item Barcode', 
296                         'flex' : 2, 'primary' : true, 'hidden' : false, 
297                         'render' : function(my) { return my.barcode; },
298                 },
299                 { 
300                         'id' : 'due_date', 
301                         'label' : 'Due Date', 
302                         'flex' : 1, 'primary' : false, 'hidden' : false, 
303                         'render' : function(my) { return my.due_date; },
304                 },
305         ];
306         if (modify) for (var i = 0; i < c.length; i++) {
307                 if (modify[ c[i].id ]) {
308                         for (var j in modify[ c[i].id ]) {
309                                 c[i][j] = modify[ c[i].id ][j];
310                         }
311                 }
312         }
313         if (params) {
314                 if (params.just_these) {
315                         JSAN.use('util.functional');
316                         var new_c = [];
317                         for (var i = 0; i < params.just_these.length; i++) {
318                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
319                                 new_c.push( function(y){ return y; }( x ) );
320                         }
321                         c = new_c;
322                 }
323                 if (params.except_these) {
324                         JSAN.use('util.functional');
325                         var new_c = [];
326                         for (var i = 0; i < c.length; i++) {
327                                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
328                                 if (!x) new_c.push(c[i]);
329                         }
330                         c = new_c;
331                 }
332
333         }
334         return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
335 }
336
337 circ.util.offline_inhouse_use_columns = function(modify,params) {
338         
339         var c = [
340                 { 
341                         'id' : 'timestamp', 
342                         'label' : 'Timestamp', 
343                         'flex' : 1, 'primary' : false, 'hidden' : true, 
344                         'render' : function(my) { return my.timestamp; },
345                 },
346                 { 
347                         'id' : 'use_time', 
348                         'label' : 'Use Time', 
349                         'flex' : 1, 'primary' : false, 'hidden' : true, 
350                         'render' : function(my) { return my.use_time; },
351                 },
352                 { 
353                         'id' : 'type', 
354                         'label' : 'Transaction Type', 
355                         'flex' : 1, 'primary' : false, 'hidden' : true, 
356                         'render' : function(my) { return my.type; },
357                 },
358                 {
359                         'id' : 'count',
360                         'label' : 'Count', 'sort_type' : 'number',
361                         'flex' : 1, 'primary' : false, 'hidden' : false,
362                         'render' : function(my) { return my.count; },
363                 },
364                 { 
365                         'id' : 'barcode', 
366                         'label' : 'Item Barcode', 
367                         'flex' : 2, 'primary' : true, 'hidden' : false, 
368                         'render' : function(my) { return my.barcode; },
369                 },
370         ];
371         if (modify) for (var i = 0; i < c.length; i++) {
372                 if (modify[ c[i].id ]) {
373                         for (var j in modify[ c[i].id ]) {
374                                 c[i][j] = modify[ c[i].id ][j];
375                         }
376                 }
377         }
378         if (params) {
379                 if (params.just_these) {
380                         JSAN.use('util.functional');
381                         var new_c = [];
382                         for (var i = 0; i < params.just_these.length; i++) {
383                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
384                                 new_c.push( function(y){ return y; }( x ) );
385                         }
386                         c = new_c;
387                 }
388                 if (params.except_these) {
389                         JSAN.use('util.functional');
390                         var new_c = [];
391                         for (var i = 0; i < c.length; i++) {
392                                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
393                                 if (!x) new_c.push(c[i]);
394                         }
395                         c = new_c;
396                 }
397
398         }
399         return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
400 }
401
402
403
404 circ.util.columns = function(modify,params) {
405         
406         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
407         JSAN.use('util.network'); var network = new util.network();
408         JSAN.use('util.money');
409
410         function getString(s) { return data.entities[s]; }
411
412         var c = [
413                 {
414                         'id' : 'acp_id', 'label' : getString('staff.acp_label_id'), 'flex' : 1,
415                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.id(); }, 'persist' : 'hidden width ordinal',
416                 },
417                 {
418                         'id' : 'circ_id', 'label' : getString('staff.circ_label_id'), 'flex' : 1,
419                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.id() : ( my.acp.circulations() ? my.acp.circulations()[0].id() : ""); },
420                         'persist' : 'hidden width ordinal',
421                 },
422                 {
423                         'id' : 'mvr_doc_id', 'label' : getString('staff.mvr_label_doc_id'), 'flex' : 1,
424                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.doc_id(); },
425                         'persist' : 'hidden width ordinal',
426                 },
427                 {
428                         'id' : 'barcode', 'label' : getString('staff.acp_label_barcode'), 'flex' : 1,
429                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.barcode(); },
430                         'persist' : 'hidden width ordinal',
431                 },
432                 {
433                         'id' : 'call_number', 'label' : getString('staff.acp_label_call_number'), 'flex' : 1,
434                         'primary' : false, 'hidden' : true, 'render' : function(my) { if (my.acp && my.acp.call_number() == -1) { return "Not Cataloged"; } else { if (!my.acn) { var x = network.simple_request("FM_ACN_RETRIEVE",[ my.acp.call_number() ]); if (x.ilsevent) { return "Not Cataloged"; } else { my.acn = x; return x.label(); } } else { return my.acn.label(); } } },
435                         'persist' : 'hidden width ordinal',
436                 },
437                 {
438                         'id' : 'owning_lib', 'label' : 'Owning Lib', 'flex' : 1,
439                         'primary' : false, 'hidden' : true,
440                         'render' : function(my) { if (Number(my.acn.owning_lib())>=0) { return data.hash.aou[ my.acn.owning_lib() ].shortname(); } else { return my.acn.owning_lib().shortname(); } }, 
441                         'persist' : 'hidden width ordinal',
442                 },
443                 {
444                         'id' : 'copy_number', 'label' : getString('staff.acp_label_copy_number'), 'flex' : 1, 'sort_type' : 'number',
445                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.copy_number(); },
446                         'persist' : 'hidden width ordinal',
447                 },
448                 {
449                         'id' : 'location', 'label' : getString('staff.acp_label_location'), 'flex' : 1,
450                         'primary' : false, 'hidden' : true, 'render' : function(my) { if (Number(my.acp.location())>=0) return data.lookup("acpl", my.acp.location() ).name(); else return my.acp.location().name(); },
451                         'persist' : 'hidden width ordinal',
452                 },
453                 {
454                         'id' : 'loan_duration', 'label' : getString('staff.acp_label_loan_duration'), 'flex' : 1,
455                         'primary' : false, 'hidden' : true, 
456                         'render' : function(my) { switch(my.acp.loan_duration()){ case 1: return "Short"; break; case 2: return "Normal"; break; case 3: return "Long"; break; }; },
457                         'persist' : 'hidden width ordinal',
458                 },
459                 {
460                         'id' : 'circ_lib', 'label' : getString('staff.acp_label_circ_lib'), 'flex' : 1,
461                         'primary' : false, 'hidden' : true, 'render' : function(my) { if (Number(my.acp.circ_lib())>=0) return data.hash.aou[ my.acp.circ_lib() ].shortname(); else return my.acp.circ_lib().shortname(); },
462                         'persist' : 'hidden width ordinal',
463                 },
464                 {
465                         'id' : 'fine_level', 'label' : getString('staff.acp_label_fine_level'), 'flex' : 1,
466                         'primary' : false, 'hidden' : true,
467                         'render' : function(my) { switch(my.acp.fine_level()){ case 1: return "Low"; break; case 2: return "Normal"; break; case 3: return "High"; break; }; },
468                         'persist' : 'hidden width ordinal',
469                 },
470                 {
471                         'id' : 'circulate', 'label' : 'Circulate?', 'flex' : 1,
472                         'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.acp.circulate() ) ? "Yes" : "No"; },
473                         'persist' : 'hidden width ordinal',
474                 },
475                 {
476                         'id' : 'deleted', 'label' : 'Deleted?', 'flex' : 1,
477                         'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.acp.deleted() ) ? "Yes" : "No"; },
478                         'persist' : 'hidden width ordinal',
479                 },
480                 {
481                         'id' : 'holdable', 'label' : 'Holdable?', 'flex' : 1,
482                         'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.acp.holdable() ) ? "Yes" : "No"; },
483                         'persist' : 'hidden width ordinal',
484                 },
485                 {
486                         'id' : 'opac_visible', 'label' : 'OPAC Visible?', 'flex' : 1,
487                         'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.acp.opac_visible() ) ? "Yes" : "No"; },
488                         'persist' : 'hidden width ordinal',
489                 },
490                 {
491                         'persist' : 'hidden width ordinal', 'id' : 'ref', 'label' : 'Reference?', 'flex' : 1,
492                         'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.acp.ref() ) ? "Yes" : "No"; },
493                 },
494                 {
495                         'persist' : 'hidden width ordinal', 'id' : 'deposit', 'label' : 'Deposit?', 'flex' : 1,
496                         'primary' : false, 'hidden' : true, 'render' : function(my) { return get_bool( my.acp.deposit() ) ? "Yes" : "No"; },
497                 },
498                 {
499                         'persist' : 'hidden width ordinal', 'id' : 'deposit_amount', 'label' : getString('staff.acp_label_deposit_amount'), 'flex' : 1,
500                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.price() == null ? "<Unset>" : util.money.sanitize(my.acp.deposit_amount()); }, 'sort_type' : 'money',
501                 },
502                 {
503                         'persist' : 'hidden width ordinal', 'id' : 'price', 'label' : getString('staff.acp_label_price'), 'flex' : 1,
504                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.price() == null ? "<Unset>" : util.money.sanitize(my.acp.price()); }, 'sort_type' : 'money',
505                 },
506                 {
507                         'persist' : 'hidden width ordinal', 'id' : 'circ_as_type', 'label' : getString('staff.acp_label_circ_as_type'), 'flex' : 1,
508                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.circ_as_type(); },
509                 },
510                 {
511                         'persist' : 'hidden width ordinal', 'id' : 'circ_modifier', 'label' : getString('staff.acp_label_circ_modifier'), 'flex' : 1,
512                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.circ_modifier(); },
513                 },
514                 {
515                         'persist' : 'hidden width ordinal', 'id' : 'checkout_lib', 'label' : 'Checkout Lib', 'flex' : 1,
516                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? data.hash.aou[ my.circ.circ_lib() ].shortname() : ( my.acp.circulations() ? data.hash.aou[ my.acp.circulations()[0].circ_lib() ].shortname() : ""); },
517                 },
518                 {
519                         'persist' : 'hidden width ordinal', 'id' : 'xact_start_full', 'label' : 'Checkout Timestamp', 'flex' : 1,
520                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.xact_start() : (my.acp.circulations() ? my.acp.circulations()[0].xact_start() : ""); },
521                 },
522                 {
523                         'persist' : 'hidden width ordinal', 'id' : 'checkin_time_full', 'label' : 'Checkin Timestamp', 'flex' : 1,
524                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.checkin_time() : (my.acp.circulations() ? my.acp.circulations()[0].checkin_time() : ""); },
525                 },
526                 {
527                         'persist' : 'hidden width ordinal', 'id' : 'xact_start', 'label' : 'Checkout Date', 'flex' : 1,
528                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.xact_start().substr(0,10) : (my.acp.circulations() ? my.acp.circulations()[0].xact_start().substr(0,10) : ""); },
529                 },
530                 {
531                         'persist' : 'hidden width ordinal', 'id' : 'checkin_time', 'label' : 'Checkin Date', 'flex' : 1,
532                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.checkin_time().substr(0,10) : (my.acp.circulations() ? my.acp.circulations()[0].checkin_time().substr(0,10) : ""); },
533                 },
534
535                 {
536                         'persist' : 'hidden width ordinal', 'id' : 'xact_finish', 'label' : 'Transaction Finished', 'flex' : 1,
537                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ.xact_finish(); },
538                 },
539                 {
540                         'persist' : 'hidden width ordinal', 'id' : 'due_date', 'label' : getString('staff.circ_label_due_date'), 'flex' : 1,
541                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.due_date().substr(0,10) : (my.acp.circulations() ? my.acp.circulations()[0].due_date().substr(0,10) : ""); },
542                 },
543                 {
544                         'persist' : 'hidden width ordinal', 'id' : 'create_date', 'label' : 'Date Created', 'flex' : 1,
545                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.create_date().substr(0,10); },
546                 },
547                 {
548                         'persist' : 'hidden width ordinal', 'id' : 'edit_date', 'label' : 'Date Last Edited', 'flex' : 1,
549                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.edit_date().substr(0,10); },
550                 },
551                 {
552                         'persist' : 'hidden width ordinal', 'id' : 'title', 'label' : getString('staff.mvr_label_title'), 'flex' : 2, 'sort_type' : 'title',
553                         'primary' : false, 'hidden' : true, 'render' : function(my) { try {  return my.mvr.title(); } catch(E) { return my.acp.dummy_title(); } }
554                 },
555                 {
556                         'persist' : 'hidden width ordinal', 'id' : 'author', 'label' : getString('staff.mvr_label_author'), 'flex' : 1,
557                         'primary' : false, 'hidden' : true, 'render' : function(my) { try { return my.mvr.author(); } catch(E) { return my.acp.dummy_author(); } }
558                 },
559                 {
560                         'persist' : 'hidden width ordinal', 'id' : 'edition', 'label' : 'Edition', 'flex' : 1,
561                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.edition(); },
562                 },
563                 {
564                         'persist' : 'hidden width ordinal', 'id' : 'isbn', 'label' : 'ISBN', 'flex' : 1,
565                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.isbn(); },
566                 },
567                 {
568                         'persist' : 'hidden width ordinal', 'id' : 'pubdate', 'label' : 'PubDate', 'flex' : 1,
569                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.pubdate(); },
570                 },
571                 {
572                         'persist' : 'hidden width ordinal', 'id' : 'publisher', 'label' : 'Publisher', 'flex' : 1,
573                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.publisher(); },
574                 },
575                 {
576                         'persist' : 'hidden width ordinal', 'id' : 'tcn', 'label' : 'TCN', 'flex' : 1,
577                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.tcn(); },
578                 },
579                 {
580                         'persist' : 'hidden width ordinal', 'id' : 'renewal_remaining', 'label' : getString('staff.circ_label_renewal_remaining'), 'flex' : 0,
581                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.renewal_remaining() : (my.acp.circulations() ? my.acp.circulations()[0].renewal_remaining() : ""); }, 'sort_type' : 'number',
582                 },
583                 {
584                         'persist' : 'hidden width ordinal', 'id' : 'stop_fines', 'label' : 'Fines Stopped', 'flex' : 0,
585                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.stop_fines() : (my.acp.circulations() ? my.acp.circulations()[0].stop_fines() : ""); },
586                 },
587                 {
588                         'persist' : 'hidden width ordinal', 'id' : 'stop_fines_time', 'label' : 'Fines Stopped Time', 'flex' : 0,
589                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.circ ? my.circ.stop_fines_time() : (my.acp.circulations() ? my.acp.circulations()[0].stop_fines_time() : ""); },
590                 },
591                 {
592                         'persist' : 'hidden width ordinal', 'id' : 'status', 'label' : getString('staff.acp_label_status'), 'flex' : 1,
593                         'primary' : false, 'hidden' : true, 'render' : function(my) { if (Number(my.acp.status())>=0) return data.hash.ccs[ my.acp.status() ].name(); else return my.acp.status().name(); },
594                 },
595                 {
596                         'persist' : 'hidden width ordinal', 'id' : 'route_to', 'label' : 'Route To', 'flex' : 1,
597                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.route_to.toString(); },
598                 },
599                 {
600                         'persist' : 'hidden width ordinal', 'id' : 'message', 'label' : 'Message', 'flex' : 1,
601                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.message.toString(); },
602                 },
603                 {
604                         'persist' : 'hidden width ordinal', 'id' : 'uses', 'label' : '# of Uses', 'flex' : 1,
605                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.uses; }, 'sort_type' : 'number',
606                 },
607                 {
608                         'persist' : 'hidden width ordinal', 'id' : 'alert_message', 'label' : 'Alert Message', 'flex' : 1,
609                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acp.alert_message(); },
610                 },
611         ];
612         for (var i = 0; i < c.length; i++) {
613                 if (modify[ c[i].id ]) {
614                         for (var j in modify[ c[i].id ]) {
615                                 c[i][j] = modify[ c[i].id ][j];
616                         }
617                 }
618         }
619         if (params) {
620                 if (params.just_these) {
621                         JSAN.use('util.functional');
622                         var new_c = [];
623                         for (var i = 0; i < params.just_these.length; i++) {
624                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
625                                 new_c.push( function(y){ return y; }( x ) );
626                         }
627                         c = new_c;
628                 }
629                 if (params.except_these) {
630                         JSAN.use('util.functional');
631                         var new_c = [];
632                         for (var i = 0; i < c.length; i++) {
633                                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
634                                 if (!x) new_c.push(c[i]);
635                         }
636                         c = new_c;
637                 }
638         }
639         return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
640 }
641
642 circ.util.transit_columns = function(modify,params) {
643         
644         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
645
646         function getString(s) { return data.entities[s]; }
647
648         var c = [
649                 {
650                         'persist' : 'hidden width ordinal', 'id' : 'transit_item_barcode', 'label' : 'Barcode', 'flex' : 1,
651                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.acp.barcode(); },
652                 },
653                 {
654                         'persist' : 'hidden width ordinal', 'id' : 'transit_item_title', 'label' : 'Title', 'flex' : 1,
655                         'primary' : false, 'hidden' : true,  'render' : function(my) { try { return my.mvr.title(); } catch(E) { return my.acp.dummy_title(); } },
656                 },
657                 {
658                         'persist' : 'hidden width ordinal', 'id' : 'transit_item_author', 'label' : 'Author', 'flex' : 1,
659                         'primary' : false, 'hidden' : true,  'render' : function(my) { try { return my.mvr.author(); } catch(E) { return my.acp.dummy_author(); } },
660                 },
661                 {
662                         'persist' : 'hidden width ordinal', 'id' : 'transit_item_callnumber', 'label' : 'Call Number', 'flex' : 1,
663                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.acn.label(); },
664                 },
665                 {
666                         'persist' : 'hidden width ordinal', 'id' : 'transit_id', 'label' : 'Transit ID', 'flex' : 1,
667                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.atc.id(); },
668                 },
669                 {
670                         'persist' : 'hidden width ordinal', 'id' : 'transit_source', 'label' : 'Transit Source', 'flex' : 1,
671                         'primary' : false, 'hidden' : false, 'render' : function(my) { return typeof my.atc.source() == "object" ? my.atc.source().shortname() : data.hash.aou[ my.atc.source() ].shortname(); },
672                 },
673                 {
674                         'persist' : 'hidden width ordinal', 'id' : 'transit_source_send_time', 'label' : 'Transitted On', 'flex' : 1,
675                         'primary' : false, 'hidden' : false, 'render' : function(my) { return my.atc.source_send_time(); },
676                 },
677                 {
678                         'persist' : 'hidden width ordinal', 'id' : 'transit_dest_lib', 'label' : 'Transit Destination', 'flex' : 1,
679                         'primary' : false, 'hidden' : false, 'render' : function(my) { return typeof my.atc.dest() == "object" ? my.atc.dest().shortname() : data.hash.aou[ my.atc.dest() ].shortname(); },
680                 },
681                 {
682                         'persist' : 'hidden width ordinal', 'id' : 'transit_dest_recv_time', 'label' : 'Transit Completed On', 'flex' : 1,
683                         'primary' : false, 'hidden' : false, 'render' : function(my) { return my.atc.dest_recv_time(); },
684                 },
685                 {
686                         'persist' : 'hidden width ordinal', 'id' : 'transit_target_copy', 'label' : 'Transit Copy ID', 'flex' : 1,
687                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.atc.target_copy(); },
688                 },
689         ];
690         for (var i = 0; i < c.length; i++) {
691                 if (modify[ c[i].id ]) {
692                         for (var j in modify[ c[i].id ]) {
693                                 c[i][j] = modify[ c[i].id ][j];
694                         }
695                 }
696         }
697         if (params) {
698                 if (params.just_these) {
699                         JSAN.use('util.functional');
700                         var new_c = [];
701                         for (var i = 0; i < params.just_these.length; i++) {
702                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
703                                 new_c.push( function(y){ return y; }( x ) );
704                         }
705                         c = new_c;
706                 }
707                 if (params.except_these) {
708                         JSAN.use('util.functional');
709                         var new_c = [];
710                         for (var i = 0; i < c.length; i++) {
711                                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
712                                 if (!x) new_c.push(c[i]);
713                         }
714                         c = new_c;
715                 }
716
717         }
718         return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
719 }
720
721
722 circ.util.hold_columns = function(modify,params) {
723         
724         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
725
726         function getString(s) { return data.entities[s]; }
727
728         var c = [
729                 {
730                         'persist' : 'hidden width ordinal', 'id' : 'request_timestamp', 'label' : 'Request Timestamp', 'flex' : 0,
731                         'primary' : false, 'hidden' : true,  
732                         'render' : function(my) { return my.ahr.request_time().toString(); },
733                 },
734                 {
735                         'persist' : 'hidden width ordinal', 'id' : 'request_time', 'label' : 'Request Date', 'flex' : 0,
736                         'primary' : false, 'hidden' : true,  
737                         'render' : function(my) { return my.ahr.request_time().toString().substr(0,10); },
738                 },
739                 {
740                         'persist' : 'hidden width ordinal', 'id' : 'available_timestamp', 'label' : 'Available On (Timestamp)', 'flex' : 1,
741                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.transit() ? ( my.ahr.transit().dest_recv_time() ? my.ahr.transit().dest_recv_time().toString() : "") : ( my.ahr.capture_time() ? my.ahr.capture_time().toString() : "" ); },
742                 },
743                 {
744                         'persist' : 'hidden width ordinal', 'id' : 'available_time', 'label' : 'Available On', 'flex' : 1,
745                         'primary' : false, 'hidden' : false,  'render' : function(my) { return my.ahr.transit() ? ( my.ahr.transit().dest_recv_time() ? my.ahr.transit().dest_recv_time().toString().substr(0,10) : "") : ( my.ahr.capture_time() ? my.ahr.capture_time().toString().substr(0,10) : "" ); },
746                 },
747                 {
748                         'persist' : 'hidden width ordinal', 'id' : 'capture_timestamp', 'label' : 'Capture Timestamp', 'flex' : 1,
749                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.capture_time() ? my.ahr.capture_time().toString() : ""; },
750                 },
751                 {
752                         'persist' : 'hidden width ordinal', 'id' : 'capture_time', 'label' : 'Capture Date', 'flex' : 1,
753                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.capture_time() ? my.ahr.capture_time().toString().substr(0,10) : ""; },
754                 },
755                 {
756                         'persist' : 'hidden width ordinal', 'id' : 'status', 'label' : getString('staff.ahr_status_label'), 'flex' : 1,
757                         'primary' : false, 'hidden' : false,  'render' : function(my) { switch(my.status) { case 1: case "1": return "Waiting for copy"; break; case 2: case "2": return "Waiting for capture"; break; case 3: case "3": return "In-Transit"; break; case 4: case "4" : return "Ready for pickup"; break; default: return my.status; break;}; },
758                 },
759                 {
760                         'persist' : 'hidden width ordinal', 'id' : 'hold_type', 'label' : getString('staff.ahr_hold_type_label'), 'flex' : 0,
761                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.hold_type(); },
762                 },
763                 {
764                         'persist' : 'hidden width ordinal', 'id' : 'pickup_lib', 'label' : 'Pickup Lib (Full Name)', 'flex' : 1,
765                         'primary' : false, 'hidden' : true,  
766                         'render' : function(my) { if (Number(my.ahr.pickup_lib())>=0) return data.hash.aou[ my.ahr.pickup_lib() ].name(); else return my.ahr.pickup_lib().name(); },
767                 },
768                 {
769                         'persist' : 'hidden width ordinal', 'id' : 'pickup_lib_shortname', 'label' : getString('staff.ahr_pickup_lib_label'), 'flex' : 0,
770                         'primary' : false, 'hidden' : true,  
771                         'render' : function(my) { if (Number(my.ahr.pickup_lib())>=0) return data.hash.aou[ my.ahr.pickup_lib() ].shortname(); else return my.ahr.pickup_lib().shortname(); },
772                 },
773                 {
774                         'persist' : 'hidden width ordinal', 'id' : 'current_copy', 'label' : getString('staff.ahr_current_copy_label'), 'flex' : 1,
775                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.acp ? my.acp.barcode() : "No Copy"; },
776                 },
777                 {
778                         'persist' : 'hidden width ordinal', 'id' : 'email_notify', 'label' : getString('staff.ahr_email_notify_label'), 'flex' : 1,
779                         'primary' : false, 'hidden' : true,  'render' : function(my) { return get_bool(my.ahr.email_notify()) ? "Yes" : "No"; },
780                 },
781                 {
782                         'persist' : 'hidden width ordinal', 'id' : 'expire_time', 'label' : getString('staff.ahr_expire_time_label'), 'flex' : 1,
783                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.expire_time(); },
784                 },
785                 {
786                         'persist' : 'hidden width ordinal', 'id' : 'fulfillment_time', 'label' : getString('staff.ahr_fulfillment_time_label'), 'flex' : 1,
787                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.fulfillment_time(); },
788                 },
789                 {
790                         'persist' : 'hidden width ordinal', 'id' : 'holdable_formats', 'label' : getString('staff.ahr_holdable_formats_label'), 'flex' : 1,
791                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.holdable_formats(); },
792                 },
793                 {
794                         'persist' : 'hidden width ordinal', 'id' : 'id', 'label' : getString('staff.ahr_id_label'), 'flex' : 1,
795                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.id(); },
796                 },
797                 {
798                         'persist' : 'hidden width ordinal', 'id' : 'phone_notify', 'label' : getString('staff.ahr_phone_notify_label'), 'flex' : 1,
799                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.phone_notify(); },
800                 },
801                 {
802                         'persist' : 'hidden width ordinal', 'id' : 'prev_check_time', 'label' : getString('staff.ahr_prev_check_time_label'), 'flex' : 1,
803                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.prev_check_time(); },
804                 },
805                 {
806                         'persist' : 'hidden width ordinal', 'id' : 'requestor', 'label' : getString('staff.ahr_requestor_label'), 'flex' : 1,
807                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.requestor(); },
808                 },
809                 {
810                         'persist' : 'hidden width ordinal', 'id' : 'selection_depth', 'label' : getString('staff.ahr_selection_depth_label'), 'flex' : 1,
811                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.selection_depth(); },
812                 },
813                 {
814                         'persist' : 'hidden width ordinal', 'id' : 'target', 'label' : getString('staff.ahr_target_label'), 'flex' : 1,
815                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.target(); },
816                 },
817                 {
818                         'persist' : 'hidden width ordinal', 'id' : 'usr', 'label' : getString('staff.ahr_usr_label'), 'flex' : 1,
819                         'primary' : false, 'hidden' : true,  'render' : function(my) { return my.ahr.usr(); },
820                 },
821                 {
822                         'persist' : 'hidden width ordinal', 'id' : 'title', 'label' : getString('staff.mvr_label_title'), 'flex' : 1, 'sort_type' : 'title',
823                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr ? my.mvr.title() : "No Title?"; },
824                 },
825                 {
826                         'persist' : 'hidden width ordinal', 'id' : 'author', 'label' : getString('staff.mvr_label_author'), 'flex' : 1,
827                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr ? my.mvr.author() : "No Author?"; },
828                 },
829                 {
830                         'persist' : 'hidden width ordinal', 'id' : 'edition', 'label' : 'Edition', 'flex' : 1,
831                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.edition(); },
832                 },
833                 {
834                         'persist' : 'hidden width ordinal', 'id' : 'isbn', 'label' : 'ISBN', 'flex' : 1,
835                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.isbn(); },
836                 },
837                 {
838                         'persist' : 'hidden width ordinal', 'id' : 'pubdate', 'label' : 'PubDate', 'flex' : 1,
839                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.pubdate(); },
840                 },
841                 {
842                         'persist' : 'hidden width ordinal', 'id' : 'publisher', 'label' : 'Publisher', 'flex' : 1,
843                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.publisher(); },
844                 },
845                 {
846                         'persist' : 'hidden width ordinal', 'id' : 'tcn', 'label' : 'TCN', 'flex' : 1,
847                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.mvr.tcn(); },
848                 },
849                 {
850                         'persist' : 'hidden width ordinal', 'id' : 'notify_time', 'label' : 'Last Notify Time', 'flex' : 1,
851                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.ahr.notify_time(); },
852                 },
853                 {
854                         'persist' : 'hidden width ordinal', 'id' : 'notify_count', 'label' : 'Notices', 'flex' : 1,
855                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.ahr.notify_count(); },
856                 },
857                 {
858                         'persist' : 'hidden width ordinal', 'id' : 'transit_source', 'label' : 'Transit Source', 'flex' : 1,
859                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.ahr.transit() ?  data.hash.aou[ my.ahr.transit().source() ].shortname() : ""; },
860                 },
861                 {
862                         'persist' : 'hidden width ordinal', 'id' : 'transit_source_send_time', 'label' : 'Transitted On', 'flex' : 1,
863                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.ahr.transit() ?  my.ahr.transit().source_send_time() : ""; },
864                 },
865                 {
866                         'persist' : 'hidden width ordinal', 'id' : 'transit_dest_lib', 'label' : 'Transit Destination', 'flex' : 1,
867                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.ahr.transit() ?  data.hash.aou[ my.ahr.transit().dest() ].shortname() : ""; },
868                 },
869                 {
870                         'persist' : 'hidden width ordinal', 'id' : 'transit_dest_recv_time', 'label' : 'Transit Completed On', 'flex' : 1,
871                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.ahr.transit() ?  my.ahr.transit().dest_recv_time() : ""; },
872                 },
873                 {
874                         'persist' : 'hidden width ordinal', 'id' : 'patron_barcode', 'label' : 'Patron Barcode', 'flex' : 1,
875                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.patron_barcode ? my.patron_barcode : ""; },
876                 },
877                 {
878                         'persist' : 'hidden width ordinal', 'id' : 'patron_family_name', 'label' : 'Patron Last Name', 'flex' : 1,
879                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.patron_family_name ? my.patron_family_name : ""; },
880                 },
881                 {
882                         'persist' : 'hidden width ordinal', 'id' : 'patron_first_given_name', 'label' : 'Patron First Name', 'flex' : 1,
883                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.patron_first_given_name ? my.patron_first_given_name : ""; },
884                 },
885                 {
886                         'persist' : 'hidden width ordinal', 'id' : 'callnumber', 'label' : 'Call Number', 'flex' : 1,
887                         'primary' : false, 'hidden' : true, 'render' : function(my) { return my.acn.label(); },
888                 },
889         ];
890         for (var i = 0; i < c.length; i++) {
891                 if (modify[ c[i].id ]) {
892                         for (var j in modify[ c[i].id ]) {
893                                 c[i][j] = modify[ c[i].id ][j];
894                         }
895                 }
896         }
897         if (params) {
898                 if (params.just_these) {
899                         JSAN.use('util.functional');
900                         var new_c = [];
901                         for (var i = 0; i < params.just_these.length; i++) {
902                                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
903                                 new_c.push( function(y){ return y; }( x ) );
904                         }
905                         c = new_c;
906                 }
907                 if (params.except_these) {
908                         JSAN.use('util.functional');
909                         var new_c = [];
910                         for (var i = 0; i < c.length; i++) {
911                                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
912                                 if (!x) new_c.push(c[i]);
913                         }
914                         c = new_c;
915                 }
916
917         }
918         return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
919 }
920 /*
921 circ.util.std_map_row_to_column = function(error_value) {
922         return function(row,col) {
923                 // row contains { 'my' : { 'acp' : {}, 'circ' : {}, 'mvr' : {} } }
924                 // col contains one of the objects listed above in columns
925                 
926                 // mimicking some of the obj in circ.checkin and circ.checkout where map_row_to_column is usually defined
927                 var obj = {}; 
928                 JSAN.use('util.error'); obj.error = new util.error();
929                 JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
930                 JSAN.use('util.network'); obj.network = new util.network();
931                 JSAN.use('util.money');
932
933                 var my = row.my;
934                 var value;
935                 try { 
936                         value = eval( col.render );
937                 } catch(E) {
938                         obj.error.sdump('D_WARN','map_row_to_column: ' + E);
939                         if (error_value) value = error_value; else value = '   ';
940                 }
941                 return value;
942         }
943 }
944 */
945 circ.util.std_map_row_to_columns = function(error_value) {
946         return function(row,cols) {
947                 // row contains { 'my' : { 'acp' : {}, 'circ' : {}, 'mvr' : {} } }
948                 // cols contains all of the objects listed above in columns
949                 
950                 var obj = {}; 
951                 JSAN.use('util.error'); obj.error = new util.error();
952                 JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
953                 JSAN.use('util.network'); obj.network = new util.network();
954                 JSAN.use('util.money');
955
956                 var my = row.my;
957                 var values = [];
958                 var cmd = '';
959                 try { 
960                         for (var i = 0; i < cols.length; i++) {
961                                 switch (typeof cols[i].render) {
962                                         case 'function': try { values[i] = cols[i].render(my); } catch(E) { values[i] = error_value; dump(E+'\n'); } break;
963                                         case 'string' : cmd += 'try { ' + cols[i].render + '; values['+i+'] = v; } catch(E) { values['+i+'] = error_value; }'; break;
964                                         default: cmd += 'values['+i+'] = "??? '+(typeof cols[i].render)+'"; ';
965                                 }
966                         }
967                         if (cmd) eval( cmd );
968                 } catch(E) {
969                         obj.error.sdump('D_WARN','map_row_to_column: ' + E);
970                         if (error_value) { value = error_value; } else { value = '   ' };
971                 }
972                 return values;
973         }
974 }
975
976 circ.util.checkin_via_barcode = function(session,params,backdate,auto_print,async) {
977         try {
978                 JSAN.use('util.error'); var error = new util.error();
979                 JSAN.use('util.network'); var network = new util.network();
980                 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
981                 JSAN.use('util.date');
982
983                 if (backdate && (backdate == util.date.formatted_date(new Date(),'%Y-%m-%d')) ) backdate = null;
984
985                 //var params = { 'barcode' : barcode };
986                 if (backdate) params.backdate = backdate;
987
988                 if (typeof async == 'object') {
989                         try { async.disable_textbox(); } catch(E) { error.sdump('D_ERROR','async.disable_textbox() = ' + E); };
990                 }
991                 var check = network.request(
992                         api.CHECKIN_VIA_BARCODE.app,
993                         api.CHECKIN_VIA_BARCODE.method,
994                         [ session, params ],
995                         async ? function(req) { 
996                                 try {
997                                         var check = req.getResultObject();
998                                         var r = circ.util.checkin_via_barcode2(session,params,backdate,auto_print,check); 
999                                         if (typeof async == 'object') {
1000                                                 try { async.checkin_result(r); } catch(E) { error.sdump('D_ERROR','async.checkin_result() = ' + E); };
1001                                         }
1002                                 } catch(E) {
1003                                         JSAN.use('util.error'); var error = new util.error();
1004                                         error.standard_unexpected_error_alert('Check In Failed (in circ.util.checkin): ',E);
1005                                         if (typeof async == 'object') {
1006                                                 try { async.enable_textbox(); } catch(E) { error.sdump('D_ERROR','async.disable_textbox() = ' + E); };
1007                                         }
1008                                         return null;
1009                                 }
1010                         } : null,
1011                         {
1012                                 'title' : 'Override Checkin Failure?',
1013                                 'overridable_events' : [ 
1014                                         1203 /* COPY_BAD_STATUS */, 
1015                                         1213 /* PATRON_BARRED */,
1016                                         1217 /* PATRON_INACTIVE */,
1017                                         1224 /* PATRON_ACCOUNT_EXPIRED */,
1018                                         7009 /* CIRC_CLAIMS_RETURNED */,
1019                                         7010 /* COPY_ALERT_MESSAGE */, 
1020                                         7011 /* COPY_STATUS_LOST */, 
1021                                         7012 /* COPY_STATUS_MISSING */, 
1022                                         7013 /* PATRON_EXCEEDS_FINES */,
1023                                 ],
1024                                 'text' : {
1025                                         '1203' : function(r) {
1026                                                 //return data.hash.ccs[ r.payload.status() ].name();
1027                                                 return r.payload.status().name();
1028                                         },
1029                                         '7010' : function(r) {
1030                                                 return r.payload;
1031                                         },
1032                                 }
1033                         }
1034                 );
1035                 if (!async) {
1036                         return circ.util.checkin_via_barcode2(session,params,backdate,auto_print,check); 
1037                 }
1038
1039
1040         } catch(E) {
1041                 JSAN.use('util.error'); var error = new util.error();
1042                 error.standard_unexpected_error_alert('Check In Failed (in circ.util.checkin): ',E);
1043                 if (typeof async == 'object') {
1044                         try { async.enable_textbox(); } catch(E) { error.sdump('D_ERROR','async.disable_textbox() = ' + E); };
1045                 }
1046                 return null;
1047         }
1048 }
1049
1050 circ.util.checkin_via_barcode2 = function(session,params,backdate,auto_print,check) {
1051         try {
1052                 JSAN.use('util.error'); var error = new util.error();
1053                 JSAN.use('util.network'); var network = new util.network();
1054                 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
1055                 JSAN.use('util.date');
1056
1057                 error.sdump('D_DEBUG','check = ' + error.pretty_print( js2JSON( check ) ) );
1058
1059                 check.message = check.textcode;
1060
1061                 if (check.payload && check.payload.copy) check.copy = check.payload.copy;
1062                 if (check.payload && check.payload.record) check.record = check.payload.record;
1063                 if (check.payload && check.payload.circ) check.circ = check.payload.circ;
1064
1065                 if (!check.route_to) check.route_to = '   ';
1066
1067                 if (document.getElementById('no_change_label')) {
1068                         document.getElementById('no_change_label').setAttribute('value','');
1069                         document.getElementById('no_change_label').setAttribute('hidden','true');
1070                 }
1071
1072                 if (check.circ) {
1073                         network.simple_request('FM_MBTS_RETRIEVE',[ses(),check.circ.id()], function(req) {
1074                                 JSAN.use('util.money');
1075                                 var bill = req.getResultObject();
1076                                 if (Number(bill.balance_owed()) == 0) return;
1077                                 if (document.getElementById('no_change_label')) {
1078                                         var m = document.getElementById('no_change_label').getAttribute('value');
1079                                         document.getElementById('no_change_label').setAttribute('value', m + 'Transaction for ' + params.barcode + ' billable $' + util.money.sanitize(bill.balance_owed()) + '  ');
1080                                         document.getElementById('no_change_label').setAttribute('hidden','false');
1081                                 }
1082                         });
1083                 }
1084
1085                 var msg = '';
1086
1087                 if (check.payload && check.payload.cancelled_hold_transit) {
1088                         msg += 'Original hold for transit cancelled.\n\n';
1089                 }
1090
1091                 /* SUCCESS  /  NO_CHANGE  /  ITEM_NOT_CATALOGED */
1092                 if (check.ilsevent == 0 || check.ilsevent == 3 || check.ilsevent == 1202) {
1093                         try { check.route_to = data.lookup('acpl', check.copy.location() ).name(); } catch(E) { msg += 'Please inform your helpdesk/developers of this error:\nFIXME: ' + E + '\n'; }
1094                         if (check.ilsevent == 3 /* NO_CHANGE */) {
1095                                 //msg = 'This item is already checked in.\n';
1096                                 if (document.getElementById('no_change_label')) {
1097                                         var m = document.getElementById('no_change_label').getAttribute('value');
1098                                         document.getElementById('no_change_label').setAttribute('value',m + params.barcode + ' was already checked in.  ');
1099                                         document.getElementById('no_change_label').setAttribute('hidden','false');
1100                                 }
1101                         }
1102                         if (check.ilsevent == 1202 /* ITEM_NOT_CATALOGED */ && check.copy.status() != 11) {
1103                                 msg = 'Please inform your helpdesk/developers of this error:\nFIXME -- ITEM_NOT_CATALOGED event but copy status is '
1104                                         + (data.hash.ccs[ check.copy.status() ] ? data.hash.ccs[ check.copy.status() ].name() : check.copy.status().name() ) + '\n';
1105                         }
1106                         switch(check.copy.status()) {
1107                                 case 0: /* AVAILABLE */
1108                                 case 7: /* RESHELVING */
1109                                         if (msg) msg += 'This item needs to be routed to ' + check.route_to + '.';
1110                                 break;
1111                                 case 8: /* ON HOLDS SHELF */
1112                                         check.route_to = 'HOLDS SHELF';
1113                                         if (check.payload.hold) {
1114                                                 if (check.payload.hold.pickup_lib() != data.list.au[0].ws_ou()) {
1115                                                         msg += 'Please inform your helpdesk/developers of this error:\nFIXME:  We should have received a ROUTE_ITEM\n';
1116                                                 } else {
1117                                                         msg += 'This item needs to be routed to ' + check.route_to + '.\n';
1118                                                 }
1119                                         } else { 
1120                                                 msg += 'Please inform your helpdesk/developers of this error:\nFIXME: status of Holds Shelf, but no actual hold found.\n';
1121                                         }
1122                                         JSAN.use('util.date'); 
1123                                         if (check.payload.hold) {
1124                                                 JSAN.use('patron.util');
1125                                                 msg += '\nBarcode: ' + check.payload.copy.barcode() + '\n';
1126                                                 msg += 'Title: ' + (check.payload.record ? check.payload.record.title() : check.payload.copy.dummy_title() ) + '\n';
1127                                                 var au_obj = patron.util.retrieve_fleshed_au_via_id( session, check.payload.hold.usr() );
1128                                                 msg += '\nHold for patron ' + au_obj.family_name() + ', ' + au_obj.first_given_name() + ' ' + au_obj.second_given_name() + '\n';
1129                                                 msg += 'Barcode: ' + au_obj.card().barcode() + '\n';
1130                                                 if (check.payload.hold.phone_notify()) msg += 'Notify by phone: ' + check.payload.hold.phone_notify() + '\n';
1131                                                 if (check.payload.hold.email_notify()) msg += 'Notify by email: ' + (au_obj.email() ? au_obj.email() : '') + '\n';
1132                                                 msg += '\nRequest Date: ' + util.date.formatted_date(check.payload.hold.request_time(),'%F') + '\n';
1133                                         }
1134                                         var rv = 0;
1135                                         msg += 'Slip Date: ' + util.date.formatted_date(new Date(),'%F') + '\n';
1136                                         if (!auto_print) rv = error.yns_alert_formatted(
1137                                                 msg,
1138                                                 'Hold Slip',
1139                                                 "Print",
1140                                                 "Don't Print",
1141                                                 null,
1142                                                 "Check here to confirm this message",
1143                                                 '/xul/server/skin/media/images/turtle.gif'
1144                                         );
1145                                         if (rv == 0) {
1146                                                 try {
1147                                                         JSAN.use('util.print'); var print = new util.print();
1148                                                         msg = msg.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g,'<br/>');
1149                                                         print.simple( msg , { 'no_prompt' : true, 'content_type' : 'text/html' } );
1150                                                 } catch(E) {
1151                                                         dump('Please inform your helpdesk/developers of this error:\nFIXME: ' + E + '\n');
1152                                                         alert('Please inform your helpdesk/developers of this error:\nFIXME: ' + E + '\n');
1153                                                 }
1154                                         }
1155                                         msg = '';
1156                                         if (document.getElementById('no_change_label')) {
1157                                                 var m = document.getElementById('no_change_label').getAttribute('value');
1158                                                 document.getElementById('no_change_label').setAttribute('value',m + params.barcode + ' has been captured for a hold.  ');
1159                                                 document.getElementById('no_change_label').setAttribute('hidden','false');
1160                                         }
1161                                 break;
1162                                 case 6: /* IN TRANSIT */
1163                                         check.route_to = 'TRANSIT SHELF??';
1164                                         msg += ("Please inform your helpdesk/developers of this error:\nFIXME -- I didn't think we could get here.\n");
1165                                 break;
1166                                 case 11: /* CATALOGING */
1167                                         check.route_to = 'CATALOGING';
1168                                         if (document.getElementById('do_not_alert_on_precat')) {
1169                                                 var x = document.getElementById('do_not_alert_on_precat');
1170                                                 if (! x.checked) msg += 'This item needs to be routed to ' + check.route_to + '.';
1171                                         } else {
1172                                                 msg += 'This item needs to be routed to ' + check.route_to + '.';
1173                                         }
1174                                         if (document.getElementById('no_change_label')) {
1175                                                 var m = document.getElementById('no_change_label').getAttribute('value');
1176                                                 document.getElementById('no_change_label').setAttribute('value',m + params.barcode + ' needs to be cataloged.  ');
1177                                                 document.getElementById('no_change_label').setAttribute('hidden','false');
1178                                         }
1179                                 break;
1180                                 default:
1181                                         msg += ('Please inform your helpdesk/developers of this error:\nFIXME -- this case "' + (data.hash.ccs[check.copy.status()] ? data.hash.ccs[check.copy.status()].name() : check.copy.status().name()) + '" is unhandled.\n');
1182                                         msg += 'This item needs to be routed to ' + check.route_to + '.';
1183                                 break;
1184                         }
1185                         if (msg) error.yns_alert(msg,'Alert',null,'OK',null,"Check here to confirm this message");
1186
1187                 } else /* ROUTE_ITEM */ if (check.ilsevent == 7000) {
1188
1189                         var lib = data.hash.aou[ check.org ];
1190                         check.route_to = lib.shortname();
1191                         msg += 'Destination: ' + check.route_to + '.\n';
1192                         msg += '\n' + lib.name() + '\n';
1193                         try {
1194                                 if (lib.holds_address() ) {
1195                                         var a = network.simple_request('FM_AOA_RETRIEVE',[ lib.holds_address() ]);
1196                                         if (typeof a.ilsevent != 'undefined') throw(a);
1197                                         if (a.street1()) msg += a.street1() + '\n';
1198                                         if (a.street2()) msg += a.street2() + '\n';
1199                                         msg += (a.city() ? a.city() + ', ' : '') + (a.state() ? a.state() + ' ' : '') + (a.post_code() ? a.post_code() : '') + '\n';
1200                                 } else {
1201                                         msg += "We do not have a holds address for this library.\n";
1202                                 }
1203                         } catch(E) {
1204                                 msg += 'Unable to retrieve mailing address.\n';
1205                                 error.standard_unexpected_error_alert('Unable to retrieve mailing address.',E);
1206                         }
1207                         msg += '\nBarcode: ' + check.payload.copy.barcode() + '\n';
1208                         msg += 'Title: ' + (check.payload.record ? check.payload.record.title() : check.payload.copy.dummy_title() ) + '\n';
1209                         msg += 'Author: ' + (check.payload.record ? check.payload.record.author() :check.payload.copy.dummy_author()  ) + '\n';
1210                         JSAN.use('util.date');
1211                         if (check.payload.hold) {
1212                                 JSAN.use('patron.util');
1213                                 var au_obj = patron.util.retrieve_fleshed_au_via_id( session, check.payload.hold.usr() );
1214                                 msg += '\nHold for patron ' + au_obj.family_name() + ', ' + au_obj.first_given_name() + ' ' + au_obj.second_given_name() + '\n';
1215                                 msg += 'Barcode: ' + au_obj.card().barcode() + '\n';
1216                                 if (check.payload.hold.phone_notify()) msg += 'Notify by phone: ' + check.payload.hold.phone_notify() + '\n';
1217                                 if (check.payload.hold.email_notify()) msg += 'Notify by email: ' + (au_obj.email() ? au_obj.email() : '') + '\n';
1218                                 msg += '\nRequest Date: ' + util.date.formatted_date(check.payload.hold.request_time(),'%F');
1219                         }
1220                         var rv = 0;
1221                         msg += '\nSlip Date: ' + util.date.formatted_date(new Date(),'%F') + '\n';
1222                         if (!auto_print) rv = error.yns_alert_formatted(
1223                                 msg,
1224                                 'Transit Slip',
1225                                 "Print",
1226                                 "Don't Print",
1227                                 null,
1228                                 "Check here to confirm this message",
1229                                 '/xul/server/skin/media/images/turtle.gif'
1230                         );
1231                         if (rv == 0) {
1232                                 try {
1233                                         JSAN.use('util.print'); var print = new util.print();
1234                                         //print.simple( msg, { 'no_prompt' : true, 'content_type' : 'text/plain' } );
1235                                         msg = msg.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g,'<br/>');
1236                                         print.simple( msg , { 'no_prompt' : true, 'content_type' : 'text/html' } );
1237                                 } catch(E) {
1238                                         dump('Please inform your helpdesk/developers of this error:\nFIXME: ' + E + '\n');
1239                                         alert('Please inform your helpdesk/developers of this error:\nFIXME: ' + E + '\n');
1240                                 }
1241                         }
1242                         if (document.getElementById('no_change_label')) {
1243                                 var m = document.getElementById('no_change_label').getAttribute('value');
1244                                 document.getElementById('no_change_label').setAttribute('value',m + params.barcode + ' is in transit.  ');
1245                                 document.getElementById('no_change_label').setAttribute('hidden','false');
1246                         }
1247
1248                 } else /* ASSET_COPY_NOT_FOUND */ if (check.ilsevent == 1502) {
1249
1250                         check.route_to = 'CATALOGING';
1251                         error.yns_alert(
1252                                 'The barcode was either mis-scanned or the item needs to be cataloged.',
1253                                 'Alert',
1254                                 null,
1255                                 'OK',
1256                                 null,
1257                                 "Check here to confirm this message"
1258                         );
1259                         if (document.getElementById('no_change_label')) {
1260                                 var m = document.getElementById('no_change_label').getAttribute('value');
1261                                 document.getElementById('no_change_label').setAttribute('value',m + params.barcode + ' is mis-scanned or not cataloged.  ');
1262                                 document.getElementById('no_change_label').setAttribute('hidden','false');
1263                         }
1264
1265                 } else /* NETWORK TIMEOUT */ if (check.ilsevent == -1) {
1266                         error.standard_network_error_alert('Check In Failed.  If you wish to use the offline interface, in the top menubar select Circulation -> Offline Interface');
1267                 } else {
1268
1269                         switch (check.ilsevent) {
1270                                 case 1203 /* COPY_BAD_STATUS */ : 
1271                                 case 1213 /* PATRON_BARRED */ :
1272                                 case 1217 /* PATRON_INACTIVE */ :
1273                                 case 1224 /* PATRON_ACCOUNT_EXPIRED */ :
1274                                 case 7009 /* CIRC_CLAIMS_RETURNED */ :
1275                                 case 7010 /* COPY_ALERT_MESSAGE */ : 
1276                                 case 7011 /* COPY_STATUS_LOST */ : 
1277                                 case 7012 /* COPY_STATUS_MISSING */ : 
1278                                 case 7013 /* PATRON_EXCEEDS_FINES */ :
1279                                         return null; /* handled */
1280                                 break;
1281                         }
1282
1283                         throw(check);
1284
1285                 }
1286
1287                 return check;
1288         } catch(E) {
1289                 JSAN.use('util.error'); var error = new util.error();
1290                 error.standard_unexpected_error_alert('Check In Failed (in circ.util.checkin): ',E);
1291                 return null;
1292         }
1293 }
1294
1295 circ.util.renew_via_barcode = function ( barcode, patron_id, async ) {
1296         try {
1297                 var obj = {};
1298                 JSAN.use('util.network'); obj.network = new util.network();
1299                 JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.stash_retrieve();
1300
1301                 var params = { barcode: barcode };
1302                 if (patron_id) params.patron = patron_id;
1303
1304                 function renew_callback(req) {
1305                         try {
1306                                 var renew = req.getResultObject();
1307                                 if (typeof renew.ilsevent != 'undefined') renew = [ renew ];
1308                                 for (var j = 0; j < renew.length; j++) { 
1309                                         switch(renew[j].ilsevent) {
1310                                                 case 0 /* SUCCESS */ : break;
1311                                                 case 5000 /* PERM_FAILURE */: break;
1312                                                 case 1212 /* PATRON_EXCEEDS_OVERDUE_COUNT */ : break;
1313                                                 case 1213 /* PATRON_BARRED */ : break;
1314                                                 case 1215 /* CIRC_EXCEEDS_COPY_RANGE */ : break;
1315                                                 case 1224 /* PATRON_ACCOUNT_EXPIRED */ : break;
1316                                                 case 7002 /* PATRON_EXCEEDS_CHECKOUT_COUNT */ : break;
1317                                                 case 7003 /* COPY_CIRC_NOT_ALLOWED */ : break;
1318                                                 case 7004 /* COPY_NOT_AVAILABLE */ : break;
1319                                                 case 7006 /* COPY_IS_REFERENCE */ : break;
1320                                                 case 7007 /* COPY_NEEDED_FOR_HOLD */ : break;
1321                                                 case 7008 /* MAX_RENEWALS_REACHED */ : break; 
1322                                                 case 7009 /* CIRC_CLAIMS_RETURNED */ : break; 
1323                                                 case 7010 /* COPY_ALERT_MESSAGE */ : break;
1324                                                 case 7013 /* PATRON_EXCEEDS_FINES */ : break;
1325                                                 default:
1326                                                         throw(renew);
1327                                                 break;
1328                                         }
1329                                 }
1330                                 if (typeof async == 'function') async(renew);
1331                                 return renew;
1332                         } catch(E) {
1333                                 JSAN.use('util.error'); var error = new util.error();
1334                                 error.standard_unexpected_error_alert('Renew Failed for ' + barcode,E);
1335                                 return null;
1336                         }
1337                 }
1338
1339                 var renew = obj.network.simple_request(
1340                         'CHECKOUT_RENEW', 
1341                         [ ses(), params ],
1342                         async ? renew_callback : null,
1343                         {
1344                                 'title' : 'Override Renew Failure?',
1345                                 'overridable_events' : [ 
1346                                         1212 /* PATRON_EXCEEDS_OVERDUE_COUNT */,
1347                                         1213 /* PATRON_BARRED */,
1348                                         1215 /* CIRC_EXCEEDS_COPY_RANGE */,
1349                                         7002 /* PATRON_EXCEEDS_CHECKOUT_COUNT */,
1350                                         7003 /* COPY_CIRC_NOT_ALLOWED */,
1351                                         7004 /* COPY_NOT_AVAILABLE */,
1352                                         7006 /* COPY_IS_REFERENCE */,
1353                                         7007 /* COPY_NEEDED_FOR_HOLD */,
1354                                         7008 /* MAX_RENEWALS_REACHED */, 
1355                                         7009 /* CIRC_CLAIMS_RETURNED */, 
1356                                         7010 /* COPY_ALERT_MESSAGE */,
1357                                         7013 /* PATRON_EXCEEDS_FINES */,
1358                                 ],
1359                                 'text' : {
1360                                         '1212' : function(r) { return 'Barcode: ' + barcode; },
1361                                         '1213' : function(r) { return 'Barcode: ' + barcode; },
1362                                         '1215' : function(r) { return 'Barcode: ' + barcode; },
1363                                         '7002' : function(r) { return 'Barcode: ' + barcode; },
1364                                         '7003' : function(r) { return 'Barcode: ' + barcode; },
1365                                         '7004' : function(r) {
1366                                                 return 'Barcode: ' + barcode + ' Status: ' + r.payload.status().name();
1367                                         },
1368                                         '7006' : function(r) { return 'Barcode: ' + barcode; },
1369                                         '7007' : function(r) { return 'Barcode: ' + barcode; },
1370                                         '7008' : function(r) { return 'Barcode: ' + barcode; },
1371                                         '7009' : function(r) { return 'Barcode: ' + barcode; },
1372                                         '7010' : function(r) {
1373                                                 return 'Barcode: ' + barcode + ' Message: ' + r.payload;
1374                                         },
1375                                         '7013' : function(r) { return 'Barcode: ' + barcode; },
1376                                 }
1377                         }
1378                 );
1379                 if (! async ) return renew_callback( { 'getResultObject' : function() { return renew; } } );
1380
1381         } catch(E) {
1382                 JSAN.use('util.error'); var error = new util.error();
1383                 error.standard_unexpected_error_alert('Renew Failed for ' + barcode,E);
1384                 return null;
1385         }
1386 }
1387
1388
1389
1390 dump('exiting circ/util.js\n');