]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/cat/copy_browser.js
refactor spawn_copy_editor and perm check
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / cat / copy_browser.js
1 dump('entering cat.copy_browser.js\n');
2
3 if (typeof cat == 'undefined') cat = {};
4 cat.copy_browser = function (params) {
5         try {
6                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
7                 JSAN.use('util.error'); this.error = new util.error();
8         } catch(E) {
9                 dump('cat.copy_browser: ' + E + '\n');
10         }
11 }
12
13 cat.copy_browser.prototype = {
14
15         'map_tree' : {},
16         'map_acn' : {},
17         'map_acp' : {},
18         'sel_list' : [],
19
20         'init' : function( params ) {
21
22                 try {
23                         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
24                         var obj = this;
25
26                         obj.docid = params.docid;
27
28                         JSAN.use('util.network'); obj.network = new util.network();
29                         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
30                         JSAN.use('util.controller'); obj.controller = new util.controller();
31                         obj.controller.init(
32                                 {
33                                         control_map : {
34                                                 'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
35                                                 'sel_clip' : [
36                                                         ['command'],
37                                                         function() { obj.list.clipboard(); }
38                                                 ],
39                                                 'cmd_broken' : [
40                                                         ['command'],
41                                                         function() { alert('Not Yet Implemented'); }
42                                                 ],
43                                                 'cmd_show_my_libs' : [
44                                                         ['command'],
45                                                         function() { 
46                                                                 obj.show_my_libs(); 
47                                                         }
48                                                 ],
49                                                 'cmd_show_all_libs' : [
50                                                         ['command'],
51                                                         function() {
52                                                                 obj.show_all_libs();
53                                                         }
54                                                 ],
55                                                 'cmd_show_libs_with_copies' : [
56                                                         ['command'],
57                                                         function() {
58                                                                 obj.show_libs_with_copies();
59                                                         }
60                                                 ],
61                                                 'cmd_clear' : [
62                                                         ['command'],
63                                                         function() {
64                                                                 obj.map_tree = {};
65                                                                 obj.list.clear();
66                                                         }
67                                                 ],
68                                                 'sel_mark_items_damaged' : [
69                                                         ['command'],
70                                                         function() {
71                                                                 JSAN.use('cat.util'); JSAN.use('util.functional');
72
73                                                                 var list = util.functional.filter_list( obj.sel_list, function (o) { return o.split(/_/)[0] == 'acp'; });
74
75                                                                 list = util.functional.map_list( list, function (o) { return o.split(/_/)[1]; });
76
77                                                                 cat.util.mark_item_damaged( list );
78
79                                                                 obj.refresh_list();
80                                                         }
81                                                 ],
82                                                 'sel_mark_items_missing' : [
83                                                         ['command'],
84                                                         function() {
85                                                                 JSAN.use('cat.util'); JSAN.use('util.functional');
86
87                                                                 var list = util.functional.filter_list( obj.sel_list, function (o) { return o.split(/_/)[0] == 'acp'; });
88
89                                                                 list = util.functional.map_list( list, function (o) { return o.split(/_/)[1]; });
90
91                                                                 cat.util.mark_item_missing( list );
92
93                                                                 obj.refresh_list();
94                                                         }
95                                                 ],
96                                                 'sel_patron' : [
97                                                         ['command'],
98                                                         function() {
99                                                                 JSAN.use('util.functional');
100
101                                                                 var list = util.functional.filter_list(
102                                                                         obj.sel_list,
103                                                                         function (o) {
104                                                                                 return o.split(/_/)[0] == 'acp';
105                                                                         }
106                                                                 );
107
108                                                                 list = util.functional.map_list(
109                                                                         list,
110                                                                         function (o) {
111                                                                                 return { 'copy_id' : o.split(/_/)[1] };
112                                                                         }
113                                                                 );
114                                                                 
115                                                                 JSAN.use('circ.util');
116                                                                 circ.util.show_last_few_circs(list);
117                                                         }
118                                                 ],
119                                                 'sel_copy_details' : [
120                                                         ['command'],
121                                                         function() {
122                                                                 JSAN.use('util.functional');
123
124                                                                 var list = util.functional.filter_list(
125                                                                         obj.sel_list,
126                                                                         function (o) {
127                                                                                 return o.split(/_/)[0] == 'acp';
128                                                                         }
129                                                                 );
130
131                                                                 list = util.functional.map_list(
132                                                                         list,
133                                                                         function (o) {
134                                                                                 return o.split(/_/)[1];
135                                                                         }
136                                                                 );
137         
138                                                                 JSAN.use('circ.util');
139                                                                 for (var i = 0; i < list.length; i++) {
140                                                                         circ.util.show_copy_details( list[i] );
141                                                                 }
142                                                         }
143                                                 ],
144                                                 'cmd_add_items' : [
145                                                         ['command'],
146                                                         function() {
147                                                                 try {
148                                                                         JSAN.use('util.functional');
149                                                                         var list = util.functional.map_list(
150                                                                                 util.functional.filter_list(
151                                                                                         obj.sel_list,
152                                                                                         function (o) {
153                                                                                                 return o.split(/_/)[0] == 'acn';
154                                                                                         }
155                                                                                 ),
156                                                                                 function (o) {
157                                                                                         return o.split(/_/)[1];
158                                                                                 }
159                                                                         );
160                                                                         if (list.length == 0) return;
161
162                                                                         var copy_shortcut = {};
163                                                                         list = util.functional.map_list(
164                                                                                 list,
165                                                                                 function (o) {
166                                                                                         var ou_id = obj.map_acn['acn_' + o].owning_lib();
167                                                                                         var volume_id = o;
168                                                                                         var label = obj.map_acn['acn_' + o].label();
169                                                                                         if (!copy_shortcut[ou_id]) copy_shortcut[ou_id] = {};
170                                                                                         copy_shortcut[ou_id][ label ] = volume_id;
171
172                                                                                         return ou_id;
173                                                                                 }
174                                                                         );
175                                                                         /* quick fix */  /* what was this fixing? */
176                                                                         list = []; for (var i in copy_shortcut) { list.push( i ); }
177
178                                                                         var edit = 0;
179                                                                         try {
180                                                                                 edit = obj.network.request(
181                                                                                         api.PERM_MULTI_ORG_CHECK.app,
182                                                                                         api.PERM_MULTI_ORG_CHECK.method,
183                                                                                         [ 
184                                                                                                 ses(), 
185                                                                                                 obj.data.list.au[0].id(), 
186                                                                                                 list,
187                                                                                                 [ 'CREATE_COPY' ]
188                                                                                         ]
189                                                                                 ).length == 0 ? 1 : 0;
190                                                                         } catch(E) {
191                                                                                 obj.error.sdump('D_ERROR','batch permission check: ' + E);
192                                                                         }
193
194                                                                         if (edit==0) return; // no read-only view for this interface
195
196                                                                         var title = 'Add Item';
197
198                                                                         JSAN.use('util.window'); var win = new util.window();
199                                                                         var w = win.open(
200                                                                                 window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
201                                                                                         //+'?doc_id=' + window.escape(obj.docid)
202                                                                                         //+'&ou_ids=' + window.escape( js2JSON(list) )
203                                                                                         //+'&copy_shortcut=' + window.escape( js2JSON(copy_shortcut) ),
204                                                                                 title,
205                                                                                 'chrome,resizable'
206                                                                         );
207                                                                         w.refresh = function() { obj.refresh_list(); }
208                                                                         w.xulG = { 'doc_id':obj.docid, 'ou_ids' : list, 'copy_shortcut' : copy_shortcut };
209                                                                 } catch(E) {
210                                                                         obj.error.standard_unexpected_error_alert('copy browser -> add copies',E);
211                                                                 }
212                                                         }
213                                                 ],
214                                                 'cmd_add_items_to_buckets' : [
215                                                         ['command'],
216                                                         function() {
217                                                                 try {
218                                                                         JSAN.use('util.functional');
219
220                                                                         var list = util.functional.filter_list(
221                                                                                 obj.sel_list,
222                                                                                 function (o) {
223                                                                                         return o.split(/_/)[0] == 'acp';
224                                                                                 }
225                                                                         );
226
227                                                                         list = util.functional.map_list(
228                                                                                 list,
229                                                                                 function (o) {
230                                                                                         return o.split(/_/)[1];
231                                                                                 }
232                                                                         );
233                                                                 
234                                                                         JSAN.use('cat.util');
235                                                                         cat.util.add_copies_to_bucket( list );
236
237                                                                 } catch(E) {
238                                                                         obj.error.standard_unexpected_error_alert('copy browser -> add copies to bucket',E);
239                                                                 }
240                                                         }
241                                                 ],
242                                                 'cmd_replace_barcode' : [
243                                                         ['command'],
244                                                         function() {
245                                                                 try {
246                                                                         JSAN.use('util.functional');
247
248                                                                         var list = util.functional.filter_list(
249                                                                                 obj.sel_list,
250                                                                                 function (o) {
251                                                                                         return o.split(/_/)[0] == 'acp';
252                                                                                 }
253                                                                         );
254
255                                                                         list = util.functional.map_list(
256                                                                                 list,
257                                                                                 function (o) {
258                                                                                         return obj.map_acp[ o ].barcode();
259                                                                                 }
260                                                                         );
261
262                                                                         JSAN.use('cat.util');
263                                                                         for (var i = 0; i < list.length; i++) {
264                                                                                 try {
265                                                                                         cat.util.replace_barcode(list[i]);
266                                                                                 } catch(E) {
267                                                                                         obj.error.standard_unexpected_error_alert('Barcode ' +list[i] + ' not likely replaced.',E);
268                                                                                 }
269                                                                         }
270                                                                         obj.refresh_list();
271
272                                                                 } catch(E) {
273                                                                         obj.error.standard_unexpected_error_alert('copy browser -> replace barcode',E);
274                                                                         obj.refresh_list();
275                                                                 }
276                                                         }
277                                                 ],
278                                                 'cmd_edit_items' : [
279                                                         ['command'],
280                                                         function() {
281                                                                 try {
282                                                                         JSAN.use('util.functional');
283
284                                                                         var list = util.functional.filter_list(
285                                                                                 obj.sel_list,
286                                                                                 function (o) {
287                                                                                         return o.split(/_/)[0] == 'acp';
288                                                                                 }
289                                                                         );
290
291                                                                         list = util.functional.map_list(
292                                                                                 list,
293                                                                                 function (o) {
294                                                                                         return o.split(/_/)[1];
295                                                                                 }
296                                                                         );
297
298                                                                         JSAN.use('cat.util'); cat.util.spawn_copy_editor( { 'copy_ids' : list, 'edit' : 1 } );
299                                                                         obj.refresh_list();
300
301                                                                 } catch(E) {
302                                                                         obj.error.standard_unexpected_error_alert('Copy Browser -> Edit Items',E);
303                                                                 }
304                                                         }
305                                                 ],
306                                                 'cmd_delete_items' : [
307                                                         ['command'],
308                                                         function() {
309                                                                 try {
310                                                                         JSAN.use('util.functional');
311
312                                                                         var list = util.functional.filter_list(
313                                                                                 obj.sel_list,
314                                                                                 function (o) {
315                                                                                         return o.split(/_/)[0] == 'acp';
316                                                                                 }
317                                                                         );
318
319                                                                         list = util.functional.map_list(
320                                                                                 list,
321                                                                                 function (o) {
322                                                                                         return JSON2js( js2JSON( obj.map_acp[ 'acp_' + o.split(/_/)[1] ] ) );
323                                                                                 }
324                                                                         );
325
326                                                                         var r = obj.error.yns_alert('Are you sure you would like to delete ' + (list.length != 1 ? 'these ' + list.length + ' items' : 'this one item') + '?', 'Delete Items?', 'Delete', 'Cancel', null, 'Check here to confirm this action');
327
328                                                                         if (r == 0) {
329                                                                                 var acn_hash = {}; var acn_list = [];
330                                                                                 for (var i = 0; i < list.length; i++) {
331                                                                                         list[i].isdeleted('1');
332                                                                                         var acn_id = list[i].call_number();
333                                                                                         if ( ! acn_hash[ acn_id ] ) {
334                                                                                                 acn_hash[ acn_id ] = obj.map_acn[ 'acn_' + acn_id ];
335                                                                                                 acn_hash[ acn_id ].copies( [] );
336                                                                                         }
337                                                                                         var temp = acn_hash[ acn_id ].copies();
338                                                                                         temp.push( list[i] );
339                                                                                         acn_hash[ acn_id ].copies( temp );
340                                                                                 }
341                                                                                 for (var i in acn_hash) acn_list.push( acn_hash[i] );
342                                                                                 var robj = obj.network.simple_request(
343                                                                                         'FM_ACN_TREE_UPDATE', 
344                                                                                         [ ses(), acn_list, true ],
345                                                                                         null,
346                                                                                         {
347                                                                                                 'title' : 'Override Delete Failure?',
348                                                                                                 'overridable_events' : [
349                                                                                                         1208 /* TITLE_LAST_COPY */,
350                                                                                                         1227 /* COPY_DELETE_WARNING */,
351                                                                                                 ]
352                                                                                         }
353                                                                                 );
354                                                                                 if (robj == null) throw(robj);
355                                                                                 if (typeof robj.ilsevent != 'undefined') {
356                                                                                         if ( (robj.ilsevent != 0) && (robj.ilsevent != 1227 /* COPY_DELETE_WARNING */) && (robj.ilsevent != 1208 /* TITLE_LAST_COPY */) ) throw(robj);
357                                                                                 }
358                                                                                 alert('Action complete.');
359                                                                                 obj.refresh_list();
360                                                                         }
361
362                                                                         
363                                                                 } catch(E) {
364                                                                         obj.error.standard_unexpected_error_alert('copy browser -> delete items',E);
365                                                                         obj.refresh_list();
366                                                                 }
367                                                         }
368                                                 ],
369                                                 'cmd_print_spine_labels' : [
370                                                         ['command'],
371                                                         function() {
372                                                                 try {
373                                                                         JSAN.use('util.functional');
374                                                                         
375                                                                         var list = util.functional.filter_list(
376                                                                                 obj.sel_list,
377                                                                                 function (o) {
378                                                                                         return o.split(/_/)[0] == 'acp';
379                                                                                 }
380                                                                         );
381
382                                                                         list = util.functional.map_list(
383                                                                                 list,
384                                                                                 function (o) {
385                                                                                         return obj.map_acp[ o ];
386                                                                                 }
387                                                                         );
388
389                                                                         obj.data.temp_barcodes_for_labels = util.functional.map_list( list, function(o){return o.barcode();}) ; 
390                                                                         obj.data.stash('temp_barcodes_for_labels');
391                                                                         xulG.new_tab(
392                                                                                 xulG.url_prefix( urls.XUL_SPINE_LABEL ),
393                                                                                 { 'tab_name' : 'Spine Labels' },
394                                                                                 {}
395                                                                         );
396                                                                 } catch(E) {
397                                                                         obj.error.standard_unexpected_error_alert('copy browser -> Spine Labels',E);
398                                                                 }
399                                                         }
400                                                 ],
401                                                 'cmd_add_volumes' : [
402                                                         ['command'],
403                                                         function() {
404                                                                 try {
405                                                                         JSAN.use('util.functional');
406                                                                         var list = util.functional.filter_list(
407                                                                                 obj.sel_list,
408                                                                                 function (o) {
409                                                                                         return o.split(/_/)[0] == 'aou';
410                                                                                 }
411                                                                         );
412                                                                         list = util.functional.map_list(
413                                                                                 list,
414                                                                                 function (o) {
415                                                                                         return o.split(/_/)[1];
416                                                                                 }
417                                                                         );              
418                                                                         var edit = 0;
419                                                                         try {
420                                                                                 edit = obj.network.request(
421                                                                                         api.PERM_MULTI_ORG_CHECK.app,
422                                                                                         api.PERM_MULTI_ORG_CHECK.method,
423                                                                                         [ 
424                                                                                                 ses(), 
425                                                                                                 obj.data.list.au[0].id(), 
426                                                                                                 list,
427                                                                                                 [ 'CREATE_VOLUME', 'CREATE_COPY' ]
428                                                                                         ]
429                                                                                 ).length == 0 ? 1 : 0;
430                                                                         } catch(E) {
431                                                                                 obj.error.sdump('D_ERROR','batch permission check: ' + E);
432                                                                         }
433
434                                                                         if (edit==0) {
435                                                                                 alert("You don't have permission to add volumes to that library.");
436                                                                                 return; // no read-only view for this interface
437                                                                         }
438
439                                                                         var title = 'Add Volume/Item';
440
441                                                                         JSAN.use('util.window'); var win = new util.window();
442                                                                         var w = win.open(
443                                                                                 window.xulG.url_prefix(urls.XUL_VOLUME_COPY_CREATOR),
444                                                                                         //+'?doc_id=' + window.escape(obj.docid)
445                                                                                         //+'&ou_ids=' + window.escape( js2JSON(list) ),
446                                                                                 title,
447                                                                                 'chrome,resizable'
448                                                                         );
449
450                                                                         w.refresh = function() { obj.refresh_list() };
451                                                                         w.xulG = { 'doc_id' : obj.docid, 'ou_ids' : list };
452                                                                 } catch(E) {
453                                                                         obj.error.standard_unexpected_error_alert('copy browser -> add volumes',E);
454                                                                 }
455                                                         }
456                                                 ],
457                                                 'cmd_edit_volumes' : [
458                                                         ['command'],
459                                                         function() {
460                                                                 try {
461                                                                         JSAN.use('util.functional');
462                                                                         var list = util.functional.map_list(
463                                                                                 util.functional.filter_list(
464                                                                                         obj.sel_list,
465                                                                                         function (o) {
466                                                                                                 return o.split(/_/)[0] == 'acn';
467                                                                                         }
468                                                                                 ),
469                                                                                 function (o) {
470                                                                                         return o.split(/_/)[1];
471                                                                                 }
472                                                                         );
473                                                                         if (list.length == 0) return;
474
475                                                                         var edit = 0;
476                                                                         try {
477                                                                                 edit = obj.network.request(
478                                                                                         api.PERM_MULTI_ORG_CHECK.app,
479                                                                                         api.PERM_MULTI_ORG_CHECK.method,
480                                                                                         [ 
481                                                                                                 ses(), 
482                                                                                                 obj.data.list.au[0].id(), 
483                                                                                                 util.functional.map_list(
484                                                                                                         list,
485                                                                                                         function (o) {
486                                                                                                                 return obj.map_acn[ 'acn_' + o ].owning_lib();
487                                                                                                         }
488                                                                                                 ),
489                                                                                                 [ 'UPDATE_VOLUME' ]
490                                                                                         ]
491                                                                                 ).length == 0 ? 1 : 0;
492                                                                         } catch(E) {
493                                                                                 obj.error.sdump('D_ERROR','batch permission check: ' + E);
494                                                                         }
495
496                                                                         if (edit==0) {
497                                                                                 alert("You don't have permission to edit this volume.");
498                                                                                 return; // no read-only view for this interface
499                                                                         }
500
501                                                                         list = util.functional.map_list(
502                                                                                 list,
503                                                                                 function (o) {
504                                                                                         var my_acn = obj.map_acn['acn_' + o];
505                                                                                         return function(r){return r;}(my_acn);
506                                                                                 }
507                                                                         );
508
509                                                                         var title = list.length == 1 ? 'Volume' : 'Volumes';
510
511                                                                         JSAN.use('util.window'); var win = new util.window();
512                                                                         //obj.data.volumes_temp = js2JSON( list );
513                                                                         //obj.data.stash('volumes_temp');
514                                                                         var my_xulG = win.open(
515                                                                                 window.xulG.url_prefix(urls.XUL_VOLUME_EDITOR),
516                                                                                 title,
517                                                                                 'chrome,modal,resizable',
518                                                                                 { 'volumes' : list }
519                                                                         );
520
521                                                                         /* FIXME -- need to unique the temp space, and not rely on modalness of window */
522                                                                         //obj.data.stash_retrieve();
523                                                                         var volumes = my_xulG.volumes;
524                                                                         if (!volumes) return;
525                                                                 
526                                                                         volumes = util.functional.filter_list(
527                                                                                 volumes,
528                                                                                 function (o) {
529                                                                                         return o.ischanged() == '1';
530                                                                                 }
531                                                                         );
532
533                                                                         volumes = util.functional.map_list(
534                                                                                 volumes,
535                                                                                 function (o) {
536                                                                                         o.record( obj.docid ); // staff client 2 did not do this.  Does it matter?
537                                                                                         return o;
538                                                                                 }
539                                                                         );
540
541                                                                         if (volumes.length == 0) return;
542
543                                                                         try {
544                                                                                 var r = obj.network.request(
545                                                                                         api.FM_ACN_TREE_UPDATE.app,
546                                                                                         api.FM_ACN_TREE_UPDATE.method,
547                                                                                         [ ses(), volumes, true ]
548                                                                                 );
549                                                                                 if (typeof r.ilsevent != 'undefined') {
550                                             switch(r.ilsevent) {
551                                                 case 1705 /* VOLUME_LABEL_EXISTS */ :
552                                                     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.");
553                                                     break;
554                                                 default: throw(r);
555                                             }
556                                         } else {
557                                                                                 alert('Volumes modified.');
558                                         }
559                                                                         } catch(E) {
560                                                                                 obj.error.standard_unexpected_error_alert('volume update error: ',E);
561                                                                         }
562                                                                         obj.refresh_list();
563
564                                                                 } catch(E) {
565                                                                         obj.error.standard_unexpected_error_alert('Copy Browser -> Volume Edit',E);
566                                                                 }
567                                                         }
568                                                 ],
569                                                 'cmd_delete_volumes' : [
570                                                         ['command'],
571                                                         function() {
572                                                                 try {
573                                                                         JSAN.use('util.functional');
574
575                                                                         var list = util.functional.filter_list(
576                                                                                 obj.sel_list,
577                                                                                 function (o) {
578                                                                                         return o.split(/_/)[0] == 'acn';
579                                                                                 }
580                                                                         );
581
582                                                                         list = util.functional.map_list(
583                                                                                 list,
584                                                                                 function (o) {
585                                                                                         return JSON2js( js2JSON( obj.map_acn[ 'acn_' + o.split(/_/)[1] ] ) );
586                                                                                 }
587                                                                         );
588
589                                                                         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');
590
591                                                                         if (r == 0) {
592                                                                                 for (var i = 0; i < list.length; i++) {
593                                                                                         list[i].isdeleted('1');
594                                                                                 }
595                                                                                 var robj = obj.network.simple_request(
596                                                                                         'FM_ACN_TREE_UPDATE', 
597                                                                                         [ ses(), list, true ],
598                                                                                         null,
599                                                                                         {
600                                                                                                 'title' : 'Override Delete Failure?',
601                                                                                                 'overridable_events' : [
602                                                                                                 ]
603                                                                                         }
604                                                                                 );
605                                                                                 if (robj == null) throw(robj);
606                                                                                 if (typeof robj.ilsevent != 'undefined') {
607                                                                                         if (robj.ilsevent == 1206 /* VOLUME_NOT_EMPTY */) {
608                                                                                                 alert('You must delete all the copies on the volume before you may delete the volume itself.');
609                                                                                                 return;
610                                                                                         }
611                                                                                         if (robj.ilsevent != 0) throw(robj);
612                                                                                 }
613                                                                                 alert('Volumes deleted.');
614                                                                                 obj.refresh_list();
615                                                                         }
616                                                                 } catch(E) {
617                                                                         obj.error.standard_unexpected_error_alert('copy browser -> delete volumes',E);
618                                                                         obj.refresh_list();
619                                                                 }
620
621                                                         }
622                                                 ],
623                                                 'cmd_mark_library' : [
624                                                         ['command'],
625                                                         function() {
626                                                                 try {
627                                                                         var list = util.functional.filter_list(
628                                                                                 obj.sel_list,
629                                                                                 function (o) {
630                                                                                         return o.split(/_/)[0] == 'aou';
631                                                                                 }
632                                                                         );
633
634                                                                         list = util.functional.map_list(
635                                                                                 list,
636                                                                                 function (o) {
637                                                                                         return o.split(/_/)[1];
638                                                                                 }
639                                                                         );
640
641                                                                         if (list.length == 1) {
642                                                                                 obj.data.marked_library = { 'lib' : list[0], 'docid' : obj.docid };
643                                                                                 obj.data.stash('marked_library');
644                                                                                 alert('Library + Record marked as Volume Transfer Destination');
645                                                                         } else {
646                                                                                 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');
647                                                                         }
648                                                                 } catch(E) {
649                                                                         obj.error.standard_unexpected_error_alert('copy browser -> mark library',E);
650                                                                 }
651                                                         }
652                                                 ],
653
654                                                 'cmd_mark_volume' : [
655                                                         ['command'],
656                                                         function() {
657                                                                 try {
658                                                                         var list = util.functional.filter_list(
659                                                                                 obj.sel_list,
660                                                                                 function (o) {
661                                                                                         return o.split(/_/)[0] == 'acn';
662                                                                                 }
663                                                                         );
664
665                                                                         list = util.functional.map_list(
666                                                                                 list,
667                                                                                 function (o) {
668                                                                                         return o.split(/_/)[1];
669                                                                                 }
670                                                                         );
671
672                                                                         if (list.length == 1) {
673                                                                                 obj.data.marked_volume = list[0];
674                                                                                 obj.data.stash('marked_volume');
675                                                                                 alert('Volume marked as Item Transfer Destination');
676                                                                         } else {
677                                                                                 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');
678                                                                         }
679                                                                 } catch(E) {
680                                                                         obj.error.standard_unexpected_error_alert('copy browser -> mark volume',E);
681                                                                 }
682                                                         }
683                                                 ],
684                                                 'cmd_refresh_list' : [
685                                                         ['command'],
686                                                         function() {
687                                                                 obj.refresh_list();
688                                                         }
689                                                 ],
690                                                 'cmd_transfer_volume' : [
691                                                         ['command'],
692                                                         function() {
693                                                                 try {
694                                                                         obj.data.stash_retrieve();
695                                                                         if (!obj.data.marked_library) {
696                                                                                 alert('Please mark a library as the destination from within holdings maintenance and then try this again.');
697                                                                                 return;
698                                                                         }
699                                                                         
700                                                                         JSAN.use('util.functional');
701
702                                                                         var list = util.functional.filter_list(
703                                                                                 obj.sel_list,
704                                                                                 function (o) {
705                                                                                         return o.split(/_/)[0] == 'acn';
706                                                                                 }
707                                                                         );
708
709                                                                         list = util.functional.map_list(
710                                                                                 list,
711                                                                                 function (o) {
712                                                                                         return o.split(/_/)[1];
713                                                                                 }
714                                                                         );
715
716                                                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
717                                                                         var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto">';
718                                                                         xml += '<description>Transfer volumes ';
719
720                                                                         xml += util.functional.map_list(
721                                                                                 list,
722                                                                                 function (o) {
723                                                                                         return obj.map_acn[ 'acn_' + o ].label();
724                                                                                 }
725                                                                         ).join(", ");
726
727                                                                         xml += ' to library ' + obj.data.hash.aou[ obj.data.marked_library.lib ].shortname();
728                                                                         xml += ' on the following record?</description>';
729                                                                         xml += '<hbox><button label="Transfer" name="fancy_submit"/>';
730                                                                         xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
731                                                                         xml += '<iframe style="overflow: scroll" flex="1" src="' + urls.XUL_BIB_BRIEF + '?docid=' + obj.data.marked_library.docid + '"/>';
732                                                                         xml += '</vbox>';
733                                                                         JSAN.use('OpenILS.data');
734                                                                         var data = new OpenILS.data(); data.init({'via':'stash'});
735                                                                         //data.temp_transfer = xml; data.stash('temp_transfer');
736                                                                         JSAN.use('util.window'); var win = new util.window();
737                                                                         var fancy_prompt_data = win.open(
738                                                                                 urls.XUL_FANCY_PROMPT,
739                                                                                 //+ '?xml_in_stash=temp_transfer'
740                                                                                 //+ '&title=' + window.escape('Volume Transfer'),
741                                                                                 'fancy_prompt', 'chrome,resizable,modal,width=500,height=300',
742                                                                                 { 'xml' : xml, 'title' : 'Volume Transfer' }
743                                                                         );
744
745                                                                         if (fancy_prompt_data.fancy_status == 'incomplete') { alert('Transfer Aborted'); return; }
746
747                                                                         var robj = obj.network.simple_request(
748                                                                                 'FM_ACN_TRANSFER', 
749                                                                                 [ ses(), { 'docid' : obj.data.marked_library.docid, 'lib' : obj.data.marked_library.lib, 'volumes' : list } ],
750                                                                                 null,
751                                                                                 {
752                                                                                         'title' : 'Override Volume Transfer Failure?',
753                                                                                         'overridable_events' : [
754                                                                                                 1208 /* TITLE_LAST_COPY */,
755                                                                                                 1219 /* COPY_REMOTE_CIRC_LIB */,
756                                                                                         ],
757                                                                                 }
758                                                                         );
759
760                                                                         if (typeof robj.ilsevent != 'undefined') {
761                                                                                 if (robj.ilsevent == 1221 /* ORG_CANNOT_HAVE_VOLS */) {
762                                                                                         alert('That destination cannot have volumes.');
763                                                                                 } else {
764                                                                                         throw(robj);
765                                                                                 }
766                                                                         } else {
767                                                                                 alert('Volumes transferred.');
768                                                                         }
769
770                                                                 } catch(E) {
771                                                                         obj.error.standard_unexpected_error_alert('All volumes not likely transferred.',E);
772                                                                 }
773                                                                 obj.refresh_list();
774                                                         }
775                                                 ],
776
777                                                 'cmd_transfer_items' : [
778                                                         ['command'],
779                                                         function() {
780                                                                 try {
781                                                                         obj.data.stash_retrieve();
782                                                                         if (!obj.data.marked_volume) {
783                                                                                 alert('Please mark a volume as the destination from within holdings maintenance and then try this again.');
784                                                                                 return;
785                                                                         }
786                                                                         
787                                                                         JSAN.use('util.functional');
788
789                                                                         var list = util.functional.filter_list(
790                                                                                 obj.sel_list,
791                                                                                 function (o) {
792                                                                                         return o.split(/_/)[0] == 'acp';
793                                                                                 }
794                                                                         );
795
796                                                                         list = util.functional.map_list(
797                                                                                 list,
798                                                                                 function (o) {
799                                                                                         return o.split(/_/)[1];
800                                                                                 }
801                                                                         );
802
803                                                                         var volume = obj.network.simple_request('FM_ACN_RETRIEVE',[ obj.data.marked_volume ]);
804
805                                                                         JSAN.use('cat.util'); cat.util.transfer_copies( { 
806                                                                                 'copy_ids' : list, 
807                                                                                 'docid' : volume.record(),
808                                                                                 'volume_label' : volume.label(),
809                                                                                 'owning_lib' : volume.owning_lib(),
810                                                                         } );
811
812                                                                 } catch(E) {
813                                                                         obj.error.standard_unexpected_error_alert('All copies not likely transferred.',E);
814                                                                 }
815                                                                 obj.refresh_list();
816                                                         }
817                                                 ],
818                                         }
819                                 }
820                         );
821
822                         obj.list_init(params);
823
824                         obj.org_ids = obj.network.simple_request('FM_AOU_IDS_RETRIEVE_VIA_RECORD_ID',[ obj.docid ]);
825                         if (typeof obj.org_ids.ilsevent != 'undefined') throw(obj.org_ids);
826
827                         var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
828                         //obj.show_libs( org );
829
830                         //obj.show_my_libs();
831
832                         JSAN.use('util.file'); JSAN.use('util.widgets');
833
834                         var file; var list_data; var ml; 
835
836                         file = new util.file('offline_ou_list'); 
837                         if (file._file.exists()) {
838                                 list_data = file.get_object(); file.close();
839                                 ml = util.widgets.make_menulist( list_data[0], list_data[1] );
840                                 ml.setAttribute('id','lib_menu'); document.getElementById('x_lib_menu').appendChild(ml);
841                                 for (var i = 0; i < obj.org_ids.length; i++) {
842                                         ml.getElementsByAttribute('value',obj.org_ids[i])[0].setAttribute('class','has_copies');
843                                 }
844                                 ml.firstChild.addEventListener(
845                                         'popupshown',
846                                         function(ev) {
847                                                 document.getElementById('legend').setAttribute('hidden','false');
848                                         },
849                                         false
850                                 );
851                                 ml.firstChild.addEventListener(
852                                         'popuphidden',
853                                         function(ev) {
854                                                 document.getElementById('legend').setAttribute('hidden','true');
855                                         },
856                                         false
857                                 );
858                                 ml.addEventListener(
859                                         'command',
860                                         function(ev) {
861                                                 //obj.show_my_libs(ev.target.value);
862                                                 //alert('lib picker, command caught - ml = ' + ml + '\nml.value = ' + ml.value + '\n');
863                                                 if (document.getElementById('refresh_button')) document.getElementById('refresh_button').focus(); 
864                                                 JSAN.use('util.file'); var file = new util.file('copy_browser_prefs.'+obj.data.server_unadorned);
865                                                 util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_acns' : [ 'checked' ], 'show_acps' : [ 'checked' ] });
866                                                 obj.refresh_list();
867                                         },
868                                         false
869                                 );
870                         } else {
871                                 throw('Missing library list.\n');
872                         }
873
874                         JSAN.use('util.widgets'); 
875                 
876                         file = new util.file('copy_browser_prefs.'+obj.data.server_unadorned);
877                         util.widgets.load_attributes(file);
878                         ml.value = ml.getAttribute('value');
879                         if (! ml.value) {
880                                 ml.value = org.id();
881                                 ml.setAttribute('value',ml.value);
882                         }
883
884                         document.getElementById('show_acns').addEventListener(
885                                 'command',
886                                 function(ev) {
887                                         JSAN.use('util.file'); var file = new util.file('copy_browser_prefs.'+obj.data.server_unadorned);
888                                         util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_acns' : [ 'checked' ], 'show_acps' : [ 'checked' ] });
889                                 },
890                                 false
891                         );
892
893                         document.getElementById('show_acps').addEventListener(
894                                 'command',
895                                 function(ev) {
896                                         JSAN.use('util.file'); var file = new util.file('copy_browser_prefs.'+obj.data.server_unadorned);
897                                         util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_acns' : [ 'checked' ], 'show_acps' : [ 'checked' ] });
898                                 },
899                                 false
900                         );
901
902                         obj.show_my_libs( ml.value );
903
904                         obj.show_consortial_count();
905
906                 } catch(E) {
907                         this.error.standard_unexpected_error_alert('cat.copy_browser.init: ',E);
908                 }
909         },
910
911         'show_consortial_count' : function() {
912                 var obj = this;
913                 try {
914                         obj.network.simple_request('FM_ACP_COUNT',[ obj.data.tree.aou.id(), obj.docid ],function(req){ 
915                                 try {
916                                         var robj = req.getResultObject();
917                                         var x = document.getElementById('consortial_total');
918                                         if (x) x.setAttribute('value',robj[0].count);
919                                         x = document.getElementById('consortial_available');
920                                         if (x) x.setAttribute('value',robj[0].available);
921                                 } catch(E) {
922                                         obj.error.standard_unexpected_error_alert('Error retrieving consortial copy count.',E);
923                                 }
924                         });
925                 } catch(E) {
926                         this.error.standard_unexpected_error_alert('cat.copy_browser.show_consortial_count: ',E);
927                 }
928         },
929
930         'show_my_libs' : function(org) {
931                 var obj = this;
932                 try {
933                         if (!org) {
934                                 org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
935                         } else {
936                                 if (typeof org != 'object') org = obj.data.hash.aou[ org ];
937                         }
938                         obj.show_libs( org, false );
939                 
940                         var p_org = obj.data.hash.aou[ org.parent_ou() ];
941                         if (p_org) {
942                                 JSAN.use('util.exec'); var exec = new util.exec();
943                                 var funcs = [];
944                                 funcs.push( function() { 
945                                         document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
946                                         document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','true'); 
947                                         document.getElementById('lib_menu').setAttribute('disabled','true'); 
948                                 } );
949                                 for (var i = 0; i < p_org.children().length; i++) {
950                                         funcs.push(
951                                                 function(o) {
952                                                         return function() {
953                                                                 obj.show_libs( o, false );
954                                                         }
955                                                 }( p_org.children()[i] )
956                                         );
957                                 }
958                                 funcs.push( function() { 
959                                         document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
960                                         document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','false'); 
961                                         document.getElementById('lib_menu').setAttribute('disabled','false'); 
962                                 } );
963                                 exec.chain( funcs );
964                         }
965                 } catch(E) {
966                         alert(E);
967                 }
968         },
969
970         'show_all_libs' : function() {
971                 var obj = this;
972                 try {
973                         obj.show_my_libs();
974
975                         obj.show_libs( obj.data.tree.aou );
976
977                         JSAN.use('util.exec'); var exec = new util.exec();
978                         var funcs = [];
979                         funcs.push( function() { 
980                                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
981                                 document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','true'); 
982                                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
983                         } );
984
985                         for (var i = 0; i < obj.data.tree.aou.children().length; i++) {
986                                 funcs.push(
987                                         function(o) {
988                                                 return function() {
989                                                         obj.show_libs( o );
990                                                 }
991                                         }( obj.data.tree.aou.children()[i] )
992                                 );
993                         }
994                         funcs.push( function() { 
995                                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
996                                 document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','false'); 
997                                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
998                         } );
999
1000                         exec.chain( funcs );
1001                 } catch(E) {
1002                         alert(E);
1003                 }
1004         },
1005
1006         'show_libs_with_copies' : function() {
1007                 var obj = this;
1008                 try {
1009                         JSAN.use('util.exec'); var exec = new util.exec();
1010                         JSAN.use('util.functional');
1011
1012                         var orgs = util.functional.map_list(
1013                                 obj.org_ids,
1014                                 function(id) { return obj.data.hash.aou[id]; }
1015                         ).sort(
1016                                 function( a, b ) {
1017                                         if (a.shortname() < b.shortname()) return -1;
1018                                         if (a.shortname() > b.shortname()) return 1;
1019                                         return 0;
1020                                 }
1021                         );
1022                         var funcs = [];
1023                         funcs.push( function() { 
1024                                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1025                                 document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','true'); 
1026                                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1027                         } );
1028
1029                         for (var i = 0; i < orgs.length; i++) {
1030                                 funcs.push(
1031                                         function(o) {
1032                                                 return function() {
1033                                                         obj.show_libs(o,false);
1034                                                 }
1035                                         }( orgs[i] )
1036                                 );
1037                         }
1038                         funcs.push( function() { 
1039                                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1040                                 document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','false'); 
1041                                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1042                         } );
1043
1044                         exec.chain( funcs );
1045                 } catch(E) {
1046                         alert(E);
1047                 }
1048         },
1049
1050         'show_libs' : function(start_aou,show_open) {
1051                 var obj = this;
1052                 try {
1053                         if (!start_aou) throw('show_libs: Need a start_aou');
1054                         JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
1055                         JSAN.use('util.functional'); JSAN.use('util.exec'); var exec = new util.exec();
1056
1057                         var funcs = [];
1058
1059                         var parents = [];
1060                         var temp_aou = start_aou;
1061                         while ( temp_aou.parent_ou() ) {
1062                                 temp_aou = obj.data.hash.aou[ temp_aou.parent_ou() ];
1063                                 parents.push( temp_aou );
1064                         }
1065                         parents.reverse();
1066
1067                         for (var i = 0; i < parents.length; i++) {
1068                                 funcs.push(
1069                                         function(o,p) {
1070                                                 return function() { 
1071                                                         if (show_open) {
1072                                                                 obj.append_org(o,p,{'container':'true','open':'true'}); 
1073                                                         } else {
1074                                                                 obj.append_org(o,p,{'container':'true'}); 
1075                                                         }
1076                                                 };
1077                                         }(parents[i], obj.data.hash.aou[ parents[i].parent_ou() ])
1078                                 );
1079                         }
1080
1081                         funcs.push(
1082                                 function(o,p) {
1083                                         return function() { obj.append_org(o,p); };
1084                                 }(start_aou,obj.data.hash.aou[ start_aou.parent_ou() ])
1085                         );
1086
1087                         funcs.push(
1088                                 function() {
1089                                         if (start_aou.children()) {
1090                                                 var x = obj.map_tree[ 'aou_' + start_aou.id() ];
1091                                                 x.setAttribute('container','true');
1092                                                 if (show_open) x.setAttribute('open','true');
1093                                                 for (var i = 0; i < start_aou.children().length; i++) {
1094                                                         funcs.push(
1095                                                                 function(o,p) {
1096                                                                         return function() { obj.append_org(o,p); };
1097                                                                 }( start_aou.children()[i], start_aou )
1098                                                         );
1099                                                 }
1100                                         }
1101                                 }
1102                         );
1103
1104                         exec.chain( funcs );
1105
1106                 } catch(E) {
1107                         alert(E);
1108                 }
1109         },
1110
1111         'on_select' : function(list,twisty) {
1112                 var obj = this;
1113                 for (var i = 0; i < list.length; i++) {
1114                         var node = obj.map_tree[ list[i] ];
1115                         //if (node.lastChild.nodeName == 'treechildren') { continue; } else { alert(node.lastChild.nodeName); }
1116                         var row_type = list[i].split('_')[0];
1117                         var id = list[i].split('_')[1];
1118                         switch(row_type) {
1119                                 case 'aou' : obj.on_select_org(id,twisty); break;
1120                                 case 'acn' : obj.on_select_acn(id,twisty); break;
1121                                 default: break;
1122                         }
1123                 }
1124         },
1125
1126         'on_select_acn' : function(acn_id,twisty) {
1127                 var obj = this;
1128                 try {
1129                         var acn_tree = obj.map_acp[ 'acn_' + acn_id ];
1130                         var funcs = [];
1131                         funcs.push( function() { 
1132                                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1133                                 document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','true'); 
1134                                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1135                         } );
1136                         if (acn_tree.copies()) {
1137                                 for (var i = 0; i < acn_tree.copies().length; i++) {
1138                                         funcs.push(
1139                                                 function(c,a) {
1140                                                         return function() {
1141                                                                 obj.append_acp(c,a);
1142                                                         }
1143                                                 }( acn_tree.copies()[i], acn_tree )
1144                                         )
1145                                 }
1146                         }
1147                         funcs.push( function() { 
1148                                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1149                                 document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','false'); 
1150                                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1151                         } );
1152                         JSAN.use('util.exec'); var exec = new util.exec();
1153                         exec.chain( funcs );
1154                 } catch(E) {
1155                         alert(E);
1156                 }
1157         },
1158
1159         'on_select_org' : function(org_id,twisty) {
1160                 var obj = this;
1161                 var org = obj.data.hash.aou[ org_id ];
1162                 if (obj.data.hash.aout[ org.ou_type() ].depth() == 0) return; 
1163                 /* otherwise, we'd show every system in the consortia */
1164                 var funcs = [];
1165                 funcs.push( function() { 
1166                         document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1167                         document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','true'); 
1168                         document.getElementById('lib_menu').setAttribute('disabled','true'); 
1169                 } );
1170                 if (org.children()) {
1171                         for (var i = 0; i < org.children().length; i++) {
1172                                 funcs.push(
1173                                         function(o,p) {
1174                                                 return function() {
1175                                                         obj.append_org(o,p)
1176                                                 }
1177                                         }(org.children()[i],org)
1178                                 );
1179                         }
1180                 } 
1181                 if (obj.map_acn[ 'aou_' + org_id ]) {
1182                         for (var i = 0; i < obj.map_acn[ 'aou_' + org_id ].length; i++) {
1183                                 funcs.push(
1184                                         function(o,a) {
1185                                                 return function() {
1186                                                         obj.append_acn(o,a);
1187                                                 }
1188                                         }( org, obj.map_acn[ 'aou_' + org_id ][i] )
1189                                 );
1190                         }
1191                 }
1192                 funcs.push( function() { 
1193                         document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1194                         document.getElementById('cmd_show_libs_with_copies').setAttribute('disabled','false'); 
1195                         document.getElementById('lib_menu').setAttribute('disabled','false'); 
1196                 } );
1197                 JSAN.use('util.exec'); var exec = new util.exec();
1198                 exec.chain( funcs );
1199         },
1200
1201         'append_org' : function (org,parent_org,params) {
1202                 var obj = this;
1203                 try {
1204                         if (obj.map_tree[ 'aou_' + org.id() ]) {
1205                                 var x = obj.map_tree[ 'aou_' + org.id() ];
1206                                 if (params) {
1207                                         for (var i in params) {
1208                                                 x.setAttribute(i,params[i]);
1209                                         }
1210                                 }
1211                                 return x;
1212                         }
1213
1214                         var data = {
1215                                 'row' : {
1216                                         'my' : {
1217                                                 'aou' : org,
1218                                         }
1219                                 },
1220                                 'skip_all_columns_except' : [0,1,2],
1221                                 'retrieve_id' : 'aou_' + org.id(),
1222                                 'to_bottom' : true,
1223                                 'no_auto_select' : true,
1224                         };
1225                 
1226                         var acn_tree_list;
1227                         if ( obj.org_ids.indexOf( org.id() ) == -1 ) {
1228                                 if ( get_bool( obj.data.hash.aout[ org.ou_type() ].can_have_vols() ) ) {
1229                                         data.row.my.volume_count = '0';
1230                                         data.row.my.copy_count = '<0>';
1231                                 } else {
1232                                         data.row.my.volume_count = '';
1233                                         data.row.my.copy_count = '';
1234                                 }
1235                         } else {
1236                                 var v_count = 0; var c_count = 0;
1237                                 acn_tree_list = obj.network.simple_request(
1238                                         'FM_ACN_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS',
1239                                         [ ses(), obj.docid, [ org.id() ] ]
1240                                 );
1241                                 for (var i = 0; i < acn_tree_list.length; i++) {
1242                                         v_count++;
1243                                         obj.map_acn[ 'acn_' + acn_tree_list[i].id() ] = function(r){return r;}(acn_tree_list[i]);
1244                                         var copies = acn_tree_list[i].copies(); if (copies) c_count += copies.length;
1245                                         for (var j = 0; j < copies.length; j++) {
1246                                                 obj.map_acp[ 'acp_' + copies[j].id() ] = function(r){return r;}(copies[j]);
1247                                         }
1248                                 }
1249                                 data.row.my.volume_count = v_count;
1250                                 data.row.my.copy_count = '<' + c_count + '>';
1251                         }
1252                         if (parent_org) {
1253                                 data.node = obj.map_tree[ 'aou_' + parent_org.id() ];
1254                         }
1255                         var nparams = obj.list.append(data);
1256                         var node = nparams.my_node;
1257                         if (params) {
1258                                 for (var i in params) {
1259                                         node.setAttribute(i,params[i]);
1260                                 }
1261                         }
1262                         obj.map_tree[ 'aou_' + org.id() ] = node;
1263
1264                         if (org.children()) {
1265                                 node.setAttribute('container','true');
1266                         }
1267
1268                         if (parent_org) {
1269                                 if ( obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ].parent_ou() == parent_org.id() ) {
1270                                         data.node.setAttribute('open','true');
1271                                 }
1272                         } else {
1273                                 obj.map_tree[ 'aou_' + org.id() ].setAttribute('open','true');
1274                         }
1275
1276                         if (acn_tree_list) {
1277                                 obj.map_acn[ 'aou_' + org.id() ] = acn_tree_list;
1278                                 node.setAttribute('container','true');
1279                         }
1280
1281                         if (document.getElementById('show_acns').checked) {
1282                                 if ( obj.data.hash.aout[ org.ou_type() ].depth() != 0 ) {
1283                                         node.setAttribute('open','true');
1284                                         setTimeout( function() { obj.on_select_org( org.id() ); }, 0 );
1285                                 }
1286                         }
1287
1288                 } catch(E) {
1289                         dump(E+'\n');
1290                         alert(E);
1291                 }
1292         },
1293
1294         'append_acn' : function( org, acn_tree, params ) {
1295                 var obj = this;
1296                 try {
1297                         if (obj.map_tree[ 'acn_' + acn_tree.id() ]) {
1298                                 var x = obj.map_tree[ 'acn_' + acn_tree.id() ];
1299                                 if (params) {
1300                                         for (var i in params) {
1301                                                 x.setAttribute(i,params[i]);
1302                                         }
1303                                 }
1304                                 return x;
1305                         }
1306
1307                         var parent_node = obj.map_tree[ 'aou_' + org.id() ];
1308                         var data = {
1309                                 'row' : {
1310                                         'my' : {
1311                                                 'aou' : org,
1312                                                 'acn' : acn_tree,
1313                                                 'volume_count' : '',
1314                                                 'copy_count' : acn_tree.copies() ? acn_tree.copies().length : '0',
1315                                         }
1316                                 },
1317                                 'skip_all_columns_except' : [0,1,2],
1318                                 'retrieve_id' : 'acn_' + acn_tree.id(),
1319                                 'node' : parent_node,
1320                                 'to_bottom' : true,
1321                                 'no_auto_select' : true,
1322                         };
1323                         var nparams = obj.list.append(data);
1324                         var node = nparams.my_node;
1325                         obj.map_tree[ 'acn_' + acn_tree.id() ] =  node;
1326                         if (params) {
1327                                 for (var i in params) {
1328                                         node.setAttribute(i,params[i]);
1329                                 }
1330                         }
1331                         if (acn_tree.copies()) {
1332                                 obj.map_acp[ 'acn_' + acn_tree.id() ] = acn_tree;
1333                                 node.setAttribute('container','true');
1334                         }
1335                         if (document.getElementById('show_acps').checked) {
1336                                 node.setAttribute('open','true');
1337                                 setTimeout( function() { obj.on_select_acn( acn_tree.id() ); }, 0 );
1338                         }
1339
1340                 } catch(E) {
1341                         dump(E+'\n');
1342                         alert(E);
1343                 }
1344         },
1345
1346         'append_acp' : function( acp_item, acn_tree, params ) {
1347                 var obj = this;
1348                 try {
1349                         if (obj.map_tree[ 'acp_' + acp_item.id() ]) {
1350                                 var x = obj.map_tree[ 'acp_' + acp_item.id() ];
1351                                 if (params) {
1352                                         for (var i in params) {
1353                                                 x.setAttribute(i,params[i]);
1354                                         }
1355                                 }
1356                                 return x;
1357                         }
1358
1359                         var parent_node = obj.map_tree[ 'acn_' + acn_tree.id() ];
1360                         var data = {
1361                                 'row' : {
1362                                         'my' : {
1363                                                 'aou' : obj.data.hash.aou[ acn_tree.owning_lib() ],
1364                                                 'acn' : acn_tree,
1365                                                 'acp' : acp_item,
1366                                                 'volume_count' : '',
1367                                                 'copy_count' : '',
1368                                         }
1369                                 },
1370                                 'retrieve_id' : 'acp_' + acp_item.id(),
1371                                 'node' : parent_node,
1372                                 'to_bottom' : true,
1373                                 'no_auto_select' : true,
1374                         };
1375                         var nparams = obj.list.append(data);
1376                         var node = nparams.my_node;
1377                         obj.map_tree[ 'acp_' + acp_item.id() ] =  node;
1378                         if (params) {
1379                                 for (var i in params) {
1380                                         node.setAttribute(i,params[i]);
1381                                 }
1382                         }
1383
1384                 } catch(E) {
1385                         dump(E+'\n');
1386                         alert(E);
1387                 }
1388         },
1389
1390         'list_init' : function( params ) {
1391
1392                 try {
1393                         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
1394                         var obj = this;
1395                         
1396                         JSAN.use('circ.util');
1397                         var columns = [
1398                                 {
1399                                         'id' : 'tree_location', 'label' : 'Location/Barcode', 'flex' : 1,
1400                                         'primary' : true, 'hidden' : false, 
1401                                         'render' : function(my) { return my.acp ? my.acp.barcode() : my.acn ? my.acn.label() : my.aou ? my.aou.shortname() + " : " + my.aou.name() : "???"; },
1402                                 },
1403                                 {
1404                                         'id' : 'volume_count', 'label' : 'Volumes', 'flex' : 0,
1405                                         'primary' : false, 'hidden' : false, 
1406                                         'render' : function(my) { return my.volume_count; },
1407                                 },
1408                                 {
1409                                         'id' : 'copy_count', 'label' : 'Copies', 'flex' : 0,
1410                                         'primary' : false, 'hidden' : false, 
1411                                         'render' : function(my) { return my.copy_count; },
1412                                 },
1413                         ].concat(
1414                                 circ.util.columns( 
1415                                         { 
1416                                                 'location' : { 'hidden' : false },
1417                                                 'circ_lib' : { 'hidden' : false },
1418                                                 'owning_lib' : { 'hidden' : false },
1419                                                 'call_number' : { 'hidden' : false },
1420                                                 'due_date' : { 'hidden' : false },
1421                                                 'status' : { 'hidden' : false },
1422                                         },
1423                                         {
1424                                                 'just_these' : [
1425                                                         'due_date',
1426                                                         'owning_lib',
1427                                                         'circ_lib',
1428                                                         'call_number',
1429                                                         'copy_number',
1430                                                         'location',
1431                                                         'barcode',
1432                                                         'loan_duration',
1433                                                         'fine_level',
1434                                                         'circulate',
1435                                                         'holdable',
1436                                                         'opac_visible',
1437                                                         'ref',
1438                                                         'deposit',
1439                                                         'deposit_amount',
1440                                                         'price',
1441                                                         'circ_as_type',
1442                                                         'circ_modifier',
1443                                                         'status',
1444                                                         'alert_message',
1445                                                         'acp_id',
1446                                                 ]
1447                                         }
1448                                 )
1449                         );
1450                         JSAN.use('util.list'); obj.list = new util.list('copy_tree');
1451                         obj.list.init(
1452                                 {
1453                                         'no_auto_select' : true,
1454                                         'columns' : columns,
1455                                         'map_row_to_columns' : circ.util.std_map_row_to_columns(' '),
1456                                         'retrieve_row' : function(params) {
1457
1458                                                 var row = params.row;
1459
1460                                                 var funcs = [];
1461                                         /*      
1462                                                 if (!row.my.mvr) funcs.push(
1463                                                         function() {
1464
1465                                                                 row.my.mvr = obj.network.request(
1466                                                                         api.MODS_SLIM_RECORD_RETRIEVE_VIA_COPY.app,
1467                                                                         api.MODS_SLIM_RECORD_RETRIEVE_VIA_COPY.method,
1468                                                                         [ row.my.circ.target_copy() ]
1469                                                                 );
1470
1471                                                         }
1472                                                 );
1473                                                 if (!row.my.acp) {
1474                                                         funcs.push(     
1475                                                                 function() {
1476
1477                                                                         row.my.acp = obj.network.request(
1478                                                                                 api.FM_ACP_RETRIEVE.app,
1479                                                                                 api.FM_ACP_RETRIEVE.method,
1480                                                                                 [ row.my.circ.target_copy() ]
1481                                                                         );
1482
1483                                                                         params.row_node.setAttribute( 'retrieve_id',row.my.acp.barcode() );
1484
1485                                                                 }
1486                                                         );
1487                                                 } else {
1488                                                         params.row_node.setAttribute( 'retrieve_id',row.my.acp.barcode() );
1489                                                 }
1490                                         */
1491                                                 funcs.push(
1492                                                         function() {
1493
1494                                                                 if (typeof params.on_retrieve == 'function') {
1495                                                                         params.on_retrieve(row);
1496                                                                 }
1497
1498                                                         }
1499                                                 );
1500
1501                                                 JSAN.use('util.exec'); var exec = new util.exec();
1502                                                 exec.on_error = function(E) {
1503                                                         var err = 'items chain: ' + js2JSON(E);
1504                                                         obj.error.sdump('D_ERROR',err);
1505                                                         return true; /* keep going */
1506                                                 }
1507                                                 exec.chain( funcs );
1508
1509                                                 return row;
1510                                         },
1511                                         'on_click' : function(ev) {
1512                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserRead');
1513                                                 var row = {}; var col = {}; var nobj = {};
1514                                                 obj.list.node.treeBoxObject.getCellAt(ev.clientX,ev.clientY,row,col,nobj); 
1515                                                 if ((row.value == -1)||(nobj.value != 'twisty')) { return; }
1516                                                 var node = obj.list.node.contentView.getItemAtIndex(row.value);
1517                                                 var list = [ node.getAttribute('retrieve_id') ];
1518                                                 if (typeof obj.on_select == 'function') {
1519                                                         obj.on_select(list,true);
1520                                                 }
1521                                                 if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
1522                                                         window.xulG.on_select(list);
1523                                                 }
1524                                         },
1525                                         'on_select' : function(ev) {
1526                                                 JSAN.use('util.functional');
1527                                                 var sel = obj.list.retrieve_selection();
1528                                                 obj.controller.view.sel_clip.disabled = sel.length < 1;
1529                                                 obj.sel_list = util.functional.map_list(
1530                                                         sel,
1531                                                         function(o) { return o.getAttribute('retrieve_id'); }
1532                                                 );
1533                                                 obj.toggle_actions();
1534                                                 if (typeof obj.on_select == 'function') {
1535                                                         obj.on_select(obj.sel_list);
1536                                                 }
1537                                                 if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
1538                                                         window.xulG.on_select(obj.sel_list);
1539                                                 }
1540                                         },
1541                                 }
1542                         );
1543
1544                         obj.controller.render();
1545
1546                 } catch(E) {
1547                         this.error.sdump('D_ERROR','cat.copy_browser.list_init: ' + E + '\n');
1548                         alert(E);
1549                 }
1550         },
1551
1552         'toggle_actions' : function() {
1553                 var obj = this;
1554                 try {
1555                         var found_aou = false; var found_acn = false; var found_acp = false;
1556                         var found_aou_with_can_have_vols = false;
1557                         for (var i = 0; i < obj.sel_list.length; i++) {
1558                                 var type = obj.sel_list[i].split(/_/)[0];
1559                                 switch(type) {
1560                                         case 'aou' : 
1561                                                 found_aou = true; 
1562                                                 var org = obj.data.hash.aou[ obj.sel_list[i].split(/_/)[1] ];
1563                                                 if ( get_bool( obj.data.hash.aout[ org.ou_type() ].can_have_vols() ) ) found_aou_with_can_have_vols = true;
1564                                         break;
1565                                         case 'acn' : found_acn = true; break;
1566                                         case 'acp' : found_acp = true; break;
1567                                 }
1568                         }
1569                         obj.controller.view.cmd_add_items.setAttribute('disabled','true');
1570                         obj.controller.view.cmd_add_items_to_buckets.setAttribute('disabled','true');
1571                         obj.controller.view.cmd_edit_items.setAttribute('disabled','true');
1572                         obj.controller.view.cmd_replace_barcode.setAttribute('disabled','true');
1573                         obj.controller.view.cmd_delete_items.setAttribute('disabled','true');
1574                         obj.controller.view.cmd_print_spine_labels.setAttribute('disabled','true');
1575                         obj.controller.view.cmd_add_volumes.setAttribute('disabled','true');
1576                         obj.controller.view.cmd_mark_library.setAttribute('disabled','true');
1577                         obj.controller.view.cmd_edit_volumes.setAttribute('disabled','true');
1578                         obj.controller.view.cmd_delete_volumes.setAttribute('disabled','true');
1579                         obj.controller.view.cmd_mark_volume.setAttribute('disabled','true');
1580                         obj.controller.view.cmd_transfer_volume.setAttribute('disabled','true');
1581                         obj.controller.view.cmd_transfer_items.setAttribute('disabled','true');
1582                         obj.controller.view.sel_copy_details.setAttribute('disabled','true');
1583                         obj.controller.view.sel_patron.setAttribute('disabled','true');
1584                         obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','true');
1585                         obj.controller.view.sel_mark_items_missing.setAttribute('disabled','true');
1586                         if (found_aou && found_aou_with_can_have_vols) {
1587                                 obj.controller.view.cmd_add_volumes.setAttribute('disabled','false');
1588                                 obj.controller.view.cmd_mark_library.setAttribute('disabled','false');
1589                         }
1590                         if (found_acn) {
1591                                 obj.controller.view.cmd_edit_volumes.setAttribute('disabled','false');
1592                                 obj.controller.view.cmd_delete_volumes.setAttribute('disabled','false');
1593                                 obj.controller.view.cmd_mark_volume.setAttribute('disabled','false');
1594                                 obj.controller.view.cmd_add_items.setAttribute('disabled','false');
1595                                 obj.controller.view.cmd_transfer_volume.setAttribute('disabled','false');
1596                         }
1597                         if (found_acp) {
1598                                 obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','false');
1599                                 obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');
1600                                 obj.controller.view.cmd_add_items_to_buckets.setAttribute('disabled','false');
1601                                 obj.controller.view.cmd_edit_items.setAttribute('disabled','false');
1602                                 obj.controller.view.cmd_replace_barcode.setAttribute('disabled','false');
1603                                 obj.controller.view.cmd_delete_items.setAttribute('disabled','false');
1604                                 obj.controller.view.cmd_print_spine_labels.setAttribute('disabled','false');
1605                                 obj.controller.view.cmd_transfer_items.setAttribute('disabled','false');
1606                                 obj.controller.view.sel_copy_details.setAttribute('disabled','false');
1607                                 obj.controller.view.sel_patron.setAttribute('disabled','false');
1608                         }
1609                 } catch(E) {
1610                         obj.error.standard_unexpected_error_alert('Copy Browser Actions',E);
1611                 }
1612         },
1613
1614         'refresh_list' : function() { 
1615                 try {
1616                         var obj = this;
1617                         obj.list.clear();
1618                         obj.map_tree = {};
1619                         obj.map_acn = {};
1620                         obj.map_acp = {};
1621                         obj.org_ids = obj.network.simple_request('FM_AOU_IDS_RETRIEVE_VIA_RECORD_ID',[ obj.docid ]);
1622                         /*
1623                         var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
1624                         obj.show_libs( org );
1625                         */
1626                         obj.show_my_libs( document.getElementById('lib_menu').value );
1627                         // FIXME - we get a null from the copy_count call if we call it too quickly here
1628                         setTimeout( function() { obj.show_consortial_count(); }, 2000 );
1629                 } catch(E) {
1630                         this.error.standard_unexpected_error_alert('Problem refreshing the volume/copy tree.',E);
1631                 }
1632         },
1633 }
1634
1635 dump('exiting cat.copy_browser.js\n');