Add support for Multi-Homed Items (aka Foreign Bibs, aka Linked Items)
[evergreen-equinox.git] / Open-ILS / xul / staff_client / server / cat / manage_multi_home_items.js
1 var data; var list; var error; var net; var sound;
2 var rows = {};
3 var bpbcm_barcode_map = {};
4
5 var commonStrings;
6 var catStrings;
7
8 //// parent interfaces may call this
9 function default_focus() { document.getElementById('scanbox').focus(); }
10 ////
11
12 function my_init() {
13     try {
14         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); 
15
16         commonStrings = $('commonStrings');
17         catStrings = $('catStrings');
18
19         if (typeof JSAN == 'undefined') {
20             throw(
21                 commonStrings.getString('common.jsan.missing')
22             );
23         }
24
25         JSAN.errorLevel = "die"; // none, warn, or die
26         JSAN.addRepository('..');
27
28         JSAN.use('util.error'); error = new util.error();
29         JSAN.use('util.sound'); sound = new util.sound();
30         JSAN.use('util.widgets');
31         JSAN.use('util.functional');
32         JSAN.use('util.list');
33         JSAN.use('OpenILS.data'); data = new OpenILS.data();
34         data.stash_retrieve();
35         JSAN.use('util.network'); net = new util.network();
36         dojo.require('openils.PermaCrud');
37         JSAN.use('cat.util');
38
39         init_menu();
40         init_list();
41         $('list_actions').appendChild( list.render_list_actions() );
42         list.set_list_actions();
43         populate_list();
44         $('submit').addEventListener('command', function() { handle_submit(true); }, false);
45         $('remove').addEventListener('command', function() { handle_remove(); }, false);
46         $('change').addEventListener('command', function() { handle_change(); }, false);
47         $('opac').addEventListener('command', function() { handle_opac(); }, false);
48         $('scanbox').addEventListener('keypress', handle_keypress, false);
49         default_focus();
50
51         if (typeof xulG.set_tab_name == 'function') {
52             xulG.set_tab_name(
53                 catStrings.getFormattedString(
54                     'staff.cat.manage_multi_bib_items.tab_name',
55                     [ xul_param('docid') ]
56                 )
57             );
58         }
59
60         if (! xul_param('no_bib_summary')) {
61             if (typeof bib_brief_overlay == 'function') {
62                 $("bib_brief_groupbox").hidden = false;
63                 bib_brief_overlay( { 'mvr_id' : xul_param('docid') } );
64             }
65         }
66
67     } catch(E) {
68         alert('Error in manage_multi_home_items.js, my_init(): ' + E);
69     }
70 }
71
72 function init_menu() {
73     try {
74         var ml = util.widgets.make_menulist(
75             util.functional.map_list(
76                 data.list.bpt.sort( function(a,b) {
77                     if (a.name().toUpperCase() < b.name().toUpperCase()) return -1;
78                     if (a.name().toUpperCase() > b.name().toUpperCase()) return 1;
79                     return 0;
80                 }),
81                 function(obj) {
82                     return [ obj.name(), obj.id() ];
83                 }
84             )
85         );
86         ml.setAttribute('id','bpt_menu');
87         $('menu_placeholder').appendChild(ml);
88     } catch(E) {
89         alert('Error in manage_multi_home_items.js, init_menu(): ' + E);
90     }
91 }
92
93 function init_list() {
94     try {
95         list = new util.list( 'list' );
96         list.init( 
97             {
98                 'retrieve_row' : function(params) {
99                     if (params.row.my.bpbcm) {
100                         params.row_node.setAttribute('retrieve_id',params.row.my.bpbcm.id());
101                     }
102                     params.on_retrieve(params.row);
103                     return params.row;
104                 },
105                 'columns' : [
106                     {
107                         'id' : 'result',
108                         'label' : 'Result',
109                         'flex' : 1,
110                         'primary' : false,
111                         'hidden' : false,
112                         'editable' : false, 'render' : function(my) { return my.result; }
113                     }
114                 ].concat(
115                     list.fm_columns('acp', {
116                         '*' : { 'expanded_label' : false, 'hidden' : true },
117                         'acp_barcode' : { 'hidden' : false },
118                         'acp_opac_visible' : { 'hidden' : false },
119                         'acp_holdable' : { 'hidden' : false }
120                     })
121                 ).concat(
122                     list.fm_columns('mvr', {
123                         '*' : { 'expanded_label' : false, 'hidden' : true }, 
124                         'mvr_title' : { 'hidden' : false },
125                         'mvr_author' : { 'hidden' : false },
126                         'mvr_isbn' : { 'hidden' : false },
127                         'mvr_tcn' : { 'hidden' : false },
128                         'mvr_id' : { 'hidden' : false }
129                     })
130                 ).concat(
131                     list.fm_columns('bpbcm', {
132                         '*' : { 'expanded_label' : false, 'hidden' : true },
133                         'bpbcm_peer_type' : {
134                             'hidden' : false,
135                             'render' : function(my) { return my.bpbcm ? data.hash.bpt[ my.bpbcm.peer_type() ].name() : ''; }
136                         }
137                     })
138                 )
139             }
140         );
141     } catch(E) {
142         alert('Error in manage_multi_home_items.js, init_list(): ' + E);
143     }
144 }
145
146 function handle_keypress(ev) {
147     try {
148         if (ev.keyCode && ev.keyCode == 13) {
149             handle_submit(true);
150         }
151     } catch(E) {
152         alert('Error in manage_multi_home_items.js, handle_keypress(): ' + E);
153     }
154 }
155
156 function handle_submit(create,my_bpbcm,my_barcode) {
157     try {
158         var barcode;
159         if (create) {
160             if (my_barcode) {
161                 barcode = my_barcode;
162             } else {
163                 barcode = $('scanbox').value;
164                 $('scanbox').value = '';
165                 default_focus();
166             }
167         }
168
169         var placeholder_acp = new acp();
170         placeholder_acp.barcode(barcode);
171         var row_params = {
172             'row' : {
173                 'my' : {
174                     'acp' : placeholder_acp,
175                     'bpbcm' : my_bpbcm
176                 }
177             }
178         };
179
180         if (barcode && rows[barcode]) {
181                 var node = rows[barcode].my_node;
182                 var parentNode = node.parentNode;
183                 parentNode.removeChild( node );
184                 delete(rows[barcode]);
185         }
186
187         row_params = list.append(row_params);
188         if (barcode) {
189             rows[barcode] = row_params;
190         }
191
192         function handle_req(req) {
193             try {
194                 var robj = req.getResultObject();
195                 row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.error');
196                 if (typeof robj.ilsevent != 'undefined') {
197                     row_params.row.my.result = robj.textcode;
198                 } else {
199                     rows[robj.copy.barcode()] = row_params;
200                     if (row_params.row.my.bpbcm) {
201                         bpbcm_barcode_map[ row_params.row.my.bpbcm.id() ] = robj.copy.barcode();
202                     }
203
204                     row_params.row.my.acp = robj.copy;
205                     row_params.row.my.mvr = robj.mvr;
206
207                     if (create && robj.mvr.doc_id() != xul_param('docid')) {
208                         var new_bpbcm = new bpbcm();
209                             new_bpbcm.isnew(1);
210                             new_bpbcm.peer_type($('bpt_menu').value);
211                             new_bpbcm.peer_record(xul_param('docid'));
212                             new_bpbcm.target_copy(robj.copy.id());
213                         var pcrud = new openils.PermaCrud( { authtoken :ses() });
214                         pcrud.create(new_bpbcm, {
215                             "onerror" : function(r) {
216                                 dump('onerror, r = ' + js2JSON(r) + '\n');
217                             },
218                             "oncomplete": function (r, objs) {
219                                 try {
220                                     var obj = objs[0];
221                                     if (obj) {
222                                         row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.success');
223                                         row_params.row.my.bpbcm = obj;
224                                         bpbcm_barcode_map[ obj.id() ] = robj.copy.barcode();
225                                     } else {
226                                         row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.failed');
227                                         sound.bad();
228                                     }
229                                     list.refresh_row( row_params );
230                                 } catch(E) {
231                                     alert('Error in manage_multi_home_items.js, handle_submit, pcrud create oncomplete callback: ' + E);
232                                 }
233                             }
234                         });
235                     } else {
236                         if (robj.mvr.doc_id() != xul_param('docid')) {
237                             row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.item_linked_to_bib');
238                         } else {
239                             row_params.row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.item_native_to_bib');
240                         }
241                     }
242                 }
243                 list.refresh_row( row_params );
244             } catch(E) {
245                 alert('Error in manage_multi_home_items.js, handle_submit, acp details callback: ' + E);
246             }
247         }
248
249         if (my_bpbcm) {
250             net.simple_request(
251                 'FM_ACP_DETAILS', // FIXME: want this to be authoritative
252                 [ ses(), my_bpbcm.target_copy() ],
253                 handle_req
254             );
255         } else {
256             net.simple_request(
257                 'FM_ACP_DETAILS_VIA_BARCODE.authoritative',
258                 [ ses(), barcode ],
259                 handle_req
260             );
261         }
262
263     } catch(E) {
264         alert('Error in manage_multi_home_items.js, handle_submit(): ' + E);
265     }
266 }
267
268 function populate_list() {
269     try {
270         var pcrud = new openils.PermaCrud( { authtoken :ses() });
271         pcrud.search(
272             'bpbcm',
273             {
274                 peer_record : xul_param('docid')
275             },
276             {
277                 async : true,
278                 streaming : true,
279                 onerror : function(r) {
280                         alert('Error in manage_multi_home_items.js, populate_list(), pcrud.search onerror: ' + r);
281                 },
282                 oncomplete : function() {
283                     if (xul_param('barcodes')) { // incoming from Holdings Maintenance
284                         handle_barcodes( xul_param('barcodes') );
285                     }
286                 },
287                 onresponse : function(r) {
288                     try {
289                         var my_bpbcm = openils.Util.readResponse(r);
290                         if (typeof my_bpbcm.ils_event != 'undefined') { throw(my_bpbcm); }
291                         handle_submit(false,my_bpbcm);
292                     } catch(E) {
293                         alert('Error in manage_multi_home_items.js, populate_list(), pcrud.search onresponse: ' + E);
294                     }
295                 }
296             }
297         );
298
299     } catch(E) {
300         alert('Error in manage_multi_home_items.js, populate_list(): ' + E);
301     }
302 }
303
304 function handle_change() {
305     try {
306         var node_list = list.retrieve_selection();
307         var eligibles = [];
308         for (var i = 0; i < node_list.length; i++) {
309             var retrieve_id = node_list[i].getAttribute('retrieve_id');
310             if (retrieve_id && retrieve_id != 'undefined') {
311                 eligibles.push( retrieve_id );
312             }
313         }
314         if (eligibles.length > 0) {
315             var new_peer_type = widget_prompt( $('bpt_menu').cloneNode(true), {
316                 'title' : catStrings.getString('staff.cat.manage_multi_bib_items.prompt.title')
317             });
318
319             if (new_peer_type) {
320                 var bpbcm_list = [];
321                 for (var i = 0; i < eligibles.length; i++) {
322                     var obj = rows[ bpbcm_barcode_map[ eligibles[i] ] ].row.my.bpbcm;
323                     obj.ischanged(1);
324                     obj.peer_type( new_peer_type );
325                     bpbcm_list.push( obj );
326                 }
327                 var pcrud = new openils.PermaCrud( { authtoken :ses() });
328                 pcrud.update(
329                     bpbcm_list, {
330                         'async' : false,
331                         'onerror': function(r) {
332                             dump('onerror: ' + r + '\n');
333                         },
334                         'onresponse': function(r) {
335                             dump('onresponse: ' + r + '\n');
336                         },
337                         'oncomplete': function(r,ids) {
338                             dump('oncomplete: r = ' + r + '\n\tids = ' + js2JSON(ids) + '\n');
339                             for (var i = 0; i < ids.length; i++) {
340                                 var bpbcm_id = ids[i];
341                                 try {
342                                     rows[ bpbcm_barcode_map[ bpbcm_id ] ].row.my.bpbcm.peer_type( new_peer_type );
343                                     rows[ bpbcm_barcode_map[ bpbcm_id ] ].row.my.result = catStrings.getString('staff.cat.manage_multi_bib_items.result.column.value.peer_type_updated');
344                                     list.refresh_row( rows[ bpbcm_barcode_map[ bpbcm_id ] ] );
345                                 } catch(E) {
346                                     alert('error in oncomplete: ' + E);
347                                 }
348                             }
349                         }
350                     }
351                 );
352             }
353         }
354
355     } catch(E) {
356         alert('Error in manage_multi_home_items.js, handle_change(): ' + E);
357     }
358 }
359
360 function handle_remove() {
361     try {
362         var node_list = list.retrieve_selection();
363         var eligibles = [];
364         for (var i = 0; i < node_list.length; i++) {
365             var retrieve_id = node_list[i].getAttribute('retrieve_id');
366             if (retrieve_id && retrieve_id != 'undefined') {
367                 eligibles.push( retrieve_id );
368             }
369         }
370         if (eligibles.length > 0) {
371             if (window.confirm(
372                 eligibles.length == 1
373                 ? catStrings.getFormattedString(
374                         'staff.cat.manage_multi_bib_items.prompt.confirm.unlink_item_from_bib.singular',
375                         [ xul_param('docid') ]
376                 )
377                 : catStrings.getFormattedString(
378                         'staff.cat.manage_multi_bib_items.prompt.confirm.unlink_item_from_bib.plural',
379                         [ xul_param('docid'), eligibles.length ]
380                 ))
381             ) {
382                 var bpbcm_list = [];
383                 for (var i = 0; i < eligibles.length; i++) {
384                     var obj = rows[ bpbcm_barcode_map[ eligibles[i] ] ].row.my.bpbcm;
385                     obj.isdeleted(1);
386                     bpbcm_list.push( obj );
387                 }
388                 var pcrud = new openils.PermaCrud( { authtoken :ses() });
389                 pcrud.eliminate(
390                     bpbcm_list, {
391                         'async' : false,
392                         'onerror': function(r) {
393                             dump('onerror: ' + r + '\n');
394                         },
395                         'onresponse': function(r) {
396                             dump('onresponse: ' + r + '\n');
397                         },
398                         'oncomplete': function(r,ids) {
399                             dump('oncomplete: r = ' + r + '\n\tids = ' + js2JSON(ids) + '\n');
400                             for (var i = 0; i < ids.length; i++) {
401                                 var bpbcm_id = ids[i];
402                                 try {
403                                     var node = rows[ bpbcm_barcode_map[ bpbcm_id ] ].my_node;
404                                     var parentNode = node.parentNode;
405                                     parentNode.removeChild( node );
406                                     delete(rows[ bpbcm_barcode_map[ bpbcm_id ] ]);
407                                 } catch(E) {
408                                     alert('error in oncomplete: ' + E);
409                                 }
410                             }
411                         }
412                     }
413                 );
414             }
415         }
416
417     } catch(E) {
418         alert('Error in manage_multi_home_items.js, handle_remove(): ' + E);
419     }
420 }
421
422 function handle_opac() {
423     try {
424         var node_list = list.retrieve_selection();
425         var eligibles = [];
426         for (var i = 0; i < node_list.length; i++) {
427             var retrieve_id = node_list[i].getAttribute('retrieve_id');
428             if (retrieve_id && retrieve_id != 'undefined') {
429                 eligibles.push( retrieve_id );
430             }
431         }
432         if (eligibles.length > 0) {
433             var selection_list = [];
434             for (var i = 0; i < eligibles.length; i++) {
435                 selection_list.push({
436                     'barcode' : bpbcm_barcode_map[ eligibles[i] ]
437                 });
438             }
439             cat.util.show_in_opac(selection_list);
440         }
441
442     } catch(E) {
443         alert('Error in manage_multi_home_items.js, handle_opac(): ' + E);
444     }
445 }
446
447 function handle_barcodes(barcodes) {
448     try {
449         var funcs = [];
450
451         for (var i = 0; i < barcodes.length; i++) {
452             if (typeof rows[barcodes[i]] == 'undefined') {
453                 funcs.push(
454                     function(barcode) {
455
456                         return function() {
457                             handle_submit(true,null,barcode);
458                         };
459
460                     }(barcodes[i])
461                 )
462             }
463         }
464
465         JSAN.use('util.exec'); var exec = new util.exec();
466         exec.timer( funcs, 500 );
467
468         funcs.push(
469             function() {
470                 exec.clear_timer();
471             }
472         );
473
474     } catch(E) {
475         alert('Error in manage_multi_home_items.js, handle_barcodes(): ' + E);
476     }
477 }