]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/OpenILS/data.js
Mozilla has a printer settings object which we serialize when saving the settings...
[working/Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / OpenILS / data.js
1 dump('entering OpenILS/data.js\n');
2
3 if (typeof OpenILS == 'undefined') OpenILS = {};
4 OpenILS.data = function () {
5
6     try {
7         JSAN.use('util.error'); this.error = new util.error();
8         JSAN.use('util.network'); this.network = new util.network();
9     } catch(E) {
10         alert(location.href + '\nError in OpenILS.data constructor: ' + E);
11         throw(E);
12     }
13
14     return this;
15 }
16
17 OpenILS.data.prototype = {
18
19     'list' : {},
20     'hash' : {},
21     'tree' : {},
22
23     'temp' : '',
24
25     'data_progress' : function(msg) {
26         try {
27             var x = document.getElementById('data_progress');
28             if (x) {
29                 x.appendChild( document.createTextNode( msg ) );
30             }
31         } catch(E) {
32             this.error.sdump('D_ERROR',msg + '\n' + E);
33         }
34     },
35
36     'init' : function (params) {
37
38         try {
39             if (params && params.via == 'stash') {    
40                 this.stash_retrieve();
41             } else {
42                 this.network_retrieve();
43             }
44         
45         } catch(E) {
46             this.error.sdump('D_ERROR','Error in OpenILS.data.init('
47                 +js2JSON(params)+'): ' + js2JSON(E) );
48         }
49
50
51     },
52
53     // This should be invoked only once per application, in a persistant window
54     'init_observer_functions' : function() {
55         try {
56             var obj = this;                // OpenILS.data
57             obj.observers = {};            //
58             obj.observers.id = 1;        // Unique id for each observer function added
59             obj.observers.id2path = {}; // Lookup for full_path via observer id
60             obj.observers.cache = {};    // Observer funcs go in here
61
62             // For a given path, this executes all the registered observer funcs
63             obj.observers.dispatch = function(full_path, old_value, new_value) {
64                 obj.error.sdump('D_OBSERVERS', 'entering observers.dispatch\nfull_path = ' + full_path + '\nold_value = ' + js2JSON(old_value) + '\nnew_value = ' + js2JSON(new_value) + '\n');
65                 try {
66                     var path = full_path.split(/\./).pop();
67                     for (var i in obj.observers.cache[full_path]) {
68                         try {
69                             var o = obj.observers.cache[full_path][i];
70                             if (typeof o.func == 'function') o.func(path, old_value, new_value);
71                         } catch(E) {
72                             obj.error.sdump('D_ERROR','Error in OpenILS.data.observers.dispatch(): ' + js2JSON(E) );
73                         }
74                     }
75                 } catch(E) {
76                     obj.error.sdump('D_ERROR','Error in OpenILS.data.observers.dispatch(): ' + js2JSON(E) );
77                 }
78             }
79
80             // This registers an observer function for a given path
81             obj.observers.add = function(full_path, func) {
82                 try {
83                     obj.error.sdump('D_OBSERVERS', 'entering observers.add\nfull_path = ' + full_path + '\nfunc = ' + func + '\n');
84                     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
85                     const OpenILS=new Components.Constructor("@mozilla.org/openils_data_cache;1", "nsIOpenILS");
86                     var data_cache=new OpenILS( );
87                     var stash = data_cache.wrappedJSObject.OpenILS.prototype.data;
88
89                     var id = obj.observers.id++;
90                     if (typeof obj.observers.cache[ full_path ] == 'undefined') obj.observers.cache[ full_path ] = {};
91                     obj.observers.cache[ full_path ][ id ] = { 'func' : func, 'time_added' : new Date() };
92                     obj.observers.id2path[ id ] = [ full_path ];
93
94                     var path_list = full_path.split(/\./);
95                     var observed_prop = path_list.pop();
96
97                     // Convert soft path to object reference.  Error if any but the last node is undefined
98                     for (var i in path_list) stash = stash[ path_list[i] ];
99
100                     /*
101
102                     // experiment with storing only json in cache to avoid the [ ] -> { '0' : .., '1' : .. } bug
103
104                     if (stash[observed_prop] && getKeys( obj.observers.cache[ full_path ] ).length == 0) {
105                         stash['_' + observed_prop] = js2JSON(stash[observed_prop]);
106                     }
107
108                     stash.__defineSetter__(observed_prop, function(x) { this['_'+observed_prop] = js2JSON(x); });
109                     stash.__defineGetter__(observed_prop, function() { return JSON2js(this['_'+observed_prop]); });
110                     */
111
112                     stash.watch(
113                         observed_prop,
114                         function(p,old_value,new_value) {
115                             obj.observers.dispatch(full_path,old_value,new_value);
116                             return new_value;
117                         }
118                     );
119
120                     return id;
121                 } catch(E) {
122                     obj.error.sdump('D_ERROR','Error in OpenILS.data.observers.add(): ' + js2JSON(E) );
123                 }
124             }
125
126             // This unregisters an observer function for a given observer id
127             obj.observers.remove = function(id) {
128                 try {
129                     obj.error.sdump('D_OBSERVERS', 'entering observers.remove\nid = ' + id + '\n');
130                     var path = obj.observers.id2path[ id ];
131                     delete obj.observers.cache[ path ][ id ];
132                     delete obj.observers.id2path[ id ];
133                 } catch(E) {
134                     obj.error.sdump('D_ERROR','Error in OpenILS.data.observers.remove(): ' + js2JSON(E) );
135                 }
136             }
137
138             // This purges observer functions for a given path
139             obj.observers.purge = function(full_path) {
140                 obj.error.sdump('D_OBSERVERS', 'entering observers.purge\nfull_path = ' + full_path + '\n');
141                 try {
142                     var remove_these = [];
143                     for (var id in obj.observers.cache[ full_path ]) remove_these.push( id );
144                     for (var id in remove_these) delete obj.observers.id2path[ id ];
145                     delete obj.observers.cache[ full_path ];
146                 } catch(E) {
147                     obj.error.sdump('D_ERROR','Error in OpenILS.data.observers.purge(): ' + js2JSON(E) );
148                 }
149             }
150
151             obj.stash('observers'); // make this accessible globally
152
153         } catch(E) {
154             this.error.sdump('D_ERROR','Error in OpenILS.data.init_observer_functions(): ' + js2JSON(E) );
155         }
156     },
157
158     'stash' : function () {
159         try {
160             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
161             const OpenILS=new Components.Constructor("@mozilla.org/openils_data_cache;1", "nsIOpenILS");
162             var data_cache=new OpenILS( );
163             for (var i = 0; i < arguments.length; i++) {
164                 try {
165                     if (arguments[i] != 'hash' && arguments[i] != 'list') this.error.sdump('D_DATA_STASH','stashing ' + arguments[i] + ' : ' + this[arguments[i]] + (typeof this[arguments[i]] == 'object' ? ' = ' + (this[arguments[i]]) : '') + '\n');
166                 } catch(F) { alert(F); }
167                 data_cache.wrappedJSObject.OpenILS.prototype.data[arguments[i]] = this[arguments[i]];
168             }
169         } catch(E) {
170             this.error.sdump('D_ERROR','Error in OpenILS.data.stash(): ' + js2JSON(E) );
171         }
172     },
173
174     'lookup' : function(key,value) {
175         try {
176             var obj = this; var found;
177             if (obj.hash[key] && obj.hash[key][value]) return obj.hash[key][value];
178             switch(key) {
179                 case 'acpl': 
180                     found = obj.network.simple_request('FM_ACPL_RETRIEVE_VIA_ID.authoritative',[ value ]);
181                 break;
182                 default: return undefined; break;
183             }
184             if (typeof found.ilsevent != 'undefined') throw(found);
185             if (!obj.hash[key]) obj.hash[key] = {};
186             obj.hash[key][value] = found; obj.list[key].push( found ); obj.stash('hash','list');
187             return found;
188         } catch(E) {
189             this.error.sdump('D_ERROR','Error in OpenILS.data.lookup('+key+','+value+'): ' + js2JSON(E) );
190             return undefined;
191         }
192     },
193
194     '_debug_stash' : function() {
195         try {
196             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
197             const OpenILS=new Components.Constructor("@mozilla.org/openils_data_cache;1", "nsIOpenILS");
198             var data_cache=new OpenILS( );
199             for (var i in data_cache.wrappedJSObject.OpenILS.prototype.data) {
200                 dump('_debug_stash ' + i + '\n');
201             }
202         } catch(E) {
203             this.error.sdump('D_ERROR','Error in OpenILS.data._debug_stash(): ' + js2JSON(E) );
204         }
205     },
206
207     '_fm_objects' : {
208
209         'pgt' : [ api.FM_PGT_RETRIEVE.app, api.FM_PGT_RETRIEVE.method, [], true ],
210         'cit' : [ api.FM_CIT_RETRIEVE.app, api.FM_CIT_RETRIEVE.method, [], true ],
211         'citm' : [ api.FM_CITM_RETRIEVE.app, api.FM_CITM_RETRIEVE.method, [], true ],
212         /*
213         'cst' : [ api.FM_CST_RETRIEVE.app, api.FM_CST_RETRIEVE.method, [], true ],
214         */
215         /*
216         'acpl' : [ api.FM_ACPL_RETRIEVE.app, api.FM_ACPL_RETRIEVE.method, [], true ],
217         */
218         'ccs' : [ api.FM_CCS_RETRIEVE.app, api.FM_CCS_RETRIEVE.method, [], true ],
219         'aou' : [ api.FM_AOU_RETRIEVE.app, api.FM_AOU_RETRIEVE.method, [], true ],
220         'aout' : [ api.FM_AOUT_RETRIEVE.app, api.FM_AOUT_RETRIEVE.method, [], true ],
221         'crahp' : [ api.FM_CRAHP_RETRIEVE.app, api.FM_CRAHP_RETRIEVE.method, [], true ]
222     },
223
224     'stash_retrieve' : function() {
225         try {
226             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
227             const OpenILS=new Components.Constructor("@mozilla.org/openils_data_cache;1", "nsIOpenILS");
228             var data_cache=new OpenILS( );
229             var dc = data_cache.wrappedJSObject.OpenILS.prototype.data;
230             for (var i in dc) {
231                 this.error.sdump('D_DATA_RETRIEVE','Retrieving ' + i + ' : ' + dc[i] + '\n');
232                 this[i] = dc[i];
233             }
234             if (typeof this.on_complete == 'function') {
235
236                 this.on_complete();
237             }
238         } catch(E) {
239             this.error.sdump('D_ERROR','Error in OpenILS.data._debug_stash(): ' + js2JSON(E) );
240         }
241     },
242
243     'print_list_defaults' : function() {
244         var obj = this;
245         //if (typeof obj.print_list_templates == 'undefined') {
246         {
247             obj.print_list_types = [ 
248                 'offline_checkout', 
249                 'offline_checkin', 
250                 'offline_renew', 
251                 'offline_inhouse_use', 
252                 'items', 
253                 'bills', 
254                 'payment', 
255                 'holds', 
256                 /* 'patrons' */
257             ];
258             obj.print_list_templates = { 
259                 'item_status' : {
260                     'type' : 'items',
261                     'header' : 'The following items have been examined:<hr/><ol>',
262                     'line_item' : '<li>%title%<br/>\r\nBarcode: %barcode%\r\n',
263                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\n<br/>\r\n'
264                 }, 
265                 'transit_list' : {
266                     'type' : 'transits',
267                     'header' : 'Transits:<hr/><ol>',
268                     'line_item' : '<li>From: %transit_source% To: %transit_dest_lib%<br/>\r\nWhen: %transit_source_send_time%<br />\r\nBarcode: %transit_item_barcode% Title: %transit_item_title%<br/>\r\n',
269                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\n<br/>\r\n'
270                 }, 
271                 'items_out' : {
272                     'type' : 'items',
273                     'header' : 'Welcome to %LIBRARY%!<br/>\r\nYou have the following items:<hr/><ol>',
274                     'line_item' : '<li>%title%<br/>\r\nBarcode: %barcode% Due: %due_date%\r\n',
275                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\nYou were helped by %STAFF_FIRSTNAME%<br/>\r\n<br/>\r\n'
276                 }, 
277                 'renew' : {
278                     'type' : 'items',
279                     'header' : 'Welcome to %LIBRARY%!<br/>\r\nYou have renewed the following items:<hr/><ol>',
280                     'line_item' : '<li>%title%<br/>\r\nBarcode: %barcode% Due: %due_date%\r\n',
281                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\nYou were helped by %STAFF_FIRSTNAME%<br/>\r\n<br/>\r\n'
282                 }, 
283                 'checkout' : {
284                     'type' : 'items',
285                     'header' : 'Welcome to %LIBRARY%!<br/>\r\nYou checked out the following items:<hr/><ol>',
286                     'line_item' : '<li>%title%<br/>\r\nBarcode: %barcode% Due: %due_date%\r\n',
287                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\nYou were helped by %STAFF_FIRSTNAME%<br/>\r\n<br/>\r\n'
288                 }, 
289                 'offline_checkout' : {
290                     'type' : 'offline_checkout',
291                     'header' : 'Patron %patron_barcode%<br/>\r\nYou checked out the following items:<hr/><ol>',
292                     'line_item' : '<li>Barcode: %barcode%<br/>\r\nDue: %due_date%\r\n',
293                     'footer' : '</ol><hr />%TODAY_TRIM%<br/>\r\n<br/>\r\n'
294                 },
295                 'checkin' : {
296                     'type' : 'items',
297                     'header' : 'You checked in the following items:<hr/><ol>',
298                     'line_item' : '<li>%title%<br/>\r\nBarcode: %barcode%  Call Number: %call_number%\r\n',
299                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\n<br/>\r\n'
300                 }, 
301                 'bill_payment' : {
302                     'type' : 'payment',
303                     'header' : 'Welcome to %LIBRARY%!<br/>A receipt of your  transaction:<hr/> <table width="100%"> <tr> <td>Original Balance:</td> <td align="right">$%original_balance%</td> </tr> <tr> <td>Payment Method:</td> <td align="right">%payment_type%</td> </tr> <tr> <td>Payment Received:</td> <td align="right">$%payment_received%</td> </tr> <tr> <td>Payment Applied:</td> <td align="right">$%payment_applied%</td> </tr> <tr> <td>Billings Voided:</td> <td align="right">%voided_balance%</td> </tr> <tr> <td>Change Given:</td> <td align="right">$%change_given%</td> </tr> <tr> <td>New Balance:</td> <td align="right">$%new_balance%</td> </tr> </table> <p> Note: %note% </p> <p> Specific bills: <blockquote>',
304                     'line_item' : 'Bill #%bill_id%  %last_billing_type% Received: $%payment%<br />%barcode% %title%<br /><br />',
305                     'footer' : '</blockquote> </p> <hr />%SHORTNAME% %TODAY_TRIM%<br/> <br/> '
306                 },
307                 'bills_historical' : {
308                     'type' : 'bills',
309                     'header' : 'Welcome to %LIBRARY%!<br/>You had the following bills:<hr/><ol>',
310                     'line_item' : '<dt><b>Bill #%id%</b></dt> <dd> <table> <tr valign="top"><td>Date:</td><td>%xact_start%</td></tr> <tr valign="top"><td>Type:</td><td>%xact_type%</td></tr> <tr valign="top"><td>Last Billing:</td><td>%last_billing_type%<br/>%last_billing_note%</td></tr> <tr valign="top"><td>Total Billed:</td><td>$%total_owed%</td></tr> <tr valign="top"><td>Last Payment:</td><td>%last_payment_type%<br/>%last_payment_note%</td></tr> <tr valign="top"><td>Total Paid:</td><td>$%total_paid%</td></tr> <tr valign="top"><td><b>Balance:</b></td><td><b>$%balance_owed%</b></td></tr> </table><br/>',
311                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\n<br/>\r\n'
312                 }, 
313                 'bills_current' : {
314                     'type' : 'bills',
315                     'header' : 'Welcome to %LIBRARY%!<br/>You have the following bills:<hr/><ol>',
316                     'line_item' : '<dt><b>Bill #%id%</b></dt> <dd> <table> <tr valign="top"><td>Date:</td><td>%xact_start%</td></tr> <tr valign="top"><td>Type:</td><td>%xact_type%</td></tr> <tr valign="top"><td>Last Billing:</td><td>%last_billing_type%<br/>%last_billing_note%</td></tr> <tr valign="top"><td>Total Billed:</td><td>$%total_owed%</td></tr> <tr valign="top"><td>Last Payment:</td><td>%last_payment_type%<br/>%last_payment_note%</td></tr> <tr valign="top"><td>Total Paid:</td><td>$%total_paid%</td></tr> <tr valign="top"><td><b>Balance:</b></td><td><b>$%balance_owed%</b></td></tr> </table><br/>',
317                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\n<br/>\r\n'
318                 },
319                 'bills_main_view' : {
320                     'type' : 'bills',
321                     'header' : 'Welcome to %LIBRARY%!<br/>You have the following bills:<hr/><ol>',
322                     'line_item' : '<dt><b>Bill #%id%</b> %title%</dt> <dd> <table width="100%"> <tr valign="top"><td>Date:</td><td>%xact_start%</td></tr> <tr valign="top"><td>Type:</td><td>%xact_type%</td></tr> <tr valign="top"><td>Last Billing:</td><td>%last_billing_type%<br/>%last_billing_note%</td></tr> <tr valign="top"><td>Total Billed:</td><td>$%total_owed%</td></tr> <tr valign="top"><td>Last Payment:</td><td>%last_payment_type%<br/>%last_payment_note%</td></tr> <tr valign="top"><td>Total Paid:</td><td>$%total_paid%</td></tr> <tr valign="top"><td><b>Balance:</b></td><td><b>$%balance_owed%</b></td></tr> </table><br/>',
323                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\n<br/>\r\n'
324                 },
325                 'offline_checkin' : {
326                     'type' : 'offline_checkin',
327                     'header' : 'You checked in the following items:<hr/><ol>',
328                     'line_item' : '<li>Barcode: %barcode%\r\n',
329                     'footer' : '</ol><hr />%TODAY_TRIM%<br/>\r\n<br/>\r\n'
330                 },
331                 'offline_renew' : {
332                     'type' : 'offline_renew',
333                     'header' : 'You renewed the following items:<hr/><ol>',
334                     'line_item' : '<li>Barcode: %barcode%\r\n',
335                     'footer' : '</ol><hr />%TODAY_TRIM%<br/>\r\n<br/>\r\n'
336                 },
337                 'offline_inhouse_use' : {
338                     'type' : 'offline_inhouse_use',
339                     'header' : 'You marked the following in-house items used:<hr/><ol>',
340                     'line_item' : '<li>Barcode: %barcode%\r\nUses: %count%',
341                     'footer' : '</ol><hr />%TODAY_TRIM%<br/>\r\n<br/>\r\n'
342                 },
343                 'in_house_use' : {
344                     'type' : 'items',
345                     'header' : 'You marked the following in-house items used:<hr/><ol>',
346                     'line_item' : '<li>Barcode: %barcode%\r\nUses: %uses%\r\n<br />%alert_message%',
347                     'footer' : '</ol><hr />%TODAY_TRIM%<br/>\r\n<br/>\r\n'
348                 },
349                 'holds' : {
350                     'type' : 'holds',
351                     'header' : 'Welcome to %LIBRARY%!<br/>\r\nYou have the following titles on hold:<hr/><ol>',
352                     'line_item' : '<li>%title%\r\n',
353                     'footer' : '</ol><hr />%SHORTNAME% %TODAY_TRIM%<br/>\r\nYou were helped by %STAFF_FIRSTNAME%<br/>\r\n<br/>\r\n'
354                 },
355                 'hold_slip' : {
356                     'type' : 'holds',
357                     'header' : 'This item needs to be routed to <b>%route_to%</b>:<br/>\r\nBarcode: %item_barcode%<br/>\r\nTitle: %item_title%<br/>\r\n<br/>\r\n%hold_for_msg%<br/>\r\nBarcode: %PATRON_BARCODE%<br/>\r\nNotify by phone: %notify_by_phone%<br/>\r\nNotify by email: %notify_by_email%<br/>\r\n',
358                     'line_item' : '%formatted_note%<br/>\r\n',
359                     'footer' : '<br/>\r\nRequest date: %request_date%<br/>\r\nSlip Date: %TODAY_TRIM%<br/>\r\nPrinted by %STAFF_FIRSTNAME% at %SHORTNAME%<br/>\r\n<br/>\r\n'
360                 },
361                 'transit_slip' : {
362                     'type' : 'transits',
363                     'header' : 'This item needs to be routed to <b>%route_to%</b>:<br/>\r\n%route_to_org_fullname%<br/>\r\n%street1%<br/>\r\n%street2%<br/>\r\n%city_state_zip%<br/>\r\n<br/>\r\n',
364                     'line_item' : 'Barcode: %item_barcode%<br/>\r\nTitle: %item_title%<br/>\r\nAuthor: %item_author%<br>\r\n<br/>\r\n',
365                     'footer' : 'Slip Date: %TODAY_TRIM%<br/>\r\nPrinted by %STAFF_FIRSTNAME% at %SHORTNAME%<br/>\r\n<br/>\r\n'
366                 },
367                 'hold_transit_slip' : {
368                     'type' : 'transits',
369                     'header' : 'This item needs to be routed to <b>%route_to%</b>:<br/>\r\n%route_to_org_fullname%<br/>\r\n%street1%<br/>\r\n%street2%<br/>\r\n%city_state_zip%<br/>\r\n<br/>\r\nBarcode: %item_barcode%<br/>\r\nTitle: %item_title%<br/>\r\nAuthor: %item_author%<br>\r\n<br/>\r\n%hold_for_msg%<br/>\r\nBarcode: %PATRON_BARCODE%<br/>\r\nNotify by phone: %notify_by_phone%<br/>\r\nNotify by email: %notify_by_email%<br/>\r\n',
370                     'line_item' : '%formatted_note%<br/>\r\n',
371                     'footer' : '<br/>\r\nRequest date: %request_date%<br/>\r\nSlip Date: %TODAY_TRIM%<br/>\r\nPrinted by %STAFF_FIRSTNAME% at %SHORTNAME%<br/>\r\n<br/>\r\n'
372                 }
373             }; 
374
375             obj.stash( 'print_list_templates', 'print_list_types' );
376         }
377     },
378
379     'network_retrieve' : function() {
380         netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
381         var obj = this;
382
383
384         JSAN.use('util.file'); var file = new util.file('print_list_templates');
385         obj.print_list_defaults();
386         obj.data_progress('Default print templates set. ');
387         if (file._file.exists()) {
388             try {
389                 var x = file.get_object();
390                 if (x) {
391                     for (var i in x) {
392                         obj.print_list_templates[i] = x[i];
393                     }
394                     obj.stash('print_list_templates');
395                     obj.data_progress('Saved print templates retrieved from file. ');
396                 }
397             } catch(E) {
398                 alert(E);
399             }
400         }
401         file.close();
402
403         JSAN.use('util.file'); var file = new util.file('global_font_adjust');
404         if (file._file.exists()) {
405             try {
406                 var x = file.get_object();
407                 if (x) {
408                     obj.global_font_adjust = x;
409                     obj.stash('global_font_adjust');
410                     obj.data_progress('Saved font settings retrieved from file. ');
411                 }
412             } catch(E) {
413                 alert(E);
414             }
415         }
416         file.close();
417
418         JSAN.use('util.file'); var file = new util.file('no_sound');
419         if (file._file.exists()) {
420             try {
421                 var x = file.get_content();
422                 if (x) {
423                     obj.no_sound = x;
424                     obj.stash('no_sound');
425                     obj.data_progress('Saved sound settings retrieved from file. ');
426                 }
427             } catch(E) {
428                 alert(E);
429             }
430         }
431         file.close();
432
433         JSAN.use('util.file'); var file = new util.file('print_strategy');
434         if (file._file.exists()) {
435             try {
436                 var x = file.get_content();
437                 if (x) {
438                     obj.print_strategy = x;
439                     obj.stash('print_strategy');
440                     obj.data_progress('Print strategy retrieved from file. ');
441                 }
442             } catch(E) {
443                 alert(E);
444             }
445         }
446         file.close();
447
448         JSAN.use('util.print'); (new util.print()).GetPrintSettings();
449         obj.data_progress('Printer settings retrieved. ');
450
451         JSAN.use('util.functional');
452         JSAN.use('util.fm_utils');
453
454         function gen_fm_retrieval_func(classname,data) {
455             var app = data[0]; var method = data[1]; var params = data[2]; var cacheable = data[3];
456             return function () {
457                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
458
459                 function convert() {
460                     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
461                     try {
462                         if (obj.list[classname].constructor.name == 'Array') {
463                             obj.hash[classname] = 
464                                 util.functional.convert_object_list_to_hash(
465                                     obj.list[classname]
466                                 );
467                         }
468                     } catch(E) {
469
470                         obj.error.sdump('D_ERROR',E + '\n');
471                     }
472
473                 }
474
475                 try {
476                     var level = obj.error.sdump_levels.D_SES_RESULT;
477                     if (classname == 'aou' || classname == 'my_aou')
478                         obj.error.sdump_levels.D_SES_RESULT = false;
479                     var robj = obj.network.request( app, method, params);
480                     if (robj != null && typeof robj.ilsevent != 'undefined') {
481                         obj.error.standard_unexpected_error_alert('The staff client failed to retrieve expected data from this call, "' + method + '"',robj);
482                         throw(robj);
483                     }
484                     obj.list[classname] = robj == null ? [] : robj;
485                     obj.error.sdump_levels.D_SES_RESULT = level;
486                     convert();
487                     obj.data_progress('Retrieved list for ' + classname + ' objects. ');
488
489                 } catch(E) {
490                     // if cacheable, try offline
491                     if (cacheable) {
492                         /* FIXME -- we're going to revisit caching and do it differently
493                         try {
494                             var file = new util.file( classname );
495                             obj.list[classname] = file.get_object(); file.close();
496                             convert();
497                         } catch(E) {
498                             throw(E);
499                         }
500                         */
501                         throw(E); // for now
502                     } else {
503                         throw(E); // for now
504                     }
505                 }
506             }
507         }
508
509         this.chain = [];
510
511         this.chain.push(
512             function() {
513                 try {
514                     var robj = obj.network.simple_request('CIRC_MODIFIER_LIST',[]);
515                     if (typeof robj.ilsevent != 'undefined') throw(robj);
516                     obj.list.circ_modifier = robj;
517                     obj.data_progress('Retrieved circ modifier list. ');
518                 } catch(E) {
519                     var error = 'Error: ' + js2JSON(E);
520                     obj.error.sdump('D_ERROR',error);
521                     throw(E);
522                 }
523             }
524         );
525
526         this.chain.push(
527             function() {
528                 var f = gen_fm_retrieval_func(
529                     'cnal',
530                     [
531                         api.FM_CNAL_RETRIEVE.app,
532                         api.FM_CNAL_RETRIEVE.method,
533                         [ obj.session.key ],
534                         false
535                     ]
536                 );
537                 try {
538                     f();
539                 } catch(E) {
540                     var error = 'Error: ' + js2JSON(E);
541                     obj.error.sdump('D_ERROR',error);
542                     throw(E);
543                 }
544             }
545         );
546
547         this.chain.push(
548             function() {
549                 var f = gen_fm_retrieval_func(
550                     'csp',
551                     [
552                         api.FM_CSP_PCRUD_SEARCH.app,
553                         api.FM_CSP_PCRUD_SEARCH.method,
554                         [ obj.session.key, {"id":{"!=":null}}, {"order_by":{"csp":"id"}} ],
555                         false
556                     ]
557                 );
558                 try {
559                     f();
560                 } catch(E) {
561                     var error = 'Error: ' + js2JSON(E);
562                     obj.error.sdump('D_ERROR',error);
563                     throw(E);
564                 }
565             }
566         );
567
568         this.chain.push(
569             function() {
570                 var f = gen_fm_retrieval_func(
571                     'ahrcc',
572                     [
573                         api.FM_AHRCC_PCRUD_SEARCH.app,
574                         api.FM_AHRCC_PCRUD_SEARCH.method,
575                         [ obj.session.key, {"id":{"!=":null}}, {"order_by":{"ahrcc":"label"}} ],
576                         false
577                     ]
578                 );
579                 try {
580                     f();
581                 } catch(E) {
582                     var error = 'Error: ' + js2JSON(E);
583                     obj.error.sdump('D_ERROR',error);
584                     throw(E);
585                 }
586             }
587         );
588
589
590         this.chain.push(
591             function() {
592                 var f = gen_fm_retrieval_func(
593                     'au',
594                     [
595                         api.FM_AU_RETRIEVE_VIA_SESSION.app,
596                         api.FM_AU_RETRIEVE_VIA_SESSION.method,
597                         [ obj.session.key ],
598                         false
599                     ]
600                 );
601                 try {
602                     f();
603                 } catch(E) {
604                     var error = 'Error: ' + js2JSON(E);
605                     obj.error.sdump('D_ERROR',error);
606                     throw(E);
607                 }
608                 obj.list.au = [ obj.list.au ];
609             }
610         );
611
612         this.chain.push(
613             function() {
614                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
615                 var f = gen_fm_retrieval_func(
616                     'my_asv',
617                     [
618                         api.FM_ASV_RETRIEVE_REQUIRED.app,
619                         api.FM_ASV_RETRIEVE_REQUIRED.method,
620                         [ obj.session.key ],
621                         true
622                     ]
623                 );
624                 try {
625                     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
626                     f();
627                 } catch(E) {
628                     var error = 'Error: ' + js2JSON(E);
629                     obj.error.sdump('D_ERROR',error);
630                     throw(E);
631                 }
632             }
633         );
634
635         this.chain.push(
636             function() {
637                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
638                 var f = gen_fm_retrieval_func(
639                     'asv',
640                     [
641                         api.FM_ASV_RETRIEVE.app,
642                         api.FM_ASV_RETRIEVE.method,
643                         [ obj.session.key ],
644                         true
645                     ]
646                 );
647                 try {
648                     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
649                     f();
650                 } catch(E) {
651                     var error = 'Error: ' + js2JSON(E);
652                     obj.error.sdump('D_ERROR',error);
653                     throw(E);
654                 }
655             }
656         );
657
658         obj.error.sdump('D_DEBUG','_fm_objects = ' + js2JSON(this._fm_objects) + '\n');
659
660         for (var i in this._fm_objects) {
661             this.chain.push( gen_fm_retrieval_func(i,this._fm_objects[i]) );
662         }
663
664         // The previous org_tree call returned a tree, not a list or hash.
665         this.chain.push(
666             function () {
667                 obj.tree.aou = obj.list.aou;
668                 obj.list.aou = util.fm_utils.flatten_ou_branch( obj.tree.aou );
669                 for (var i = 0; i < obj.list.aou.length; i++) {
670                     var c = obj.list.aou[i].children();
671                     if (!c) c = [];
672                     c = c.sort(
673                         function( a, b ) {
674                             if (a.shortname() < b.shortname()) return -1;
675                             if (a.shortname() > b.shortname()) return 1;
676                             return 0;
677                         }
678                     );
679                     obj.list.aou[i].children( c );
680                 }
681                 obj.list.aou = util.fm_utils.flatten_ou_branch( obj.tree.aou );
682                 obj.hash.aou = util.functional.convert_object_list_to_hash( obj.list.aou );
683             }
684         );
685
686         // The previous pgt call returned a tree, not a list or hash.
687         this.chain.push(
688             function () {
689                 obj.tree.pgt = obj.list.pgt;
690                 obj.list.pgt = util.fm_utils.flatten_ou_branch( obj.tree.pgt );
691                 obj.hash.pgt = util.functional.convert_object_list_to_hash( obj.list.pgt );
692             }
693         );
694
695         // Do these after we get the user object
696
697         this.chain.push(
698             function() {
699                 try {
700                     var robj = obj.network.simple_request('FM_AOUS_RETRIEVE',[ obj.session.key, obj.list.au[0].ws_ou() ]);
701                     if (typeof robj.ilsevent != 'undefined') throw(robj);
702                     obj.hash.aous = robj;
703                     obj.data_progress('Retrieved org unit settings. ');
704                 } catch(E) {
705                     var error = 'Error: ' + js2JSON(E);
706                     obj.error.sdump('D_ERROR',error);
707                     throw(E);
708                 }
709             }
710         );
711
712         this.chain.push(
713
714             function() {
715
716                 gen_fm_retrieval_func('my_aou', 
717                     [ 
718                         api.FM_AOU_RETRIEVE_RELATED_VIA_SESSION.app,
719                         api.FM_AOU_RETRIEVE_RELATED_VIA_SESSION.method,
720                         [ obj.session.key, obj.list.au[0].ws_ou() ], /* use ws_ou and not home_ou */
721                         true
722                     ]
723                 )();
724             }
725         );
726
727         this.chain.push(
728
729             function () {
730
731                 gen_fm_retrieval_func( 'my_actsc', 
732                     [ 
733                         api.FM_ACTSC_RETRIEVE_VIA_AOU.app,
734                         api.FM_ACTSC_RETRIEVE_VIA_AOU.method,
735                         [ obj.session.key, obj.list.au[0].ws_ou() ],
736                         true
737                     ]
738                 )();
739             }
740         );
741
742         this.chain.push(
743
744             function () {
745
746                 gen_fm_retrieval_func( 'my_asc', 
747                     [ 
748                         api.FM_ASC_RETRIEVE_VIA_AOU.app,
749                         api.FM_ASC_RETRIEVE_VIA_AOU.method,
750                         [ obj.session.key, obj.list.au[0].ws_ou() ],
751                         true
752                     ]
753                 )();
754             }
755         );
756
757
758         this.chain.push(
759             function() {
760                 var f = gen_fm_retrieval_func(
761                     'cnct',
762                     [
763                         api.FM_CNCT_RETRIEVE.app,
764                         api.FM_CNCT_RETRIEVE.method,
765                         [ obj.list.au[0].ws_ou() ], 
766                         false
767                     ]
768                 );
769                 try {
770                     f();
771                 } catch(E) {
772                     var error = 'Error: ' + js2JSON(E);
773                     obj.error.sdump('D_ERROR',error);
774                     throw(E);
775                 }
776             }
777         );
778
779         this.chain.push(
780             function() {
781                 var f = gen_fm_retrieval_func(
782                     'my_cnct',
783                     [
784                         api.FM_CNCT_RETRIEVE.app,
785                         api.FM_CNCT_RETRIEVE.method,
786                         [ obj.list.au[0].ws_ou() ], 
787                         false
788                     ]
789                 );
790                 try {
791                     f();
792                 } catch(E) {
793                     var error = 'Error: ' + js2JSON(E);
794                     obj.error.sdump('D_ERROR',error);
795                     throw(E);
796                 }
797             }
798         );
799
800
801         this.chain.push(
802             function() {
803                 var f = gen_fm_retrieval_func(
804                     'acpl',
805                     [
806                         api.FM_ACPL_RETRIEVE.app,
807                         api.FM_ACPL_RETRIEVE.method,
808                         [ obj.list.au[0].ws_ou() ],
809                         false
810                     ]
811                 );
812                 try {
813                     f();
814                 } catch(E) {
815                     var error = 'Error: ' + js2JSON(E);
816                     obj.error.sdump('D_ERROR',error);
817                     throw(E);
818                 }
819             }
820         );
821
822         this.chain.push(
823             function() {
824                 var f = gen_fm_retrieval_func(
825                     'cbt',
826                     [
827                         api.FM_CBT_RETRIEVE.app,
828                         api.FM_CBT_RETRIEVE.method,
829                         [ obj.session.key, obj.list.au[0].ws_ou() ],
830                         false
831                     ]
832                 );
833                 try {
834                     f();
835                 } catch(E) {
836                     var error = 'Error: ' + js2JSON(E);
837                     obj.error.sdump('D_ERROR',error);
838                     throw(E);
839                 }
840             }
841         );
842
843         if (typeof this.on_complete == 'function') {
844
845             this.chain.push( this.on_complete );
846         }
847         JSAN.use('util.exec'); this.exec = new util.exec();
848         this.exec.on_error = function(E) { 
849         
850             if (typeof obj.on_error == 'function') {
851                 return obj.on_error(E); /* false breaks chain */
852             } else {
853                 alert('oops: ' + E ); 
854                 return false; /* break chain */
855             }
856
857         }
858
859         this.exec.chain( this.chain );
860
861     }
862 }
863
864 dump('exiting OpenILS/data.js\n');