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