]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/util.js
f97437d99acccf3e54962b24f4bd67639e90711f
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / util.js
1 dump('entering patron/util.js\n');
2
3 if (typeof patron == 'undefined') var patron = {};
4 patron.util = {};
5
6 patron.util.EXPORT_OK    = [ 
7     'columns', 'mbts_columns', 'mb_columns', 'mp_columns', /*'std_map_row_to_column',*/ 'std_map_row_to_columns',
8     'retrieve_au_via_id', 'retrieve_fleshed_au_via_id', 'retrieve_fleshed_au_via_barcode', 'set_penalty_css', 'retrieve_name_via_id',
9     'merge', 'ausp_columns', 'format_name', 'work_log_patron_edit'
10 ];
11 patron.util.EXPORT_TAGS    = { ':all' : patron.util.EXPORT_OK };
12
13 patron.util.mbts_columns = function(modify,params) {
14
15     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
16     JSAN.use('util.money'); JSAN.use('util.date');
17
18     var commonStrings = document.getElementById('commonStrings');
19
20     var c = [
21         {
22             'persist' : 'hidden width ordinal', 'id' : 'mbts_id', 'label' : commonStrings.getString('staff.mbts_id_label'), 'flex' : 1,
23             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.id(); }
24         },
25         {
26             'persist' : 'hidden width ordinal', 'id' : 'usr', 'label' : commonStrings.getString('staff.mbts_usr_label'), 'flex' : 1,
27             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.usr() ? "Id = " + my.mbts.usr() : ""; }
28         },
29         {
30             'persist' : 'hidden width ordinal', 'id' : 'xact_type', 'label' : commonStrings.getString('staff.mbts_xact_type_label'), 'flex' : 1,
31             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.xact_type(); }
32         },
33         {
34             'persist' : 'hidden width ordinal', 'id' : 'balance_owed', 'label' : commonStrings.getString('staff.mbts_balance_owed_label'), 'flex' : 1,
35             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.balance_owed() ); },
36             'sort_type' : 'money'
37         },
38         {
39             'persist' : 'hidden width ordinal', 'id' : 'total_owed', 'label' : commonStrings.getString('staff.mbts_total_owed_label'), 'flex' : 1,
40             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.total_owed() ); },
41             'sort_type' : 'money'
42         },
43         {
44             'persist' : 'hidden width ordinal', 'id' : 'total_paid', 'label' : commonStrings.getString('staff.mbts_total_paid_label'), 'flex' : 1,
45             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mbts.total_paid() ); },
46             'sort_type' : 'money'
47         },
48         {
49             'persist' : 'hidden width ordinal', 'id' : 'last_billing_note', 'label' : commonStrings.getString('staff.mbts_last_billing_note_label'), 'flex' : 2,
50             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_billing_note(); }
51         },
52         {
53             'persist' : 'hidden width ordinal', 'id' : 'last_billing_type', 'label' : commonStrings.getString('staff.mbts_last_billing_type_label'), 'flex' : 1,
54             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_billing_type(); }
55         },
56         {
57             'persist' : 'hidden width ordinal', 'id' : 'last_billing_ts', 'label' : commonStrings.getString('staff.mbts_last_billing_timestamp_label'), 'flex' : 1,
58             'sort_type' : 'date',
59             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mbts.last_billing_ts(), "%{localized}" ); }
60             ,'sort_value' : function(my) { return util.date.db_date2Date( my.mbts.last_billing_ts() ).getTime(); }
61         },
62         {
63             'persist' : 'hidden width ordinal', 'id' : 'last_payment_note', 'label' : commonStrings.getString('staff.mbts_last_payment_note_label'), 'flex' : 2,
64             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_payment_note(); }
65         },
66         {
67             'persist' : 'hidden width ordinal', 'id' : 'last_payment_type', 'label' : commonStrings.getString('staff.mbts_last_payment_type_label'), 'flex' : 1,
68             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mbts.last_payment_type(); }
69         },
70         {
71             'persist' : 'hidden width ordinal', 'id' : 'last_payment_ts', 'label' : commonStrings.getString('staff.mbts_last_payment_timestamp_label'), 'flex' : 1,
72             'sort_type' : 'date',
73             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mbts.last_payment_ts(), "%{localized}" ); }
74             ,'sort_value' : function(my) { return util.date.db_date2Date( my.mbts.last_payment_ts() ).getTime(); }
75         },
76         {
77             'persist' : 'hidden width ordinal', 'id' : 'mbts_xact_start', 'label' : commonStrings.getString('staff.mbts_xact_start_label'), 'flex' : 1,
78             'sort_type' : 'date',
79             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.xact_start() ? util.date.formatted_date( my.mbts.xact_start(), "%{localized}" ) : ""; }
80             ,'sort_value' : function(my) { return util.date.db_date2Date( my.mbts.xact_start() ).getTime(); }
81         },
82         {
83             'persist' : 'hidden width ordinal', 'id' : 'mbts_xact_finish', 'label' : commonStrings.getString('staff.mbts_xact_finish_label'), 'flex' : 1,
84             'sort_type' : 'date',
85             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mbts.xact_finish() ? util.date.formatted_date( my.mbts.xact_finish(), "%{localized}" ) : ""; }
86             ,'sort_value' : function(my) { return util.date.db_date2Date( my.mbts.xact_finish() ).getTime(); }
87         },
88     ];
89     for (var i = 0; i < c.length; i++) {
90         if (modify[ c[i].id ]) {
91             for (var j in modify[ c[i].id ]) {
92                 c[i][j] = modify[ c[i].id ][j];
93             }
94         }
95     }
96     if (params) {
97         if (params.just_these) {
98             JSAN.use('util.functional');
99             var new_c = [];
100             for (var i = 0; i < params.just_these.length; i++) {
101                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
102                 new_c.push( function(y){ return y; }( x ) );
103             }
104             c = new_c;
105         }
106         if (params.except_these) {
107             JSAN.use('util.functional');
108             var new_c = [];
109             for (var i = 0; i < c.length; i++) {
110                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
111                 if (!x) new_c.push(c[i]);
112             }
113             c = new_c;
114         }
115     }
116     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
117 }
118
119 patron.util.mb_columns = function(modify,params) {
120
121     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
122     JSAN.use('util.money'); JSAN.use('util.date');
123
124     var commonStrings = document.getElementById('commonStrings');
125
126     var c = [
127         {
128             'persist' : 'hidden width ordinal', 'id' : 'mb_id', 'label' : commonStrings.getString('staff.mb_id_label'), 'flex' : 1,
129             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mb.id(); }
130         },
131         {
132             'persist' : 'hidden width ordinal', 'id' : 'voided', 'label' : commonStrings.getString('staff.mb_voided_label'), 'flex' : 1,
133             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return get_bool( my.mb.voided() ) ? "Yes" : "No"; }
134         },
135         {
136             'persist' : 'hidden width ordinal', 'id' : 'voider', 'label' : commonStrings.getString('staff.mb_voider_label'), 'flex' : 1,
137             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mb.voider() ? "Id = " + my.mb.voider() : ""; }
138         },
139         {
140             'persist' : 'hidden width ordinal', 'id' : 'void_time', 'label' : commonStrings.getString('staff.mb_void_time_label'), 'flex' : 1,
141             'sort_type' : 'date',
142             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mb.void_time(), "%{localized}" ); }
143             ,'sort_value' : function(my) { return util.date.db_date2Date( my.mb.void_time() ).getTime(); }
144         },
145         {
146             'persist' : 'hidden width ordinal', 'id' : 'amount', 'label' : commonStrings.getString('staff.mb_amount_label'), 'flex' : 1,
147             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mb.amount() ); },
148             'sort_type' : 'money'
149         },
150         {
151             'persist' : 'hidden width ordinal', 'id' : 'billing_type', 'label' : commonStrings.getString('staff.mb_billing_type_label'), 'flex' : 1,
152             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mb.billing_type(); }
153         },
154         {
155             'persist' : 'hidden width ordinal', 'id' : 'billing_ts', 'label' : commonStrings.getString('staff.mb_billing_ts_label'), 'flex' : 1,
156             'sort_type' : 'date',
157             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mb.billing_ts(), "%{localized}" ); }
158             ,'sort_value' : function(my) { return util.date.db_date2Date( my.mb.billing_ts() ).getTime(); }
159         },
160         {
161             'persist' : 'hidden width ordinal', 'id' : 'note', 'label' : commonStrings.getString('staff.mb_note_label'), 'flex' : 2,
162             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mb.note(); }
163         },
164         {
165             'persist' : 'hidden width ordinal', 'id' : 'xact', 'label' : commonStrings.getString('staff.mb_xact_label'), 'flex' : 1,
166             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mb.xact(); }
167         },
168     ];
169     for (var i = 0; i < c.length; i++) {
170         if (modify[ c[i].id ]) {
171             for (var j in modify[ c[i].id ]) {
172                 c[i][j] = modify[ c[i].id ][j];
173             }
174         }
175     }
176     if (params) {
177         if (params.just_these) {
178             JSAN.use('util.functional');
179             var new_c = [];
180             for (var i = 0; i < params.just_these.length; i++) {
181                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
182                 new_c.push( function(y){ return y; }( x ) );
183             }
184             c = new_c;
185         }
186         if (params.except_these) {
187             JSAN.use('util.functional');
188             var new_c = [];
189             for (var i = 0; i < c.length; i++) {
190                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
191                 if (!x) new_c.push(c[i]);
192             }
193             c = new_c;
194         }
195
196     }
197     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
198 }
199
200 patron.util.mp_columns = function(modify,params) {
201
202     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
203     JSAN.use('util.money'); JSAN.use('util.date'); JSAN.use('patron.util');
204
205     var commonStrings = document.getElementById('commonStrings');
206
207     var c = [
208         {
209             'persist' : 'hidden width ordinal', 'id' : 'mp_id', 'label' : commonStrings.getString('staff.mp_id_label'), 'flex' : 1,
210             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mp.id(); }
211         },
212         {
213             'persist' : 'hidden width ordinal', 'id' : 'mp_amount', 'label' : commonStrings.getString('staff.mp_amount_label'), 'flex' : 1,
214             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.money.sanitize( my.mp.amount() ); },
215             'sort_type' : 'money'
216         },
217         {
218             'persist' : 'hidden width ordinal', 'id' : 'mp_payment_type', 'label' : commonStrings.getString('staff.mp_payment_type_label'), 'flex' : 1,
219             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mp.payment_type(); }
220         },
221         {
222             'persist' : 'hidden width ordinal', 'id' : 'mp_payment_ts', 'label' : commonStrings.getString('staff.mp_payment_timestamp_label'), 'flex' : 1,
223             'sort_type' : 'date',
224             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.mp.payment_ts(), "%{localized}" ); }
225             ,'sort_value' : function(my) { return util.date.db_date2Date( my.mp.payment_ts() ).getTime(); }
226         },
227         {
228             'persist' : 'hidden width ordinal', 'id' : 'mp_note', 'label' : commonStrings.getString('staff.mp_note_label'), 'flex' : 2,
229             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mp.note(); }
230         },
231         {
232             'persist' : 'hidden width ordinal', 'id' : 'mp_ws', 'label' : commonStrings.getString('staff.mp_cash_drawer_label'), 'flex' : 1,
233             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return my.mp.cash_drawer().name(); }
234         },
235         {
236             'persist' : 'hidden width ordinal', 'id' : 'mp_staff', 'label' : commonStrings.getString('staff.mp_accepting_usr_label'), 'flex' : 1,
237             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { var s = my.mp.accepting_usr(); if (s && typeof s != "object") s = patron.util.retrieve_fleshed_au_via_id(ses(),s,["card"]); return s.family_name() + " (" + s.card().barcode() + ") @ " + data.hash.aou[ s.home_ou() ].shortname(); }
238         },
239         {
240             'persist' : 'hidden width ordinal', 'id' : 'mp_xact', 'label' : commonStrings.getString('staff.mp_xact_label'), 'flex' : 1,
241             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.mp.xact(); }
242         },
243     ];
244     for (var i = 0; i < c.length; i++) {
245         if (modify[ c[i].id ]) {
246             for (var j in modify[ c[i].id ]) {
247                 c[i][j] = modify[ c[i].id ][j];
248             }
249         }
250     }
251     if (params) {
252         if (params.just_these) {
253             JSAN.use('util.functional');
254             var new_c = [];
255             for (var i = 0; i < params.just_these.length; i++) {
256                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
257                 new_c.push( function(y){ return y; }( x ) );
258             }
259             c = new_c;
260         }
261         if (params.except_these) {
262             JSAN.use('util.functional');
263             var new_c = [];
264             for (var i = 0; i < c.length; i++) {
265                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
266                 if (!x) new_c.push(c[i]);
267             }
268             c = new_c;
269         }
270
271     }
272     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
273 }
274
275 patron.util.ausp_columns = function(modify,params) {
276
277     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
278     JSAN.use('util.functional');
279
280     var commonStrings = document.getElementById('commonStrings');
281
282     var c = [
283         {
284             'persist' : 'hidden width ordinal', 'id' : 'csp_id', 'label' : commonStrings.getString('staff.csp_id_label'), 'flex' : 1,
285             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.id() : my.csp; }
286         },
287         {
288             'persist' : 'hidden width ordinal', 'id' : 'csp_name', 'label' : commonStrings.getString('staff.csp_name_label'), 'flex' : 1,
289             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.name() : data.hash.csp[ my.csp ].name(); }
290         },
291         {
292             'persist' : 'hidden width ordinal', 'id' : 'csp_label', 'label' : commonStrings.getString('staff.csp_label_label'), 'flex' : 1,
293             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.label() : data.hash.csp[ my.csp ].label(); }
294         },
295         {
296             'persist' : 'hidden width ordinal', 'id' : 'csp_block_list', 'label' : commonStrings.getString('staff.csp_block_list_label'), 'flex' : 1,
297             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return typeof my.csp == 'object' ? my.csp.block_list() : data.hash.csp[ my.csp ].block_list(); }
298         },
299         {
300             'persist' : 'hidden width ordinal', 'id' : 'csp_block_circ', 'label' : commonStrings.getString('staff.csp_block_circ_label'), 'flex' : 1,
301             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
302                 var my_csp = typeof my.csp == 'object' ? my.csp : data.hash.csp[ my.csp ];
303                 return String( my_csp.block_list() ).match('CIRC') ? commonStrings.getString('staff.csp_block_circ_yes') : commonStrings.getString('staff.csp_block_circ_no'); 
304             }
305         },
306         {
307             'persist' : 'hidden width ordinal', 'id' : 'csp_block_renew', 'label' : commonStrings.getString('staff.csp_block_renew_label'), 'flex' : 1,
308             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
309                 var my_csp = typeof my.csp == 'object' ? my.csp : data.hash.csp[ my.csp ];
310                 return String( my_csp.block_list() ).match('RENEW') ? commonStrings.getString('staff.csp_block_renew_yes') : commonStrings.getString('staff.csp_block_renew_no'); 
311
312             }
313         },
314         {
315             'persist' : 'hidden width ordinal', 'id' : 'csp_block_hold', 'label' : commonStrings.getString('staff.csp_block_hold_label'), 'flex' : 1,
316             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
317                 var my_csp = typeof my.csp == 'object' ? my.csp : data.hash.csp[ my.csp ];
318                 return String( my_csp.block_list() ).match('HOLD') ?  commonStrings.getString('staff.csp_block_hold_yes') : commonStrings.getString('staff.csp_block_hold_no'); 
319             }
320         },
321         {
322             'persist' : 'hidden width ordinal', 'id' : 'ausp_id', 'label' : commonStrings.getString('staff.ausp_id_label'), 'flex' : 1,
323             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.ausp ? my.ausp.id() : ''; }
324         },
325         {
326             'persist' : 'hidden width ordinal', 'id' : 'ausp_staff', 'label' : commonStrings.getString('staff.ausp_staff_label'), 'flex' : 1,
327             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { 
328                 return my.ausp ? my.ausp.staff() : '';
329             }
330         },
331         {
332             'persist' : 'hidden width ordinal', 'id' : 'ausp_set_date', 'label' : commonStrings.getString('staff.ausp_set_date_label'), 'flex' : 1,
333             'sort_type' : 'date',
334             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { 
335                 return my.ausp ? util.date.formatted_date( my.ausp.set_date(), "%{localized}" ) : '';
336             }
337             ,'sort_value' : function(my) { return util.date.db_date2Date( my.ausp.set_date() ).getTime(); }
338         },
339         {
340             'persist' : 'hidden width ordinal', 'id' : 'ausp_note', 'label' : commonStrings.getString('staff.ausp_note_label'), 'flex' : 1,
341             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { 
342                 return my.ausp ? my.ausp.note() : '';
343             }
344         },
345         {
346             'persist' : 'hidden width ordinal', 'id' : 'ausp_org_unit', 'label' : commonStrings.getString('staff.ausp_org_unit_label'), 'flex' : 1,
347             'primary' : false, 'hidden' : false, 'editable' : false, 'render' : function(my) { 
348                 return my.ausp ? data.hash.aou[ my.ausp.org_unit() ].shortname() : '';
349             }
350         }
351     ];
352     for (var i = 0; i < c.length; i++) {
353         if (modify[ c[i].id ]) {
354             for (var j in modify[ c[i].id ]) {
355                 c[i][j] = modify[ c[i].id ][j];
356             }
357         }
358     }
359     if (params) {
360         if (params.just_these) {
361             var new_c = [];
362             for (var i = 0; i < params.just_these.length; i++) {
363                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
364                 new_c.push( function(y){ return y; }( x ) );
365             }
366             c = new_c;
367         }
368         if (params.except_these) {
369             var new_c = [];
370             for (var i = 0; i < c.length; i++) {
371                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
372                 if (!x) new_c.push(c[i]);
373             }
374             c = new_c;
375         }
376
377     }
378     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
379 }
380
381
382 patron.util.columns = function(modify,params) {
383     
384     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
385
386     var commonStrings = document.getElementById('commonStrings');
387
388     var c = [
389         {
390             'persist' : 'hidden width ordinal', 'id' : 'au_barcode', 'label' : commonStrings.getString('staff.card_barcode_label'), 'flex' : 1, 
391             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.card().barcode(); }
392         },
393         { 
394             'persist' : 'hidden width ordinal', 'id' : 'usrname', 'label' : commonStrings.getString('staff.au_usrname_label'), 'flex' : 1, 
395             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.usrname(); }
396         },
397         { 
398             'persist' : 'hidden width ordinal', 'id' : 'profile', 'label' : commonStrings.getString('staff.au_profile_label'), 'flex' : 1, 
399             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.pgt[ my.au.profile() ].name(); }
400         },
401         { 
402             'persist' : 'hidden width ordinal', 'id' : 'active', 'label' : commonStrings.getString('staff.au_active_label'), 'flex' : 1, 
403             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return get_bool( my.au.active() ) ? "Yes" : "No"; }
404         },
405         {
406             'persist' : 'hidden width ordinal', 'id' : 'barred', 'label' : commonStrings.getString('staff.au_barred_label'), 'flex' : 1,
407             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return get_bool( my.au.barred() ) ? "Yes" : "No"; }
408         },
409         { 
410             'persist' : 'hidden width ordinal', 'id' : 'au_id', 'label' : document.getElementById('commonStrings').getString('staff.au_id_label'), 'flex' : 1, 
411             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.id(); }
412         },
413         { 
414             'persist' : 'hidden width ordinal', 'id' : 'prefix', 'label' : document.getElementById('commonStrings').getString('staff.au_name_prefix_label'), 'flex' : 1, 
415             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.prefix(); }
416         },
417         { 
418             'persist' : 'hidden width ordinal', 'id' : 'family_name', 'label' : document.getElementById('commonStrings').getString('staff.au_family_name_label'), 'flex' : 1, 
419             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.family_name(); }
420         },
421         { 
422             'persist' : 'hidden width ordinal', 'id' : 'first_given_name', 'label' : document.getElementById('commonStrings').getString('staff.au_first_given_name_label'), 'flex' : 1, 
423             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.first_given_name(); }
424         },
425         { 
426             'persist' : 'hidden width ordinal', 'id' : 'second_given_name', 'label' : document.getElementById('commonStrings').getString('staff.au_second_given_name_label'), 'flex' : 1, 
427             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.second_given_name(); }
428         },
429         { 
430             'persist' : 'hidden width ordinal', 'id' : 'suffix', 'label' : document.getElementById('commonStrings').getString('staff.au_name_suffix_label'), 'flex' : 1, 
431             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.suffix(); }
432         },
433         { 
434             'persist' : 'hidden width ordinal', 'id' : 'au_alert_message', 'label' : commonStrings.getString('staff.au_alert_message_label'), 'flex' : 1, 
435             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.alert_message(); }
436         },
437         { 
438             'persist' : 'hidden width ordinal', 'id' : 'claims_returned_count', 'label' : commonStrings.getString('staff.au_claims_returned_count_label'), 'flex' : 1, 
439             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.claims_returned_count(); },
440             'sort_type' : 'number'
441         },
442         { 
443             'persist' : 'hidden width ordinal', 'id' : 'au_create_date', 'label' : commonStrings.getString('staff.au_create_date_label'), 'flex' : 1, 
444             'sort_type' : 'date',
445             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.au.create_date(), "%{localized}" ); }
446             ,'sort_value' : function(my) { return util.date.db_date2Date( my.au.create_date() ).getTime(); }
447         },
448         { 
449             'persist' : 'hidden width ordinal', 'id' : 'au_last_update_time', 'label' : commonStrings.getString('staff.au_last_update_time_label'), 'flex' : 1, 
450             'sort_type' : 'date',
451             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.au.last_update_time(), "%{localized}" ); }
452             ,'sort_value' : function(my) { return util.date.db_date2Date( my.au.last_update_time() ).getTime(); }
453         },
454
455         { 
456             'persist' : 'hidden width ordinal', 'id' : 'expire_date', 'label' : commonStrings.getString('staff.au_expire_date_label'), 'flex' : 1, 
457             'sort_type' : 'date',
458             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.au.expire_date(), "%{localized_date}" ); }
459             ,'sort_value' : function(my) { return util.date.db_date2Date( my.au.expire_date() ).getTime(); }
460         },
461         { 
462             'persist' : 'hidden width ordinal', 'id' : 'home_ou', 'label' : commonStrings.getString('staff.au_home_library_label'), 'flex' : 1, 
463             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.aou[ my.au.home_ou() ].shortname(); }
464         },
465         { 
466             'persist' : 'hidden width ordinal', 'id' : 'home_ou_fullname', 'label' : commonStrings.getString('staff.au_home_library_fullname_label'), 'flex' : 1, 
467             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.aou[ my.au.home_ou() ].name(); }
468         },
469         { 
470             'persist' : 'hidden width ordinal', 'id' : 'credit_forward_balance', 'label' : commonStrings.getString('staff.au_credit_forward_balance_label'), 'flex' : 1, 
471             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.credit_forward_balance(); },
472             'sort_type' : 'money'
473         },
474         { 
475             'persist' : 'hidden width ordinal', 'id' : 'day_phone', 'label' : commonStrings.getString('staff.au_day_phone_label'), 'flex' : 1, 
476             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.day_phone(); }
477         },
478         { 
479             'persist' : 'hidden width ordinal', 'id' : 'evening_phone', 'label' : commonStrings.getString('staff.au_evening_phone_label'), 'flex' : 1, 
480             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.evening_phone(); }
481         },
482         { 
483             'persist' : 'hidden width ordinal', 'id' : 'other_phone', 'label' : commonStrings.getString('staff.au_other_phone_label'), 'flex' : 1, 
484             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.other_phone(); }
485         },
486         { 
487             'persist' : 'hidden width ordinal', 'id' : 'email', 'label' : commonStrings.getString('staff.au_email_label'), 'flex' : 1, 
488             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.email(); }
489         },
490         { 
491             'persist' : 'hidden width ordinal', 'id' : 'alias', 'label' : commonStrings.getString('staff.au_alias_label'), 'flex' : 1, 
492             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.alias(); }
493         },
494         { 
495             'persist' : 'hidden width ordinal', 'id' : 'dob', 'label' : commonStrings.getString('staff.au_birth_date_label'), 'flex' : 1, 
496             'sort_type' : 'date',
497             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return util.date.formatted_date( my.au.dob(), "%{localized_date}" ); }
498             ,'sort_value' : function(my) { return util.date.db_date2Date( my.au.dob() ).getTime(); }
499         },
500         { 
501             'persist' : 'hidden width ordinal', 'id' : 'ident_type', 'label' : commonStrings.getString('staff.au_ident_type_label'), 'flex' : 1, 
502             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.cit[ my.au.ident_type() ].name(); }
503         },
504         { 
505             'persist' : 'hidden width ordinal', 'id' : 'ident_value', 'label' : commonStrings.getString('staff.au_ident_value_label'), 'flex' : 1, 
506             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.ident_value(); }
507         },
508         { 
509             'persist' : 'hidden width ordinal', 'id' : 'ident_type2', 'label' : commonStrings.getString('staff.au_ident_type2_label'), 'flex' : 1, 
510             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return data.hash.cit[ my.au.ident_type2() ].name(); }
511         },
512         { 
513             'persist' : 'hidden width ordinal', 'id' : 'ident_value2', 'label' : commonStrings.getString('staff.au_ident_value2_label'), 'flex' : 1, 
514             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.ident_value2(); }
515         },
516         { 
517             'persist' : 'hidden width ordinal', 'id' : 'net_access_level', 'label' : commonStrings.getString('staff.au_net_access_level_label'), 'flex' : 1, 
518             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.net_access_level(); }
519         },
520         { 
521             'persist' : 'hidden width ordinal', 'id' : 'master_account', 'label' : commonStrings.getString('staff.au_master_account_label'), 'flex' : 1, 
522             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return get_bool( my.au.master_account() ) ? "Yes" : "No"; }
523         },
524         { 
525             'persist' : 'hidden width ordinal', 'id' : 'usrgroup', 'label' : commonStrings.getString('staff.au_group_id_label'), 'flex' : 1, 
526             'primary' : false, 'hidden' : true, 'editable' : false, 'render' : function(my) { return my.au.usrgroup(); }
527         },
528     ];
529     for (var i = 0; i < c.length; i++) {
530         if (modify[ c[i].id ]) {
531             for (var j in modify[ c[i].id ]) {
532                 c[i][j] = modify[ c[i].id ][j];
533             }
534         }
535     }
536     if (params) {
537         if (params.just_these) {
538             JSAN.use('util.functional');
539             var new_c = [];
540             for (var i = 0; i < params.just_these.length; i++) {
541                 var x = util.functional.find_list(c,function(d){return(d.id==params.just_these[i]);});
542                 new_c.push( function(y){ return y; }( x ) );
543             }
544             c = new_c;
545         }
546         if (params.except_these) {
547             JSAN.use('util.functional');
548             var new_c = [];
549             for (var i = 0; i < c.length; i++) {
550                 var x = util.functional.find_list(params.except_these,function(d){return(d==c[i].id);});
551                 if (!x) new_c.push(c[i]);
552             }
553             c = new_c;
554         }
555
556     }
557     return c.sort( function(a,b) { if (a.label < b.label) return -1; if (a.label > b.label) return 1; return 0; } );
558 }
559
560 patron.util.std_map_row_to_columns = function(error_value) {
561     return function(row,cols,scratch) {
562         // row contains { 'my' : { 'au' : {} } }
563         // cols contains all of the objects listed above in columns
564         // scratch is a temporary space shared by all cells/rows (or just per row if not explicitly passed in)
565         
566         var obj = {}; obj.OpenILS = {}; 
567         JSAN.use('util.error'); obj.error = new util.error();
568         JSAN.use('OpenILS.data'); obj.OpenILS.data = new OpenILS.data(); obj.OpenILS.data.init({'via':'stash'});
569         JSAN.use('util.date'); JSAN.use('util.money');
570
571         var my = row.my;
572         var values = [];
573         var sort_values = [];
574         var cmd = '';
575         try { 
576             for (var i = 0; i < cols.length; i++) {
577                 switch (typeof cols[i].render) {
578                     case 'function': try { values[i] = cols[i].render(my); } catch(E) { values[i] = error_value; obj.error.sdump('D_COLUMN_RENDER_ERROR',E); } break;
579                     case 'string' : cmd += 'try { ' + cols[i].render + '; values['+i+'] = v; } catch(E) { values['+i+'] = error_value; }'; break;
580                     default: cmd += 'values['+i+'] = "??? '+(typeof cols[i].render)+'"; ';
581                 }
582                 switch (typeof cols[i].sort_value) {
583                     case 'function':
584                         try {
585                             sort_values[i] = cols[i].sort_value(my,scratch);
586                         } catch(E) {
587                             sort_values[i] = error_value;
588                             obj.error.sdump('D_COLUMN_RENDER_ERROR',E);
589                         }
590                         break;
591                     case 'string' :
592                         sort_values[i] = JSON2js(cols[i].sort_value);
593                         break;
594                     default:
595                         cmd += 'sort_values['+i+'] = values[' + i + '];';
596                 }
597             }
598             if (cmd) eval( cmd );
599         } catch(E) {
600             obj.error.sdump('D_WARN','map_row_to_column: ' + E);
601             if (error_value) { value = error_value; } else { value = '   ' };
602         }
603         return {values: values, sort_values: sort_values};
604     }
605 }
606
607 patron.util.retrieve_au_via_id = function(session, id, f) {
608     JSAN.use('util.network');
609     var network = new util.network();
610     var patron_obj = network.simple_request(
611         'FM_AU_RETRIEVE_VIA_ID.authoritative',
612         [ session, id ],
613         f
614     );
615     return patron_obj;
616 }
617
618 patron.util.retrieve_name_via_id = function(session, id) {
619     JSAN.use('util.network');
620     var network = new util.network();
621     var parts = network.simple_request(
622         'BLOB_AU_PARTS_RETRIEVE',
623         [ session, id, ['family_name', 'first_given_name', 'second_given_name', 'home_ou' ] ]
624     );
625     return parts;
626 }
627
628 patron.util.retrieve_fleshed_au_via_id = function(session, id, fields, func) {
629     JSAN.use('util.network');
630     var network = new util.network();
631     var patron_obj = network.simple_request(
632         'FM_AU_FLESHED_RETRIEVE_VIA_ID.authoritative',
633         [ session, id, fields ],
634         typeof func == 'function' ? func : null
635     );
636     if (typeof func != 'function') {
637         if (!fields) { patron.util.set_penalty_css(patron_obj); }
638         return patron_obj;
639     }
640 }
641
642 patron.util.retrieve_fleshed_au_via_barcode = function(session, id) {
643     JSAN.use('util.network');
644     var network = new util.network();
645     var patron_obj = network.simple_request(
646         'FM_AU_RETRIEVE_VIA_BARCODE.authoritative',
647         [ session, id ]
648     );
649     if (typeof patron_obj.ilsevent == 'undefined') patron.util.set_penalty_css(patron_obj);
650     return patron_obj;
651 }
652
653 var TIME = { minute : 60, hour : 60*60, day : 60*60*24, year : 60*60*24*365 };
654
655 patron.util.set_penalty_css = function(patron) {
656     try {
657         removeCSSClass(document.documentElement,'PATRON_HAS_BILLS');
658         removeCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
659         removeCSSClass(document.documentElement,'PATRON_HAS_NOTES');
660         removeCSSClass(document.documentElement,'PATRON_EXCEEDS_CHECKOUT_COUNT');
661         removeCSSClass(document.documentElement,'PATRON_EXCEEDS_OVERDUE_COUNT');
662         removeCSSClass(document.documentElement,'PATRON_EXCEEDS_FINES');
663         removeCSSClass(document.documentElement,'NO_PENALTIES');
664         removeCSSClass(document.documentElement,'ONE_PENALTY');
665         removeCSSClass(document.documentElement,'MULTIPLE_PENALTIES');
666         removeCSSClass(document.documentElement,'INVALID_PATRON_EMAIL_ADDRESS');
667         removeCSSClass(document.documentElement,'INVALID_PATRON_DAY_PHONE');
668         removeCSSClass(document.documentElement,'INVALID_PATRON_EVENING_PHONE');
669         removeCSSClass(document.documentElement,'INVALID_PATRON_OTHER_PHONE');
670         removeCSSClass(document.documentElement,'PATRON_HAS_ALERT');
671         removeCSSClass(document.documentElement,'PATRON_BARRED');
672         removeCSSClass(document.documentElement,'PATRON_INACTIVE');
673         removeCSSClass(document.documentElement,'PATRON_EXPIRED');
674         removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_DOB');
675         removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
676         removeCSSClass(document.documentElement,'PATRON_AGE_GE_65');
677         removeCSSClass(document.documentElement,'PATRON_AGE_LT_65');
678         removeCSSClass(document.documentElement,'PATRON_AGE_GE_24');
679         removeCSSClass(document.documentElement,'PATRON_AGE_LT_24');
680         removeCSSClass(document.documentElement,'PATRON_AGE_GE_21');
681         removeCSSClass(document.documentElement,'PATRON_AGE_LT_21');
682         removeCSSClass(document.documentElement,'PATRON_AGE_GE_18');
683         removeCSSClass(document.documentElement,'PATRON_AGE_LT_18');
684         removeCSSClass(document.documentElement,'PATRON_AGE_GE_13');
685         removeCSSClass(document.documentElement,'PATRON_AGE_LT_13');
686         removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_1');
687         removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_2');
688         removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_3');
689
690         JSAN.use('util.network'); var net = new util.network();
691         net.simple_request('FM_MOUS_RETRIEVE.authoritative',[ ses(), patron.id() ], function(req) {
692             var summary = req.getResultObject();
693             if (summary && summary.balance_owed() > 0) addCSSClass(document.documentElement,'PATRON_HAS_BILLS');
694         });
695         net.simple_request('FM_CIRC_COUNT_RETRIEVE_VIA_USER.authoritative',[ ses(), patron.id() ], function(req) {
696             try {
697                 var co = req.getResultObject();
698                 if (co.overdue > 0 || co.long_overdue > 0) addCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
699             } catch(E) {
700                 alert(E);
701             }
702         });
703         net.simple_request('FM_AUN_RETRIEVE_ALL.authoritative',[ ses(), { 'patronid' : patron.id() } ], function(req) {
704             var notes = req.getResultObject();
705             if (notes.length > 0) addCSSClass(document.documentElement,'PATRON_HAS_NOTES');
706         });
707
708         /*
709         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
710         data.last_patron = patron.id(); data.stash('last_patron');
711         */
712
713         var penalties = patron.standing_penalties() || [];
714         penalties = penalties.filter(
715             function(p) {
716                 return (!(p.isdeleted() || p.stop_date()));
717             }
718         );
719         for (var i = 0; i < penalties.length; i++) {
720             /* this comes from /opac/common/js/utils.js */
721             addCSSClass(document.documentElement,penalties[i].standing_penalty().name());
722             if (penalties[i].standing_penalty().id() >= 100) {
723                 addCSSClass(document.documentElement,'PATRON_HAS_CUSTOM_PENALTY');
724             }
725             if (get_bool( penalties[i].standing_penalty().staff_alert() )) {
726                 addCSSClass(document.documentElement,'PATRON_HAS_STAFF_ALERT');
727             }
728             var block_list = penalties[i].standing_penalty().block_list();
729             if (block_list) {
730                 addCSSClass(document.documentElement,'PATRON_HAS_BLOCK');
731                 // TODO: futureproofing, split and loop on block_list to produce these classnames
732                 if (block_list.match('CIRC')) {
733                     addCSSClass(document.documentElement,'PATRON_HAS_CIRC_BLOCK');
734                 }
735                 if (block_list.match('RENEW')) {
736                     addCSSClass(document.documentElement,'PATRON_HAS_RENEW_BLOCK');
737                 }
738                 if (block_list.match('HOLD')) {
739                     addCSSClass(document.documentElement,'PATRON_HAS_HOLD_BLOCK');
740                 }
741                 if (block_list.match('CAPTURE')) {
742                     addCSSClass(document.documentElement,'PATRON_HAS_CAPTURE_BLOCK');
743                 }
744                 if (block_list.match('FULFILL')) {
745                     addCSSClass(document.documentElement,'PATRON_HAS_FULFILL_BLOCK');
746                 }
747             }
748         }
749
750         switch(penalties.length) {
751             case 0: addCSSClass(document.documentElement,'NO_PENALTIES'); break;
752             case 1: addCSSClass(document.documentElement,'ONE_PENALTY'); break;
753             default: addCSSClass(document.documentElement,'MULTIPLE_PENALTIES'); break;
754         }
755
756         if (patron.alert_message()) {
757             addCSSClass(document.documentElement,'PATRON_HAS_ALERT');
758         }
759
760         if (get_bool( patron.barred() )) {
761             addCSSClass(document.documentElement,'PATRON_BARRED');
762         }
763
764         if (!get_bool( patron.active() )) {
765             addCSSClass(document.documentElement,'PATRON_INACTIVE');
766         }
767
768         try { addCSSClass(document.documentElement,'PATRON_NET_ACCESS_' + patron.net_access_level()); } catch(E) {}
769
770         var now = new Date();
771         now = now.getTime()/1000;
772
773         var expire_parts = patron.expire_date().substr(0,10).split('-');
774         expire_parts[1] = expire_parts[1] - 1;
775
776         var expire = new Date();
777         expire.setFullYear(expire_parts[0], expire_parts[1], expire_parts[2]);
778         expire = expire.getTime()/1000
779
780         if (expire < now) addCSSClass(document.documentElement,'PATRON_EXPIRED');
781
782         if (patron.dob()) {
783             var age_parts = patron.dob().substr(0,10).split('-');
784             age_parts[1] = age_parts[1] - 1;
785
786             var born = new Date();
787             born.setFullYear(age_parts[0], age_parts[1], age_parts[2]);
788             born = born.getTime()/1000
789
790             var patron_age = now - born;
791             var years_old = Number(patron_age / TIME.year);
792
793             addCSSClass(document.documentElement,'PATRON_AGE_IS_' + years_old);
794
795             if ( years_old >= 65 ) addCSSClass(document.documentElement,'PATRON_AGE_GE_65');
796             if ( years_old < 65 )  addCSSClass(document.documentElement,'PATRON_AGE_LT_65');
797         
798             if ( years_old >= 24 ) addCSSClass(document.documentElement,'PATRON_AGE_GE_24');
799             if ( years_old < 24 )  addCSSClass(document.documentElement,'PATRON_AGE_LT_24');
800             
801             if ( years_old >= 21 ) addCSSClass(document.documentElement,'PATRON_AGE_GE_21');
802             if ( years_old < 21 )  addCSSClass(document.documentElement,'PATRON_AGE_LT_21');
803         
804             if ( years_old >= 18 ) addCSSClass(document.documentElement,'PATRON_AGE_GE_18');
805             if ( years_old < 18 )  addCSSClass(document.documentElement,'PATRON_AGE_LT_18');
806         
807             if ( years_old >= 13 ) addCSSClass(document.documentElement,'PATRON_AGE_GE_13');
808             if ( years_old < 13 )  addCSSClass(document.documentElement,'PATRON_AGE_LT_13');
809         } else {
810             addCSSClass(document.documentElement,'PATRON_HAS_INVALID_DOB');
811         }
812
813         if ( get_bool( patron.juvenile() ) ) addCSSClass(document.documentElement,'PATRON_JUVENILE');
814         else removeCSSClass(document.documentElement,'PATRON_JUVENILE');
815
816         if (patron.mailing_address() && typeof patron.mailing_address() == 'object') {
817             if (!get_bool(patron.mailing_address().valid())) {
818                 addCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
819             }
820         }
821         if (patron.billing_address() && typeof patron.billing_address() == 'object') {
822             if (!get_bool(patron.billing_address().valid())) {
823                 addCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
824             }
825         }
826
827     } catch(E) {
828         dump('patron.util.set_penalty_css: ' + E + '\n');
829         alert('patron.util.set_penalty_css: ' + E + '\n');
830     }
831 }
832
833 patron.util.merge = function(record_ids) {
834     var error;
835     try {
836         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
837         JSAN.use('util.error'); error = new util.error();
838         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
839         var horizontal_interface = String( data.hash.aous['ui.circ.patron_summary.horizontal'] ) == 'true';
840         var top_xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" >';
841         top_xml += '<description>' + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.merge_lead') + '</description>';
842         top_xml += '<hbox>';
843         top_xml += '<button id="lead" disabled="true" label="'
844                 + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.button.label') + '" name="fancy_submit"/>';
845         top_xml += '<button label="' + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.cancel_button.label') +'" accesskey="'
846                 + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.cancel_button.accesskey') +'" name="fancy_cancel"/></hbox></vbox>';
847
848         var xml = '<form xmlns="http://www.w3.org/1999/xhtml">';
849         xml += '<table>';
850
851         function table_cell_with_lead_button(id) {
852             var xml = '';
853             xml += '<td><input value="' + $("patronStrings").getString('staff.patron.usr_buckets.merge_records.lead')
854             xml += '" id="record_' + id + '" type="radio" name="lead"';
855             xml += ' onclick="' + "try { var x = $('lead'); x.setAttribute('value',";
856             xml += id + '); x.disabled = false; } catch(E) { alert(E); }">';
857             xml += '</input>' + $("patronStrings").getFormattedString('staff.patron.usr_buckets.merge_records.lead_record_number',[id]) + '</td>';
858             return xml;
859         }
860
861         var iframe_css;
862         if (!horizontal_interface) {
863             xml += '<tr valign="top">';
864             for (var i = 0; i < record_ids.length; i++) {
865                 xml += table_cell_with_lead_button( record_ids[i] );
866             }
867             xml += '</tr><tr valign="top">';
868             iframe_css = 'min-height: 1000px; min-width: 300px;';
869         } else {
870             iframe_css = 'min-height: 200px; min-width: 1000px;';
871         }
872         for (var i = 0; i < record_ids.length; i++) {
873             if (horizontal_interface) {
874                 xml += '<tr valign="top">' + table_cell_with_lead_button( record_ids[i] );
875             }
876             xml += '<td nowrap="nowrap"><iframe style="' + iframe_css + '" flex="1" src="' + urls.XUL_PATRON_SUMMARY; 
877             xml += '?id=' + record_ids[i] + '&amp;show_name=1"/></td>';
878             if (horizontal_interface) {
879                 xml += '</tr>';
880             }
881         }
882         if (!horizontal_interface) {
883             xml += '</tr>';
884         }
885         xml += '</table></form>';
886         JSAN.use('util.window'); var win = new util.window();
887         var fancy_prompt_data = win.open(
888             urls.XUL_FANCY_PROMPT,
889             'fancy_prompt', 'chrome,resizable,modal,width=1000,height=700',
890             {
891                 'top_xml' : top_xml, 'xml' : xml, 'title' : $("patronStrings").getString('staff.patron.usr_buckets.merge_records.fancy_prompt_title')
892             }
893         );
894
895         if (typeof fancy_prompt_data.fancy_status == 'undefined' || fancy_prompt_data.fancy_status == 'incomplete') {
896             alert($("patronStrings").getString('staff.patron.usr_buckets.merge_records.fancy_prompt.alert'));
897             return false;
898         }
899
900         JSAN.use('util.functional'); JSAN.use('util.network'); var network = new util.network();
901         var robj = network.simple_request('FM_AU_MERGE', 
902             [ 
903                 ses(), 
904                 fancy_prompt_data.lead,
905                 util.functional.filter_list( record_ids,
906                     function(o) {
907                         return o != fancy_prompt_data.lead;
908                     }
909                 )
910             ]
911         );
912         if (Number(robj) != 1) { throw(robj); }
913         return fancy_prompt_data.lead;
914     } catch(E) {
915         dump('patron.util.merge: ' + js2JSON(E) + '\n');
916         try { error.standard_unexpected_error_alert('Error in patron.util.merge',E); } catch(F) { alert('patron.util.merge: ' + E + '\n'); }
917         return false;
918     }
919 }
920
921 patron.util.format_name = function(patron_obj) {
922     var patron_name = ( patron_obj.prefix() ? patron_obj.prefix() + ' ' : '') +
923         patron_obj.family_name() + ', ' +
924         patron_obj.first_given_name() + ' ' +
925         ( patron_obj.second_given_name() ? patron_obj.second_given_name() + ' ' : '' ) +
926         ( patron_obj.suffix() ? patron_obj.suffix() : ''); 
927     return patron_name;
928 }
929
930 patron.util.work_log_patron_edit = function(p) {
931     var error;
932     try {
933         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
934         JSAN.use('util.error'); error = new util.error();
935         error.work_log(
936             document.getElementById('patronStrings').getFormattedString(
937                 'staff.circ.work_log_patron_edit.message',
938                 [
939                     ses('staff_usrname'),
940                     p.family_name(),
941                     p.card().barcode()
942                 ]
943             ), {
944                 'au_id' : p.id(),
945                 'au_family_name' : p.family_name(),
946                 'au_barcode' : p.card().barcode()
947             }
948         );
949     } catch(E) {
950         error.sdump('D_ERROR','Error with work_logging in menu.js, cmd_patron_register:' + E);
951     }
952 }
953
954
955 dump('exiting patron/util.js\n');