]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/holds.js
xul_param and modal xulG conversion
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / holds.js
1 dump('entering patron.holds.js\n');
2
3 if (typeof patron == 'undefined') patron = {};
4 patron.holds = function (params) {
5
6         JSAN.use('util.error'); this.error = new util.error();
7         JSAN.use('util.network'); this.network = new util.network();
8         JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
9 }
10
11 patron.holds.prototype = {
12
13         'foreign_shelf' : null,
14
15         'retrieve_ids' : [],
16
17         'holds_map' : {},
18
19         'init' : function( params ) {
20
21                 var obj = this;
22
23                 obj.patron_id = params['patron_id'];
24                 obj.docid = params['docid'];
25                 obj.shelf = params['shelf'];
26                 obj.tree_id = params['tree_id'];
27
28                 JSAN.use('circ.util');
29                 var columns = circ.util.hold_columns( 
30                         { 
31                                 'title' : { 'hidden' : false, 'flex' : '3' },
32                                 'request_time' : { 'hidden' : false },
33                                 'pickup_lib_shortname' : { 'hidden' : false },
34                                 'hold_type' : { 'hidden' : false },
35                                 'current_copy' : { 'hidden' : false },
36                                 'capture_time' : { 'hidden' : false },
37                                 'notify_time' : { 'hidden' : false },
38                                 'notify_count' : { 'hidden' : false },
39                         } 
40                 );
41
42                 JSAN.use('util.list'); obj.list = new util.list( obj.tree_id || 'holds_list');
43                 obj.list.init(
44                         {
45                                 'columns' : columns,
46                                 'map_row_to_columns' : circ.util.std_map_row_to_columns(),
47                                 'retrieve_row' : function(params) {
48                                         var row = params.row;
49                                         try {
50                                                 obj.network.simple_request('FM_AHR_BLOB_RETRIEVE', [ ses(), row.my.hold_id ],
51                                                         function(blob_req) {
52                                                                 try {
53                                                                         var blob = blob_req.getResultObject();
54                                                                         if (typeof blob.ilsevent != 'undefined') throw(blob);
55                                                                         row.my.ahr = blob.hold;
56                                                                         row.my.status = blob.status;
57                                                                         row.my.acp = blob.copy;
58                                                                         row.my.acn = blob.volume;
59                                                                         row.my.mvr = blob.mvr;
60                                                                         row.my.patron_family_name = blob.patron_last;
61                                                                         row.my.patron_first_given_name = blob.patron_first;
62                                                                         row.my.patron_barcode = blob.patron_barcode;
63
64                                                                         var copy_id = row.my.ahr.current_copy();
65                                                                         if (typeof copy_id == 'object') {
66                                                                                 if (copy_id == null) {
67                                                                                         if (typeof row.my.acp == 'object' && row.my.acp != null) copy_id = row.my.acp.id();
68                                                                                 } else {
69                                                                                         copy_id = copy_id.id();
70                                                                                 }
71                                                                         } else {
72                                                                                 copy_id = row.my.acp.id();
73                                                                         }
74
75                                                                         obj.holds_map[ row.my.ahr.id() ] = row.my.ahr;
76                                                                         params.row_node.setAttribute('retrieve_id', 
77                                                                                 js2JSON({
78                                                                                         'copy_id':copy_id,
79                                                                                         'id':row.my.ahr.id(),
80                                                                                         'type':row.my.ahr.hold_type(),
81                                                                                         'target':row.my.ahr.target(),
82                                                                                         'usr':row.my.ahr.usr(),
83                                                                                 })
84                                                                         );
85                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
86
87                                                                 } catch(E) {
88                                                                         obj.error.standard_unexpected_error_alert('Error retrieving details for hold #' + row.my.hold_id, E);
89                                                                 }
90                                                         }
91                                                 );
92                                                 /*
93                                                 obj.network.simple_request('FM_AHR_RETRIEVE', [ ses(), row.my.hold_id ],
94                                                         function(ahr_req) {
95                                                                 try {
96                                                                         var ahr_robj = ahr_req.getResultObject();
97                                                                         if (typeof ahr_robj.ilsevent != 'undefined') throw(ahr_robj);
98                                                                         row.my.ahr = ahr_robj[0];
99                                                                         obj.holds_map[ row.my.ahr.id() ] = row.my.ahr;
100                                                                         params.row_node.setAttribute('retrieve_id', 
101                                                                                 js2JSON({
102                                                                                         'copy_id':row.my.ahr.current_copy(),
103                                                                                         'id':row.my.ahr.id(),
104                                                                                         'type':row.my.ahr.hold_type(),
105                                                                                         'target':row.my.ahr.target(),
106                                                                                         'usr':row.my.ahr.usr(),
107                                                                                 })
108                                                                         );
109
110                                                                         obj.network.simple_request('FM_AHR_STATUS',[ ses(), row.my.ahr.id() ],
111                                                                                 function(status_req) {
112                                                                                         try {
113                                                                                                 var status_robj = status_req.getResultObject();
114                                                                                                 row.my.status = status_robj;
115                                                                                                 switch(row.my.ahr.hold_type()) {
116                                                                                                         case 'M' :
117                                                                                                                 obj.network.request(
118                                                                                                                         api.MODS_SLIM_METARECORD_RETRIEVE.app,
119                                                                                                                         api.MODS_SLIM_METARECORD_RETRIEVE.method,
120                                                                                                                         [ row.my.ahr.target() ],
121                                                                                                                         function(mvr_req) {
122                                                                                                                                 row.my.mvr = mvr_req.getResultObject();
123                                                                                                                                 if ( row.my.ahr.current_copy() && ! row.my.acp) {
124                                                                                                                                         obj.network.simple_request( 'FM_ACP_RETRIEVE', [ row.my.ahr.current_copy() ],
125                                                                                                                                                 function(acp_req) {
126                                                                                                                                                         row.my.acp = acp_req.getResultObject();
127                                                                                                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
128                                                                                                                                                 }
129                                                                                                                                         );
130                                                                                                                                 } else {
131                                                                                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
132                                                                                                                                 }
133                                                                                                                         }
134                                                                                                                 );
135                                                                                                         break;
136                                                                                                         case 'T' :
137                                                                                                                 obj.network.request(
138                                                                                                                         api.MODS_SLIM_RECORD_RETRIEVE.app,
139                                                                                                                         api.MODS_SLIM_RECORD_RETRIEVE.method,
140                                                                                                                         [ row.my.ahr.target() ],
141                                                                                                                         function(mvr_req) {
142                                                                                                                                 row.my.mvr = mvr_req.getResultObject();
143                                                                                                                                 if ( row.my.ahr.current_copy() && ! row.my.acp) {
144                                                                                                                                         obj.network.simple_request( 'FM_ACP_RETRIEVE', [ row.my.ahr.current_copy() ],
145                                                                                                                                                 function(acp_req) {
146                                                                                                                                                         row.my.acp = acp_req.getResultObject();
147                                                                                                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
148                                                                                                                                                 }
149                                                                                                                                         );
150                                                                                                                                 } else {
151                                                                                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
152                                                                                                                                 }
153         
154                                                                                                                         }
155                                                                                                                 );
156                                                                                                         break;
157                                                                                                         case 'V' :
158                                                                                                                 row.my.acn = obj.network.simple_request( 'FM_ACN_RETRIEVE', [ row.my.ahr.target() ],
159                                                                                                                         function(acn_req) {
160                                                                                                                                 row.my.acn = acn_req.getResultObject();
161                                                                                                                                 obj.network.request(
162                                                                                                                                         api.MODS_SLIM_RECORD_RETRIEVE.app,
163                                                                                                                                         api.MODS_SLIM_RECORD_RETRIEVE.method,
164                                                                                                                                         [ row.my.acn.record() ],
165                                                                                                                                         function(mvr_req) {
166                                                                                                                                                 try { row.my.mvr = mvr_req.getResultObject(); } catch(E) {}
167                                                                                                                                                 if ( row.my.ahr.current_copy() && ! row.my.acp) {
168                                                                                                                                                         obj.network.simple_request( 'FM_ACP_RETRIEVE', [ row.my.ahr.current_copy() ],
169                                                                                                                                                                 function(acp_req) {
170                                                                                                                                                                         row.my.acp = acp_req.getResultObject();
171                                                                                                                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
172                                                                                                                                                                 }
173                                                                                                                                                         );
174                                                                                                                                                 } else {
175                                                                                                                                                         if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
176                                                                                                                                                 }
177                                                                                                                                         }
178                                                                                                                                 );
179                                                                                                                         }
180                                                                                                                 );
181                                                                                                         break;
182                                                                                                         case 'C' :
183                                                                                                                 obj.network.simple_request( 'FM_ACP_RETRIEVE', [ row.my.ahr.target() ],
184                                                                                                                         function(acp_req) {
185                                                                                                                                 row.my.acp = acp_req.getResultObject();
186                                                                                                                                 obj.network.simple_request( 'FM_ACN_RETRIEVE', [ typeof row.my.acp.call_number() == 'object' ? row.my.acp.call_number().id() : row.my.acp.call_number() ],
187                                                                                                                                         function(acn_req) {
188                                                                                                                                                 row.my.acn = acn_req.getResultObject();
189                                                                                                                                                 obj.network.request(
190                                                                                                                                                         api.MODS_SLIM_RECORD_RETRIEVE.app,
191                                                                                                                                                         api.MODS_SLIM_RECORD_RETRIEVE.method,
192                                                                                                                                                         [ row.my.acn.record() ],
193                                                                                                                                                         function(mvr_req) {
194                                                                                                                                                                 try { row.my.mvr = mvr_req.getResultObject(); } catch(E) {}
195                                                                                                                                                                 if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
196                                                                                                                                                         }
197                                                                                                                                                 );
198                                                                                                                                         }
199                                                                                                                                 );
200                                                                                                                         }
201                                                                                                                 );
202                                                                                                         break;
203                                                                                                 }
204                                                                                         } catch(E) {
205                                                                                                 obj.error.standard_unexpected_error_alert('Error retrieving status for hold #' + row.my.hold_id, E);
206                                                                                         }
207                                                                                 }
208                                                                         );
209                                                                 } catch(E) {
210                                                                         obj.error.standard_unexpected_error_alert('Error retrieving hold #' + row.my.hold_id, E);
211                                                                 }
212                                                         }
213                                                 );
214                                                 */
215                                         } catch(E) {
216                                                 obj.error.sdump('D_ERROR','retrieve_row: ' + E );
217                                         }
218                                         return row;
219                                 },
220                                 'on_select' : function(ev) {
221                                         JSAN.use('util.functional');
222                                         var sel = obj.list.retrieve_selection();
223                                         obj.controller.view.sel_clip.setAttribute('disabled',sel.length < 1);
224                                         obj.retrieve_ids = util.functional.map_list(
225                                                 sel,
226                                                 function(o) { return JSON2js( o.getAttribute('retrieve_id') ); }
227                                         );
228                                         if (obj.retrieve_ids.length > 0) {
229                                                 obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','false');
230                                                 obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');
231                                                 obj.controller.view.sel_copy_details.setAttribute('disabled','false');
232                                                 obj.controller.view.sel_patron.setAttribute('disabled','false');
233                                                 obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','false');
234                                                 obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','false');
235                                                 obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','false');
236                                                 obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','false');
237                                                 obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','false');
238                                                 obj.controller.view.cmd_show_notifications.setAttribute('disabled','false');
239                                                 obj.controller.view.cmd_holds_retarget.setAttribute('disabled','false');
240                                                 obj.controller.view.cmd_holds_cancel.setAttribute('disabled','false');
241                                                 obj.controller.view.cmd_show_catalog.setAttribute('disabled','false');
242                                         } else {
243                                                 obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','true');
244                                                 obj.controller.view.sel_mark_items_missing.setAttribute('disabled','true');
245                                                 obj.controller.view.sel_copy_details.setAttribute('disabled','true');
246                                                 obj.controller.view.sel_patron.setAttribute('disabled','true');
247                                                 obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','true');
248                                                 obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','true');
249                                                 obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','true');
250                                                 obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','true');
251                                                 obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','true');
252                                                 obj.controller.view.cmd_show_notifications.setAttribute('disabled','true');
253                                                 obj.controller.view.cmd_holds_retarget.setAttribute('disabled','true');
254                                                 obj.controller.view.cmd_holds_cancel.setAttribute('disabled','true');
255                                                 obj.controller.view.cmd_show_catalog.setAttribute('disabled','true');
256                                         }
257                                 },
258
259                         }
260                 );
261                 
262                 JSAN.use('util.controller'); obj.controller = new util.controller();
263                 obj.controller.init(
264                         {
265                                 'control_map' : {
266                                         'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
267                                         'sel_clip' : [
268                                                 ['command'],
269                                                 function() { obj.list.clipboard(); }
270                                         ],
271                                         'cmd_broken' : [
272                                                 ['command'],
273                                                 function() { alert('Not Yet Implemented'); }
274                                         ],
275                                         'sel_patron' : [
276                                                 ['command'],
277                                                 function() {
278                                                         JSAN.use('circ.util');
279                                                         circ.util.show_last_few_circs(obj.retrieve_ids);
280                                                 }
281                                         ],
282                                         'sel_mark_items_damaged' : [
283                                                 ['command'],
284                                                 function() {
285                                                         JSAN.use('cat.util'); JSAN.use('util.functional');
286                                                         cat.util.mark_item_damaged( util.functional.map_list( obj.retrieve_ids, function(o) { return o.copy_id; } ) );
287                                                 }
288                                         ],
289                                         'sel_mark_items_missing' : [
290                                                 ['command'],
291                                                 function() {
292                                                         JSAN.use('cat.util'); JSAN.use('util.functional');
293                                                         cat.util.mark_item_missing( util.functional.map_list( obj.retrieve_ids, function(o) { return o.copy_id; } ) );
294                                                 }
295                                         ],
296                                         'sel_copy_details' : [
297                                                 ['command'],
298                                                 function() {
299                                                         JSAN.use('circ.util');
300                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
301                                                                 if (obj.retrieve_ids[i].copy_id) circ.util.show_copy_details( obj.retrieve_ids[i].copy_id );
302                                                         }
303                                                 }
304                                         ],
305                                         'cmd_holds_print' : [
306                                                 ['command'],
307                                                 function() {
308                                                         try {
309                                                                 dump(js2JSON(obj.list.dump_with_keys()) + '\n');
310                                                                 function flesh_callback() {
311                                                                         try {
312                                                                                 JSAN.use('patron.util');
313                                                                                 var params = { 
314                                                                                         'patron' : patron.util.retrieve_au_via_id(ses(),obj.patron_id), 
315                                                                                         'lib' : obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ],
316                                                                                         'staff' : obj.data.list.au[0],
317                                                                                         'header' : obj.data.print_list_templates.holds.header,
318                                                                                         'line_item' : obj.data.print_list_templates.holds.line_item,
319                                                                                         'footer' : obj.data.print_list_templates.holds.footer,
320                                                                                         'type' : obj.data.print_list_templates.holds.type,
321                                                                                         'list' : obj.list.dump_with_keys(),
322                                                                                 };
323                                                                                 JSAN.use('util.print'); var print = new util.print();
324                                                                                 print.tree_list( params );
325                                                                                 setTimeout(function(){obj.list.on_all_fleshed = null;},0);
326                                                                         } catch(E) {
327                                                                                 obj.error.standard_unexpected_error_alert('print 2',E);
328                                                                         }
329                                                                 }
330                                                                 obj.list.on_all_fleshed = flesh_callback;
331                                                                 obj.list.full_retrieve();
332                                                         } catch(E) {
333                                                                 obj.error.standard_unexpected_error_alert('print 1',E);
334                                                         }
335                                                 }
336                                         ],
337                                         'cmd_holds_export' : [
338                                                 ['command'],
339                                                 function() {
340                                                         try {
341                                                                 function flesh_callback() {
342                                                                         try {
343                                                                                 dump(obj.list.dump_csv() + '\n');
344                                                                                 copy_to_clipboard(obj.list.dump_csv());
345                                                                                 setTimeout(function(){obj.list.on_all_fleshed = null;},0);
346                                                                         } catch(E) {
347                                                                                 obj.error.standard_unexpected_error_alert('export 2',E);
348                                                                         }
349                                                                 }
350                                                                 obj.list.on_all_fleshed = flesh_callback;
351                                                                 obj.list.full_retrieve();
352                                                         } catch(E) {
353                                                                 obj.error.standard_unexpected_error_alert('export 1',E);
354                                                         }
355                                                 }
356                                         ],
357
358                                         'cmd_show_notifications' : [
359                                                 ['command'],
360                                                 function() {
361                                                         try {
362                                                                 JSAN.use('util.window'); var win = new util.window();
363                                                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
364                                                                         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
365                                                                         win.open(
366                                                                                 xulG.url_prefix(urls.XUL_HOLD_NOTICES), // + '?ahr_id=' + obj.retrieve_ids[i].id,
367                                                                                 'hold_notices_' + obj.retrieve_ids[i].id,
368                                                                                 'chrome,resizable',
369                                                                                 { 'ahr_id' : obj.retrieve_ids[i].id }
370                                                                         );
371                                                                 }
372                                                         } catch(E) {
373                                                                 obj.error.standard_unexpected_error_alert('Error rendering/retrieving hold notifications.',E);
374                                                         }
375                                                 }
376                                         ],
377                                         'cmd_holds_edit_selection_depth' : [
378                                                 ['command'],
379                                                 function() {
380                                                         try {
381                                                                 JSAN.use('util.widgets'); JSAN.use('util.functional'); 
382                                                                 var ws_type = obj.data.hash.aout[ obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ].ou_type() ];
383                                                                 var list = util.functional.map_list(
384                                                                         util.functional.filter_list(    
385                                                                                 obj.data.list.aout,
386                                                                                 function(o) {
387                                                                                         if (o.depth() > ws_type.depth()) return false;
388                                                                                         if (o.depth() < ws_type.depth()) return true;
389                                                                                         return (o.id() == ws_type.id());
390                                                                                 }
391                                                                         ),
392                                                                         function(o) { 
393                                                                                 return [
394                                                                                         o.opac_label(),
395                                                                                         o.id(),
396                                                                                         false,
397                                                                                         ( o.depth() * 2),
398                                                                                 ]; 
399                                                                         }
400                                                                 );
401                                                                 ml = util.widgets.make_menulist( list, obj.data.list.au[0].ws_ou() );
402                                                                 ml.setAttribute('id','selection');
403                                                                 ml.setAttribute('name','fancy_data');
404                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
405                                                                 xml += '<description>Please choose a Hold Range:</description>';
406                                                                 xml += util.widgets.serialize_node(ml);
407                                                                 xml += '</vbox>';
408                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
409                                                                 bot_xml += '<spacer flex="1"/><button label="Done" accesskey="D" name="fancy_submit"/>';
410                                                                 bot_xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
411                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
412                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
413                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
414                                                                 JSAN.use('util.window'); var win = new util.window();
415                                                                 var fancy_prompt_data = win.open(
416                                                                         urls.XUL_FANCY_PROMPT,
417                                                                         //+ '?xml_in_stash=temp_mid'
418                                                                         //+ '&bottom_xml_in_stash=temp_bot'
419                                                                         //+ '&title=' + window.escape('Choose a Pick Up Library'),
420                                                                         'fancy_prompt', 'chrome,resizable,modal',
421                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Choose a Pick Up Library' }
422                                                                 );
423                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
424                                                                 var selection = fancy_prompt_data.selection;
425                                                                 var msg = 'Are you sure you would like to change the Hold Range for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + ' to "' + obj.data.hash.aout[selection].opac_label() + '"?';
426                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
427                                                                 if (r == 0) {
428                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
429                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
430                                                                                 hold.selection_depth( obj.data.hash.aout[selection].depth() ); hold.ischanged('1');
431                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
432                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
433                                                                         }
434                                                                         obj.retrieve();
435                                                                 }
436                                                         } catch(E) {
437                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
438                                                         }
439                                                 }
440                                         ],
441
442                                         'cmd_holds_edit_pickup_lib' : [
443                                                 ['command'],
444                                                 function() {
445                                                         try {
446                                                                 JSAN.use('util.widgets'); JSAN.use('util.functional'); 
447                                                                 var list = util.functional.map_list(
448                                                                         obj.data.list.aou,
449                                                                         function(o) { 
450                                                                                 var sname = o.shortname(); for (i = sname.length; i < 20; i++) sname += ' ';
451                                                                                 return [
452                                                                                         o.name() ? sname + ' ' + o.name() : o.shortname(),
453                                                                                         o.id(),
454                                                                                         ( obj.data.hash.aout[ o.ou_type() ].can_have_users() == 0),
455                                                                                         ( obj.data.hash.aout[ o.ou_type() ].depth() * 2),
456                                                                                 ]; 
457                                                                         }
458                                                                 );
459                                                                 ml = util.widgets.make_menulist( list, obj.data.list.au[0].ws_ou() );
460                                                                 ml.setAttribute('id','lib');
461                                                                 ml.setAttribute('name','fancy_data');
462                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
463                                                                 xml += '<description>Please choose a new Pickup Library:</description>';
464                                                                 xml += util.widgets.serialize_node(ml);
465                                                                 xml += '</vbox>';
466                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
467                                                                 bot_xml += '<spacer flex="1"/><button label="Done" accesskey="D" name="fancy_submit"/>';
468                                                                 bot_xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
469                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
470                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
471                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
472                                                                 JSAN.use('util.window'); var win = new util.window();
473                                                                 var fancy_prompt_data = win.open(
474                                                                         urls.XUL_FANCY_PROMPT,
475                                                                         //+ '?xml_in_stash=temp_mid'
476                                                                         //+ '&bottom_xml_in_stash=temp_bot'
477                                                                         //+ '&title=' + window.escape('Choose a Pick Up Library'),
478                                                                         'fancy_prompt', 'chrome,resizable,modal',
479                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Choose a Pick Up Library' }
480                                                                 );
481                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
482                                                                 var pickup_lib = fancy_prompt_data.lib;
483                                                                 var msg = 'Are you sure you would like to change the Pick Up Lib for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + ' to ' + obj.data.hash.aou[pickup_lib].shortname() + '?';
484                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
485                                                                 if (r == 0) {
486                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
487                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
488                                                                                 hold.pickup_lib(  pickup_lib ); hold.ischanged('1');
489                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
490                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
491                                                                         }
492                                                                         obj.retrieve();
493                                                                 }
494                                                         } catch(E) {
495                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
496                                                         }
497                                                 }
498                                         ],
499                                         'cmd_holds_edit_phone_notify' : [
500                                                 ['command'],
501                                                 function() {
502                                                         try {
503                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
504                                                                 xml += '<description>Please enter a new phone number for hold notification (leave the field empty to disable phone notification):</description>';
505                                                                 xml += '<textbox id="phone" name="fancy_data"/>';
506                                                                 xml += '</vbox>';
507                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
508                                                                 bot_xml += '<spacer flex="1"/><button label="Done" accesskey="D" name="fancy_submit"/>';
509                                                                 bot_xml += '<button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
510                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
511                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
512                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
513                                                                 JSAN.use('util.window'); var win = new util.window();
514                                                                 var fancy_prompt_data = win.open(
515                                                                         urls.XUL_FANCY_PROMPT,
516                                                                         //+ '?xml_in_stash=temp_mid'
517                                                                         //+ '&bottom_xml_in_stash=temp_bot'
518                                                                         //+ '&title=' + window.escape('Choose a Hold Notification Phone Number')
519                                                                         //+ '&focus=phone',
520                                                                         'fancy_prompt', 'chrome,resizable,modal',
521                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Choose a Hold Notification Phone Number', 'focus' : 'phone' }
522                                                                 );
523                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
524                                                                 var phone = fancy_prompt_data.phone;
525                                                                 var msg = 'Are you sure you would like to change the Notification Phone Number for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + ' to "' + phone + '"?';
526                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
527                                                                 if (r == 0) {
528                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
529                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
530                                                                                 hold.phone_notify(  phone ); hold.ischanged('1');
531                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
532                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
533                                                                         }
534                                                                         obj.retrieve();
535                                                                 }
536                                                         } catch(E) {
537                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
538                                                         }
539                                                 }
540                                         ],
541                                         'cmd_holds_edit_email_notify' : [
542                                                 ['command'],
543                                                 function() {
544                                                         try {
545                                                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
546                                                                 xml += '<description>Send email notifications (when appropriate)?  The email address used is found in the hold recepient account.</description>';
547                                                                 xml += '<hbox><button value="email" label="Email" accesskey="E" name="fancy_submit"/>';
548                                                                 xml += '<button value="noemail" label="No Email" accesskey="N" name="fancy_submit"/></hbox>';
549                                                                 xml += '</vbox>';
550                                                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
551                                                                 bot_xml += '<spacer flex="1"/><button label="Cancel" accesskey="C" name="fancy_cancel"/></hbox>';
552                                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
553                                                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
554                                                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
555                                                                 JSAN.use('util.window'); var win = new util.window();
556                                                                 var fancy_prompt_data = win.open(
557                                                                         urls.XUL_FANCY_PROMPT,
558                                                                         //+ '?xml_in_stash=temp_mid'
559                                                                         //+ '&bottom_xml_in_stash=temp_bot'
560                                                                         //+ '&title=' + window.escape('Set Email Notification for Holds'),
561                                                                         'fancy_prompt', 'chrome,resizable,modal',
562                                                                         { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : 'Set Email Notification for Holds' }
563                                                                 );
564                                                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
565                                                                 var email = fancy_prompt_data.fancy_submit == 'email' ? get_db_true() : get_db_false();
566                                                                 var msg = 'Are you sure you would like ' + ( get_bool( email ) ? 'enable' : 'disable' ) + ' email notification for hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '?';
567                                                                 var r = obj.error.yns_alert(msg,'Modifying Holds','Yes','No',null,'Check here to confirm this message');
568                                                                 if (r == 0) {
569                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
570                                                                                 var hold = obj.holds_map[ obj.retrieve_ids[i].id ];
571                                                                                 hold.email_notify(  email ); hold.ischanged('1');
572                                                                                 var robj = obj.network.simple_request('FM_AHR_UPDATE',[ ses(), hold ]);
573                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
574                                                                         }
575                                                                         obj.retrieve();
576                                                                 }
577                                                         } catch(E) {
578                                                                 obj.error.standard_unexpected_error_alert('Holds not likely modified.',E);
579                                                         }
580                                                 }
581                                         ],
582
583
584                                         'cmd_holds_retarget' : [
585                                                 ['command'],
586                                                 function() {
587                                                         try {
588                                                                 JSAN.use('util.functional');
589                                                                 var msg = 'Are you sure you would like to reset hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '?';
590                                                                 var r = obj.error.yns_alert(msg,'Resetting Holds','Yes','No',null,'Check here to confirm this message');
591                                                                 if (r == 0) {
592                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
593                                                                                 var robj = obj.network.simple_request('FM_AHR_RESET',[ ses(), obj.retrieve_ids[i].id]);
594                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
595                                                                         }
596                                                                         obj.retrieve();
597                                                                 }
598                                                         } catch(E) {
599                                                                 obj.error.standard_unexpected_error_alert('Holds not likely reset.',E);
600                                                         }
601
602                                                 }
603                                         ],
604
605                                         'cmd_holds_cancel' : [
606                                                 ['command'],
607                                                 function() {
608                                                         try {
609                                                                 JSAN.use('util.functional');
610                                                                 var msg = 'Are you sure you would like to cancel hold' + ( obj.retrieve_ids.length > 1 ? 's ' : ' ') + util.functional.map_list( obj.retrieve_ids, function(o){return o.id;}).join(', ') + '?';
611                                                                 var r = obj.error.yns_alert(msg,'Cancelling Holds','Yes','No',null,'Check here to confirm this message');
612                                                                 if (r == 0) {
613                                                                         for (var i = 0; i < obj.retrieve_ids.length; i++) {
614                                                                                 var robj = obj.network.simple_request('FM_AHR_CANCEL',[ ses(), obj.retrieve_ids[i].id]);
615                                                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
616                                                                         }
617                                                                         obj.retrieve();
618                                                                 }
619                                                         } catch(E) {
620                                                                 obj.error.standard_unexpected_error_alert('Holds not likely cancelled.',E);
621                                                         }
622                                                 }
623                                         ],
624                                         'cmd_retrieve_patron' : [
625                                                 ['command'],
626                                                 function() {
627                                                         try {
628                                                                 var seen = {};
629                                                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
630                                                                         var patron_id = obj.retrieve_ids[i].usr;
631                                                                         if (seen[patron_id]) continue; seen[patron_id] = true;
632                                                                         xulG.new_tab(
633                                                                                 xulG.url_prefix(urls.XUL_PATRON_DISPLAY), // + '?id=' + patron_id, 
634                                                                                 {}, 
635                                                                                 { 'id' : patron_id }
636                                                                         );
637                                                                 }
638                                                         } catch(E) {
639                                                                 obj.error.standard_unexpected_error_alert('',E);
640                                                         }
641                                                 }
642                                         ],
643                                         'cmd_show_catalog' : [
644                                                 ['command'],
645                                                 function() {
646                                                         try {
647                                                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
648                                                                         var htarget = obj.retrieve_ids[i].target;
649                                                                         var htype = obj.retrieve_ids[i].type;
650                                                                         var opac_url;
651                                                                         switch(htype) {
652                                                                                 case 'M' :
653                                                                                         opac_url = xulG.url_prefix( urls.opac_rresult ) + '?m=' + htarget;
654                                                                                 break;
655                                                                                 case 'T' : 
656                                                                                         opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + htarget;
657                                                                                 break;
658                                                                                 case 'V' :
659                                                                                         var my_acn = obj.network.simple_request( 'FM_ACN_RETRIEVE', [ htarget ]);
660                                                                                         opac_url = xulG.url_prefix( urls.opac_rdetail) + '?r=' + my_acn.record();
661                                                                                 break;
662                                                                                 case 'C' :
663                                                                                         var my_acp = obj.network.simple_request( 'FM_ACP_RETRIEVE', [ htarget ]);
664                                                                                         var my_acn;
665                                                                                         if (typeof my_acp.call_number() == 'object') {
666                                                                                                 my_acn = my.acp.call_number();
667                                                                                         } else {
668                                                                                                 my_acn = obj.network.simple_request( 'FM_ACN_RETRIEVE', 
669                                                                                                         [ my_acp.call_number() ]);
670                                                                                         }
671                                                                                         opac_url = xulG.url_prefix( urls.opac_rdetail) + '?r=' + my_acn.record();
672                                                                                 break;
673                                                                                 default:
674                                                                                         obj.error.standard_unexpected_error_alert("I don't understand the hold type of " + htype + ", so I can't jump to the appropriate record in the catalog.", obj.retrieve_ids[i]);
675                                                                                         continue;
676                                                                                 break;
677                                                                         }
678                                                                         var content_params = { 
679                                                                                 'session' : ses(),
680                                                                                 'authtime' : ses('authtime'),
681                                                                                 'opac_url' : opac_url,
682                                                                         };
683                                                                         xulG.new_tab(
684                                                                                 xulG.url_prefix(urls.XUL_OPAC_WRAPPER), 
685                                                                                 {'tab_name': htype == 'M' ? 'Catalog' : 'Retrieving title...'}, 
686                                                                                 content_params
687                                                                         );
688                                                                 }
689                                                         } catch(E) {
690                                                                 obj.error.standard_unexpected_error_alert('',E);
691                                                         }
692                                                 }
693                                         ],
694                                 }
695                         }
696                 );
697                 obj.controller.render();
698
699                 obj.retrieve();
700
701                 obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','true');
702                 obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','true');
703                 obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','true');
704                 obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','true');
705                 obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','true');
706                 obj.controller.view.cmd_show_notifications.setAttribute('disabled','true');
707                 obj.controller.view.cmd_holds_retarget.setAttribute('disabled','true');
708                 obj.controller.view.cmd_holds_cancel.setAttribute('disabled','true');
709                 obj.controller.view.cmd_show_catalog.setAttribute('disabled','true');
710         },
711
712         'retrieve' : function(dont_show_me_the_list_change) {
713                 var obj = this;
714                 if (window.xulG && window.xulG.holds) {
715                         obj.holds = window.xulG.holds;
716                 } else {
717                         var method; var params = [ ses() ];
718                         if (obj.patron_id) {                 /*************************************************** PATRON ******************************/
719                                 method = 'FM_AHR_ID_LIST_RETRIEVE_VIA_AU'; 
720                                 params.push( obj.patron_id ); 
721                                 obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','true');
722                         } else if (obj.docid) {                 /*************************************************** RECORD ******************************/
723                                 method = 'FM_AHR_RETRIEVE_ALL_VIA_BRE'; 
724                                 params.push( obj.docid ); 
725                                 obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
726                         } else if (obj.pull) {                 /*************************************************** PULL ******************************/
727                                 method = 'FM_AHR_ID_LIST_PULL_LIST'; 
728                                 params.push( 50 ); params.push( 0 );
729                         } else if (obj.shelf) {
730                                 method = 'FM_AHR_ID_LIST_ONSHELF_RETRIEVE';                  /*************************************************** HOLD SHELF ******************************/
731                                 params.push( obj.foreign_shelf || obj.data.list.au[0].ws_ou() ); 
732                                 obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
733                                 obj.render_lib_menu();
734                         } else {
735                                 //method = 'FM_AHR_RETRIEVE_VIA_PICKUP_AOU'; 
736                                 method = 'FM_AHR_ID_LIST_PULL_LIST';                  /*************************************************** PULL ******************************/
737                                 params.push( 50 ); params.push( 0 );
738                                 obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
739                         }
740                         var robj = obj.network.simple_request( method, params );
741                         if (typeof robj.ilsevent != 'undefined') throw(robj);
742                         if (method == 'FM_AHR_RETRIEVE_ALL_VIA_BRE') {
743                                 obj.holds = [];
744                                 obj.holds = obj.holds.concat( robj.copy_holds );
745                                 obj.holds = obj.holds.concat( robj.volume_holds );
746                                 obj.holds = obj.holds.concat( robj.title_holds );
747                                 obj.holds = obj.holds.sort();
748                         } else {
749                                 obj.holds = robj;
750                         }
751                         //alert('method = ' + method + ' params = ' + js2JSON(params));
752                 }
753
754                 function list_append(hold_id) {
755                         obj.list.append(
756                                 {
757                                         'row' : {
758                                                 'my' : {
759                                                         'hold_id' : hold_id,
760                                                 }
761                                         }
762                                 }
763                         );
764                 }
765
766                 function gen_list_append(hold) {
767                         return function() {
768                                 if (typeof obj.controller.view.lib_menu == 'undefined') {
769                                         list_append(typeof hold == 'object' ? hold.id() : hold);
770                                 } else {
771                                         /*
772                                         var pickup_lib = hold.pickup_lib();
773                                         if (typeof pickup_lib == 'object') pickup_lib = pickup_lib.id();
774                                         if (pickup_lib == obj.controller.view.lib_menu.value) {
775                                         */
776                                                 list_append(typeof hold == 'object' ? hold.id() : hold);
777                                         /*
778                                         }
779                                         */
780                                 }
781                         };
782                 }
783
784                 obj.list.clear();
785
786                 //alert('obj.holds = ' + js2JSON(obj.holds));
787                 JSAN.use('util.exec'); var exec = new util.exec(2);
788                 var rows = [];
789                 for (var i in obj.holds) {
790                         rows.push( gen_list_append(obj.holds[i]) );
791                 }
792                 exec.chain( rows );
793         
794                 if (!dont_show_me_the_list_change) {
795                         if (window.xulG && typeof window.xulG.on_list_change == 'function') {
796                                 try { window.xulG.on_list_change(obj.holds); } catch(E) { this.error.sdump('D_ERROR',E); }
797                         }
798                 }
799         },
800
801         'render_lib_menu' : function() {
802                 try {
803                         var obj = this;
804                         JSAN.use('util.widgets'); JSAN.use('util.functional'); JSAN.use('util.fm_utils');
805                         var x = document.getElementById('menu_placeholder');
806                         if (x.firstChild) return;
807                         util.widgets.remove_children( x );
808         
809                         var ml = util.widgets.make_menulist( 
810                                 util.functional.map_list( 
811                                         obj.data.list.my_aou.concat(
812                                                 util.functional.filter_list(
813                                                         util.fm_utils.find_ou(
814                                                                 obj.data.tree.aou,
815                                                                 obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ].parent_ou()
816                                                         ).children(),
817                                                         function(o) {
818                                                                 return o.id() != obj.data.list.au[0].ws_ou();
819                                                         }
820                                                 )
821                                         ),
822                                         function(o) { return [ 
823                                                 o.shortname(), 
824                                                 o.id(), 
825                                                 ( ! get_bool( obj.data.hash.aout[ o.ou_type() ].can_have_users() ) ),
826                                                 ( obj.data.hash.aout[ o.ou_type() ].depth() ),
827                                         ]; }
828                                 ).sort(
829                                         function( a, b ) {
830                                                 var A = obj.data.hash.aou[ a[1] ];
831                                                 var B = obj.data.hash.aou[ b[1] ];
832                                                 var X = obj.data.hash.aout[ A.ou_type() ];
833                                                 var Y = obj.data.hash.aout[ B.ou_type() ];
834                                                 if (X.depth() < Y.depth()) return -1;
835                                                 if (X.depth() > Y.depth()) return 1;
836                                                 if (A.shortname() < B.shortname()) return -1;
837                                                 if (A.shortname() > B.shortname()) return 1;
838                                                 return 0;
839                                         }
840                                 ),
841                                 obj.data.list.au[0].ws_ou()
842                         );
843                         x.appendChild( ml );
844                         ml.addEventListener(
845                                 'command',
846                                 function(ev) {
847                                         /*
848                                         obj.list.on_all_fleshed = function() {
849                                                 obj.list.clear();
850                                                 obj.foreign_shelf = ev.target.value;
851                                                 obj.retrieve();
852                                                 setTimeout( function() { obj.list.on_all_fleshed = null; }, 0);
853                                         };
854                                         obj.list.full_retrieve();
855                                         */
856                                         obj.list.clear();
857                                         obj.foreign_shelf = ev.target.value;
858                                         obj.retrieve();
859                                 },
860                                 false
861                         );
862                         obj.controller.view.lib_menu = ml;
863                 } catch(E) {
864                         this.error.standard_unexpected_error_alert('rendering lib menu',E);
865                 }
866         },
867 }
868
869 dump('exiting patron.holds.js\n');