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