]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/holds.js
List columns for hold cancel reason, cancel note, and cancel time. Display them...
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / holds.js
1 dump('entering patron.holds.js\n');
2
3 function $(id) { return document.getElementById(id); }
4
5 if (typeof patron == 'undefined') patron = {};
6 patron.holds = function (params) {
7
8     JSAN.use('util.error'); this.error = new util.error();
9     JSAN.use('util.network'); this.network = new util.network();
10     JSAN.use('OpenILS.data'); this.data = new OpenILS.data(); this.data.init({'via':'stash'});
11 }
12
13 patron.holds.prototype = {
14
15     'hold_interface_type' : null,
16
17     'pull_from_shelf_interface' : {
18         '_default' : { 'limit' : 50, 'offset' : 0 },
19         'current' : { 'limit' : 50, 'offset' : 0 }
20     },
21
22     'filter_lib' : null,
23
24     'retrieve_ids' : [],
25
26     'holds_map' : {},
27
28     'flatten_copy' : function(hold) {
29         try { if ( hold.current_copy() && typeof hold.current_copy() == 'object') hold.current_copy( hold.current_copy().id() ); } catch(E) { alert('FIXME: Error flattening hold before hold update: ' + E); }
30         return hold;
31     },
32
33     'init' : function( params ) {
34
35         var obj = this;
36
37         obj.patron_id = params['patron_id'];
38         obj.patron_barcode = params['patron_barcode'];
39         obj.docid = params['docid'];
40         obj.shelf = params['shelf'];
41         obj.tree_id = params['tree_id'];
42
43         var progressmeter = document.getElementById('progress');
44
45         JSAN.use('circ.util');
46         var columns = circ.util.hold_columns(
47             {
48                 'title' : { 'hidden' : false, 'flex' : '3' },
49                 'request_time' : { 'hidden' : false },
50                 'pickup_lib_shortname' : { 'hidden' : false },
51                 'hold_type' : { 'hidden' : false },
52                 'current_copy' : { 'hidden' : false },
53                 'capture_time' : { 'hidden' : false },
54                 'notify_time' : { 'hidden' : false },
55                 'notify_count' : { 'hidden' : false },
56                 'cancel_cause' : { 'hidden' : ! ( obj.data.hash.aous['circ.holds.canceled.display_count'] || obj.data.hash.aous['circ.holds.canceled.display_age'] ) },
57                 'cancel_note' : { 'hidden' :  ! ( obj.data.hash.aous['circ.holds.canceled.display_count'] || obj.data.hash.aous['circ.holds.canceled.display_age'] ) },
58                 'cancel_time' : { 'hidden' :  ! ( obj.data.hash.aous['circ.holds.canceled.display_count'] || obj.data.hash.aous['circ.holds.canceled.display_age'] ) }
59             }
60         );
61
62         JSAN.use('util.list'); obj.list = new util.list( obj.tree_id || 'holds_list');
63         obj.list.init(
64             {
65                 'columns' : columns,
66                 'map_row_to_columns' : circ.util.std_map_row_to_columns(),
67                 'retrieve_row' : function(params) {
68                     var row = params.row;
69                     try {
70                         obj.network.simple_request('FM_AHR_BLOB_RETRIEVE.authoritative', [ ses(), row.my.hold_id ],
71                             function(blob_req) {
72                                 try {
73                                     var blob = blob_req.getResultObject();
74                                     if (typeof blob.ilsevent != 'undefined') throw(blob);
75                                     row.my.ahr = blob.hold;
76                                     row.my.status = blob.status;
77                                                                         row.my.ahr.status( blob.status );
78                                     row.my.acp = blob.copy;
79                                     row.my.acn = blob.volume;
80                                     row.my.mvr = blob.mvr;
81                                     row.my.patron_family_name = blob.patron_last;
82                                     row.my.patron_first_given_name = blob.patron_first;
83                                     row.my.patron_barcode = blob.patron_barcode;
84                                                                         row.my.total_holds = blob.total_holds;
85                                                                         row.my.queue_position = blob.queue_position;
86                                                                         row.my.potential_copies = blob.potential_copies;
87                                                                         row.my.estimated_wait = blob.estimated_wait;
88                                                                         row.my.ahrn_count = blob.hold.notes().length;
89
90                                     var copy_id = row.my.ahr.current_copy();
91                                     if (typeof copy_id == 'object') {
92                                         if (copy_id == null) {
93                                             if (typeof row.my.acp == 'object' && row.my.acp != null) copy_id = row.my.acp.id();
94                                         } else {
95                                             copy_id = copy_id.id();
96                                         }
97                                     } else {
98                                         copy_id = row.my.acp.id();
99                                     }
100
101                                     obj.holds_map[ row.my.ahr.id() ] = blob;
102                                     params.row_node.setAttribute('retrieve_id',
103                                         js2JSON({
104                                             'copy_id':copy_id,
105                                                                                         'barcode':row.my.acp ? row.my.acp.barcode() : null,
106                                             'id':row.my.ahr.id(),
107                                             'type':row.my.ahr.hold_type(),
108                                             'target':row.my.ahr.target(),
109                                             'usr':row.my.ahr.usr()
110                                         })
111                                     );
112                                     if (typeof params.on_retrieve == 'function') { params.on_retrieve(row); }
113
114                                 } catch(E) {
115                                     obj.error.standard_unexpected_error_alert($("patronStrings").getFormattedString('staff.patron.holds.init.hold_num_error', [row.my.hold_id]), E);
116                                 }
117                             }
118                         );
119                     } catch(E) {
120                         obj.error.sdump('D_ERROR','retrieve_row: ' + E );
121                     }
122                     return row;
123                 },
124                 'on_select' : function(ev) {
125                     JSAN.use('util.functional');
126                     var sel = obj.list.retrieve_selection();
127                     obj.controller.view.sel_clip.setAttribute('disabled',sel.length < 1);
128                     obj.retrieve_ids = util.functional.map_list(
129                         sel,
130                         function(o) { return JSON2js( o.getAttribute('retrieve_id') ); }
131                     );
132                     if (obj.retrieve_ids.length > 0) {
133                         obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','false');
134                         obj.controller.view.sel_mark_items_missing.setAttribute('disabled','false');
135                         obj.controller.view.sel_copy_details.setAttribute('disabled','false');
136                         obj.controller.view.sel_patron.setAttribute('disabled','false');
137                         obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','false');
138                         obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','false');
139                         obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','false');
140                         obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','false');
141                         obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','false');
142                         obj.controller.view.cmd_holds_edit_expire_time.setAttribute('disabled','false');
143                         obj.controller.view.cmd_holds_edit_thaw_date.setAttribute('disabled','false');
144                         obj.controller.view.cmd_holds_activate.setAttribute('disabled','false');
145                         obj.controller.view.cmd_holds_suspend.setAttribute('disabled','false');
146                         obj.controller.view.cmd_alt_view.setAttribute('disabled','false');
147                         obj.controller.view.cmd_holds_retarget.setAttribute('disabled','false');
148                         obj.controller.view.cmd_holds_cancel.setAttribute('disabled','false');
149                         obj.controller.view.cmd_show_catalog.setAttribute('disabled','false');
150                     } else {
151                         obj.controller.view.sel_mark_items_damaged.setAttribute('disabled','true');
152                         obj.controller.view.sel_mark_items_missing.setAttribute('disabled','true');
153                         obj.controller.view.sel_copy_details.setAttribute('disabled','true');
154                         obj.controller.view.sel_patron.setAttribute('disabled','true');
155                         obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','true');
156                         obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','true');
157                         obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','true');
158                         obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','true');
159                         obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','true');
160                         obj.controller.view.cmd_holds_edit_expire_time.setAttribute('disabled','true');
161                         obj.controller.view.cmd_holds_edit_thaw_date.setAttribute('disabled','true');
162                         obj.controller.view.cmd_holds_activate.setAttribute('disabled','true');
163                         obj.controller.view.cmd_holds_suspend.setAttribute('disabled','true');
164                         obj.controller.view.cmd_alt_view.setAttribute('disabled','true');
165                         obj.controller.view.cmd_holds_retarget.setAttribute('disabled','true');
166                         obj.controller.view.cmd_holds_cancel.setAttribute('disabled','true');
167                         obj.controller.view.cmd_show_catalog.setAttribute('disabled','true');
168                     }
169                 }
170             }
171         );
172
173         JSAN.use('util.controller'); obj.controller = new util.controller();
174         obj.controller.init(
175             {
176                 'control_map' : {
177                     'save_columns' : [ [ 'command' ], function() { obj.list.save_columns(); } ],
178                     'sel_clip' : [
179                         ['command'],
180                         function() { obj.list.clipboard(); }
181                     ],
182                     'cmd_broken' : [
183                         ['command'],
184                         function() { alert($("commonStrings").getString('common.unimplemented')); }
185                     ],
186                     'sel_patron' : [
187                         ['command'],
188                         function() {
189                             JSAN.use('circ.util');
190                             circ.util.show_last_few_circs(obj.retrieve_ids);
191                         }
192                     ],
193                     'alt_view_btn' : [
194                         ['render'],
195                         function(e) {
196                             e.setAttribute('label', document.getElementById("circStrings").getString('staff.circ.holds.alt_view.label'));
197                             e.setAttribute('accesskey', document.getElementById("circStrings").getString('staff.circ.holds.alt_view.accesskey'));
198                         }
199                     ],
200                     'cmd_alt_view' : [
201                         ['command'],
202                         function(ev) {
203                             try {
204                                 var n = obj.controller.view.alt_view_btn;
205                                 if (n.getAttribute('toggle') == '1') {
206                                     document.getElementById('deck').selectedIndex = 0;
207                                     n.setAttribute('toggle','0');
208                                     n.setAttribute('label', document.getElementById("circStrings").getString('staff.circ.holds.alt_view.label'));
209                                     n.setAttribute('accesskey', document.getElementById("circStrings").getString('staff.circ.holds.alt_view.accesskey'));
210                                 } else {
211                                     document.getElementById('deck').selectedIndex = 1;
212                                     n.setAttribute('toggle','1');
213                                     n.setAttribute('label', document.getElementById("circStrings").getString('staff.circ.holds.list_view.label'));
214                                     n.setAttribute('accesskey', document.getElementById("circStrings").getString('staff.circ.holds.list_view.accesskey'));
215                                     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
216                                     if (obj.retrieve_ids.length == 0) return;
217                                     var f = obj.browser.get_content();
218                                     xulG.ahr_id = obj.retrieve_ids[0].id;
219                                     xulG.blob = obj.holds_map[ xulG.ahr_id ];
220                                     xulG.patron_rendered_elsewhere = (obj.hold_interface_type == 'patron');
221                                     xulG.bib_rendered_elsewhere = (obj.hold_interface_type == 'record');
222                                     f.xulG = xulG;
223                                     f.fetch_and_render_all();
224                                 }
225                             } catch(E) {
226                                 alert('Error in holds.js, cmd_alt_view handler: ' + E);
227                             }
228                         },
229                     ],
230                     'sel_mark_items_damaged' : [
231                         ['command'],
232                         function() {
233                             JSAN.use('cat.util'); JSAN.use('util.functional');
234                             cat.util.mark_item_damaged( util.functional.map_list( obj.retrieve_ids, function(o) { return o.copy_id; } ) );
235                         }
236                     ],
237                     'sel_mark_items_missing' : [
238                         ['command'],
239                         function() {
240                             JSAN.use('cat.util'); JSAN.use('util.functional');
241                             cat.util.mark_item_missing( util.functional.map_list( obj.retrieve_ids, function(o) { return o.copy_id; } ) );
242                         }
243                     ],
244                     'sel_copy_details' : [
245                         ['command'],
246                         function() {
247                             JSAN.use('circ.util');
248                             for (var i = 0; i < obj.retrieve_ids.length; i++) {
249                                 if (obj.retrieve_ids[i].copy_id) circ.util.show_copy_details( obj.retrieve_ids[i].copy_id );
250                             }
251                         }
252                     ],
253
254                     'cmd_holds_print' : [
255                         ['command'],
256                         function() {
257                             try {
258                                 JSAN.use('patron.util');
259                                 var params = {
260                                     'patron' : patron.util.retrieve_au_via_id(ses(),obj.patron_id),
261                                     'template' : 'holds'
262                                 };
263                                 obj.list.print(params);
264                             } catch(E) {
265                                 obj.error.standard_unexpected_error_alert('print 1',E);
266                             }
267                         }
268                     ],
269                     'cmd_csv_to_clipboard' : [ ['command'], function() { obj.list.dump_csv_to_clipboard(); } ],
270                     'cmd_csv_to_printer' : [ ['command'], function() { obj.list.dump_csv_to_printer(); } ],
271                     'cmd_csv_to_file' : [ ['command'], function() { obj.list.dump_csv_to_file( { 'defaultFileName' : 'holds.txt' } ); } ],
272
273                     'cmd_holds_edit_selection_depth' : [
274                         ['command'],
275                         function() {
276                             try {
277                                 JSAN.use('util.widgets'); JSAN.use('util.functional');
278                                 var ws_type = obj.data.hash.aout[ obj.data.hash.aou[ obj.data.list.au[0].ws_ou() ].ou_type() ];
279                                 var list = util.functional.map_list(
280                                     util.functional.filter_list(
281                                         obj.data.list.aout,
282                                         function(o) {
283                                             if (o.depth() > ws_type.depth()) return false;
284                                             if (o.depth() < ws_type.depth()) return true;
285                                             return (o.id() == ws_type.id());
286                                         }
287                                     ),
288                                     function(o) {
289                                         return [
290                                             o.opac_label(),
291                                             o.id(),
292                                             false,
293                                             ( o.depth() * 2),
294                                         ];
295                                     }
296                                 );
297                                 ml = util.widgets.make_menulist( list, obj.data.list.au[0].ws_ou() );
298                                 ml.setAttribute('id','selection');
299                                 ml.setAttribute('name','fancy_data');
300                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
301                                 xml += '<description>' + $("patronStrings").getString('staff.patron.holds.holds_edit_selection_depth.choose_hold_range') + '</description>';
302                                 xml += util.widgets.serialize_node(ml);
303                                 xml += '</vbox>';
304                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
305                                 bot_xml += '<spacer flex="1"/><button label="'+ $("patronStrings").getString('staff.patron.holds.holds_edit_selection_depth.done.label') +'"';
306                                 bot_xml += 'accesskey="'+ $("patronStrings").getString('staff.patron.holds.holds_edit_selection_depth.done.accesskey') +'" name="fancy_submit"/>';
307                                 bot_xml += '<button label="'+ $("patronStrings").getString('staff.patron.holds.holds_edit_selection_depth.cancel.label') +'"';
308                                 bot_xml += 'accesskey="'+ $("patronStrings").getString('staff.patron.holds.holds_edit_selection_depth.cancel.accesskey') +'" name="fancy_cancel"/></hbox>';
309                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
310                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
311                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
312                                 JSAN.use('util.window'); var win = new util.window();
313                                 var fancy_prompt_data = win.open(
314                                     urls.XUL_FANCY_PROMPT,
315                                     //+ '?xml_in_stash=temp_mid'
316                                     //+ '&bottom_xml_in_stash=temp_bot'
317                                     //+ '&title=' + window.escape('Choose a Pick Up Library'),
318                                     'fancy_prompt', 'chrome,resizable,modal',
319                                     { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : $("patronStrings").getString('staff.patron.holds.holds_edit_selection_depth.choose_library') }
320                                 );
321                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
322                                 var selection = fancy_prompt_data.selection;
323
324                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
325                                 var msg = '';
326                                 if(obj.retrieve_ids.length > 1) {
327                                     msg = $("patronStrings").getformattedString('staff.patron.holds.holds_edit_selection_depth.modify_holds_message.plural', [hold_list.join(', '), obj.data.hash.aout[selection].opac_label()])
328                                 } else {
329                                     msg = $("patronStrings").getformattedString('staff.patron.holds.holds_edit_selection_depth.modify_holds_message.singular', [hold_list.join(', '), obj.data.hash.aout[selection].opac_label()])
330                                 }
331
332                                 var r = obj.error.yns_alert(msg,
333                                         $("patronStrings").getString('staff.patron.holds.holds_edit_selection_depth.modify_holds_title'),
334                                         $("commonStrings").getString('common.yes'),
335                                         $("commonStrings").getString('common.no'),
336                                         null,
337                                         $("commonStrings").getString('common.check_to_confirm')
338                                 );
339                                 if (r == 0) {
340                                     circ.util.batch_hold_update(hold_list, { 'selection_depth' : obj.data.hash.aout[selection].depth() }, { 'progressmeter' : progressmeter, 'oncomplete' :  function() { obj.clear_and_retrieve(true); } });
341                                 }
342                             } catch(E) {
343                                 obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.holds.holds_not_modified'),E);
344                             }
345                         }
346                     ],
347
348                     'cmd_holds_edit_pickup_lib' : [
349                         ['command'],
350                         function() {
351                             try {
352                                 JSAN.use('util.widgets'); JSAN.use('util.functional');
353
354                                 var deny_edit_because_of_transit = false;
355                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
356                                     var hold = obj.holds_map[ obj.retrieve_ids[i].id ].hold;
357                                     if (hold.status() == 3 /* In-Transit */) deny_edit_because_of_transit = true;
358                                 }
359                                 if (deny_edit_because_of_transit) {
360                                     alert(document.getElementById('circStrings').getString('staff.circ.holds.error.may_not_edit_pickup_lib_for_hold_intransit'));
361                                     return;
362                                 }
363
364                                 var list = util.functional.map_list(
365                                     obj.data.list.aou,
366                                     function(o) {
367                                         var sname = o.shortname(); for (i = sname.length; i < 20; i++) sname += ' ';
368                                         return [
369                                             o.name() ? sname + ' ' + o.name() : o.shortname(),
370                                             o.id(),
371                                             ( obj.data.hash.aout[ o.ou_type() ].can_have_users() == 0),
372                                             ( obj.data.hash.aout[ o.ou_type() ].depth() * 2),
373                                         ];
374                                     }
375                                 );
376                                 ml = util.widgets.make_menulist( list, obj.data.list.au[0].ws_ou() );
377                                 ml.setAttribute('id','lib');
378                                 ml.setAttribute('name','fancy_data');
379                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
380                                 xml += '<description>'+$("patronStrings").getString('staff.patron.holds.holds_edit_pickup_lib.new_pickup_lib.description')+'</description>';
381                                 xml += util.widgets.serialize_node(ml);
382                                 xml += '</vbox>';
383                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
384                                 bot_xml += '<spacer flex="1"/><button label="'+ $("patronStrings").getString('staff.patron.holds.holds_edit_pickup_lib.done.label') +'"';
385                                 bot_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.holds.holds_edit_pickup_lib.done.accesskey')+'" name="fancy_submit"/>';
386                                 bot_xml += '<button label="'+$("patronStrings").getString('staff.patron.holds.holds_edit_pickup_lib.cancel.label')+'"';
387                                 bot_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.holds.holds_edit_pickup_lib.cancel.accesskey')+'" name="fancy_cancel"/></hbox>';
388                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
389                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
390                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
391                                 JSAN.use('util.window'); var win = new util.window();
392                                 var fancy_prompt_data = win.open(
393                                     urls.XUL_FANCY_PROMPT,
394                                     //+ '?xml_in_stash=temp_mid'
395                                     //+ '&bottom_xml_in_stash=temp_bot'
396                                     //+ '&title=' + window.escape('Choose a Pick Up Library'),
397                                     'fancy_prompt', 'chrome,resizable,modal',
398                                     { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : $("patronStrings").getString('staff.patron.holds.holds_edit_pickup_lib.choose_lib') }
399                                 );
400                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
401                                 var pickup_lib = fancy_prompt_data.lib;
402
403                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
404                                 var msg = '';
405                                 if(obj.retrieve_ids.length > 1) {
406                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_pickup_lib.change_pickup_lib_message.plural',[hold_list.join(', '), obj.data.hash.aou[pickup_lib].shortname()]);
407                                 } else {
408                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_pickup_lib.change_pickup_lib_message.singular',[hold_list.join(', '), obj.data.hash.aou[pickup_lib].shortname()]);
409                                 }
410                                 var r = obj.error.yns_alert(msg,
411                                         $("patronStrings").getString('staff.patron.holds.holds_edit_pickup_lib.change_pickup_lib_title'),
412                                         $("commonStrings").getString('common.yes'),
413                                         $("commonStrings").getString('common.no'),
414                                         null,
415                                         $("commonStrings").getString('common.check_to_confirm')
416                                 );
417                                 if (r == 0) {
418                                     circ.util.batch_hold_update(hold_list, { 'pickup_lib' : pickup_lib }, { 'progressmeter' : progressmeter, 'oncomplete' :  function() { obj.clear_and_retrieve(true); } });
419                                 }
420                             } catch(E) {
421                                 obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.holds.holds_not_modified'),E);
422                             }
423                         }
424                     ],
425                     'cmd_holds_edit_phone_notify' : [
426                         ['command'],
427                         function() {
428                             try {
429                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
430                                 xml += '<description>'+$("patronStrings").getString('staff.patron.holds.holds_edit_phone_notify.new_phone_number')+'</description>';
431                                 xml += '<textbox id="phone" name="fancy_data" context="clipboard"/>';
432                                 xml += '</vbox>';
433                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
434                                 bot_xml += '<spacer flex="1"/><button label="'+$("patronStrings").getString('staff.patron.holds.holds_edit_phone_notify.btn_done.label')+'"';
435                                 bot_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.holds.holds_edit_phone_notify.btn_done.accesskey')+'" name="fancy_submit"/>';
436                                 bot_xml += '<button label="'+$("patronStrings").getString('staff.patron.holds.holds_edit_phone_notify.btn_cancel.label')+'"';
437                                 bot_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.holds.holds_edit_phone_notify.btn_cancel.accesskey')+'" name="fancy_cancel"/></hbox>';
438                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
439                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
440                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
441                                 JSAN.use('util.window'); var win = new util.window();
442                                 var fancy_prompt_data = win.open(
443                                     urls.XUL_FANCY_PROMPT,
444                                     //+ '?xml_in_stash=temp_mid'
445                                     //+ '&bottom_xml_in_stash=temp_bot'
446                                     //+ '&title=' + window.escape('Choose a Hold Notification Phone Number')
447                                     //+ '&focus=phone',
448                                     'fancy_prompt', 'chrome,resizable,modal',
449                                     { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : $("patronStrings").getString('staff.patron.holds.holds_edit_phone_notify.choose_phone_number'), 'focus' : 'phone' }
450                                 );
451                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
452                                 var phone = fancy_prompt_data.phone;
453
454                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
455                                 var msg = '';
456                                 if(obj.retrieve_ids.length > 1) {
457                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_phone_notify.confirm_phone_number_change.plural',[hold_list.join(', '), phone]);
458                                 } else {
459                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_phone_notify.confirm_phone_number_change.singular',[hold_list.join(', '), phone]);
460                                 }
461                                 var r = obj.error.yns_alert(msg,
462                                         $("patronStrings").getString('staff.patron.holds.holds_edit_phone_notify.modifying_holds_title'),
463                                         $("commonStrings").getString('common.yes'),
464                                         $("commonStrings").getString('common.no'),
465                                         null,
466                                         $("commonStrings").getString('common.check_to_confirm')
467                                 );
468                                 if (r == 0) {
469                                     circ.util.batch_hold_update(hold_list, { 'phone_notify' : phone }, { 'progressmeter' : progressmeter, 'oncomplete' :  function() { obj.clear_and_retrieve(true); } });
470                                 }
471                             } catch(E) {
472                                 obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.holds.holds_not_modified'),E);
473                             }
474                         }
475                     ],
476                     'cmd_holds_edit_email_notify' : [
477                         ['command'],
478                         function() {
479                             try {
480                                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
481                                 xml += '<description>'+$("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.description')+'</description>';
482                                 xml += '<hbox><button value="email" label="'+$("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.btn_email.label')+'"';
483                                 xml += ' accesskey="'+$("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.btn_email.accesskey')+'" name="fancy_submit"/>';
484                                 xml += '<button value="noemail" label="'+$("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.btn_no_email.label')+'"';
485                                 xml += '  accesskey="'+$("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.btn_no_email.accesskey')+'" name="fancy_submit"/></hbox>';
486                                 xml += '</vbox>';
487                                 var bot_xml = '<hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: vertical">';
488                                 bot_xml += '<spacer flex="1"/><button label="'+$("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.btn_cancel.label')+'"';
489                                 bot_xml += ' accesskey="'+$("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.btn_cancel.accesskey')+'" name="fancy_cancel"/></hbox>';
490                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
491                                 //obj.data.temp_mid = xml; obj.data.stash('temp_mid');
492                                 //obj.data.temp_bot = bot_xml; obj.data.stash('temp_bot');
493                                 JSAN.use('util.window'); var win = new util.window();
494                                 var fancy_prompt_data = win.open(
495                                     urls.XUL_FANCY_PROMPT,
496                                     //+ '?xml_in_stash=temp_mid'
497                                     //+ '&bottom_xml_in_stash=temp_bot'
498                                     //+ '&title=' + window.escape('Set Email Notification for Holds'),
499                                     'fancy_prompt', 'chrome,resizable,modal',
500                                     { 'xml' : xml, 'bottom_xml' : bot_xml, 'title' : $("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.set_notifs') }
501                                 );
502                                 if (fancy_prompt_data.fancy_status == 'incomplete') { return; }
503                                 var email = fancy_prompt_data.fancy_submit == 'email' ? get_db_true() : get_db_false();
504
505                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
506                                 var msg = '';
507                                 if(get_bool(email)) {
508                                     if(obj.retrieve_ids.length > 1) {
509                                         msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_email_notify.enable_email.plural', [hold_list.join(', ')]);
510                                     } else {
511                                         msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_email_notify.enable_email.singular', [hold_list.join(', ')]);
512                                     }
513                                 } else {
514                                     if(obj.retrieve_ids.length > 1) {
515                                         msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_email_notify.disable_email.plural', [hold_list.join(', ')]);
516                                     } else {
517                                         msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_edit_email_notify.disable_email.singular', [hold_list.join(', ')]);
518                                     }
519                                 }
520
521                                 var r = obj.error.yns_alert(msg,
522                                         $("patronStrings").getString('staff.patron.holds.holds_edit_email_notify.mod_holds_title'),
523                                         $("commonStrings").getString('common.yes'),
524                                         $("commonStrings").getString('common.no'),
525                                         null,
526                                         $("commonStrings").getString('common.check_to_confirm')
527                                 );
528                                 if (r == 0) {
529                                     circ.util.batch_hold_update(hold_list, { 'email_notify' : email }, { 'progressmeter' : progressmeter, 'oncomplete' :  function() { obj.clear_and_retrieve(true); } });
530                                 }
531                             } catch(E) {
532                                 obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.holds.holds_not_modified'),E);
533                             }
534                         }
535                     ],
536                     'cmd_holds_suspend' : [
537                         ['command'],
538                         function() {
539                             try {
540                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
541                                 var r = obj.error.yns_alert(
542                                     obj.retrieve_ids.length > 1 ?
543                                     document.getElementById('circStrings').getFormattedString('staff.circ.holds.suspend.prompt.plural',[hold_list.join(', ')]) :
544                                     document.getElementById('circStrings').getFormattedString('staff.circ.holds.suspend.prompt',[hold_list.join(', ')]),
545                                     document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds'),
546                                     document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds.yes'),
547                                     document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds.no'),
548                                     null,
549                                     document.getElementById('commonStrings').getString('common.confirm')
550                                 );
551                                 if (r == 0) {
552                                     var already_suspended = []; var filtered_hold_list = [];
553                                     for (var i = 0; i < obj.retrieve_ids.length; i++) {
554                                         var hold = obj.holds_map[ obj.retrieve_ids[i].id ].hold;
555                                         if ( get_bool( hold.frozen() ) ) {
556                                             already_suspended.push( hold.id() );
557                                             continue;
558                                         }
559                                         filtered_hold_list.push( hold.id() );
560                                     }
561                                     circ.util.batch_hold_update(filtered_hold_list, { 'frozen' : 't', 'thaw_date' : null }, { 'progressmeter' : progressmeter, 'oncomplete' :  function() { 
562                                         if (already_suspended.length == 1) {
563                                             alert( document.getElementById('circStrings').getFormattedString('staff.circ.holds.already_suspended',[already_suspended[0]]) );
564                                         } else if (already_suspended.length > 1) {
565                                             alert( document.getElementById('circStrings').getFormattedString('staff.circ.holds.already_suspended.plural',[already_suspended.join(', ')]) );
566                                         }
567                                         obj.clear_and_retrieve(true); 
568                                     } });
569                                 }
570                             } catch(E) {
571                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.holds.unexpected_error.not_likely_suspended'),E);
572                             }
573                         }
574                     ],
575                     'cmd_holds_activate' : [
576                         ['command'],
577                         function() {
578                             try {
579                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
580                                 var r = obj.error.yns_alert(
581                                     obj.retrieve_ids.length > 1 ?
582                                     document.getElementById('circStrings').getFormattedString('staff.circ.holds.activate.prompt.plural',[hold_list.join(', ')]) :
583                                     document.getElementById('circStrings').getFormattedString('staff.circ.holds.activate.prompt',[hold_list.join(', ')]),
584                                     document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds'),
585                                     document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds.yes'),
586                                     document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds.no'),
587                                     null,
588                                     document.getElementById('commonStrings').getString('common.confirm')
589                                 );
590                                 if (r == 0) {
591                                     var already_activated = []; var filtered_hold_list = [];
592                                     for (var i = 0; i < obj.retrieve_ids.length; i++) {
593                                         var hold = obj.holds_map[ obj.retrieve_ids[i].id ].hold;
594                                         if ( ! get_bool( hold.frozen() ) ) {
595                                             already_activated.push( hold.id() );
596                                             continue;
597                                         }
598                                         filtered_hold_list.push( hold.id() );
599                                     }
600                                     circ.util.batch_hold_update(filtered_hold_list, { 'frozen' : 'f', 'thaw_date' : null }, { 'progressmeter' : progressmeter, 'oncomplete' :  function() { 
601                                         if (already_activated.length == 1) {
602                                             alert( document.getElementById('circStrings').getFormattedString('staff.circ.holds.already_activated',[already_activated[0]]) );
603                                         } else if (already_activated.length > 1) {
604                                             alert( document.getElementById('circStrings').getFormattedString('staff.circ.holds.already_activated.plural',[already_activated.join(', ')]) );
605                                         }
606                                         obj.clear_and_retrieve(true); 
607                                     } });
608                                 }
609                             } catch(E) {
610                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.holds.unexpected_error.not_likely_activated'),E);
611                             }
612                         }
613                     ],
614                     'cmd_holds_edit_thaw_date' : [
615                         ['command'],
616                         function() {
617                             try {
618                                 JSAN.use('util.date');
619                                 function check_date(value) {
620                                     try {
621                                         if (! util.date.check('YYYY-MM-DD',value) ) { throw(document.getElementById('circStrings').getString('staff.circ.holds.activation_date.invalid_date')); }
622                                         if (util.date.check_past('YYYY-MM-DD',value) || util.date.formatted_date(new Date(),'%F') == value ) {
623                                             throw(document.getElementById('circStrings').getString('staff.circ.holds.activation_date.too_early.error'));
624                                         }
625                                         return true;
626                                     } catch(E) {
627                                         alert(E);
628                                         return false;
629                                     }
630                                 }
631
632                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
633                                 var msg_singular = document.getElementById('circStrings').getFormattedString('staff.circ.holds.activation_date.prompt',[hold_list.join(', ')]);
634                                 var msg_plural = document.getElementById('circStrings').getFormattedString('staff.circ.holds.activation_date.prompt',[hold_list.join(', ')]);
635                                 var msg = obj.retrieve_ids.length > 1 ? msg_plural : msg_singular;
636                                 var value = 'YYYY-MM-DD';
637                                 var title = document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds');
638                                 var thaw_date; var invalid = true;
639                                 while(invalid) {
640                                     thaw_date = window.prompt(msg,value,title);
641                                     if (thaw_date) {
642                                         invalid = ! check_date(thaw_date);
643                                     } else {
644                                         invalid = false;
645                                     }
646                                 }
647                                 if (thaw_date || thaw_date == '') {
648                                     circ.util.batch_hold_update(
649                                         hold_list, 
650                                         { 'frozen' : 't', 'thaw_date' : thaw_date == '' ? null : util.date.formatted_date(thaw_date + ' 00:00:00','%{iso8601}') }, 
651                                         { 'progressmeter' : progressmeter, 'oncomplete' :  function() { obj.clear_and_retrieve(true); } }
652                                     );
653                                 }
654                             } catch(E) {
655                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.holds.unexpected_error.not_likely_modified'),E);
656                             }
657                         }
658                     ],
659                     'cmd_holds_edit_expire_time' : [
660                         ['command'],
661                         function() {
662                             try {
663                                 JSAN.use('util.date');
664                                 function check_date(value) {
665                                     try {
666                                         if (! util.date.check('YYYY-MM-DD',value) ) { throw(document.getElementById('circStrings').getString('staff.circ.holds.expire_time.invalid_date')); }
667                                         if (util.date.check_past('YYYY-MM-DD',value) || util.date.formatted_date(new Date(),'%F') == value ) {
668                                             throw(document.getElementById('circStrings').getString('staff.circ.holds.expire_time.too_early.error'));
669                                         }
670                                         return true;
671                                     } catch(E) {
672                                         alert(E);
673                                         return false;
674                                     }
675                                 }
676
677                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
678                                 var msg_singular = document.getElementById('circStrings').getFormattedString('staff.circ.holds.expire_time.prompt',[hold_list.join(', ')]);
679                                 var msg_plural = document.getElementById('circStrings').getFormattedString('staff.circ.holds.expire_time.prompt',[hold_list.join(', ')]);
680                                 var msg = obj.retrieve_ids.length > 1 ? msg_plural : msg_singular;
681                                 var value = 'YYYY-MM-DD';
682                                 var title = document.getElementById('circStrings').getString('staff.circ.holds.modifying_holds');
683                                 var expire_time; var invalid = true;
684                                 while(invalid) {
685                                     expire_time = window.prompt(msg,value,title);
686                                     if (expire_time) {
687                                         invalid = ! check_date(expire_time);
688                                     } else {
689                                         invalid = false;
690                                     }
691                                 }
692                                 if (expire_time || expire_time == '') {
693                                     circ.util.batch_hold_update(
694                                         hold_list, 
695                                         { 'expire_time' : expire_time == '' ? null : util.date.formatted_date(expire_time + ' 00:00:00','%{iso8601}') }, 
696                                         { 'progressmeter' : progressmeter, 'oncomplete' :  function() { obj.clear_and_retrieve(true); } }
697                                     );
698                                 }
699                             } catch(E) {
700                                 obj.error.standard_unexpected_error_alert(document.getElementById('circStrings').getString('staff.circ.holds.unexpected_error.not_likely_modified'),E);
701                             }
702                         }
703                     ],
704
705
706
707                     'cmd_holds_retarget' : [
708                         ['command'],
709                         function() {
710                             try {
711                                 JSAN.use('util.functional');
712
713                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
714                                 var msg = '';
715                                 if(obj.retrieve_ids.length > 1) {
716                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_retarget.reset_hold_message.plural',[hold_list.join(', ')]);
717                                 } else {
718                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_retarget.reset_hold_message.singular',[hold_list.join(', ')]);
719                                 }
720                                 var r = obj.error.yns_alert(msg,
721                                         $("patronStrings").getString('staff.patron.holds.holds_retarget.reset_hold_title'),
722                                         $("commonStrings").getString('common.yes'),
723                                         $("commonStrings").getString('common.no'),
724                                         null,
725                                         $("commonStrings").getString('common.check_to_confirm')
726                                 );
727                                 if (r == 0) {
728                                     for (var i = 0; i < obj.retrieve_ids.length; i++) {
729                                         var robj = obj.network.simple_request('FM_AHR_RESET',[ ses(), obj.retrieve_ids[i].id]);
730                                         if (typeof robj.ilsevent != 'undefined') throw(robj);
731                                     }
732                                     obj.clear_and_retrieve();
733                                 }
734                             } catch(E) {
735                                 obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.holds.holds_retarget.holds_not_reset'),E);
736                             }
737
738                         }
739                     ],
740
741                     'cmd_holds_cancel' : [
742                         ['command'],
743                         function() {
744                             try {
745                                 JSAN.use('util.functional');
746
747                                 var hold_list = util.functional.map_list(obj.retrieve_ids, function(o){return o.id;});
748                                 var msg = '';
749                                 if(obj.retrieve_ids.length > 1 ) {
750                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_cancel.cancel_hold_message.plural', [hold_list.join(', ')]);
751                                 } else {
752                                     msg = $("patronStrings").getFormattedString('staff.patron.holds.holds_cancel.cancel_hold_message.singular', [hold_list.join(', ')]);
753                                 }
754
755                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
756                                 JSAN.use('util.window');
757                                 var win = new util.window();
758                                 var my_xulG = win.open(
759                                     urls.XUL_HOLD_CANCEL,
760                                     'hold_cancel',
761                                     'chrome,resizable,modal',
762                                     {}
763                                 );
764                                 /*var r = obj.error.yns_alert(msg,
765                                         $("patronStrings").getString('staff.patron.holds.holds_cancel.cancel_hold_title'),
766                                         $("commonStrings").getString('common.yes'),
767                                         $("commonStrings").getString('common.no'),
768                                         null,
769                                         $("commonStrings").getString('common.check_to_confirm')
770                                 );*/
771
772                                 if (my_xulG.proceed) { 
773                                     var transits = [];
774                                     for (var i = 0; i < obj.retrieve_ids.length; i++) {
775                                         if (obj.holds_map[ obj.retrieve_ids[i].id ].hold.transit()) {
776                                             transits.push( obj.retrieve_ids[i].barcode );
777                                         }
778                                         var robj = obj.network.simple_request('FM_AHR_CANCEL',[ ses(), obj.retrieve_ids[i].id, my_xulG.cancel_reason, my_xulG.note]);
779                                         if (typeof robj.ilsevent != 'undefined') throw(robj);
780                                     }
781                                     if (transits.length > 0) {
782                                         var msg2 = $("patronStrings").getFormattedString('staff.patron.holds.holds_cancel.cancel_for_barcodes', [transits.join(', ')]);
783                                         var r2 = obj.error.yns_alert(msg2,
784                                             $("patronStrings").getString('staff.patron.holds.holds_cancel.cancel_for_barcodes.title'),
785                                             $("commonStrings").getString('common.yes'),
786                                             $("commonStrings").getString('common.no'),
787                                             null,
788                                             $("commonStrings").getString('common.check_to_confirm'));
789                                         if (r2 == 0) {
790                                             try {
791                                                 for (var i = 0; i < transits.length; i++) {
792                                                     var robj = obj.network.simple_request('FM_ATC_VOID',[ ses(), { 'barcode' : transits[i] } ]);
793                                                     if (typeof robj.ilsevent != 'undefined') {
794                                                         switch(Number(robj.ilsevent)) {
795                                                             case 1225 /* TRANSIT_ABORT_NOT_ALLOWED */ :
796                                                                 alert(robj.desc);
797                                                             break;
798                                                             case 5000 /* PERM_FAILURE */ :
799                                                             break;
800                                                             default:
801                                                                 throw(robj);
802                                                             break;
803                                                         }
804                                                     }
805                                                 }
806                                             } catch(E) {
807                                                obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.holds.holds_cancel.hold_transits_not_cancelled'),E);
808                                             }
809                                         }
810                                     }
811                                     obj.clear_and_retrieve();
812                                 }
813                             } catch(E) {
814                                 obj.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.holds.holds_cancel.hold_not_cancelled'),E);
815                             }
816                         }
817                     ],
818                     'cmd_retrieve_patron' : [
819                         ['command'],
820                         function() {
821                             try {
822                                 var seen = {};
823                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
824                                     var patron_id = obj.retrieve_ids[i].usr;
825                                     if (seen[patron_id]) continue; seen[patron_id] = true;
826                                     xulG.new_patron_tab(
827                                         {},
828                                         { 'id' : patron_id }
829                                     );
830                                 }
831                             } catch(E) {
832                                 obj.error.standard_unexpected_error_alert('',E);
833                             }
834                         }
835                     ],
836                     'cmd_show_catalog' : [
837                         ['command'],
838                         function() {
839                             try {
840                                 for (var i = 0; i < obj.retrieve_ids.length; i++) {
841                                     var htarget = obj.retrieve_ids[i].target;
842                                     var htype = obj.retrieve_ids[i].type;
843                                     var opac_url;
844                                     switch(htype) {
845                                         case 'M' :
846                                             opac_url = xulG.url_prefix( urls.opac_rresult ) + '?m=' + htarget;
847                                         break;
848                                         case 'T' :
849                                             opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + htarget;
850                                         break;
851                                         case 'V' :
852                                             var my_acn = obj.network.simple_request( 'FM_ACN_RETRIEVE.authoritative', [ htarget ]);
853                                             opac_url = xulG.url_prefix( urls.opac_rdetail) + '?r=' + my_acn.record();
854                                         break;
855                                         case 'C' :
856                                             var my_acp = obj.network.simple_request( 'FM_ACP_RETRIEVE', [ htarget ]);
857                                             var my_acn;
858                                             if (typeof my_acp.call_number() == 'object') {
859                                                 my_acn = my.acp.call_number();
860                                             } else {
861                                                 my_acn = obj.network.simple_request( 'FM_ACN_RETRIEVE.authoritative',
862                                                     [ my_acp.call_number() ]);
863                                             }
864                                             opac_url = xulG.url_prefix( urls.opac_rdetail) + '?r=' + my_acn.record();
865                                         break;
866                                         default:
867                                             obj.error.standard_unexpected_error_alert($("patronStrings").getFormattedString('staff.patron.holds.show_catalog.unknown_htype', [htype]), obj.retrieve_ids[i]);
868                                             continue;
869                                         break;
870                                     }
871                                     var content_params = {
872                                         'session' : ses(),
873                                         'authtime' : ses('authtime'),
874                                         'opac_url' : opac_url
875                                     };
876                                     xulG.new_tab(
877                                         xulG.url_prefix(urls.XUL_OPAC_WRAPPER),
878                                         {'tab_name': htype == 'M' ? 'Catalog' : $("patronStrings").getString('staff.patron.holds.show_catalog.retrieving_title') },
879                                         content_params
880                                     );
881                                 }
882                             } catch(E) {
883                                 obj.error.standard_unexpected_error_alert('',E);
884                             }
885                         }
886                     ],
887                     'fetch_more' : [
888                         ['command'],
889                         function() {
890                             obj.pull_from_shelf_interface.current.offset += obj.pull_from_shelf_interface.current.limit;
891                             obj.retrieve(true);
892                         }
893                     ],
894                     'lib_filter_checkbox' : [
895                         ['command'],
896                         function(ev) {
897                             var x_lib_type_menu = document.getElementById('lib_type_menu');
898                             if (x_lib_type_menu) x_lib_type_menu.disabled = ! ev.target.checked;
899                             if (obj.controller.view.lib_menu) obj.controller.view.lib_menu.disabled = ! ev.target.checked;
900                             obj.clear_and_retrieve();
901                             ev.target.setAttribute('checked',ev.target.checked);
902                         }
903                     ],
904                     'cmd_search_opac' : [
905                         ['command'],
906                         function(ev) {
907                             try {
908                                 var content_params = {
909                                     'show_nav_buttons' : false,
910                                     'show_print_button' : true,
911                                     'passthru_content_params' : {
912                                         'authtoken' : ses(),
913                                         'authtime' : ses('authtime'),
914                                         'window_open' : function(a,b,c) {
915                                             try {
916                                                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
917                                                 return window.open(a,b,c);
918                                             } catch(E) {
919                                                 obj.error.standard_unexpected_error_alert('window_open',E);
920                                             }
921                                         },
922                                         'opac_hold_placed' : function(hold) {
923                                             try {
924                                                 obj.list.append(
925                                                     {
926                                                         'row' : {
927                                                             'my' : {
928                                                                 'hold_id' : typeof hold == 'object' ? hold.id() : hold
929                                                             }
930                                                         }
931                                                     }
932                                                 );
933                                                 if (window.xulG && typeof window.xulG.on_list_change == 'function') {
934                                                     window.xulG.on_list_change(); 
935                                                 }
936                                             } catch(E) {
937                                                 obj.error.standard_unexpected_error_alert('holds.js, opac_hold_placed(): ',E);
938                                             }
939                                         },
940                                         'patron_barcode' : obj.patron_barcode
941                                     },
942                                     'url_prefix' : xulG.url_prefix,
943                                     'url' : xulG.url_prefix( urls.browser )
944                                 };
945                                 xulG.display_window.g.patron.right_deck.set_iframe( urls.XUL_REMOTE_BROWSER + '?patron_hold=1', {}, content_params);
946                             } catch(E) {
947                                 obj.error.sdump('D_ERROR','cmd_search_opac: ' + E);
948                             }
949
950                         }
951                     ]
952                 }
953             }
954         );
955
956         obj.determine_hold_interface_type();
957         var x_fetch_more = document.getElementById('fetch_more');
958         var x_lib_type_menu = document.getElementById('lib_type_menu');
959         var x_lib_menu_placeholder = document.getElementById('lib_menu_placeholder');
960         var x_lib_filter_checkbox = document.getElementById('lib_filter_checkbox');
961         switch(obj.hold_interface_type) {
962             case 'shelf':
963                 obj.render_lib_menus({'pickup_lib':true});
964                 if (x_lib_type_menu) x_lib_type_menu.hidden = false;
965                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = false;
966             break;
967             case 'pull' :
968                 if (x_fetch_more) x_fetch_more.hidden = false;
969                 if (x_lib_type_menu) x_lib_type_menu.hidden = true;
970                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = true;
971             break;
972             case 'record' :
973                 obj.render_lib_menus({'pickup_lib':true,'request_lib':true});
974                 if (x_lib_filter_checkbox) x_lib_filter_checkbox.hidden = false;
975                 if (x_lib_type_menu) x_lib_type_menu.hidden = false;
976                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = false;
977             break;
978             default:
979                 if (obj.controller.view.cmd_search_opac) obj.controller.view.cmd_search_opac.setAttribute('hidden', false);
980                 if (x_fetch_more) x_fetch_more.hidden = true;
981                 if (x_lib_type_menu) x_lib_type_menu.hidden = true;
982                 if (x_lib_menu_placeholder) x_lib_menu_placeholder.hidden = true;
983             break;
984         }
985         setTimeout( // We do this because render_lib_menus above creates and appends a DOM node, but until this thread exits, it doesn't really happen
986             function() {
987                 if (x_lib_filter_checkbox) if (!x_lib_filter_checkbox.checked) {
988                     if (x_lib_type_menu) x_lib_type_menu.disabled = true;
989                     if (obj.controller.view.lib_menu) obj.controller.view.lib_menu.disabled = true;
990                 }
991                 obj.controller.render();
992                 obj.retrieve(true);
993
994                 obj.controller.view.cmd_retrieve_patron.setAttribute('disabled','true');
995                 obj.controller.view.cmd_holds_edit_pickup_lib.setAttribute('disabled','true');
996                 obj.controller.view.cmd_holds_edit_phone_notify.setAttribute('disabled','true');
997                 obj.controller.view.cmd_holds_edit_email_notify.setAttribute('disabled','true');
998                 obj.controller.view.cmd_holds_edit_thaw_date.setAttribute('disabled','true');
999                 obj.controller.view.cmd_holds_activate.setAttribute('disabled','true');
1000                 obj.controller.view.cmd_holds_suspend.setAttribute('disabled','true');
1001                 obj.controller.view.cmd_holds_edit_selection_depth.setAttribute('disabled','true');
1002                 obj.controller.view.cmd_alt_view.setAttribute('disabled','true');
1003                 obj.controller.view.cmd_holds_retarget.setAttribute('disabled','true');
1004                 obj.controller.view.cmd_holds_cancel.setAttribute('disabled','true');
1005                 obj.controller.view.cmd_show_catalog.setAttribute('disabled','true');
1006             }, 0
1007         );
1008
1009         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
1010         JSAN.use('util.browser');
1011         obj.browser = new util.browser();
1012         obj.browser.init(
1013             {
1014                 'url' : urls.XUL_HOLD_DETAILS,
1015                 'push_xulG' : true,
1016                 'alt_print' : false,
1017                 'browser_id' : 'hold_detail_frame',
1018                 'passthru_content_params' : xulG,
1019             }
1020         );
1021
1022     },
1023
1024     'determine_hold_interface_type' : function() {
1025         var obj = this;
1026         if (obj.patron_id) { /*************************************************** PATRON ******************************/
1027             obj.hold_interface_type = 'patron';
1028         } else if (obj.docid) { /*************************************************** RECORD ******************************/
1029             obj.hold_interface_type = 'record';
1030         } else if (obj.pull) { /*************************************************** PULL ******************************/
1031             obj.hold_interface_type = 'pull';
1032         } else if (obj.shelf) { /*************************************************** HOLD SHELF ******************************/
1033             obj.hold_interface_type = 'shelf';
1034         } else { /*************************************************** PULL ******************************/
1035             obj.hold_interface_type = 'pull';
1036         }
1037     },
1038
1039     'clear_and_retrieve' : function() {
1040         try {
1041             this.list.clear();
1042             this.pull_from_shelf_interface.current.offset = this.pull_from_shelf_interface._default.offset;
1043             this.retrieve();
1044             if (window.xulG && typeof window.xulG.on_list_change == 'function') {
1045                 window.xulG.on_list_change(); 
1046             }
1047         } catch(E) {
1048             this.error.standard_unexpected_error_alert('holds.js, clear_and_retrieve(): ',E);
1049         }
1050     },
1051
1052     'retrieve' : function() {
1053         var obj = this; var holds = [];
1054         if (window.xulG && window.xulG.holds) {
1055             holds = window.xulG.holds;
1056         } else {
1057             var method; var params = [ ses() ];
1058             switch(obj.hold_interface_type) {
1059                 case 'patron' :
1060                     method = 'FM_AHR_ID_LIST_RETRIEVE_VIA_AU.authoritative';
1061                     params.push( obj.patron_id );
1062                     obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','true');
1063                 break;
1064                 case 'record' :
1065                     method = 'FM_AHR_RETRIEVE_ALL_VIA_BRE';
1066                     params.push( obj.docid );
1067                     var x_lib_filter = document.getElementById('lib_filter_checkbox');
1068                     var x_lib_type_menu = document.getElementById('lib_type_menu');
1069                     if (x_lib_filter) {
1070                         if (x_lib_filter.checked) {
1071                             if (x_lib_type_menu && obj.controller.view.lib_menu) {
1072                                 var x = {};
1073                                 x[ x_lib_type_menu.value ] = obj.controller.view.lib_menu.value;
1074                                 params.push( x );
1075                             }
1076                         }
1077                     }
1078                     obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
1079                 break;
1080                 case 'shelf' :
1081                     method = 'FM_AHR_ID_LIST_ONSHELF_RETRIEVE';
1082                     params.push( obj.filter_lib || obj.data.list.au[0].ws_ou() );
1083                     obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
1084                 break;
1085                 case 'pull' :
1086                 default:
1087                     method = 'FM_AHR_ID_LIST_PULL_LIST';
1088                     params.push( obj.pull_from_shelf_interface.current.limit ); params.push( obj.pull_from_shelf_interface.current.offset );
1089                     //obj.controller.view.cmd_retrieve_patron.setAttribute('hidden','false');
1090                 break;
1091             }
1092             var robj = obj.network.simple_request( method, params );
1093             if (robj != null && typeof robj.ilsevent != 'undefined') throw(robj);
1094             if (method == 'FM_AHR_RETRIEVE_ALL_VIA_BRE') {
1095                 holds = [];
1096                 if (robj != null) {
1097                     holds = holds.concat( robj.copy_holds );
1098                     holds = holds.concat( robj.volume_holds );
1099                     holds = holds.concat( robj.title_holds );
1100                     holds = holds.concat( robj.metarecord_holds );
1101                     holds = holds.sort();
1102                 }
1103             } else {
1104                 if (robj == null ) {
1105                     holds = [];
1106                 } else {
1107                     if (typeof robj.length == 'undefined') {
1108                         holds = [ robj ];
1109                     } else {
1110                         holds = robj;
1111                     }
1112                 }
1113             }
1114             //alert('method = ' + method + ' params = ' + js2JSON(params));
1115         }
1116
1117         var x_fetch_more = document.getElementById('fetch_more');
1118         if (holds.length == 0) {
1119             if (x_fetch_more) x_fetch_more.disabled = true;
1120         } else {
1121             if (x_fetch_more) x_fetch_more.disabled = false;
1122             obj.render(holds);
1123         }
1124
1125     },
1126
1127     'render' : function(holds) {
1128         try {
1129             var obj = this;
1130
1131             function list_append(hold_id) {
1132                 obj.list.append(
1133                     {
1134                         'row' : {
1135                             'my' : {
1136                                 'hold_id' : hold_id
1137                             }
1138                         }
1139                     }
1140                 );
1141             }
1142
1143             function gen_list_append(hold) {
1144                 return function() {
1145                     if (typeof obj.controller.view.lib_menu == 'undefined') {
1146                         list_append(typeof hold == 'object' ? hold.id() : hold);
1147                     } else {
1148                         list_append(typeof hold == 'object' ? hold.id() : hold);
1149                     }
1150                 };
1151             }
1152
1153             //obj.list.clear();
1154
1155             JSAN.use('util.exec'); var exec = new util.exec(2);
1156             var rows = [];
1157             for (var i in holds) {
1158                 rows.push( gen_list_append(holds[i]) );
1159             }
1160             exec.chain( rows );
1161
1162         } catch(E) {
1163             this.error.standard_unexpected_error_alert('holds.js, render():',E);
1164         }
1165     },
1166
1167     'render_lib_menus' : function(types) {
1168         try {
1169             var obj = this;
1170             JSAN.use('util.widgets'); JSAN.use('util.functional'); JSAN.use('util.fm_utils');
1171
1172             var x = document.getElementById('lib_type_menu');
1173             if (types) {
1174                 var nodes = x.firstChild.childNodes;
1175                 for (var i = 0; i < nodes.length; i++) nodes[i].hidden = true;
1176                 for (var i in types) document.getElementById(i).hidden = false;
1177             }
1178             x.setAttribute('oncommand','g.holds.clear_and_retrieve()');
1179
1180             x = document.getElementById('lib_menu_placeholder');
1181             util.widgets.remove_children( x );
1182
1183             JSAN.use('util.file');
1184             var file = new util.file('offline_ou_list');
1185             if (file._file.exists()) {
1186                 var list_data = file.get_object(); file.close();
1187                 var ml = util.widgets.make_menulist( list_data[0], obj.data.list.au[0].ws_ou() );
1188                 ml.setAttribute('id','lib_menu');
1189                 x.appendChild( ml );
1190                 ml.addEventListener(
1191                     'command',
1192                     function(ev) {
1193                         obj.filter_lib = ev.target.value;
1194                         obj.clear_and_retrieve();
1195                     },
1196                     false
1197                 );
1198                 obj.controller.view.lib_menu = ml;
1199             } else {
1200                 throw($("patronStrings").getString('staff.patron.holds.lib_menus.missing_library_list'));
1201             }
1202
1203         } catch(E) {
1204             this.error.standard_unexpected_error_alert('rendering lib menu',E);
1205         }
1206     }
1207 }
1208
1209 dump('exiting patron.holds.js\n');