]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/info_group.xul
277eaa5c9ea52f8fcc68df7119879341568ac35a
[Evergreen.git] / Open-ILS / xul / staff_client / server / patron / info_group.xul
1 <?xml version="1.0"?>
2 <!-- Application: Evergreen Staff Client -->
3 <!-- Screen: Patron Display -->
4
5 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
6 <!-- STYLESHEETS -->
7 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
8 <?xml-stylesheet href="chrome://open_ils_staff_client/skin/global.css" type="text/css"?>
9 <?xml-stylesheet href="/xul/server/skin/global.css" type="text/css"?>
10 <?xml-stylesheet href="/xul/server/skin/patron_display.css" type="text/css"?>
11
12 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
13 <!-- LOCALIZATION -->
14 <!DOCTYPE window PUBLIC "" ""[
15         <!--#include virtual="/opac/locale/en-US/lang.dtd"-->
16 ]>
17
18 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
19 <!-- OVERLAYS -->
20 <?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
21
22 <window id="patron_info_group_win" width="700" height="550"
23         onload="try{ my_init(); font_helper(); } catch(E) { alert(E); }"
24         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
25
26         <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
27         <!-- BEHAVIOR -->
28         <script type="text/javascript">var myPackageDir = 'open_ils_staff_client'; var IAMXUL = true; var g = {};</script>
29         <scripts id="openils_util_scripts"/>
30
31         <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
32         <script>
33         <![CDATA[
34
35                 function $(id) { return document.getElementById(id); }
36
37                 function my_init() {
38                         try {
39                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
40                                 if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
41                                 JSAN.errorLevel = "die"; // none, warn, or die
42                                 JSAN.addRepository('/xul/server/');
43
44                                 JSAN.use('util.error'); g.error = new util.error();
45                                 JSAN.use('util.network'); g.network = new util.network();
46                                 JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('patron.util'); JSAN.use('util.functional');
47                                 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
48
49                                 g.error.sdump('D_TRACE','my_init() for patron_info_group.xul');
50
51                                 g.patron_id = xul_param('patron_id');
52
53                                 tree_init();
54
55                                 refresh();
56
57                         } catch(E) {
58                                 var err_msg = "!! This software has encountered an error.  Please tell your friendly " +
59                                         "system administrator or software developer the following:\npatron_info_group.xul\n" + E + '\n';
60                                 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
61                                 alert(err_msg);
62                         }
63                 }
64
65                 function tree_init() {
66                                 JSAN.use('OpenILS.data'); g.OpenILS = {}; 
67                                 g.OpenILS.data = new OpenILS.data(); g.OpenILS.data.init({'via':'stash'});
68
69                                 JSAN.use('util.list'); g.list = new util.list('patron_list');
70
71                                 JSAN.use('patron.util');
72                                 var columns = patron.util.columns(
73                                         {
74                                                 'active' : { 'hidden' : 'false' },
75                                                 'barred' : { 'hidden' : 'false' },
76                                                 'family_name' : { 'hidden' : 'false' },
77                                                 'first_given_name' : { 'hidden' : 'false' },
78                                                 'second_given_name' : { 'hidden' : 'false' },
79                                                 'dob' : { 'hidden' : 'false' },
80                                                 'master_account' : { 'hidden' : 'false' },
81                                         }
82                                 );
83                                 g.list.init(
84                                         {
85                                                 'columns' : columns,
86                                                 'map_row_to_columns' : patron.util.std_map_row_to_columns(),
87                                                 'retrieve_row' : function(params) {
88                                                         var id = params.retrieve_id;
89                                                         var au_obj = patron.util.retrieve_au_via_id( ses(), id );
90
91                                                         var row = params.row;
92                                                         if (typeof row.my == 'undefined') row.my = {};
93                                                         row.my.au = au_obj;
94                                                         if (typeof params.on_retrieve == 'function') {
95                                                                 params.on_retrieve(row);
96                                                         }
97                                                         return row;
98                                                 },
99                                                 'on_select' : function(ev) {
100                                                         JSAN.use('util.functional');
101                                                         var sel = g.list.retrieve_selection();
102                                                         g.sel_list = util.functional.map_list(
103                                                                 sel,
104                                                                 function(o) { return o.getAttribute('retrieve_id'); }
105                                                         );
106                                                         if (g.sel_list.length > 0) {
107                                                                 $('retrieve_p').disabled = false;
108                                                                 $('retrieve_p').setAttribute('disabled','false');
109                                                                 $('clone').disabled = false;
110                                                                 $('clone').setAttribute('disabled','false');
111                                                                 $('remove').disabled = false;
112                                                                 $('remove').setAttribute('disabled','false');
113                                                                 $('move').disabled = false;
114                                                                 $('move').setAttribute('disabled','false');
115                                                         } else {
116                                                                 $('retrieve_p').disabled = true;
117                                                                 $('retrieve_p').setAttribute('disabled','true');
118                                                                 $('clone').disabled = true;
119                                                                 $('clone').setAttribute('disabled','true');
120                                                                 $('remove').disabled = true;
121                                                                 $('remove').setAttribute('disabled','true');
122                                                                 $('move').disabled = true;
123                                                                 $('move').setAttribute('disabled','true');
124                                                         }
125                                                 }
126                                         }
127                                 );
128                                 $('retrieve_p').disabled = true;
129                                 $('retrieve_p').setAttribute('disabled','true');
130                                 $('clone').disabled = true;
131                                 $('clone').setAttribute('disabled','true');
132                                 $('remove').disabled = true;
133                                 $('remove').setAttribute('disabled','true');
134                                 $('move').disabled = true;
135                                 $('move').setAttribute('disabled','true');
136                                 setTimeout( function() { $('patron_list').focus(); }, 0 );
137                 }
138
139                 function refresh() {
140                         retrieve_group_members();
141                 }
142
143                 function retrieve_group_members() {
144                         try {
145                                 JSAN.use('util.functional'); JSAN.use('patron.util');
146                                 g.group_members = [];
147                                 var p = patron.util.retrieve_au_via_id(ses(),g.patron_id);
148                                 if ((p == null) || (typeof p.ilsevent != 'undefined') ) throw(p);
149                                 var robj = g.network.simple_request(
150                                         'FM_AU_LIST_RETRIEVE_VIA_GROUP.authoritative',
151                                         [ ses(), p.usrgroup() ]
152                                 );
153                                 if ((robj == null) || (typeof robj.ilsevent != 'undefined') ) throw(robj);
154                                 var ids = util.functional.filter_list( robj, function(o) { return o != g.patron_id; });
155
156                                 g.list.clear();
157
158                                 var funcs = [];
159
160                                         function gen_func(r) {
161                                                 return function() {
162                                                         g.list.append( { 'retrieve_id' : r, 'row' : {} } );
163                                                 }
164                                         }
165
166                                 funcs.push( gen_func(g.patron_id) );
167                                 for (var i = 0; i < ids.length; i++) {
168                                         funcs.push( gen_func(ids[i]) );
169                                 }
170                                 JSAN.use('util.exec'); var exec = new util.exec(4);
171                                 exec.chain( funcs );
172
173                         } catch(E) {
174                                 g.error.standard_unexpected_error_alert('Failed to retrieve all the group members.',E);
175                         }
176                 }
177
178                 function retrieve_patron() {
179                         try {
180                                 if (! g.sel_list ) return;
181                                 if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
182                                         for (var i = 0; i < g.sel_list.length; i++) {   
183                                                 try {
184                                                         var url = urls.XUL_PATRON_DISPLAY// + '?id=' + window.escape( g.sel_list[i] );
185                                                         window.xulG.new_tab(
186                                                                 url, 
187                                                                 { 'tab_name' : 'Retrieving Patron..' }, 
188                                                                 { 
189                                                                         'id' : g.sel_list[i],
190                                                                         'url_prefix' : xulG.url_prefix,
191                                                                         'new_tab' : xulG.new_tab,
192                                                                 }
193                                                         );
194                                                 } catch(E) {
195                                                         g.error.standard_unexpected_error_alert('Failed to retrieve patron.',E);
196                                                 }
197                                         }
198                                 }
199                         } catch(E) {
200                                 g.error.standard_unexpected_error_alert('Failed to retrieve patrons.',E);
201                         }
202                 }
203
204                 function clone_patron() {
205                         if (! g.sel_list ) return;
206                         try {
207                                 for (var i = 0; i < g.sel_list.length; i++) {   
208                                         var loc = xulG.url_prefix( urls.XUL_REMOTE_BROWSER ); 
209                                                 //+ '?url=' + window.escape( urls.XUL_PATRON_EDIT + '?ses=' 
210                                                 //+ window.escape( ses() ) + '&clone=' + g.sel_list[i] );
211                                         if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') xulG.new_tab(
212                                                 loc, 
213                                                 {}, 
214                                                 { 
215                                                         'url' : urls.XUL_PATRON_EDIT, // + '?ses=' + window.escape(ses()) + '&clone=' + g.sel_list[i],
216                                                         'show_print_button' : true , 
217                                                         'tab_name' : 'Register Patron Clone for Group' ,
218                                                         'passthru_content_params' : {
219                                                                 'ses' : ses(),
220                                                                 'clone' : g.sel_list[i],
221                                                                 'spawn_search' : spawn_search,
222                                                                 'spawn_editor' : spawn_editor,
223                                                                 'on_save' : function() { refresh(); },
224                                                                 'url_prefix' : xulG.url_prefix,
225                                                                 'new_tab' : xulG.new_tab,
226                                                         },
227                                                         'url_prefix' : xulG.url_prefix,
228                                                         'new_tab' : xulG.new_tab,
229                                                 }
230                                         );
231                                 }
232                         } catch(E) {
233                                 g.error.standard_unexpected_error_alert('error spawning user editors',E);
234                         }
235                 }
236
237                 function spawn_editor(p) {
238                         var url = urls.XUL_PATRON_EDIT;
239                         var passthru = {
240                                 'spawn_search' : spawn_search,
241                                 'spawn_editor' : spawn_editor,
242                                 'on_save' : function() { refresh(); },
243                                 'url_prefix' : xulG.url_prefix,
244                                 'new_tab' : xulG.new_tab,
245                         };
246                         for (var i in p) {
247                                 passthru[i] = p[i];
248                         }
249                         var loc = xulG.url_prefix( urls.XUL_REMOTE_BROWSER ); // + '?url=' + window.escape( url );
250                         if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') xulG.new_tab(
251                                 loc, 
252                                 {}, 
253                                 { 
254                                         'url' : url,
255                                         'show_print_button' : true , 
256                                         'tab_name' : 'Editing Related Patron' ,
257                                         'passthru_content_params' : passthru,
258                                         'url_prefix' : xulG.url_prefix,
259                                         'new_tab' : xulG.new_tab,
260                                 }
261                         );
262
263                 }
264
265                 function spawn_search(s) {
266                         try {
267                                 g.error.sdump('D_TRACE', 'Editor would like to search for: ' + js2JSON(s) ); 
268                                 var loc = xulG.url_prefix(urls.XUL_PATRON_DISPLAY);
269                                         //loc += '?doit=1&query=' + window.escape(js2JSON(s));
270                                 if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') 
271                                         xulG.new_tab( loc, {}, {'doit':1,'query':s} );
272                         } catch(E) {
273                                 g.error.standard_unexpected_error_alert('spawn search',E);
274                         }
275                 }
276
277                 function remove_patron() {
278                         if (! g.sel_list ) return;
279                         var msg = ''; for (var i = 0 ; i < g.sel_list.length; i++) if (g.sel_list[i] == g.patron_id) msg =
280                                 'WARNING: If you remove the currently displayed patron, a NEW group will be displayed in this interface.';
281                         var c = window.confirm('Remove selected patrons from this group?  ' + msg);
282                         if (c) {
283                                 for (var i = 0; i < g.sel_list.length; i++) {   
284                                         var robj = g.network.simple_request('FM_AU_NEW_USERGROUP', [ ses(), g.sel_list[i], get_db_true() ]);
285                                         if (typeof robj.ilsevent != 'undefined') {
286                                                 g.error.standard_unexpected_error_alert('error removing patron (id=' + g.sel_list[i] + ') from usergroup',robj);
287                                         }
288                                 }
289                                 alert('Patrons removed from group.'); 
290                                 /* FIXME - xulrunner bug if this alert comes after refresh? */
291                                 /* that's okay, because now that we're on a distributed database, we want human delay to mitigate race conditions */
292                                 refresh();
293                         } else {
294                                 alert('Patron not removed from group.');
295                         }
296                 }
297
298                 function link_patron(direction) {
299                         try {
300                                 if (! g.sel_list ) { g.sel_list = []; g.sel_list[0] = g.patron_id; }
301                                 if (direction == null) throw('null paramater not allowed');
302                                 var first_msg; var second_msg;
303                                 switch(direction) {
304                                         case true: first_msg = "-->"; break;
305                                         case false: first_msg = "<--"; break;
306                                         default: throw('Invalid parameter.  Expected boolean.'); break;
307                                 }
308                                 var barcode = window.prompt('Please scan a patron barcode:','',first_msg);
309                                 if (!barcode) return;
310                                 JSAN.use('patron.util');
311                                 var patron_b = patron.util.retrieve_fleshed_au_via_barcode(ses(),barcode);
312                                 if (typeof patron_b.ilsevent != 'undefined') throw(patron_b);
313
314                                 if (g.sel_list.length == 0) g.sel_list[0] = g.patron_id;
315                                 for (var i = 0; i < g.sel_list.length; i++) {   
316
317                                         var patron_a = patron.util.retrieve_fleshed_au_via_id(ses(),g.sel_list[i]);
318                                         if (typeof patron_a.ilsevent != 'undefined') throw(patron_a);
319                                         switch(direction) {
320                                                 case true: second_msg = "Move patron " + patron_a.card().barcode() + " into patron " + patron_b.card().barcode() + "'s usergroup..."; break;
321                                                 case false: second_msg = "Move patron " + patron_b.card().barcode() + " into patron " + patron_a.card().barcode() + "'s usergroup..."; break;
322                                         }
323
324                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
325                                         var top_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto"><description>' + second_msg + '</description><hbox><spacer flex="1"/><button label="Move" accesskey="M" name="fancy_submit"/><button label="Done" accesskey="D" name="fancy_cancel"/></hbox></vbox>';
326                                         var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical"><hbox flex="1">';
327                                         /************/
328                                         xml += '<vbox flex="1">';
329                                         xml += '<hbox><spacer flex="1"/>';
330                                         if (direction) {
331                                                 xml += '<image src="/xul/server/skin/media/images/patron_right_arrow.png"/>';
332                                         } else {
333                                                 xml += '<image src="/xul/server/skin/media/images/patron_left_arrow.png"/>';
334                                         }
335                                         xml += '</hbox>';
336                                         xml += '<iframe style="min-height: 100px" flex="1" src="' + xulG.url_prefix( urls.XUL_PATRON_SUMMARY );
337                                         xml += '?show_name=1&amp;id=' + g.sel_list[i] + '"/>';
338                                         xml += '</vbox>';
339                                         xml += '<vbox flex="1">';
340                                         xml += '<hbox>';
341                                         if (direction) {
342                                                 xml += '<image src="/xul/server/skin/media/images/patron_right_arrow.png"/>';
343                                         } else {
344                                                 xml += '<image src="/xul/server/skin/media/images/patron_left_arrow.png"/>';
345                                         }
346                                         xml += '<spacer flex="1"/></hbox>';
347                                         xml += '<iframe style="min-height: 100px" flex="1" src="' + xulG.url_prefix( urls.XUL_PATRON_SUMMARY );
348                                         xml += '?show_name=1&amp;id=' + patron_b.id() + '"/>';
349                                         xml += '</vbox>';
350                                         /************/
351                                         xml += '</hbox></vbox>';
352                                         
353                                         var bot_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto"><hbox>';
354                                         bot_xml += '</hbox></vbox>';
355                 
356                                         //g.data.temp_top = top_xml; g.data.stash('temp_top');
357                                         //g.data.temp_mid = xml; g.data.stash('temp_mid');
358                                         //g.data.temp_bot = bot_xml; g.data.stash('temp_bot');
359                                         JSAN.use('util.window'); var win = new util.window();
360                                         var fancy_prompt_data = win.open(
361                                                 urls.XUL_FANCY_PROMPT,
362                                                 //+ '?xml_in_stash=temp_mid'
363                                                 //+ '&top_xml_in_stash=temp_top'
364                                                 //+ '&bottom_xml_in_stash=temp_bot'
365                                                 //+ '&title=' + window.escape('Move Patron into a Usergroup'),
366                                                 'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
367                                                 { 'xml' : xml, 'top_xml' : top_xml, 'bottom_xml' : bot_xml, 'title' : 'Move Patron into a Usergroup' }
368                                         );
369                                         if (fancy_prompt_data.fancy_status == 'incomplete') { continue; }
370                                         else {
371                                                 var patron_c;
372                                                 switch(direction) {
373                                                         case true:
374                                                                 patron_a.usrgroup( patron_b.usrgroup() );
375                                                                 patron_a.ischanged( '1' );
376                                                                 patron_c = patron_a;
377                                                         break;
378                                                         case false:
379                                                                 patron_b.usrgroup( patron_a.usrgroup() );
380                                                                 patron_b.ischanged( '1' );
381                                                                 patron_c = patron_b;
382                                                         break;
383                                                 }
384                                                 var robj = g.network.simple_request('FM_AU_UPDATE',[ ses(), patron_c ]);
385                                                 if (typeof robj.ilsevent != 'undefined') g.error.standard_unexpected_error_alert('error linking patron (id=' + g.sel_list[i] + ')', robj);
386                                         }
387                                 }
388                                 alert('User groups updated.');
389                                 refresh();
390                         } catch(E) {
391                                 g.error.standard_unexpected_error_alert('error linking patrons',E);
392                                 refresh();
393                         }
394                 }
395
396         ]]>
397         </script>
398
399         <commandset id="info_group_cmds">
400                 <command id="clone" accesskey="N" label="Register a New Group Member by Cloning Selected Patrons" oncommand="try{clone_patron();}catch(E){alert('FIXME:'+E);}"/>
401                 <command id="remove" accesskey="R" label="Remove Selected Patrons from the Group" oncommand="try{remove_patron();}catch(E){alert('FIXME:'+E);}"/>
402                 <command id="move" accesskey="M" label="Move Selected Patrons to ANOTHER patron's group." oncommand="try{link_patron(true);}catch(E){alert('FIXME:'+E);}"/>     
403                 <command id="add" accesskey="A" label="Move ANOTHER patron to this patron group." oncommand="try{link_patron(false);}catch(E){alert('FIXME:'+E);}"/>    
404                 <command id="retrieve_p" label="Retrieve Selected Patrons" accesskey="P" oncommand="try{retrieve_patron();}catch(E){alert(E);}"/>
405         </commandset>
406
407         <popupset id="info_group_popupset">
408                 <popup id="info_group_actions" position="at_pointer"> 
409                         <menuitem command="clone" />
410                         <menuitem command="remove" />
411                         <menuitem command="move" />
412                         <menuitem command="add" />
413                         <menuitem command="retrieve_p" />
414                 </popup>
415         </popupset>
416
417     <messagecatalog id="commonStrings" src="/xul/server/locale/<!--#echo var='locale'-->/common.properties"/>
418
419         <vbox flex="1" class="my_overflow" id="group_panel">
420                 <groupbox flex="1">
421                         <caption label="Group Members"/>
422                         <hbox>
423                                 <spacer flex="1"/>
424                                 <menubar id="ml">
425                                         <menu label="Choose an Action..." accesskey="A" value="0">
426                                                 <menupopup>
427                                                         <menuitem command="clone" />
428                                                         <menuitem command="remove" />
429                                                         <menuitem command="move" />
430                                                         <menuitem command="add" />
431                                                         <menuitem command="retrieve_p" />
432                                                 </menupopup>
433                                         </menu>
434                                 </menubar>
435                         </hbox>
436                         <tree id="patron_list" flex="1" enableColumnDrag="true" seltype="multiple" context="info_group_actions"/>
437                 </groupbox>
438         </vbox>
439
440
441 </window>
442