]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/serial/manage_subs.js
Remove located URI scope notes from 2.2 Release Notes
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / serial / manage_subs.js
1 dump('entering serial/manage_subs.js\n');
2 // vim:et:sw=4:ts=4:
3
4 if (typeof serial == 'undefined') serial = {};
5 serial.manage_subs = function (params) {
6     try {
7         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
8         JSAN.use('util.error'); this.error = new util.error();
9     } catch(E) {
10         dump('serial/manage_subs: ' + E + '\n');
11     }
12 };
13
14 serial.manage_subs.prototype = {
15
16     'map_tree' : {},
17     'map_ssub' : {},
18     'map_sdist' : {},
19     'map_siss' : {},
20     'map_scap' : {},
21     'sel_list' : [],
22     'funcs' : [],
23     'editor_indexes' : { 'ssub' : 1, 'sdist' : 2, 'siss' : 3, 'scap' : 4 },
24
25     'ids_from_sel_list' : function(type) {
26         var obj = this;
27         JSAN.use('util.functional');
28
29         var list = util.functional.map_list(
30             util.functional.filter_list(
31                 obj.sel_list,
32                 function (o) {
33                     return o.split(/_/)[0] == type;
34                 }
35             ),
36             function (o) {
37                 return o.split(/_/)[1];
38             }
39         );
40
41         return list;
42     },
43
44     'editor_init' : function(type, mode, params) {
45         var obj = this;
46         try {
47             $('serial_manage_subs_editor_deck').selectedIndex = obj.editor_indexes[type];
48
49             if (type == "siss") { // begin transition from xul to dojo editors
50                 var iframe = dojo.byId('alt_siss_editor');
51                 var src;
52                 if (mode == "add") {
53                     src = '/eg/serial/edit_siss/new/' + params.sisses[0].subscription();
54                     iframe.refresh_command = function () {obj.refresh_list();};
55                 } else {
56                     src = '/eg/serial/edit_siss/' + params.siss_ids[0];
57                     iframe.refresh_command = function () { /* TODO: redraw tree node */ };
58                 }
59                 iframe.setAttribute("src", src);
60             } else {
61                 var editor_type = type + '_editor';
62                 if (typeof obj[editor_type] == 'undefined') {
63                     JSAN.use('serial.' + editor_type);
64                     obj[editor_type] = new serial[editor_type]();
65                 }
66
67                 params.do_edit = true;
68                 params.handle_update = true;
69                 params.trigger_refresh = true;
70                 if (mode == 'add') {
71                     params.refresh_command = function () {obj.refresh_list();};
72                 } else {
73                     params.refresh_command = function () {obj.remap_node(type, this);};
74                 }
75
76                 obj[editor_type].init(params);
77             }
78         } catch(E) {
79             obj.error.standard_unexpected_error_alert('editor_init() error',E);
80         }
81     },
82
83     'do_delete' : function(type, method, overridable_events) {
84         var obj = this;
85         try {
86             JSAN.use('util.functional');
87
88             var list = util.functional.filter_list(
89                 obj.sel_list,
90                 function (o) {
91                     return o.split(/_/)[0] == type;
92                 }
93             );
94
95             list = util.functional.map_list(
96                 list,
97                 function (o) {
98                     return JSON2js( js2JSON( obj['map_' + type][ type + '_' + o.split(/_/)[1] ] ) );
99                 }
100             );
101
102             //TODO: proper messages
103             var delete_msg;
104             if (list.length != 1) {
105                 delete_msg = document.getElementById('serialStrings').getFormattedString('staff.serial.manage_subs.delete_' + type + '.confirm.plural', [list.length]);
106             } else {
107                 delete_msg = document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete_' + type + '.confirm');
108             }
109             var r = obj.error.yns_alert(
110                     delete_msg,
111                     document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete_' + type + '.title'),
112                     document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.delete'),
113                     document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.cancel'),
114                     null,
115                     document.getElementById('commonStrings').getString('common.confirm')
116             );
117
118             if (r == 0) {
119                 for (var i = 0; i < list.length; i++) {
120                     list[i].isdeleted('1');
121                 }
122                 var robj = obj.network.request(
123                     'open-ils.serial', 
124                     method, 
125                     [ ses(), list, true ],
126                     null,
127                     {
128                         'title' : document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete_' + type + '.override'),
129                         'overridable_events' : overridable_events
130                     }
131                 );
132                 if (robj == null) throw(robj);
133                 if (typeof robj.ilsevent != 'undefined') {
134                     if (robj.ilsevent != 0) {
135                         var overridable = false;
136                         for (i = 0; i < overridable_events.length; i++) {
137                             if (overridable_events[i] == robj.ilsevent) {
138                                 overridable = true;
139                                 break;
140                             }
141                         }
142                         if (!overridable) throw(robj);
143                     }
144                 }
145                 obj.refresh_list();
146             }
147         } catch(E) {
148             obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.delete.error'),E);
149             obj.refresh_list();
150         }
151     },
152
153     'init' : function( params ) {
154
155         try {
156             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
157             var obj = this;
158
159             obj.docid = params.docid;
160
161             JSAN.use('util.network'); obj.network = new util.network();
162             JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
163             JSAN.use('util.controller'); obj.controller = new util.controller();
164             obj.controller.init(
165                 {
166                     control_map : {
167                         'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
168                         'sel_clip' : [
169                             ['command'],
170                             function() { obj.list.clipboard(); }
171                         ],
172                         'cmd_broken' : [
173                             ['command'],
174                             function() { 
175                                 alert(document.getElementById('commonStrings').getString('common.unimplemented'));
176                             }
177                         ],
178                         'cmd_show_my_libs' : [
179                             ['command'],
180                             function() { 
181                                 obj.show_my_libs(); 
182                             }
183                         ],
184                         'cmd_show_all_libs' : [
185                             ['command'],
186                             function() {
187                                 obj.show_all_libs();
188                             }
189                         ],
190                         'cmd_show_libs_with_distributions' : [
191                             ['command'],
192                             function() {
193                                 obj.show_libs_with_distributions();
194                             }
195                         ],
196                         'cmd_clear' : [
197                             ['command'],
198                             function() {
199                                 obj.map_tree = {};
200                                 obj.list.clear();
201                             }
202                         ],
203                         'cmd_add_scap' : [
204                             ['command'],
205                             function() {
206                                 try {
207                                     var list = obj.ids_from_sel_list('ssub');
208                                     if (list.length == 0) list = obj.ids_from_sel_list('scap-group');
209                                     if (list.length == 0) return;
210
211                                     /*TODO: permission check?
212                                     //populate 'list' with owning_libs of subs, TODO
213                                     var edit = 0;
214                                     try {
215                                         edit = obj.network.request(
216                                             api.PERM_MULTI_ORG_CHECK.app,
217                                             api.PERM_MULTI_ORG_CHECK.method,
218                                             [ 
219                                                 ses(), 
220                                                 obj.data.list.au[0].id(), 
221                                                 list,
222                                                 [ 'CREATE_COPY' ]
223                                             ]
224                                         ).length == 0 ? 1 : 0;
225                                     } catch(E) {
226                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
227                                     }
228
229                                     if (edit==0) return; // no read-only view for this interface */
230                                     var new_scap = new scap();
231                                     new_scap.subscription(list[0]);//TODO: add multiple at once support?
232                                     new_scap.isnew(1);
233                                     var params = {};
234                                     params.scaps = [new_scap];
235                                     obj.editor_init('scap', 'add', params);
236                                 } catch(E) {
237                                     obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.add.error'),E);
238                                 }
239                             }
240                         ],
241                         'cmd_add_siss' : [
242                             ['command'],
243                             function() {
244                                 try {
245                                     var list = obj.ids_from_sel_list('ssub');
246                                     if (list.length == 0) list = obj.ids_from_sel_list('siss-group');
247                                     if (list.length == 0) return;
248
249                                     /*TODO: permission check?
250                                     //populate 'list' with owning_libs of subs, TODO
251                                     var edit = 0;
252                                     try {
253                                         edit = obj.network.request(
254                                             api.PERM_MULTI_ORG_CHECK.app,
255                                             api.PERM_MULTI_ORG_CHECK.method,
256                                             [ 
257                                                 ses(), 
258                                                 obj.data.list.au[0].id(), 
259                                                 list,
260                                                 [ 'CREATE_COPY' ]
261                                             ]
262                                         ).length == 0 ? 1 : 0;
263                                     } catch(E) {
264                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
265                                     }
266
267                                     if (edit==0) return; // no read-only view for this interface */
268                                     var new_siss = new siss();
269                                     new_siss.subscription(list[0]);//TODO: add multiple at once support?
270                                     new_siss.isnew(1);
271                                     var params = {};
272                                     params.sisses = [new_siss];
273                                     obj.editor_init('siss', 'add', params);
274                                 } catch(E) {
275                                     obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.add.error'),E);
276                                 }
277                             }
278                         ],
279                         'cmd_add_sdist' : [
280                             ['command'],
281                             function() {
282                                 try {
283                                     var list = obj.ids_from_sel_list('ssub');
284                                     if (list.length == 0) list = obj.ids_from_sel_list('sdist-group');
285                                     if (list.length == 0) return;
286
287                                     /*TODO: permission check?
288                                     //populate 'list' with owning_libs of subs, TODO
289                                     var edit = 0;
290                                     try {
291                                         edit = obj.network.request(
292                                             api.PERM_MULTI_ORG_CHECK.app,
293                                             api.PERM_MULTI_ORG_CHECK.method,
294                                             [ 
295                                                 ses(), 
296                                                 obj.data.list.au[0].id(), 
297                                                 list,
298                                                 [ 'CREATE_COPY' ]
299                                             ]
300                                         ).length == 0 ? 1 : 0;
301                                     } catch(E) {
302                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
303                                     }
304
305                                     if (edit==0) return; // no read-only view for this interface */
306                                     var new_sdist = new sdist();
307                                     new_sdist.subscription(list[0]);//TODO: add multiple at once support?
308                                     new_sdist.holding_lib(obj.map_ssub['ssub_' + list[0]].owning_lib());//default to sub owning lib
309                                     new_sdist.label($('serialStrings').getString('serial.common.default'));
310                                     new_sdist.isnew(1);
311                                     var params = {};
312                                     params.sdists = [new_sdist];
313                                     obj.editor_init('sdist', 'add', params);
314                                 } catch(E) {
315                                     obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.add.error'),E);
316                                 }
317                             }
318                         ],
319                         'cmd_delete_scap' : [
320                             ['command'],
321                             function() {
322                                 var overridable_events = [
323                                     11001 // SERIAL_CAPTION_AND_PATTERN_HAS_ISSUANCES
324                                 ];
325                                 obj.do_delete('scap', 'open-ils.serial.caption_and_pattern.batch.update', overridable_events);
326                             }
327                         ],
328                         'cmd_delete_sdist' : [
329                             ['command'],
330                             function() {
331                                 var overridable_events = [ //TODO: proper overrides
332                                 ];
333                                 obj.do_delete('sdist', 'open-ils.serial.distribution.fleshed.batch.update', overridable_events);
334                             }
335                         ],
336                         'cmd_delete_siss' : [
337                             ['command'],
338                             function() {
339                                 var overridable_events = [ //TODO: proper overrides
340                                 ];
341                                 obj.do_delete('siss', 'open-ils.serial.issuance.fleshed.batch.update', overridable_events);
342                             }
343                         ],
344                         'cmd_delete_ssub' : [
345                             ['command'],
346                             function() {
347                                 var overridable_events = [
348                                     11000 // SERIAL_SUBSCRIPTION_NOT_EMPTY
349                                 ];
350                                 obj.do_delete('ssub', 'open-ils.serial.subscription.fleshed.batch.update', overridable_events);
351                             }
352                         ],
353                         /*dbw2 'cmd_delete_ssub' : [
354                             ['command'],
355                             function() {
356                                 try {
357                                     JSAN.use('util.functional');
358
359                                     var list = util.functional.filter_list(
360                                         obj.sel_list,
361                                         function (o) {
362                                             return o.split(/_/)[0] == 'ssub';
363                                         }
364                                     );
365
366                                     list = util.functional.map_list(
367                                         list,
368                                         function (o) {
369                                             return JSON2js( js2JSON( obj.map_ssub[ 'ssub_' + o.split(/_/)[1] ] ) );
370                                         }
371                                     );
372
373                                     var del_prompt;
374                                     if (list.length == 1) {
375                                         //TODO: correct prompts
376                                         del_prompt = document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.prompt');
377                                     } else {
378                                         del_prompt = document.getElementById('catStrings').getFormattedString('staff.cat.copy_browser.delete_volume.prompt.plural', [list.length]);
379                                     }
380
381                                     var r = obj.error.yns_alert(
382                                             del_prompt,
383                                             document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.title'),
384                                             document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.delete'),
385                                             document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.cancel'),
386                                             null,
387                                             document.getElementById('commonStrings').getString('common.confirm')
388                                     );
389
390                                     if (r == 0) {
391                                         for (var i = 0; i < list.length; i++) {
392                                             list[i].isdeleted('1');
393                                         }
394                                         var robj = obj.network.simple_request(
395                                             'FM_ACN_TREE_UPDATE', 
396                                             [ ses(), list, true ],
397                                             null,
398                                             {
399                                                 'title' : document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.override'),
400                                                 'overridable_events' : [
401                                                 ]
402                                             }
403                                         );
404                                         if (robj == null) throw(robj);
405                                         if (typeof robj.ilsevent != 'undefined') {
406                                             if (robj.ilsevent == 1206 ) { // VOLUME_NOT_EMPTY
407                                                 alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.copies_remain'));
408                                                 return;
409                                             }
410                                             if (robj.ilsevent != 0) throw(robj);
411                                         }
412                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.success'));
413                                         obj.refresh_list();
414                                     }
415                                 } catch(E) {
416                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_volume.exception'),E);
417                                     obj.refresh_list();
418                                 }
419
420                             }
421                         ], dbw2*/
422                         'cmd_mark_library' : [
423                             ['command'],
424                             function() {
425                                 try {
426                                     var list = obj.ids_from_sel_list('aou');
427                                     if (list.length == 1) {
428                                         obj.data.marked_library = { 'lib' : list[0], 'docid' : obj.docid };
429                                         obj.data.stash('marked_library');
430                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_library.alert'));
431                                     } else {
432                                         obj.error.yns_alert(
433                                                 document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_library.prompt'),
434                                                 document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_library.title'),
435                                                 document.getElementById('commonStrings').getString('common.ok'),
436                                                 null,
437                                                 null,
438                                                 document.getElementById('commonStrings').getString('common.confirm')
439                                                 );
440                                     }
441                                 } catch(E) {
442                                     obj.error.standard_unexpected_error_alert('manage_subs.js -> mark library',E);
443                                 }
444                             }
445                         ],
446
447                         'cmd_mark_subscription' : [
448                             ['command'],
449                             function() {
450                                 try {
451                                     var list = obj.ids_from_sel_list('ssub');
452                                     if (list.length == 1) {
453                                         obj.data.marked_subscription = list[0];
454                                         obj.data.stash('marked_subscription');
455                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_volume.alert'));
456                                     } else {
457                                         obj.error.yns_alert(
458                                                 document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_volume.prompt'),
459                                                 document.getElementById('catStrings').getString('staff.cat.copy_browser.mark_volume.title'),
460                                                 document.getElementById('commonStrings').getString('common.ok'),
461                                                 null,
462                                                 null,
463                                                 document.getElementById('commonStrings').getString('common.confirm')
464                                                 );
465                                     }
466                                 } catch(E) {
467                                     obj.error.standard_unexpected_error_alert('manage_subs.js -> mark subscription',E);
468                                 }
469                             }
470                         ],
471                         'cmd_add_subscriptions' : [
472                             ['command'],
473                             function() {
474                                 try {
475                                     var list = obj.ids_from_sel_list('aou');
476                                     if (list.length == 0) return;
477                                     //TODO: permission check?
478                                     /*var edit = 0;
479                                     try {
480                                         edit = obj.network.request(
481                                             api.PERM_MULTI_ORG_CHECK.app,
482                                             api.PERM_MULTI_ORG_CHECK.method,
483                                             [ 
484                                                 ses(), 
485                                                 obj.data.list.au[0].id(), 
486                                                 list,
487                                                 [ 'CREATE_VOLUME', 'CREATE_COPY' ]
488                                             ]
489                                         ).length == 0 ? 1 : 0;
490                                     } catch(E) {
491                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
492                                     }
493
494                                     if (edit==0) {
495                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.add_volume.permission_error'));
496                                         return; // no read-only view for this interface
497                                     } */
498                                     var new_ssub = new ssub();
499                                     new_ssub.owning_lib(list[0]);//TODO: add multiple at once support?
500                                     new_ssub.isnew(1);
501                                     new_ssub.record_entry(obj.docid);
502                                     var params = {};
503                                     params.ssubs = [new_ssub];
504                                     obj.editor_init('ssub', 'add', params);
505                                 } catch(E) {
506                                     obj.error.standard_unexpected_error_alert(document.getElementById('serialStrings').getString('staff.serial.manage_subs.add.error'),E);
507                                 }
508                             }
509                         ],
510                         'cmd_transfer_subscription' : [
511                             ['command'],
512                             function() {
513                                 try {
514                                     obj.data.stash_retrieve();
515                                     if (!obj.data.marked_library) {
516                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer_volume.alert'));
517                                         return;
518                                     }
519                                     
520                                     var list = obj.ids_from_sel_list('ssub');
521
522                                     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
523
524                                     JSAN.use('util.functional');
525
526                                     var ssub_list = util.functional.map_list(
527                                         list,
528                                         function (o) {
529                                             return obj.map_ssub[ 'ssub_' + o ].start_date();
530                                         }
531                                     ).join(document.getElementById('commonStrings').getString('common.grouping_string'));
532
533                                     var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto">';
534                                     xml += '<description>';
535                                     xml += document.getElementById('catStrings').getFormattedString('staff.cat.copy_browser.transfer.prompt', [ssub_list, obj.data.hash.aou[ obj.data.marked_library.lib ].shortname()]);
536                                     xml += '</description>';
537                                     xml += '<hbox><button label="' + document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.submit.label') + '" name="fancy_submit"/>';
538                                     xml += '<button label="' 
539                                         + document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.cancel.label') 
540                                         + '" accesskey="' 
541                                         + document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.cancel.accesskey') 
542                                         + '" name="fancy_cancel"/></hbox>';
543                                     xml += '<iframe style="overflow: scroll" flex="1" src="' + urls.XUL_BIB_BRIEF + '?docid=' + obj.data.marked_library.docid + '"/>';
544                                     xml += '</vbox>';
545                                     JSAN.use('OpenILS.data');
546                                     var data = new OpenILS.data(); data.init({'via':'stash'});
547                                     //data.temp_transfer = xml; data.stash('temp_transfer');
548                                     JSAN.use('util.window'); var win = new util.window();
549                                     var fancy_prompt_data = win.open(
550                                         urls.XUL_FANCY_PROMPT,
551                                         //+ '?xml_in_stash=temp_transfer'
552                                         //+ '&title=' + window.escape('Volume Transfer'),
553                                         'fancy_prompt', 'chrome,resizable,modal,width=500,height=300',
554                                         {
555                                             'xml' : xml,
556                                             'title' : document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.title')
557                                         }
558                                     );
559
560                                     if (fancy_prompt_data.fancy_status == 'incomplete') {
561                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.incomplete'));
562                                         return;
563                                     }
564
565                                     var robj = obj.network.simple_request(
566                                         'FM_ACN_TRANSFER', 
567                                         [ ses(), { 'docid' : obj.data.marked_library.docid, 'lib' : obj.data.marked_library.lib, 'subscriptions' : list } ],
568                                         null,
569                                         {
570                                             'title' : document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.override.failure'),
571                                             'overridable_events' : [
572                                                 1208, // TITLE_LAST_COPY
573                                                 1219, // COPY_REMOTE_CIRC_LIB
574                                             ],
575                                         }
576                                     );
577
578                                     if (typeof robj.ilsevent != 'undefined') {
579                                         if (robj.ilsevent == 1221) { // ORG_CANNOT_HAVE_VOLS
580                                             alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.ineligible_destination'));
581                                         } else {
582                                             throw(robj);
583                                         }
584                                     } else {
585                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.success'));
586                                     }
587
588                                 } catch(E) {
589                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer.unexpected_error'),E);
590                                 }
591                                 obj.refresh_list();
592                             }
593                         ],
594
595                         'cmd_transfer_sdists' : [
596                             ['command'],
597                             function() {
598                                 try {
599                                     obj.data.stash_retrieve();
600                                     if (!obj.data.marked_subscription) {
601                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer_items.missing_volume'));
602                                         return;
603                                     }
604                                     
605                                     JSAN.use('util.functional');
606
607                                     var list = obj.ids_from_sel_list('sdist');
608                                     var subscription = obj.network.simple_request('FM_ACN_RETRIEVE.authoritative',[ obj.data.marked_subscription ]);
609
610                                     JSAN.use('cat.util'); cat.util.transfer_copies( { 
611                                         'distribution_ids' : list, 
612                                         'docid' : subscription.record(),
613                                         'subscription_label' : subscription.start_date(),
614                                         'owning_lib' : subscription.owning_lib(),
615                                     } );
616
617                                 } catch(E) {
618                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.transfer_items.unexpected_error'),E);
619                                 }
620                                 obj.refresh_list();
621                             }
622                         ],
623                         'cmd_refresh_list' : [
624                             ['command'],
625                             function() {
626                                 obj.refresh_list();
627                             }
628                         ],
629                         'cmd_make_predictions' : [
630                             ['command'],
631                             function() {
632                                 try {
633                                     var list = obj.ids_from_sel_list('ssub');
634                                     if (list.length == 0) {
635                                         alert($('serialStrings').getString('serial.manage_subs.predict.alert')); //TODO: better error
636                                         return;
637                                     }
638
639                                     var num_to_predict = prompt($('serialStrings').getString('serial.manage_subs.predict.prompt'),
640                                             '12',
641                                             $('serialStrings').getString('serial.manage_subs.predict.prompt.text'));
642                                     num_to_predict = String( num_to_predict ).replace(/\D/g,'');
643                                     if (num_to_predict == '') {
644                                         alert($('serialStrings').getString('serial.manage_subs.invalid_number')); //TODO: better error
645                                         return;
646                                     }
647
648                                     for (i = 0; i < list.length; i++) {
649                                         var robj = obj.network.request(
650                                                 'open-ils.serial',
651                                                 'open-ils.serial.make_predictions',
652                                                 [ ses(), {"ssub_id":list[i], "num_to_predict":num_to_predict}]
653                                         );
654                                         alert($('serialStrings').getFormattedString('serial.manage_subs.predict_success', [robj.length, list[i]]));
655                                     }
656
657                                     obj.refresh_list();
658
659                                 } catch(E) {
660                                     obj.error.standard_unexpected_error_alert('cmd_make_predictions failed!',E);
661                                 }
662                             }
663                         ],
664 /*dbw2                      'sel_distribution_details' : [
665                             ['command'],
666                             function() {
667                                 JSAN.use('util.functional');
668
669                                 var list = util.functional.filter_list(
670                                     obj.sel_list,
671                                     function (o) {
672                                         return o.split(/_/)[0] == 'sdist';
673                                     }
674                                 );
675
676                                 list = util.functional.map_list(
677                                     list,
678                                     function (o) {
679                                         return o.split(/_/)[1];
680                                     }
681                                 );
682     
683                                 JSAN.use('circ.util');
684                                 for (var i = 0; i < list.length; i++) {
685                                     circ.util.show_copy_details( list[i] );
686                                 }
687                             }
688                         ],
689                         'cmd_edit_sdists' : [
690                             ['command'],
691                             function() {
692                                 try {
693                                     JSAN.use('util.functional');
694
695                                     var list = util.functional.filter_list(
696                                         obj.sel_list,
697                                         function (o) {
698                                             return o.split(/_/)[0] == 'sdist';
699                                         }
700                                     );
701
702                                     list = util.functional.map_list(
703                                         list,
704                                         function (o) {
705                                             return o.split(/_/)[1];
706                                         }
707                                     );
708
709                                     JSAN.use('cat.util'); cat.util.spawn_copy_editor( { 'copy_ids' : list, 'edit' : 1 } );
710                                     obj.refresh_list();
711
712                                 } catch(E) {
713                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_items.error'),E);
714                                 }
715                             }
716                         ], dbw2*/
717
718 /*dbw2                      'cmd_print_spine_labels' : [
719                             ['command'],
720                             function() {
721                                 try {
722                                     JSAN.use('util.functional');
723                                     
724                                     var list = util.functional.filter_list(
725                                         obj.sel_list,
726                                         function (o) {
727                                             return o.split(/_/)[0] == 'sdist';
728                                         }
729                                     );
730
731                                     list = util.functional.map_list(
732                                         list,
733                                         function (o) {
734                                             return obj.map_sdist[ o ];
735                                         }
736                                     );
737
738                                     obj.data.temp_barcodes_for_labels = util.functional.map_list( list, function(o){return o.barcode();}) ; 
739                                     obj.data.stash('temp_barcodes_for_labels');
740                                     xulG.new_tab(
741                                         xulG.url_prefix( urls.XUL_SPINE_LABEL ),
742                                         { 'tab_name' : document.getElementById('catStrings').getString('staff.cat.copy_browser.print_spine.tab') },
743                                         {}
744                                     );
745                                 } catch(E) {
746                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.print_spine.error'),E);
747                                 }
748                             }
749                         ],
750                         'cmd_edit_subscriptions' : [
751                             ['command'],
752                             function() {
753                                 try {
754                                     JSAN.use('util.functional');
755                                     var list = util.functional.map_list(
756                                         util.functional.filter_list(
757                                             obj.sel_list,
758                                             function (o) {
759                                                 return o.split(/_/)[0] == 'ssub';
760                                             }
761                                         ),
762                                         function (o) {
763                                             return o.split(/_/)[1];
764                                         }
765                                     );
766                                     if (list.length == 0) return;
767
768                                     var edit = 0;
769                                     try {
770                                         edit = obj.network.request(
771                                             api.PERM_MULTI_ORG_CHECK.app,
772                                             api.PERM_MULTI_ORG_CHECK.method,
773                                             [ 
774                                                 ses(), 
775                                                 obj.data.list.au[0].id(), 
776                                                 util.functional.map_list(
777                                                     list,
778                                                     function (o) {
779                                                         return obj.map_ssub[ 'ssub_' + o ].owning_lib();
780                                                     }
781                                                 ),
782                                                 [ 'UPDATE_VOLUME' ]
783                                             ]
784                                         ).length == 0 ? 1 : 0;
785                                     } catch(E) {
786                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
787                                     }
788
789                                     if (edit==0) {
790                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.permission_error'));
791                                         return; // no read-only view for this interface
792                                     }
793
794                                     list = util.functional.map_list(
795                                         list,
796                                         function (o) {
797                                             var my_ssub = obj.map_ssub['ssub_' + o];
798                                             return function(r){return r;}(my_ssub);
799                                         }
800                                     );
801
802                                     var title;
803                                     if (list.length == 1) {
804                                         title = document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.title');
805                                     } else {
806                                         title = document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.title.plural');
807                                     }
808
809                                     JSAN.use('util.window'); var win = new util.window();
810                                     //obj.data.volumes_temp = js2JSON( list );
811                                     //obj.data.stash('volumes_temp');
812                                     var my_xulG = win.open(
813                                         window.xulG.url_prefix(urls.XUL_VOLUME_EDITOR),
814                                         title,
815                                         'chrome,modal,resizable',
816                                         { 'subscriptions' : JSON2js(js2JSON(list)) }
817                                     );
818
819                                     // FIXME -- need to unique the temp space, and not rely on modalness of window
820                                     //obj.data.stash_retrieve();
821                                     if (typeof my_xulG.update_these_subscriptions == 'undefined') { return; }
822                                     var subscriptions = my_xulG.subscriptions;
823                                     if (!subscriptions) return;
824                                 
825                                     subscriptions = util.functional.filter_list(
826                                         subscriptions,
827                                         function (o) {
828                                             return o.ischanged() == '1';
829                                         }
830                                     );
831
832                                     subscriptions = util.functional.map_list(
833                                         subscriptions,
834                                         function (o) {
835                                             o.record( obj.docid ); // staff client 2 did not do this.  Does it matter?
836                                             return o;
837                                         }
838                                     );
839
840                                     if (subscriptions.length == 0) return;
841
842                                     try {
843                                         var r = obj.network.request(
844                                             api.FM_ACN_TREE_UPDATE.app,
845                                             api.FM_ACN_TREE_UPDATE.method,
846                                             [ ses(), subscriptions, true ]
847                                         );
848                                         if (typeof r.ilsevent != 'undefined') {
849                                             switch(Number(r.ilsevent)) {
850                                                 case 1705 : // VOLUME_LABEL_EXISTS
851                                                     alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.failed'));
852                                                     break;
853                                                 default: throw(r);
854                                             }
855                                         } else {
856                                             alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.success'));
857                                         }
858                                     } catch(E) {
859                                         obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.error'),E);
860                                     }
861                                     obj.refresh_list();
862
863                                 } catch(E) {
864                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.exception'),E);
865                                 }
866                             }
867                         ], dbw2*/
868                     }
869                 }
870             );
871
872             obj.list_init(params);
873
874             obj.org_ids = obj.network.simple_request('FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative',[ obj.docid ]);
875             if (typeof obj.org_ids.ilsevent != 'undefined') throw(obj.org_ids);
876             JSAN.use('util.functional'); 
877             obj.org_ids = util.functional.map_list( obj.org_ids, function (o) { return Number(o); });
878
879             var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
880             //obj.show_libs( org );
881
882             //obj.show_my_libs();
883
884             JSAN.use('util.file'); JSAN.use('util.widgets');
885
886             var file; var list_data; var ml; 
887
888             file = new util.file('offline_ou_list'); 
889             if (file._file.exists()) {
890                 list_data = file.get_object(); file.close();
891                 ml = util.widgets.make_menulist( list_data[0], list_data[1] );
892                 ml.setAttribute('id','lib_menu'); document.getElementById('serial_sub_lib_menu').appendChild(ml);
893                 //TODO: class this menu properly
894                 for (var i = 0; i < obj.org_ids.length; i++) {
895                     ml.getElementsByAttribute('value',obj.org_ids[i])[0].setAttribute('class','has_distributions');
896                 }
897                 ml.firstChild.addEventListener(
898                     'popupshown',
899                     function(ev) {
900                         document.getElementById('legend').setAttribute('hidden','false');
901                     },
902                     false
903                 );
904                 ml.firstChild.addEventListener(
905                     'popuphidden',
906                     function(ev) {
907                         document.getElementById('legend').setAttribute('hidden','true');
908                     },
909                     false
910                 );
911                 ml.addEventListener(
912                     'command',
913                     function(ev) {
914                         if (document.getElementById('refresh_button')) document.getElementById('refresh_button').focus(); 
915                         JSAN.use('util.file'); var file = new util.file('manage_subs_prefs.'+obj.data.server_unadorned);
916                         util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_ssubs' : [ 'checked' ], 'show_ssub_groups' : [ 'checked' ] });
917                         obj.refresh_list();
918                     },
919                     false
920                 );
921             } else {
922                 throw(document.getElementById('catStrings').getString('staff.cat.copy_browser.missing_library') + '\n');
923             }
924
925             file = new util.file('manage_subs_prefs.'+obj.data.server_unadorned);
926             util.widgets.load_attributes(file);
927             ml.value = ml.getAttribute('value');
928             if (! ml.value) {
929                 ml.value = org.id();
930                 ml.setAttribute('value',ml.value);
931             }
932
933             document.getElementById('show_ssubs').addEventListener(
934                 'command',
935                 function(ev) {
936                     JSAN.use('util.file'); var file = new util.file('manage_subs_prefs.'+obj.data.server_unadorned);
937                     util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_ssubs' : [ 'checked' ], 'show_ssub_groups' : [ 'checked' ] });
938                 },
939                 false
940             );
941
942             document.getElementById('show_ssub_groups').addEventListener(
943                 'command',
944                 function(ev) {
945                     JSAN.use('util.file'); var file = new util.file('manage_subs_prefs.'+obj.data.server_unadorned);
946                     util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_ssubs' : [ 'checked' ], 'show_ssub_groups' : [ 'checked' ] });
947                 },
948                 false
949             );
950
951             obj.show_my_libs( ml.value );
952
953             JSAN.use('util.exec'); var exec = new util.exec(20); exec.timer(obj.funcs,100);
954
955             obj.toggle_actions(); // disable menus initially
956
957         } catch(E) {
958             this.error.standard_unexpected_error_alert('serial/manage_subs.init: ',E);
959         }
960     },
961
962     'show_my_libs' : function(org) {
963         var obj = this;
964         try {
965             if (!org) {
966                 org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
967             } else {
968                 if (typeof org != 'object') org = obj.data.hash.aou[ org ];
969             }
970             obj.show_libs( org, false );
971         
972             var p_org = obj.data.hash.aou[ org.parent_ou() ];
973             if (p_org) {
974                 obj.funcs.push( function() { 
975                     document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
976                     document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
977                     document.getElementById('lib_menu').setAttribute('disabled','true'); 
978                 } );
979                 for (var i = 0; i < p_org.children().length; i++) {
980                     obj.funcs.push(
981                         function(o) {
982                             return function() {
983                                 obj.show_libs( o, false );
984                             }
985                         }( p_org.children()[i] )
986                     );
987                 }
988                 obj.funcs.push( function() { 
989                     document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
990                     document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
991                     document.getElementById('lib_menu').setAttribute('disabled','false'); 
992                 } );
993             }
994         } catch(E) {
995             alert(E);
996         }
997     },
998
999     'show_all_libs' : function() {
1000         var obj = this;
1001         try {
1002             obj.show_my_libs();
1003
1004             obj.show_libs( obj.data.tree.aou );
1005
1006             obj.funcs.push( function() { 
1007                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1008                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1009                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1010             } );
1011
1012             for (var i = 0; i < obj.data.tree.aou.children().length; i++) {
1013                 obj.funcs.push(
1014                     function(o) {
1015                         return function() {
1016                             obj.show_libs( o );
1017                         }
1018                     }( obj.data.tree.aou.children()[i] )
1019                 );
1020             }
1021             obj.funcs.push( function() { 
1022                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1023                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1024                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1025             } );
1026
1027         } catch(E) {
1028             alert(E);
1029         }
1030     },
1031
1032     'show_libs_with_distributions' : function() {
1033         var obj = this;
1034         try {
1035             JSAN.use('util.functional');
1036
1037             var orgs = util.functional.map_list(
1038                 obj.org_ids,
1039                 function(id) { return obj.data.hash.aou[id]; }
1040             ).sort(
1041                 function( a, b ) {
1042                     if (a.shortname() < b.shortname()) return -1;
1043                     if (a.shortname() > b.shortname()) return 1;
1044                     return 0;
1045                 }
1046             );
1047             obj.funcs.push( function() { 
1048                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1049                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1050                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1051             } );
1052
1053             for (var i = 0; i < orgs.length; i++) {
1054                 obj.funcs.push(
1055                     function(o) {
1056                         return function() {
1057                             obj.show_libs(o,false);
1058                         }
1059                     }( orgs[i] )
1060                 );
1061             }
1062             obj.funcs.push( function() { 
1063                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1064                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1065                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1066             } );
1067
1068         } catch(E) {
1069             alert(E);
1070         }
1071     },
1072
1073     'show_libs' : function(start_aou,show_open) {
1074         var obj = this;
1075         try {
1076             if (!start_aou) throw('show_libs: Need a start_aou');
1077             JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
1078             JSAN.use('util.functional'); 
1079
1080             var parents = [];
1081             var temp_aou = start_aou;
1082             while ( temp_aou.parent_ou() ) {
1083                 temp_aou = obj.data.hash.aou[ temp_aou.parent_ou() ];
1084                 parents.push( temp_aou );
1085             }
1086             parents.reverse();
1087
1088             for (var i = 0; i < parents.length; i++) {
1089                 obj.funcs.push(
1090                     function(o,p) {
1091                         return function() { 
1092                             obj.append_org(o,p,{'container':'true','open':'true'}); 
1093                         };
1094                     }(parents[i], obj.data.hash.aou[ parents[i].parent_ou() ])
1095                 );
1096             }
1097
1098             obj.funcs.push(
1099                 function(o,p) {
1100                     return function() { obj.append_org(o,p); };
1101                 }(start_aou,obj.data.hash.aou[ start_aou.parent_ou() ])
1102             );
1103
1104             obj.funcs.push(
1105                 function() {
1106                     if (start_aou.children()) {
1107                         var x = obj.map_tree[ 'aou_' + start_aou.id() ];
1108                         x.setAttribute('container','true');
1109                         if (show_open) x.setAttribute('open','true');
1110                         for (var i = 0; i < start_aou.children().length; i++) {
1111                             obj.funcs.push(
1112                                 function(o,p) {
1113                                     return function() { obj.append_org(o,p); };
1114                                 }( start_aou.children()[i], start_aou )
1115                             );
1116                         }
1117                     }
1118                 }
1119             );
1120
1121         } catch(E) {
1122             alert(E);
1123         }
1124     },
1125
1126     'on_select' : function(list,twisty) {
1127         var obj = this;
1128         var sel_lists = {};
1129
1130         for (var i = 0; i < list.length; i++) {
1131             var row_type = list[i].split('_')[0];
1132             var id = list[i].split('_')[1];
1133
1134             if (!sel_lists[row_type]) sel_lists[row_type] = [];
1135             sel_lists[row_type].push(id);
1136
1137             switch(row_type) {
1138                 case 'aou' : obj.on_click_aou(id,twisty); break;
1139                 case 'ssub' : obj.on_select_ssub(id,twisty); break;
1140                 default: break;
1141             }
1142         }
1143
1144         if (!obj.focused_node_retrieve_id) return;
1145
1146         var row_type = obj.focused_node_retrieve_id.split('_')[0];
1147         var id = obj.focused_node_retrieve_id.split('_')[1];
1148
1149         if (sel_lists[row_type]) { // the type focused is in the selection (usually the case)
1150             switch(row_type) {
1151                 case 'aou' : obj.on_click_aou(id,twisty); break;
1152                 default: if (obj['on_click_' + row_type]) obj['on_click_' + row_type](sel_lists[row_type],twisty);
1153             }
1154         }
1155     },
1156
1157     'on_select_ssub' : function(ssub_id,twisty) {
1158         var obj = this;
1159         try {
1160             //typo? var ssub_tree = obj.map_sdist[ 'ssub_' + ssub_id ];
1161             var ssub_tree = obj.map_ssub[ 'ssub_' + ssub_id ];
1162             obj.funcs.push( function() { 
1163                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1164                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1165                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1166             } );
1167             if (ssub_tree.distributions()) {
1168                 for (var i = 0; i < ssub_tree.distributions().length; i++) {
1169                     obj.funcs.push(
1170                         function(c,a) {
1171                             return function() {
1172                                 obj.append_member(c,a,[],'sdist');
1173                             }
1174                         }( ssub_tree.distributions()[i], ssub_tree )
1175                     )
1176                 }
1177             }
1178             if (ssub_tree.issuances()) {
1179                 for (var i = 0; i < ssub_tree.issuances().length; i++) {
1180                     obj.funcs.push(
1181                         function(c,a) {
1182                             return function() {
1183                                 obj.append_member(c,a,[],'siss');
1184                             }
1185                         }( ssub_tree.issuances()[i], ssub_tree )
1186                     )
1187                 }
1188             }
1189             if (ssub_tree.scaps()) {
1190                 for (var i = 0; i < ssub_tree.scaps().length; i++) {
1191                     obj.funcs.push(
1192                         function(c,a) {
1193                             return function() {
1194                                 obj.append_member(c,a,[],'scap');
1195                             }
1196                         }( ssub_tree.scaps()[i], ssub_tree )
1197                     )
1198                 }
1199             }
1200             obj.funcs.push( function() { 
1201                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1202                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1203                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1204             } );
1205         } catch(E) {
1206             alert(E);
1207         }
1208     },
1209
1210     'on_click_ssub' : function(ssub_ids,twisty) {
1211         var obj = this;
1212         try {
1213             // draw sdist editor
1214             if (typeof twisty == 'undefined') {
1215                 var params = {};
1216                 params.ssub_ids = ssub_ids;
1217                 obj.editor_init('ssub', 'edit', params);
1218             }
1219         } catch(E) {
1220             alert(E);
1221         }
1222     },
1223
1224     'on_click_sdist' : function(sdist_ids,twisty) {
1225         var obj = this;
1226         try {
1227             // draw sdist editor
1228             if (typeof twisty == 'undefined') {
1229                 var params = {};
1230                 params.sdist_ids = sdist_ids;
1231                 obj.editor_init('sdist', 'edit', params);
1232             }
1233         } catch(E) {
1234             alert(E);
1235         }
1236     },
1237
1238     'on_click_siss' : function(siss_ids,twisty) {
1239         var obj = this;
1240         try {
1241             // draw siss editor
1242             if (typeof twisty == 'undefined') {
1243                 var params = {};
1244                 params.siss_ids = siss_ids;
1245                 obj.editor_init('siss', 'edit', params);
1246             }
1247         } catch(E) {
1248             alert(E);
1249         }
1250     },
1251
1252     'on_click_scap' : function(scap_ids,twisty) {
1253         var obj = this;
1254         try {
1255             // draw scap editor
1256             if (typeof twisty == 'undefined') {
1257                 var params = {};
1258                 params.scap_ids = scap_ids;
1259                 obj.editor_init('scap', 'edit', params);
1260             }
1261         } catch(E) {
1262             alert(E);
1263         }
1264     },
1265
1266     'on_click_aou' : function(org_id,twisty) {
1267         var obj = this;
1268         var org = obj.data.hash.aou[ org_id ];
1269         obj.funcs.push( function() { 
1270             document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1271             document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1272             document.getElementById('lib_menu').setAttribute('disabled','true'); 
1273         } );
1274         if (org.children()) {
1275             for (var i = 0; i < org.children().length; i++) {
1276                 obj.funcs.push(
1277                     function(o,p) {
1278                         return function() {
1279                             obj.append_org(o,p)
1280                         }
1281                     }(org.children()[i],org)
1282                 );
1283             }
1284         } 
1285         if (obj.map_ssub[ 'aou_' + org_id ]) {
1286             for (var i = 0; i < obj.map_ssub[ 'aou_' + org_id ].length; i++) {
1287                 obj.funcs.push(
1288                     function(o,a) {
1289                         return function() {
1290                             obj.append_ssub(o,a);
1291                         }
1292                     }( org, obj.map_ssub[ 'aou_' + org_id ][i] )
1293                 );
1294             }
1295         }
1296         obj.funcs.push( function() { 
1297             document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1298             document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1299             document.getElementById('lib_menu').setAttribute('disabled','false'); 
1300         } );
1301
1302         // remove current editor
1303         if (typeof twisty == 'undefined') {
1304             document.getElementById('serial_manage_subs_editor_deck').selectedIndex = 0;
1305         }
1306     },
1307
1308     'append_org' : function (org,parent_org,params) {
1309         var obj = this;
1310         try {
1311             if (obj.map_tree[ 'aou_' + org.id() ]) {
1312                 var x = obj.map_tree[ 'aou_' + org.id() ];
1313                 if (params) {
1314                     for (var i in params) {
1315                         x.setAttribute(i,params[i]);
1316                     }
1317                 }
1318                 return x;
1319             }
1320
1321             var data = {
1322                 'row' : {
1323                     'my' : {
1324                         'aou' : org,
1325                     }
1326                 },
1327                 'skip_all_columns_except' : [0,1,2],
1328                 'retrieve_id' : 'aou_' + org.id(),
1329                 'to_bottom' : true,
1330                 'no_auto_select' : true,
1331             };
1332         
1333             var ssub_tree_list;
1334             if ( obj.org_ids.indexOf( Number( org.id() ) ) == -1 ) {
1335                 if ( get_bool( obj.data.hash.aout[ org.ou_type() ].can_have_vols() ) ) {
1336                     data.row.my.subscription_count = '0';
1337                     //data.row.my.distribution_count = '<0>';
1338                 } else {
1339                     data.row.my.subscription_count = '';
1340                     //data.row.my.distribution_count = '';
1341                 }
1342             } else {
1343                 var v_count = 0; var d_count = 0;
1344                 ssub_tree_list = obj.network.simple_request(
1345                     'FM_SSUB_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS.authoritative',
1346                     [ ses(), obj.docid, [ org.id() ] ]
1347                 );
1348                 for (var i = 0; i < ssub_tree_list.length; i++) {
1349                     v_count++;
1350                     obj.map_ssub[ 'ssub_' + ssub_tree_list[i].id() ] = function(r){return r;}(ssub_tree_list[i]);
1351                     var distributions = ssub_tree_list[i].distributions();
1352                     //if (distributions) d_count += distributions.length;
1353                     for (var j = 0; j < distributions.length; j++) {
1354                         obj.map_sdist[ 'sdist_' + distributions[j].id() ] = function(r){return r;}(distributions[j]);
1355                     }
1356                     var issuances = ssub_tree_list[i].issuances();
1357                     for (var j = 0; j < issuances.length; j++) {
1358                         obj.map_siss[ 'siss_' + issuances[j].id() ] = function(r){return r;}(issuances[j]);
1359                     }
1360                     var scaps = ssub_tree_list[i].scaps();
1361                     for (var j = 0; j < scaps.length; j++) {
1362                         obj.map_scap[ 'scap_' + scaps[j].id() ] = function(r){return r;}(scaps[j]);
1363                     }
1364                 }
1365                 data.row.my.subscription_count = v_count;
1366                 //data.row.my.distribution_count = '<' + d_count + '>';
1367             }
1368             if (parent_org) {
1369                 data.node = obj.map_tree[ 'aou_' + parent_org.id() ];
1370             }
1371             var nparams = obj.list.append(data);
1372             var node = nparams.treeitem_node;
1373             if (params) {
1374                 for (var i in params) {
1375                     node.setAttribute(i,params[i]);
1376                 }
1377             }
1378             obj.map_tree[ 'aou_' + org.id() ] = node;
1379
1380             if (org.children()) {
1381                 node.setAttribute('container','true');
1382             }
1383
1384             if (parent_org) {
1385                 if ( obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ].parent_ou() == parent_org.id() ) {
1386                     data.node.setAttribute('open','true');
1387                 }
1388             } else {
1389                 obj.map_tree[ 'aou_' + org.id() ].setAttribute('open','true');
1390             }
1391
1392             if (ssub_tree_list) {
1393                 obj.map_ssub[ 'aou_' + org.id() ] = ssub_tree_list;
1394                 node.setAttribute('container','true');
1395             }
1396
1397             if (document.getElementById('show_ssubs').checked) {
1398                 obj.funcs.push( function() { obj.on_click_aou( org.id() ); } );
1399                 node.setAttribute('open','true');
1400             }
1401
1402         } catch(E) {
1403             dump(E+'\n');
1404             alert(E);
1405         }
1406     },
1407
1408     'append_ssub' : function( org, ssub_tree, params ) {
1409         var obj = this;
1410         try {
1411             if (obj.map_tree[ 'ssub_' + ssub_tree.id() ]) {
1412                 var x = obj.map_tree[ 'ssub_' + ssub_tree.id() ];
1413                 if (params) {
1414                     for (var i in params) {
1415                         x.setAttribute(i,params[i]);
1416                     }
1417                 }
1418                 return x;
1419             }
1420
1421             var parent_node = obj.map_tree[ 'aou_' + org.id() ];
1422             var data = {
1423                 'row' : {
1424                     'my' : {
1425                         'aou' : org,
1426                         'ssub' : ssub_tree,
1427                         'subscription_count' : '',
1428                         //'distribution_count' : ssub_tree.distributions() ? ssub_tree.distributions().length : '0',
1429                     }
1430                 },
1431                 'skip_all_columns_except' : [0,1,2],
1432                 'retrieve_id' : 'ssub_' + ssub_tree.id(),
1433                 'node' : parent_node,
1434                 'to_bottom' : true,
1435                 'no_auto_select' : true,
1436             };
1437             var nparams = obj.list.append(data);
1438             var node = nparams.treeitem_node;
1439             obj.map_tree[ 'ssub_' + ssub_tree.id() ] =  node;
1440             if (params) {
1441                 for (var i in params) {
1442                     node.setAttribute(i,params[i]);
1443                 }
1444             }
1445             if (ssub_tree.distributions() || ssub_tree.scaps() || ssub_tree.issuances()) {
1446                 //did this support a later typo? obj.map_sdist[ 'ssub_' + ssub_tree.id() ] = ssub_tree;
1447                 node.setAttribute('container','true');
1448             }
1449             if (document.getElementById('show_ssub_groups').checked) {
1450                 node.setAttribute('open','true');
1451                 obj.funcs.push( function() { obj.on_select_ssub( ssub_tree.id(), true ); } );
1452             }
1453             var sdist_group_node_data = {
1454                 'row' : {
1455                     'my' : {
1456                         'label' : $('serialStrings').getString('serial.manage_subs.distributions'),
1457                     }
1458                 },
1459                 'retrieve_id' : 'sdist-group_' + ssub_tree.id(),
1460                 'node' : node,
1461                 'to_bottom' : true,
1462                 'no_auto_select' : true,
1463             };
1464             nparams = obj.list.append(sdist_group_node_data);
1465             obj.map_tree[ 'ssub_sdist_group_' + ssub_tree.id() ] =  nparams.treeitem_node;
1466
1467             var siss_group_node_data = {
1468                 'row' : {
1469                     'my' : {
1470                         'label' : $('serialStrings').getString('serial.manage_subs.issuances'),
1471                     }
1472                 },
1473                 'retrieve_id' : 'siss-group_' + ssub_tree.id(),
1474                 'node' : node,
1475                 'to_bottom' : true,
1476                 'no_auto_select' : true,
1477             };
1478             nparams = obj.list.append(siss_group_node_data);
1479             obj.map_tree[ 'ssub_siss_group_' + ssub_tree.id() ] =  nparams.treeitem_node;
1480
1481             var scap_group_node_data = {
1482                 'row' : {
1483                     'my' : {
1484                         'label' : $('serialStrings').getString('serial.manage_subs.captions_patterns'),
1485                     }
1486                 },
1487                 'retrieve_id' : 'scap-group_' + ssub_tree.id(),
1488                 'node' : node,
1489                 'to_bottom' : true,
1490                 'no_auto_select' : true,
1491             };
1492             nparams = obj.list.append(scap_group_node_data);
1493             obj.map_tree[ 'ssub_scap_group_' + ssub_tree.id() ] =  nparams.treeitem_node;
1494         } catch(E) {
1495             dump(E+'\n');
1496             alert(E);
1497         }
1498     },
1499
1500     'append_member' : function( item, ssub_tree, attributes, type ) {
1501         var obj = this;
1502         try {
1503             if (obj.map_tree[ type + '_' + item.id() ]) {
1504                 var x = obj.map_tree[ type + '_' + item.id() ];
1505                 if (attributes) {
1506                     for (var i in attributes) {
1507                         x.setAttribute(i,attributes[i]);
1508                     }
1509                 }
1510                 return x;
1511             }
1512
1513             var parent_node = obj.map_tree[ 'ssub_' + type + '_group_' + ssub_tree.id() ];
1514             var data = {
1515                 'row' : {
1516                     'my' : {
1517                         'aou' : obj.data.hash.aou[ ssub_tree.owning_lib() ],
1518                         'ssub' : ssub_tree,
1519                         'subscription_count' : '',
1520                         //'distribution_count' : '',
1521                     }
1522                 },
1523                 'retrieve_id' : type + '_' + item.id(),
1524                 'node' : parent_node,
1525                 'to_bottom' : true,
1526                 'no_auto_select' : true,
1527             };
1528             data['row']['my'][type] = item; // TODO: future optimization: get only the IDs of these leaves, then fetch the full row in 'retrieve_row'
1529             var nparams = obj.list.append(data);
1530             var node = nparams.treeitem_node;
1531             obj.map_tree[ type + '_' + item.id() ] =  node;
1532             if (attributes) {
1533                 for (var i in attributes) {
1534                     node.setAttribute(i,attributes[i]);
1535                 }
1536             }
1537
1538         } catch(E) {
1539             dump(E+'\n');
1540             alert(E);
1541         }
1542     },
1543
1544     'list_init' : function( params ) {
1545
1546         try {
1547             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
1548             var obj = this;
1549             
1550             JSAN.use('circ.util');
1551             var columns = [
1552                 {
1553                     'id' : 'tree_location',
1554                     'label' : $('serialStrings').getString('serial.manage_subs.tree_location'),
1555                     'flex' : 1, 'primary' : true, 'hidden' : false, 
1556                     'render' : function(my) { 
1557                         if (my.sdist) { return my.sdist.label(); }
1558                         if (my.siss) { return my.siss.label(); }
1559                         if (my.scap) { return $('serialStrings').getFormattedString('serial.manage_subs.scap_id', [my.scap.id()]); }
1560                         if (my.ssub) { return $('serialStrings').getFormattedString('serial.manage_subs.ssub_id', [my.ssub.id()]); }
1561                         if (my.aou) { return $('serialStrings').getFormattedString('serial.manage_dists.library_label', [my.aou.shortname(), my.aou.name()]); }
1562                         if (my.label) { return my.label; }
1563                         /* If all else fails... */
1564                         return "???"; 
1565                     },
1566                 },
1567                 {
1568                     'id' : 'subscription_count',
1569                     'label' : $('serialStrings').getString('serial.manage_subs.subscriptions'),
1570                     'flex' : 0, 'primary' : false, 'hidden' : false, 
1571                     'render' : function(my) { return my.subscription_count; },
1572                 },
1573                 /*{
1574                     'id' : 'distribution_count',
1575                     'label' : 'Members',
1576                     'flex' : 0,
1577                     'primary' : false, 'hidden' : false, 
1578                     'render' : function(my) { return my.distribution_count; },
1579                 },*/
1580             ];
1581             JSAN.use('util.list'); obj.list = new util.list('subs_tree');
1582             obj.list.init(
1583                 {
1584                     'no_auto_select' : true,
1585                     'columns' : columns,
1586                     'retrieve_row' : function(params) {
1587
1588                         var row = params.row;
1589                         obj.funcs.push(
1590                             function() {
1591
1592                                 if (typeof params.on_retrieve == 'function') {
1593                                     params.on_retrieve(row);
1594                                 }
1595
1596                             }
1597                         );
1598
1599                         return row;
1600                     },
1601                     'on_click' : function(ev) {
1602                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserRead');
1603                         var row = {}; var col = {}; var nobj = {};
1604                         obj.list.node.treeBoxObject.getCellAt(ev.clientX,ev.clientY,row,col,nobj); 
1605                         if ((row.value == -1)||(nobj.value != 'twisty')) { return; } // on_click runs for twistys only
1606
1607                         var node = obj.list.node.contentView.getItemAtIndex(row.value);
1608                         var list = [ node.getAttribute('retrieve_id') ];
1609                         if (typeof obj.on_select == 'function') {
1610                             obj.on_select(list,true);
1611                         }
1612                         if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
1613                             window.xulG.on_select(list);
1614                         }
1615                     },
1616                     'on_select' : function(ev) {
1617                         JSAN.use('util.functional');
1618                         
1619                         // get the actual node clicked to determine which editor to use
1620                         if (obj.list.node.view.selection.currentIndex > -1) {
1621                             var node = obj.list.node.contentView.getItemAtIndex(obj.list.node.view.selection.currentIndex);
1622                             obj.focused_node_retrieve_id = node.getAttribute('retrieve_id');
1623                         }
1624
1625                         var sel = obj.list.retrieve_selection();
1626                         obj.controller.view.sel_clip.disabled = sel.length < 1;
1627                         obj.sel_list = util.functional.map_list(
1628                             sel,
1629                             function(o) { return o.getAttribute('retrieve_id'); }
1630                         );
1631                         obj.toggle_actions();
1632                         if (typeof obj.on_select == 'function') {
1633                             obj.on_select(obj.sel_list);
1634                         }
1635                         if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
1636                             window.xulG.on_select(obj.sel_list);
1637                         }
1638                     },
1639                 }
1640             );
1641
1642             obj.controller.render();
1643
1644         } catch(E) {
1645             this.error.sdump('D_ERROR','serial/manage_subs.list_init: ' + E + '\n');
1646             alert(E);
1647         }
1648     },
1649
1650     'toggle_actions' : function() {
1651         var obj = this;
1652         try {
1653             var found_aou = false; var found_ssub = false; var found_sdist = false; var found_siss = false; var found_scap = false; var found_sdist_group = false; var found_siss_group = false; var found_scap_group = false;
1654             for (var i = 0; i < obj.sel_list.length; i++) {
1655                 var type = obj.sel_list[i].split(/_/)[0];
1656                 switch(type) {
1657                     case 'aou' : 
1658                         found_aou = true; 
1659                     break;
1660                     case 'ssub' : found_ssub = true; break;
1661                     case 'sdist' : found_sdist = true; break;
1662                     case 'siss' : found_siss = true; break;
1663                     case 'scap' : found_scap = true; break;
1664                     case 'sdist-group' : found_sdist_group = true; break;
1665                     case 'siss-group' : found_siss_group = true; break;
1666                     case 'scap-group' : found_scap_group = true; break;
1667                 }
1668             }
1669             obj.controller.view.cmd_add_sdist.setAttribute('disabled','true');
1670             obj.controller.view.cmd_add_siss.setAttribute('disabled','true');
1671             obj.controller.view.cmd_add_scap.setAttribute('disabled','true');
1672             obj.controller.view.cmd_make_predictions.setAttribute('disabled','true');
1673             obj.controller.view.cmd_delete_sdist.setAttribute('disabled','true');
1674             obj.controller.view.cmd_delete_siss.setAttribute('disabled','true');
1675             obj.controller.view.cmd_delete_scap.setAttribute('disabled','true');
1676             obj.controller.view.cmd_add_subscriptions.setAttribute('disabled','true');
1677             obj.controller.view.cmd_mark_library.setAttribute('disabled','true');
1678             obj.controller.view.cmd_delete_ssub.setAttribute('disabled','true');
1679             obj.controller.view.cmd_mark_subscription.setAttribute('disabled','true');
1680             obj.controller.view.cmd_transfer_subscription.setAttribute('disabled','true');
1681             obj.controller.view.cmd_transfer_sdists.setAttribute('disabled','true');
1682             if (found_aou) {
1683                 obj.controller.view.cmd_add_subscriptions.setAttribute('disabled','false');
1684                 obj.controller.view.cmd_mark_library.setAttribute('disabled','false');
1685             }
1686             if (found_ssub) {
1687                 obj.controller.view.cmd_delete_ssub.setAttribute('disabled','false');
1688                 obj.controller.view.cmd_mark_subscription.setAttribute('disabled','false');
1689                 obj.controller.view.cmd_add_sdist.setAttribute('disabled','false');
1690                 obj.controller.view.cmd_add_siss.setAttribute('disabled','false');
1691                 obj.controller.view.cmd_add_scap.setAttribute('disabled','false');
1692                 obj.controller.view.cmd_transfer_subscription.setAttribute('disabled','false');
1693                 obj.controller.view.cmd_make_predictions.setAttribute('disabled','false');
1694             }
1695             if (found_sdist_group) {
1696                 obj.controller.view.cmd_add_sdist.setAttribute('disabled','false');
1697             }
1698             if (found_siss_group) {
1699                 obj.controller.view.cmd_add_siss.setAttribute('disabled','false');
1700             }
1701             if (found_scap_group) {
1702                 obj.controller.view.cmd_add_scap.setAttribute('disabled','false');
1703             }
1704             if (found_sdist) {
1705                 obj.controller.view.cmd_delete_sdist.setAttribute('disabled','false');
1706                 obj.controller.view.cmd_transfer_sdists.setAttribute('disabled','false');
1707             }
1708             if (found_siss) {
1709                 obj.controller.view.cmd_delete_siss.setAttribute('disabled','false');
1710             }
1711             if (found_scap) {
1712                 obj.controller.view.cmd_delete_scap.setAttribute('disabled','false');
1713             }
1714         } catch(E) {
1715             obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.actions.error'),E);
1716         }
1717     },
1718
1719     'refresh_list' : function() { 
1720         try {
1721             var obj = this;
1722             obj.list.clear();
1723             obj.map_tree = {};
1724             obj.map_ssub = {};
1725             obj.map_sdist = {};
1726             obj.map_siss = {};
1727             obj.map_scap = {};
1728             obj.org_ids = obj.network.simple_request('FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative',[ obj.docid ]);
1729             if (typeof obj.org_ids.ilsevent != 'undefined') throw(obj.org_ids);
1730             JSAN.use('util.functional'); 
1731             obj.org_ids = util.functional.map_list( obj.org_ids, function (o) { return Number(o); });
1732             /*
1733             var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
1734             obj.show_libs( org );
1735             */
1736             obj.show_my_libs( document.getElementById('lib_menu').value );
1737         } catch(E) {
1738             this.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.refresh_list.error'),E);
1739         }
1740     },
1741 };
1742
1743 dump('exiting serial/manage_subs.js\n');