]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/circ/copy_status.js
Handle a VOLUME_LABEL_EXISTS event. We might want to consider offering a magic item...
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / circ / copy_status.js
1 dump('entering circ.copy_status.js\n');
2
3 if (typeof circ == 'undefined') circ = {};
4 circ.copy_status = function (params) {
5
6         JSAN.use('util.error'); this.error = new util.error();
7         JSAN.use('util.network'); this.network = new util.network();
8         JSAN.use('util.barcode');
9         JSAN.use('util.date');
10         JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
11         JSAN.use('util.sound'); this.sound = new util.sound();
12 }
13
14 circ.copy_status.prototype = {
15         'selection_list' : [],
16         'list_barcode_map' : {},
17
18         'init' : function( params ) {
19
20                 var obj = this;
21
22                 JSAN.use('circ.util');
23                 var columns = circ.util.columns( 
24                         { 
25                                 'barcode' : { 'hidden' : false },
26                                 'title' : { 'hidden' : false },
27                                 'location' : { 'hidden' : false },
28                                 'call_number' : { 'hidden' : false },
29                                 'status' : { 'hidden' : false },
30                                 'alert_message' : { 'hidden' : false },
31                                 'due_date' : { 'hidden' : false },
32                         },
33                         {
34                                 'except_these' : [
35                                         'checkin_time', 'checkin_time_full', 'route_to', 'message', 'uses', 'xact_finish',
36                                 ],
37                         }
38                 );
39
40                 JSAN.use('util.list'); obj.list = new util.list('copy_status_list');
41                 obj.list.init(
42                         {
43                                 'columns' : columns,
44                                 'map_row_to_columns' : circ.util.std_map_row_to_columns(),
45                                 'on_select' : function(ev) {
46                                         try {
47                                                 JSAN.use('util.functional');
48                                                 var sel = obj.list.retrieve_selection();
49                                                 obj.selection_list = util.functional.map_list(
50                                                         sel,
51                                                         function(o) { return JSON2js(o.getAttribute('retrieve_id')); }
52                                                 );
53                                                 obj.error.sdump('D_TRACE','circ/copy_status: selection list = ' + js2JSON(obj.selection_list) );
54                                                 if (obj.selection_list.length == 0) {
55                                                         obj.controller.view.sel_checkin.setAttribute('disabled','true');
56                                                         obj.controller.view.cmd_replace_barcode.setAttribute('disabled','true');
57                                                         obj.controller.view.sel_edit.setAttribute('disabled','true');
58                                                         obj.controller.view.sel_opac.setAttribute('disabled','true');
59                                                         obj.controller.view.sel_bucket.setAttribute('disabled','true');
60                                                         obj.controller.view.sel_copy_details.setAttribute('disabled','true');
61                                                         obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','true');
62                                                         obj.controller.view.sel_mark_items_missing.setAttribute('disabled','true');
63                                                         obj.controller.view.sel_patron.setAttribute('disabled','true');
64                                                         obj.controller.view.sel_spine.setAttribute('disabled','true');
65                                                         obj.controller.view.sel_transit_abort.setAttribute('disabled','true');
66                                                         obj.controller.view.sel_clip.setAttribute('disabled','true');
67                                                         obj.controller.view.sel_renew.setAttribute('disabled','true');
68                                                         obj.controller.view.cmd_add_items.setAttribute('disabled','true');
69                                                         obj.controller.view.cmd_delete_items.setAttribute('disabled','true');
70                                                         obj.controller.view.cmd_transfer_items.setAttribute('disabled','true');
71                                                         obj.controller.view.cmd_add_volumes.setAttribute('disabled','true');
72                                                         obj.controller.view.cmd_edit_volumes.setAttribute('disabled','true');
73                                                         obj.controller.view.cmd_delete_volumes.setAttribute('disabled','true');
74                                                         obj.controller.view.cmd_mark_volume.setAttribute('disabled','true');
75                                                         obj.controller.view.cmd_mark_library.setAttribute('disabled','true');
76                                                         obj.controller.view.cmd_transfer_volume.setAttribute('disabled','true');
77                                                 } else {
78                                                         obj.controller.view.sel_checkin.setAttribute('disabled','false');
79                                                         obj.controller.view.cmd_replace_barcode.setAttribute('disabled','false');
80                                                         obj.controller.view.sel_edit.setAttribute('disabled','false');
81                                                         obj.controller.view.sel_opac.setAttribute('disabled','false');
82                                                         obj.controller.view.sel_patron.setAttribute('disabled','false');
83                                                         obj.controller.view.sel_bucket.setAttribute('disabled','false');
84                                                         obj.controller.view.sel_copy_details.setAttribute('disabled','false');
85                                                         obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','false');
86                                                         obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');
87                                                         obj.controller.view.sel_spine.setAttribute('disabled','false');
88                                                         obj.controller.view.sel_transit_abort.setAttribute('disabled','false');
89                                                         obj.controller.view.sel_clip.setAttribute('disabled','false');
90                                                         obj.controller.view.sel_renew.setAttribute('disabled','false');
91                                                         obj.controller.view.cmd_add_items.setAttribute('disabled','false');
92                                                         obj.controller.view.cmd_delete_items.setAttribute('disabled','false');
93                                                         obj.controller.view.cmd_transfer_items.setAttribute('disabled','false');
94                                                         obj.controller.view.cmd_add_volumes.setAttribute('disabled','false');
95                                                         obj.controller.view.cmd_edit_volumes.setAttribute('disabled','false');
96                                                         obj.controller.view.cmd_delete_volumes.setAttribute('disabled','false');
97                                                         obj.controller.view.cmd_mark_volume.setAttribute('disabled','false');
98                                                         obj.controller.view.cmd_mark_library.setAttribute('disabled','false');
99                                                         obj.controller.view.cmd_transfer_volume.setAttribute('disabled','false');
100                                                 }
101                                         } catch(E) {
102                                                 alert('FIXME: ' + E);
103                                         }
104                                 },
105                         }
106                 );
107                 
108                 JSAN.use('util.controller'); obj.controller = new util.controller();
109                 obj.controller.init(
110                         {
111                                 'control_map' : {
112                                         'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
113                                         'sel_clip' : [
114                                                 ['command'],
115                                                 function() { obj.list.clipboard(); }
116                                         ],
117                                         'sel_checkin' : [
118                                                 ['command'],
119                                                 function() {
120                                                         try {
121                                                                 var funcs = [];
122                                                                 JSAN.use('circ.util');
123                                                                 for (var i = 0; i < obj.selection_list.length; i++) {
124                                                                         var barcode = obj.selection_list[i].barcode;
125                                                                         var checkin = circ.util.checkin_via_barcode( ses(), { 'barcode' : barcode } );
126                                                                         funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
127                                                                 }
128                                                                 for (var i = 0; i < funcs.length; i++) { funcs[i](); }
129                                                                 alert('Action complete.');
130                                                         } catch(E) {
131                                                                 obj.error.standard_unexpected_error_alert('Checkin did not likely happen.',E);
132                                                         }
133                                                 }
134                                         ],
135                                         'cmd_replace_barcode' : [
136                                                 ['command'],
137                                                 function() {
138                                                         try {
139                                                                 var funcs = [];
140                                                                 JSAN.use('cat.util');
141                                                                 for (var i = 0; i < obj.selection_list.length; i++) {
142                                                                         try { 
143                                                                                 var barcode = obj.selection_list[i].barcode;
144                                                                                 var new_bc = cat.util.replace_barcode( barcode );
145                                                                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(new_bc) );
146                                                                         } catch(E) {
147                                                                                 obj.error.standard_unexpected_error_alert('Barcode ' + barcode + ' was not likely replaced.',E);
148                                                                         }
149                                                                 }
150                                                                 for (var i = 0; i < funcs.length; i++) { funcs[i](); }
151                                                                 alert('Action complete.');
152                                                         } catch(E) {
153                                                                 obj.error.standard_unexpected_error_alert('Barcode replacements did not likely happen.',E);
154                                                         }
155                                                 }
156                                         ],
157                                         'sel_edit' : [
158                                                 ['command'],
159                                                 function() {
160                                                         try {
161                                                                 var funcs = [];
162                                                                 obj.spawn_copy_editor();
163                                                                 for (var i = 0; i < obj.selection_list.length; i++) {
164                                                                                 var barcode = obj.selection_list[i].barcode;
165                                                                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
166                                                                 }
167                                                                 for (var i = 0; i < funcs.length; i++) { funcs[i](); }
168                                                         } catch(E) {
169                                                                 obj.error.standard_unexpected_error_alert('with copy editor',E);
170                                                         }
171                                                 }
172                                         ],
173                                         'sel_spine' : [
174                                                 ['command'],
175                                                 function() {
176                                                         JSAN.use('cat.util');
177                                                         cat.util.spawn_spine_editor(obj.selection_list);
178                                                 }
179                                         ],
180                                         'sel_opac' : [
181                                                 ['command'],
182                                                 function() {
183                                                         JSAN.use('cat.util');
184                                                         cat.util.show_in_opac(obj.selection_list);
185                                                 }
186                                         ],
187                                         'sel_transit_abort' : [
188                                                 ['command'],
189                                                 function() {
190                                                         var funcs = [];
191                                                         JSAN.use('circ.util');
192                                                         circ.util.abort_transits(obj.selection_list);
193                                                         for (var i = 0; i < obj.selection_list.length; i++) {
194                                                                 var barcode = obj.selection_list[i].barcode;
195                                                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
196                                                         }
197                                                         for (var i = 0; i < funcs.length; i++) { funcs[i](); }
198                                                         alert('Action complete.');
199                                                 }
200                                         ],
201                                         'sel_patron' : [
202                                                 ['command'],
203                                                 function() {
204                                                         JSAN.use('circ.util');
205                                                         circ.util.show_last_few_circs(obj.selection_list);
206                                                 }
207                                         ],
208                                         'sel_copy_details' : [
209                                                 ['command'],
210                                                 function() {
211                                                         JSAN.use('circ.util');
212                                                         for (var i = 0; i < obj.selection_list.length; i++) {
213                                                                 circ.util.show_copy_details( obj.selection_list[i].copy_id );
214                                                         }
215                                                 }
216                                         ],
217                                         'sel_renew' : [
218                                                 ['command'],
219                                                 function() {
220                                                         var funcs = [];
221                                                         JSAN.use('circ.util');
222                                                         for (var i = 0; i < obj.selection_list.length; i++) {
223                                                                 var test = obj.selection_list[i].renewable;
224                                                                 var barcode = obj.selection_list[i].barcode;
225                                                                 if (test == 't') {
226                                                                         circ.util.renew_via_barcode( barcode );
227                                                                         funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
228                                                                 } else {
229                                                                         alert('Item with barcode ' + barcode + ' is not circulating.');
230                                                                 }
231                                                         }
232                                                         for (var i = 0; i < funcs.length; i++) { funcs[i](); }
233                                                         alert('Action complete.');
234                                                 }
235                                         ],
236
237                                         'sel_mark_items_damaged' : [
238                                                 ['command'],
239                                                 function() {
240                                                         var funcs = [];
241                                                         JSAN.use('cat.util'); JSAN.use('util.functional');
242                                                         cat.util.mark_item_damaged( util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } ) );
243                                                         for (var i = 0; i < obj.selection_list.length; i++) {
244                                                                 var barcode = obj.selection_list[i].barcode;
245                                                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
246                                                         }
247                                                         for (var i = 0; i < funcs.length; i++) { funcs[i](); }
248                                                 }
249                                         ],
250                                         'sel_mark_items_missing' : [
251                                                 ['command'],
252                                                 function() {
253                                                         var funcs = [];
254                                                         JSAN.use('cat.util'); JSAN.use('util.functional');
255                                                         cat.util.mark_item_missing( util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } ) );
256                                                         for (var i = 0; i < obj.selection_list.length; i++) {
257                                                                 var barcode = obj.selection_list[i].barcode;
258                                                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
259                                                         }
260                                                         for (var i = 0; i < funcs.length; i++) { funcs[i](); }
261                                                 }
262                                         ],
263                                         'sel_bucket' : [
264                                                 ['command'],
265                                                 function() {
266                                                         JSAN.use('cat.util');
267                                                         cat.util.add_copies_to_bucket(obj.selection_list);
268                                                 }
269                                         ],
270                                         'copy_status_barcode_entry_textbox' : [
271                                                 ['keypress'],
272                                                 function(ev) {
273                                                         if (ev.keyCode && ev.keyCode == 13) {
274                                                                 obj.copy_status();
275                                                         }
276                                                 }
277                                         ],
278                                         'cmd_broken' : [
279                                                 ['command'],
280                                                 function() { alert('Not Yet Implemented'); }
281                                         ],
282                                         'cmd_copy_status_submit_barcode' : [
283                                                 ['command'],
284                                                 function() {
285                                                         obj.copy_status();
286                                                 }
287                                         ],
288                                         'cmd_copy_status_upload_file' : [
289                                                 ['command'],
290                                                 function() {
291                                                         function pick_file(mode) {
292                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
293                                                                 var nsIFilePicker = Components.interfaces.nsIFilePicker;
294                                                                 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance( nsIFilePicker );
295                                                                 fp.init( 
296                                                                         window, 
297                                                                         mode == 'open' ? "Import Barcode File" : "Save Barcode File As", 
298                                                                         mode == 'open' ? nsIFilePicker.modeOpen : nsIFilePicker.modeSave
299                                                                 );
300                                                                 fp.appendFilters( nsIFilePicker.filterAll );
301                                                                 var fp_result = fp.show();
302                                                                 if ( ( fp_result == nsIFilePicker.returnOK || fp_result == nsIFilePicker.returnReplace ) && fp.file ) {
303                                                                         return fp.file;
304                                                                 } else {
305                                                                         return null;
306                                                                 }
307                                                         }
308                                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
309                                                         JSAN.use('util.file');
310                                                         var f = pick_file('open');
311                                                         var i_file = new util.file(''); i_file._file = f;
312                                                         var content = i_file.get_content();
313                                                         i_file.close();
314                                                         var barcodes = content.split(/\s+/);
315                                         if (barcodes.length > 0) {
316                                             JSAN.use('util.exec'); var exec = new util.exec();
317                                             var funcs = [];
318                                             for (var i = 0; i < barcodes.length; i++) {
319                                                 funcs.push(
320                                                     function(b){
321                                                         return function() {
322                                                             obj.copy_status(b);
323                                                         }
324                                                     }(barcodes[i])
325                                                 );
326                                             }
327                                                                 funcs.push( function() { alert('File uploaded.'); } );
328                                             exec.chain( funcs );
329                                         } else {
330                                                                 alert('No barcodes found in file.');
331                                                         }
332
333                                                 }
334                                         ],
335                                         'cmd_copy_status_print' : [
336                                                 ['command'],
337                                                 function() {
338                                                         try {
339                                                                 obj.list.on_all_fleshed =
340                                                                         function() {
341                                                                                 try {
342                                                                                         dump( js2JSON( obj.list.dump_with_keys() ) + '\n' );
343                                                                                         obj.data.stash_retrieve();
344                                                                                         var lib = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
345                                                                                         lib.children(null);
346                                                                                         var p = { 
347                                                                                                 'lib' : lib,
348                                                                                                 'staff' : obj.data.list.au[0],
349                                                                                                 'header' : obj.data.print_list_templates.item_status.header,
350                                                                                                 'line_item' : obj.data.print_list_templates.item_status.line_item,
351                                                                                                 'footer' : obj.data.print_list_templates.item_status.footer,
352                                                                                                 'type' : obj.data.print_list_templates.item_status.type,
353                                                                                                 'list' : obj.list.dump_with_keys(),
354                                                                                         };
355                                                                                         JSAN.use('util.print'); var print = new util.print();
356                                                                                         print.tree_list( p );
357                                                                                         setTimeout(function(){ obj.list.on_all_fleshed = null; },0);
358                                                                                 } catch(E) {
359                                                                                         obj.error.standard_unexpected_error_alert('print',E); 
360                                                                                 }
361                                                                         }
362                                                                 obj.list.full_retrieve();
363                                                         } catch(E) {
364                                                                 obj.error.standard_unexpected_error_alert('print',E); 
365                                                         }
366                                                 }
367                                         ],
368                                         'cmd_copy_status_export' : [
369                                                 ['command'],
370                                                 function() {
371                                                         try {
372                                                                 obj.list.on_all_fleshed =
373                                                                         function() {
374                                                                                 try {
375                                                                                         dump( obj.list.dump_csv() + '\n' );
376                                                                                         copy_to_clipboard(obj.list.dump_csv());
377                                                                                         setTimeout(function(){ obj.list.on_all_fleshed = null; },0);
378                                                                                 } catch(E) {
379                                                                                         obj.error.standard_unexpected_error_alert('export',E); 
380                                                                                 }
381                                                                         }
382                                                                 obj.list.full_retrieve();
383                                                         } catch(E) {
384                                                                 obj.error.standard_unexpected_error_alert('export',E); 
385                                                         }
386                                                 }
387                                         ],
388                                         'cmd_copy_status_print_export' : [
389                                                 ['command'],
390                                                 function() {
391                                                         try {
392                                                                 obj.list.on_all_fleshed =
393                                                                         function() {
394                                                                                 try {
395                                                                                         dump( obj.list.dump_csv() + '\n' );
396                                                                                         //copy_to_clipboard(obj.list.dump_csv());
397                                                                                         JSAN.use('util.print'); var print = new util.print();
398                                                                                         print.simple(obj.list.dump_csv(),{'content_type':'text/plain'});
399                                                                                         setTimeout(function(){ obj.list.on_all_fleshed = null; },0);
400                                                                                 } catch(E) {
401                                                                                         obj.error.standard_unexpected_error_alert('export',E); 
402                                                                                 }
403                                                                         }
404                                                                 obj.list.full_retrieve();
405                                                         } catch(E) {
406                                                                 obj.error.standard_unexpected_error_alert('export',E); 
407                                                         }
408                                                 }
409                                         ],
410
411                                         'cmd_add_items' : [
412                                                 ['command'],
413                                                 function() {
414                                                         try {
415
416                                                                 JSAN.use('util.functional');
417                                                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
418                                                                 if (list.length == 0) return;
419
420                                                                 var copy_shortcut = {}; var map_acn = {};
421
422                                                                 for (var i = 0; i < list.length; i++) {
423                                                                         var volume_id = list[i];
424                                                                         if (volume_id == -1) continue; /* ignore magic pre-cat volume */
425                                                                         if (! map_acn[volume_id]) {
426                                                                                 map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE',[ volume_id ]);
427                                                                         }
428                                                                         var record_id = map_acn[ volume_id ].record();
429                                                                         var ou_id = map_acn[ volume_id ].owning_lib();
430                                                                         var label = map_acn[ volume_id ].label();
431                                                                         if (!copy_shortcut[record_id]) copy_shortcut[record_id] = {};
432                                                                         if (!copy_shortcut[record_id][ou_id]) copy_shortcut[record_id][ou_id] = {};
433                                                                         copy_shortcut[record_id][ou_id][ label ] = volume_id;
434
435                                                                 }
436
437                                                                 for (var r in copy_shortcut) {
438
439                                                                         /* quick fix */  /* what was this fixing? */
440                                                                         list = []; for (var i in copy_shortcut[r]) { list.push( i ); }
441
442                                                                         var edit = 0;
443                                                                         try {
444                                                                                 edit = obj.network.request(
445                                                                                         api.PERM_MULTI_ORG_CHECK.app,
446                                                                                         api.PERM_MULTI_ORG_CHECK.method,
447                                                                                         [ 
448                                                                                                 ses(), 
449                                                                                                 obj.data.list.au[0].id(), 
450                                                                                                 list,
451                                                                                                 [ 'CREATE_COPY' ]
452                                                                                         ]
453                                                                                 ).length == 0 ? 1 : 0;
454                                                                         } catch(E) {
455                                                                                 obj.error.sdump('D_ERROR','batch permission check: ' + E);
456                                                                         }
457         
458                                                                         if (edit==0) return; // no read-only view for this interface
459         
460                                                                         var title = 'Add Item for record #' + r;
461         
462                                                                         JSAN.use('util.window'); var win = new util.window();
463                                                                         var w = win.open(
464                                                                                 window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
465                                                                                         //+'?doc_id=' + window.escape(r)
466                                                                                         //+'&ou_ids=' + window.escape( js2JSON(list) )
467                                                                                         //+'&copy_shortcut=' + window.escape( js2JSON(copy_shortcut[r]) ),
468                                                                                 title,
469                                                                                 'chrome,resizable',
470                                                                                 { 'doc_id' : r, 'ou_ids' : list, 'copy_shortcut' : copy_shortcut[r] }
471                                                                         );
472                                                                 }
473
474                                                         } catch(E) {
475                                                                 obj.error.standard_unexpected_error_alert('copy status -> add copies',E);
476                                                         }
477                                                 }
478
479                                         ],
480                                         'cmd_delete_items' : [
481                                                 ['command'],
482                                                 function() {
483                                                         try {
484
485                                 JSAN.use('util.functional');
486
487                                                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } );
488
489                                 var copies = util.functional.map_list(
490                                     list,
491                                     function (acp_id) {
492                                         return obj.network.simple_request('FM_ACP_RETRIEVE',[acp_id]);
493                                     }
494                                 );
495
496                                 for (var i = 0; i < copies.length; i++) {
497                                     copies[i].ischanged(1);
498                                     copies[i].isdeleted(1);
499                                 }
500
501                                                                 if (! window.confirm('Are you sure sure you want to delete these items? ' + util.functional.map_list( copies, function(o) { return o.barcode(); }).join(", ")) ) return;
502
503                                 var robj = obj.network.simple_request('FM_ACP_FLESHED_BATCH_UPDATE',[ ses(), copies, true]);
504                                                                 var robj = obj.network.simple_request(
505                                                                         'FM_ACP_FLESHED_BATCH_UPDATE', 
506                                                                         [ ses(), copies, true ], 
507                                                                         null,
508                                                                         {
509                                                                                 'title' : 'Override Delete Failure?',
510                                                                                 'overridable_events' : [
511                                                                                         1208 /* TITLE_LAST_COPY */,
512                                                                                         1227 /* COPY_DELETE_WARNING */,
513                                                                                 ]
514                                                                         }
515                                                                 );
516         
517                                 if (typeof robj.ilsevent != 'undefined') {
518                                                                         switch(robj.ilsevent) {
519                                                                                 case 1208 /* TITLE_LAST_COPY */:
520                                                                                 case 1227 /* COPY_DELETE_WARNING */:
521                                                                                 break;
522                                                                                 default:
523                                                                                         obj.error.standard_unexpected_error_alert('Batch Item Deletion',robj);
524                                                                                 break;
525                                                                         }
526                                                                 } else { alert('Items Deleted'); }
527
528                                                         } catch(E) {
529                                                                 obj.error.standard_unexpected_error_alert('copy status -> delete items',E);
530                                                         }
531                                                 }
532                                         ],
533                                         'cmd_transfer_items' : [
534                                                 ['command'],
535                                                 function() {
536                                                                 try {
537                                                                         obj.data.stash_retrieve();
538                                                                         if (!obj.data.marked_volume) {
539                                                                                 alert('Please mark a volume as the destination and then try this again.');
540                                                                                 return;
541                                                                         }
542                                                                         
543                                                                         JSAN.use('util.functional');
544
545                                                                         var list = util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } );
546
547                                                                         var volume = obj.network.simple_request('FM_ACN_RETRIEVE',[ obj.data.marked_volume ]);
548
549                                                                         JSAN.use('cat.util'); cat.util.transfer_copies( { 
550                                                                                 'copy_ids' : list, 
551                                                                                 'docid' : volume.record(),
552                                                                                 'volume_label' : volume.label(),
553                                                                                 'owning_lib' : volume.owning_lib(),
554                                                                         } );
555
556                                                                 } catch(E) {
557                                                                         obj.error.standard_unexpected_error_alert('All copies not likely transferred.',E);
558                                                                 }
559                                                         }
560
561                                         ],
562                                         'cmd_add_volumes' : [
563                                                 ['command'],
564                                                 function() {
565                                                         try {
566                                                                 JSAN.use('util.functional');
567                                                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
568                                                                 if (list.length == 0) return;
569
570                                                                 var aou_hash = {}; var map_acn = {};
571
572                                                                 for (var i = 0; i < list.length; i++) {
573                                                                         var volume_id = list[i];
574                                                                         if (volume_id == -1) continue; /* ignore magic pre-cat volume */
575                                                                         if (! map_acn[volume_id]) {
576                                                                                 map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE',[ volume_id ]);
577                                                                         }
578                                                                         var record_id = map_acn[ volume_id ].record();
579                                                                         var ou_id = map_acn[ volume_id ].owning_lib();
580                                                                         var label = map_acn[ volume_id ].label();
581                                                                         if (!aou_hash[record_id]) aou_hash[record_id] = {};
582                                                                         aou_hash[record_id][ou_id] = 1;
583
584                                                                 }
585
586                                                                 for (var r in aou_hash) {
587
588                                                                         list = []; for (var org in aou_hash[r]) list.push(org);
589
590                                                                         var edit = 0;
591                                                                         try {
592                                                                                 edit = obj.network.request(
593                                                                                         api.PERM_MULTI_ORG_CHECK.app,
594                                                                                         api.PERM_MULTI_ORG_CHECK.method,
595                                                                                         [ 
596                                                                                                 ses(), 
597                                                                                                 obj.data.list.au[0].id(), 
598                                                                                                 list,
599                                                                                                 [ 'CREATE_VOLUME', 'CREATE_COPY' ]
600                                                                                         ]
601                                                                                 ).length == 0 ? 1 : 0;
602                                                                         } catch(E) {
603                                                                                 obj.error.sdump('D_ERROR','batch permission check: ' + E);
604                                                                         }
605
606                                                                         if (edit==0) {
607                                                                                 alert("You don't have permission to add volumes to that library.");
608                                                                                 return; // no read-only view for this interface
609                                                                         }
610
611                                                                         var title = 'Add Volume/Item for Record # ' + r;
612
613                                                                         JSAN.use('util.window'); var win = new util.window();
614                                                                         var w = win.open(
615                                                                                 window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
616                                                                                         //+'?doc_id=' + window.escape(r)
617                                                                                         //+'&ou_ids=' + window.escape( js2JSON(list) ),
618                                                                                 title,
619                                                                                 'chrome,resizable',
620                                                                                 { 'doc_id' : r, 'ou_ids' : list }
621                                                                         );
622
623                                                                 }
624
625                                                         } catch(E) {
626                                                                 obj.error.standard_unexpected_error_alert('copy status -> add volumes',E);
627                                                         }
628                                                 }
629
630                                         ],
631                                         'cmd_edit_volumes' : [
632                                                 ['command'],
633                                                 function() {
634                                                         try {
635                                                                 JSAN.use('util.functional');
636                                                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
637                                                                 if (list.length == 0) return;
638
639                                                                 var volume_hash = {}; var map_acn = {};
640
641                                                                 for (var i = 0; i < list.length; i++) {
642                                                                         var volume_id = list[i];
643                                                                         if (volume_id == -1) continue; /* ignore magic pre-cat volume */
644                                                                         if (! map_acn[volume_id]) {
645                                                                                 map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE',[ volume_id ]);
646                                                                                 map_acn[ volume_id ].copies( [] );
647                                                                         }
648                                                                         var record_id = map_acn[ volume_id ].record();
649                                                                         if (!volume_hash[record_id]) volume_hash[record_id] = {};
650                                                                         volume_hash[record_id][volume_id] = 1;
651                                                                 }
652
653                                                                 for (var rec in volume_hash) {
654
655                                                                         list = []; for (var v in volume_hash[rec]) list.push( map_acn[v] );
656
657                                                                         var edit = 0;
658                                                                         try {
659                                                                                 edit = obj.network.request(
660                                                                                         api.PERM_MULTI_ORG_CHECK.app,
661                                                                                         api.PERM_MULTI_ORG_CHECK.method,
662                                                                                         [ 
663                                                                                                 ses(), 
664                                                                                                 obj.data.list.au[0].id(), 
665                                                                                                 util.functional.map_list(
666                                                                                                         list,
667                                                                                                         function (o) {
668                                                                                                                 return o.owning_lib();
669                                                                                                         }
670                                                                                                 ),
671                                                                                                 [ 'UPDATE_VOLUME' ]
672                                                                                         ]
673                                                                                 ).length == 0 ? 1 : 0;
674                                                                         } catch(E) {
675                                                                                 obj.error.sdump('D_ERROR','batch permission check: ' + E);
676                                                                         }
677
678                                                                         if (edit==0) {
679                                                                                 alert("You don't have permission to edit this volume.");
680                                                                                 return; // no read-only view for this interface
681                                                                         }
682
683                                                                         var title = (list.length == 1 ? 'Volume' : 'Volumes') + ' for record # ' + rec;
684
685                                                                         JSAN.use('util.window'); var win = new util.window();
686                                                                         //obj.data.volumes_temp = js2JSON( list );
687                                                                         //obj.data.stash('volumes_temp');
688                                                                         var my_xulG = win.open(
689                                                                                 window.xulG.url_prefix(urls.XUL_VOLUME_EDITOR),
690                                                                                 title,
691                                                                                 'chrome,modal,resizable',
692                                                                                 { 'volumes' : list }
693                                                                         );
694
695                                                                         /* FIXME -- need to unique the temp space, and not rely on modalness of window */
696                                                                         //obj.data.stash_retrieve();
697                                                                         //var volumes = JSON2js( obj.data.volumes_temp );
698                                                                         var volumes = my_xulG.volumes;
699                                                                         if (!volumes) return;
700                                                                 
701                                                                         volumes = util.functional.filter_list(
702                                                                                 volumes,
703                                                                                 function (o) {
704                                                                                         return o.ischanged() == '1';
705                                                                                 }
706                                                                         );
707
708                                                                         volumes = util.functional.map_list(
709                                                                                 volumes,
710                                                                                 function (o) {
711                                                                                         o.record( rec ); // staff client 2 did not do this.  Does it matter?
712                                                                                         return o;
713                                                                                 }
714                                                                         );
715
716                                                                         if (volumes.length == 0) return;
717
718                                                                         try {
719                                                                                 var r = obj.network.request(
720                                                                                         api.FM_ACN_TREE_UPDATE.app,
721                                                                                         api.FM_ACN_TREE_UPDATE.method,
722                                                                                         [ ses(), volumes, false ]
723                                                                                 );
724                                         if (typeof r.ilsevent != 'undefined') {
725                                             switch(r.ilsevent) {
726                                                 case 1705 /* VOLUME_LABEL_EXISTS */ :
727                                                     alert("Edit failed:  You tried to change a volume's callnumber to one that is already in use for the given library.  You should transfer the items to the desired callnumber instead.");
728                                                     break;
729                                                 default: throw(r);
730                                             }
731                                         } else {
732                                                                                 alert('Volumes modified.');
733                                         }
734                                                                         } catch(E) {
735                                                                                 obj.error.standard_unexpected_error_alert('volume update error: ',E);
736                                                                         }
737
738                                                                 }
739                                                         } catch(E) {
740                                                                 obj.error.standard_unexpected_error_alert('Copy Status -> Volume Edit',E);
741                                                         }
742                                                 }
743
744                                         ],
745                                         'cmd_delete_volumes' : [
746                                                 ['command'],
747                                                 function() {
748                                                         try {
749                                                                 JSAN.use('util.functional');
750                                                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
751                                                                 if (list.length == 0) return;
752
753                                                                 var map_acn = {};
754
755                                                                 for (var i = 0; i < list.length; i++) {
756                                                                         var volume_id = list[i];
757                                                                         if (volume_id == -1) continue; /* ignore magic pre-cat volume */
758                                                                         if (! map_acn[volume_id]) {
759                                                                                 map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE',[ volume_id ]);
760                                                                         }
761                                                                 }
762
763                                                                 list = []; for (var v in map_acn) list.push( map_acn[v] );
764
765                                                                 var r = obj.error.yns_alert('Are you sure you would like to delete ' + (list.length != 1 ? 'these ' + list.length + ' volumes' : 'this one volume') + '?', 'Delete Volumes?', 'Delete', 'Cancel', null, 'Check here to confirm this action');
766
767                                                                 if (r == 0) {
768                                                                         for (var i = 0; i < list.length; i++) {
769                                                                                 list[i].isdeleted('1');
770                                                                         }
771                                                                         var robj = obj.network.simple_request(
772                                                                                 'FM_ACN_TREE_UPDATE', 
773                                                                                 [ ses(), list, true ],
774                                                                                 null,
775                                                                                 {
776                                                                                         'title' : 'Override Delete Failure?',
777                                                                                         'overridable_events' : [
778                                                                                         ]
779                                                                                 }
780                                                                         );
781                                                                         if (robj == null) throw(robj);
782                                                                         if (typeof robj.ilsevent != 'undefined') {
783                                                                                 if (robj.ilsevent == 1206 /* VOLUME_NOT_EMPTY */) {
784                                                                                         alert('You must delete all the copies on the volume before you may delete the volume itself.');
785                                                                                         return;
786                                                                                 }
787                                                                                 if (robj.ilsevent != 0) throw(robj);
788                                                                         }
789                                                                         alert('Volumes deleted.');
790                                                                 }
791                                                         } catch(E) {
792                                                                 obj.error.standard_unexpected_error_alert('copy status -> delete volumes',E);
793                                                         }
794
795                                                 }
796
797                                         ],
798                                         'cmd_mark_volume' : [
799                                                 ['command'],
800                                                 function() {
801                                                         try {
802                                                                 JSAN.use('util.functional');
803                                                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
804
805                                                                 if (list.length == 1) {
806                                                                         obj.data.marked_volume = list[0];
807                                                                         obj.data.stash('marked_volume');
808                                                                         alert('Volume marked as Item Transfer Destination');
809                                                                 } else {
810                                                                         obj.error.yns_alert('Choose just one Volume to mark as Item Transfer Destination','Limit Selection','OK',null,null,'Check here to confirm this dialog');
811                                                                 }
812                                                         } catch(E) {
813                                                                 obj.error.standard_unexpected_error_alert('copy status -> mark volume',E);
814                                                         }
815                                                 }
816                                         ],
817                                         'cmd_mark_library' : [
818                                                 ['command'],
819                                                 function() {
820                                                         try {
821                                                                 JSAN.use('util.functional');
822                                                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
823
824                                                                 if (list.length == 1) {
825                                                                         var v = obj.network.simple_request('FM_ACN_RETRIEVE',[list[0]]);
826                                                                         var owning_lib = v.owning_lib(); if (typeof owning_lib == 'object') owning_lib = owning_lib.id();
827
828                                                                         obj.data.marked_library = { 'lib' : owning_lib, 'docid' : v.record() };
829                                                                         obj.data.stash('marked_library');
830                                                                         alert('Library + Record marked as Volume Transfer Destination');
831                                                                 } else {
832                                                                         obj.error.yns_alert('Choose just one Library to mark as Volume Transfer Destination','Limit Selection','OK',null,null,'Check here to confirm this dialog');
833                                                                 }
834                                                         } catch(E) {
835                                                                 obj.error.standard_unexpected_error_alert('copy status -> mark library',E);
836                                                         }
837                                                 }
838                                         ],
839                                         'cmd_transfer_volume' : [
840                                                 ['command'],
841                                                 function() {
842                                                         try {
843                                                                         obj.data.stash_retrieve();
844                                                                         if (!obj.data.marked_library) {
845                                                                                 alert('Please mark a library as the destination from within holdings maintenance and then try this again.');
846                                                                                 return;
847                                                                         }
848                                                                         
849                                                                         JSAN.use('util.functional');
850
851                                                                         var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
852                                                                         if (list.length == 0) return;
853
854                                                                         var map_acn = {};
855
856                                                                         for (var i = 0; i < list.length; i++) {
857                                                                                 var volume_id = list[i];
858                                                                                 if (volume_id == -1) continue; /* ignore magic pre-cat volume */
859                                                                                 if (! map_acn[volume_id]) {
860                                                                                         map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE',[ volume_id ]);
861                                                                                 }
862                                                                         }
863
864                                                                         list = []; for (v in map_acn) list.push(map_acn[v]);
865
866                                                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
867                                                                         var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto">';
868                                                                         xml += '<description>Transfer volumes ';
869
870                                                                         xml += util.functional.map_list(
871                                                                                 list,
872                                                                                 function (o) {
873                                                                                         return o.label();
874                                                                                 }
875                                                                         ).join(", ");
876
877                                                                         xml += ' to library ' + obj.data.hash.aou[ obj.data.marked_library.lib ].shortname();
878                                                                         xml += ' on the following record?</description>';
879                                                                         xml += '<hbox><button label="Transfer" name="fancy_submit"/>';
880                                                                         xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
881                                                                         xml += '<iframe style="overflow: scroll" flex="1" src="' + urls.XUL_BIB_BRIEF + '?docid=' + obj.data.marked_library.docid + '"/>';
882                                                                         xml += '</vbox>';
883                                                                         JSAN.use('OpenILS.data');
884                                                                         //var data = new OpenILS.data(); data.init({'via':'stash'});
885                                                                         //data.temp_transfer = xml; data.stash('temp_transfer');
886                                                                         JSAN.use('util.window'); var win = new util.window();
887                                                                         var fancy_prompt_data = win.open(
888                                                                                 urls.XUL_FANCY_PROMPT,
889                                                                                 //+ '?xml_in_stash=temp_transfer'
890                                                                                 //+ '&title=' + window.escape('Volume Transfer'),
891                                                                                 'fancy_prompt', 'chrome,resizable,modal,width=500,height=300',
892                                                                                 { 'xml' : xml, 'title' : 'Volume Transfer' }
893                                                                         );
894                                                                 
895                                                                         if (fancy_prompt_data.fancy_status == 'incomplete') { alert('Transfer Aborted'); return; }
896
897                                                                         var robj = obj.network.simple_request(
898                                                                                 'FM_ACN_TRANSFER', 
899                                                                                 [ ses(), { 'docid' : obj.data.marked_library.docid, 'lib' : obj.data.marked_library.lib, 'volumes' : util.functional.map_list( list, function(o) { return o.id(); }) } ],
900                                                                                 null,
901                                                                                 {
902                                                                                         'title' : 'Override Volume Transfer Failure?',
903                                                                                         'overridable_events' : [
904                                                                                                 1208 /* TITLE_LAST_COPY */,
905                                                                                                 1219 /* COPY_REMOTE_CIRC_LIB */,
906                                                                                         ],
907                                                                                 }
908                                                                         );
909
910                                                                         if (typeof robj.ilsevent != 'undefined') {
911                                                                                 if (robj.ilsevent == 1221 /* ORG_CANNOT_HAVE_VOLS */) {
912                                                                                         alert('That destination cannot have volumes.');
913                                                                                 } else {
914                                                                                         throw(robj);
915                                                                                 }
916                                                                         } else {
917                                                                                 alert('Volumes transferred.');
918                                                                         }
919
920                                                         } catch(E) {
921                                                                 obj.error.standard_unexpected_error_alert('All volumes not likely transferred.',E);
922                                                         }
923                                                 }
924
925                                         ],
926                                 }
927                         }
928                 );
929                 this.controller.render();
930                 this.controller.view.copy_status_barcode_entry_textbox.focus();
931
932         },
933
934         'test_barcode' : function(bc) {
935                 var obj = this;
936                 var good = util.barcode.check(bc);
937                 var x = document.getElementById('strict_barcode');
938                 if (x && x.checked != true) return true;
939                 if (good) {
940                         return true;
941                 } else {
942                         if ( 1 == obj.error.yns_alert(
943                                                 'Bad checkdigit; possible mis-scan.  Use this barcode ("' + bc + '") anyway?',
944                                                 'Bad Barcode',
945                                                 'Cancel',
946                                                 'Accept Barcode',
947                                                 null,
948                                                 'Check here to confirm this action',
949                                                 '/xul/server/skin/media/images/bad_barcode.png'
950                         ) ) {
951                                 return true;
952                         } else {
953                                 return false;
954                         }
955                 }
956         },
957
958         'copy_status' : function(barcode,refresh) {
959                 var obj = this;
960                 try {
961                         try { document.getElementById('last_scanned').setAttribute('value',''); } catch(E) {}
962                         if (!barcode) barcode = obj.controller.view.copy_status_barcode_entry_textbox.value;
963                         if (!barcode) return;
964                         if (barcode) {
965                                 if ( obj.test_barcode(barcode) ) { /* good */ } else { /* bad */ return; }
966                         }
967                         JSAN.use('circ.util');
968                         function handle_req(req) {
969                                 try {
970                                         var details = req.getResultObject();
971                                         if (details == null) {
972                                                 throw('Something weird happened.  null result');
973                                         } else if (details.ilsevent) {
974                                                 switch(details.ilsevent) {
975                                                         case -1: 
976                                                                 obj.error.standard_network_error_alert(); 
977                                                                 obj.controller.view.copy_status_barcode_entry_textbox.select();
978                                                                 obj.controller.view.copy_status_barcode_entry_textbox.focus();
979                                                                 return;
980                                                         break;
981                                                         case 1502 /* ASSET_COPY_NOT_FOUND */ :
982                                                                 try { document.getElementById('last_scanned').setAttribute('value',barcode + ' was either mis-scanned or is not cataloged.'); } catch(E) {}
983                                                                 obj.error.yns_alert(barcode + ' was either mis-scanned or is not cataloged.','Not Cataloged','OK',null,null,'Check here to confirm this message');
984                                                                 obj.controller.view.copy_status_barcode_entry_textbox.select();
985                                                                 obj.controller.view.copy_status_barcode_entry_textbox.focus();
986                                                                 return;
987                                                         break;
988                                                         default: 
989                                                                 throw(details); 
990                                                         break;
991                                                 }
992                                         }
993                                         var msg = details.copy.barcode() + ' -- ';
994                                         if (details.copy.call_number() == -1) msg += 'Item is a Pre-Cat.  ';
995                                         if (details.hold) msg += 'Item is captured for a Hold.  ';
996                                         if (details.transit) msg += 'Item is in Transit.  ';
997                                         if (details.circ && ! details.circ.checkin_time()) msg += 'Item is circulating.  ';
998                                         try { document.getElementById('last_scanned').setAttribute('value',msg); } catch(E) {}
999                                         if (document.getElementById('trim_list')) {
1000                                                 var x = document.getElementById('trim_list');
1001                                                 if (x.checked) { obj.list.trim_list = 20; } else { obj.list.trim_list = null; }
1002                                         }
1003                                         var params = {
1004                                                 'retrieve_id' : js2JSON( 
1005                                                         { 
1006                                                                 'renewable' : details.circ ? 't' : 'f', 
1007                                                                 'copy_id' : details.copy.id(), 
1008                                                                 'acn_id' : details.volume ? details.volume.id() : -1, 
1009                                                                 'barcode' : barcode, 
1010                                                                 'doc_id' : details.mvr ? details.mvr.doc_id() : null  
1011                                                         } 
1012                                                 ),
1013                                                 'row' : {
1014                                                         'my' : {
1015                                                                 'mvr' : details.mvr,
1016                                                                 'acp' : details.copy,
1017                                                                 'acn' : details.volume,
1018                                                                 'atc' : details.transit,
1019                                                                 'circ' : details.circ,
1020                                                                 'ahr' : details.hold,
1021                                                         }
1022                                                 },
1023                                                 'to_top' : true,
1024                                         };
1025                                         if (!refresh) {
1026                                                 var nparams = obj.list.append(params);
1027                                                 if (!document.getElementById('trim_list').checked) {
1028                                                         if (typeof obj.list_barcode_map[barcode] == 'undefined') obj.list_barcode_map[barcode] =[];
1029                                                         obj.list_barcode_map[barcode].push(nparams);
1030                                                 }
1031                                         } else {
1032                                                 if (!document.getElementById('trim_list').checked) {
1033                                                         for (var i = 0; i < obj.list_barcode_map[barcode].length; i++) {
1034                                                                 params.my_node = obj.list_barcode_map[barcode][i].my_node;
1035                                                                 obj.list.refresh_row(params);
1036                                                         }
1037                                                 } else {
1038                                                         obj.list.append(params);
1039                                                 }
1040                                         }
1041                                 } catch(E) {
1042                                         obj.error.standard_unexpected_error_alert('barcode = ' + barcode,E);
1043                                 }
1044                         }
1045                         var result = obj.network.simple_request('FM_ACP_DETAILS_VIA_BARCODE', [ ses(), barcode ]);
1046                         handle_req({'getResultObject':function(){return result;}}); // used to be async
1047                         obj.controller.view.copy_status_barcode_entry_textbox.value = '';
1048                         obj.controller.view.copy_status_barcode_entry_textbox.focus();
1049                         
1050                 } catch(E) {
1051                         obj.error.standard_unexpected_error_alert('barcode = ' + barcode,E);
1052                         obj.controller.view.copy_status_barcode_entry_textbox.select();
1053                         obj.controller.view.copy_status_barcode_entry_textbox.focus();
1054                 }
1055
1056         },
1057         
1058         'spawn_copy_editor' : function() {
1059
1060                 /* FIXME -  a lot of redundant calls here */
1061
1062                 var obj = this;
1063
1064                 JSAN.use('util.widgets'); JSAN.use('util.functional');
1065
1066                 var list = obj.selection_list;
1067
1068                 list = util.functional.map_list(
1069                         list,
1070                         function (o) {
1071                                 return o.copy_id;
1072                         }
1073                 );
1074
1075                 var copies = util.functional.map_list(
1076                         list,
1077                         function (acp_id) {
1078                                 return obj.network.simple_request('FM_ACP_RETRIEVE',[acp_id]);
1079                         }
1080                 );
1081
1082                 var edit = 0;
1083                 try {
1084                         edit = obj.network.request(
1085                                 api.PERM_MULTI_ORG_CHECK.app,
1086                                 api.PERM_MULTI_ORG_CHECK.method,
1087                                 [ 
1088                                         ses(), 
1089                                         obj.data.list.au[0].id(), 
1090                                         util.functional.map_list(
1091                                                 copies,
1092                                                 function (o) {
1093                                                         return o.call_number() == -1 ? o.circ_lib() : obj.network.simple_request('FM_ACN_RETRIEVE',[o.call_number()]).owning_lib();
1094                                                 }
1095                                         ),
1096                                         copies.length == 1 ? [ 'UPDATE_COPY' ] : [ 'UPDATE_COPY', 'UPDATE_BATCH_COPY' ]
1097                                 ]
1098                         ).length == 0 ? 1 : 0;
1099                 } catch(E) {
1100                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
1101                 }
1102
1103                 JSAN.use('cat.util'); cat.util.spawn_copy_editor(list,edit);
1104
1105         },
1106
1107 }
1108
1109 dump('exiting circ.copy_status.js\n');