Lazy Circ (AKA partial barcode lookup)
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / circ / copy_status.js
1 dump('entering circ.copy_status.js\n');
2 // vim:noet:sw=4:ts=4:
3
4 if (typeof circ == 'undefined') { circ = {}; }
5 circ.copy_status = function (params) {
6
7     JSAN.use('util.error'); this.error = new util.error();
8     JSAN.use('util.network'); this.network = new util.network();
9     JSAN.use('util.barcode');
10     JSAN.use('util.date');
11     JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
12     JSAN.use('util.sound'); this.sound = new util.sound();
13 };
14
15 circ.copy_status.prototype = {
16     'selection_list' : [],
17     'list_copyid_map' : {},
18     'detail_map' : {},
19
20     'init' : function( params ) {
21
22         var obj = this;
23
24         JSAN.use('circ.util');
25         var columns = circ.util.columns( 
26             { 
27                 'barcode' : { 'hidden' : false },
28                 'title' : { 'hidden' : false },
29                 'location' : { 'hidden' : false },
30                 'call_number' : { 'hidden' : false },
31                 'acp_status' : { 'hidden' : false },
32                 'alert_message' : { 'hidden' : false },
33                 'due_date' : { 'hidden' : false }
34             },
35             {
36                 'except_these' : [
37                     'route_to', 'message', 'uses'
38                 ]
39             }
40         );
41
42         JSAN.use('util.list'); obj.list = new util.list('copy_status_list');
43         obj.list.init(
44             {
45                 'columns' : columns,
46                 'map_row_to_columns' : circ.util.std_map_row_to_columns(),
47                 'on_select' : function(ev) {
48                     try {
49                         JSAN.use('util.functional');
50                         var sel = obj.list.retrieve_selection();
51                         obj.selection_list = util.functional.map_list(
52                             sel,
53                             function(o) { return JSON2js(o.getAttribute('retrieve_id')); }
54                         );
55                         obj.error.sdump('D_TRACE','circ/copy_status: selection list = ' + js2JSON(obj.selection_list) );
56                         if (obj.selection_list.length == 0) {
57                             obj.controller.view.sel_checkin.setAttribute('disabled','true');
58                             obj.controller.view.cmd_replace_barcode.setAttribute('disabled','true');
59                             obj.controller.view.sel_edit.setAttribute('disabled','true');
60                             obj.controller.view.sel_opac.setAttribute('disabled','true');
61                             obj.controller.view.sel_bucket.setAttribute('disabled','true');
62                             obj.controller.view.sel_record_bucket.setAttribute('disabled','true');
63                             obj.controller.view.sel_copy_details.setAttribute('disabled','true');
64                             obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','true');
65                             obj.controller.view.sel_mark_items_missing.setAttribute('disabled','true');
66                             obj.controller.view.sel_patron.setAttribute('disabled','true');
67                             obj.controller.view.cmd_triggered_events.setAttribute('disabled','true');
68                             obj.controller.view.cmd_create_brt.setAttribute('disabled','true');
69                             obj.controller.view.cmd_book_item_now.setAttribute('disabled','true');
70                             obj.controller.view.cmd_find_acq_po.setAttribute('disabled','true');
71                             obj.controller.view.sel_spine.setAttribute('disabled','true');
72                             obj.controller.view.sel_transit_abort.setAttribute('disabled','true');
73                             obj.controller.view.sel_clip.setAttribute('disabled','true');
74                             obj.controller.view.sel_renew.setAttribute('disabled','true');
75                             obj.controller.view.cmd_add_items.setAttribute('disabled','true');
76                             obj.controller.view.cmd_delete_items.setAttribute('disabled','true');
77                             obj.controller.view.cmd_transfer_items.setAttribute('disabled','true');
78                             obj.controller.view.cmd_add_volumes.setAttribute('disabled','true');
79                             obj.controller.view.cmd_edit_volumes.setAttribute('disabled','true');
80                             obj.controller.view.cmd_delete_volumes.setAttribute('disabled','true');
81                             obj.controller.view.cmd_mark_volume.setAttribute('disabled','true');
82                             obj.controller.view.cmd_mark_library.setAttribute('disabled','true');
83                             obj.controller.view.cmd_transfer_volume.setAttribute('disabled','true');
84                         } else {
85                             obj.controller.view.sel_checkin.setAttribute('disabled','false');
86                             obj.controller.view.cmd_replace_barcode.setAttribute('disabled','false');
87                             obj.controller.view.sel_edit.setAttribute('disabled','false');
88                             obj.controller.view.sel_opac.setAttribute('disabled','false');
89                             obj.controller.view.sel_patron.setAttribute('disabled','false');
90                             obj.controller.view.cmd_triggered_events.setAttribute('disabled','false');
91                             obj.controller.view.sel_bucket.setAttribute('disabled','false');
92                             obj.controller.view.sel_record_bucket.setAttribute('disabled','false');
93                             obj.controller.view.sel_copy_details.setAttribute('disabled','false');
94                             obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','false');
95                             obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');
96                             if (obj.selected_one_unique_owning_lib()) {
97                                 obj.controller.view.cmd_book_item_now.setAttribute('disabled','false');
98                             } else {
99                                 obj.controller.view.cmd_book_item_now.setAttribute('disabled','true');
100                             }
101                             obj.controller.view.cmd_create_brt.setAttribute('disabled','false');
102                             obj.controller.view.cmd_find_acq_po.setAttribute("disabled", obj.selection_list.length == 1 ? "false" : "true");
103                             obj.controller.view.sel_spine.setAttribute('disabled','false');
104                             obj.controller.view.sel_transit_abort.setAttribute('disabled','false');
105                             obj.controller.view.sel_clip.setAttribute('disabled','false');
106                             obj.controller.view.sel_renew.setAttribute('disabled','false');
107                             obj.controller.view.cmd_add_items.setAttribute('disabled','false');
108                             obj.controller.view.cmd_delete_items.setAttribute('disabled','false');
109                             obj.controller.view.cmd_transfer_items.setAttribute('disabled','false');
110                             obj.controller.view.cmd_add_volumes.setAttribute('disabled','false');
111                             obj.controller.view.cmd_edit_volumes.setAttribute('disabled','false');
112                             obj.controller.view.cmd_delete_volumes.setAttribute('disabled','false');
113                             obj.controller.view.cmd_mark_volume.setAttribute('disabled','false');
114                             obj.controller.view.cmd_mark_library.setAttribute('disabled','false');
115                             obj.controller.view.cmd_transfer_volume.setAttribute('disabled','false');
116                         }
117                     } catch(E) {
118                         alert('FIXME: ' + E);
119                     }
120                 }
121             }
122         );
123         
124         JSAN.use('util.controller'); obj.controller = new util.controller();
125         obj.controller.init(
126             {
127                 'control_map' : {
128                     'list_actions' : [
129                         ['render'],
130                         function(e) {
131                             return function() {
132                                 e.appendChild( obj.list.render_list_actions() );
133                                 obj.list.set_list_actions(
134                                     {
135                                         'on_complete' : function() { obj.controller.view.copy_status_barcode_entry_textbox.focus(); } 
136                                     }
137                                 );
138                             };
139                         }
140                     ],
141                     'sel_clip' : [ ['command'], function() { obj.list.clipboard(); obj.controller.view.copy_status_barcode_entry_textbox.focus(); } ],
142                     'save_columns' : [ ['command'], function() { obj.list.save_columns(); obj.controller.view.copy_status_barcode_entry_textbox.focus(); } ],
143                     'alt_view_btn' : [
144                         ['render'],
145                         function(e) {
146                             e.setAttribute('label', document.getElementById("circStrings").getString('staff.circ.copy_status.alt_view.label'));
147                             e.setAttribute('accesskey', document.getElementById("circStrings").getString('staff.circ.copy_status.alt_view.accesskey'));
148                         }
149                     ],
150                     'cmd_alt_view' : [
151                         ['command'],
152                         function(ev) {
153                             try {
154                                 var n = obj.controller.view.alt_view_btn;
155                                 if (n.getAttribute('toggle') == '1') {
156                                     document.getElementById('deck').selectedIndex = 0;
157                                     n.setAttribute('toggle','0');
158                                     n.setAttribute('label', document.getElementById("circStrings").getString('staff.circ.copy_status.alt_view.label'));
159                                     n.setAttribute('accesskey', document.getElementById("circStrings").getString('staff.circ.copy_status.alt_view.accesskey'));
160                                     obj.controller.view.copy_status_barcode_entry_textbox.focus();
161                                 } else {
162                                     document.getElementById('deck').selectedIndex = 1;
163                                     n.setAttribute('toggle','1');
164                                     n.setAttribute('label', document.getElementById("circStrings").getString('staff.circ.copy_status.list_view.label'));
165                                     n.setAttribute('accesskey', document.getElementById("circStrings").getString('staff.circ.copy_status.list_view.accesskey'));
166                                     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
167                                     obj.controller.view.copy_status_barcode_entry_textbox.focus();
168                                     if (obj.selection_list.length == 0) return;
169                                     var f = obj.browser.get_content();
170                                     xulG.barcode = obj.selection_list[0].barcode; 
171                                     f.xulG = xulG;
172                                     f.load_item();
173                                 }
174                             } catch(E) {
175                                 alert('Error in copy_status.js, cmd_alt_view handler: ' + E);
176                             }
177                         },
178                     ],
179                     'cmd_triggered_events' : [
180                         ['command'],
181                         function() {
182                             try {
183                                 for (var i = 0; i < obj.selection_list.length; i++) {
184                                     xulG.new_tab(
185                                         urls.XUL_TRIGGER_EVENTS,
186                                         {
187                                             'tab_name' : document.getElementById('commonStrings').getFormattedString('tab.label.triggered_events_for_copy',[ obj.selection_list[i].barcode ])
188                                         },
189                                         {
190                                             'copy_id' : obj.selection_list[i].copy_id
191                                         }
192                                     );
193                                 }
194                             } catch(E) {
195                                 alert('Error in copy_status.js, cmd_triggered_events: ' + E);
196                             }
197                         }
198                     ],
199                     'cmd_create_brt' : [
200                         ['command'],
201                         function() {
202                             JSAN.use("cat.util");
203                             JSAN.use("util.functional");
204
205                             var results = cat.util.make_bookable(
206                                 util.functional.map_list(
207                                     obj.selection_list, function (o) {
208                                         return o.copy_id;
209                                     }
210                                 )
211                             );
212                             if (results && results["brsrc"]) {
213                                 cat.util.edit_new_brsrc(results["brsrc"]);
214                             }
215                         }
216                     ],
217                     'cmd_book_item_now' : [
218                         ['command'],
219                         function() {
220                             JSAN.use("cat.util");
221                             JSAN.use("util.functional");
222
223                             var results = cat.util.make_bookable(
224                                 util.functional.map_list(
225                                     obj.selection_list, function (o) {
226                                         return o.copy_id;
227                                     }
228                                 )
229                             );
230                             if (results) {
231                                 cat.util.edit_new_bresv(results);
232                             }
233                         }
234                     ],
235                     "cmd_find_acq_po" : [
236                         ["command"],
237                         function() {
238                             JSAN.use("circ.util");
239                             circ.util.find_acq_po(
240                                 ses(), obj.selection_list[0].copy_id
241                             );
242                         }
243                     ],
244                     'sel_checkin' : [
245                         ['command'],
246                         function() {
247                             try {
248                                 var funcs = [];
249                                 var auto_print = document.getElementById('checkin_auto_print_slips');
250                                 if (auto_print) auto_print = auto_print.getAttribute('checked') == 'true';
251                                 JSAN.use('circ.util');
252                                 for (var i = 0; i < obj.selection_list.length; i++) {
253                                     var barcode = obj.selection_list[i].barcode;
254                                     var checkin = circ.util.checkin_via_barcode(
255                                         ses(),
256                                         { 'barcode' : barcode },
257                                         false /* backdate */,
258                                         auto_print
259                                     );
260                                     funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
261                                 }
262                                 for (var i = 0; i < funcs.length; i++) { funcs[i](); }
263                             } catch(E) {
264                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.sel_checkin.error'),E);
265                             }
266                         }
267                     ],
268                     'cmd_replace_barcode' : [
269                         ['command'],
270                         function() {
271                             try {
272                                 var funcs = [];
273                                 JSAN.use('cat.util');
274                                 for (var i = 0; i < obj.selection_list.length; i++) {
275                                     try { 
276                                         var barcode = obj.selection_list[i].barcode;
277                                         var new_bc = cat.util.replace_barcode( barcode );
278                                         funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(new_bc) );
279                                     } catch(E) {
280                                         obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.cmd_replace_barcode.error', [barcode]), E);
281                                     }
282                                 }
283                                 for (var i = 0; i < funcs.length; i++) { funcs[i](); }
284                             } catch(E) {
285                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.cmd_replace_barcodes.error'), E);
286                             }
287                         }
288                     ],
289                     'sel_edit' : [
290                         ['command'],
291                         function() {
292                             try {
293                                 var funcs = [];
294                                 obj.spawn_copy_editor();
295                                 for (var i = 0; i < obj.selection_list.length; i++) {
296                                         var barcode = obj.selection_list[i].barcode;
297                                         funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
298                                 }
299                                 for (var i = 0; i < funcs.length; i++) { funcs[i](); }
300                             } catch(E) {
301                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.sel_edit.error'), E);
302                             }
303                         }
304                     ],
305                     'sel_spine' : [
306                         ['command'],
307                         function() {
308                             JSAN.use('cat.util');
309                             cat.util.spawn_spine_editor(obj.selection_list);
310                         }
311                     ],
312                     'sel_opac' : [
313                         ['command'],
314                         function() {
315                             JSAN.use('cat.util');
316                             cat.util.show_in_opac(obj.selection_list);
317                         }
318                     ],
319                     'sel_transit_abort' : [
320                         ['command'],
321                         function() {
322                             var funcs = [];
323                             JSAN.use('circ.util');
324                             circ.util.abort_transits(obj.selection_list);
325                             for (var i = 0; i < obj.selection_list.length; i++) {
326                                 var barcode = obj.selection_list[i].barcode;
327                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
328                             }
329                             for (var i = 0; i < funcs.length; i++) { funcs[i](); }
330                         }
331                     ],
332                     'sel_patron' : [
333                         ['command'],
334                         function() {
335                             JSAN.use('circ.util');
336                             circ.util.show_last_few_circs(obj.selection_list);
337                         }
338                     ],
339                     'sel_copy_details' : [
340                         ['command'],
341                         function() {
342                             JSAN.use('circ.util');
343                             circ.util.item_details_new(
344                                 util.functional.map_list(
345                                     obj.selection_list,
346                                     function(o) { return o.barcode; }
347                                 )
348                             );
349                         }
350                     ],
351                     'sel_renew' : [
352                         ['command'],
353                         function() {
354                             var funcs = [];
355                             JSAN.use('circ.util');
356                             for (var i = 0; i < obj.selection_list.length; i++) {
357                                 var test = obj.selection_list[i].renewable;
358                                 var barcode = obj.selection_list[i].barcode;
359                                 if (test == 't') {
360                                     circ.util.renew_via_barcode( { 'barcode' : barcode } );
361                                     funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
362                                 } else {
363                                     alert(document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.sel_renew.not_circulating', [barcode]));
364                                 }
365                             }
366                             for (var i = 0; i < funcs.length; i++) { funcs[i](); }
367                         }
368                     ],
369
370                     'sel_mark_items_damaged' : [
371                         ['command'],
372                         function() {
373                             var funcs = [];
374                             JSAN.use('cat.util'); JSAN.use('util.functional');
375                             cat.util.mark_item_damaged( util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } ) );
376                             for (var i = 0; i < obj.selection_list.length; i++) {
377                                 var barcode = obj.selection_list[i].barcode;
378                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
379                             }
380                             for (var i = 0; i < funcs.length; i++) { funcs[i](); }
381                         }
382                     ],
383                     'sel_mark_items_missing' : [
384                         ['command'],
385                         function() {
386                             var funcs = [];
387                             JSAN.use('cat.util'); JSAN.use('util.functional');
388                             cat.util.mark_item_missing( util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } ) );
389                             for (var i = 0; i < obj.selection_list.length; i++) {
390                                 var barcode = obj.selection_list[i].barcode;
391                                 funcs.push( function(a) { return function() { obj.copy_status( a, true ); }; }(barcode) );
392                             }
393                             for (var i = 0; i < funcs.length; i++) { funcs[i](); }
394                         }
395                     ],
396                     'sel_bucket' : [
397                         ['command'],
398                         function() {
399                             JSAN.use('cat.util');
400                             cat.util.add_copies_to_bucket(obj.selection_list);
401                         }
402                     ],
403                     'sel_record_bucket' : [
404                         ['command'],
405                         function() {
406                             JSAN.use('cat.util'); JSAN.use('util.functional');
407                             cat.util.add_titles_to_bucket(
408                                 util.functional.map_list(
409                                     obj.selection_list, function (o) {
410                                         return o.doc_id;
411                                     }
412                                 )
413                             );
414                         }
415                     ],
416                     'copy_status_barcode_entry_textbox' : [
417                         ['keypress'],
418                         function(ev) {
419                             if (ev.keyCode && ev.keyCode == 13) {
420                                 obj.copy_status();
421                             }
422                         }
423                     ],
424                     'cmd_broken' : [
425                         ['command'],
426                         function() { alert(document.getElementById('circStrings').getString('staff.circ.unimplemented')); }
427                     ],
428                     'cmd_copy_status_submit_barcode' : [
429                         ['command'],
430                         function() {
431                             obj.copy_status();
432                         }
433                     ],
434                     'cmd_copy_status_upload_file' : [
435                         ['command'],
436                         function() {
437                             netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
438                             JSAN.use('util.file');
439                             var f = new util.file('');
440                             var content = f.import_file( { 'title' : document.getElementById('circStrings').getString('staff.circ.copy_status.upload_file.title'), 'not_json' : true } );
441                             if (!content) { return; }
442                             var barcodes = content.split(/[,\s]+/);
443                             if (barcodes.length > 0) {
444                                 JSAN.use('util.exec'); var exec = new util.exec();
445                                 var funcs = [];
446                                 for (var i = 0; i < barcodes.length; i++) {
447                                     funcs.push(
448                                         function(b){
449                                             return function() {
450                                                 obj.copy_status(b);
451                                             };
452                                         }(barcodes[i])
453                                     );
454                                 }
455                                 funcs.push( function() { alert(document.getElementById('circStrings').getString('staff.circ.copy_status.upload_file.complete')); } );
456                                 exec.chain( funcs );
457                             } else {
458                                 alert(document.getElementById('circStrings').getString('staff.circ.copy_status.upload_file.no_barcodes'));
459                             }
460
461                         }
462                     ],
463                     'cmd_copy_status_print' : [
464                         ['command'],
465                         function() {
466                             try {
467                                 var p = { 
468                                     'template' : 'item_status'
469                                 };
470                                 obj.list.print(p);
471                             } catch(E) {
472                                 obj.error.standard_unexpected_error_alert('print',E); 
473                             }
474                         }
475                     ],
476                     'cmd_add_items' : [
477                         ['command'],
478                         function() {
479                             try {
480
481                                 JSAN.use('util.functional');
482                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
483                                 if (list.length == 0) { return; }
484
485                                 var copy_shortcut = {}; var map_acn = {};
486
487                                 for (var i = 0; i < list.length; i++) {
488                                     var volume_id = list[i];
489                                     if (volume_id == -1) { 
490                                         continue; /* ignore magic pre-cat volume */
491                                     }
492                                     if (! map_acn[volume_id]) {
493                                         map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ volume_id ]);
494                                     }
495                                     var call_number = obj.map_acn[volume_id];
496                                     var record_id = call_number.record();
497                                     var ou_id = call_number.owning_lib();
498                                     var label = call_number.label();
499                                     var acnc_id = typeof call_number.label_class() == 'object'
500                                         ? call_number.label_class().id()
501                                         : call_number.label_class();
502                                     var acnp_id = typeof call_number.prefix() == 'object'
503                                         ? call_number.prefix().id()
504                                         : call_number.prefix();
505                                     var acns_id = typeof call_number.suffix() == 'object'
506                                         ? call_number.suffix().id()
507                                         : call_number.suffix();
508                                     if (!copy_shortcut[ou_id]) copy_shortcut[ou_id] = {};
509                                     var callnumber_composite_key = acnc_id + ':' + acnp_id + ':' + label + ':' + acns_id;
510                                     if (!copy_shortcut[record_id]) {
511                                         copy_shortcut[record_id] = {};
512                                     }
513                                     if (!copy_shortcut[record_id][ou_id]) {
514                                         copy_shortcut[record_id][ou_id] = {};
515                                     }
516                                     copy_shortcut[record_id][ou_id][ callnumber_composite_key ] = volume_id;
517
518                                 }
519
520                                 for (var r in copy_shortcut) {
521
522                                     /* quick fix */  /* what was this fixing? */
523                                     list = []; for (var i in copy_shortcut[r]) { list.push( i ); }
524
525                                     var edit = 0;
526                                     try {
527                                         edit = obj.network.request(
528                                             api.PERM_MULTI_ORG_CHECK.app,
529                                             api.PERM_MULTI_ORG_CHECK.method,
530                                             [ 
531                                                 ses(), 
532                                                 obj.data.list.au[0].id(), 
533                                                 list,
534                                                 [ 'CREATE_COPY' ]
535                                             ]
536                                         ).length == 0 ? 1 : 0;
537                                     } catch(E) {
538                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
539                                     }
540     
541                                     if (edit==0) { 
542                                         return; // no read-only view for this interface
543                                     }
544     
545                                     var title = document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.add_items.title', [r]);
546     
547                                     var url;
548                                     var unified_interface = String( obj.data.hash.aous['ui.unified_volume_copy_editor'] ) == 'true';
549                                     if (unified_interface) {
550                                         var horizontal_interface = String( obj.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
551                                         url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
552                                     } else {
553                                         url = window.xulG.url_prefix( urls.XUL_VOLUME_COPY_CREATOR_ORIGINAL );
554                                     }
555
556                                     var w = xulG.new_tab(
557                                         url,
558                                         { 'tab_name' : title },
559                                         { 'doc_id' : r, 'ou_ids' : list, 'copy_shortcut' : copy_shortcut[r] }
560                                     );
561                                 }
562
563                             } catch(E) {
564                                 obj.error.standard_unexpected_error_alert('copy status -> add copies',E);
565                             }
566                         }
567
568                     ],
569                     'cmd_delete_items' : [
570                         ['command'],
571                         function() {
572                             try {
573
574                                 JSAN.use('util.functional');
575
576                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } );
577
578                                 var copies = util.functional.map_list(
579                                     list,
580                                     function (acp_id) {
581                                         return obj.network.simple_request('FM_ACP_RETRIEVE',[acp_id]);
582                                     }
583                                 );
584
585                                 for (var i = 0; i < copies.length; i++) {
586                                     copies[i].ischanged(1);
587                                     copies[i].isdeleted(1);
588                                 }
589
590                                 if (! window.confirm(document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.del_items.confirm', [util.functional.map_list( copies, function(o) { return o.barcode(); }).join(", ")]))) {
591                                     return;
592                                 }
593
594                                 var robj = obj.network.simple_request('FM_ACP_FLESHED_BATCH_UPDATE',[ ses(), copies, true]);
595                                 var robj = obj.network.simple_request(
596                                     'FM_ACP_FLESHED_BATCH_UPDATE', 
597                                     [ ses(), copies, true ], 
598                                     null,
599                                     {
600                                         'title' : document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.title'),
601                                         'overridable_events' : [
602                                             1208 /* TITLE_LAST_COPY */,
603                                             1227 /* COPY_DELETE_WARNING */
604                                         ]
605                                     }
606                                 );
607     
608                                 if (typeof robj.ilsevent != 'undefined') {
609                                     switch(Number(robj.ilsevent)) {
610                                         case 1208 /* TITLE_LAST_COPY */:
611                                         case 1227 /* COPY_DELETE_WARNING */:
612                                         break;
613                                         default:
614                                             obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.success.error'), robj);
615                                         break;
616                                     }
617                                 } else { alert(document.getElementById('circStrings').getString('staff.circ.copy_status.del_items.success')); }
618
619                             } catch(E) {
620                                 obj.error.standard_unexpected_error_alert('copy status -> delete items',E);
621                             }
622                         }
623                     ],
624                     'cmd_transfer_items' : [
625                         ['command'],
626                         function() {
627                                 try {
628                                     obj.data.stash_retrieve();
629                                     if (!obj.data.marked_volume) {
630                                         alert(document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_items.mark_destination'));
631                                         return;
632                                     }
633                                     
634                                     JSAN.use('util.functional');
635
636                                     var list = util.functional.map_list( obj.selection_list, function(o) { return o.copy_id; } );
637
638                                     var volume = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ obj.data.marked_volume ]);
639
640                                     JSAN.use('cat.util'); cat.util.transfer_copies( { 
641                                         'copy_ids' : list, 
642                                         'docid' : volume.record(),
643                                         'volume_label' : volume.label(),
644                                         'owning_lib' : volume.owning_lib()
645                                     } );
646
647                                 } catch(E) {
648                                     obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_items.problem'), E);
649                                 }
650                             }
651
652                     ],
653                     'cmd_add_volumes' : [
654                         ['command'],
655                         function() {
656                             try {
657                                 JSAN.use('util.functional');
658                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
659                                 if (list.length == 0) { return; }
660
661                                 var aou_hash = {}; var map_acn = {};
662
663                                 for (var i = 0; i < list.length; i++) {
664                                     var volume_id = list[i];
665                                     if (volume_id == -1) {
666                                         continue; /* ignore magic pre-cat volume */
667                                     }
668                                     if (! map_acn[volume_id]) {
669                                         map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ volume_id ]);
670                                     }
671                                     var record_id = map_acn[ volume_id ].record();
672                                     var ou_id = map_acn[ volume_id ].owning_lib();
673                                     var label = map_acn[ volume_id ].label();
674                                     if (!aou_hash[record_id]) aou_hash[record_id] = {};
675                                     aou_hash[record_id][ou_id] = 1;
676
677                                 }
678
679                                 for (var r in aou_hash) {
680
681                                     list = []; for (var org in aou_hash[r]) list.push(org);
682
683                                     var edit = 0;
684                                     try {
685                                         edit = obj.network.request(
686                                             api.PERM_MULTI_ORG_CHECK.app,
687                                             api.PERM_MULTI_ORG_CHECK.method,
688                                             [ 
689                                                 ses(), 
690                                                 obj.data.list.au[0].id(), 
691                                                 list,
692                                                 [ 'CREATE_VOLUME', 'CREATE_COPY' ]
693                                             ]
694                                         ).length == 0 ? 1 : 0;
695                                     } catch(E) {
696                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
697                                     }
698
699                                     if (edit==0) {
700                                         alert(document.getElementById('circStrings').getString('staff.circ.copy_status.add_volumes.perm_failure'));
701                                         return; // no read-only view for this interface
702                                     }
703
704                                     var title = document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.add_volumes.title', [r]);
705
706                                     var url;
707                                     var unified_interface = String( obj.data.hash.aous['ui.unified_volume_copy_editor'] ) == 'true';
708                                     if (unified_interface) {
709                                         var horizontal_interface = String( obj.data.hash.aous['ui.cat.volume_copy_editor.horizontal'] ) == 'true';
710                                         url = window.xulG.url_prefix( horizontal_interface ? urls.XUL_VOLUME_COPY_CREATOR_HORIZONTAL : urls.XUL_VOLUME_COPY_CREATOR );
711                                     } else {
712                                         url = window.xulG.url_prefix( urls.XUL_VOLUME_COPY_CREATOR_ORIGINAL );
713                                     }
714
715                                     var w = xulG.new_tab(
716                                         url,
717                                         { 'tab_name' : title },
718                                         { 'doc_id' : r, 'ou_ids' : list }
719                                     );
720
721                                 }
722
723                             } catch(E) {
724                                 obj.error.standard_unexpected_error_alert('copy status -> add volumes',E);
725                             }
726                         }
727
728                     ],
729                     'cmd_edit_volumes' : [
730                         ['command'],
731                         function() {
732                             try {
733                                 JSAN.use('util.functional');
734                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
735                                 if (list.length == 0) { return; }
736
737                                 var volumes = []; var seen = {};
738
739                                 for (var i = 0; i < list.length; i++) {
740                                     var volume_id = list[i];
741                                     if (volume_id == -1) {
742                                         continue; /* ignore magic pre-cat volume */
743                                     }
744                                     if (! seen[volume_id]) {
745                                         seen[volume_id] = 1;
746                                         var volume = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ volume_id ]);
747                                         if (volume && typeof volume.ilsevent == 'undefined') {
748                                             volumes.push( volume );
749                                         }
750                                     }
751                                 }
752
753                                 JSAN.use('cat.util'); cat.util.batch_edit_volumes( volumes );
754
755                             } catch(E) {
756                                 obj.error.standard_unexpected_error_alert('Copy Status -> Volume Edit',E);
757                             }
758                         }
759
760                     ],
761                     'cmd_delete_volumes' : [
762                         ['command'],
763                         function() {
764                             try {
765                                 JSAN.use('util.functional');
766                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
767                                 if (list.length == 0) { return; }
768
769                                 var map_acn = {};
770
771                                 for (var i = 0; i < list.length; i++) {
772                                     var volume_id = list[i];
773                                     if (volume_id == -1) {
774                                         continue; /* ignore magic pre-cat volume */
775                                     }
776                                     if (! map_acn[volume_id]) {
777                                         map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ volume_id ]);
778                                     }
779                                 }
780
781                                 list = [];
782                                 for (var v in map_acn) {
783                                     list.push( map_acn[v] );
784                                 }
785
786                                 var confirm_prompt;
787                                 if (list.length == 1) {
788                                     confirm_prompt = document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.singular');
789                                 } else {
790                                     confirm_prompt = document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.plural');
791                                 }    
792
793                                 var r = obj.error.yns_alert(
794                                     confirm_prompt,
795                                     document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.title'),
796                                     document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.delete'),
797                                     document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.cancel'),
798                                     null,
799                                     document.getElementById('circStrings').getString('staff.circ.confirm')
800                                 );
801
802                                 if (r == 0) {
803                                     for (var i = 0; i < list.length; i++) {
804                                         list[i].isdeleted('1');
805                                     }
806                                     var robj = obj.network.simple_request(
807                                         'FM_ACN_TREE_UPDATE', 
808                                         [ ses(), list, true ],
809                                         null,
810                                         {
811                                             'title' : document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.override'),
812                                             'overridable_events' : [
813                                             ]
814                                         }
815                                     );
816                                     if (robj == null) throw(robj);
817                                     if (typeof robj.ilsevent != 'undefined') {
818                                         if (robj.ilsevent == 1206 /* VOLUME_NOT_EMPTY */) {
819                                             alert(document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.delete_copies'));
820                                             return;
821                                         }
822                                         if (robj.ilsevent != 0) { throw(robj); }
823                                     }
824                                     alert(document.getElementById('circStrings').getString('staff.circ.copy_status.delete_volumes.success'));
825                                 }
826                             } catch(E) {
827                                 obj.error.standard_unexpected_error_alert('copy status -> delete volumes',E);
828                             }
829
830                         }
831
832                     ],
833                     'cmd_mark_volume' : [
834                         ['command'],
835                         function() {
836                             try {
837                                 JSAN.use('util.functional');
838                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
839
840                                 if (list.length == 1) {
841                                     obj.data.marked_volume = list[0];
842                                     obj.data.stash('marked_volume');
843                                     alert(document.getElementById('circStrings').getString('staff.circ.copy_status.mark_volume.status'));
844                                 } else {
845                                     obj.error.yns_alert(
846                                         document.getElementById('circStrings').getString('staff.circ.copy_status.mark_volume.prompt'),
847                                         document.getElementById('circStrings').getString('staff.circ.copy_status.mark_volume.title'),
848                                         document.getElementById('circStrings').getString('staff.circ.copy_status.ok'),
849                                         null,
850                                         null,
851                                         document.getElementById('circStrings').getString('staff.circ.confirm')
852                                     );
853                                 }
854                             } catch(E) {
855                                 obj.error.standard_unexpected_error_alert('copy status -> mark volume',E);
856                             }
857                         }
858                     ],
859                     'cmd_mark_library' : [
860                         ['command'],
861                         function() {
862                             try {
863                                 JSAN.use('util.functional');
864                                 var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
865
866                                 if (list.length == 1) {
867                                     var v = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[list[0]]);
868                                     var owning_lib = v.owning_lib();
869                                     if (typeof owning_lib == 'object') {
870                                         owning_lib = owning_lib.id();
871                                     }
872
873                                     obj.data.marked_library = { 'lib' : owning_lib, 'docid' : v.record() };
874                                     obj.data.stash('marked_library');
875                                     alert(document.getElementById('circStrings').getString('staff.circ.copy_status.mark_library'));
876                                 } else {
877                                     obj.error.yns_alert(
878                                         document.getElementById('circStrings').getString('staff.circ.copy_status.mark_library.limit_one'),
879                                         document.getElementById('circStrings').getString('staff.circ.copy_status.mark_library.limit_one.title'),
880                                         document.getElementById('circStrings').getString('staff.circ.copy_status.ok'),
881                                         null,
882                                         null,
883                                         document.getElementById('circStrings').getString('staff.circ.confirm')
884                                     );
885                                 }
886                             } catch(E) {
887                                 obj.error.standard_unexpected_error_alert('copy status -> mark library',E);
888                             }
889                         }
890                     ],
891                     'cmd_transfer_volume' : [
892                         ['command'],
893                         function() {
894                             try {
895                                     obj.data.stash_retrieve();
896                                     if (!obj.data.marked_library) {
897                                         alert(document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.none'));
898                                         return;
899                                     }
900                                     
901                                     JSAN.use('util.functional');
902
903                                     var list = util.functional.map_list( obj.selection_list, function(o) { return o.acn_id; } );
904                                     if (list.length == 0) { return; }
905
906                                     var map_acn = {};
907
908                                     for (var i = 0; i < list.length; i++) {
909                                         var volume_id = list[i];
910                                         if (volume_id == -1) {
911                                             continue; /* ignore magic pre-cat volume */
912                                         }
913                                         if (! map_acn[volume_id]) {
914                                             map_acn[ volume_id ] = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ volume_id ]);
915                                         }
916                                     }
917
918                                     list = [];
919                                     for (v in map_acn) {
920                                         list.push(map_acn[v]);
921                                     }
922
923                                     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
924                                     var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto">';
925                                     xml += '<description>';
926
927                                     var vols = util.functional.map_list(list,
928                                         function (o) {
929                                             return o.label();
930                                         }
931                                     ).join(", ");
932
933                                     var volume_list = document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.transfer_volume.confirm', 
934                                         [vols, obj.data.hash.aou[ obj.data.marked_library.lib ].shortname()]);
935
936                                     xml += volume_list;
937                                     xml += '</description>';
938                                     xml += '<hbox><button label="';
939                                     xml += document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.transfer.label');
940                                     xml += '" name="fancy_submit"/>';
941                                     xml += '<button label="';
942                                     xml += document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.cancel.label');
943                                     xml += '" accesskey="';
944                                     xml += document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.cancel.accesskey');
945                                     xml += '" name="fancy_cancel"/></hbox>';
946                                     xml += '<iframe style="overflow: scroll" flex="1" src="' + urls.XUL_BIB_BRIEF + '?docid=' + obj.data.marked_library.docid + '"/>';
947                                     xml += '</vbox>';
948                                     JSAN.use('OpenILS.data');
949                                     //var data = new OpenILS.data(); data.init({'via':'stash'});
950                                     //data.temp_transfer = xml; data.stash('temp_transfer');
951                                     JSAN.use('util.window'); var win = new util.window();
952                                     var fancy_prompt_data = win.open(
953                                         urls.XUL_FANCY_PROMPT,
954                                         //+ '?xml_in_stash=temp_transfer'
955                                         //+ '&title=' + window.escape('Volume Transfer'),
956                                         'fancy_prompt', 'chrome,resizable,modal,width=500,height=300',
957                                         { 'xml' : xml, 'title' : document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.title') }
958                                     );
959                                 
960                                     if (fancy_prompt_data.fancy_status == 'incomplete') { 
961                                         alert(document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.aborted'));
962                                         return;
963                                     }
964
965                                     var robj = obj.network.simple_request(
966                                         'FM_ACN_TRANSFER', 
967                                         [ ses(), { 'docid' : obj.data.marked_library.docid, 'lib' : obj.data.marked_library.lib, 'volumes' : util.functional.map_list( list, function(o) { return o.id(); }) } ],
968                                         null,
969                                         {
970                                             'title' : document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.override_failure'),
971                                             'overridable_events' : [
972                                                 1208 /* TITLE_LAST_COPY */,
973                                                 1219 /* COPY_REMOTE_CIRC_LIB */
974                                             ]
975                                         }
976                                     );
977
978                                     if (typeof robj.ilsevent != 'undefined') {
979                                         if (robj.ilsevent == 1221 /* ORG_CANNOT_HAVE_VOLS */) {
980                                             alert(document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.cannot_have_vols'));
981                                         } else {
982                                             throw(robj);
983                                         }
984                                     } else {
985                                         alert(document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.success'));
986                                     }
987
988                             } catch(E) {
989                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.copy_status.transfer_volume.error'),E);
990                             }
991                         }
992
993                     ]
994                 }
995             }
996         );
997         this.controller.render();
998         this.controller.view.copy_status_barcode_entry_textbox.focus();
999
1000         JSAN.use('util.browser');
1001         obj.browser = new util.browser();
1002         obj.browser.init(
1003             {
1004                 'url' : 'alternate_copy_summary.xul',
1005                 'push_xulG' : true,
1006                 'alt_print' : false,
1007                 'browser_id' : 'copy_status_frame',
1008                 'passthru_content_params' : xulG,
1009             }
1010         );
1011
1012     },
1013
1014     'selected_one_unique_owning_lib': function () {
1015         JSAN.use('util.functional');
1016         var list = util.functional.map_list(
1017             this.selection_list,
1018             function(o) { return o.owning_lib; }
1019         );
1020         return util.functional.unique_list_values(list).length == 1;
1021     },
1022
1023     'test_barcode' : function(bc) {
1024         var obj = this;
1025         var good = util.barcode.check(bc);
1026         var x = document.getElementById('strict_barcode');
1027         if (x && x.checked != true) { return true; }
1028         if (good) {
1029             return true;
1030         } else {
1031             if ( 1 == obj.error.yns_alert(
1032                         document.getElementById('circStrings').getFormattedString('staff.circ.check_digit.bad', [bc]),
1033                         document.getElementById('circStrings').getString('staff.circ.barcode.bad'),
1034                         document.getElementById('circStrings').getString('staff.circ.cancel'),
1035                         document.getElementById('circStrings').getString('staff.circ.barcode.accept'),
1036                         null,
1037                         document.getElementById('circStrings').getString('staff.circ.confirm'),
1038                         '/xul/server/skin/media/images/bad_barcode.png'
1039             ) ) {
1040                 return true;
1041             } else {
1042                 return false;
1043             }
1044         }
1045     },
1046
1047     'copy_status' : function(barcode,refresh) {
1048         var obj = this;
1049         try {
1050             try { document.getElementById('last_scanned').setAttribute('value',''); } catch(E) {}
1051             if (!barcode) {
1052                 // No barcode provided = get barcode
1053                 barcode = obj.controller.view.copy_status_barcode_entry_textbox.value;
1054                 // Complete the barcode - just items
1055                 var barcode_object = xulG.get_barcode(window, 'asset', barcode);
1056                 // user_false is user said "None of the above" - Abort before other errors/prompts can result
1057                 if(barcode_object == "user_false") return;
1058                 // Got a barcode and no error? Use the barcode. Otherwise, fall through with entered barcode.
1059                 if(barcode_object && typeof barcode_object.ilsevent == 'undefined')
1060                     barcode = barcode_object.barcode;
1061             }
1062             if (!barcode) { return; }
1063             if (barcode) {
1064                 if ( obj.test_barcode(barcode) ) { /* good */ } else { /* bad */ return; }
1065             }
1066             JSAN.use('circ.util');
1067             function handle_req(req) {
1068                 try {
1069                     var details = req.getResultObject();
1070                     if (details == null) {
1071                         throw(document.getElementById('circStrings').getString('staff.circ.copy_status.status.null_result'));
1072                     } else if (details.ilsevent) {
1073                         switch(Number(details.ilsevent)) {
1074                             case -1: 
1075                                 obj.error.standard_network_error_alert(); 
1076                                 obj.controller.view.copy_status_barcode_entry_textbox.select();
1077                                 obj.controller.view.copy_status_barcode_entry_textbox.focus();
1078                                 return;
1079                             break;
1080                             case 1502 /* ASSET_COPY_NOT_FOUND */ :
1081                                 try { document.getElementById('last_scanned').setAttribute('value', document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.status.copy_not_found', [barcode])); } catch(E) {}
1082                                 obj.error.yns_alert(
1083                                     document.getElementById('circStrings').getFormattedString('staff.circ.copy_status.status.copy_not_found', [barcode]),
1084                                     document.getElementById('circStrings').getString('staff.circ.copy_status.status.not_cataloged'),
1085                                     document.getElementById('circStrings').getString('staff.circ.copy_status.ok'),
1086                                     null,
1087                                     null,
1088                                     document.getElementById('circStrings').getString('staff.circ.confirm.msg')
1089                                 );
1090                                 obj.controller.view.copy_status_barcode_entry_textbox.select();
1091                                 obj.controller.view.copy_status_barcode_entry_textbox.focus();
1092                                 return;
1093                             break;
1094                             default: 
1095                                 throw(details); 
1096                             break;
1097                         }
1098                     }
1099                     var msg = details.copy.barcode() + ' -- ';
1100                     if (details.copy.call_number() == -1) {
1101                         msg += document.getElementById('circStrings').getString('staff.circ.copy_status.status.pre_cat') + '  ';
1102                     }
1103                     if (details.hold) {
1104                         msg += document.getElementById('circStrings').getString('staff.circ.copy_status.status.hold') + '  ';
1105                     }
1106                     if (details.transit) {
1107                         msg += document.getElementById('circStrings').getString('staff.circ.copy_status.status.transit') + '  ';
1108                     }
1109                     if (details.circ && ! details.circ.checkin_time()) {
1110                         msg += document.getElementById('circStrings').getString('staff.circ.copy_status.status.circ') + '  ';
1111                     }
1112                     try { document.getElementById('last_scanned').setAttribute('value',msg); } catch(E) {}
1113                     if (document.getElementById('trim_list')) {
1114                         var x = document.getElementById('trim_list');
1115                         if (x.checked) { obj.list.trim_list = 20; } else { obj.list.trim_list = null; }
1116                     }
1117                     var params = {
1118                         'retrieve_id' : js2JSON( 
1119                             { 
1120                                 'renewable' : details.circ ? 't' : 'f', 
1121                                 'copy_id' : details.copy.id(), 
1122                                 'acn_id' : details.volume ? details.volume.id() : -1, 
1123                                 'owning_lib' : details.volume ? details.volume.owning_lib() : -1, 
1124                                 'barcode' : barcode, 
1125                                 'doc_id' : details.mvr ? details.mvr.doc_id() : null  
1126                             } 
1127                         ),
1128                         'row' : {
1129                             'my' : {
1130                                 'mvr' : details.mvr,
1131                                 'acp' : details.copy,
1132                                 'acn' : details.volume,
1133                                 'atc' : details.transit,
1134                                 'circ' : details.circ,
1135                                 'ahr' : details.hold
1136                             }
1137                         },
1138                         'to_top' : true
1139                     };
1140                     if (!refresh) {
1141                         var nparams = obj.list.append(params);
1142                         if (!document.getElementById('trim_list').checked) {
1143                             if (typeof obj.list_copyid_map[details.copy.id()] == 'undefined') obj.list_copyid_map[details.copy.id()] =[];
1144                             obj.list_copyid_map[details.copy.id()].push(nparams);
1145                         }
1146                     } else {
1147                         if (!document.getElementById('trim_list').checked) {
1148                             if (typeof obj.list_copyid_map[details.copy.id()] != 'undefined') {
1149                                 for (var i = 0; i < obj.list_copyid_map[details.copy.id()].length; i++) {
1150                                     if (typeof obj.list_copyid_map[details.copy.id()][i] == 'undefined') {
1151                                         obj.list.append(params);
1152                                     } else {
1153                                         params.my_node = obj.list_copyid_map[details.copy.id()][i].my_node;
1154                                         obj.list.refresh_row(params);
1155                                     }
1156                                 }
1157                             } else {
1158                                 obj.list.append(params);
1159                             }
1160                         } else {
1161                             obj.list.append(params);
1162                         }
1163                     }
1164                 } catch(E) {
1165                     obj.error.standard_unexpected_error_alert('barcode = ' + barcode,E);
1166                 }
1167             }
1168             var result = obj.network.simple_request('FM_ACP_DETAILS_VIA_BARCODE.authoritative', [ ses(), barcode ]);
1169             handle_req({'getResultObject':function(){return result;}}); // used to be async
1170             if (result.copy && document.getElementById('deck').selectedIndex == 1) {
1171                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
1172                 var f = obj.browser.get_content();
1173                 xulG.barcode = result.copy.barcode(); // FIXME: We could pass the already-fetched data, but need to figure out how to manage that and honor Trim List, the whole point of which is to limit memory consumption
1174                 if (f) {
1175                     if (!xulG.from_item_details_new) {
1176                         /* We don't want to call load_item() in this case
1177                          * because we're going to call copy_status() later
1178                          * (which gets action menus populated, unlike
1179                          * load_item()). */
1180                         f.xulG = xulG;
1181                         f.load_item();
1182                     }
1183                 } else {
1184                     alert('hrmm');
1185                 }
1186             }
1187             obj.controller.view.copy_status_barcode_entry_textbox.value = '';
1188             obj.controller.view.copy_status_barcode_entry_textbox.focus();
1189             return result; // In some cases we're going to want to save this
1190         } catch(E) {
1191             obj.error.standard_unexpected_error_alert('barcode = ' + barcode,E);
1192             obj.controller.view.copy_status_barcode_entry_textbox.select();
1193             obj.controller.view.copy_status_barcode_entry_textbox.focus();
1194         }
1195     },
1196     
1197     'spawn_copy_editor' : function() {
1198
1199         var obj = this;
1200
1201         JSAN.use('util.functional');
1202
1203         var list = obj.selection_list;
1204
1205         list = util.functional.map_list(
1206             list,
1207             function (o) {
1208                 return o.copy_id;
1209             }
1210         );
1211
1212         JSAN.use('cat.util'); cat.util.spawn_copy_editor( { 'copy_ids' : list, 'edit' : 1 } );
1213
1214     },
1215
1216 }
1217
1218 dump('exiting circ.copy_status.js\n');