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