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