]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/serial/manage_subs.js
307cc49c43cf28ef06d9049e019853c27e12ee82
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / serial / manage_subs.js
1 dump('entering serial/manage_subs.js\n');
2 // vim:noet: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('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('You must select a subscription before predicting issuances.'); //TODO: better error
619                                         return;
620                                     }
621
622                                     var num_to_predict = prompt('How many items would you like to predict?',
623                                             '12',
624                                             'Number of Predicted Items');
625                                     num_to_predict = String( num_to_predict ).replace(/\D/g,'');
626                                     if (num_to_predict == '') {
627                                         alert('Invalid number entered!'); //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, "last_rec_date":"2010-07-07"}]
636                                         );
637                                         util.functional.map_list(
638                                             robj,
639                                             function(o) {
640                                                 alert('debug: ' + o.date_expected());
641                                             }
642                                         );
643                                     }
644                                     return;
645
646                                     /*JSAN.use('util.functional');
647                                     var list = util.functional.map_list(
648                                             robj,
649                                             function (o) {
650                                                 o.distribution(obj.sdist_id);
651                                                 return o;
652                                             }
653                                         );*/
654
655                                     var robj = obj.network.request(
656                                                 'open-ils.serial',
657                                                 'open-ils.serial.item.fleshed.batch.update',
658                                                 [ ses(), list ]
659                                             );
660
661                                     //obj.refresh_list('main');
662
663                                 } catch(E) {
664                                     obj.error.standard_unexpected_error_alert('cmd_make_predictions failed!',E);
665                                 }
666                             }
667                         ],
668 /*dbw2                      'sel_distribution_details' : [
669                             ['command'],
670                             function() {
671                                 JSAN.use('util.functional');
672
673                                 var list = util.functional.filter_list(
674                                     obj.sel_list,
675                                     function (o) {
676                                         return o.split(/_/)[0] == 'sdist';
677                                     }
678                                 );
679
680                                 list = util.functional.map_list(
681                                     list,
682                                     function (o) {
683                                         return o.split(/_/)[1];
684                                     }
685                                 );
686     
687                                 JSAN.use('circ.util');
688                                 for (var i = 0; i < list.length; i++) {
689                                     circ.util.show_copy_details( list[i] );
690                                 }
691                             }
692                         ],
693                         'cmd_edit_sdists' : [
694                             ['command'],
695                             function() {
696                                 try {
697                                     JSAN.use('util.functional');
698
699                                     var list = util.functional.filter_list(
700                                         obj.sel_list,
701                                         function (o) {
702                                             return o.split(/_/)[0] == 'sdist';
703                                         }
704                                     );
705
706                                     list = util.functional.map_list(
707                                         list,
708                                         function (o) {
709                                             return o.split(/_/)[1];
710                                         }
711                                     );
712
713                                     JSAN.use('cat.util'); cat.util.spawn_copy_editor( { 'copy_ids' : list, 'edit' : 1 } );
714                                     obj.refresh_list();
715
716                                 } catch(E) {
717                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_items.error'),E);
718                                 }
719                             }
720                         ], dbw2*/
721
722 /*dbw2                      'cmd_print_spine_labels' : [
723                             ['command'],
724                             function() {
725                                 try {
726                                     JSAN.use('util.functional');
727                                     
728                                     var list = util.functional.filter_list(
729                                         obj.sel_list,
730                                         function (o) {
731                                             return o.split(/_/)[0] == 'sdist';
732                                         }
733                                     );
734
735                                     list = util.functional.map_list(
736                                         list,
737                                         function (o) {
738                                             return obj.map_sdist[ o ];
739                                         }
740                                     );
741
742                                     obj.data.temp_barcodes_for_labels = util.functional.map_list( list, function(o){return o.barcode();}) ; 
743                                     obj.data.stash('temp_barcodes_for_labels');
744                                     xulG.new_tab(
745                                         xulG.url_prefix( urls.XUL_SPINE_LABEL ),
746                                         { 'tab_name' : document.getElementById('catStrings').getString('staff.cat.copy_browser.print_spine.tab') },
747                                         {}
748                                     );
749                                 } catch(E) {
750                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.print_spine.error'),E);
751                                 }
752                             }
753                         ],
754                         'cmd_edit_subscriptions' : [
755                             ['command'],
756                             function() {
757                                 try {
758                                     JSAN.use('util.functional');
759                                     var list = util.functional.map_list(
760                                         util.functional.filter_list(
761                                             obj.sel_list,
762                                             function (o) {
763                                                 return o.split(/_/)[0] == 'ssub';
764                                             }
765                                         ),
766                                         function (o) {
767                                             return o.split(/_/)[1];
768                                         }
769                                     );
770                                     if (list.length == 0) return;
771
772                                     var edit = 0;
773                                     try {
774                                         edit = obj.network.request(
775                                             api.PERM_MULTI_ORG_CHECK.app,
776                                             api.PERM_MULTI_ORG_CHECK.method,
777                                             [ 
778                                                 ses(), 
779                                                 obj.data.list.au[0].id(), 
780                                                 util.functional.map_list(
781                                                     list,
782                                                     function (o) {
783                                                         return obj.map_ssub[ 'ssub_' + o ].owning_lib();
784                                                     }
785                                                 ),
786                                                 [ 'UPDATE_VOLUME' ]
787                                             ]
788                                         ).length == 0 ? 1 : 0;
789                                     } catch(E) {
790                                         obj.error.sdump('D_ERROR','batch permission check: ' + E);
791                                     }
792
793                                     if (edit==0) {
794                                         alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.permission_error'));
795                                         return; // no read-only view for this interface
796                                     }
797
798                                     list = util.functional.map_list(
799                                         list,
800                                         function (o) {
801                                             var my_ssub = obj.map_ssub['ssub_' + o];
802                                             return function(r){return r;}(my_ssub);
803                                         }
804                                     );
805
806                                     var title;
807                                     if (list.length == 1) {
808                                         title = document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.title');
809                                     } else {
810                                         title = document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.title.plural');
811                                     }
812
813                                     JSAN.use('util.window'); var win = new util.window();
814                                     //obj.data.volumes_temp = js2JSON( list );
815                                     //obj.data.stash('volumes_temp');
816                                     var my_xulG = win.open(
817                                         window.xulG.url_prefix(urls.XUL_VOLUME_EDITOR),
818                                         title,
819                                         'chrome,modal,resizable',
820                                         { 'subscriptions' : JSON2js(js2JSON(list)) }
821                                     );
822
823                                     // FIXME -- need to unique the temp space, and not rely on modalness of window
824                                     //obj.data.stash_retrieve();
825                                     if (typeof my_xulG.update_these_subscriptions == 'undefined') { return; }
826                                     var subscriptions = my_xulG.subscriptions;
827                                     if (!subscriptions) return;
828                                 
829                                     subscriptions = util.functional.filter_list(
830                                         subscriptions,
831                                         function (o) {
832                                             return o.ischanged() == '1';
833                                         }
834                                     );
835
836                                     subscriptions = util.functional.map_list(
837                                         subscriptions,
838                                         function (o) {
839                                             o.record( obj.docid ); // staff client 2 did not do this.  Does it matter?
840                                             return o;
841                                         }
842                                     );
843
844                                     if (subscriptions.length == 0) return;
845
846                                     try {
847                                         var r = obj.network.request(
848                                             api.FM_ACN_TREE_UPDATE.app,
849                                             api.FM_ACN_TREE_UPDATE.method,
850                                             [ ses(), subscriptions, true ]
851                                         );
852                                         if (typeof r.ilsevent != 'undefined') {
853                                             switch(Number(r.ilsevent)) {
854                                                 case 1705 : // VOLUME_LABEL_EXISTS
855                                                     alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.failed'));
856                                                     break;
857                                                 default: throw(r);
858                                             }
859                                         } else {
860                                             alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.success'));
861                                         }
862                                     } catch(E) {
863                                         obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.error'),E);
864                                     }
865                                     obj.refresh_list();
866
867                                 } catch(E) {
868                                     obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_volume.exception'),E);
869                                 }
870                             }
871                         ], dbw2*/
872                     }
873                 }
874             );
875
876             obj.list_init(params);
877
878             obj.org_ids = obj.network.simple_request('FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative',[ obj.docid ]);
879             if (typeof obj.org_ids.ilsevent != 'undefined') throw(obj.org_ids);
880             JSAN.use('util.functional'); 
881             obj.org_ids = util.functional.map_list( obj.org_ids, function (o) { return Number(o); });
882
883             var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
884             //obj.show_libs( org );
885
886             //obj.show_my_libs();
887
888             JSAN.use('util.file'); JSAN.use('util.widgets');
889
890             var file; var list_data; var ml; 
891
892             file = new util.file('offline_ou_list'); 
893             if (file._file.exists()) {
894                 list_data = file.get_object(); file.close();
895                 ml = util.widgets.make_menulist( list_data[0], list_data[1] );
896                 ml.setAttribute('id','lib_menu'); document.getElementById('serial_sub_lib_menu').appendChild(ml);
897                 //TODO: class this menu properly
898                 for (var i = 0; i < obj.org_ids.length; i++) {
899                     ml.getElementsByAttribute('value',obj.org_ids[i])[0].setAttribute('class','has_distributions');
900                 }
901                 ml.firstChild.addEventListener(
902                     'popupshown',
903                     function(ev) {
904                         document.getElementById('legend').setAttribute('hidden','false');
905                     },
906                     false
907                 );
908                 ml.firstChild.addEventListener(
909                     'popuphidden',
910                     function(ev) {
911                         document.getElementById('legend').setAttribute('hidden','true');
912                     },
913                     false
914                 );
915                 ml.addEventListener(
916                     'command',
917                     function(ev) {
918                         if (document.getElementById('refresh_button')) document.getElementById('refresh_button').focus(); 
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_groups' : [ 'checked' ] });
921                         obj.refresh_list();
922                     },
923                     false
924                 );
925             } else {
926                 throw(document.getElementById('catStrings').getString('staff.cat.copy_browser.missing_library') + '\n');
927             }
928
929             file = new util.file('manage_subs_prefs.'+obj.data.server_unadorned);
930             util.widgets.load_attributes(file);
931             ml.value = ml.getAttribute('value');
932             if (! ml.value) {
933                 ml.value = org.id();
934                 ml.setAttribute('value',ml.value);
935             }
936
937             document.getElementById('show_ssubs').addEventListener(
938                 'command',
939                 function(ev) {
940                     JSAN.use('util.file'); var file = new util.file('manage_subs_prefs.'+obj.data.server_unadorned);
941                     util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_ssubs' : [ 'checked' ], 'show_groups' : [ 'checked' ] });
942                 },
943                 false
944             );
945
946             document.getElementById('show_groups').addEventListener(
947                 'command',
948                 function(ev) {
949                     JSAN.use('util.file'); var file = new util.file('manage_subs_prefs.'+obj.data.server_unadorned);
950                     util.widgets.save_attributes(file, { 'lib_menu' : [ 'value' ], 'show_ssubs' : [ 'checked' ], 'show_groups' : [ 'checked' ] });
951                 },
952                 false
953             );
954
955             obj.show_my_libs( ml.value );
956
957             JSAN.use('util.exec'); var exec = new util.exec(20); exec.timer(obj.funcs,100);
958
959             obj.toggle_actions(); // disable menus initially
960
961         } catch(E) {
962             this.error.standard_unexpected_error_alert('serial/manage_subs.init: ',E);
963         }
964     },
965
966     'show_my_libs' : function(org) {
967         var obj = this;
968         try {
969             if (!org) {
970                 org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
971             } else {
972                 if (typeof org != 'object') org = obj.data.hash.aou[ org ];
973             }
974             obj.show_libs( org, false );
975         
976             var p_org = obj.data.hash.aou[ org.parent_ou() ];
977             if (p_org) {
978                 obj.funcs.push( function() { 
979                     document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
980                     document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
981                     document.getElementById('lib_menu').setAttribute('disabled','true'); 
982                 } );
983                 for (var i = 0; i < p_org.children().length; i++) {
984                     obj.funcs.push(
985                         function(o) {
986                             return function() {
987                                 obj.show_libs( o, false );
988                             }
989                         }( p_org.children()[i] )
990                     );
991                 }
992                 obj.funcs.push( function() { 
993                     document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
994                     document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
995                     document.getElementById('lib_menu').setAttribute('disabled','false'); 
996                 } );
997             }
998         } catch(E) {
999             alert(E);
1000         }
1001     },
1002
1003     'show_all_libs' : function() {
1004         var obj = this;
1005         try {
1006             obj.show_my_libs();
1007
1008             obj.show_libs( obj.data.tree.aou );
1009
1010             obj.funcs.push( function() { 
1011                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1012                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1013                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1014             } );
1015
1016             for (var i = 0; i < obj.data.tree.aou.children().length; i++) {
1017                 obj.funcs.push(
1018                     function(o) {
1019                         return function() {
1020                             obj.show_libs( o );
1021                         }
1022                     }( obj.data.tree.aou.children()[i] )
1023                 );
1024             }
1025             obj.funcs.push( function() { 
1026                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1027                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1028                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1029             } );
1030
1031         } catch(E) {
1032             alert(E);
1033         }
1034     },
1035
1036     'show_libs_with_distributions' : function() {
1037         var obj = this;
1038         try {
1039             JSAN.use('util.functional');
1040
1041             var orgs = util.functional.map_list(
1042                 obj.org_ids,
1043                 function(id) { return obj.data.hash.aou[id]; }
1044             ).sort(
1045                 function( a, b ) {
1046                     if (a.shortname() < b.shortname()) return -1;
1047                     if (a.shortname() > b.shortname()) return 1;
1048                     return 0;
1049                 }
1050             );
1051             obj.funcs.push( function() { 
1052                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1053                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1054                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1055             } );
1056
1057             for (var i = 0; i < orgs.length; i++) {
1058                 obj.funcs.push(
1059                     function(o) {
1060                         return function() {
1061                             obj.show_libs(o,false);
1062                         }
1063                     }( orgs[i] )
1064                 );
1065             }
1066             obj.funcs.push( function() { 
1067                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1068                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1069                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1070             } );
1071
1072         } catch(E) {
1073             alert(E);
1074         }
1075     },
1076
1077     'show_libs' : function(start_aou,show_open) {
1078         var obj = this;
1079         try {
1080             if (!start_aou) throw('show_libs: Need a start_aou');
1081             JSAN.use('OpenILS.data'); obj.data = new OpenILS.data(); obj.data.init({'via':'stash'});
1082             JSAN.use('util.functional'); 
1083
1084             var parents = [];
1085             var temp_aou = start_aou;
1086             while ( temp_aou.parent_ou() ) {
1087                 temp_aou = obj.data.hash.aou[ temp_aou.parent_ou() ];
1088                 parents.push( temp_aou );
1089             }
1090             parents.reverse();
1091
1092             for (var i = 0; i < parents.length; i++) {
1093                 obj.funcs.push(
1094                     function(o,p) {
1095                         return function() { 
1096                             obj.append_org(o,p,{'container':'true','open':'true'}); 
1097                         };
1098                     }(parents[i], obj.data.hash.aou[ parents[i].parent_ou() ])
1099                 );
1100             }
1101
1102             obj.funcs.push(
1103                 function(o,p) {
1104                     return function() { obj.append_org(o,p); };
1105                 }(start_aou,obj.data.hash.aou[ start_aou.parent_ou() ])
1106             );
1107
1108             obj.funcs.push(
1109                 function() {
1110                     if (start_aou.children()) {
1111                         var x = obj.map_tree[ 'aou_' + start_aou.id() ];
1112                         x.setAttribute('container','true');
1113                         if (show_open) x.setAttribute('open','true');
1114                         for (var i = 0; i < start_aou.children().length; i++) {
1115                             obj.funcs.push(
1116                                 function(o,p) {
1117                                     return function() { obj.append_org(o,p); };
1118                                 }( start_aou.children()[i], start_aou )
1119                             );
1120                         }
1121                     }
1122                 }
1123             );
1124
1125         } catch(E) {
1126             alert(E);
1127         }
1128     },
1129
1130     'on_select' : function(list,twisty) {
1131         var obj = this;
1132         var sel_lists = {};
1133
1134         for (var i = 0; i < list.length; i++) {
1135             var row_type = list[i].split('_')[0];
1136             var id = list[i].split('_')[1];
1137
1138             if (!sel_lists[row_type]) sel_lists[row_type] = [];
1139             sel_lists[row_type].push(id);
1140
1141             if (twisty) {
1142                 switch(row_type) {
1143                     case 'aou' : obj.on_click_aou(id,twisty); break;
1144                     case 'ssub' : obj.on_select_ssub(id,twisty); break;
1145                     default: break;
1146                 }
1147             }
1148         }
1149
1150         if (!obj.focused_node_retrieve_id) return;
1151
1152         var row_type = obj.focused_node_retrieve_id.split('_')[0];
1153         var id = obj.focused_node_retrieve_id.split('_')[1];
1154
1155         if (sel_lists[row_type]) { // the type focused is in the selection (usually the case)
1156             switch(row_type) {
1157                 case 'aou' : obj.on_click_aou(id,twisty); break;
1158                 default: if (obj['on_click_' + row_type]) obj['on_click_' + row_type](sel_lists[row_type],twisty);
1159             }
1160         }
1161     },
1162
1163     'on_select_ssub' : function(ssub_id,twisty) {
1164         var obj = this;
1165         try {
1166             //typo? var ssub_tree = obj.map_sdist[ 'ssub_' + ssub_id ];
1167             var ssub_tree = obj.map_ssub[ 'ssub_' + ssub_id ];
1168             obj.funcs.push( function() { 
1169                 document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1170                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1171                 document.getElementById('lib_menu').setAttribute('disabled','true'); 
1172             } );
1173             if (ssub_tree.distributions()) {
1174                 for (var i = 0; i < ssub_tree.distributions().length; i++) {
1175                     obj.funcs.push(
1176                         function(c,a) {
1177                             return function() {
1178                                 obj.append_member(c,a,[],'sdist');
1179                             }
1180                         }( ssub_tree.distributions()[i], ssub_tree )
1181                     )
1182                 }
1183             }
1184             if (ssub_tree.issuances()) {
1185                 for (var i = 0; i < ssub_tree.issuances().length; i++) {
1186                     obj.funcs.push(
1187                         function(c,a) {
1188                             return function() {
1189                                 obj.append_member(c,a,[],'siss');
1190                             }
1191                         }( ssub_tree.issuances()[i], ssub_tree )
1192                     )
1193                 }
1194             }
1195             if (ssub_tree.scaps()) {
1196                 for (var i = 0; i < ssub_tree.scaps().length; i++) {
1197                     obj.funcs.push(
1198                         function(c,a) {
1199                             return function() {
1200                                 obj.append_member(c,a,[],'scap');
1201                             }
1202                         }( ssub_tree.scaps()[i], ssub_tree )
1203                     )
1204                 }
1205             }
1206             obj.funcs.push( function() { 
1207                 document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1208                 document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1209                 document.getElementById('lib_menu').setAttribute('disabled','false'); 
1210             } );
1211         } catch(E) {
1212             alert(E);
1213         }
1214     },
1215
1216     'on_click_ssub' : function(ssub_ids,twisty) {
1217         var obj = this;
1218         try {
1219             // draw sdist editor
1220             if (typeof twisty == 'undefined') {
1221                 var params = {};
1222                 params.ssub_ids = ssub_ids;
1223                 obj.editor_init('ssub', 'edit', params);
1224             }
1225         } catch(E) {
1226             alert(E);
1227         }
1228     },
1229
1230     'on_click_sdist' : function(sdist_ids,twisty) {
1231         var obj = this;
1232         try {
1233             // draw sdist editor
1234             if (typeof twisty == 'undefined') {
1235                 var params = {};
1236                 params.sdist_ids = sdist_ids;
1237                 obj.editor_init('sdist', 'edit', params);
1238             }
1239         } catch(E) {
1240             alert(E);
1241         }
1242     },
1243
1244     'on_click_siss' : function(siss_ids,twisty) {
1245         var obj = this;
1246         try {
1247             // draw siss editor
1248             if (typeof twisty == 'undefined') {
1249                 var params = {};
1250                 params.siss_ids = siss_ids;
1251                 obj.editor_init('siss', 'edit', params);
1252             }
1253         } catch(E) {
1254             alert(E);
1255         }
1256     },
1257
1258     'on_click_scap' : function(scap_ids,twisty) {
1259         var obj = this;
1260         try {
1261             // draw scap editor
1262             if (typeof twisty == 'undefined') {
1263                 var params = {};
1264                 params.scap_ids = scap_ids;
1265                 obj.editor_init('scap', 'edit', params);
1266             }
1267         } catch(E) {
1268             alert(E);
1269         }
1270     },
1271
1272     'on_click_aou' : function(org_id,twisty) {
1273         var obj = this;
1274         var org = obj.data.hash.aou[ org_id ];
1275         obj.funcs.push( function() { 
1276             document.getElementById('cmd_refresh_list').setAttribute('disabled','true'); 
1277             document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','true'); 
1278             document.getElementById('lib_menu').setAttribute('disabled','true'); 
1279         } );
1280         if (org.children()) {
1281             for (var i = 0; i < org.children().length; i++) {
1282                 obj.funcs.push(
1283                     function(o,p) {
1284                         return function() {
1285                             obj.append_org(o,p)
1286                         }
1287                     }(org.children()[i],org)
1288                 );
1289             }
1290         } 
1291         if (obj.map_ssub[ 'aou_' + org_id ]) {
1292             for (var i = 0; i < obj.map_ssub[ 'aou_' + org_id ].length; i++) {
1293                 obj.funcs.push(
1294                     function(o,a) {
1295                         return function() {
1296                             obj.append_ssub(o,a);
1297                         }
1298                     }( org, obj.map_ssub[ 'aou_' + org_id ][i] )
1299                 );
1300             }
1301         }
1302         obj.funcs.push( function() { 
1303             document.getElementById('cmd_refresh_list').setAttribute('disabled','false'); 
1304             document.getElementById('cmd_show_libs_with_distributions').setAttribute('disabled','false'); 
1305             document.getElementById('lib_menu').setAttribute('disabled','false'); 
1306         } );
1307
1308         // remove current editor
1309         if (typeof twisty == 'undefined') {
1310             document.getElementById('serial_manage_subs_editor_deck').selectedIndex = 0;
1311         }
1312     },
1313
1314     'append_org' : function (org,parent_org,params) {
1315         var obj = this;
1316         try {
1317             if (obj.map_tree[ 'aou_' + org.id() ]) {
1318                 var x = obj.map_tree[ 'aou_' + org.id() ];
1319                 if (params) {
1320                     for (var i in params) {
1321                         x.setAttribute(i,params[i]);
1322                     }
1323                 }
1324                 return x;
1325             }
1326
1327             var data = {
1328                 'row' : {
1329                     'my' : {
1330                         'aou' : org,
1331                     }
1332                 },
1333                 'skip_all_columns_except' : [0,1,2],
1334                 'retrieve_id' : 'aou_' + org.id(),
1335                 'to_bottom' : true,
1336                 'no_auto_select' : true,
1337             };
1338         
1339             var ssub_tree_list;
1340             if ( obj.org_ids.indexOf( Number( org.id() ) ) == -1 ) {
1341                 if ( get_bool( obj.data.hash.aout[ org.ou_type() ].can_have_vols() ) ) {
1342                     data.row.my.subscription_count = '0';
1343                     //data.row.my.distribution_count = '<0>';
1344                 } else {
1345                     data.row.my.subscription_count = '';
1346                     //data.row.my.distribution_count = '';
1347                 }
1348             } else {
1349                 var v_count = 0; var d_count = 0;
1350                 ssub_tree_list = obj.network.simple_request(
1351                     'FM_SSUB_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS.authoritative',
1352                     [ ses(), obj.docid, [ org.id() ] ]
1353                 );
1354                 for (var i = 0; i < ssub_tree_list.length; i++) {
1355                     v_count++;
1356                     obj.map_ssub[ 'ssub_' + ssub_tree_list[i].id() ] = function(r){return r;}(ssub_tree_list[i]);
1357                     var distributions = ssub_tree_list[i].distributions();
1358                     //if (distributions) d_count += distributions.length;
1359                     for (var j = 0; j < distributions.length; j++) {
1360                         obj.map_sdist[ 'sdist_' + distributions[j].id() ] = function(r){return r;}(distributions[j]);
1361                     }
1362                     var issuances = ssub_tree_list[i].issuances();
1363                     for (var j = 0; j < issuances.length; j++) {
1364                         obj.map_siss[ 'siss_' + issuances[j].id() ] = function(r){return r;}(issuances[j]);
1365                     }
1366                     var scaps = ssub_tree_list[i].scaps();
1367                     for (var j = 0; j < scaps.length; j++) {
1368                         obj.map_scap[ 'scap_' + scaps[j].id() ] = function(r){return r;}(scaps[j]);
1369                     }
1370                 }
1371                 data.row.my.subscription_count = v_count;
1372                 //data.row.my.distribution_count = '<' + d_count + '>';
1373             }
1374             if (parent_org) {
1375                 data.node = obj.map_tree[ 'aou_' + parent_org.id() ];
1376             }
1377             var nparams = obj.list.append(data);
1378             var node = nparams.my_node;
1379             if (params) {
1380                 for (var i in params) {
1381                     node.setAttribute(i,params[i]);
1382                 }
1383             }
1384             obj.map_tree[ 'aou_' + org.id() ] = node;
1385
1386             if (org.children()) {
1387                 node.setAttribute('container','true');
1388             }
1389
1390             if (parent_org) {
1391                 if ( obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ].parent_ou() == parent_org.id() ) {
1392                     data.node.setAttribute('open','true');
1393                 }
1394             } else {
1395                 obj.map_tree[ 'aou_' + org.id() ].setAttribute('open','true');
1396             }
1397
1398             if (ssub_tree_list) {
1399                 obj.map_ssub[ 'aou_' + org.id() ] = ssub_tree_list;
1400                 node.setAttribute('container','true');
1401             }
1402
1403             if (document.getElementById('show_ssubs').checked) {
1404                 obj.funcs.push( function() { obj.on_click_aou( org.id() ); } );
1405                 node.setAttribute('open','true');
1406             }
1407
1408         } catch(E) {
1409             dump(E+'\n');
1410             alert(E);
1411         }
1412     },
1413
1414     'append_ssub' : function( org, ssub_tree, params ) {
1415         var obj = this;
1416         try {
1417             if (obj.map_tree[ 'ssub_' + ssub_tree.id() ]) {
1418                 var x = obj.map_tree[ 'ssub_' + ssub_tree.id() ];
1419                 if (params) {
1420                     for (var i in params) {
1421                         x.setAttribute(i,params[i]);
1422                     }
1423                 }
1424                 return x;
1425             }
1426
1427             var parent_node = obj.map_tree[ 'aou_' + org.id() ];
1428             var data = {
1429                 'row' : {
1430                     'my' : {
1431                         'aou' : org,
1432                         'ssub' : ssub_tree,
1433                         'subscription_count' : '',
1434                         //'distribution_count' : ssub_tree.distributions() ? ssub_tree.distributions().length : '0',
1435                     }
1436                 },
1437                 'skip_all_columns_except' : [0,1,2],
1438                 'retrieve_id' : 'ssub_' + ssub_tree.id(),
1439                 'node' : parent_node,
1440                 'to_bottom' : true,
1441                 'no_auto_select' : true,
1442             };
1443             var nparams = obj.list.append(data);
1444             var node = nparams.my_node;
1445             obj.map_tree[ 'ssub_' + ssub_tree.id() ] =  node;
1446             if (params) {
1447                 for (var i in params) {
1448                     node.setAttribute(i,params[i]);
1449                 }
1450             }
1451             if (ssub_tree.distributions() || ssub_tree.scaps() || ssub_tree.issuances()) {
1452                 //did this support a later typo? obj.map_sdist[ 'ssub_' + ssub_tree.id() ] = ssub_tree;
1453                 node.setAttribute('container','true');
1454             }
1455             if (document.getElementById('show_groups').checked) {
1456                 node.setAttribute('open','true');
1457                 obj.funcs.push( function() { obj.on_select_ssub( ssub_tree.id(), true ); } );
1458             }
1459             var sdist_group_node_data = {
1460                 'row' : {
1461                     'my' : {
1462                         'label' : 'Distributions',
1463                     }
1464                 },
1465                 'retrieve_id' : 'sdist-group_' + ssub_tree.id(),
1466                 'node' : node,
1467                 'to_bottom' : true,
1468                 'no_auto_select' : true,
1469             };
1470             nparams = obj.list.append(sdist_group_node_data);
1471             obj.map_tree[ 'ssub_sdist_group_' + ssub_tree.id() ] =  nparams.my_node;
1472
1473             var siss_group_node_data = {
1474                 'row' : {
1475                     'my' : {
1476                         'label' : 'Issuances',
1477                     }
1478                 },
1479                 'retrieve_id' : 'siss-group_' + ssub_tree.id(),
1480                 'node' : node,
1481                 'to_bottom' : true,
1482                 'no_auto_select' : true,
1483             };
1484             nparams = obj.list.append(siss_group_node_data);
1485             obj.map_tree[ 'ssub_siss_group_' + ssub_tree.id() ] =  nparams.my_node;
1486
1487             var scap_group_node_data = {
1488                 'row' : {
1489                     'my' : {
1490                         'label' : 'Captions/Patterns',
1491                     }
1492                 },
1493                 'retrieve_id' : 'scap-group_' + ssub_tree.id(),
1494                 'node' : node,
1495                 'to_bottom' : true,
1496                 'no_auto_select' : true,
1497             };
1498             nparams = obj.list.append(scap_group_node_data);
1499             obj.map_tree[ 'ssub_scap_group_' + ssub_tree.id() ] =  nparams.my_node;
1500         } catch(E) {
1501             dump(E+'\n');
1502             alert(E);
1503         }
1504     },
1505
1506     'append_member' : function( item, ssub_tree, attributes, type ) {
1507         var obj = this;
1508         try {
1509             if (obj.map_tree[ type + '_' + item.id() ]) {
1510                 var x = obj.map_tree[ type + '_' + item.id() ];
1511                 if (attributes) {
1512                     for (var i in attributes) {
1513                         x.setAttribute(i,attributes[i]);
1514                     }
1515                 }
1516                 return x;
1517             }
1518
1519             var parent_node = obj.map_tree[ 'ssub_' + type + '_group_' + ssub_tree.id() ];
1520             var data = {
1521                 'row' : {
1522                     'my' : {
1523                         'aou' : obj.data.hash.aou[ ssub_tree.owning_lib() ],
1524                         'ssub' : ssub_tree,
1525                         'subscription_count' : '',
1526                         //'distribution_count' : '',
1527                     }
1528                 },
1529                 'retrieve_id' : type + '_' + item.id(),
1530                 'node' : parent_node,
1531                 'to_bottom' : true,
1532                 'no_auto_select' : true,
1533             };
1534             data['row']['my'][type] = item; // TODO: future optimization: get only the IDs of these leaves, then fetch the full row in 'retrieve_row'
1535             var nparams = obj.list.append(data);
1536             var node = nparams.my_node;
1537             obj.map_tree[ type + '_' + item.id() ] =  node;
1538             if (attributes) {
1539                 for (var i in attributes) {
1540                     node.setAttribute(i,attributes[i]);
1541                 }
1542             }
1543
1544         } catch(E) {
1545             dump(E+'\n');
1546             alert(E);
1547         }
1548     },
1549
1550     'list_init' : function( params ) {
1551
1552         try {
1553             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
1554             var obj = this;
1555             
1556             JSAN.use('circ.util');
1557             var columns = [
1558                 {
1559                     'id' : 'tree_location',
1560                     'label' : document.getElementById('catStrings').getString('staff.cat.copy_browser.list_init.tree_location'),
1561                     'flex' : 1, 'primary' : true, 'hidden' : false, 
1562                     'render' : function(my) { return my.sdist ? my.sdist.label() : my.siss ? my.siss.label() : my.scap ? 'C/P : #' + my.scap.id() : my.ssub ? 'Subscription : #' + my.ssub.id() : my.aou ? my.aou.shortname() + " : " + my.aou.name() : my.label ? my.label : "???"; },
1563                 },
1564                 {
1565                     'id' : 'subscription_count',
1566                     'label' : 'Subscriptions',
1567                     'flex' : 0, 'primary' : false, 'hidden' : false, 
1568                     'render' : function(my) { return my.subscription_count; },
1569                 },
1570                 /*{
1571                     'id' : 'distribution_count',
1572                     'label' : 'Members',
1573                     'flex' : 0,
1574                     'primary' : false, 'hidden' : false, 
1575                     'render' : function(my) { return my.distribution_count; },
1576                 },*/
1577             ];
1578             JSAN.use('util.list'); obj.list = new util.list('subs_tree');
1579             obj.list.init(
1580                 {
1581                     'no_auto_select' : true,
1582                     'columns' : columns,
1583                     'map_row_to_columns' : circ.util.std_map_row_to_columns(' '),
1584                     'retrieve_row' : function(params) {
1585
1586                         var row = params.row;
1587                         obj.funcs.push(
1588                             function() {
1589
1590                                 if (typeof params.on_retrieve == 'function') {
1591                                     params.on_retrieve(row);
1592                                 }
1593
1594                             }
1595                         );
1596
1597                         return row;
1598                     },
1599                     'on_click' : function(ev) {
1600                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserRead');
1601                         var row = {}; var col = {}; var nobj = {};
1602                         obj.list.node.treeBoxObject.getCellAt(ev.clientX,ev.clientY,row,col,nobj); 
1603                         if ((row.value == -1)||(nobj.value != 'twisty')) { return; } // on_click runs for twistys only
1604
1605                         var node = obj.list.node.contentView.getItemAtIndex(row.value);
1606                         var list = [ node.getAttribute('retrieve_id') ];
1607                         if (typeof obj.on_select == 'function') {
1608                             obj.on_select(list,true);
1609                         }
1610                         if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
1611                             window.xulG.on_select(list);
1612                         }
1613                     },
1614                     'on_select' : function(ev) {
1615                         JSAN.use('util.functional');
1616                         
1617                         // get the actual node clicked to determine which editor to use
1618                         if (obj.list.node.view.selection.currentIndex > -1) {
1619                             var node = obj.list.node.contentView.getItemAtIndex(obj.list.node.view.selection.currentIndex);
1620                             obj.focused_node_retrieve_id = node.getAttribute('retrieve_id');
1621                         }
1622
1623                         var sel = obj.list.retrieve_selection();
1624                         obj.controller.view.sel_clip.disabled = sel.length < 1;
1625                         obj.sel_list = util.functional.map_list(
1626                             sel,
1627                             function(o) { return o.getAttribute('retrieve_id'); }
1628                         );
1629                         obj.toggle_actions();
1630                         if (typeof obj.on_select == 'function') {
1631                             obj.on_select(obj.sel_list);
1632                         }
1633                         if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
1634                             window.xulG.on_select(obj.sel_list);
1635                         }
1636                     },
1637                 }
1638             );
1639
1640             obj.controller.render();
1641
1642         } catch(E) {
1643             this.error.sdump('D_ERROR','serial/manage_subs.list_init: ' + E + '\n');
1644             alert(E);
1645         }
1646     },
1647
1648     'toggle_actions' : function() {
1649         var obj = this;
1650         try {
1651             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;
1652             for (var i = 0; i < obj.sel_list.length; i++) {
1653                 var type = obj.sel_list[i].split(/_/)[0];
1654                 switch(type) {
1655                     case 'aou' : 
1656                         found_aou = true; 
1657                     break;
1658                     case 'ssub' : found_ssub = true; break;
1659                     case 'sdist' : found_sdist = true; break;
1660                     case 'siss' : found_siss = true; break;
1661                     case 'scap' : found_scap = true; break;
1662                     case 'sdist-group' : found_sdist_group = true; break;
1663                     case 'siss-group' : found_siss_group = true; break;
1664                     case 'scap-group' : found_scap_group = true; break;
1665                 }
1666             }
1667             obj.controller.view.cmd_add_sdist.setAttribute('disabled','true');
1668             obj.controller.view.cmd_add_siss.setAttribute('disabled','true');
1669             obj.controller.view.cmd_add_scap.setAttribute('disabled','true');
1670             obj.controller.view.cmd_make_predictions.setAttribute('disabled','true');
1671             obj.controller.view.cmd_delete_sdist.setAttribute('disabled','true');
1672             obj.controller.view.cmd_delete_siss.setAttribute('disabled','true');
1673             obj.controller.view.cmd_delete_scap.setAttribute('disabled','true');
1674             obj.controller.view.cmd_add_subscriptions.setAttribute('disabled','true');
1675             obj.controller.view.cmd_mark_library.setAttribute('disabled','true');
1676             obj.controller.view.cmd_delete_ssub.setAttribute('disabled','true');
1677             obj.controller.view.cmd_mark_subscription.setAttribute('disabled','true');
1678             obj.controller.view.cmd_transfer_subscription.setAttribute('disabled','true');
1679             obj.controller.view.cmd_transfer_sdists.setAttribute('disabled','true');
1680             if (found_aou) {
1681                 obj.controller.view.cmd_add_subscriptions.setAttribute('disabled','false');
1682                 obj.controller.view.cmd_mark_library.setAttribute('disabled','false');
1683             }
1684             if (found_ssub) {
1685                 obj.controller.view.cmd_delete_ssub.setAttribute('disabled','false');
1686                 obj.controller.view.cmd_mark_subscription.setAttribute('disabled','false');
1687                 obj.controller.view.cmd_add_sdist.setAttribute('disabled','false');
1688                 obj.controller.view.cmd_add_siss.setAttribute('disabled','false');
1689                 obj.controller.view.cmd_add_scap.setAttribute('disabled','false');
1690                 obj.controller.view.cmd_transfer_subscription.setAttribute('disabled','false');
1691                 obj.controller.view.cmd_make_predictions.setAttribute('disabled','false');
1692             }
1693             if (found_sdist_group) {
1694                 obj.controller.view.cmd_add_sdist.setAttribute('disabled','false');
1695             }
1696             if (found_siss_group) {
1697                 obj.controller.view.cmd_add_siss.setAttribute('disabled','false');
1698             }
1699             if (found_scap_group) {
1700                 obj.controller.view.cmd_add_scap.setAttribute('disabled','false');
1701             }
1702             if (found_sdist) {
1703                 obj.controller.view.cmd_delete_sdist.setAttribute('disabled','false');
1704                 obj.controller.view.cmd_transfer_sdists.setAttribute('disabled','false');
1705             }
1706             if (found_siss) {
1707                 obj.controller.view.cmd_delete_siss.setAttribute('disabled','false');
1708             }
1709             if (found_scap) {
1710                 obj.controller.view.cmd_delete_scap.setAttribute('disabled','false');
1711             }
1712         } catch(E) {
1713             obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.actions.error'),E);
1714         }
1715     },
1716
1717     'refresh_list' : function() { 
1718         try {
1719             var obj = this;
1720             obj.list.clear();
1721             obj.map_tree = {};
1722             obj.map_ssub = {};
1723             obj.map_sdist = {};
1724             obj.map_siss = {};
1725             obj.map_scap = {};
1726             obj.org_ids = obj.network.simple_request('FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative',[ obj.docid ]);
1727             if (typeof obj.org_ids.ilsevent != 'undefined') throw(obj.org_ids);
1728             JSAN.use('util.functional'); 
1729             obj.org_ids = util.functional.map_list( obj.org_ids, function (o) { return Number(o); });
1730             /*
1731             var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
1732             obj.show_libs( org );
1733             */
1734             obj.show_my_libs( document.getElementById('lib_menu').value );
1735         } catch(E) {
1736             this.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.refresh_list.error'),E);
1737         }
1738     },
1739 };
1740
1741 dump('exiting serial/manage_subs.js\n');