]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/serial/manage_items.js
Improve Firefox/XULRunner Support
[Evergreen.git] / Open-ILS / xul / staff_client / server / serial / manage_items.js
1 dump('entering manage_items.js\n');
2
3 function $(id) { return document.getElementById(id); }
4
5 if (typeof serial == 'undefined') serial = {};
6 serial.manage_items = function (params) {
7
8         JSAN.use('util.error'); this.error = new util.error();
9         JSAN.use('util.network'); this.network = new util.network();
10         JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
11
12     this.current_sunit_id = -1; //default to **AUTO**
13     this.mode = 'receive';
14
15 }
16
17 serial.manage_items.prototype = {
18
19         'list_sitem_map' : {},
20     'sdist_map' : {},
21     'ssub_map' : {},
22     'row_map' : {},
23
24     'retrieve_ssubs_and_sdists' : function () {
25                 var obj = this;
26
27         try {
28             obj.lib = $('serial_item_lib_menu').value;
29             var sdist_retrieve_params = {"+ssub":{"record_entry" : obj.docid}};
30             if (obj.mode == 'receive') {
31                 sdist_retrieve_params["+ssub"].owning_lib = obj.lib;
32             } else {
33                 sdist_retrieve_params.holding_lib = obj.lib;
34             }
35             var robj = obj.network.request(
36                 'open-ils.pcrud',
37                 'open-ils.pcrud.id_list.sdist',
38                 [ ses(), sdist_retrieve_params, {"join":"ssub"} ]
39             );
40             if (robj != null) {
41                 if (typeof robj.ilsevent != 'undefined') throw(robj);
42                 obj.sdist_ids = robj.length ? robj : [robj];
43                 // now get actual sdist and ssub objects
44                 robj = obj.network.simple_request(
45                     'FM_SDIST_FLESHED_BATCH_RETRIEVE.authoritative',
46                     [ obj.sdist_ids ]
47                 );
48                 if (robj != null) {
49                     if (typeof robj.ilsevent != 'undefined') throw(robj);
50                     robj = robj.length ? robj : [robj];
51                     for (var i = 0; i < robj.length; i++) {
52                         obj.sdist_map[robj[i].id()] = robj[i];
53                     }
54                 }
55                 robj = obj.network.request(
56                     'open-ils.pcrud',
57                     'open-ils.pcrud.id_list.ssub',
58                     [ ses(), {"+sdist" : {"id" : obj.sdist_ids}}, {"join":"sdist"} ]
59                 );
60                 var ssub_ids = robj.length ? robj : [robj];
61                 robj = obj.network.simple_request(
62                     'FM_SSUB_FLESHED_BATCH_RETRIEVE.authoritative',
63                     [ ssub_ids ]
64                 );
65                 if (robj != null) {
66                     if (typeof robj.ilsevent != 'undefined') throw(robj);
67                     robj = robj.length ? robj : [robj];
68                     for (var i = 0; i < robj.length; i++) {
69                         obj.ssub_map[robj[i].id()] = robj[i];
70                     }
71                 }
72             } else {
73                 obj.sdist_ids = [];
74             }
75
76         } catch(E) {
77             obj.error.standard_unexpected_error_alert('retrieve_ssubs_and_sdists failed!',E);
78         }
79     },
80
81     'build_menus' : function () {
82                 var obj = this;
83
84         // draw library drop-down
85         obj.org_ids = obj.network.simple_request('FM_SSUB_AOU_IDS_RETRIEVE_VIA_RECORD_ID.authoritative',[ obj.docid ]);
86         if (typeof obj.org_ids.ilsevent != 'undefined') throw(obj.org_ids);
87         JSAN.use('util.functional');
88         obj.org_ids = util.functional.map_list( obj.org_ids, function (o) { return Number(o); });
89
90         var org = obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ];
91
92         JSAN.use('util.file'); JSAN.use('util.widgets');
93
94         var file; var list_data; var ml;
95
96         file = new util.file('offline_ou_list');
97         if (file._file.exists()) {
98             list_data = file.get_object(); file.close();
99             for (var i = 0; i < list_data[0].length; i++) { // make sure all entries are enabled
100                     list_data[0][i][2] = false;
101             }
102             ml = util.widgets.make_menulist( list_data[0], list_data[1] );
103             ml.setAttribute('id','serial_item_lib_menu'); document.getElementById('serial_item_lib_menu_box').appendChild(ml);
104             //TODO: class this menu properly
105             for (var i = 0; i < obj.org_ids.length; i++) {
106                 ml.getElementsByAttribute('value',obj.org_ids[i])[0].setAttribute('class','has_distributions');
107             }
108             /*TODO: add/enable this legend?
109             ml.firstChild.addEventListener(
110                 'popupshown',
111                 function(ev) {
112                     document.getElementById('legend').setAttribute('hidden','false');
113                 },
114                 false
115             );
116             ml.firstChild.addEventListener(
117                 'popuphidden',
118                 function(ev) {
119                     document.getElementById('legend').setAttribute('hidden','true');
120                 },
121                 false
122             );*/
123             ml.addEventListener(
124                 'command',
125                 function(ev) {
126                     //if (document.getElementById('serial_item_refresh_button')) document.getElementById('serial_item_refresh_button').focus();
127                     obj.save_settings();
128                     // get latest sdist id list based on library drowdown
129                     obj.retrieve_ssubs_and_sdists();
130                     obj.refresh_list('main');
131                     obj.refresh_list('workarea');
132                 },
133                 false
134             );
135
136         } else {
137             throw(document.getElementById('catStrings').getString('staff.cat.copy_browser.missing_library') + '\n');
138         }
139         file = new util.file('serial_items_prefs.'+obj.data.server_unadorned);
140         util.widgets.load_attributes(file);
141         ml.value = ml.getAttribute('value');
142         if (! ml.value) {
143             ml.value = org.id();
144             ml.setAttribute('value',ml.value);
145         }
146         
147         // deal with mode radio selectedIndex, as load_attributes is setting a "read-only" value
148         if ($('mode_receive').getAttribute('selected')) {
149             $('serial_manage_items_mode').selectedIndex = 0;
150         } else if ($('mode_advanced_receive').getAttribute('selected')) {
151             $('serial_manage_items_mode').selectedIndex = 1;
152         } else {
153             $('serial_manage_items_mode').selectedIndex = 2;
154         }
155
156         // setup recent sunits list
157         var recent_sunits_file = new util.file('serial_items_recent_sunits_'+obj.docid+'.'+obj.data.server_unadorned);
158         util.widgets.load_attributes(recent_sunits_file);
159         var recent_sunits_popup = $('serial_items_recent_sunits');
160         obj.sunit_entries = JSON2js(recent_sunits_popup.getAttribute('sunit_json'));
161         for (i = 0; i < obj.sunit_entries.length; i++) {
162             var sunit_info = obj.sunit_entries[i];
163             var new_menu_item = recent_sunits_popup.appendItem(sunit_info.label);
164             new_menu_item.setAttribute('id', 'serial_items_recent_sunits_entry_'+sunit_info.id);
165             new_menu_item.setAttribute('sunit_id', sunit_info.id);
166             new_menu_item.setAttribute('command', 'cmd_set_sunit');
167         }
168     },
169
170         'init' : function( params ) {
171                 var obj = this;
172
173                 obj.docid = params['docid'];
174
175         obj.build_menus();
176         obj.set_sunit($('serial_items_current_sunit').getAttribute('sunit_id'), $('serial_items_current_sunit').getAttribute('sunit_label'), $('serial_items_current_sunit').getAttribute('sdist_id'), $('serial_items_current_sunit').getAttribute('sstr_id'));
177         //obj.retrieve_ssubs_and_sdists();
178                 obj.init_lists();
179
180         var mode_radio_group = $('serial_manage_items_mode');
181         obj.set_mode(mode_radio_group.selectedItem.id.substr(5));
182         mode_radio_group.addEventListener(
183             'command',
184             function(ev) {
185                 obj.save_settings();
186                 var mode = ev.target.id.substr(5); //strip out 'mode_'
187                 obj.set_mode(mode);
188                 obj.refresh_list('main');
189                 obj.refresh_list('workarea');
190             },
191             false
192         );
193         $('serial_manage_items_show_all').addEventListener(
194             'command',
195             function(ev) {
196                 obj.save_settings();
197                 obj.set_mode();
198                 obj.refresh_list('main');
199                 obj.refresh_list('workarea');
200             },
201             false
202         );
203
204                 JSAN.use('util.controller'); obj.controller = new util.controller();
205                 obj.controller.init(
206                         {
207                                 'control_map' : {
208                                         'save_columns' : [ [ 'command' ], function() { obj.lists.main.save_columns(); } ],
209                                         'cmd_broken' : [ ['command'], function() { alert('Not Yet Implemented'); } ],
210                                         'sel_clip' : [ ['command'], function() { obj.lists.main.clipboard(); } ],
211                     'cmd_add_item' : [
212                         ['command'],
213                         function() {
214                             try {
215                                 var new_item = new sitem();
216                                 new_item.issuance(new siss());
217                                 new_item.stream(1); //FIXME: hard-coded stream
218                                 new_item.issuance().subscription(1); //FIXME: hard-coded subscription
219                                 new_item.isnew(1);
220                                 new_item.issuance().isnew(1);
221                                 spawn_sitem_editor( {'sitems' : [new_item], 'do_edit' : 1 } );
222
223                                 obj.refresh_list('main');
224
225                             } catch(E) {
226                                 obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_items.error'),E);
227                             }
228                         }
229                     ],
230                     'cmd_edit_items' : [
231                         ['command'],
232                         function() {
233                             try {
234                                 if (!obj.retrieve_ids || obj.retrieve_ids.length == 0) return;
235
236                                 JSAN.use('util.functional');
237                                 var list = util.functional.map_list(
238                                         obj.retrieve_ids,
239                                         function (o) {
240                                             return o.sitem_id;
241                                         }
242                                     );
243
244                                 spawn_sitem_editor( { 'sitem_ids' : list, 'do_edit' : 1 } );
245
246                                 obj.refresh_rows(list);
247
248                             } catch(E) {
249                                 obj.error.standard_unexpected_error_alert(document.getElementById('catStrings').getString('staff.cat.copy_browser.edit_items.error'),E);
250                             }
251                         }
252                     ],
253                     'cmd_reset_items' : [
254                         ['command'],
255                         function() {
256                             try {
257                                 if (!obj.retrieve_ids || obj.retrieve_ids.length == 0) return;
258
259                                 JSAN.use('util.functional');
260                                 var list = util.functional.map_list(
261                                         obj.retrieve_ids,
262                                         function (o) {
263                                             return o.sitem_id;
264                                         }
265                                     );
266
267                                 var robj = obj.network.request(
268                                             'open-ils.serial',
269                                             'open-ils.serial.reset_items',
270                                             [ ses(), list ]
271                                         );
272                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
273
274                                 alert('Successfully reset '+robj.num_items+' item(s)');
275
276                                 obj.refresh_list('main');
277                                 obj.refresh_list('workarea');
278                             } catch(E) {
279                                 obj.error.standard_unexpected_error_alert('staff.serial.manage_items.reset_items.error',E);
280                             }
281                         }
282                     ],
283                     'cmd_delete_items' : [
284                         ['command'],
285                         function() {
286                             try {
287                                 JSAN.use('util.functional');
288                                 var list = util.functional.map_list(
289                                         obj.retrieve_ids,
290                                         function (o) {
291                                             return obj.list_sitem_map[o.sitem_id];
292                                         }
293                                     );
294                                 var delete_msg;
295                                 if (list.length != 1) {
296                                     delete_msg = document.getElementById('catStrings').getFormattedString('staff.cat.copy_browser.delete_items.confirm.plural', [list.length]);
297                                 } else {
298                                     delete_msg = document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.confirm');
299                                 }
300                                 var r = obj.error.yns_alert(
301                                         delete_msg,
302                                         document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.title'),
303                                         document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.delete'),
304                                         document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.cancel'),
305                                         null,
306                                         document.getElementById('commonStrings').getString('common.confirm')
307                                 );
308
309                                 if (r == 0) {
310                                     for (var i = 0; i < list.length; i++) {
311                                         list[i].isdeleted('1');
312                                     }
313                                     var robj = obj.network.request(
314                                             'open-ils.serial',
315                                             'open-ils.serial.item.fleshed.batch.update',
316                                         [ ses(), list ],
317                                         null,
318                                         {
319                                             'title' : document.getElementById('catStrings').getString('staff.cat.copy_browser.delete_items.override'),
320                                             'overridable_events' : [ // FIXME: replace or delete these events
321                                                 1208 /* TITLE_LAST_COPY */,
322                                                 1227 /* COPY_DELETE_WARNING */,
323                                             ]
324                                         }
325                                     );
326                                     if (robj == null) throw(robj);
327                                     if (typeof robj.ilsevent != 'undefined') {
328                                         if ( (robj.ilsevent != 0) && (robj.ilsevent != 1227 /* COPY_DELETE_WARNING */) && (robj.ilsevent != 1208 /* TITLE_LAST_COPY */) ) throw(robj);
329                                     }
330                                     obj.refresh_list(obj.selected_list);
331                                 }
332
333
334                             } catch(E) {
335                                 obj.error.standard_unexpected_error_alert('staff.serial.manage_items.delete_items.error',E);
336                                 obj.refresh_list();
337                             }
338                         }
339                     ],
340                     'cmd_set_sunit' : [
341                         ['command'],
342                         function(evt) {
343                             try {
344                                 var target = evt.explicitOriginalTarget;
345                                 obj.process_unit_selection(target);
346                             } catch(E) {
347                                 obj.error.standard_unexpected_error_alert('cmd_set_sunit failed!',E);
348                             }
349                         }
350                     ],
351                     'cmd_set_other_sunit' : [
352                         ['command'],
353                         function() {
354                             obj.set_other_sunit();
355                             if (obj.mode == 'bind') {
356                                 obj.refresh_list('main');
357                                 obj.refresh_list('workarea');
358                             }
359                         }
360                     ],
361                     'cmd_predict_items' : [
362                         ['command'],
363                         function() {
364                             alert('Subscription selection needed here'); //FIXME: make this prompt, or discard this feature
365                         }
366                     ],
367                     'cmd_receive_items' : [
368                         ['command'],
369                         function() {
370                             try {
371                                 JSAN.use('util.functional');
372                                 var donor_unit_ids = {};
373                                 var list = util.functional.map_list(
374                                         obj.retrieve_ids,
375                                         function (o) {
376                                             var item = obj.list_sitem_map[o.sitem_id];
377                                             if (item.unit()) {
378                                                 donor_unit_ids[item.unit().id()] = 1;
379                                             }
380                                             item.unit(obj.current_sunit_id);
381                                             return item;
382                                         }
383                                     );
384
385                                 var mode = obj.mode;
386                                 if (mode == 'advanced_receive') mode = 'receive';
387
388                                 var method; var success_label;
389                                 if (mode == 'receive') {
390                                     method = 'open-ils.serial.receive_items';
391                                     success_label = 'received';
392                                 } else { // bind mode
393                                     method = 'open-ils.serial.bind_items';
394                                     success_label = 'bound';
395                                 } 
396
397                                 // deal with barcodes and call numbers for *NEW* units
398                                 var barcodes = {};
399                                 var call_numbers = {};
400                                 var call_numbers_by_siss_and_sdist = {};
401
402                                 if (obj.current_sunit_id < 0) { // **AUTO** or **NEW** units
403                                     var new_unit_barcode = '';
404                                     var new_unit_call_number = '';
405                                     for (var i = 0; i < list.length; i++) {
406                                         var item = list[i];
407                                         if (new_unit_barcode) {
408                                             barcodes[item.id()] = new_unit_barcode;
409                                             call_numbers[item.id()] = new_unit_call_number;
410                                             continue;
411                                         }
412                                         var prompt_text;
413                                         if (obj.current_sunit_id == -1) {
414                                             prompt_text = 'for '+item.issuance().label()+ ' from Distribution: '+obj.sdist_map[item.stream().distribution()].label()+'/'+item.stream().id()+':';
415                                         } else { // must be -2
416                                             prompt_text = 'for the new unit:';
417                                         }
418
419                                         // first barcodes
420                                         var barcode = window.prompt('Please enter a barcode ' + prompt_text,
421                                             '@@AUTO',
422                                             'Unit Barcode Prompt');
423                                         barcode = String( barcode ).replace(/\s/g,'');
424                                         /* Casting a possibly null input value to a String turns it into "null" */
425                                         if (!barcode || barcode == 'null') {
426                                             alert('Invalid barcode entered, defaulting to system-generated.');
427                                             barcode = '@@AUTO';
428                                         } else {
429                                             // disable alarm sound temporarily
430                                             var sound_setting = obj.data.no_sound;
431                                             if (!sound_setting) { // undefined or false
432                                                 obj.data.no_sound = true; obj.data.stash('no_sound');
433                                             }
434                                             var test = obj.network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[ barcode ]);
435                                             if (typeof test.ilsevent == 'undefined') {
436                                                 alert('Another copy has barcode "' + barcode + '", defaulting to system-generated.');
437                                                 barcode = '@@AUTO';
438                                             }
439                                             if (!sound_setting) {
440                                                 obj.data.no_sound = sound_setting; obj.data.stash('no_sound');
441                                             }
442                                         }
443                                         barcodes[item.id()] = barcode;
444
445                                         // now call numbers
446                                         if (typeof call_numbers_by_siss_and_sdist[item.issuance().id() + '@' + item.stream().distribution()] == 'undefined') {
447                                             var default_cn = 'DEFAULT';
448                                             // if they defined a *_call_number, honor it as the default
449                                             var preset_cn = obj.sdist_map[item.stream().distribution()][mode + '_call_number']();
450                                             if (preset_cn) {
451                                                 default_cn = preset_cn.label();
452                                             } else {
453                                                 // for now, let's default to the last created call number if there is one
454                                                 var acn_list = obj.network.request(
455                                                         'open-ils.pcrud',
456                                                         'open-ils.pcrud.search.acn',
457                                                         [ ses(), {"record" : obj.docid, "owning_lib" : obj.sdist_map[item.stream().distribution()].holding_lib().id(), "deleted" : 'f' }, {"order_by" : {"acn" : "create_date DESC"}, "limit" : "1" } ]
458                                                 );
459
460                                                 if (acn_list) {
461                                                     default_cn = acn_list.label();
462                                                 }
463                                             }
464                                             var call_number = window.prompt('Please enter/adjust a call number ' + prompt_text,
465                                                 default_cn, //TODO: real default by setting
466                                                 'Unit Call Number Prompt');
467                                             call_number = String( call_number ).replace(/^\s+/,'').replace(/\s$/,'');
468                                             /* Casting a possibly null input value to a String turns it into "null" */
469                                             if (!call_number || call_number == 'null') {
470                                                 alert('Invalid call number entered, setting to "DEFAULT".');
471                                                 call_number = 'DEFAULT'; //TODO: real default by setting
472                                             }
473                                             call_numbers[item.id()] = call_number;
474                                             call_numbers_by_siss_and_sdist[item.issuance().id() + '@' + item.stream().distribution()] = call_number;
475                                         } else {
476                                             // we have already seen this same issuance and distribution combo, so use the same call number
477                                             call_numbers[item.id()] = call_numbers_by_siss_and_sdist[item.issuance().id() + '@' + item.stream().distribution()];
478                                         }
479
480                                         if (obj.current_sunit_id == -2) {
481                                             new_unit_barcode = barcode;
482                                             new_unit_call_number = call_number;
483                                         }
484                                     }
485                                 }
486
487                                 var robj = obj.network.request(
488                                             'open-ils.serial',
489                                             method,
490                                             [ ses(), list, barcodes, call_numbers, donor_unit_ids ]
491                                         );
492                                 if (typeof robj.ilsevent != 'undefined') throw(robj); //TODO: catch for override
493
494                                 alert('Successfully '+success_label+' '+robj.num_items+' item(s)');
495
496                                 if (obj.current_sunit_id == -2) {
497                                     obj.current_sunit_id = robj.new_unit_id;
498                                 }
499
500                                 obj.rebuild_current_sunit(obj.sdist_map[list[0].stream().distribution()].label(), list[0].stream().distribution(), list[0].stream().id());
501                                 obj.refresh_list('main');
502                                 obj.refresh_list('workarea');
503                                 
504                             } catch(E) {
505                                 obj.error.standard_unexpected_error_alert('cmd_receive_items failed!',E);
506                             }
507                         }
508                     ],
509                     'cmd_edit_sunit' : [
510                         ['command'],
511                         function() {
512                             try {
513                                 /*if (!obj.retrieve_ids || obj.retrieve_ids.length == 0) return;
514
515                                 JSAN.use('util.functional');
516                                 var list = util.functional.map_list(
517                                         obj.retrieve_ids,
518                                         function (o) {
519                                             return o.sitem_id;
520                                         }
521                                     );
522 */
523                                 spawn_sunit_editor( { 'sunit_ids' : [1], 'edit' : 1 } ); //FIXME: hard-coded sunit
524
525                             } catch(E) {
526                                 obj.error.standard_unexpected_error_alert('cmd_edit_sunit failed!',E);
527                             }
528                         }
529                     ],
530                     'cmd_view_sitem_notes' : [
531                         ['command'],
532                         function() {
533                             try {
534                                 obj.view_notes('sitem');
535                             } catch(E) {
536                                 obj.error.standard_unexpected_error_alert('cmd_view_sitem_notes failed!',E);
537                             }
538                         }
539                     ],
540                     'cmd_view_sdist_notes' : [
541                         ['command'],
542                         function() {
543                             try {
544                                 obj.view_notes('sdist');
545                             } catch(E) {
546                                 obj.error.standard_unexpected_error_alert('cmd_view_sdist_notes failed!',E);
547                             }
548                         }
549                     ],
550                     'cmd_view_ssub_notes' : [
551                         ['command'],
552                         function() {
553                             try {
554                                 obj.view_notes('ssub');
555                             } catch(E) {
556                                 obj.error.standard_unexpected_error_alert('cmd_view_ssub_notes failed!',E);
557                             }
558                         }
559                     ],
560                     'cmd_items_print' : [ ['command'], function() { obj.items_print(obj.selected_list); } ],
561                                         'cmd_items_export' : [ ['command'], function() { obj.items_export(obj.selected_list); } ],
562                                         'cmd_refresh_list' : [ ['command'], function() { obj.retrieve_ssubs_and_sdists(); obj.refresh_list('main'); obj.refresh_list('workarea'); } ]
563                                 }
564                         }
565                 );
566         
567                 obj.retrieve('main'); // retrieve main list
568         obj.retrieve('workarea'); // retrieve shelving unit list
569
570                 obj.controller.view.sel_clip.setAttribute('disabled','true');
571
572         },
573
574         'items_print' : function(which) {
575                 var obj = this;
576                 try {
577                         var list = obj.lists[which];
578 /* FIXME: serial items print template?                  JSAN.use('patron.util');
579                         var params = { 
580                                 'patron' : patron.util.retrieve_fleshed_au_via_id(ses(),obj.patron_id), 
581                                 'template' : 'items_out'
582                         }; */
583                         list.print( params );
584                 } catch(E) {
585                         obj.error.standard_unexpected_error_alert('manage_items printing',E);
586                 }
587         },
588
589         'items_export' : function(which) {
590                 var obj = this;
591                 try {
592                         var list = obj.lists[which];
593                         list.dump_csv_to_clipboard();
594                 } catch(E) {
595                         obj.error.standard_unexpected_error_alert('manage_items export',E);
596                 }
597         },
598
599         'rebuild_current_sunit' : function(sdist_label, sdist_id, sstr_id) {
600                 var obj = this;
601         if (!obj.current_sunit_id) return; // current sunit is NONE
602                 try {
603             var robj = obj.network.request(
604                 'open-ils.pcrud',
605                 'open-ils.pcrud.retrieve.sunit',
606                 [ ses(),  obj.current_sunit_id]
607             );
608             if (!robj) return; // current sunit is NEW or AUTO
609
610             var label = '[' + sdist_label + '/' + sstr_id + ' #' + obj.current_sunit_id + '] ' + robj.summary_contents();
611             obj.set_sunit(obj.current_sunit_id, label, sdist_id, sstr_id);
612             obj.save_sunit(obj.current_sunit_id, label, sdist_id, sstr_id);
613                 } catch(E) {
614                         obj.error.standard_unexpected_error_alert('serial items set_sunit',E);
615                 }
616         },
617
618         'set_sunit' : function(sunit_id, label, sdist_id, sstr_id) {
619                 var obj = this;
620                 try {
621             obj.current_sunit_id = sunit_id;
622             obj.current_sunit_sdist_id = sdist_id;
623             obj.current_sunit_sstr_id = sstr_id;
624             if (sunit_id < 0  || sunit_id === '') {
625                 $('serial_workarea_sunit_desc').firstChild.nodeValue = '**' + label + '**';
626             } else {
627                 $('serial_workarea_sunit_desc').firstChild.nodeValue = label;
628                 obj.add_sunit_to_menu(sunit_id, label, sdist_id, sstr_id);
629             }
630                 } catch(E) {
631                         obj.error.standard_unexpected_error_alert('serial items set_sunit',E);
632                 }
633         },
634
635         'save_sunit' : function(sunit_id, label, sdist_id, sstr_id) {
636                 var obj = this;
637                 try {
638             $('serial_items_current_sunit').setAttribute('sunit_id', sunit_id);
639             $('serial_items_current_sunit').setAttribute('sunit_label', label);
640             if (sunit_id > 0) {
641                 $('serial_items_current_sunit').setAttribute('sdist_id', sdist_id);
642                 $('serial_items_current_sunit').setAttribute('sstr_id', sstr_id);
643             }
644             var recent_sunits_file = new util.file('serial_items_recent_sunits_'+obj.docid+'.'+obj.data.server_unadorned);
645             util.widgets.save_attributes(recent_sunits_file, { 'serial_items_recent_sunits' : [ 'sunit_json' ], 'serial_items_current_sunit' : [ 'sunit_id', 'sunit_label', 'sdist_id', 'sstr_id' ] });
646                 } catch(E) {
647                         obj.error.standard_unexpected_error_alert('serial items save_sunit',E);
648                 }
649         },
650
651         'set_other_sunit' : function() {
652                 var obj = this;
653                 try {
654             JSAN.use('util.window'); var win = new util.window();
655             var select_unit_window = win.open(
656                 xulG.url_prefix('XUL_SERIAL_SELECT_UNIT'),
657                 '_blank',
658                 'chrome,resizable,modal,centerscreen',
659                 {'sdist_ids' : obj.sdist_ids}
660             );
661             if (!select_unit_window.sunit_selection) {
662                 return;
663             }
664
665             var selection = select_unit_window.sunit_selection;
666             var sunit_id = selection.sunit;
667             var sdist_id = selection.sdist;
668             var sstr_id = selection.sstr;
669             var label = selection.label;
670
671             obj.set_sunit(sunit_id, label, sdist_id, sstr_id);
672             obj.save_sunit(sunit_id, label, sdist_id, sstr_id);
673                 } catch(E) {
674                         obj.error.standard_unexpected_error_alert('serial items set_other_sunit',E);
675                 }
676         },
677
678         'add_sunit_to_menu' : function(sunit_id, label, sdist_id, sstr_id) {
679                 var obj = this;
680                 try {
681             if (sunit_id > 0) {
682                 // check if it is already in sunit_entries, remove it
683                 for (i = 0; i < obj.sunit_entries.length; i++) {
684                     if (obj.sunit_entries[i].id == sunit_id) {
685                         obj.sunit_entries.splice(i,1);
686                         var menu_item = $('serial_items_recent_sunits_entry_'+sunit_id);
687                         menu_item.parentNode.removeChild(menu_item);
688                         i--;
689                     }
690                 }
691                 // add to front of array
692                 obj.sunit_entries.unshift({"id" : sunit_id, "label" : label, "sdist_id" : sdist_id, "sstr_id" : sstr_id});
693                 var recent_sunits_popup = $('serial_items_recent_sunits');
694                 var new_menu_item = recent_sunits_popup.insertItemAt(0,label);
695                 new_menu_item.setAttribute('id', 'serial_items_recent_sunits_entry_'+sunit_id);
696                 new_menu_item.setAttribute('sunit_id', sunit_id);
697                 new_menu_item.setAttribute('sdist_id', sdist_id);
698                 new_menu_item.setAttribute('sstr_id', sstr_id);
699                 new_menu_item.setAttribute('command', 'cmd_set_sunit');
700
701                 // pop off from sunit_entries if it already has 10 sunits
702                 if (obj.sunit_entries.length > 10) {
703                     var sunit_info = obj.sunit_entries.pop();
704                     var menu_item = $('serial_items_recent_sunits_entry_'+sunit_info.id);
705                     menu_item.parentNode.removeChild(menu_item);
706                 }
707
708                 recent_sunits_popup.setAttribute('sunit_json', js2JSON(obj.sunit_entries));
709             }
710                 } catch(E) {
711                         obj.error.standard_unexpected_error_alert('serial items add_sunit_to_menu',E);
712                 }
713         },
714
715         'set_mode' : function(mode) {
716                 var obj = this;
717
718         if (!mode) {
719             mode = obj.mode;
720         } else {
721             obj.mode = mode;
722         }
723
724         obj.retrieve_ssubs_and_sdists();
725
726         if (mode == 'receive' || mode == 'advanced_receive') {
727             $('serial_workarea_mode_label').value = 'Recently Received';
728             if ($('serial_manage_items_show_all').checked) {
729                 obj.lists.main.sitem_retrieve_params = {};
730             } else {
731                 obj.lists.main.sitem_retrieve_params = {'date_received' : null };
732             }
733             obj.lists.main.sitem_extra_params ={'order_by' : {'sitem' : 'date_expected ASC, stream ASC'}};
734
735             obj.lists.workarea.sitem_retrieve_params = {'date_received' : {"!=" : null}};
736             obj.lists.workarea.sitem_extra_params ={'order_by' : {'sitem' : 'date_received DESC'}, 'limit' : 30};
737             if (mode == 'receive') {
738                 $('serial_manage_items_context').value = $('serialStrings').getString('staff.serial.manage_items.subscriber.label') + ':';
739                 $('cmd_set_other_sunit').setAttribute('disabled','true');
740                 $('serial_items_recent_sunits').disabled = true;
741                 obj.process_unit_selection($('serial_items_auto_per_item_menuitem'));
742                 //obj.set_sunit(obj.current_sunit_id, label, sdist_id, sstr_id);
743             } else {
744                 $('serial_manage_items_context').value = $('serialStrings').getString('staff.serial.manage_items.holder.label') + ':';
745                 $('cmd_set_other_sunit').setAttribute('disabled','false');
746                 $('serial_items_recent_sunits').disabled = false;
747             }    
748         } else { // bind mode
749             $('serial_workarea_mode_label').value = 'Bound Items in Current Working Unit';
750             $('serial_manage_items_context').value = $('serialStrings').getString('staff.serial.manage_items.holder.label') + ':';
751             if ($('serial_manage_items_show_all').checked) {
752                 obj.lists.main.sitem_retrieve_params = {};
753             } else {
754                 obj.lists.main.sitem_retrieve_params = {'date_received' : {'!=' : null}}; // unit set dynamically in 'retrieve'
755             }
756             obj.lists.main.sitem_extra_params ={'order_by' : {'sitem' : 'date_expected ASC, stream ASC'}};
757
758             obj.lists.workarea.sitem_retrieve_params = {}; // unit set dynamically in 'retrieve'
759             obj.lists.workarea.sitem_extra_params ={'order_by' : {'sitem' : 'date_received DESC'}};
760
761             $('cmd_set_other_sunit').setAttribute('disabled','false');
762             $('serial_items_recent_sunits').disabled = false;
763             // default to **NEW UNIT**
764             // For now, keep the unit static.  TODO: Eventually, keep track of and store the last used unit value for both receive and bind separately
765             // obj.set_sunit(-2, 'New Unit', '', '');
766         }
767     },
768
769         'save_settings' : function() {
770                 var obj = this;
771
772         JSAN.use('util.file'); var file = new util.file('serial_items_prefs.'+obj.data.server_unadorned);
773         util.widgets.save_attributes(file, { 'serial_item_lib_menu' : [ 'value' ], 'mode_receive' : [ 'selected' ], 'mode_advanced_receive' : [ 'selected' ], 'mode_bind' : [ 'selected' ], 'serial_manage_items_show_all' : [ 'checked' ] });
774     },
775
776         'init_lists' : function() {
777                 var obj = this;
778
779                 JSAN.use('circ.util');
780         var columns = item_columns({});
781
782         function retrieve_row(params) {
783                         try { 
784                                 var row = params.row;
785                 obj.network.simple_request(
786                     'FM_SITEM_FLESHED_BATCH_RETRIEVE.authoritative',
787                     [[row.my.sitem_id]],
788                     //[ ses(), row.my.sitem_id, {"flesh":2,"flesh_fields":{"sitem":["creator","editor","issuance","stream","unit","notes"], "sunit":["call_number"], "sstr":["distribution"]}}],
789                     function(req) {
790                         try {
791                             var robj = req.getResultObject();
792                             if (typeof robj.ilsevent != 'undefined') throw(robj);
793                             if (typeof robj.ilsevent == 'null') throw('null result');
794                             var sitem = robj[0];
795                             obj.list_sitem_map[sitem.id()] = sitem;
796                             row.my.sitem = sitem;
797                             row.my.parent_obj = obj;
798                             //params.treeitem_node.setAttribute( 'retrieve_id', js2JSON({'copy_id':copy_id,'circ_id':row.my.circ.id(),'barcode':row.my.acp.barcode(),'doc_id': ( row.my.record ? row.my.record.id() : null ) }) );
799                             params.treeitem_node.setAttribute( 'retrieve_id', js2JSON({'sitem_id':sitem.id()}) );
800                             dump('dumping... ' + js2JSON(obj.list_sitem_map[sitem.id()]));
801                             if (typeof params.on_retrieve == 'function') {
802                                 params.on_retrieve(row);
803                             }
804
805                         } catch(E) {
806                             obj.error.standard_unexpected_error_alert('staff.serial.manage_items.retrieve_row.callback_error', E);
807                         }
808                     }
809                 );
810                                 return row;
811                         } catch(E) {
812                                 obj.error.standard_unexpected_error_alert('staff.serial.manage_items.retrieve_row.error_in_retrieve_row',E);
813                                 return params.row;
814                         }
815                 }
816
817                 JSAN.use('util.list');
818
819         obj.lists = {};
820         obj.lists.main = new util.list('item_tree');
821                 obj.lists.main.init(
822                         {
823                                 'columns' : columns,
824                                 'retrieve_row' : retrieve_row,
825                                 'on_select' : function(ev) {
826                     obj.selected_list = 'main';
827                                         JSAN.use('util.functional');
828                                         var sel = obj.lists.main.retrieve_selection();
829                                         obj.controller.view.sel_clip.setAttribute('disabled',sel.length < 1);
830                                         var list = util.functional.map_list(
831                                                 sel,
832                                                 function(o) { return JSON2js( o.getAttribute('retrieve_id') ); }
833                                         );
834                                         if (typeof obj.on_select == 'function') {
835                                                 obj.on_select(list);
836                                         }
837                                         if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
838                                                 obj.error.sdump('D_CAT','manage_items: Calling external .on_select()\n');
839                                                 window.xulG.on_select(list);
840                                         }
841                                 }
842                         }
843                 );
844
845         obj.lists.workarea = new util.list('workarea_tree');
846                 obj.lists.workarea.init(
847                         {
848                                 'columns' : columns,
849                                 'retrieve_row' : retrieve_row,
850                                 'on_select' : function(ev) {
851                     obj.selected_list = 'workarea';
852                                         JSAN.use('util.functional');
853                                         var sel = obj.lists.workarea.retrieve_selection();
854                                         obj.controller.view.sel_clip.setAttribute('disabled',sel.length < 1);
855                                         var list = util.functional.map_list(
856                                                 sel,
857                                                 function(o) { return JSON2js( o.getAttribute('retrieve_id') ); }
858                                         );
859                                         if (typeof obj.on_select == 'function') {
860                                                 obj.on_select(list);
861                                         }
862                                         if (typeof window.xulG == 'object' && typeof window.xulG.on_select == 'function') {
863                                                 obj.error.sdump('D_CAT','serctrl: Calling external .on_select()\n');
864                                                 window.xulG.on_select(list);
865                                         } else {
866                                                 obj.error.sdump('D_CAT','serctrl: No external .on_select()\n');
867                                         }
868                                 }
869                         }
870                 );
871     },
872
873         'refresh_list' : function(list_name) {
874         var obj = this;
875
876         //TODO Optimize this?
877         obj.retrieve(list_name);
878     },
879
880     // accepts a list of ids or a list of objects
881     'refresh_rows' : function(list) {
882         var obj = this;
883
884         var id_list;
885
886         if (typeof list[0] == 'object') {
887             id_list = util.functional.map_list(
888                 list,
889                 function(o) {
890                     return o.id()
891                 }
892             );
893         } else {
894             id_list = list;
895         }
896
897         for (var i = 0; i < id_list.length; i++) {
898             obj.lists[obj.selected_list].refresh_row(obj.row_map[id_list[i]]);
899         }
900     },
901
902         'retrieve' : function(list_name) {
903                 var obj = this;
904         var list = obj.lists[list_name];
905         
906                 list.clear();
907
908         if (!obj.sdist_ids.length) { // no sdists to retrieve items for
909             return;
910         }
911
912         var rparams = list.sitem_retrieve_params;
913         var robj;
914         rparams['+sstr'] = { "distribution" : obj.sdist_ids };
915
916         if (obj.mode == 'bind') {
917             if (list_name == 'workarea') {
918                 rparams['unit'] = obj.current_sunit_id;
919             } else if (!$('serial_manage_items_show_all').checked){
920                 rparams['unit'] = {"<>" : obj.current_sunit_id};
921             }
922         }
923
924         var other_params = list.sitem_extra_params;
925         other_params.join = 'sstr';
926
927         robj = obj.network.simple_request(
928             'FM_SITEM_ID_LIST',
929             [ ses(), rparams, other_params ]
930         );
931         if (!robj) {
932             robj = [];
933         } else if (typeof robj.ilsevent!='undefined') {
934             obj.error.standard_unexpected_error_alert('Failed to retrieve serial item ID list',E);
935         } else if (!robj.length) {
936             robj = [robj];
937         }
938
939         for (i = 0; i < robj.length; i++) {
940             var nparams = list.append( { 'row' : { 'my' : { 'sitem_id' : robj[i] } }, 'to_bottom' : true, 'no_auto_select' : true } );
941             obj.row_map[robj[i]] = nparams;
942         }
943         },
944
945         'on_select' : function(list) {
946
947                 dump('manage_items.on_select list = ' + js2JSON(list) + '\n');
948
949                 var obj = this;
950
951                 /*obj.controller.view.cmd_items_claimed_returned.setAttribute('disabled','false');
952                 obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');*/
953
954                 obj.retrieve_ids = list;
955         },
956
957     'process_unit_selection' : function(menuitem) {
958         var obj = this;
959
960         var label = menuitem.label;
961         var sunit_id = menuitem.getAttribute('sunit_id');
962         var sdist_id = menuitem.getAttribute('sdist_id');
963         var sstr_id = menuitem.getAttribute('sstr_id');
964         obj.set_sunit(sunit_id, label, sdist_id, sstr_id);
965         obj.save_sunit(sunit_id, label, sdist_id, sstr_id);
966         if (obj.mode == 'bind') {
967             obj.refresh_list('main');
968             obj.refresh_list('workarea');
969         }
970     },
971
972     'view_notes' : function(type) {
973         var obj = this;
974
975         if (!obj.retrieve_ids || obj.retrieve_ids.length == 0) return;
976
977         var object_id_fn;
978         var function_type;
979         var object_type;
980         var constructor;
981
982         switch(type) {
983             case 'sitem':
984                 object_id_fn = function(item) { return item.id() };
985                 title_fn = function(item) { return fieldmapper.IDL.fmclasses.sitem.field_map.id.label + ' ' + item.id() };
986                 function_type = 'SIN';
987                 object_type = 'item';
988                 constructor = sin;
989                 break;
990             case 'sdist':
991                 object_id_fn = function(item) { return item.stream().distribution() };
992                 title_fn = function(item) {
993                     var sdist_id = object_id_fn(item);
994                     return obj.sdist_map[sdist_id].label()
995                         + ' -- ' + obj.sdist_map[sdist_id].holding_lib().shortname()
996                         + ' (' + fieldmapper.IDL.fmclasses.sdist.field_map.id.label + ' ' + sdist_id + ')'
997                 };
998                 function_type = 'SDISTN';
999                 object_type = 'distribution';
1000                 constructor = sdistn;
1001                 break;
1002             case 'ssub':
1003                 object_id_fn = function(item) { return item.issuance().subscription().id() };
1004                 title_fn = function(item) {
1005                     var ssub_id = object_id_fn(item);
1006                     return obj.ssub_map[ssub_id].owning_lib().shortname()
1007                         + ' (' + fieldmapper.IDL.fmclasses.ssub.field_map.id.label + ' ' + ssub_id + ')'
1008                 };
1009                 function_type = 'SSUBN';
1010                 object_type = 'subscription';
1011                 constructor = ssubn;
1012                 break;
1013             default:
1014                 return;
1015         }
1016
1017         var seen_ids = {};
1018         for (var i = 0; i < obj.retrieve_ids.length; i++) {
1019             var item = obj.list_sitem_map[obj.retrieve_ids[i].sitem_id];
1020             var obj_id = object_id_fn(item);
1021             if (seen_ids[obj_id]) continue;
1022             JSAN.use('util.window'); var win = new util.window();
1023             win.open(
1024                 urls.XUL_SERIAL_NOTES,
1025                 '','chrome,resizable,modal',
1026                 { 'object_id' : obj_id, 'function_type' : function_type, 'object_type' : object_type, 'constructor' : constructor, 'title' : $('serialStrings').getString('staff.serial.'+type+'_editor.notes') + ' -- ' + title_fn(item) }
1027             );
1028             seen_ids[obj_id] = 1;
1029         }
1030     }
1031 }
1032
1033 function item_columns(modify,params) {
1034
1035     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
1036     //JSAN.use('util.network'); var network = new util.network();
1037
1038     var c = [
1039         {
1040             'id' : 'sitem_id',
1041             'label' : 'Item ID',
1042             'flex' : 1,
1043             'primary' : false,
1044             'hidden' : false,
1045             'render' : function(my) { return my.sitem.id(); },
1046             'persist' : 'hidden width ordinal'
1047         },
1048         {
1049             'id' : 'label',
1050             'label' : 'Issuance Label',
1051             'flex' : 1,
1052             'primary' : false,
1053             'hidden' : false,
1054             'render' : function(my) { return my.sitem.issuance().label(); },
1055             'persist' : 'hidden width ordinal'
1056         },
1057         {
1058             'id' : 'distribution',
1059             'label' : 'Distribution',
1060             'flex' : 1,
1061             'primary' : false,
1062             'hidden' : false,
1063             'persist' : 'hidden width ordinal',
1064             'render' : function(my) { return my.parent_obj.sdist_map[my.sitem.stream().distribution()].label(); }
1065         },
1066         {
1067             'id' : 'distribution_ou',
1068             'label' : $('serialStrings').getString('staff.serial.manage_items.holder.label'),
1069             'flex' : 1,
1070             'primary' : false,
1071             'hidden' : false,
1072             'persist' : 'hidden width ordinal',
1073             'render' : function(my) { return my.parent_obj.sdist_map[my.sitem.stream().distribution()].holding_lib().shortname(); }
1074         },
1075         {
1076             'id' : 'stream_id',
1077             'label' : 'Stream ID',
1078             'flex' : 1,
1079             'primary' : false,
1080             'hidden' : false,
1081             'persist' : 'hidden width ordinal',
1082             'render' : function(my) { return my.sitem.stream().id(); }
1083         },
1084         {
1085             'id' : 'date_published',
1086             'label' : 'Date Published',
1087             'flex' : 1,
1088             'primary' : false,
1089             'hidden' : false,
1090             'render' : function(my) { return my.sitem.issuance().date_published().substr(0,10); },
1091             'persist' : 'hidden width ordinal'
1092         },
1093         {
1094             'id' : 'date_expected',
1095             'label' : 'Date Expected',
1096             'flex' : 1,
1097             'primary' : false,
1098             'hidden' : false,
1099             'render' : function(my) { return my.sitem.date_expected().substr(0,10); },
1100             'persist' : 'hidden width ordinal'
1101         },
1102         {
1103             'id' : 'date_received',
1104             'label' : 'Date Received',
1105             'flex' : 1,
1106             'primary' : false,
1107             'hidden' : false,
1108             'render' : function(my) { return my.sitem.date_received().substr(0,10); },
1109             'persist' : 'hidden width ordinal'
1110         },
1111         {
1112             'id' : 'notes',
1113             'label' : $('serialStrings').getString('staff.serial.manage_items.notes_column.label'),
1114             'flex' : 1,
1115             'primary' : false,
1116             'hidden' : false,
1117             'render' : function(my) { return my.sitem.notes().length + ' / ' + my.parent_obj.sdist_map[my.sitem.stream().distribution()].notes().length + ' / ' + my.parent_obj.ssub_map[my.sitem.issuance().subscription().id()].notes().length; },
1118             'persist' : 'hidden width ordinal'
1119         },
1120         {
1121             'id' : 'call_number',
1122             'label' : 'Call Number',
1123             'flex' : 1,
1124             'primary' : false,
1125             'hidden' : false,
1126             'persist' : 'hidden width ordinal',
1127             'render' : function(my) { return my.sitem.unit().call_number().label(); }
1128         },
1129         {
1130             'id' : 'unit_id_contents',
1131             'label' : 'Unit ID / Contents',
1132             'flex' : 1,
1133             'primary' : false,
1134             'hidden' : false,
1135             'render' : function(my) { return '[' + my.sitem.unit().id() + '] ' + my.sitem.unit().summary_contents() ; },
1136             'persist' : 'hidden width ordinal'
1137         },
1138         {
1139             'id' : 'creator',
1140             'label' : 'Creator',
1141             'flex' : 1,
1142             'primary' : false,
1143             'hidden' : true,
1144             'persist' : 'hidden width ordinal',
1145             'render' : function(my) { return my.sitem.creator().usrname(); }
1146         },
1147         {
1148             'id' : 'create_date',
1149             'label' : document.getElementById('circStrings').getString('staff.circ.utils.create_date'),
1150             'flex' : 1,
1151             'primary' : false,
1152             'hidden' : true,
1153             'persist' : 'hidden width ordinal',
1154             'render' : function(my) { return my.sitem.create_date().substr(0,10); }
1155         },
1156         {
1157             'id' : 'editor',
1158             'label' : 'Editor',
1159             'flex' : 1,
1160             'primary' : false,
1161             'hidden' : true,
1162             'persist' : 'hidden width ordinal',
1163             'render' : function(my) { return my.sitem.editor().usrname(); }
1164         },
1165         {
1166             'id' : 'edit_date',
1167             'label' : document.getElementById('circStrings').getString('staff.circ.utils.edit_date'),
1168             'flex' : 1,
1169             'primary' : false,
1170             'hidden' : false,
1171             'persist' : 'hidden width ordinal',
1172             'render' : function(my) { return my.sitem.edit_date().substr(0,10); }
1173         },
1174         {
1175             'id' : 'holding_code',
1176             'label' : 'Holding Code',
1177             'flex' : 1,
1178             'primary' : false,
1179             'hidden' : true,
1180             'render' : function(my) { return my.sitem.issuance().holding_code(); },
1181             'persist' : 'hidden width ordinal'
1182         },
1183         {
1184             'id' : 'holding_type',
1185             'label' : 'Holding Type',
1186             'flex' : 1,
1187             'primary' : false,
1188             'hidden' : true,
1189             'render' : function(my) { return my.sitem.issuance().holding_type(); },
1190             'persist' : 'hidden width ordinal'
1191         },
1192         {
1193             'id' : 'holding_link_id',
1194             'label' : 'Holding Link ID',
1195             'flex' : 1,
1196             'primary' : false,
1197             'hidden' : true,
1198             'render' : function(my) { return my.sitem.issuance().holding_link_id(); },
1199             'persist' : 'hidden width ordinal'
1200         }
1201     ];
1202     for (var i = 0; i < c.length; i++) {
1203         if (modify[ c[i].id ]) {
1204             for (var j in modify[ c[i].id ]) {
1205                 c[i][j] = modify[ c[i].id ][j];
1206             }
1207         }
1208     }
1209     if (params) {
1210         if (params.just_these) {
1211             JSAN.use('util.functional');
1212             var new_c = [];
1213             for (var i = 0; i < params.just_these.length; i++) {
1214                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
1215                 new_c.push( function(y){ return y; }( x ) );
1216             }
1217             c = new_c;
1218         }
1219         if (params.except_these) {
1220             JSAN.use('util.functional');
1221             var new_c = [];
1222             for (var i = 0; i < c.length; i++) {
1223                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
1224                 if (!x) new_c.push(c[i]);
1225             }
1226             c = new_c;
1227         }
1228     }
1229     //return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
1230     return c;
1231 };
1232
1233 spawn_sitem_editor = function(params) {
1234     try {
1235         if (!params.sitem_ids && !params.sitems) return;
1236         if (params.sitem_ids && params.sitem_ids.length == 0) return;
1237         if (params.sitems && params.sitems.length == 0) return;
1238         if (params.sitem_ids) params.sitem_ids = js2JSON(params.sitem_ids); // legacy
1239         if (!params.caller_handles_update) params.handle_update = 1; // legacy
1240
1241         var obj = {};
1242         JSAN.use('util.network'); obj.network = new util.network();
1243         JSAN.use('util.error'); obj.error = new util.error();
1244
1245         var title = '';
1246         if (params.sitem_ids && params.sitem_ids.length > 1 && params.do_edit == 1)
1247             title = 'Batch Edit Items';
1248         else /* if(params.sitems && params.sitems.length > 1 && params.do_edit == 1)
1249             title = 'Batch View Items';
1250         else if(params.sitem_ids && params.sitem_ids.length == 1) */
1251             title = 'Edit Item';/*
1252         else
1253             title = 'View Item';*/
1254
1255         JSAN.use('util.window'); var win = new util.window();
1256         params.in_modal = true;
1257         var my_xulG = win.open(
1258             (urls.XUL_SERIAL_ITEM_EDITOR),
1259             title,
1260             'chrome,modal,resizable',
1261             params
1262         );
1263         if (my_xulG.sitems && params.do_edit) {
1264             return my_xulG.sitems;
1265         } else {
1266             return [];
1267         }
1268     } catch(E) {
1269         JSAN.use('util.error'); var error = new util.error();
1270         error.standard_unexpected_error_alert('error in spawn_sitem_editor',E);
1271     }
1272 }
1273
1274 dump('exiting manage_items.js\n');