]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/xul/staff_client/server/patron/barcode_entry.js
adding circ_item_list example reporter view; installing staged-search stuff
[Evergreen.git] / Open-ILS / xul / staff_client / server / patron / barcode_entry.js
1                 function $(id) { return document.getElementById(id); }
2                 function $c(tag) { return document.createElement(tag); }
3                 function $w(e,msg) { 
4                         if (typeof e != 'object') e = $(e); 
5                         switch(e.nodeName) {
6                                 case 'description' :
7                                         e.appendChild( document.createTextNode( msg ) );
8                                 break;
9                                 case 'label' : 
10                                 default:
11                                         e.setAttribute('value',msg);
12                                 break;
13                         }
14                 }
15
16 /*********************************************************************************************************/
17 /* Main entry point */
18
19                 function my_init() {
20                         try {
21                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
22                                 if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
23                                 JSAN.errorLevel = "die"; // none, warn, or die
24                                 JSAN.addRepository('/xul/server/');
25                                 JSAN.use('util.error'); g.error = new util.error();
26                                 g.error.sdump('D_TRACE','my_init() for patron/barcode_entry.xul');
27                                 JSAN.use('OpenILS.data'); g.data = new OpenILS.data(); g.data.init({'via':'stash'});
28
29                                 JSAN.use('util.network'); g.network = new util.network();
30                                 JSAN.use('util.barcode');
31                                 JSAN.use('util.print'); g.print = new util.print();
32
33                                 g.cgi = new CGI();
34
35                                 /************************************************************/
36                                 /* set up the non-cat menu */
37
38                                 JSAN.use('util.widgets'); JSAN.use('util.functional'); JSAN.use('util.fm_utils');
39                                 var items = [ [ 'or choose a non-barcoded option' , 'barcode' ] ].concat(
40                                                 util.functional.map_list(
41                                                         util.functional.filter_list(
42                                                                 g.data.list.cnct,
43                                                                 function(o) {
44                                                                         return util.fm_utils.compare_aou_a_is_b_or_ancestor(o.owning_lib(), g.data.list.au[0].ws_ou());
45                                                                 }
46                                                         ).sort(
47
48                                                                 function(a,b) {
49                                                                         try { 
50                                                                                 return util.fm_utils.sort_func_aou_by_depth_and_then_string(
51                                                                                         [ a.owning_lib(), a.name() ],
52                                                                                         [ b.owning_lib(), b.name() ]
53                                                                                 );
54                                                                         } catch(E) {
55                                                                                 alert('error in noncat sorting: ' + E);
56                                                                                 return 0;
57                                                                         }
58                                                                 }
59
60                                                         ),
61                                                         function(o) {
62                                                                 return [ g.data.hash.aou[ o.owning_lib() ].shortname() + ' : ' + o.name(), o.id() ];
63                                                         }
64                                                 )
65                                 );
66                                 g.error.sdump('D_TRACE','items = ' + js2JSON(items));
67                                 var ml = util.widgets.make_menulist(
68                                         items
69                                 );
70                                 $("checkout_menu_placeholder").appendChild( ml );
71                                 ml.setAttribute('id','checkout_menulist');
72                                 ml.setAttribute('accesskey','');
73                                 ml.addEventListener(
74                                         'command',
75                                         function(ev) {
76                                                 var tb = $('checkout_barcode_entry_textbox');
77                                                 var db = $('checkout_duedate_menu');
78                                                 if (ev.target.value == 'barcode') {
79                                                         db.value = db.getAttribute('default_value') || db.value;
80                                                         db.disabled = false;
81                                                         tb.disabled = false;
82                                                         tb.value = '';
83                                                         tb.focus();
84                                                 } else {
85                                                         db.setAttribute('default_value',db.value);
86                                                         db.value = 'Normal';
87                                                         db.disabled = true;
88                                                         tb.disabled = true;
89                                                         tb.value = 'Non-Cataloged';
90                                                 }
91                                         }, false
92                                 );
93
94                                 /************************************************************/
95                                 /* set up the patron barcode textbox */
96
97                                 var tb = $('barcode_tb');
98                                 tb.addEventListener(
99                                         'keypress',
100                                         function(ev) {
101                                                 if (ev.keyCode == 13 || ev.keyCode == 77) {
102                                                         setTimeout(
103                                                                 function() {
104                                                                         submit();
105                                                                 }, 0
106                                                         );
107                                                 }
108                                         },
109                                         false
110                                 );
111                                 tb.focus();
112
113                                 /************************************************************/
114                                 /* set up the item barcode textbox */
115
116                                 $('checkout_barcode_entry_textbox').addEventListener(
117                                         'keypress',
118                                         function(ev) {
119                                                 if (ev.keyCode == 13 || ev.keyCode == 77) {
120                                                         setTimeout(
121                                                                 function() {
122                                                                         submit_item();
123                                                                 }, 0
124                                                         );
125                                                 }
126                                         },
127                                         false
128                                 );
129
130                                 $('checkout_top_ui').hidden = ! $('quick_checkout').checked;    
131         
132                                 $("checkout_barcode_entry_textbox").disabled = true;
133                                 $("checkout_duedate_menu").disabled = true;
134                                 $("checkout_menulist").disabled = true;
135                                 $("checkout_submit").disabled = true;
136                                 $("done").disabled = true;
137                                 $("retrieve_patron").disabled = true;
138                                 $("strict_barcode").disabled = true;
139                                 $("enable_print").disabled = true;
140
141                                 if (typeof window.xulG == 'object' && typeof window.xulG.set_tab_name == 'function') {
142                                         try { window.xulG.set_tab_name('Check Out'); } catch(E) { alert(E); }
143                                 }
144
145                                 if (g.cgi.param('error')) { 
146                                         var error = g.cgi.param('error');
147                                         alert(error);
148                                 }
149
150                         } catch(E) {
151                                 var err_msg = "!! This software has encountered an error.  Please tell your friendly " +
152                                         "system administrator or software developer the following:\n" + E + '\n';
153                                 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); }
154                                 alert(err_msg);
155                         }
156                 }
157
158
159 /*********************************************************************************************************/
160 /* test for a specific event in array or scalar */
161
162                 function test_event(list,ev) {
163                         if (typeof list.ilsevent != 'undefined' ) {
164                                 if (list.ilsevent == ev) {
165                                         return list;
166                                 } else {
167                                         return false;
168                                 }
169                         } else {
170                                 for (var i = 0; i < list.length; i++) {
171                                         if (typeof list[i].ilsevent != 'undefined') {
172                                                 if (list[i].ilsevent == ev) return list[i];
173                                         }
174                                 }
175                                 return false;
176                         }
177                 }
178
179 /*********************************************************************************************************/
180 /* look for a valid checkdigit if the strict barcode check is enabled */
181
182                 function test_barcode(bc) {
183                         var x = document.getElementById('strict_barcode');
184                         if (x && x.checked != true) return true;
185                         var good = util.barcode.check(bc);
186                         if (good) {
187                                 return true;
188                         } else {
189                                 if ( 1 == g.error.yns_alert(
190                                                         'Bad checkdigit; possible mis-scan.  Use this barcode ("' + bc + '") anyway?',
191                                                         'Bad Barcode',
192                                                         'Cancel',
193                                                         'Accept Barcode',
194                                                         null,
195                                                         'Check here to confirm this action',
196                                                         '/xul/server/skin/media/images/bad_barcode.png'
197                                 ) ) {
198                                         return true;
199                                 } else {
200                                         return false;
201                                 }
202                         }
203                 }
204
205 /*********************************************************************************************************/
206 /* check and convert the value in the due_date widget */
207
208                 function test_date(node) {
209                         JSAN.use('util.date');
210                         try {
211                                 if (node.value == 'Normal') return true;
212                                 var pattern = node.value.match(/Today \+ (\d+) days/);
213                                 if (pattern) {
214                                         var today = new Date();
215                                         var todayPlus = new Date(); todayPlus.setTime( today.getTime() + 24*60*60*1000*pattern[1] );
216                                         node.value = util.date.formatted_date(todayPlus,"%F");
217                                 }
218                                 if (! util.date.check('YYYY-MM-DD',node.value) ) { throw('Invalid Date'); }
219                                 if (util.date.check_past('YYYY-MM-DD',node.value) ) { throw('Due date needs to be after today.'); }
220                                 if ( util.date.formatted_date(new Date(),'%F') == node.value) { throw('Due date needs to be after today.'); }
221                                 return true;
222                         } catch(E) {
223                                 alert(E);
224                                 node.value = 'Normal';
225                                 return true;
226                         }
227                 }
228
229 /*********************************************************************************************************/
230 /* process the checkout submission -- first pass */
231
232                 function submit_item() {
233                         try {
234                 
235                                 var checkout_params = {};
236
237                                 JSAN.use('util.sound'); var sound = new util.sound();
238
239                                 try { test_date($('checkout_duedate_menu')); } catch(E) { return; }
240                                 if ($('checkout_duedate_menu').value != 'Normal') {
241                                         checkout_params.due_date = $('checkout_duedate_menu').value;
242                                 }
243
244                                 switch( $('checkout_menulist').value ) {
245
246                                         case 'barcode' :
247                                                 var tb = $('checkout_barcode_entry_textbox');
248                                                 var barcode = tb.value; barcode = String( barcode ).replace( /\s+/g, '' );
249                                                 if (!barcode) { sound.circ_bad(); /*add_msg('No item barcode entered.');*/ tb.select(); tb.focus(); return; }
250                                                 var row = $c('row'); 
251                                                 if ($('spacer').nextSibling) {
252                                                         $('rows').insertBefore(row,$('spacer').nextSibling); 
253                                                 } else {
254                                                         $('rows').appendChild(row);
255                                                 }
256                                                 row.setAttribute('name','lineitem');
257                                                 var bc_label = $c('label'); row.appendChild(bc_label); $w(bc_label,barcode);
258                                                 var dd_label = $c('label'); row.appendChild(dd_label); 
259                                                 var tt_label = $c('description'); row.appendChild(tt_label);
260                                                 addCSSClass(bc_label,'line_item'); addCSSClass(dd_label,'line_item'); addCSSClass(tt_label,'line_item');
261
262                                                 if ( test_barcode(barcode) ) { 
263                                                         sound.circ_good(); 
264                                                         checkout_params.patron_id = g.patron_id;
265                                                         checkout_params.barcode = barcode;
266                                                         process_barcoded_item( checkout_params,dd_label,tt_label);
267                                                 } else {
268                                                         $w(dd_label,'Bad Barcode');
269                                                         addCSSClass(dd_label,'bad_barcode');
270                                                         sound.circ_bad(); 
271                                                 }
272
273                                                 tb.value = ''; tb.select(); tb.focus();
274                                         break;
275
276                                         default:
277                                                 alert('non-cat quick checkout not yet implemented');
278                                         break;
279
280                                 }
281
282                         } catch(E) {
283                                 g.error.standard_unexpected_error_alert('barcode_entry.xul:submit_item()',E);
284                                 $('checkout_barcode_entry_textbox').focus();
285                                 $('checkout_barcode_entry_textbox').select();
286                         }
287                 }
288
289 /*********************************************************************************************************/
290 /* process the checkout submission -- second pass, barcoded item */
291
292         function process_barcoded_item(checkout_params,dd_label,tt_label) {
293                 try {
294                         addCSSClass(dd_label,'checking_barcode');
295                         $w(dd_label,'Checking...');
296                         g.network.simple_request(
297                                 checkout_params.precat ? 'CHECKOUT' : 'CHECKOUT_FULL',
298                                 [ ses(), checkout_params ],
299                                 function(req) {
300                                         try {
301                                                 removeCSSClass(dd_label,'checking_barcode');
302                                                 $w(dd_label,'');
303                                                 process_barcoded_item_callback(req,checkout_params,dd_label,tt_label);
304                                         } catch(E) {
305                                                 g.error.standard_unexpected_error_alert('barcode_entry.xul:process_barcoded('+checkout_params+'),callback wrapper',E);
306                                                 $('checkout_barcode_entry_textbox').focus();
307                                                 $('checkout_barcode_entry_textbox').select();
308                                         }
309                                 },
310                                 {
311                                         'title' : 'Override Checkout Failure?',
312                                         'overridable_events' : [ 
313                                                 1212 /* PATRON_EXCEEDS_OVERDUE_COUNT */,
314                                                 1213 /* PATRON_BARRED */,
315                                                 1215 /* CIRC_EXCEEDS_COPY_RANGE */,
316                                                 7002 /* PATRON_EXCEEDS_CHECKOUT_COUNT */,
317                                                 7003 /* COPY_CIRC_NOT_ALLOWED */,
318                                                 7004 /* COPY_NOT_AVAILABLE */, 
319                                                 7006 /* COPY_IS_REFERENCE */, 
320                                                 7010 /* COPY_ALERT_MESSAGE */,
321                                                 7013 /* PATRON_EXCEEDS_FINES */,
322                                                 7016 /* ITEM_ON_HOLDS_SHELF */,
323                                         ],
324                                         'text' : {
325                                                 '1212' : function(r) { return 'Item: ' + checkout_params.barcode; },
326                                                 '1213' : function(r) { return 'Item: ' + checkout_params.barcode; },
327                                                 '1215' : function(r) { return 'Item: ' + checkout_params.barcode; },
328                                                 '7002' : function(r) { return 'Item: ' + checkout_params.barcode; },
329                                                 '7003' : function(r) { return 'Item: ' + checkout_params.barcode; },
330                                                 '7004' : function(r) {
331                                                         return 'Status: ' + r.payload.status().name() + '\nItem: ' + checkout_params.barcode;
332                                                 },
333                                                 '1212' : function(r) { return 'Item: ' + checkout_params.barcode; },
334                                                 '7010' : function(r) {
335                                                         return 'Alert: ' + r.payload + '\nItem: ' + checkout_params.barcode;
336                                                 },
337                                                 '7013' : function(r) { return 'Item: ' + checkout_params.barcode; },
338                                                 '7016' : function(r) { return 'Item: ' + checkout_params.barcode; },
339                                         }
340                                 }
341                         );
342                 } catch(E) {
343                         g.error.standard_unexpected_error_alert('barcode_entry.xul:process_barcoded('+checkout_params+')',E);
344                         $('checkout_barcode_entry_textbox').focus();
345                         $('checkout_barcode_entry_textbox').select();
346                 }
347         }
348
349         function process_barcoded_item_callback(req,checkout_params,dd_label,tt_label) {
350                 try {
351                         var checkout = req.getResultObject();
352
353                         if (typeof checkout.ilsevent != 'undefined') checkout = [ checkout ];
354
355                         if (test_event(checkout, 0 /* SUCCESS */)) {
356
357                                 removeCSSClass(dd_label,'bad_barcode'); removeCSSClass(tt_label,'bad_barcode');
358                                 var dd = String(checkout[0].payload.circ.due_date()).substr(0,10);
359                                 var tt = checkout[0].payload.record ? checkout[0].payload.record.title() : checkout[0].payload.copy.dummy_title(); 
360                                 $w(dd_label, dd);
361                                 util.widgets.remove_children(tt_label);
362                                 $w(tt_label, tt);
363                                 if ($('enable_print').checked) {
364                                         var print_params = { 
365                                                 'patron' : g.patron, 
366                                                 'lib' : g.data.hash.aou[ g.data.list.au[0].ws_ou() ],
367                                                 'staff' : g.data.list.au[0],
368                                                 //'header' : g.data.print_list_templates.checkout.header,
369                                                 'line_item' : g.data.print_list_templates.checkout.line_item,
370                                                 //'footer' : g.data.print_list_templates.checkout.footer,
371                                                 'type' : g.data.print_list_templates.checkout.type,
372                                                 'list' : [ { 'barcode' : checkout_params.barcode, 'title' : tt, 'due_date' : dd } ],
373                                                 'silent' : true,
374                                                 'print_strategy' : 'dos.print',
375                                         };
376                                         g.print.tree_list( print_params );
377                                 }
378                         } else if (
379                                 test_event(checkout, 1212 /* PATRON_EXCEEDS_OVERDUE_COUNT */) ||
380                                 test_event(checkout, 1213 /* PATRON_BARRED */) ||
381                                 test_event(checkout, 1215 /* CIRC_EXCEEDS_COPY_RANGE */) ||
382                                 test_event(checkout, 7002 /* PATRON_EXCEEDS_CHECKOUT_COUNT */) ||
383                                 test_event(checkout, 7003 /* COPY_CIRC_NOT_ALLOWED */) ||
384                                 test_event(checkout, 7004 /* COPY_NOT_AVAILABLE */) || 
385                                 test_event(checkout, 7006 /* COPY_IS_REFERENCE */) || 
386                                 test_event(checkout, 7010 /* COPY_ALERT_MESSAGE */) ||
387                                 test_event(checkout, 7016 /* ITEM_ON_HOLDS_SHELF */) ||
388                                 test_event(checkout, 7013 /* PATRON_EXCEEDS_FINES */) 
389                         ) {
390                                 addCSSClass(dd_label,'bad_barcode'); addCSSClass(tt_label,'bad_barcode');
391                                 $w(dd_label,'Failed');
392                                 for (var i = 0; i < checkout.length; i++) $w(tt_label,checkout[i].textcode + ' ');
393                         } else if (test_event(checkout,1202 /* ITEM_NOT_CATALOGED */)) {
394
395                                 /**************************************************************************************/
396                                 /* offer pre-cat checkout */
397
398                                 $w(dd_label,'Pre-Cat?');
399
400                                 if ( 1 == g.error.yns_alert(
401                                         'Mis-scan or non-cataloged item.  Checkout ("' + checkout_params.barcode + '") as a pre-cataloged item?',
402                                         'Alert',
403                                         'Cancel',
404                                         'Pre-Cat',
405                                         null,
406                                         'Check here to confirm this action',
407                                         '/xul/server/skin/media/images/book_question.png'
408                                 ) ) {
409
410                                         g.data.dummy_title = ''; g.data.dummy_author = ''; g.data.stash('dummy_title','dummy_author');
411                                         JSAN.use('util.window'); var win = new util.window();
412                                         win.open(urls.XUL_PRE_CAT, 'dummy_fields', 'chrome,resizable,modal');
413                                         g.data.stash_retrieve();
414
415                                         checkout_params.permit_key = checkout[0].payload;
416                                         checkout_params.dummy_title = g.data.dummy_title;
417                                         checkout_params.dummy_author = g.data.dummy_author;
418                                         checkout_params.precat = 1;
419
420                                         if (checkout_params.dummy_title != '') { 
421                                                 process_barcoded_item( checkout_params, dd_label, tt_label ); 
422                                         } else { 
423                                                 throw(checkout); 
424                                         }
425
426                                 } else {
427                                         throw(checkout);
428                                 }
429                         } else if (test_event(checkout, 1702 /* OPEN_CIRCULATION_EXISTS */)) {
430
431                                 /**************************************************************************************/
432                                 /* offer to checkin an already circulating item */
433
434                                 addCSSClass(dd_label,'bad_barcode'); $w(dd_label,'Check In?');
435                                 addCSSClass(tt_label,'bad_barcode'); for (var i = 0; i < checkout.length; i++) $w(tt_label,checkout[i].textcode + ' ');
436                                 g.network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[checkout_params.barcode],
437                                         function(req) {
438                                                 try {
439                                                         var my_copy = req.getResultObject();
440                                                         if (typeof my_copy.ilsevent != 'undefined') throw(my_copy);
441                                                         g.network.simple_request('FM_CIRC_RETRIEVE_VIA_COPY',[ses(),my_copy.id(),1],
442                                                                 function(rreq) {
443                                                                         try {
444                                                                                 var my_circ = rreq.getResultObject();
445                                                                                 if (typeof my_circ.ilsevent != 'undefined') throw(my_copy);
446                                                                                 my_circ = my_circ[0];
447                                                                                 var due_date = my_circ.due_date() ? my_circ.due_date().substr(0,10) : null;
448                                                                                 JSAN.use('util.date'); var today = util.date.formatted_date(new Date(),'%F');
449                                                                                 var msg = 'This item ("' + checkout_params.barcode + '") is already circulating.';
450                                                                                 if (due_date) if (today > due_date) msg += '\nIt was due on ' + due_date + '.\n';
451                                                                                 var r = g.error.yns_alert(
452                                                                                         msg, 'Check Out Failed','Cancel','Checkin then Checkout', 
453                                                                                         due_date ? (today > due_date ? 'Forgiving Checkin then Checkout' : null) : null,
454                                                                                         'Check here to confirm this message'
455                                                                                 );
456                                                                                 JSAN.use('circ.util');
457                                                                                 switch(r) {
458                                                                                         case 1:
459                                                                                                 circ.util.checkin_via_barcode( ses(), { 'barcode' : checkout_params.barcode } );
460                                                                                                 process_barcoded_item( checkout_params, dd_label, tt_label ); 
461                                                                                         break;
462                                                                                         case 2:
463                                                                                                 circ.util.checkin_via_barcode( ses(), { 'barcode' : checkout_params.barcode }, due_date );
464                                                                                                 process_barcoded_item( checkout_params, dd_label, tt_label ); 
465                                                                                         break;
466                                                                                 }
467                                                                         } catch(E) {
468                                                                                 addCSSClass(dd_label,'bad_barcode'); addCSSClass(tt_label,'bad_barcode');
469                                                                                 $w(dd_label,'Error');
470                                                                                 if (E.length) {
471                                                                                         for (var i = 0; i < E.length; i++) $w(tt_label,E[i].textcode + ' ');
472                                                                                 } else {
473                                                                                         $w(tt_label,E);
474                                                                                 }
475                                                                         }
476                                                                 }
477                                                         );
478                                                 } catch(E) {
479                                                         addCSSClass(dd_label,'bad_barcode'); addCSSClass(tt_label,'bad_barcode');
480                                                         $w(dd_label,'Error');
481                                                         if (E.length) {
482                                                                 for (var i = 0; i < E.length; i++) $w(tt_label,E[i].textcode + ' ');
483                                                         } else {
484                                                                 $w(tt_label,E);
485                                                         }
486                                                 }
487                                         }
488                                 );
489                         } else if (test_event(checkout, 7014 /* COPY_IN_TRANSIT */)) {
490
491                                 /**************************************************************************************/
492                                 /* offer to abort an existing transit for the item attempting to be checked out */
493
494                                 addCSSClass(dd_label,'bad_barcode'); $w(dd_label,'Abort transit?');
495                                 addCSSClass(tt_label,'bad_barcode'); for (var i = 0; i < checkout.length; i++) $w(tt_label,checkout[i].textcode + ' ');
496                                 var r = g.error.yns_alert('This item ("' + checkout_params.barcode + '") is in transit.','Check Out Failed','Cancel','Abort Transit then Checkout',null,'Check here to confirm this message');
497                                 switch(r) {
498                                         case 1:
499                                                 var robj = g.network.simple_request('FM_ATC_VOID',[ ses(), { 'barcode' : checkout_params.barcode } ]);
500                                                 if (typeof robj.ilsevent == 'undefined') {
501                                                         process_barcoded_item( checkout_params, dd_label, tt_label ); 
502                                                 } else {
503                                                         throw(robj);
504                                                 }
505                                         break;
506                                 }
507                         } else {
508                                 throw(checkout);
509                         }
510
511                 } catch(E) {
512                         addCSSClass(dd_label,'bad_barcode'); addCSSClass(tt_label,'bad_barcode');
513                         $w(dd_label,'Error');
514                         if (E.length) {
515                                 for (var i = 0; i < E.length; i++) $w(tt_label,E[i].textcode + ' ');
516                         } else {
517                                 $w(tt_label,E);
518                         }
519                         //g.error.standard_unexpected_error_alert('Error in barcode_entry.js:process_barcoded_item_callack()',E);
520                 }
521         }
522         
523 /*********************************************************************************************************/
524 /* process the patron submission */
525
526                 function submit() {
527                         var tb;
528                         try {
529                                 JSAN.use('util.sound'); var sound = new util.sound();
530                                 tb = $('barcode_tb');
531                                 var barcode = tb.value;
532
533                                 barcode = String( barcode ).replace( /\s+/g, '' );
534
535                                 if (!barcode) { sound.bad(); add_msg('No barcode entered.'); tb.select(); tb.focus(); return; }
536
537                                 tb.disabled = true; $('submit_cb').disabled = true; $('quick_checkout').disabled = true;
538                                 $('progress').setAttribute('hidden','false');
539                                 g.network.simple_request('PATRON_BARCODE_EXISTS',[ ses(), barcode ],
540                                         function(req) {
541                                                 $('progress').setAttribute('hidden','true');
542                                                 var robj = req.getResultObject();
543                                                 if (typeof robj.ilsevent != 'undefined') {
544                                                         tb.disabled = false; tb.select(); tb.focus(); $('submit_cb').disabled = false; $('quick_checkout').disabled = false;
545                                                         sound.bad();
546                                                         add_msg('Problem retrieving ' + barcode + '.  Please report this message: \n' + js2JSON(robj));
547                                                         return;
548                                                 } else if (robj == 0) {
549                                                         tb.disabled = false; tb.select(); tb.focus(); $('submit_cb').disabled = false; $('quick_checkout').disabled = false;
550                                                         sound.bad(); 
551                                                         add_msg('Barcode ' + barcode + ' not found.');
552                                                         return;
553                                                 }
554
555                                                 sound.good(); g.barcode = barcode;
556
557                                                 if ($('quick_checkout').checked) {
558                                                         g.network.simple_request(
559                                                                 'FM_AU_RETRIEVE_VIA_BARCODE',
560                                                                 [ ses(), barcode ],
561                                                                 function(req) {
562                                                                         var p = req.getResultObject();  
563                                                                         g.patron = p;
564                                                                         $w('patron_name',
565                                                                                 p.family_name() + ', ' + p.first_given_name() + ' ' +
566                                                                                 ( p.second_given_name() ? p.second_given_name() : '' )
567                                                                         );
568                                                                         JSAN.use('patron.util'); patron.util.set_penalty_css(p);
569                                                                         alert_message(p);
570
571                                                                         g.patron_id = p.id();
572                                                                         /**/
573                                                                         util.widgets.remove_children( 'status' );
574                                                                         $("checkout_barcode_entry_textbox").disabled = false;
575                                                                         $("checkout_barcode_entry_textbox").focus();
576                                                                         $("checkout_duedate_menu").disabled = false;
577                                                                         $("checkout_menulist").disabled = false;
578                                                                         $("checkout_submit").disabled = false;
579                                                                         $("done").disabled = false;
580                                                                         $("retrieve_patron").disabled = false;
581                                                                         $("strict_barcode").disabled = false;
582                                                                         $("enable_print").disabled = false;
583                                                                         /**/
584                                                                 }
585                                                         );
586                                                 } else {
587                                                         retrieve_patron(true);
588                                                 }
589                                         }
590                                 );
591                         } catch(E) {
592                                 tb.select(); tb.focus();
593                                 g.error.standard_unexpected_error_alert('barcode_entry.xul:submit()',E);
594                         }
595                 }
596
597 /*********************************************************************************************************/
598 /* finish with simple checkout and go back to patron submission form */
599
600                 function done() {
601                         try {
602                                 removeCSSClass(document.documentElement,'PATRON_HAS_BILLS');
603                                 removeCSSClass(document.documentElement,'PATRON_HAS_OVERDUES');
604                                 removeCSSClass(document.documentElement,'PATRON_HAS_NOTES');
605                                 removeCSSClass(document.documentElement,'PATRON_EXCEEDS_CHECKOUT_COUNT');
606                                 removeCSSClass(document.documentElement,'PATRON_EXCEEDS_OVERDUE_COUNT');
607                                 removeCSSClass(document.documentElement,'PATRON_EXCEEDS_FINES');
608                                 removeCSSClass(document.documentElement,'NO_PENALTIES');
609                                 removeCSSClass(document.documentElement,'ONE_PENALTY');
610                                 removeCSSClass(document.documentElement,'MULTIPLE_PENALTIES');
611                                 removeCSSClass(document.documentElement,'PATRON_HAS_ALERT');
612                                 removeCSSClass(document.documentElement,'PATRON_BARRED');
613                                 removeCSSClass(document.documentElement,'PATRON_INACTIVE');
614                                 removeCSSClass(document.documentElement,'PATRON_EXPIRED');
615                                 removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_DOB');
616                                 removeCSSClass(document.documentElement,'PATRON_HAS_INVALID_ADDRESS');
617                                 removeCSSClass(document.documentElement,'PATRON_AGE_GE_65');
618                                 removeCSSClass(document.documentElement,'PATRON_AGE_LT_65');
619                                 removeCSSClass(document.documentElement,'PATRON_AGE_GE_24');
620                                 removeCSSClass(document.documentElement,'PATRON_AGE_LT_24');
621                                 removeCSSClass(document.documentElement,'PATRON_AGE_GE_21');
622                                 removeCSSClass(document.documentElement,'PATRON_AGE_LT_21');
623                                 removeCSSClass(document.documentElement,'PATRON_AGE_GE_18');
624                                 removeCSSClass(document.documentElement,'PATRON_AGE_LT_18');
625                                 removeCSSClass(document.documentElement,'PATRON_AGE_GE_13');
626                                 removeCSSClass(document.documentElement,'PATRON_AGE_LT_13');
627                                 removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_1');
628                                 removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_2');
629                                 removeCSSClass(document.documentElement,'PATRON_NET_ACCESS_3');
630                                 $w('patron_name','');
631                                 g.barcode = '';
632                                 var nl = document.getElementsByAttribute('name','lineitem');
633                                 var remove_these = [];
634                                 for (var i = 0; i < nl.length; i++) remove_these.push( nl[i] ); // a nodelist is not a simple array we can safely delete the dom nodes from
635                                 for (var i = 0; i < remove_these.length; i++) remove_these[i].parentNode.removeChild( remove_these[i] );
636                                 $("checkout_barcode_entry_textbox").value = ''; $("checkout_menulist").value = 'barcode';
637                                 $("checkout_barcode_entry_textbox").disabled = true; $("checkout_duedate_menu").disabled = true;
638                                 $("checkout_menulist").disabled = true; $("checkout_submit").disabled = true;
639                                 $('barcode_tb').disabled = false; $('barcode_tb').value = ''; $('barcode_tb').select(); $('barcode_tb').focus(); $('submit_cb').disabled = false;
640                                 $('quick_checkout').disabled = false; $("done").disabled = true; $("retrieve_patron").disabled = true;
641                                 $("strict_barcode").disabled = true; $("enable_print").disabled = true;
642
643                         } catch(E) {
644                                 g.error.standard_unexpected_error_alert('barcode_entry.xul:done()',E);
645                         }
646                 }
647
648 /*********************************************************************************************************/
649 /* take a patron object and alert any needed messages based on the patron */
650
651                 function alert_message(patron) {
652                                 g.network.simple_request(
653                                         'FM_AHR_COUNT_RETRIEVE',
654                                         [ ses(), patron.id() ],
655                                         function(req) {
656                                                 try {
657                                                         var msg = ''; g.stop_checkouts = false;
658                                                         if (patron.alert_message()) msg += '"' + patron.alert_message() + '"\n';
659                                                         if (g.barcode) {
660                                                                 if (patron.cards()) for (var i = 0; i < patron.cards().length; i++) {
661                                                                         //alert('card #'+i+' == ' + js2JSON(patron.cards()[i]));
662                                                                         if ( (patron.cards()[i].barcode()==g.barcode) && ( ! get_bool(patron.cards()[i].active()) ) ) {
663                                                                                 msg += 'Patron account retrieved with an INACTIVE card.\n';
664                                                                                 g.stop_checkouts = true;
665                                                                         }
666                                                                 }
667                                                         }
668                                                         if (get_bool(patron.barred())) {
669                                                                 msg += 'Patron account is BARRED.\n';
670                                                                 g.stop_checkouts = true;
671                                                         }
672                                                         if (!get_bool(patron.active())) {
673                                                                 msg += 'Patron account is INACTIVE.\n';
674                                                                 g.stop_checkouts = true;
675                                                         }
676                                                         if (patron.expire_date()) {
677                                                                 var now = new Date();
678                                                                 now = now.getTime()/1000;
679
680                                                                 var expire_parts = patron.expire_date().substr(0,10).split('-');
681                                                                 expire_parts[1] = expire_parts[1] - 1;
682
683                                                                 var expire = new Date();
684                                                                 expire.setFullYear(expire_parts[0], expire_parts[1], expire_parts[2]);
685                                                                 expire = expire.getTime()/1000
686
687                                                                 if (expire < now) {
688                                                                         msg += 'Patron account is EXPIRED.\n';
689                                                                         g.stop_checkouts = true;
690                                                                 }
691                                                         }
692                                                         var holds = req.getResultObject();
693                                                         if (holds.ready && holds.ready > 0) msg += 'Holds available: ' + holds.ready;
694                                                         if (msg) {
695                                                                 g.error.yns_alert(msg,'Alert Message','OK',null,null,'Check here to confirm this message.');
696                                                         }
697                                                 } catch(E) {
698                                                         g.error.standard_unexpected_error_alert('Error showing patron alert and holds availability.',E);
699                                                 }
700                                         }
701                                 );
702                 }
703
704 /*********************************************************************************************************/
705 /* append text to an error section onscreen */
706
707                 function add_msg(text) {
708                         var x = $('status');
709                         var d = $c('description');
710                         x.appendChild(d);
711                         $w(d,text);
712                         d.setAttribute('style','color: red');
713                 }
714
715 /*********************************************************************************************************/
716 /* Open the usual patron display in current tab */
717
718                 function spawn(barcode) {
719                         try {
720                                 var loc = urls.XUL_PATRON_DISPLAY; // + '?barcode=' + window.escape(barcode);
721
722                                 if (typeof window.xulG == 'object' && typeof window.xulG.set_tab == 'function') {
723
724                                         window.xulG.set_tab( loc, {}, { 'barcode' : barcode } );
725                                 } else {
726
727                                         location.href = loc + '?barcode=' + window.escape(barcode);
728 ;
729                                 }
730                         } catch(E) {
731                                 g.error.standard_unexpected_error_alert('spawning patron display',E);
732                         }
733                 }
734
735 /*********************************************************************************************************/
736 /* Open the usual patron display */
737
738                 function retrieve_patron(same_tab) {
739                         try {
740                                 if (same_tab) {
741                                         if (typeof window.xulG == 'object' && typeof window.xulG.set_tab == 'function') {
742                                                 var url = urls.XUL_PATRON_DISPLAY; 
743                                                 window.xulG.set_tab( url, {}, { 'barcode' : g.barcode });
744                                         }
745                                 } else {
746                                         if (typeof window.xulG == 'object' && typeof window.xulG.new_tab == 'function') {
747                                                 var url = urls.XUL_PATRON_DISPLAY; 
748                                                 window.xulG.new_tab( url, {}, { 'barcode' : g.barcode });
749                                         }
750                                 }
751                         } catch(E) {
752                                 g.error.standard_unexpected_error_alert('Error retrieving patron',E);
753                         }
754                 }
755
756 /*********************************************************************************************************/
757 /* used by the menu/tab code for determining focus upon a tab switch */
758
759                 function default_focus() { try { setTimeout( function() { if (g.barcode) $('checkout_barcode_entry_textbox').focus(); else $('barcode_tb').focus(); }, 0); } catch(E) {} }
760