]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/info_group.js
moving users in and out of groups produced dialogs that expected vertical patron...
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / info_group.js
1 function $(id) { return document.getElementById(id); }
2
3 function my_init() {
4     try {
5         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
6         if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
7         JSAN.errorLevel = "die"; // none, warn, or die
8         JSAN.addRepository('/xul/server/');
9
10         JSAN.use('util.error'); g.error = new util.error();
11         JSAN.use('util.network'); g.network = new util.network();
12         JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('patron.util'); JSAN.use('util.functional');
13         JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.stash_retrieve();
14
15         g.error.sdump('D_TRACE','my_init() for patron_info_group.xul');
16
17         g.patron_id = xul_param('patron_id');
18
19         tree_init();
20
21         g.patron = patron.util.retrieve_au_via_id(ses(),g.patron_id);
22         if ((g.patron == null) || (typeof g.patron.ilsevent != 'undefined') ) throw(p);
23
24         refresh();
25
26     } catch(E) {
27         var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/info_group.xul', E]);
28         try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
29         alert(err_msg);
30     }
31 }
32
33 function retrieve_money_summaries() {
34     try {
35         JSAN.use('util.money');
36         var robj = g.network.simple_request( 'BLOB_BALANCE_OWED_VIA_USERGROUP', [ ses(), g.patron.usrgroup() ]);
37         if (typeof robj.ilsevent != 'undefined') { throw(robj); }
38
39         var sum = 0; /* in cents */
40         g.group_owed = {};
41
42         for (var i = 0; i < robj.length; i++) {
43             sum += util.money.dollars_float_to_cents_integer( robj[i].balance_owed );
44             g.group_owed[ robj[i].usr ] = robj[i].balance_owed;
45         }
46
47         $('total_owed').setAttribute(
48             'value',
49             $('patronStrings').getFormattedString( 'staff.patron.info_group.total_owed.label', [ util.money.cents_as_dollars(sum) ] )
50         );
51
52     } catch(E) {
53         alert('Error in info_group.js, retrieve_money_summaries(): ' + E);
54     }
55 }
56
57 function tree_init() {
58     try {
59         var obscure_dob = String( g.data.hash.aous['circ.obscure_dob'] ) == 'true';
60
61         JSAN.use('util.list'); g.list = new util.list('patron_list');
62
63         var columns = g.list.fm_columns( 'au', {
64             '*' : { 'hidden' : true },
65             'au_active' : { 'hidden' : 'false' },
66             'au_barred' : { 'hidden' : 'false' },
67             'au_family_name' : { 'hidden' : 'false' },
68             'au_first_given_name' : { 'hidden' : 'false' },
69             'au_second_given_name' : { 'hidden' : 'false' },
70             'au_dob' : { 'hidden' : obscure_dob },
71             'au_master_account' : { 'hidden' : 'false' }
72         }).concat([
73             {
74                 'id' : 'gl_balance_owed', 'flex' : 1, 'sort_type' : 'money',
75                 'label' : $("patronStrings").getString('staff.patron.summary.group_list.column.balance_owed.label'),
76                 'render' : function(my) { return my.balance_owed; } 
77             },
78             {
79                 'id' : 'gl_circ_count_out', 'flex' : 1, 'sort_type' : 'number',
80                 'label' : $("patronStrings").getString('staff.patron.info_group.column.circs_out.label'),
81                 'render' : function(my) { return my.circ_counts.out; }
82             },
83             {
84                 'id' : 'gl_circ_count_overdue', 'flex' : 1, 'sort_type' : 'number',
85                 'label' : $("patronStrings").getString('staff.patron.info_group.column.circs_overdue.label'),
86                 'render' : function(my) { return my.circ_counts.overdue; }
87             },
88             {
89                 'id' : 'gl_circ_count_claims_returned', 'flex' : 1, 'sort_type' : 'number', 'hidden' : true,
90                 'label' : $("patronStrings").getString('staff.patron.info_group.column.circs_claimed_returned.label'),
91                 'render' : function(my) { return my.circ_counts.claims_returned; }
92             },
93             {
94                 'id' : 'gl_circ_count_long_overdue', 'flex' : 1, 'sort_type' : 'number', 'hidden' : true,
95                 'label' : $("patronStrings").getString('staff.patron.info_group.column.circs_long_overdue.label'),
96                 'render' : function(my) { return my.circ_counts.long_overdue; }
97             },
98             {
99                 'id' : 'gl_circ_count_lost', 'flex' : 1, 'sort_type' : 'number', 'hidden' : true,
100                 'label' : $("patronStrings").getString('staff.patron.info_group.column.circs_lost.label'),
101                 'render' : function(my) { return my.circ_counts.lost; }
102             }
103         ]);
104         g.list.init(
105             {
106                 'columns' : columns,
107                 'retrieve_row' : function(params) {
108                     var id = params.retrieve_id;
109                     var row = params.row;
110                     if (typeof row.my == 'undefined') row.my = {};
111
112                     function process_and_return() {
113                         if (typeof params.on_retrieve == 'function') {
114                             params.on_retrieve(row);
115                         }
116                         return row;
117                     }
118
119                     patron.util.retrieve_fleshed_au_via_id( ses(), id, null, function(req) {
120                         row.my.au = req.getResultObject();
121                         process_and_return();
122                     });
123                     g.network.simple_request(
124                         'FM_CIRC_COUNT_RETRIEVE_VIA_USER.authoritative',
125                         [ ses(), id ],
126                         function(req) {
127                             try {
128                                 var robj = req.getResultObject();
129                                 // robj.out / robj.overdue / robj.claims_returned / robj.long_overdue / robj.lost
130                                 row.my.circ_counts = robj;
131                                 g.flesh_count++;
132                                 if (g.flesh_count >= g.row_count) {
133                                     $('total_out').setAttribute(
134                                         'value',
135                                         $('patronStrings').getFormattedString(
136                                             'staff.patron.info_group.total_out.label', 
137                                             [ g.total_out ]
138                                         )
139                                     );
140                                     $('total_overdue').setAttribute(
141                                         'value',
142                                         $('patronStrings').getFormattedString(
143                                             'staff.patron.info_group.total_overdue.label', 
144                                             [ g.total_overdue ]
145                                         )
146                                     );
147                                 }
148                                 process_and_return();
149                             } catch(E) {
150                                 alert('Error in info_group.js, circ count retrieve(): ' + E);
151                             }
152                         }
153                     );
154
155                     process_and_return();
156                 },
157                 'on_select' : function(ev) {
158                     JSAN.use('util.functional');
159                     var sel = g.list.retrieve_selection();
160                     g.sel_list = util.functional.map_list(
161                         sel,
162                         function(o) { return o.getAttribute('retrieve_id'); }
163                     );
164                     if (g.sel_list.length > 0) {
165                         $('retrieve_p').disabled = false;
166                         $('retrieve_p').setAttribute('disabled','false');
167                         if (g.sel_list.length > 1) {
168                             $('merge_p').disabled = false;
169                             $('merge_p').setAttribute('disabled','false');
170                         }
171                         $('clone').disabled = false;
172                         $('clone').setAttribute('disabled','false');
173                         $('remove').disabled = false;
174                         $('remove').setAttribute('disabled','false');
175                         $('move').disabled = false;
176                         $('move').setAttribute('disabled','false');
177                     } else {
178                         $('retrieve_p').disabled = true;
179                         $('retrieve_p').setAttribute('disabled','true');
180                         $('merge_p').disabled = true;
181                         $('merge_p').setAttribute('disabled','true');
182                         $('clone').disabled = true;
183                         $('clone').setAttribute('disabled','true');
184                         $('remove').disabled = true;
185                         $('remove').setAttribute('disabled','true');
186                         $('move').disabled = true;
187                         $('move').setAttribute('disabled','true');
188                     }
189                 }
190             }
191         );
192         $('list_actions').appendChild( g.list.render_list_actions() );
193         g.list.set_list_actions();
194         $('retrieve_p').disabled = true;
195         $('retrieve_p').setAttribute('disabled','true');
196         $('merge_p').disabled = true;
197         $('merge_p').setAttribute('disabled','true');
198         $('clone').disabled = true;
199         $('clone').setAttribute('disabled','true');
200         $('remove').disabled = true;
201         $('remove').setAttribute('disabled','true');
202         $('move').disabled = true;
203         $('move').setAttribute('disabled','true');
204         setTimeout( function() { $('patron_list').focus(); }, 0 );
205     } catch(E) {
206         alert('Error in info_group.js, tree_init(): ' + E);
207     }
208 }
209
210 function refresh() {
211     try {
212         retrieve_money_summaries();
213         retrieve_group_members();
214     } catch(E) {
215         alert('Error in info_group.js, refresh(): ' + E);
216     }
217 }
218
219 function retrieve_group_members() {
220     try {
221         JSAN.use('util.functional'); JSAN.use('patron.util');
222         g.group_members = [];
223         var robj = g.network.simple_request(
224             'FM_AU_LIST_RETRIEVE_VIA_GROUP.authoritative',
225             [ ses(), g.patron.usrgroup() ]
226         );
227         if ((robj == null) || (typeof robj.ilsevent != 'undefined') ) throw(robj);
228         var ids = util.functional.filter_list( robj, function(o) { return o != g.patron_id; });
229         g.row_count = ids.length + 1;
230         g.flesh_count = 0;
231         g.total_out = 0;
232         g.total_overdue = 0;
233
234         g.list.clear();
235
236         var funcs = [];
237
238             function gen_func(r) {
239                 return function() {
240                     g.list.append( {
241                         'retrieve_id' : r, 
242                         'row' : {
243                             'my' : {
244                                 'balance_owed' : g.group_owed[r]
245                             }
246                          }
247                     } );
248                 }
249             }
250
251         funcs.push( gen_func(g.patron_id) );
252         for (var i = 0; i < ids.length; i++) {
253             funcs.push( gen_func(ids[i]) );
254         }
255         JSAN.use('util.exec'); var exec = new util.exec(4);
256         exec.on_error = function(E) { alert('Error in info_group.js, retrieve_group_members chain exec: ' + E); }
257         exec.chain( funcs );
258
259     } catch(E) {
260         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.retrieve_group_members.failure'),E);
261     }
262 }
263
264 function retrieve_patron() {
265     try {
266         if (! g.sel_list ) return;
267         if (typeof window.xulG == 'object' && typeof window.xulG.new_patron_tab == 'function') {
268             for (var i = 0; i < g.sel_list.length; i++) {    
269                 try {
270                     window.xulG.new_patron_tab(
271                         { 'tab_name' : $("patronStrings").getString('staff.patron.info_group.retrieve_patron.tab_name') }, 
272                         { 
273                             'id' : g.sel_list[i],
274                             'url_prefix' : xulG.url_prefix,
275                             'new_tab' : xulG.new_tab,
276                             'set_tab' : xulG.set_tab
277                         }
278                     );
279                 } catch(E) {
280                     g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.retrieve_patron.failed_retrieving_patron'),E);
281                 }
282             }
283         }
284     } catch(E) {
285         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.retrieve_patron.failed_retrieving_patrons'),E);
286     }
287 }
288
289 function merge_patrons() {
290     try {
291         if (! g.sel_list ) return;
292         JSAN.use('patron.util'); 
293         var result = patron.util.merge(g.sel_list);
294         if (result) {
295             if (result != g.patron_id && g.sel_list.indexOf( g.patron_id ) != -1) {
296                 xulG.set_patron_tab(
297                     { 'tab_name' : $("patronStrings").getString('staff.patron.info_group.retrieve_patron.tab_name') }, 
298                     {
299                         'id' : result
300                     } 
301                 );
302             } else {
303                 refresh();
304             }
305         }
306     } catch(E) {
307         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.merge_patrons.failed_merging_patrons'),E);
308     }
309 }
310
311 function clone_patron() {
312     if (! g.sel_list ) return;
313     try {
314         for (var i = 0; i < g.sel_list.length; i++) {    
315             var loc = xulG.url_prefix( urls.XUL_REMOTE_BROWSER ); 
316                 //+ '?url=' + window.escape( urls.XUL_PATRON_EDIT + '?ses=' 
317                 //+ window.escape( ses() ) + '&clone=' + g.sel_list[i] );
318             if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') xulG.new_tab(
319                 loc, 
320                 {}, 
321                 { 
322                     'url' : urls.XUL_PATRON_EDIT, // + '?ses=' + window.escape(ses()) + '&clone=' + g.sel_list[i],
323                     'show_print_button' : true , 
324                     'tab_name' : $("patronStrings").getString('staff.patron.info_group.clone_patron.register_clone.tab_name'),
325                     'passthru_content_params' : {
326                         'ses' : ses(),
327                         'clone' : g.sel_list[i],
328                         'spawn_search' : spawn_search,
329                         'spawn_editor' : spawn_editor,
330                         'on_save' : function(p) { patron.util.work_log_patron_edit(p); refresh(); },
331                         'url_prefix' : xulG.url_prefix,
332                         'new_tab' : xulG.new_tab,
333                     },
334                     'url_prefix' : xulG.url_prefix,
335                     'new_tab' : xulG.new_tab,
336                 }
337             );
338         }
339     } catch(E) {
340         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.clone_patron.error_spawning_editors'),E);
341     }
342 }
343
344 function spawn_editor(p) {
345     var url = urls.XUL_PATRON_EDIT;
346     var passthru = {
347         'spawn_search' : spawn_search,
348         'spawn_editor' : spawn_editor,
349         'on_save' : function(p) { patron.util.work_log_patron_edit(p); refresh(); },
350         'url_prefix' : xulG.url_prefix,
351         'new_tab' : xulG.new_tab,
352     };
353     for (var i in p) {
354         passthru[i] = p[i];
355     }
356     var loc = xulG.url_prefix( urls.XUL_REMOTE_BROWSER ); // + '?url=' + window.escape( url );
357     if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') xulG.new_tab(
358         loc, 
359         {}, 
360         { 
361             'url' : url,
362             'show_print_button' : true , 
363             'tab_name' : $("patronStrings").getString('staff.patron.info_group.spawn_editor.editing_patron'),
364             'passthru_content_params' : passthru,
365             'url_prefix' : xulG.url_prefix,
366             'new_tab' : xulG.new_tab
367         }
368     );
369
370 }
371
372 function spawn_search(s) {
373     try {
374         g.error.sdump('D_TRACE', 'Editor would like to search for: ' + js2JSON(s) ); 
375         if (typeof window.xulG == 'object' && typeof window.xulG.new_patron_tab == 'function') 
376             xulG.new_patron_tab( {}, {'doit':1,'query':s} );
377     } catch(E) {
378         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.spawn_search'),E);
379     }
380 }
381
382 function remove_patron() {
383     if (! g.sel_list ) return;
384     var msg = '';
385     for (var i = 0 ; i < g.sel_list.length; i++)
386         if (g.sel_list[i] == g.patron_id)
387             msg = $("patronStrings").getString('staff.patron.info_group.remove_patron.warning_message');
388             
389     var c = window.confirm($("patronStrings").getFormattedString('staff.patron.info_group.remove_patron.warning_message_confirm', [msg]));
390     if (c) {
391         for (var i = 0; i < g.sel_list.length; i++) {    
392             var robj = g.network.simple_request('FM_AU_NEW_USERGROUP', [ ses(), g.sel_list[i], get_db_true() ]);
393             if (typeof robj.ilsevent != 'undefined') {
394                 g.error.standard_unexpected_error_alert($("patronStrings").getFormattedString('staff.patron.info_group.remove_patron.error_removing_patron', [g.sel_list[i]]), robj);
395             }
396         }
397         alert($("patronStrings").getString('staff.patron.info_group.remove_patron.patrons_removed_from_group')); 
398         /* FIXME - xulrunner bug if this alert comes after refresh? */
399         /* that's okay, because now that we're on a distributed database, we want human delay to mitigate race conditions */
400         refresh();
401     } else {
402         alert($("patronStrings").getString('staff.patron.info_group.remove_patron.patrons_not_removed_from_group'));
403     }
404 }
405
406 function link_patron(direction) {
407     try {
408         if (! g.sel_list ) { g.sel_list = []; g.sel_list[0] = g.patron_id; }
409         if (direction == null) throw($("patronStrings").getString('staff.patron.info_group.link_patron.null_not_allowed'));
410         var first_msg; var second_msg;
411         switch(direction) {
412             case true:
413                 first_msg = "-->";
414                 break;
415             case false:
416                 first_msg = "<--";
417                 break;
418             default:
419                 throw($("patronStrings").getString('staff.patron.info_group.link_patron.invalid_parameter'));
420                 break;
421         }
422         var barcode = window.prompt($("patronStrings").getString('staff.patron.info_group.link_patron.scan_patron_barcode'),'',first_msg);
423         if (!barcode) return;
424         JSAN.use('patron.util');
425         var patron_b = patron.util.retrieve_fleshed_au_via_barcode(ses(),barcode);
426         if (typeof patron_b.ilsevent != 'undefined') throw(patron_b);
427
428         if (g.sel_list.length == 0) g.sel_list[0] = g.patron_id;
429         for (var i = 0; i < g.sel_list.length; i++) {    
430
431             var patron_a = patron.util.retrieve_fleshed_au_via_id(ses(),g.sel_list[i],null);
432             if (typeof patron_a.ilsevent != 'undefined') throw(patron_a);
433             switch(direction) {
434                 case true:
435                     second_msg = $("patronStrings").getFormattedString('staff.patron.info_group.link_patron.move_patron_to_new_usergroup',[patron_a.card().barcode(), patron_b.card().barcode()]);
436                     break;
437                 case false:
438                     second_msg = $("patronStrings").getFormattedString('staff.patron.info_group.link_patron.move_patron_to_new_usergroup',[patron_b.card().barcode(), patron_a.card().barcode()]);
439                     break;
440             }
441
442             var horizontal_interface = String( g.data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
443             netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
444             var top_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto"><description>' + second_msg + '</description>';
445             top_xml += '<hbox><spacer flex="1"/><button label="'+$("patronStrings").getString('staff.patron.info_group.link_patron.move.label')+'"';
446             top_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.info_group.link_patron.move.accesskey')+'" name="fancy_submit"/>';
447             top_xml += '<button label="'+$("patronStrings").getString('staff.patron.info_group.link_patron.done.label')+'"';
448             top_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.info_group.link_patron.done.accesskey')+'" name="fancy_cancel"/></hbox></vbox>';
449             var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
450             if (horizontal_interface) {
451                 xml += '<vbox flex="1">';
452             } else {
453                 xml += '<hbox flex="1">';
454             }
455             /************/
456             xml += '<vbox flex="1">';
457             xml += '<hbox><spacer flex="1"/>';
458             if (direction) {
459                 xml += '<image src="/xul/server/skin/media/images/patron_right_arrow.png"/>';
460             } else {
461                 xml += '<image src="/xul/server/skin/media/images/patron_left_arrow.png"/>';
462             }
463             xml += '</hbox>';
464             xml += '<iframe style="min-height: 100px" flex="1" src="' + xulG.url_prefix( urls.XUL_PATRON_SUMMARY );
465             xml += '?show_name=1&amp;id=' + g.sel_list[i] + '"/>';
466             xml += '</vbox>';
467             xml += '<vbox flex="1">';
468             xml += '<hbox>';
469             if (direction) {
470                 xml += '<image src="/xul/server/skin/media/images/patron_right_arrow.png"/>';
471             } else {
472                 xml += '<image src="/xul/server/skin/media/images/patron_left_arrow.png"/>';
473             }
474             xml += '<spacer flex="1"/></hbox>';
475             xml += '<iframe style="min-height: 100px" flex="1" src="' + xulG.url_prefix( urls.XUL_PATRON_SUMMARY );
476             xml += '?show_name=1&amp;id=' + patron_b.id() + '"/>';
477             xml += '</vbox>';
478             /************/
479             if (horizontal_interface) {
480                 xml += '</vbox>';
481             } else {
482                 xml += '</hbox>';
483             }
484             xml += '</vbox>';
485             
486             var bot_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto"><hbox>';
487             bot_xml += '</hbox></vbox>';
488
489             //g.data.temp_top = top_xml; g.data.stash('temp_top');
490             //g.data.temp_mid = xml; g.data.stash('temp_mid');
491             //g.data.temp_bot = bot_xml; g.data.stash('temp_bot');
492             JSAN.use('util.window'); var win = new util.window();
493             var fancy_prompt_data = win.open(
494                 urls.XUL_FANCY_PROMPT,
495                 //+ '?xml_in_stash=temp_mid'
496                 //+ '&top_xml_in_stash=temp_top'
497                 //+ '&bottom_xml_in_stash=temp_bot'
498                 //+ '&title=' + window.escape('Move Patron into a Usergroup'),
499                 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
500                 { 'xml' : xml, 'top_xml' : top_xml, 'bottom_xml' : bot_xml, 'title' : $("patronStrings").getString('staff.patron.info_group.link_patron.move_patron_to_usergroup')}
501             );
502             if (fancy_prompt_data.fancy_status == 'incomplete') { continue; }
503             else {
504                 var patron_c;
505                 switch(direction) {
506                     case true:
507                         patron_a.usrgroup( patron_b.usrgroup() );
508                         patron_a.ischanged( '1' );
509                         patron_c = patron_a;
510                     break;
511                     case false:
512                         patron_b.usrgroup( patron_a.usrgroup() );
513                         patron_b.ischanged( '1' );
514                         patron_c = patron_b;
515                     break;
516                 }
517                 var robj = g.network.simple_request('FM_AU_UPDATE',[ ses(), patron_c ]);
518                 if (typeof robj.ilsevent != 'undefined') g.error.standard_unexpected_error_alert($("patronStrings").getFormattedString('staff.patron.info_group.link_patron.error_linking_patron', [g.sel_list[i]]), robj);
519             }
520         }
521         alert($("patronStrings").getString('staff.patron.info_group.link_patron.usergroups_updated'));
522         refresh();
523     } catch(E) {
524         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.info_group.link_patron.error_linking_patrons'),E);
525         refresh();
526     }
527 }
528
529