[open-ils-commits] SPAM: r10243 - in branches/acq-experiment: . Open-ILS/examples/apache Open-ILS/src/c-apps Open-ILS/src/perlmods/OpenILS/Application Open-ILS/src/perlmods/OpenILS/Utils Open-ILS/src/support-scripts Open-ILS/src/support-scripts/test-scripts Open-ILS/web/js/dojo/fieldmapper Open-ILS/web/opac/common/js Open-ILS/web/opac/extras/selfcheck Open-ILS/web/opac/locale/en-US Open-ILS/web/opac/skin/default/js

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Aug 3 21:25:59 EDT 2008


Author: erickson
Date: 2008-08-03 21:25:53 -0400 (Sun, 03 Aug 2008)
New Revision: 10243

Modified:
   branches/acq-experiment/
   branches/acq-experiment/Open-ILS/examples/apache/eg_vhost.conf
   branches/acq-experiment/Open-ILS/src/c-apps/oils_cstore.c
   branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Application/Ingest.pm
   branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm
   branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/ZClient.pm
   branches/acq-experiment/Open-ILS/src/support-scripts/fine_generator.pl
   branches/acq-experiment/Open-ILS/src/support-scripts/test-scripts/indb_circ.pl
   branches/acq-experiment/Open-ILS/web/js/dojo/fieldmapper/OrgUtils.js
   branches/acq-experiment/Open-ILS/web/opac/common/js/org_utils.js
   branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.css
   branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.js
   branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.xml
   branches/acq-experiment/Open-ILS/web/opac/locale/en-US/opac.dtd
   branches/acq-experiment/Open-ILS/web/opac/skin/default/js/myopac.js
Log:
Merged revisions 10219-10220,10223,10225,10228-10229,10231-10233,10236-10237,10240-10241 via svnmerge from 
svn://svn.open-ils.org/ILS/trunk

........
  r10219 | erickson | 2008-07-31 11:53:44 -0400 (Thu, 31 Jul 2008) | 12 lines
  
  
  Upped the default patron timeout to 10 minutes
  
  When an item barcode is scanned but the Enter key is not sent,
  the system waits a configured amount of time (default 800 milliseconds)
  then selects the text so the next scan will replace the existing text.
  
  Automatically print at logout time
  
  Replace Logout and Print links with "Done" links since printing is assumed
........
  r10220 | miker | 2008-07-31 12:16:11 -0400 (Thu, 31 Jul 2008) | 1 line
  
  make grace period a command line parameter
........
  r10223 | erickson | 2008-07-31 12:28:30 -0400 (Thu, 31 Jul 2008) | 1 line
  
  added explicit DESTROY methods to each package so AUTOLOAD won't attempt to use it
........
  r10225 | erickson | 2008-07-31 12:44:46 -0400 (Thu, 31 Jul 2008) | 1 line
  
  if a patron barcode regex is configured and a patron barcode is scanned into the item barcode input, the current user is logged out and the new user is logged in
........
  r10228 | erickson | 2008-07-31 14:55:38 -0400 (Thu, 31 Jul 2008) | 1 line
  
  if you set signed.applets.codebase_principal_support to true in about:config in Firefox, you now have the option to bypass the printer dialog if you accept the security dialogs
........
  r10229 | dbs | 2008-07-31 22:47:39 -0400 (Thu, 31 Jul 2008) | 2 lines
  
  No leading period for selector, please.
........
  r10231 | dbs | 2008-08-01 12:21:15 -0400 (Fri, 01 Aug 2008) | 2 lines
  
  D'oh! That 404 error really does mean that osrf-http-translator could not be found.
........
  r10232 | erickson | 2008-08-01 12:45:45 -0400 (Fri, 01 Aug 2008) | 1 line
  
  removed ":" from log line so output can be pasted directly into srfsh
........
  r10233 | erickson | 2008-08-01 13:04:08 -0400 (Fri, 01 Aug 2008) | 7 lines
  
  
  
  fixed faulty rule set query
  made some var names more explicit
  fix getopt setting
........
  r10236 | miker | 2008-08-01 14:00:30 -0400 (Fri, 01 Aug 2008) | 1 line
  
  add support for selecting from a function, given the function name and all params in an array (and the function takes only TEXT params)
........
  r10237 | miker | 2008-08-01 14:57:44 -0400 (Fri, 01 Aug 2008) | 1 line
  
  ingest of dates thinko
........
  r10240 | erickson | 2008-08-03 19:57:06 -0400 (Sun, 03 Aug 2008) | 1 line
  
  "parent" is a special variable.  some browsers (opera) will complain
........
  r10241 | erickson | 2008-08-03 19:58:09 -0400 (Sun, 03 Aug 2008) | 1 line
  
  "parent" is a special variable.  some browsers (opera) will complain
........



Property changes on: branches/acq-experiment
___________________________________________________________________
Name: svnmerge-integrated
   - /trunk:1-10217
   + /trunk:1-10242

Modified: branches/acq-experiment/Open-ILS/examples/apache/eg_vhost.conf
===================================================================
--- branches/acq-experiment/Open-ILS/examples/apache/eg_vhost.conf	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/examples/apache/eg_vhost.conf	2008-08-04 01:25:53 UTC (rev 10243)
@@ -207,7 +207,7 @@
 # OpenSRF-over-HTTP translator
 # (http://open-ils.org/dokuwiki/doku.php?id=opensrf_over_http)
 # ----------------------------------------------------------------------------------
-<Location /osrf_http_translator>
+<Location /osrf-http-translator>
     SetHandler osrf_http_translator_module
     allow from all
 </Location>

Modified: branches/acq-experiment/Open-ILS/src/c-apps/oils_cstore.c
===================================================================
--- branches/acq-experiment/Open-ILS/src/c-apps/oils_cstore.c	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/src/c-apps/oils_cstore.c	2008-08-04 01:25:53 UTC (rev 10243)
@@ -1725,6 +1725,7 @@
 	jsonObject* found = NULL;
 
 	char* string = NULL;
+	int from_function = 0;
 	int first = 1;
 	int gfirst = 1;
 	//int hfirst = 1;
@@ -1752,13 +1753,17 @@
 		jsonIteratorFree( tmp_itr );
 		snode = NULL;
 
+	} else if (join_hash->type == JSON_ARRAY) {
+        from_function = 1;
+        selhash = NULL;
+
 	} else if (join_hash->type == JSON_STRING) {
 		core_class = jsonObjectToSimpleString( join_hash );
 		join_hash = NULL;
 	}
 
-	// punt if we don't know about the core class
-	if (!(core_meta = osrfHashGet( oilsIDL(), core_class ))) {
+	// punt if we don't know about the core class (and it's not a function)
+	if (!from_function && !(core_meta = osrfHashGet( oilsIDL(), core_class ))) {
 		free(core_class);
 		return NULL;
 	}
@@ -1786,7 +1791,8 @@
 	growing_buffer* group_buf = buffer_init(128);
 	growing_buffer* having_buf = buffer_init(128);
 
-	core_fields = osrfHashGet(core_meta, "fields");
+	if (!from_function) 
+        core_fields = osrfHashGet(core_meta, "fields");
 
 	// ... and if we /are/ building the default list, do that
 	if ( (_tmp = jsonObjectGetKey(selhash,core_class)) && !_tmp->size ) {
@@ -1794,354 +1800,365 @@
 		int i = 0;
 		char* field;
 
-		osrfStringArray* keys = osrfHashKeys( core_fields );
-		while ( (field = osrfStringArrayGetString(keys, i++)) ) {
-			if ( strncasecmp( "true", osrfHashGet( osrfHashGet( core_fields, field ), "virtual" ), 4 ) )
-				jsonObjectPush( _tmp, jsonNewObject( field ) );
-		}
-		osrfStringArrayFree(keys);
+        if (!from_function) {
+    		osrfStringArray* keys = osrfHashKeys( core_fields );
+	    	while ( (field = osrfStringArrayGetString(keys, i++)) ) {
+		    	if ( strncasecmp( "true", osrfHashGet( osrfHashGet( core_fields, field ), "virtual" ), 4 ) )
+			    	jsonObjectPush( _tmp, jsonNewObject( field ) );
+    		}
+	    	osrfStringArrayFree(keys);
+        }
 	}
 
 	// Now we build the actual select list
-	int sel_pos = 1;
-	jsonObject* is_agg = jsonObjectFindPath(selhash, "//aggregate");
-	first = 1;
-	gfirst = 1;
-	jsonIterator* selclass_itr = jsonNewIterator( selhash );
-	while ( (selclass = jsonIteratorNext( selclass_itr )) ) {
+	if (!from_function) {
+	    int sel_pos = 1;
+	    jsonObject* is_agg = jsonObjectFindPath(selhash, "//aggregate");
+	    first = 1;
+	    gfirst = 1;
+	    jsonIterator* selclass_itr = jsonNewIterator( selhash );
+	    while ( (selclass = jsonIteratorNext( selclass_itr )) ) {
 
-		// round trip through the idl, just to be safe
-		idlClass = osrfHashGet( oilsIDL(), selclass_itr->key );
-		if (!idlClass) continue;
-		char* cname = osrfHashGet(idlClass, "classname");
+		    // round trip through the idl, just to be safe
+		    idlClass = osrfHashGet( oilsIDL(), selclass_itr->key );
+		    if (!idlClass) continue;
+		    char* cname = osrfHashGet(idlClass, "classname");
 
-		// make sure the target relation is in the join tree
-		if (strcmp(core_class,cname)) {
-			if (!join_hash) continue;
+		    // make sure the target relation is in the join tree
+		    if (strcmp(core_class,cname)) {
+			    if (!join_hash) continue;
 
-			if (join_hash->type == JSON_STRING) {
-				string = jsonObjectToSimpleString(join_hash);
-				found = strcmp(string,cname) ? NULL : jsonParseString("{\"1\":\"1\"}");
-				free(string);
-			} else {
-				found = jsonObjectFindPath(join_hash, "//%s", cname);
-			}
+			    if (join_hash->type == JSON_STRING) {
+				    string = jsonObjectToSimpleString(join_hash);
+				    found = strcmp(string,cname) ? NULL : jsonParseString("{\"1\":\"1\"}");
+				    free(string);
+			    } else {
+				    found = jsonObjectFindPath(join_hash, "//%s", cname);
+			    }
 
-			if (!found->size) {
-				jsonObjectFree(found);
-				continue;
-			}
+			    if (!found->size) {
+				    jsonObjectFree(found);
+				    continue;
+			    }
 
-			jsonObjectFree(found);
-		}
+			    jsonObjectFree(found);
+		    }
 
-		// stitch together the column list ...
-		jsonIterator* select_itr = jsonNewIterator( selclass );
-		while ( (selfield = jsonIteratorNext( select_itr )) ) {
+		    // stitch together the column list ...
+		    jsonIterator* select_itr = jsonNewIterator( selclass );
+		    while ( (selfield = jsonIteratorNext( select_itr )) ) {
 
-			char* __column = NULL;
-			char* __alias = NULL;
+			    char* __column = NULL;
+			    char* __alias = NULL;
 
-			// ... if it's a sstring, just toss it on the pile
-			if (selfield->type == JSON_STRING) {
+			    // ... if it's a sstring, just toss it on the pile
+			    if (selfield->type == JSON_STRING) {
 
-				// again, just to be safe
-				char* _requested_col = jsonObjectToSimpleString(selfield);
-				osrfHash* field = osrfHashGet( osrfHashGet( idlClass, "fields" ), _requested_col );
-				free(_requested_col);
+				    // again, just to be safe
+				    char* _requested_col = jsonObjectToSimpleString(selfield);
+				    osrfHash* field = osrfHashGet( osrfHashGet( idlClass, "fields" ), _requested_col );
+				    free(_requested_col);
 
-				if (!field) continue;
-				__column = strdup(osrfHashGet(field, "name"));
+				    if (!field) continue;
+				    __column = strdup(osrfHashGet(field, "name"));
 
-				if (first) {
-					first = 0;
-				} else {
-					buffer_add(select_buf, ",");
-				}
+				    if (first) {
+					    first = 0;
+				    } else {
+					    buffer_add(select_buf, ",");
+				    }
 
-                if (locale) {
-            		char* i18n = osrfHashGet(field, "i18n");
-			        if (flags & DISABLE_I18N)
-                        i18n = NULL;
+                    if (locale) {
+            		    char* i18n = osrfHashGet(field, "i18n");
+			            if (flags & DISABLE_I18N)
+                            i18n = NULL;
 
-    	    		if ( i18n && !strncasecmp("true", i18n, 4)) {
-        	            char* pkey = osrfHashGet(idlClass, "primarykey");
-        	            char* tname = osrfHashGet(idlClass, "tablename");
+    	    		    if ( i18n && !strncasecmp("true", i18n, 4)) {
+        	                char* pkey = osrfHashGet(idlClass, "primarykey");
+        	                char* tname = osrfHashGet(idlClass, "tablename");
 
-                        buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, cname, __column, pkey, cname, pkey, locale, __column);
+                            buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, cname, __column, pkey, cname, pkey, locale, __column);
+                        } else {
+				            buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, __column, __column);
+                        }
                     } else {
 				        buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, __column, __column);
                     }
-                } else {
-				    buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, __column, __column);
-                }
 
-			// ... but it could be an object, in which case we check for a Field Transform
-			} else {
+			    // ... but it could be an object, in which case we check for a Field Transform
+			    } else {
 
-				__column = jsonObjectToSimpleString( jsonObjectGetKeyConst( selfield, "column" ) );
+				    __column = jsonObjectToSimpleString( jsonObjectGetKeyConst( selfield, "column" ) );
 
-				// again, just to be safe
-				osrfHash* field = osrfHashGet( osrfHashGet( idlClass, "fields" ), __column );
-				if (!field) continue;
-				const char* fname = osrfHashGet(field, "name");
+				    // again, just to be safe
+				    osrfHash* field = osrfHashGet( osrfHashGet( idlClass, "fields" ), __column );
+				    if (!field) continue;
+				    const char* fname = osrfHashGet(field, "name");
 
-				if (first) {
-					first = 0;
-				} else {
-					buffer_add(select_buf, ",");
-				}
+				    if (first) {
+					    first = 0;
+				    } else {
+					    buffer_add(select_buf, ",");
+				    }
 
-				if ((tmp_const = jsonObjectGetKeyConst( selfield, "alias" ))) {
-					__alias = jsonObjectToSimpleString( tmp_const );
-				} else {
-					__alias = strdup(__column);
-				}
+				    if ((tmp_const = jsonObjectGetKeyConst( selfield, "alias" ))) {
+					    __alias = jsonObjectToSimpleString( tmp_const );
+				    } else {
+					    __alias = strdup(__column);
+				    }
 
-				if (jsonObjectGetKeyConst( selfield, "transform" )) {
-					free(__column);
-					__column = searchFieldTransform(cname, field, selfield);
-					buffer_fadd(select_buf, " %s AS \"%s\"", __column, __alias);
-				} else {
-                    if (locale) {
-                		char* i18n = osrfHashGet(field, "i18n");
-			            if (flags & DISABLE_I18N)
-                            i18n = NULL;
+				    if (jsonObjectGetKeyConst( selfield, "transform" )) {
+					    free(__column);
+					    __column = searchFieldTransform(cname, field, selfield);
+					    buffer_fadd(select_buf, " %s AS \"%s\"", __column, __alias);
+				    } else {
+                        if (locale) {
+                		    char* i18n = osrfHashGet(field, "i18n");
+			                if (flags & DISABLE_I18N)
+                                i18n = NULL;
+    
+    	        		    if ( i18n && !strncasecmp("true", i18n, 4)) {
+        	                    char* pkey = osrfHashGet(idlClass, "primarykey");
+        	                    char* tname = osrfHashGet(idlClass, "tablename");
 
-    	        		if ( i18n && !strncasecmp("true", i18n, 4)) {
-        	                char* pkey = osrfHashGet(idlClass, "primarykey");
-        	                char* tname = osrfHashGet(idlClass, "tablename");
-
-                            buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, cname, fname, pkey, cname, pkey, locale, __alias);
+                                buffer_fadd(select_buf, " oils_i18n_xlate('%s', '%s', '%s', '%s', \"%s\".%s::TEXT, '%s') AS \"%s\"", tname, cname, fname, pkey, cname, pkey, locale, __alias);
+                            } else {
+					            buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, fname, __alias);
+                            }
                         } else {
 					        buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, fname, __alias);
                         }
-                    } else {
-					    buffer_fadd(select_buf, " \"%s\".%s AS \"%s\"", cname, fname, __alias);
-                    }
-				}
-			}
+				    }
+			    }
 
-			if (is_agg->size || (flags & SELECT_DISTINCT)) {
+			    if (is_agg->size || (flags & SELECT_DISTINCT)) {
 
-				if (!jsonBoolIsTrue( jsonObjectGetKey( selfield, "aggregate" ) )) {
-					if (gfirst) {
-						gfirst = 0;
-					} else {
-						buffer_add(group_buf, ",");
-					}
+				    if (!jsonBoolIsTrue( jsonObjectGetKey( selfield, "aggregate" ) )) {
+					    if (gfirst) {
+						    gfirst = 0;
+					    } else {
+						    buffer_add(group_buf, ",");
+					    }
 
-					buffer_fadd(group_buf, " %d", sel_pos);
-				/*
-				} else if (is_agg = jsonObjectGetKey( selfield, "having" )) {
-					if (gfirst) {
-						gfirst = 0;
-					} else {
-						buffer_add(group_buf, ",");
-					}
+					    buffer_fadd(group_buf, " %d", sel_pos);
+				    /*
+				    } else if (is_agg = jsonObjectGetKey( selfield, "having" )) {
+					    if (gfirst) {
+						    gfirst = 0;
+					    } else {
+						    buffer_add(group_buf, ",");
+					    }
 
-					__column = searchFieldTransform(cname, field, selfield);
-					buffer_fadd(group_buf, " %s", __column);
-					__column = searchFieldTransform(cname, field, selfield);
-				*/
-				}
-			}
+					    __column = searchFieldTransform(cname, field, selfield);
+					    buffer_fadd(group_buf, " %s", __column);
+					    __column = searchFieldTransform(cname, field, selfield);
+				    */
+				    }
+			    }
 
-			if (__column) free(__column);
-			if (__alias) free(__alias);
+			    if (__column) free(__column);
+			    if (__alias) free(__alias);
 
-			sel_pos++;
-		}
+			    sel_pos++;
+		    }
 
-        // jsonIteratorFree(select_itr);
-	}
+            // jsonIteratorFree(select_itr);
+	    }
 
-    // jsonIteratorFree(selclass_itr);
+        // jsonIteratorFree(selclass_itr);
 
-	if (is_agg) jsonObjectFree(is_agg);
+	    if (is_agg) jsonObjectFree(is_agg);
+    } else {
+        buffer_add(select_buf, "*");
+    }
 
+
 	char* col_list = buffer_release(select_buf);
-	char* table = getSourceDefinition(core_meta);
+	char* table = NULL;
+    if (!from_function) table = getSourceDefinition(core_meta);
+    else table = searchValueTransform(join_hash);
 
 	// Put it all together
 	buffer_fadd(sql_buf, "SELECT %s FROM %s AS \"%s\" ", col_list, table, core_class );
 	free(col_list);
 	free(table);
 
-	// Now, walk the join tree and add that clause
-	if ( join_hash ) {
-		char* join_clause = searchJOIN( join_hash, core_meta );
-		buffer_add(sql_buf, join_clause);
-		free(join_clause);
-	}
+    if (!from_function) {
+	    // Now, walk the join tree and add that clause
+	    if ( join_hash ) {
+		    char* join_clause = searchJOIN( join_hash, core_meta );
+		    buffer_add(sql_buf, join_clause);
+		    free(join_clause);
+	    }
 
-	if ( search_hash ) {
-		buffer_add(sql_buf, " WHERE ");
+	    if ( search_hash ) {
+		    buffer_add(sql_buf, " WHERE ");
 
-		// and it's on the the WHERE clause
-		char* pred = searchWHERE( search_hash, core_meta, AND_OP_JOIN );
+		    // and it's on the the WHERE clause
+		    char* pred = searchWHERE( search_hash, core_meta, AND_OP_JOIN );
 
-		if (!pred) {
-			osrfAppSessionStatus(
-				ctx->session,
-				OSRF_STATUS_INTERNALSERVERERROR,
-				"osrfMethodException",
-				ctx->request,
-				"Severe query error in WHERE predicate -- see error log for more details"
-			);
-			free(core_class);
-			buffer_free(having_buf);
-			buffer_free(group_buf);
-			buffer_free(order_buf);
-			buffer_free(sql_buf);
-			if (defaultselhash) jsonObjectFree(defaultselhash);
-			return NULL;
-		} else {
-			buffer_add(sql_buf, pred);
-			free(pred);
-		}
-    }
+		    if (!pred) {
+			    osrfAppSessionStatus(
+				    ctx->session,
+				    OSRF_STATUS_INTERNALSERVERERROR,
+				    "osrfMethodException",
+				    ctx->request,
+				    "Severe query error in WHERE predicate -- see error log for more details"
+			    );
+			    free(core_class);
+			    buffer_free(having_buf);
+			    buffer_free(group_buf);
+			    buffer_free(order_buf);
+			    buffer_free(sql_buf);
+			    if (defaultselhash) jsonObjectFree(defaultselhash);
+			    return NULL;
+		    } else {
+			    buffer_add(sql_buf, pred);
+			    free(pred);
+		    }
+        }
 
-	if ( having_hash ) {
-		buffer_add(sql_buf, " HAVING ");
+	    if ( having_hash ) {
+		    buffer_add(sql_buf, " HAVING ");
 
-		// and it's on the the WHERE clause
-		char* pred = searchWHERE( having_hash, core_meta, AND_OP_JOIN );
+		    // and it's on the the WHERE clause
+		    char* pred = searchWHERE( having_hash, core_meta, AND_OP_JOIN );
 
-		if (!pred) {
-			osrfAppSessionStatus(
-				ctx->session,
-				OSRF_STATUS_INTERNALSERVERERROR,
-				"osrfMethodException",
-				ctx->request,
-				"Severe query error in HAVING predicate -- see error log for more details"
-			);
-			free(core_class);
-			buffer_free(having_buf);
-			buffer_free(group_buf);
-			buffer_free(order_buf);
-			buffer_free(sql_buf);
-			if (defaultselhash) jsonObjectFree(defaultselhash);
-			return NULL;
-		} else {
-			buffer_add(sql_buf, pred);
-			free(pred);
-		}
-	}
+		    if (!pred) {
+			    osrfAppSessionStatus(
+				    ctx->session,
+				    OSRF_STATUS_INTERNALSERVERERROR,
+				    "osrfMethodException",
+				    ctx->request,
+				    "Severe query error in HAVING predicate -- see error log for more details"
+			    );
+			    free(core_class);
+			    buffer_free(having_buf);
+			    buffer_free(group_buf);
+			    buffer_free(order_buf);
+			    buffer_free(sql_buf);
+			    if (defaultselhash) jsonObjectFree(defaultselhash);
+			    return NULL;
+		    } else {
+			    buffer_add(sql_buf, pred);
+			    free(pred);
+		    }
+	    }
 
-	first = 1;
-	jsonIterator* class_itr = jsonNewIterator( order_hash );
-	while ( (snode = jsonIteratorNext( class_itr )) ) {
+	    first = 1;
+	    jsonIterator* class_itr = jsonNewIterator( order_hash );
+	    while ( (snode = jsonIteratorNext( class_itr )) ) {
 
-		if (!jsonObjectGetKeyConst(selhash,class_itr->key))
-			continue;
+		    if (!jsonObjectGetKeyConst(selhash,class_itr->key))
+			    continue;
 
-		if ( snode->type == JSON_HASH ) {
+		    if ( snode->type == JSON_HASH ) {
 
-		    jsonIterator* order_itr = jsonNewIterator( snode );
-			while ( (onode = jsonIteratorNext( order_itr )) ) {
+		        jsonIterator* order_itr = jsonNewIterator( snode );
+			    while ( (onode = jsonIteratorNext( order_itr )) ) {
 
-				if (!oilsIDLFindPath( "/%s/fields/%s", class_itr->key, order_itr->key ))
-					continue;
+				    if (!oilsIDLFindPath( "/%s/fields/%s", class_itr->key, order_itr->key ))
+					    continue;
 
-				char* direction = NULL;
-				if ( onode->type == JSON_HASH ) {
-					if ( jsonObjectGetKeyConst( onode, "transform" ) ) {
-						string = searchFieldTransform(
-							class_itr->key,
-							oilsIDLFindPath( "/%s/fields/%s", class_itr->key, order_itr->key ),
-							onode
-						);
-					} else {
-						growing_buffer* field_buf = buffer_init(16);
-						buffer_fadd(field_buf, "\"%s\".%s", class_itr->key, order_itr->key);
-						string = buffer_release(field_buf);
-					}
+				    char* direction = NULL;
+				    if ( onode->type == JSON_HASH ) {
+					    if ( jsonObjectGetKeyConst( onode, "transform" ) ) {
+						    string = searchFieldTransform(
+							    class_itr->key,
+							    oilsIDLFindPath( "/%s/fields/%s", class_itr->key, order_itr->key ),
+							    onode
+						    );
+					    } else {
+						    growing_buffer* field_buf = buffer_init(16);
+						    buffer_fadd(field_buf, "\"%s\".%s", class_itr->key, order_itr->key);
+						    string = buffer_release(field_buf);
+					    }
 
-					if ( (tmp_const = jsonObjectGetKeyConst( onode, "direction" )) ) {
-						direction = jsonObjectToSimpleString(tmp_const);
-						if (!strncasecmp(direction, "d", 1)) {
-							free(direction);
-							direction = " DESC";
-						} else {
-							free(direction);
-							direction = " ASC";
-						}
-					}
+					    if ( (tmp_const = jsonObjectGetKeyConst( onode, "direction" )) ) {
+						    direction = jsonObjectToSimpleString(tmp_const);
+						    if (!strncasecmp(direction, "d", 1)) {
+							    free(direction);
+							    direction = " DESC";
+						    } else {
+							    free(direction);
+							    direction = " ASC";
+						    }
+					    }
 
-				} else {
-					string = strdup(order_itr->key);
-					direction = jsonObjectToSimpleString(onode);
-					if (!strncasecmp(direction, "d", 1)) {
-						free(direction);
-						direction = " DESC";
-					} else {
-						free(direction);
-						direction = " ASC";
-					}
-				}
+				    } else {
+					    string = strdup(order_itr->key);
+					    direction = jsonObjectToSimpleString(onode);
+					    if (!strncasecmp(direction, "d", 1)) {
+						    free(direction);
+						    direction = " DESC";
+					    } else {
+						    free(direction);
+						    direction = " ASC";
+					    }
+				    }
 
-				if (first) {
-					first = 0;
-				} else {
-					buffer_add(order_buf, ", ");
-				}
+				    if (first) {
+					    first = 0;
+				    } else {
+					    buffer_add(order_buf, ", ");
+				    }
 
-				buffer_add(order_buf, string);
-				free(string);
+				    buffer_add(order_buf, string);
+				    free(string);
 
-				if (direction) {
-					buffer_add(order_buf, direction);
-				}
+				    if (direction) {
+					    buffer_add(order_buf, direction);
+				    }
 
-			}
-            // jsonIteratorFree(order_itr);
+			    }
+                // jsonIteratorFree(order_itr);
 
-		} else if ( snode->type == JSON_ARRAY ) {
+		    } else if ( snode->type == JSON_ARRAY ) {
 
-		    jsonIterator* order_itr = jsonNewIterator( snode );
-			while ( (onode = jsonIteratorNext( order_itr )) ) {
+		        jsonIterator* order_itr = jsonNewIterator( snode );
+			    while ( (onode = jsonIteratorNext( order_itr )) ) {
 
-				char* _f = jsonObjectToSimpleString( onode );
+				    char* _f = jsonObjectToSimpleString( onode );
 
-				if (!oilsIDLFindPath( "/%s/fields/%s", class_itr->key, _f))
-					continue;
+				    if (!oilsIDLFindPath( "/%s/fields/%s", class_itr->key, _f))
+					    continue;
 
-				if (first) {
-					first = 0;
-				} else {
-					buffer_add(order_buf, ", ");
-				}
+				    if (first) {
+					    first = 0;
+				    } else {
+					    buffer_add(order_buf, ", ");
+				    }
 
-				buffer_add(order_buf, _f);
-				free(_f);
+				    buffer_add(order_buf, _f);
+				    free(_f);
 
-			}
-            // jsonIteratorFree(order_itr);
+			    }
+                // jsonIteratorFree(order_itr);
 
 
-		// IT'S THE OOOOOOOOOOOLD STYLE!
-		} else {
-			osrfLogError(OSRF_LOG_MARK, "%s: Possible SQL injection attempt; direct order by is not allowed", MODULENAME);
-			osrfAppSessionStatus(
-				ctx->session,
-				OSRF_STATUS_INTERNALSERVERERROR,
-				"osrfMethodException",
-				ctx->request,
-				"Severe query error -- see error log for more details"
-			);
+		    // IT'S THE OOOOOOOOOOOLD STYLE!
+		    } else {
+			    osrfLogError(OSRF_LOG_MARK, "%s: Possible SQL injection attempt; direct order by is not allowed", MODULENAME);
+			    osrfAppSessionStatus(
+				    ctx->session,
+				    OSRF_STATUS_INTERNALSERVERERROR,
+				    "osrfMethodException",
+				    ctx->request,
+				    "Severe query error -- see error log for more details"
+			    );
 
-			free(core_class);
-			buffer_free(having_buf);
-			buffer_free(group_buf);
-			buffer_free(order_buf);
-			buffer_free(sql_buf);
-			if (defaultselhash) jsonObjectFree(defaultselhash);
-			jsonIteratorFree(class_itr);
-			return NULL;
-		}
+			    free(core_class);
+			    buffer_free(having_buf);
+			    buffer_free(group_buf);
+			    buffer_free(order_buf);
+			    buffer_free(sql_buf);
+			    if (defaultselhash) jsonObjectFree(defaultselhash);
+			    jsonIteratorFree(class_itr);
+			    return NULL;
+		    }
 
-	}
+	    }
+    }
 
     // jsonIteratorFree(class_itr);
 

Modified: branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Application/Ingest.pm
===================================================================
--- branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Application/Ingest.pm	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Application/Ingest.pm	2008-08-04 01:25:53 UTC (rev 10243)
@@ -1088,12 +1088,16 @@
 	my $res = $rd_script->run || ($log->error( "Descriptor script died!  $@" ) && return undef);
 	$log->debug("Script for biblio descriptor extraction completed successfully");
 
-    if ($res->{date1} ne '    ') {
-        $res->{date1} =~ tr/ux/00/;
+    my $d1 = $res->date1;
+    if ($d1 && $d1 ne '    ') {
+        $d1 =~ tr/ux/00/;
+        $res->date1( $d1 );
     }
 
-    if ($res->{date2} ne '    ') {
-        $res->{date2} =~ tr/ux/99/;
+    my $d2 = $res->date2;
+    if ($d2 && $d2 ne '    ') {
+        $d2 =~ tr/ux/99/;
+        $res->date2( $d2 );
     }
 
 	return $res;

Modified: branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm
===================================================================
--- branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/CStoreEditor.pm	2008-08-04 01:25:53 UTC (rev 10243)
@@ -289,7 +289,7 @@
 	my $err;
 	my $argstr = __arg_to_string( (scalar(@params)) == 1 ? $params[0] : \@params);
 
-	$self->log(I, "request $method : $argstr");
+	$self->log(I, "request $method $argstr");
 
 	if( ($self->{xact} or $always_xact) and 
 			$self->session->state != OpenSRF::AppSession::CONNECTED() ) {

Modified: branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/ZClient.pm
===================================================================
--- branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/ZClient.pm	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/src/perlmods/OpenILS/Utils/ZClient.pm	2008-08-04 01:25:53 UTC (rev 10243)
@@ -1,6 +1,8 @@
 package OpenILS::Utils::ZClient;
 use UNIVERSAL::require;
 
+sub DESTROY {};
+
 use overload 'bool' => sub { return $_[0]->{connection} ? 1 : 0 };
 
 sub EVENT_NONE { 0 }
@@ -85,6 +87,7 @@
 #-------------------------------------------------------------------------------
 package OpenILS::Utils::ZClient::ResultSet;
 
+sub DESTROY {};
 our $AUTOLOAD;
 
 sub new {
@@ -128,6 +131,7 @@
 #-------------------------------------------------------------------------------
 package OpenILS::Utils::ZClient::Record;
 
+sub DESTROY {};
 our $AUTOLOAD;
 
 sub new {

Modified: branches/acq-experiment/Open-ILS/src/support-scripts/fine_generator.pl
===================================================================
--- branches/acq-experiment/Open-ILS/src/support-scripts/fine_generator.pl	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/src/support-scripts/fine_generator.pl	2008-08-04 01:25:53 UTC (rev 10243)
@@ -12,6 +12,7 @@
 
 my $config = shift || die "bootstrap config required\n";
 my $lockfile = shift || "/tmp/generate_fines-LOCK";
+my $grace = int(shift()) || 1;
 
 if (-e $lockfile) {
         open(F,$lockfile);
@@ -36,7 +37,7 @@
 
 my $r = OpenSRF::AppSession
 		->create( 'open-ils.storage' )
-		->request( 'open-ils.storage.action.circulation.overdue.generate_fines' => 1 );
+		->request( 'open-ils.storage.action.circulation.overdue.generate_fines' => $grace );
 
 while (!$r->complete) { $r->recv };
 

Modified: branches/acq-experiment/Open-ILS/src/support-scripts/test-scripts/indb_circ.pl
===================================================================
--- branches/acq-experiment/Open-ILS/src/support-scripts/test-scripts/indb_circ.pl	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/src/support-scripts/test-scripts/indb_circ.pl	2008-08-04 01:25:53 UTC (rev 10243)
@@ -17,7 +17,7 @@
     ('/openils/conf/opensrf_core.xml', 326, 3, 301313, undef);
 
 GetOptions(
-    'org=o' => \$org_id,
+    'org=i' => \$org_id,
     'user=i' => \$user_id,
     'copy=i' => \$copy_id,
     'barcode=s' => \$copy_barcode,
@@ -32,6 +32,7 @@
             column => 'id',
             params => [$copy_id, $user_id],
             result_field => 'matchpoint',
+            alias => 'matchpoint'
         }]
     },
     from => 'aou',
@@ -40,41 +41,45 @@
 
 my $e = new_editor();
 
-my $mp_id = $e->json_query($CIRC_TEST)->[0]->{id};
-my $mp = $e->retrieve_config_circ_matrix_ruleset([
-    $mp_id,
+my $start = time;
+my $mp_id = $e->json_query($CIRC_TEST)->[0]->{matchpoint};
+
+my $rule_set = $e->search_config_circ_matrix_ruleset([
+    {matchpoint => $mp_id},
     {   flesh => 1,
         flesh_fields => {
             'ccmrs' => ['duration_rule', 'recurring_fine_rule', 'max_fine_rule']
         }
     }
-]);
+])->[0];
 
+my $rundur = time - $start;
+
 my $cp = $e->retrieve_asset_copy($copy_id);
 my ($dur, $recf);
 
 # get the actual duration
 if($cp->loan_duration == 1) {
-    $dur = $mp->duration_rule->shrt;
+    $dur = $rule_set->duration_rule->shrt;
 } elsif($cp->loan_duration == 2) {
-    $dur = $mp->duration_rule->normal;
+    $dur = $rule_set->duration_rule->normal;
 } else {
-    $dur = $mp->duration_rule->extended;
+    $dur = $rule_set->duration_rule->extended;
 }
 
 # get the recurring fine level
 if($cp->fine_level == 1) {
-    $recf = $mp->recurring_fine_rule->low;
+    $recf = $rule_set->recurring_fine_rule->low;
 } elsif($cp->fine_level == 2) {
-    $recf = $mp->recurring_fine_rule->normal;
+    $recf = $rule_set->recurring_fine_rule->normal;
 } else {
-    $recf = $mp->recurring_fine_rule->high;
+    $recf = $rule_set->recurring_fine_rule->high;
 }
 
+print "Duration [".$rule_set->duration_rule->name."] = $dur\n";
+print "Recurring fines [".$rule_set->recurring_fine_rule->name."; interval='".
+    $rule_set->recurring_fine_rule->recurance_interval."'] = \$$recf\n";
+print "Max fine [".$rule_set->max_fine_rule->name."] = \$".$rule_set->max_fine_rule->amount."\n";
+print "took: $rundur\n";
 
-print "Duration [".$mp->duration_rule->name."] = $dur\n";
-print "Recurring fines [".$mp->recurring_fine_rule->name."; interval='".
-    $mp->recurring_fine_rule->recurance_interval."'] = \$$recf\n";
-print "Max fine [".$mp->max_fine_rule->name."] = \$".$mp->max_fine_rule->amount."\n";
 
-

Modified: branches/acq-experiment/Open-ILS/web/js/dojo/fieldmapper/OrgUtils.js
===================================================================
--- branches/acq-experiment/Open-ILS/web/js/dojo/fieldmapper/OrgUtils.js	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/web/js/dojo/fieldmapper/OrgUtils.js	2008-08-04 01:25:53 UTC (rev 10243)
@@ -82,9 +82,9 @@
 				continue;
 			}
 
-			var parent = fieldmapper.aou.findOrgUnit(x.parent_ou(),true);
-			if (!parent.children()) parent.children([]);
-			parent.children().push(x);
+			var par = fieldmapper.aou.findOrgUnit(x.parent_ou(),true);
+			if (!par.children()) par.children([]);
+			par.children().push(x);
 			fieldmapper.aou.OrgCache[x.id()].treePtr = x;
 		}
 

Modified: branches/acq-experiment/Open-ILS/web/opac/common/js/org_utils.js
===================================================================
--- branches/acq-experiment/Open-ILS/web/opac/common/js/org_utils.js	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/web/opac/common/js/org_utils.js	2008-08-04 01:25:53 UTC (rev 10243)
@@ -112,9 +112,9 @@
 		continue;
 	} 
 
-	var parent = findOrgUnit(x.parent_ou());
-	if (!parent.children()) parent.children(new Array());
-	parent.children().push(x);
+	var par = findOrgUnit(x.parent_ou());
+	if (!par.children()) par.children(new Array());
+	par.children().push(x);
 }
 
 function _tree_killer () {

Modified: branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.css
===================================================================
--- branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.css	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.css	2008-08-04 01:25:53 UTC (rev 10243)
@@ -81,6 +81,15 @@
     display: block;
     visibility: visible;
 }
+#selfck-items-out-done-div {
+    width: 100%;
+    text-align: center;
+    margin-top: 20px;
+}
 
+.selfck-done-link {
+    font-size: 12pt;
+    font-weight: bold;
+}
 
 

Modified: branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.js
===================================================================
--- branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.js	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.js	2008-08-04 01:25:53 UTC (rev 10243)
@@ -19,28 +19,37 @@
 ----------------------------------------------------------------- */
 
 var STAFF_SES_PARAM = 'ses';
+var PATRON_BARCODE_COOKIE = 'pbcc';
 var patron = null
 var itemBarcode = null;
 var itemsOutTemplate = null;
 var isRenewal = false;
 var pendingXact = false;
-var patronTimeout = 120000;
+var patronTimeout = 600000; /* 10 minutes */
 var timerId = null;
 var printWrapper;
 var printTemplate;
 var successfulItems = {};
+var scanTimeout = 800;
+var scanTimeoutId;
+var patronBarcodeRegex;
 
 
 function selfckInit() {
     var cgi = new CGI();
     var staff = grabUser(cookieManager.read(STAFF_SES_PARAM) || cgi.param(STAFF_SES_PARAM));
 
+    selfckSetupPrinter();
+
     /*
     XXX we need org information (from the proxy?)
     var t = fetchOrgSettingDefault(1, 'circ.selfcheck.patron_login_timeout');
     patronTimeout = (t) ? parseInt(t) * 1000 : patronTimeout;
     */
 
+    var reg = fetchOrgSettingDefault(globalOrgTree.id(), 'opac.barcode_regex');
+    if(reg) patronBarcodeRegex = new RegExp(reg);
+
     if(!staff) {
         // should not happen when behind the proxy
         return alert('Staff must login');
@@ -54,10 +63,7 @@
             selfckPatronLogin();
     };
 
-    $('selfck-item-barcode-input').onkeypress = function(evt) {
-        if(userPressedEnter(evt)) 
-            selfckCheckout();
-    };
+    $('selfck-item-barcode-input').onkeypress = selfckItemBarcodeKeypress;
 
     // for debugging, allow passing the user barcode via param
     var urlbc = new CGI().param('patron');
@@ -70,9 +76,57 @@
     printTemplate = printWrapper.removeChild($n(printWrapper, 'selfck-print-items-template'));
     itemsOutTemplate = $('selfck-items-out-tbody').removeChild($('selfck-items-out-row'));
 
+    selfckTryPatronCookie();
+
 //    selfckMkDummyCirc(); // testing only
+    
 }
 
+function selfckSetupPrinter() {
+    try { // Mozilla only
+		netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+        netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesRead');
+        netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesWrite');
+        var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+        if (pref)
+            pref.setBoolPref('print.always_print_silent', true);
+    } catch(E) {
+        
+    }
+}
+
+function selfckTryPatronCookie() {
+    var pb = cookieManager.read(PATRON_BARCODE_COOKIE);
+    if(pb) {
+        cookieManager.write(PATRON_BARCODE_COOKIE, '');
+        $('selfck-patron-login-input').value = pb;
+        selfckPatronLogin();
+    }
+}
+
+
+function selfckItemBarcodeKeypress(evt) {
+    if(userPressedEnter(evt)) {
+        clearTimeout(scanTimeoutId);
+        selfckCheckout();
+    } else {
+        /*  If scanTimeout milliseconds have passed and there is
+            still data in the input box, it's a likely indication
+            of a partial scan. Select the text so the next scan
+            will replace the value */
+        clearTimeout(scanTimeoutId);
+        scanTimeoutId = setTimeout(
+            function() {
+                if($('selfck-item-barcode-input').value) {
+                    $('selfck-item-barcode-input').select();
+                }
+            },
+            scanTimeout
+        );
+    }
+}
+
 /*
  * Start the logout timer
  */
@@ -100,8 +154,13 @@
 function selfckLogoutPatron() {
     $('selfck-item-barcode-input').value = ''; // prevent browser caching
     $('selfck-patron-login-input').value = '';
-    if(patron) // page reload resets everything
-        location.href = location.href;
+    if(patron) {
+        selfckPrint();
+        setTimeout(
+            function() { location.href = location.href; },
+            800
+        );
+    }
 }
 
 /*
@@ -139,6 +198,21 @@
 }
 
 /**
+  * If a user barcode was scanned into the item barcode
+  * input, log out the current user and log in the new user
+  */
+function selfckCheckPatronBarcode(itemBc) {
+    if(patronBarcodeRegex) {
+        if(itemBc.match(patronBarcodeRegex)) {
+            cookieManager.write(PATRON_BARCODE_COOKIE, itemBc, -1);
+            selfckLogoutPatron();
+            return true;
+        }
+    }
+    return false;
+}
+
+/**
   * Sends the checkout request
   */
 function selfckCheckout() {
@@ -153,6 +227,9 @@
     itemBarcode = $('selfck-item-barcode-input').value;
     if(!itemBarcode) return;
 
+    if(selfckCheckPatronBarcode(itemBarcode))
+        return;
+
     if (itemBarcode in successfulItems) {
         selfckShowMsgNode({textcode:'dupe-barcode'});
         $('selfck-item-barcode-input').select();
@@ -210,7 +287,7 @@
   * Renders a row in the checkouts table for the current circulation
   */
 function selfckDislplayCheckout(evt) {
-    unHideMe($('selfck-items-out-table'));
+    unHideMe($('selfck-items-out-table-wrapper'));
 
     var template = itemsOutTemplate.cloneNode(true);
     var copy = evt.payload.copy;
@@ -279,8 +356,11 @@
   * Sets the print date and prints the page
   */
 function selfckPrint() {
-    appendClear($('selfck-print-date'), text(new Date().toLocaleString()));
-    window.print();
+    for(var x in successfulItems) { // make sure we've checked out at least one item
+        appendClear($('selfck-print-date'), text(new Date().toLocaleString()));
+        window.print();
+        return;
+    }
 }
 
 

Modified: branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.xml
===================================================================
--- branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.xml	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/web/opac/extras/selfcheck/selfcheck.xml	2008-08-04 01:25:53 UTC (rev 10243)
@@ -73,17 +73,9 @@
                     </div>
                     <div id='selfck-logout-link-div'>
                         <span class='selfck-link-span'>
-                            <a href='javascript:void(0);' id='selfck-print-co-button' 
-                                onclick='selfckPrint();'>&selfck.print_checkouts;</a>
+                            <a href='javascript:void(0);' class='selfck-done-link' 
+                                onclick='selfckLogoutPatron();'>&selfck.done;</a>
                         </span>
-                        <span class='selfck-link-span'>
-                            <a href='javascript:void(0);' id='selfck-logout-button' 
-                                onclick='selfckLogoutPatron();'>&selfck.logout;</a>
-                        </span>
-                        <span class='selfck-link-span'>
-                            <a href='javascript:void(0);' id='selfck-logout-print-button' 
-                                onclick='selfckPrint(); selfckLogoutPatron();'>&selfck.print_logout;</a>
-                        </span>
                     </div>
                 </div>
 
@@ -113,6 +105,7 @@
                         <div id='selfck-item-barcode-form'>
                             <span><input type='text' id='selfck-item-barcode-input'> </input></span>
                             <span><button onclick='selfckCheckout();'>&selfck.submit;</button></span>
+                            <span><button onclick='$("selfck-item-barcode-input").value = "";'>&selfck.clear;</button></span>
                         </div>
                     </div>
                 </div>
@@ -120,33 +113,39 @@
                 <!--***********************************************************************
                     This is where patrons scan in the item barcodes
                     *********************************************************************** -->
-                <table id='selfck-items-out-table' class='hide_me'>
-                    <thead>
-                        <tr>
-                            <td id='selfck-pic-cell'></td>
-                            <td>&selfck.barcode;</td>
-                            <td>&selfck.title;</td>
-                            <td>&selfck.author;</td>
-                            <td>&selfck.due_date;</td>
-                            <td>&selfck.remaining;</td>
-                            <td>&selfck.cotype;</td>
-                        </tr>
-                    </thead>
-                    <tbody id='selfck-items-out-tbody'>
-                        <tr id='selfck-items-out-row'>
-                            <td><img class='jacket' name='selfck.jacket'></img></td>
-                            <td name='selfck.barcode'></td>
-                            <td name='selfck.title'></td>
-                            <td name='selfck.author'></td>
-                            <td name='selfck.due_date'></td>
-                            <td name='selfck.remaining'></td>
-                            <td>
-                                <span name='selfck.cotype_co'>&selfck.cotype_co;</span>
-                                <span name='selfck.cotype_rn' class='hide_me'>&selfck.cotype_rn;</span>
-                            </td>
-                        </tr>
-                    </tbody>
-                </table>
+                <div id='selfck-items-out-table-wrapper' class='hide_me'>
+                    <table id='selfck-items-out-table'>
+                        <thead>
+                            <tr>
+                                <td id='selfck-pic-cell'></td>
+                                <td>&selfck.barcode;</td>
+                                <td>&selfck.title;</td>
+                                <td>&selfck.author;</td>
+                                <td>&selfck.due_date;</td>
+                                <td>&selfck.remaining;</td>
+                                <td>&selfck.cotype;</td>
+                            </tr>
+                        </thead>
+                        <tbody id='selfck-items-out-tbody'>
+                            <tr id='selfck-items-out-row'>
+                                <td><img class='jacket' name='selfck.jacket'></img></td>
+                                <td name='selfck.barcode'></td>
+                                <td name='selfck.title'></td>
+                                <td name='selfck.author'></td>
+                                <td name='selfck.due_date'></td>
+                                <td name='selfck.remaining'></td>
+                                <td>
+                                    <span name='selfck.cotype_co'>&selfck.cotype_co;</span>
+                                    <span name='selfck.cotype_rn' class='hide_me'>&selfck.cotype_rn;</span>
+                                </td>
+                            </tr>
+                        </tbody>
+                    </table>
+                    <div id='selfck-items-out-done-div'>
+                        <a href='javascript:void(0);' id='selfck-print-co-button' 
+                            class='selfck-done-link' onclick='selfckLogoutPatron();'>&selfck.done;</a>
+                    </div>
+                </div>
             </div>
         </div>
 

Modified: branches/acq-experiment/Open-ILS/web/opac/locale/en-US/opac.dtd
===================================================================
--- branches/acq-experiment/Open-ILS/web/opac/locale/en-US/opac.dtd	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/web/opac/locale/en-US/opac.dtd	2008-08-04 01:25:53 UTC (rev 10243)
@@ -645,6 +645,7 @@
 <!ENTITY selfck.staff_login "Library barcode or username">
 <!ENTITY selfck.staff_pw "Password">
 <!ENTITY selfck.submit "Submit">
+<!ENTITY selfck.clear "Clear">
 <!ENTITY selfck.patron_barcode_label "Please scan your library barcode">
 <!ENTITY selfck.item_barcode_label "Please scan an item to checkout or renew:">
 <!ENTITY selfck.barcode "Barcode">
@@ -655,8 +656,7 @@
 <!ENTITY selfck.cotype "Type">
 <!ENTITY selfck.cotype_co "Checkout">
 <!ENTITY selfck.cotype_rn "Renewal">
-<!ENTITY selfck.logout "Logout">
-<!ENTITY selfck.print_logout "Print &amp; Logout">
+<!ENTITY selfck.done "Done">
 <!ENTITY selfck.welcome "Welcome">
 
 <!-- event messages -->
@@ -666,5 +666,4 @@
 <!ENTITY selfck.event.patron_not_found "The patron barcode was not found">
 <!ENTITY selfck.event.item_noncat "The requested item is not in the catalog">
 <!ENTITY selfck.event.item_nocirc "The requested item is not allowed to circulate">
-<!ENTITY selfck.print_checkouts "Print Receipt">
 

Modified: branches/acq-experiment/Open-ILS/web/opac/skin/default/js/myopac.js
===================================================================
--- branches/acq-experiment/Open-ILS/web/opac/skin/default/js/myopac.js	2008-08-04 00:03:24 UTC (rev 10242)
+++ branches/acq-experiment/Open-ILS/web/opac/skin/default/js/myopac.js	2008-08-04 01:25:53 UTC (rev 10243)
@@ -349,7 +349,7 @@
             unHideMe($n(row, 'myopac_hold_unfrozen_false'))
             if(h.thaw_date()) {
                 var d = dojo.date.stamp.fromISOString(h.thaw_date());
-                $n(row, 'myopac_holds_frozen_until').appendChild(text(dojo.date.locale.format(d, {.selector: 'date', fullYear: true})));
+                $n(row, 'myopac_holds_frozen_until').appendChild(text(dojo.date.locale.format(d, {selector: 'date', fullYear: true})));
             }
         } else {
             unHideMe($n(row, 'myopac_hold_unfrozen_true'))



More information about the open-ils-commits mailing list