]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/bill2.js
LP2061136 - Stamping 1405 DB upgrade script
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / patron / bill2.js
1 function my_init() {
2     try {
3         if (typeof JSAN == 'undefined') { throw( $("commonStrings").getString('common.jsan.missing') ); }
4         JSAN.errorLevel = "die"; // none, warn, or die
5         JSAN.addRepository('/xul/server/');
6
7         JSAN.use('util.error'); g.error = new util.error();
8         JSAN.use('util.network'); g.network = new util.network();
9         JSAN.use('util.date');
10         JSAN.use('util.money');
11         JSAN.use('util.widgets');
12         JSAN.use('patron.util');
13         JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
14         g.data.voided_billings = []; g.data.stash('voided_billings');
15
16         g.error.sdump('D_TRACE','my_init() for bill2.xul');
17         window.bill_event_listeners = new EventListenerList();
18
19         document.title = $("patronStrings").getString('staff.patron.bill_history.my_init.current_bills');
20
21         g.funcs = []; g.bill_map = {}; g.row_map = {}; g.check_map = {};
22
23         g.safe_for_refresh = false;
24
25         g.patron_id = xul_param('patron_id');
26
27         $('circulating_hint').hidden = true;
28
29         init_lists();
30
31         retrieve_mbts_for_list();
32
33         event_listeners();
34
35         JSAN.use('util.exec'); var exec = new util.exec(20); 
36         exec.on_error = function(E) { alert(E); return true; }
37         exec.timer(g.funcs,100);
38
39         $('credit_forward').setAttribute('value','???');
40         if (!g.patron) {
41             refresh_patron();
42         } else {
43             $('credit_forward').setAttribute('value',util.money.sanitize( g.patron.credit_forward_balance() ));
44         }
45
46         if (g.data.hash.aous['circ.disable_patron_credit']) {
47             var nodes = document.getElementsByClassName('hide_patron_credit');
48             for (var i = 0; i < nodes.length; i++) 
49                 nodes[i].setAttribute('hidden', true);
50         }
51
52         if (g.data.hash.aous['ui.circ.billing.uncheck_bills_and_unfocus_payment_box']) {
53             g.funcs.push(
54                 function() {
55                     $('uncheck_all').focus();
56                     tally_all();
57                 }
58             );
59         } else {
60             g.funcs.push(
61                 function() {
62                     default_focus();
63                     tally_all();
64                 }
65             );
66         }
67
68         g.funcs.push( function() { g.safe_for_refresh = true; } );
69
70     } catch(E) {
71         var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/bill2.xul', E]);
72         try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
73         alert(err_msg);
74     }
75 }
76
77 function my_cleanup() {
78     try {
79         window.bill_event_listeners.removeAll();
80         g.bill_list.cleanup();
81         g.bill_list.clear();
82     } catch(E) {
83         var err_msg = $("commonStrings").getFormattedString('common.exception', ['patron/bill2.xul', E]);
84         try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
85         alert(err_msg);
86     }
87 }
88
89 function event_listeners() {
90     try {
91         window.bill_event_listeners.add($('details'), 
92             'command',
93             handle_details,
94             false
95         );
96
97         window.bill_event_listeners.add($('add'), 
98             'command',
99             handle_add,
100             false
101         );
102
103         window.bill_event_listeners.add($('voidall'), 
104             'command',
105             handle_void_all,
106             false
107         );
108
109         window.bill_event_listeners.add($('refund'), 
110             'command',
111             handle_refund,
112             false
113         );
114
115         window.bill_event_listeners.add($('adjust_to_zero'),
116             'command',
117             handle_adjust_to_zero,
118             false
119         );
120
121         window.bill_event_listeners.add($('opac'), 
122             'command',
123             handle_opac,
124             false
125         );
126
127         window.bill_event_listeners.add($('copy_details'), 
128             'command',
129             handle_copy_details,
130             false
131         );
132
133         window.bill_event_listeners.add($('payment'), 
134             'change',
135             function(ev) {
136                 if ($('payment_type').value == 'credit_payment') {
137                     JSAN.use('util.money');
138                     JSAN.use('patron.util'); g.patron = patron.util.retrieve_fleshed_au_via_id(ses(),g.patron_id,null);
139                     var proposed = util.money.dollars_float_to_cents_integer(ev.target.value);
140                     var available = util.money.dollars_float_to_cents_integer(g.patron.credit_forward_balance());
141                     if (proposed > available) {
142                         alert($("patronStrings").getFormattedString('staff.patron.bills.bill_payment_amount.credit_amount', [g.patron.credit_forward_balance()]));
143                         ev.target.value = util.money.cents_as_dollars( available );
144                         ev.target.setAttribute('value',ev.target.value);
145                     }
146                 }
147                 distribute_payment(); 
148             },
149             false
150         );
151
152         window.bill_event_listeners.add($('payment'), 
153             'focus',
154             function(ev) { ev.target.select(); },
155             false
156         );
157
158         window.bill_event_listeners.add($('payment'), 
159             'keypress',
160             function(ev) {
161                 if (! (ev.keyCode == 13 /* enter */ || ev.keyCode == 77 /* mac enter */) ) { return; }
162                 if (!verify_amount()) { return; }
163                 distribute_payment();
164                 $('apply_payment_btn').focus();
165             },
166             false
167         );
168
169         window.bill_event_listeners.add($('bill_patron_btn'), 
170             'command',
171             function() {
172                 JSAN.use('util.window'); var win = new util.window();
173                 var my_xulG = win.open(
174                     urls.XUL_PATRON_BILL_WIZARD,
175                     'billwizard',
176                     'chrome,resizable,modal',
177                     { 'patron_id' : g.patron_id }
178                 );
179                 if (my_xulG.xact_id) {
180                     g.funcs.push( gen_list_append_func( my_xulG.xact_id ) );
181                     if (typeof window.xulG == 'object' && typeof window.xulG.on_money_change == 'function') window.xulG.on_money_change();
182                 }
183             },
184             false
185         );
186
187         window.bill_event_listeners.add($('bill_history_btn'), 
188             'command',
189             function() {
190                 xulG.display_window.g.patron.right_deck.reset_iframe( 
191                     urls.XUL_PATRON_BILL_HISTORY,
192                     {},
193                     {
194                         'patron_id' : g.patron_id,
195                         'refresh' : function() { refresh(); },
196                         'new_tab' : xulG.new_tab,
197                         'url_prefix' : xulG.url_prefix
198                     }
199                 );
200             },
201             false
202         );
203
204         window.bill_event_listeners.add($('convert_change_to_credit'), 
205             'command',
206             function(ev) {
207                 if (ev.target.checked) {
208                     addCSSClass( $('change_due'), 'change_to_credit' );
209                 } else {
210                     removeCSSClass( $('change_due'), 'change_to_credit' );
211                 }
212             },
213             false
214         );
215
216         window.bill_event_listeners.add($('apply_payment_btn'), 
217             'command',
218             function(ev) {
219                 try {
220                     $('apply_payment_btn').disabled = true;
221                     if (verify_amount()) {
222                         apply_payment();
223                         tally_all();
224                     }
225                     $('apply_payment_btn').disabled = false;
226                 } catch(E) {
227                     alert('Error in bill2.js, apply_payment_btn: ' + E);
228                 }
229             },
230             false
231         );
232
233     } catch(E) {
234         alert('Error in bill2.js, event_listeners(): ' + E);
235     }
236 }
237
238 function $(id) { return document.getElementById(id); }
239
240 function default_focus() {
241     try { $('payment').focus(); } catch(E) { alert('Error in default_focus(): ' + E); }
242 }
243
244 function tally_pending() {
245     try {
246         var payments = [];
247         JSAN.use('util.money');
248         var tb = $('payment');
249         var payment_tendered = util.money.dollars_float_to_cents_integer( tb.value );
250         var payment_pending = 0;
251         var retrieve_ids = g.bill_list.dump_retrieve_ids();
252         for (var i = 0; i < retrieve_ids.length; i++) {
253             var row_params = g.row_map[retrieve_ids[i]];
254             if (g.check_map[retrieve_ids[i]]) { 
255                 var value = util.money.dollars_float_to_cents_integer( row_params.row.my.payment_pending );
256                 payment_pending += value;
257                 if (value != '0.00') { payments.push( [ retrieve_ids[i], util.money.cents_as_dollars(value) ] ); }
258             }
259         }
260         var change_pending = payment_tendered - payment_pending;
261         $('pending_payment').value = util.money.cents_as_dollars( payment_pending );
262         $('pending_change').value = util.money.cents_as_dollars( change_pending );
263         $('change_due').value = util.money.cents_as_dollars( change_pending );
264         return { 'payments' : payments, 'change' : util.money.cents_as_dollars( change_pending ) };
265     } catch(E) {
266         alert('Error in bill2.js, tally_pending(): ' + E);
267     }
268 }
269
270 function tally_selected() {
271     try {
272         JSAN.use('util.money');
273         var selected_billed = 0;
274         var selected_paid = 0;
275         var selected_balance = 0;
276
277         for (var i = 0; i < g.bill_list_selection.length; i++) {
278             var bill = g.bill_map[g.bill_list_selection[i]];
279             if (!bill) {
280                 //$('checked_owed').setAttribute('value', '???');
281                 //$('checked_billed').setAttribute('value', '???');
282                 //$('checked_paid').setAttribute('value', '???');
283                 return;
284             }
285             var to = util.money.dollars_float_to_cents_integer( bill.transaction.total_owed() );
286             var tp = util.money.dollars_float_to_cents_integer( bill.transaction.total_paid() );
287             var bo = util.money.dollars_float_to_cents_integer( bill.transaction.balance_owed() );
288             selected_billed += to;
289             selected_paid += tp;
290             selected_balance += bo;
291         }
292         //$('checked_billed').setAttribute('value', util.money.cents_as_dollars( selected_billed ) );
293         //$('checked_paid').setAttribute('value', util.money.cents_as_dollars( selected_paid ) );
294         //$('checked_owed').setAttribute('value', util.money.cents_as_dollars( selected_balance ) );
295     } catch(E) {
296         alert('Error in bill2.js, tally_selected(): ' + E);
297     }
298 }
299
300 function tally_voided() {
301     try {
302         JSAN.use('util.money');
303         var voided_total = 0;
304
305         g.data.stash_retrieve();
306
307         for (var i = 0; i < g.data.voided_billings.length; i++) {
308             var billing = g.data.voided_billings[i];
309             var bv = util.money.dollars_float_to_cents_integer( billing.amount() );
310             voided_total += bv;
311         }
312         $('currently_voided').setAttribute('value', util.money.cents_as_dollars( voided_total ) );
313     } catch(E) {
314         alert('Error in bill2.js, tally_voided(): ' + E);
315     }
316 }
317
318 function tally_all() {
319     try {
320         JSAN.use('util.money');
321         var checked_billed = 0;
322         var checked_paid = 0;
323         var checked_balance = 0;
324         var total_billed = 0;
325         var total_paid = 0;
326         var total_balance = 0;
327         var refunds_owed = 0;
328
329         var retrieve_ids = g.bill_list.dump_retrieve_ids();
330         for (var i = 0; i < retrieve_ids.length; i++) {
331             var bill = g.bill_map[retrieve_ids[i]];
332             if (!bill) {
333                 $('checked_owed').value = '???';
334                 $('checked_owed2').setAttribute('value', '???');
335                 $('checked_billed').value = '???';
336                 $('checked_paid').value = '???';
337                 $('tb_total_owed').value = '???';
338                 $('total_owed2').setAttribute('value', '???');
339                 $('total_billed').value = '???';
340                 $('tb_total_paid').value = '???';
341                 $('refunds_owed').setAttribute('value', '???');
342                 return;
343             }
344             var to = util.money.dollars_float_to_cents_integer( bill.transaction.total_owed() );
345             var tp = util.money.dollars_float_to_cents_integer( bill.transaction.total_paid() );
346             var bo = util.money.dollars_float_to_cents_integer( bill.transaction.balance_owed() );
347             total_billed += to;
348             total_paid += tp;
349             total_balance += bo;
350             if ( bo < 0 ) refunds_owed += bo;
351             if (g.check_map[retrieve_ids[i]]) {
352                 checked_billed += to;
353                 checked_paid += tp;
354                 checked_balance += bo;
355             }
356         }
357         $('checked_billed').value = util.money.cents_as_dollars( checked_billed );
358         $('checked_paid').value = util.money.cents_as_dollars( checked_paid );
359         $('checked_owed').value = util.money.cents_as_dollars( checked_balance );
360         $('checked_owed2').setAttribute('value', util.money.cents_as_dollars( checked_balance ) );
361         $('total_billed').value = util.money.cents_as_dollars( total_billed );
362         $('tb_total_paid').value = util.money.cents_as_dollars( total_paid );
363         $('tb_total_owed').value = util.money.cents_as_dollars( total_balance );
364         $('total_owed2').setAttribute('value', util.money.cents_as_dollars( total_balance ) );
365         $('refunds_owed').setAttribute('value', util.money.cents_as_dollars( Math.abs( refunds_owed ) ) );
366         // tally_selected();
367     } catch(E) {
368         alert('Error in bill2.js, tally_all(): ' + E);
369     }
370 }
371
372 function handle_refund() {
373     if(g.bill_list_selection.length > 1) {
374         var msg = $("patronStrings").getFormattedString('staff.patron.bills.handle_refund.message_plural', [g.bill_list_selection]);
375     } else {
376         var msg = $("patronStrings").getFormattedString('staff.patron.bills.handle_refund.message_singular', [g.bill_list_selection]);
377     }
378         
379     var r = g.error.yns_alert(msg,
380         $("patronStrings").getString('staff.patron.bills.handle_refund.title'),
381         $("patronStrings").getString('staff.patron.bills.handle_refund.btn_yes'),
382         $("patronStrings").getString('staff.patron.bills.handle_refund.btn_no'),null);
383     if (r == 0) {
384         for (var i = 0; i < g.bill_list_selection.length; i++) {
385             var bill_id = g.bill_list_selection[i];
386             //alert('g.check_map['+bill_id+'] = '+g.check_map[bill_id]+' bill_map['+bill_id+'] = ' + js2JSON(g.bill_map[bill_id]));
387             g.check_map[bill_id] = true;
388             var row_params = g.row_map[bill_id];
389             row_params.row.my.checked = true;
390             g.bill_list.refresh_row(row_params);
391         }
392     }
393     tally_all();
394     distribute_payment();
395 }
396
397 /**
398  * Calls open-ils.circ.money.billable_xact.adjust_to_zero on selected
399  * transactions to produce a zero-balance transaction.
400  * Successfully cleared transactions will disappear from the billing list.
401  */
402 function handle_adjust_to_zero() {
403
404     var msgkey = g.bill_list_selection.length > 1 ?
405         'staff.patron.bills.handle_adjust_to_zero.message_plural' :
406         'staff.patron.bills.handle_adjust_to_zero.message_singular';
407
408     var msg = $("patronStrings").getFormattedString(
409         msgkey, [g.bill_list_selection]);
410
411     var r = g.error.yns_alert(msg,
412         $("patronStrings").getString(
413             'staff.patron.bills.handle_adjust_to_zero.title'),
414         $("patronStrings").getString(
415             'staff.patron.bills.handle_adjust_to_zero.btn_yes'),
416         $("patronStrings").getString(
417             'staff.patron.bills.handle_adjust_to_zero.btn_no'),null);
418     if (r == 0) {
419         var xact_ids = [];
420         for (var i = 0; i < g.bill_list_selection.length; i++) {
421             var bill_id = g.bill_list_selection[i];
422             xact_ids.push(bill_id);
423         }
424
425         var mod_ids = g.network.simple_request(
426             'ADJUST_BILLS_TO_ZERO', [ses(), xact_ids]);
427
428         g.error.sdump('D_DEBUG', 'adjusted to zero transactions ' + mod_ids);
429
430         refresh();
431         tally_all();
432         distribute_payment();
433     }
434 }
435
436
437 function check_all() {
438     try {
439         for (var i in g.bill_map) {
440             g.check_map[i] = true;
441             var row_params = g.row_map[i];
442             row_params.row.my.checked = true;
443             g.bill_list.refresh_row(row_params);
444         }
445         tally_all();
446         distribute_payment();
447     } catch(E) {
448         alert('Error in bill2.js, check_all(): ' + E);
449     }
450
451 }
452
453 function uncheck_all() {
454     try {
455         for (var i in g.bill_map) {
456             g.check_map[i] = false;
457             var row_params = g.row_map[i];
458             row_params.row.my.checked = false;
459             g.bill_list.refresh_row(row_params);
460         }
461         tally_all();
462         distribute_payment();
463     } catch(E) {
464         alert('Error in bill2.js, check_all(): ' + E);
465     }
466
467 }
468
469 function check_all_refunds() {
470     try {
471         for (var i in g.bill_map) {
472             if ( Number( g.bill_map[i].transaction.balance_owed() ) < 0 ) {
473                 g.check_map[i] = true;
474                 var row_params = g.row_map[i];
475                 row_params.row.my.checked = true;
476                 g.bill_list.refresh_row(row_params);
477             }
478         }
479         tally_all();
480         distribute_payment();
481     } catch(E) {
482         alert('Error in bill2.js, check_all_refunds(): ' + E);
483     }
484 }
485
486 function gen_list_append_func(r) {
487     return function() {
488         var default_check_state = g.data.hash.aous[
489             'ui.circ.billing.uncheck_bills_and_unfocus_payment_box'
490         ] ? false : true;
491         if (typeof r == 'object') {
492             g.row_map[ r.id() ] = g.bill_list.append( {
493                 'retrieve_id' : r.id(),
494                 'flesh_immediately' : true,
495                 'row' : {
496                     'my' : {
497                         'checked' : default_check_state,
498                         'mbts' : r
499                     }
500                 }
501             } );
502         } else {
503             g.row_map[r] = g.bill_list.append( {
504                 'retrieve_id' : r,
505                 'flesh_immediately' : true,
506                 'row' : {
507                     'my' : {
508                         'checked' : default_check_state
509                     }
510                 }
511             } );
512         }
513     }
514 }
515
516 function retrieve_mbts_for_list() {
517     var method = 'FM_MBTS_IDS_RETRIEVE_ALL_HAVING_BALANCE.authoritative';
518     g.mbts_ids = g.network.simple_request(method,[ses(),g.patron_id]);
519     if (g.mbts_ids.ilsevent) {
520         switch(Number(g.mbts_ids.ilsevent)) {
521             case -1: g.error.standard_network_error_alert($("patronStrings").getString('staff.patron.bill_history.retrieve_mbts_for_list.close_win_try_again')); break;
522             default: g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.bill_history.retrieve_mbts_for_list.close_win_try_again'),g.mbts_ids); break;
523         }
524     } else if (g.mbts_ids == null) {
525         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.bill_history.retrieve_mbts_for_list.close_win_try_again'),null);
526     } else {
527    
528         g.mbts_ids.reverse();
529         g.safe_for_refresh = false;
530         for (var i = 0; i < g.mbts_ids.length; i++) {
531             dump('i = ' + i + ' g.mbts_ids[i] = ' + g.mbts_ids[i] + '\n');
532             g.funcs.push( gen_list_append_func(g.mbts_ids[i]) );
533         }
534         g.funcs.push( function() { g.safe_for_refresh = true; } );
535     }
536 }
537
538 function init_lists() {
539     JSAN.use('util.list'); JSAN.use('circ.util'); 
540
541     g.bill_list_selection = [];
542
543     g.bill_list = new util.list('bill_tree');
544
545     g.bill_list.init( {
546         'columns' : 
547             [
548                 {
549                     'id' : 'select', 'primary' : true, 'type' : 'checkbox', 'editable' : true, 'label' : '', 'style' : 'min-width: 3em;',
550                     'render' : function(my) { return String( my.checked ) == 'true'; }, 
551                 }
552             ].concat(
553                 patron.util.mbts_columns({
554                     'mbts_xact_finish' : { 'hidden' : true }
555                 }
556             ).concat( 
557                 circ.util.columns({ 
558                     'title' : { 'hidden' : false, 'flex' : '3' }
559                 }
560             ).concat( 
561                 [
562                     {
563                         'id' : 'payment_pending', 'editable' : false, 'sort_type' : 'money', 
564                         'label' : $('patronStrings').getString('staff.patron.bill_interface.payment_pending.column_header'),
565                         'render' : function(my) { return my.payment_pending || '0.00'; }, 
566                     }
567                 ]
568             ))),
569         'on_select' : function(ev) {
570             JSAN.use('util.functional');
571             g.bill_list_selection = util.functional.map_list(
572                 g.bill_list.retrieve_selection(),
573                 function(o) { return o.getAttribute('retrieve_id'); }
574             );
575             //tally_selected();
576             $('details').setAttribute('disabled', g.bill_list_selection.length == 0);
577             $('add').setAttribute('disabled', g.bill_list_selection.length == 0);
578             $('voidall').setAttribute('disabled', g.bill_list_selection.length == 0);
579             $('adjust_to_zero').setAttribute('disabled', g.bill_list_selection.length == 0);
580             $('refund').setAttribute('disabled', g.bill_list_selection.length == 0);
581             $('opac').setAttribute('disabled', g.bill_list_selection.length == 0);
582             $('copy_details').setAttribute('disabled', g.bill_list_selection.length == 0);
583         },
584         'on_click' : function(ev) {
585             var row = {}; var col = {}; var nobj = {};
586             g.bill_list.node.treeBoxObject.getCellAt(ev.clientX,ev.clientY,row,col,nobj);
587             if (row.value == -1) return;
588             var treeItem = g.bill_list.node.contentView.getItemAtIndex(row.value);
589             if (treeItem.nodeName != 'treeitem') return;
590             var treeRow = treeItem.firstChild;
591             var treeCell = treeRow.firstChild.nextSibling;
592             if (g.check_map[ treeItem.getAttribute('retrieve_id') ] != (treeCell.getAttribute('value') == 'true')) {
593                 g.check_map[ treeItem.getAttribute('retrieve_id') ] = treeCell.getAttribute('value') == 'true';
594                 g.row_map[ treeItem.getAttribute('retrieve_id') ].row.my.checked = treeCell.getAttribute('value') == 'true';
595                 tally_all();
596                 distribute_payment();
597             }
598         },
599         'on_sort' : function() {
600             tally_all();
601         },
602         'on_checkbox_toggle' : function(toggle) {
603             try {
604                 var retrieve_ids = g.bill_list.dump_retrieve_ids();
605                 for (var i = 0; i < retrieve_ids.length; i++) {
606                     g.check_map[ retrieve_ids[i] ] = (toggle=='on');
607                     g.row_map[ retrieve_ids[i] ].row.my.checked = (toggle=='on');
608                 }
609                 tally_all();
610             } catch(E) {
611                 alert('error in on_checkbox_toggle(): ' + E);
612             }
613         },
614         'retrieve_row' : function(params) {
615             try {
616                 var id = params.retrieve_id;
617                 var row = params.row;
618
619                 function handle_props(row) {
620                     try {
621                         if ( row && row.my && row.my.mbts && Number( row.my.mbts.balance_owed() ) < 0 ) {
622                             util.widgets.addProperty(params.treeitem_node.firstChild,'refundable');
623                             util.widgets.addProperty(params.treeitem_node.firstChild.childNodes[ g.payment_pending_column_idx ],'refundable');
624                         }
625                         if ( row && row.my && row.my.circ && ! row.my.circ.checkin_time() ) {
626                             var style_type = 'circulating';
627                             var stop_fines = row.my.circ.stop_fines() || '';
628
629                             // we have custom syling for these stop-fines reasons
630                             if (stop_fines.match(/LOST|LONGOVERDUE/)) 
631                                 style_type = stop_fines.toLowerCase();
632
633                             $(style_type + '_hint').hidden = false;
634
635                             // style every cell in the row
636                             for (var n in params.treeitem_node.firstChild.childNodes) {
637                                 try {
638                                     util.widgets.addProperty(
639                                         params.treeitem_node.firstChild.childNodes[n], 
640                                         style_type
641                                     );
642                                 } catch(E) {}
643                             }
644                         }
645                     } catch(E) {
646                         g.error.sdump('D_WARN','Error setting list properties in bill2.js: ' + E);
647                         alert('Error setting list properties in bill2.js: ' + E);
648                     }
649                 }
650
651                 if (id) {
652                     if (typeof row.my == 'undefined') row.my = {};
653                     if (typeof row.my.mbts == 'undefined' ) {
654                         g.network.simple_request('BLOB_MBTS_DETAILS_RETRIEVE',[ses(),id], function(req) {
655                             var blob = req.getResultObject();
656                             row.my.mbts = blob.transaction;
657                             row.my.circ = blob.circ;
658                             row.my.acp = blob.copy;
659                             row.my.mvr = blob.record;
660                             if (typeof params.on_retrieve == 'function') {
661                                 if ( row.my.mbts && Number( row.my.mbts.balance_owed() ) < 0 ) {
662                                     row.my.checked = false;
663                                 }
664                                 handle_props(row);
665                                 params.on_retrieve(row);
666                             };
667                             g.bill_map[ id ] = blob;
668                             g.check_map[ id ] = row.my.checked;
669                             tally_all();
670                         } );
671                     } else {
672                         if (typeof params.on_retrieve == 'function') { 
673                             handle_props(row);
674                             params.on_retrieve(row); 
675                         }
676                     }
677                 } else {
678                     if (typeof params.on_retrieve == 'function') { 
679                         params.on_retrieve(row); 
680                     }
681                 }
682
683                 return row;
684             } catch(E) {
685                 alert('Error in bill2.js, retrieve_row(): ' + E);
686             }
687         }
688     } );
689
690     g.title_column_idx = util.functional.map_list( g.bill_list.columns, function(o) { return o.id; } ).indexOf( 'title' );
691     g.payment_pending_column_idx = util.functional.map_list( g.bill_list.columns, function(o) { return o.id; } ).indexOf( 'payment_pending' );
692     $('bill_list_actions').appendChild( g.bill_list.render_list_actions() );
693     g.bill_list.set_list_actions();
694 }
695
696 function handle_add() {
697     if(g.bill_list_selection.length > 1) {
698         var msg = $("patronStrings").getFormattedString('staff.patron.bill_history.handle_add.message_plural', [g.bill_list_selection]);
699     } else {
700         var msg = $("patronStrings").getFormattedString('staff.patron.bill_history.handle_add.message_singular', [g.bill_list_selection]);
701     }
702         
703     var r = g.error.yns_alert(msg,
704         $("patronStrings").getString('staff.patron.bill_history.handle_add.title'),
705         $("patronStrings").getString('staff.patron.bill_history.handle_add.btn_yes'),
706         $("patronStrings").getString('staff.patron.bill_history.handle_add.btn_no'),null,
707         $("patronStrings").getString('staff.patron.bill_history.handle_add.confirm_message'));
708     if (r == 0) {
709         JSAN.use('util.window');
710         var win = new util.window();
711         for (var i = 0; i < g.bill_list_selection.length; i++) {
712             var w = win.open(
713                 urls.XUL_PATRON_BILL_WIZARD,
714                 'billwizard',
715                 'chrome,resizable,modal',
716                 { 'patron_id' : g.patron_id, 'xact_id' : g.bill_list_selection[i] }
717             );
718         }
719         refresh();
720         if (typeof window.xulG == 'object' && typeof window.xulG.refresh == 'function') window.xulG.refresh();
721     }
722 }
723
724 function handle_void_all() {
725     var prohibit_default = g.data.hash.aous['bill.prohibit_negative_balance_default'];
726     var prohibit_on_overdues = g.data.hash.aous['bill.prohibit_negative_balance_on_overdues'];
727     if (prohibit_on_overdues === undefined) prohibit_on_overdues = prohibit_default;
728     var prohibit_on_lost = g.data.hash.aous['bill.prohibit_negative_balance_on_lost'];
729     if (prohibit_on_lost === undefined) prohibit_on_lost = prohibit_default;
730
731     if (prohibit_on_overdues || prohibit_on_lost) {
732         var choice = g.error.yns_alert_original(
733             $("patronStrings").getString('staff.patron.bills.void_warning.message'),
734             $("patronStrings").getString('staff.patron.bills.void_warning.title'),
735             $('commonStrings').getString('common.yes'),
736             $('commonStrings').getString('common.no'),
737             null,
738             $('commonStrings').getString('common.confirm')
739         );
740         if (choice != 0) return;
741     }
742     if(g.bill_list_selection.length > 1) {
743         var msg = $("patronStrings").getFormattedString('staff.patron.bill_history.handle_void.message_plural', [g.bill_list_selection]);
744     } else {
745         var msg = $("patronStrings").getFormattedString('staff.patron.bill_history.handle_void.message_singular', [g.bill_list_selection]);
746     }
747         
748     var r = g.error.yns_alert(msg,
749         $("patronStrings").getString('staff.patron.bill_history.handle_void.title'),
750         $("patronStrings").getString('staff.patron.bill_history.handle_void.btn_yes'),
751         $("patronStrings").getString('staff.patron.bill_history.handle_void.btn_no'),null,
752         $("patronStrings").getString('staff.patron.bill_history.handle_void.confirm_message'));
753     if (r == 0) {
754         for (var i = 0; i < g.bill_list_selection.length; i++) {
755             void_all_billings( g.bill_list_selection[i] );
756         }
757         refresh();
758         if (typeof window.xulG == 'object' && typeof window.xulG.refresh == 'function') window.xulG.refresh();
759         if (typeof window.xulG == 'object' && typeof window.xulG.on_money_change == 'function') window.xulG.on_money_change();
760     }
761 }
762
763 function handle_opac() {
764     try {
765         var ids = [];
766         for (var i = 0; i < g.bill_list_selection.length; i++) {
767             var my_mvr = g.bill_map[ g.bill_list_selection[i] ].record;
768             var my_acp = g.bill_map[ g.bill_list_selection[i] ].copy;
769             if (typeof my_mvr != 'undefined' && my_mvr != null) {
770                 ids.push( { 'barcode' : my_acp.barcode(), 'doc_id' : my_mvr.doc_id() } );
771             }
772         }
773         JSAN.use('cat.util');
774         cat.util.show_in_opac( ids );
775     } catch(E) {
776         alert('Error in bill2.js, handle_opac: ' + E);
777     }
778 }
779
780 function handle_copy_details() {
781     try {
782         var ids = [];
783         for (var i = 0; i < g.bill_list_selection.length; i++) {
784             var my_acp = g.bill_map[ g.bill_list_selection[i] ].copy;
785             if (typeof my_acp != 'undefined' && my_acp != null) {
786                 ids.push( my_acp.barcode() );
787             }
788         }
789         JSAN.use('circ.util');
790         circ.util.item_details_new( ids );
791     } catch(E) {
792         alert('Error in bill2.js, handle_opac: ' + E);
793     }
794 }
795
796 function handle_details() {
797     JSAN.use('util.window'); var win = new util.window();
798     for (var i = 0; i < g.bill_list_selection.length; i++) {
799         var my_xulG = win.open(
800             urls.XUL_PATRON_BILL_DETAILS,
801             'test_billdetails_' + g.bill_list_selection[i],
802             'chrome,resizable',
803             {
804                 'patron_id' : g.patron_id,
805                 'mbts_id' : g.bill_list_selection[i],
806                 'refresh' : function() {
807                     refresh(); 
808                     if (typeof window.xulG == 'object' && typeof window.xulG.refresh == 'function') window.xulG.refresh();
809                 }, 
810                 'new_tab' : xulG.new_tab,
811                 'url_prefix' : xulG.url_prefix
812             }
813         );
814     }
815 }
816
817 function print_bills() {
818     try {
819         var template = 'bills_current';
820         JSAN.use('patron.util');
821         g.patron = patron.util.retrieve_fleshed_au_via_id(ses(),g.patron_id,null); 
822         g.bill_list.print({ 
823               'patron' : g.patron
824             , 'printer_context' : 'receipt'
825             , 'template' : template
826             , 'data' : {
827                   grand_total_owed:   $('tb_total_owed').value
828                 , grand_total_billed: $('total_billed').value
829                 , grand_total_paid:   $('tb_total_paid').value
830             }
831          });
832     } catch(E) {
833         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.bill_history.print_bills.print_error'), E);
834     }
835 }
836
837 function distribute_payment() {
838     try {
839         JSAN.use('util.money');
840         var tb = $('payment');
841         tb.value = util.money.cents_as_dollars( util.money.dollars_float_to_cents_integer( tb.value ) );
842         tb.setAttribute('value', tb.value );
843         var total = util.money.dollars_float_to_cents_integer( tb.value );
844         if (total < 0) { tb.value = '0.00'; tb.setAttribute('value','0.00'); total = 0; }
845         var retrieve_ids = g.bill_list.dump_retrieve_ids();
846         for (var i = 0; i < retrieve_ids.length; i++) {
847             var row_params = g.row_map[retrieve_ids[i]];
848             if (g.check_map[retrieve_ids[i]]) { 
849                 var bill = g.bill_map[retrieve_ids[i]].transaction;
850                 var bo = util.money.dollars_float_to_cents_integer( bill.balance_owed() );
851                 if ( bo > total ) {
852                     row_params.row.my.payment_pending = util.money.cents_as_dollars( total );
853                     total = 0;
854                 } else {
855                     row_params.row.my.payment_pending = util.money.cents_as_dollars( bo );
856                     total = total - bo;
857                 }
858             } else {
859                 row_params.row.my.payment_pending = '0.00';
860             }
861             g.bill_list.refresh_row(row_params);
862         }
863         tally_pending();
864     } catch(E) {
865         alert('Error in bill2.js, distribute_payment(): ' + E);
866     }
867 }
868
869 function verify_amount() {
870
871     try {
872         var amt_warn = Number(g.data.hash.aous['ui.circ.billing.amount_warn']) || 1000;
873         var amt_limit = Number(g.data.hash.aous['ui.circ.billing.amount_limit']) || 100000;
874         var box = $('payment');
875         var amt = Number(box.value);
876
877         if (amt <= amt_warn) { return true;}
878
879         if (amt > amt_limit) {
880             alert($("patronStrings").getFormattedString('staff.patron.bills.pay.over_limit', [amt_limit]));
881         } else {
882             var r = g.error.yns_alert(
883                     $('patronStrings').getFormattedString('staff.patron.bills.pay.over_warn_limit', [amt]),
884                     $('patronStrings').getString('staff.patron.bills.pay.over_warn_limit.title'),
885                     $('commonStrings').getString('common.yes'),
886                     $('commonStrings').getString('common.no'),
887                     null
888                 );
889             if (r == 0) { return true; }
890         }
891
892         box.value = ''; box.select(); box.focus();
893         distribute_payment();
894         return false;
895
896     } catch (e) {
897       return false;
898     }
899
900 }
901
902
903 function apply_payment() {
904     try {
905         var payment_blob = {};
906         JSAN.use('util.window');
907         var win = new util.window();
908         switch($('payment_type').value) {
909             case 'credit_card_payment' :
910                 g.data.temp = '';
911                 g.data.stash('temp');
912                 var my_xulG = win.open(
913                     urls.XUL_PATRON_BILL_CC_INFO,
914                     'billccinfo',
915                     'chrome,resizable,modal',
916                     {'patron_id': g.patron_id}
917                 );
918                 g.data.stash_retrieve();
919                 payment_blob = JSON2js( g.data.temp ); // FIXME - replace with my_xulG and update_modal_xulG, though it looks like we were using that before and moved away from it
920             break;
921             case 'check_payment' :
922                 g.data.temp = '';
923                 g.data.stash('temp');
924                 var my_xulG = win.open(
925                     urls.XUL_PATRON_BILL_CHECK_INFO,
926                     'billcheckinfo',
927                     'chrome,resizable,modal'
928                 );
929                 g.data.stash_retrieve();
930                 payment_blob = JSON2js( g.data.temp );
931             break;
932         }
933         if (
934             (typeof payment_blob == 'undefined') || 
935             payment_blob=='' || 
936             payment_blob.cancelled=='true'
937         ) { 
938             alert( $('commonStrings').getString('common.cancelled') ); 
939             return; 
940         }
941         payment_blob.userid = g.patron_id;
942         payment_blob.note = payment_blob.note || '';
943         //payment_blob.cash_drawer = 1; // FIXME: get new Config() to work
944         payment_blob.payment_type = $('payment_type').value;
945         var tally_blob = tally_pending();
946         payment_blob.payments = tally_blob.payments;
947         // Handle patron credit
948         if ( payment_blob.payment_type == 'credit_payment' ) { // paying with patron credit
949             if ( $('convert_change_to_credit').checked ) {
950                 // No need to convert credit into credit, handled automatically
951                 payment_blob.patron_credit = '0.00';
952             } else {
953                 // Cashing out extra credit as change
954                 payment_blob.patron_credit = 0 - tally_blob.change;
955             }
956         } else if ( $('convert_change_to_credit').checked ) {
957             // Saving change from a non-credit payment as patron credit on server
958             payment_blob.patron_credit = tally_blob.change;
959         } else {
960             payment_blob.patron_credit = '0.00';
961         }
962         if ( payment_blob.payments.length == 0 && payment_blob.patron_credit == '0.00' ) {
963             alert($("patronStrings").getString('staff.patron.bills.apply_payment.nothing_applied'));
964             return;
965         }
966         if ( pay( payment_blob ) ) {
967
968             $('payment').value = ''; $('payment').select(); $('payment').focus();
969             refresh({'clear_voided_summary':true});
970             if (typeof window.xulG == 'object' && typeof window.xulG.refresh == 'function') window.xulG.refresh();
971             if (typeof window.xulG == 'object' && typeof window.xulG.on_money_change == 'function') window.xulG.on_money_change();
972             if ( $('payment_type').value == 'credit_payment' || $('convert_change_to_credit').checked ) {
973                 refresh_patron();
974             }
975             try {
976                 if ( ! $('receipt_upon_payment').hasAttribute('checked') ) { return; } // Skip print attempt
977                 if ( ! $('receipt_upon_payment').getAttribute('checked') ) { return; } // Skip print attempt
978                 var no_print_prompting = g.data.hash.aous['circ.staff_client.do_not_auto_attempt_print'];
979                 if (no_print_prompting) {
980                     if (no_print_prompting.indexOf( "Bill Pay" ) > -1) { return; } // Skip print attempt
981                 }
982                 g.data.stash_retrieve();
983                 var template = 'bill_payment';
984                 JSAN.use('patron.util'); JSAN.use('util.functional');
985                 var params = { 
986                     'patron' : g.patron,
987                     'lib' : g.data.hash.aou[ ses('ws_ou') ],
988                     'staff' : ses('staff'),
989                     'header' : g.data.print_list_templates[template].header,
990                     'line_item' : g.data.print_list_templates[template].line_item,
991                     'footer' : g.data.print_list_templates[template].footer,
992                     'type' : g.data.print_list_templates[template].type,
993                     'list' : util.functional.map_list(
994                         payment_blob.payments,
995                         function(o) {
996                             return {
997                                 'bill_id' : o[0],
998                                 'payment' : o[1],
999                                 'last_billing_type' : g.bill_map[ o[0] ].transaction.last_billing_type(),
1000                                 'last_billing_note' : g.bill_map[ o[0] ].transaction.last_billing_note(),
1001                                 'title' : typeof g.bill_map[ o[0] ].record != 'undefined' ? g.bill_map[ o[0] ].record.title() : '', 
1002                                 'barcode' : typeof g.bill_map[ o[0] ].copy != 'undefined' ? g.bill_map[ o[0] ].copy.barcode() : ''
1003                             };
1004                         }
1005                     ),
1006                     'data' : g.previous_summary,
1007                     'context' : g.data.print_list_templates[template].context,
1008                 };
1009                 g.error.sdump('D_DEBUG',js2JSON(params));
1010                 if ($('printer_prompt').hasAttribute('checked')) {
1011                     if ($('printer_prompt').getAttribute('checked')) {
1012                             params.no_prompt = false;
1013                     } else {
1014                             params.no_prompt = true;
1015                     }
1016                 } else {
1017                     params.no_prompt = true;
1018                 }
1019                 JSAN.use('util.print'); var print = new util.print('receipt');
1020                 for (var i = 0; i < $('num_of_receipts').value; i++) {
1021                     print.tree_list( params );
1022                 }
1023             } catch(E) {
1024                 g.error.standard_unexpected_error_alert('bill receipt', E);
1025             }
1026         }
1027     } catch(E) {
1028         alert('Error in bill2.js, apply_payment(): ' + E);
1029     }
1030 }
1031
1032 function pay(payment_blob) {
1033     try {
1034         var x = $('annotate_payment');
1035         if (x && x.checked && (! payment_blob.note)) {
1036             payment_blob.note = window.prompt(
1037                 $("patronStrings").getString('staff.patron.bills.pay.annotate_payment'),
1038                 '', 
1039                 $("patronStrings").getString('staff.patron.bills.pay.annotate_payment.title')
1040             );
1041         }
1042         g.previous_summary = {
1043             original_balance : $('tb_total_owed').value,
1044             voided_balance : $('currently_voided').value,
1045             payment_received : $('payment').value,
1046             payment_applied : $('pending_payment').value,
1047             change_given : $('convert_change_to_credit').checked ? 0 : $('pending_change').value,
1048             credit_given : $('convert_change_to_credit').checked ? $('pending_change').value : 0,
1049             new_balance : util.money.cents_as_dollars( 
1050                 util.money.dollars_float_to_cents_integer( $('tb_total_owed').value ) - 
1051                 util.money.dollars_float_to_cents_integer( $('pending_payment').value )
1052             ),
1053             payment_type : $('payment_type').getAttribute('label'),
1054             note : payment_blob.note
1055         }
1056         var robj = g.network.simple_request( 'BILL_PAY', [ ses(), payment_blob, g.patron.last_xact_id() ]);
1057
1058         try {
1059             g.error.work_log(
1060                 $('circStrings').getFormattedString(
1061                     robj && robj.payments
1062                         ? 'staff.circ.work_log_payment_attempt.success.message'
1063                         : 'staff.circ.work_log_payment_attempt.failure.message',
1064                     [
1065                         ses('staff_usrname'), // 1 - Staff Username
1066                         g.patron.family_name(), // 2 - Patron Family
1067                         g.patron.card().barcode(), // 3 - Patron Barcode
1068                         g.previous_summary.original_balance, // 4 - Original Balance
1069                         g.previous_summary.voided_balance, // 5 - Voided Balance
1070                         g.previous_summary.payment_received, // 6 - Payment Received
1071                         g.previous_summary.payment_applied, // 7 - Payment Applied
1072                         g.previous_summary.change_given, // 8 - Change Given
1073                         g.previous_summary.credit_given, // 9 - Credit Given
1074                         g.previous_summary.new_balance, // 10 - New Balance
1075                         g.previous_summary.payment_type, // 11 - Payment Type
1076                         g.previous_summary.note, // 12 - Note
1077                         robj && robj.textcode ? robj.textcode : robj // 13 - API call result
1078                     ]
1079                 ), {
1080                     'au_id' : g.patron.id(),
1081                     'au_family_name' : g.patron.family_name(),
1082                     'au_barcode' : g.patron.card().barcode()
1083                 }
1084             );
1085         } catch(E) {
1086             alert('Error logging payment in bill2.js: ' + E);
1087         }
1088
1089         if (typeof robj.ilsevent != 'undefined') {
1090             switch(robj.textcode) {
1091                 case 'SUCCESS' : return true; break;
1092                 case 'REFUND_EXCEEDS_DESK_PAYMENTS' : alert($("patronStrings").getFormattedString('staff.patron.bills.pay.refund_exceeds_desk_payment', [robj.desc])); return false; break;
1093                 case 'INVALID_USER_XACT_ID' :
1094                     refresh(); default_focus();
1095                     alert($("patronStrings").getFormattedString('staff.patron.bills.pay.invalid_user_xact_id', [robj.desc])); return false; break;
1096                 case 'PATRON_CREDIT_DISABLED' :
1097                     refresh(); 
1098                     default_focus();
1099                     alert(robj.desc);
1100                     return false;
1101                     break;
1102
1103                 default: throw(robj); break;
1104             }
1105         }
1106         return true;
1107     } catch(E) {
1108         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.bills.pay.payment_failed'),E);
1109         return false;
1110     }
1111 }
1112
1113 function refresh(params) {
1114     try {
1115         if (g.safe_for_refresh) {
1116             if (params && params.clear_voided_summary) {
1117                 g.data.voided_billings = []; g.data.stash('voided_billings');
1118             }
1119             refresh_patron();
1120             g.bill_list.clear();
1121             retrieve_mbts_for_list();
1122             tally_voided();
1123             distribute_payment();
1124         }
1125     } catch(E) {
1126         alert('Error in bill2.js, refresh(): ' + E);
1127     }
1128 }
1129
1130 function void_all_billings(mobts_id) {
1131     try {
1132         JSAN.use('util.functional');
1133         
1134         var mb_list = g.network.simple_request( 'FM_MB_RETRIEVE_VIA_MBTS_ID.authoritative', [ ses(), mobts_id ] );
1135         if (typeof mb_list.ilsevent != 'undefined') throw(mb_list);
1136
1137         mb_list = util.functional.filter_list( mb_list, function(o) { return ! get_bool( o.voided() ) });
1138
1139         if (mb_list.length == 0) { alert($("patronStrings").getString('staff.patron.bills.void_all_billings.all_voided')); return; }
1140
1141         var sum = 0;
1142         for (var i = 0; i < mb_list.length; i++) sum += util.money.dollars_float_to_cents_integer( mb_list[i].amount() );
1143         sum = util.money.cents_as_dollars( sum );
1144
1145         var msg = $("patronStrings").getFormattedString('staff.patron.bills.void_all_billings.void.message', [sum]);
1146         var r = g.error.yns_alert(msg,
1147             $("patronStrings").getString('staff.patron.bills.void_all_billings.void.title'),
1148             $("patronStrings").getString('staff.patron.bills.void_all_billings.void.yes'),
1149             $("patronStrings").getString('staff.patron.bills.void_all_billings.void.no'), null,
1150             $("patronStrings").getString('staff.patron.bills.void_all_billings.void.confirm_message'));
1151         if (r == 0) {
1152             var robj = g.network.simple_request('FM_MB_VOID',[ses()].concat(util.functional.map_list(mb_list,function(o){return o.id();})));
1153             if (robj.ilsevent) {
1154                 switch(Number(robj.ilsevent)) {
1155                     case 5000 /* PERM_FAILURE */:
1156                         return;
1157                     break;
1158                     default: 
1159                         g.error.standard_unexpected_error_alert($("patronStrings").getString('staff.patron.bills.void_all_billings.error_voiding_bills'),robj); 
1160                         return; 
1161                     break;
1162                 }
1163             }
1164
1165             g.data.stash_retrieve(); if (! g.data.voided_billings ) g.data.voided_billings = []; 
1166             for (var i = 0; i < mb_list.length; i++) {
1167                     g.data.voided_billings.push( mb_list[i] );
1168             }
1169             g.data.stash('voided_billings');
1170         }
1171     } catch(E) {
1172         try { g.error.standard_unexpected_error_alert('bill2.js, void_all_billings():',E); } catch(F) { alert(E); }
1173     }
1174 }
1175
1176 function refresh_patron() {
1177     JSAN.use('patron.util'); JSAN.use('util.money');
1178     patron.util.retrieve_fleshed_au_via_id(ses(),g.patron_id,null,function(req) {
1179         var au_obj = req.getResultObject();
1180         if (typeof au_obj.ilsevent == 'undefined') {
1181             g.patron = au_obj;
1182             $('credit_forward').setAttribute('value',util.money.sanitize( g.patron.credit_forward_balance() ));
1183             set_patron_based_menu_options();
1184         }
1185     });
1186 }
1187
1188 function set_patron_based_menu_options() {
1189     ['voidall', 'adjust_to_zero'].forEach(function (commandname) {
1190         show_hide_menu_by_class(commandname + '_command', true);
1191     });
1192
1193     $('voidall').setAttribute('hidden','true');
1194     $('adjust_to_zero').setAttribute('hidden','true');
1195     if (check_perms_for_patron_ou(['VOID_BILLING'])) {
1196         show_hide_menu_by_class('voidall_command', false);
1197     }
1198     if (check_perms_for_patron_ou(['ADJUST_BILLS'])) {
1199         show_hide_menu_by_class('adjust_to_zero_command', false);
1200     }
1201 }
1202
1203 function show_hide_menu_by_class(class_name, hidden) {
1204     var nodes = document.getElementsByClassName(class_name);
1205     for (var i = 0; i < nodes.length; i++) {
1206         nodes[i].setAttribute('hidden', hidden);
1207     }
1208 }
1209
1210 function check_perms_for_patron_ou(perms) {
1211     try {
1212         var check = g.network.simple_request('PERM_CHECK',[ses(),ses('staff_id'),g.patron.home_ou(),perms]);
1213         if (typeof check.ilsevent != 'undefined') {
1214             g.error.standard_unexpected_error_alert('check_perms_for_patron_ou()',check);
1215             return false;
1216         }
1217         return check.length == 0 ? true : false;
1218     } catch(E) {
1219         g.error.standard_unexpected_error_alert('check_perms_for_patron_ou()',E);
1220     }
1221 }